Initial commit
This commit is contained in:
115
uni_modules/ak-sbsrv/utssdk/protocol_handler.uts
Normal file
115
uni_modules/ak-sbsrv/utssdk/protocol_handler.uts
Normal file
@@ -0,0 +1,115 @@
|
||||
// Minimal ProtocolHandler runtime class used by pages and components.
|
||||
// This class adapts the platform `BluetoothService` to a small protocol API
|
||||
// expected by pages: setConnectionParameters, initialize, testBatteryLevel,
|
||||
// testVersionInfo. Implemented conservatively to avoid heavy dependencies.
|
||||
|
||||
import type { BluetoothService, AutoBleInterfaces, AutoDiscoverAllResult, BleService, BleCharacteristic, BleProtocolType, BleDevice, ScanDevicesOptions, BleConnectOptionsExt, SendDataPayload, BleOptions } from './interface.uts'
|
||||
|
||||
export class ProtocolHandler {
|
||||
// bluetoothService may be omitted for lightweight wrappers; allow null
|
||||
bluetoothService: BluetoothService | null = null
|
||||
protocol: BleProtocolType = 'standard'
|
||||
deviceId: string | null = null
|
||||
serviceId: string | null = null
|
||||
writeCharId: string | null = null
|
||||
notifyCharId: string | null = null
|
||||
initialized: boolean = false
|
||||
|
||||
// Accept an optional BluetoothService so wrapper subclasses can call
|
||||
// `super()` without forcing a runtime instance.
|
||||
constructor(bluetoothService?: BluetoothService) {
|
||||
if (bluetoothService != null) this.bluetoothService = bluetoothService
|
||||
}
|
||||
|
||||
setConnectionParameters(deviceId: string, serviceId: string, writeCharId: string, notifyCharId: string) {
|
||||
this.deviceId = deviceId
|
||||
this.serviceId = serviceId
|
||||
this.writeCharId = writeCharId
|
||||
this.notifyCharId = notifyCharId
|
||||
}
|
||||
|
||||
// initialize: optional setup, returns a Promise that resolves when ready
|
||||
async initialize(): Promise<void> {
|
||||
// Simple async initializer — keep implementation minimal and generator-friendly.
|
||||
try {
|
||||
// If bluetoothService exposes any protocol-specific setup, call it here.
|
||||
this.initialized = true
|
||||
return
|
||||
} catch (e) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
// Protocol lifecycle / operations — default no-ops so generated code has
|
||||
// concrete member references and platform-specific handlers can override.
|
||||
async scanDevices(options?: ScanDevicesOptions): Promise<void> { return; }
|
||||
async connect(device: BleDevice, options?: BleConnectOptionsExt): Promise<void> { return; }
|
||||
async disconnect(device: BleDevice): Promise<void> { return; }
|
||||
async sendData(device: BleDevice, payload?: SendDataPayload, options?: BleOptions): Promise<void> { return; }
|
||||
async autoConnect(device: BleDevice, options?: BleConnectOptionsExt): Promise<AutoBleInterfaces> { return { serviceId: '', writeCharId: '', notifyCharId: '' }; }
|
||||
|
||||
// Example: testBatteryLevel will attempt to read the battery characteristic
|
||||
// if write/notify-based protocol is not available. Returns number percentage.
|
||||
async testBatteryLevel(): Promise<number> {
|
||||
if (this.deviceId == null) throw new Error('deviceId not set')
|
||||
// copy to local so Kotlin generator can smart-cast the value across awaits
|
||||
const deviceId = this.deviceId
|
||||
// try reading standard Battery characteristic (180F -> 2A19)
|
||||
if (this.bluetoothService == null) throw new Error('bluetoothService not set')
|
||||
const services = await this.bluetoothService.getServices(deviceId)
|
||||
|
||||
|
||||
let found: BleService | null = null
|
||||
for (let i = 0; i < services.length; i++) {
|
||||
const s = services[i]
|
||||
const uuidCandidate: string | null = (s != null && s.uuid != null ? s.uuid : null)
|
||||
const uuid = uuidCandidate != null ? ('' + uuidCandidate).toLowerCase() : ''
|
||||
if (uuid.indexOf('180f') !== -1) { found = s; break }
|
||||
}
|
||||
if (found == null) {
|
||||
// fallback: if writeCharId exists and notify available use protocol (not implemented)
|
||||
return 0
|
||||
}
|
||||
const foundUuid = found!.uuid
|
||||
const charsRaw = await this.bluetoothService.getCharacteristics(deviceId, foundUuid)
|
||||
const chars: BleCharacteristic[] = charsRaw
|
||||
const batChar = chars.find((c: BleCharacteristic) => ((c.properties != null && c.properties.read) || (c.uuid != null && ('' + c.uuid).toLowerCase().includes('2a19'))))
|
||||
if (batChar == null) return 0
|
||||
const buf = await this.bluetoothService.readCharacteristic(deviceId, foundUuid, batChar.uuid)
|
||||
const arr = new Uint8Array(buf)
|
||||
if (arr.length > 0) {
|
||||
return arr[0]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// testVersionInfo: try to read Device Information characteristics or return empty
|
||||
async testVersionInfo(hw: boolean): Promise<string> {
|
||||
// copy to local so Kotlin generator can smart-cast the value across awaits
|
||||
const deviceId = this.deviceId
|
||||
if (deviceId == null) return ''
|
||||
// Device Information service 180A, characteristics: 2A26 (SW), 2A27 (HW) sometimes
|
||||
if (this.bluetoothService == null) return ''
|
||||
const _services = await this.bluetoothService.getServices(deviceId)
|
||||
const services2: BleService[] = _services
|
||||
let found2: BleService | null = null
|
||||
for (let i = 0; i < services2.length; i++) {
|
||||
const s = services2[i]
|
||||
const uuidCandidate: string | null = (s != null && s.uuid != null ? s.uuid : null)
|
||||
const uuid = uuidCandidate != null ? ('' + uuidCandidate).toLowerCase() : ''
|
||||
if (uuid.indexOf('180a') !== -1) { found2 = s; break }
|
||||
}
|
||||
if (found2 == null) return ''
|
||||
const _found2 = found2
|
||||
const found2Uuid = _found2!.uuid
|
||||
const chars = await this.bluetoothService.getCharacteristics(deviceId, found2Uuid)
|
||||
const target = chars.find((c) => {
|
||||
const id = ('' + c.uuid).toLowerCase()
|
||||
if (hw) return id.includes('2a27') || id.includes('hardware')
|
||||
return id.includes('2a26') || id.includes('software')
|
||||
})
|
||||
if (target == null) return ''
|
||||
const buf = await this.bluetoothService.readCharacteristic(deviceId, found2Uuid, target.uuid)
|
||||
try { return new TextDecoder().decode(new Uint8Array(buf)) } catch (e) { return '' }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user