Files
2026-03-16 10:37:46 +08:00

1 line
252 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"version":3,"sources":["uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts","uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts","F:/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/socket.ts","App.uvue","ak/PermissionManager.uts","F:/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts","uni_modules/ak-sbsrv/utssdk/interface.uts","uni_modules/ak-sbsrv/utssdk/protocol_handler.uts","uni_modules/ak-sbsrv/utssdk/unierror.uts","uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts","uni_modules/ak-sbsrv/utssdk/app-android/index.uts","uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts","pages/akbletest.uvue","main.uts","uni_modules/uni-getbatteryinfo/utssdk/interface.uts"],"sourcesContent":["import type { BleDevice, BleOptions, BleConnectionState, BleConnectionStateChangeCallback } from '../interface.uts'\r\nimport type { BleConnectOptionsExt } from '../interface.uts'\r\nimport type { ScanDevicesOptions } from '../interface.uts';\r\nimport Context from \"android.content.Context\";\r\nimport BluetoothAdapter from \"android.bluetooth.BluetoothAdapter\";\r\nimport BluetoothManager from \"android.bluetooth.BluetoothManager\";\r\nimport BluetoothDevice from \"android.bluetooth.BluetoothDevice\";\r\nimport BluetoothGatt from \"android.bluetooth.BluetoothGatt\";\r\nimport BluetoothGattCallback from \"android.bluetooth.BluetoothGattCallback\";\r\nimport ScanCallback from \"android.bluetooth.le.ScanCallback\";\r\nimport ScanResult from \"android.bluetooth.le.ScanResult\";\r\nimport ScanSettings from \"android.bluetooth.le.ScanSettings\";\r\nimport Handler from \"android.os.Handler\";\r\nimport Looper from \"android.os.Looper\";\r\nimport ContextCompat from \"androidx.core.content.ContextCompat\";\r\nimport PackageManager from \"android.content.pm.PackageManager\";\r\n// 定义 PendingConnect 类型和实现类\r\ninterface PendingConnect {\r\n resolve: () => void;\r\n reject: (err?: any) => void; // Changed to make err optional\r\n timer?: number;\r\n}\r\n\r\nclass PendingConnectImpl implements PendingConnect {\r\n resolve: () => void;\r\n reject: (err?: any) => void; // Changed to make err optional\r\n timer?: number;\r\n \r\n constructor(resolve: () => void, reject: (err?: any) => void, timer?: number) {\r\n this.resolve = resolve;\r\n this.reject = reject;\r\n this.timer = timer;\r\n }\r\n}\r\n// 引入全局回调管理\r\nimport { gattCallback } from './service_manager.uts'\r\nconst pendingConnects = new Map<string, PendingConnect>();\r\n\r\nconst STATE_DISCONNECTED = 0;\r\nconst STATE_CONNECTING = 1;\r\nconst STATE_CONNECTED = 2;\r\nconst STATE_DISCONNECTING = 3;\r\n\r\nexport class DeviceManager {\r\n private static instance: DeviceManager | null = null;\r\n private devices = new Map<string, BleDevice>();\r\n private connectionStates = new Map<string, BleConnectionState>();\r\n private connectionStateChangeListeners: BleConnectionStateChangeCallback[] = []\r\n private gattMap = new Map<string, BluetoothGatt | null>();\r\n private scanCallback: ScanCallback | null = null\r\n private isScanning: boolean = false\r\n private constructor() {}\r\n static getInstance(): DeviceManager {\r\n if (DeviceManager.instance == null) {\r\n DeviceManager.instance = new DeviceManager();\r\n }\r\n return DeviceManager.instance!;\r\n }\r\n startScan(options: ScanDevicesOptions): void {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:60','ak startscan now')\r\n const adapter = this.getBluetoothAdapter();\r\n if (adapter == null) {\r\n throw new Error('未找到蓝牙适配器');\r\n }\r\n if (!adapter.isEnabled) {\r\n // 尝试请求用户开启蓝牙\r\n try {\r\n adapter.enable(); // 直接调用,无需可选链和括号\r\n } catch (e) {\r\n // 某些设备可能不支持 enable\r\n }\r\n setTimeout(() => {\r\n if (!adapter.isEnabled) {\r\n throw new Error('蓝牙未开启');\r\n }\r\n }, 1500);\r\n throw new Error('正在开启蓝牙,请重试');\r\n }\r\n const foundDevices = this.devices; // 直接用全局 devices\r\n \r\n class MyScanCallback extends ScanCallback {\r\n private foundDevices: Map<string, BleDevice>;\r\n private onDeviceFound: (device: BleDevice) => void;\r\n constructor(foundDevices: Map<string, BleDevice>, onDeviceFound: (device: BleDevice) => void) {\r\n super();\r\n this.foundDevices = foundDevices;\r\n this.onDeviceFound = onDeviceFound;\r\n }\r\n override onScanResult(callbackType: Int, result: ScanResult): void {\r\n const device = result.getDevice();\r\n if (device != null) {\r\n const deviceId = device.getAddress();\r\n let bleDevice = foundDevices.get(deviceId);\r\n if (bleDevice == null) {\r\n bleDevice = {\r\n deviceId,\r\n name: device.getName() ?? 'Unknown',\r\n rssi: result.getRssi(),\r\n lastSeen: Date.now()\r\n };\r\n foundDevices.set(deviceId, bleDevice);\r\n this.onDeviceFound(bleDevice);\r\n } else {\r\n // 更新属性(已确保 bleDevice 非空)\r\n bleDevice.rssi = result.getRssi();\r\n bleDevice.name = device.getName() ?? bleDevice.name;\r\n bleDevice.lastSeen = Date.now();\r\n }\r\n }\r\n }\r\n \r\n \r\n override onScanFailed(errorCode: Int): void {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:114','ak scan fail')\r\n }\r\n }\r\n this.scanCallback = new MyScanCallback(foundDevices, options.onDeviceFound ?? (() => {}));\r\n const scanner = adapter.getBluetoothLeScanner();\r\n if (scanner == null) {\r\n throw new Error('无法获取扫描器');\r\n }\r\n const scanSettings = new ScanSettings.Builder()\r\n .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)\r\n .build();\r\n scanner.startScan(null, scanSettings, this.scanCallback);\r\n this.isScanning = true;\r\n // 默认10秒后停止扫描\r\n new Handler(Looper.getMainLooper()).postDelayed(() => {\r\n if (this.isScanning && this.scanCallback != null) {\r\n scanner.stopScan(this.scanCallback);\r\n this.isScanning = false;\r\n // this.devices = foundDevices;\r\n if (options.onScanFinished != null) options.onScanFinished?.invoke();\r\n }\r\n }, 40000);\r\n }\r\n\r\n async connectDevice(deviceId: string, options?: BleConnectOptionsExt): Promise<void> {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:139','[AKBLE] connectDevice called, deviceId:', deviceId, 'options:', options, 'connectionStates:')\r\n const adapter = this.getBluetoothAdapter();\r\n if (adapter == null) {\r\n __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:142','[AKBLE] connectDevice failed: 蓝牙适配器不可用')\r\n throw new Error('蓝牙适配器不可用');\r\n }\r\n const device = adapter.getRemoteDevice(deviceId);\r\n if (device == null) {\r\n __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:147','[AKBLE] connectDevice failed: 未找到设备', deviceId)\r\n throw new Error('未找到设备');\r\n }\r\n this.connectionStates.set(deviceId, STATE_CONNECTING);\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:151','[AKBLE] connectDevice set STATE_CONNECTING, deviceId:', deviceId, 'connectionStates:')\r\n this.emitConnectionStateChange(deviceId, STATE_CONNECTING);\r\n const activity = UTSAndroid.getUniActivity();\r\n const timeout = options?.timeout ?? 15000;\r\n const key = `${deviceId}|connect`;\r\n return new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:158','[AKBLE] connectDevice 超时:', deviceId)\r\n pendingConnects.delete(key);\r\n this.connectionStates.set(deviceId, STATE_DISCONNECTED);\r\n this.gattMap.set(deviceId, null);\r\n this.emitConnectionStateChange(deviceId, STATE_DISCONNECTED);\r\n reject(new Error('连接超时'));\r\n }, timeout);\r\n \r\n // 创建一个适配器函数来匹配类型签名\r\n const resolveAdapter = () => { \r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:168','[AKBLE] connectDevice resolveAdapter:', deviceId)\r\n resolve(); \r\n };\r\n const rejectAdapter = (err?: any) => { \r\n __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:172','[AKBLE] connectDevice rejectAdapter:', deviceId, err)\r\n reject(err); \r\n };\r\n \r\n pendingConnects.set(key, new PendingConnectImpl(resolveAdapter, rejectAdapter, timer));\r\n try {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:178','[AKBLE] connectGatt 调用前:', deviceId)\r\n const gatt = device.connectGatt(activity, false, gattCallback);\r\n this.gattMap.set(deviceId, gatt);\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:181','[AKBLE] connectGatt 调用后:', deviceId, gatt)\r\n } catch (e) {\r\n __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:183','[AKBLE] connectGatt 异常:', deviceId, e)\r\n clearTimeout(timer);\r\n pendingConnects.delete(key);\r\n this.connectionStates.set(deviceId, STATE_DISCONNECTED);\r\n this.gattMap.set(deviceId, null);\r\n this.emitConnectionStateChange(deviceId, STATE_DISCONNECTED);\r\n reject(e);\r\n }\r\n });\r\n }\r\n\r\n // 统一分发连接回调(应在 gattCallback.onConnectionStateChange 内调用)\r\n static handleConnectionStateChange(deviceId: string, newState: number, error?: any) {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:196','[AKBLE] handleConnectionStateChange:', deviceId, 'newState:', newState, 'error:', error, 'pendingConnects:')\r\n const key = `${deviceId}|connect`;\r\n const cb = pendingConnects.get(key);\r\n if (cb != null) {\r\n // 修复 timer 的空安全问题,使用临时变量\r\n const timerValue = cb.timer;\r\n if (timerValue != null) {\r\n clearTimeout(timerValue);\r\n }\r\n \r\n // 修复 error 处理\r\n if (newState === STATE_CONNECTED) {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:208','[AKBLE] handleConnectionStateChange: 连接成功', deviceId)\r\n cb.resolve();\r\n } else {\r\n // 正确处理可空值\r\n const errorToUse = error != null ? error : new Error('连接断开');\r\n __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:213','[AKBLE] handleConnectionStateChange: 连接失败', deviceId, errorToUse)\r\n cb.reject(errorToUse);\r\n }\r\n pendingConnects.delete(key);\r\n } else {\r\n __f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:218','[AKBLE] handleConnectionStateChange: 未找到 pendingConnects', deviceId, newState)\r\n }\r\n }\r\n\r\n async disconnectDevice(deviceId: string, isActive: boolean = true): Promise<void> {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:223','[AKBLE] disconnectDevice called, deviceId:', deviceId, 'isActive:', isActive)\r\n let gatt = this.gattMap.get(deviceId);\r\n if (gatt != null) {\r\n gatt.disconnect();\r\n gatt.close();\r\n // gatt=null;\r\n this.gattMap.set(deviceId, null);\r\n this.connectionStates.set(deviceId, STATE_DISCONNECTED);\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:231','[AKBLE] disconnectDevice set STATE_DISCONNECTED, deviceId:', deviceId, 'connectionStates:')\r\n this.emitConnectionStateChange(deviceId, STATE_DISCONNECTED);\r\n return;\r\n } else {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:235','[AKBLE] disconnectDevice: gatt is null, deviceId:', deviceId)\r\n return;\r\n }\r\n }\r\n\r\n async reconnectDevice(deviceId: string, options?: BleConnectOptionsExt): Promise<void> {\r\n let attempts = 0;\r\n const maxAttempts = options?.maxAttempts ?? 3;\r\n const interval = options?.interval ?? 3000;\r\n while (attempts < maxAttempts) {\r\n try {\r\n await this.disconnectDevice(deviceId, false);\r\n await this.connectDevice(deviceId, options);\r\n return;\r\n } catch (e) {\r\n attempts++;\r\n if (attempts >= maxAttempts) throw new Error('重连失败');\r\n // 修复 setTimeout 问题,使用旧式 Promise + setTimeout 解决\r\n await new Promise<void>((resolve) => {\r\n setTimeout(() => {\r\n resolve();\r\n }, interval);\r\n });\r\n }\r\n }\r\n }\r\n\r\n getConnectedDevices(): BleDevice[] {\r\n // 创建一个空数组来存储结果\r\n const result: BleDevice[] = [];\r\n \r\n // 遍历 devices Map 并检查连接状态\r\n this.devices.forEach((device, deviceId) => {\r\n if (this.connectionStates.get(deviceId) === STATE_CONNECTED) {\r\n result.push(device);\r\n }\r\n });\r\n \r\n return result;\r\n }\r\n\r\n onConnectionStateChange(listener: BleConnectionStateChangeCallback) {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:277','[AKBLE][LOG] onConnectionStateChange 注册, 当前监听数:', this.connectionStateChangeListeners.length + 1, listener)\r\n this.connectionStateChangeListeners.push(listener)\r\n }\r\n\r\n protected emitConnectionStateChange(deviceId: string, state: BleConnectionState) {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:282','[AKBLE][LOG] emitConnectionStateChange', deviceId, state, 'listeners:', this.connectionStateChangeListeners.length, 'connectionStates:', this.connectionStates)\r\n for (const listener of this.connectionStateChangeListeners) {\r\n try { \r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:285','[AKBLE][LOG] emitConnectionStateChange 调用 listener', listener)\r\n listener(deviceId, state) \r\n } catch (e) { \r\n __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:288','[AKBLE][LOG] emitConnectionStateChange listener error', e) \r\n }\r\n }\r\n }\r\n\r\n getGattInstance(deviceId: string): BluetoothGatt | null {\r\n return this.gattMap.get(deviceId) ?? null;\r\n }\r\n\r\n private getBluetoothAdapter(): BluetoothAdapter | null {\r\n const context = UTSAndroid.getAppContext();\r\n if (context == null) return null;\r\n const manager = context?.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager;\r\n return manager.getAdapter();\r\n }\r\n\r\n /**\r\n * 获取指定ID的设备如果存在\r\n */\r\n public getDevice(deviceId: string): BleDevice | null {\r\n\t __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/device_manager.uts:308',deviceId,this.devices)\r\n return this.devices.get(deviceId) ?? null;\r\n }\r\n}\r\n","import type { BleService, BleCharacteristic, BleDataReceivedCallback, BleCharacteristicProperties, WriteCharacteristicOptions, ByteArray } from '../interface.uts'\r\nimport BluetoothGatt from \"android.bluetooth.BluetoothGatt\";\r\nimport BluetoothGattService from \"android.bluetooth.BluetoothGattService\";\r\nimport BluetoothGattCharacteristic from \"android.bluetooth.BluetoothGattCharacteristic\";\r\nimport BluetoothGattDescriptor from \"android.bluetooth.BluetoothGattDescriptor\";\r\nimport BluetoothGattCallback from \"android.bluetooth.BluetoothGattCallback\";\r\n\r\nimport UUID from \"java.util.UUID\";\r\nimport { DeviceManager } from './device_manager.uts'\r\nimport { AkBleErrorImpl, AkBluetoothErrorCode } from '../unierror.uts'\r\nimport { AutoDiscoverAllResult } from '../interface.uts'\r\n\r\n\r\n\r\n\r\n// 补全UUID格式将短格式转换为标准格式\r\nfunction getFullUuid(shortUuid : string) : string {\r\n\treturn `0000${shortUuid}-0000-1000-8000-00805f9b34fb`\r\n}\r\n\r\n\r\nconst deviceWriteQueues = new Map<string, Promise<void>>();\r\n\r\nfunction enqueueDeviceWrite<T>(deviceId : string, work : () => Promise<T>) : Promise<T> {\r\n\tconst previous = deviceWriteQueues.get(deviceId) ?? Promise.resolve();\r\n\tconst next = (async () : Promise<T> => {\r\n\t\ttry {\r\n\t\t\tawait previous;\r\n\t\t} catch (e) { /* ignore previous rejection to keep queue alive */ }\r\n\t\treturn await work();\r\n\t})();\r\n\tconst queued = next.then(() => { }, () => { });\r\n\tdeviceWriteQueues.set(deviceId, queued);\r\n\treturn next.finally(() => {\r\n\t\tif (deviceWriteQueues.get(deviceId) == queued) {\r\n\t\t\tdeviceWriteQueues.delete(deviceId);\r\n\t\t}\r\n\t});\r\n}\r\n\r\n\r\n\r\nfunction createCharProperties(props : number) : BleCharacteristicProperties {\r\n\tconst result : BleCharacteristicProperties = {\r\n\t\tread: false,\r\n\t\twrite: false,\r\n\t\tnotify: false,\r\n\t\tindicate: false,\r\n\t\tcanRead: false,\r\n\t\tcanWrite: false,\r\n\t\tcanNotify: false,\r\n\t\twriteWithoutResponse: false\r\n\t};\r\n\tresult.read = (props & BluetoothGattCharacteristic.PROPERTY_READ) !== 0;\r\n\tresult.write = (props & BluetoothGattCharacteristic.PROPERTY_WRITE) !== 0;\r\n\tresult.notify = (props & BluetoothGattCharacteristic.PROPERTY_NOTIFY) !== 0;\r\n\tresult.indicate = (props & BluetoothGattCharacteristic.PROPERTY_INDICATE) !== 0;\r\n\tresult.writeWithoutResponse = (props & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) !== 0;\r\n\r\n\tresult.canRead = result.read;\r\n\tconst writeWithoutResponse = result.writeWithoutResponse;\r\n\tresult.canWrite = (result.write != null && result.write) || (writeWithoutResponse != null && writeWithoutResponse);\r\n\tresult.canNotify = result.notify;\r\n\treturn result;\r\n}\r\n\r\n// 定义 PendingCallback 类型和实现类\r\ninterface PendingCallback {\r\n\tresolve : (data : any) => void;\r\n\treject : (err ?: any) => void;\r\n\ttimer ?: number; // Changed from any to number\r\n}\r\n\r\nclass PendingCallbackImpl implements PendingCallback {\r\n\tresolve : (data : any) => void;\r\n\treject : (err ?: any) => void;\r\n\ttimer ?: number; // Changed from any to number\r\n\r\n\tconstructor(resolve : (data : any) => void, reject : (err ?: any) => void, timer ?: number) {\r\n\t\tthis.resolve = resolve;\r\n\t\tthis.reject = reject;\r\n\t\tthis.timer = timer;\r\n\t}\r\n}\r\n\r\n// 全局回调管理(必须在类外部声明)\r\nlet pendingCallbacks : Map<string, PendingCallback>;\r\nlet notifyCallbacks : Map<string, BleDataReceivedCallback>;\r\n\r\n// 在全局范围内初始化\r\npendingCallbacks = new Map<string, PendingCallback>();\r\nnotifyCallbacks = new Map<string, BleDataReceivedCallback>();\r\n\r\n// 服务发现等待队列deviceId -> 回调数组\r\nconst serviceDiscoveryWaiters = new Map<string, ((services : BleService[] | null, error ?: Error) => void)[]>();\r\n// 服务发现状态deviceId -> 是否已发现\r\nconst serviceDiscovered = new Map<string, boolean>();\r\n\r\n// 特征发现等待队列deviceId|serviceId -> 回调数组\r\nconst characteristicDiscoveryWaiters = new Map<string, ((characteristics : BleCharacteristic[] | null, error ?: Error) => void)[]>();\r\n\r\nclass GattCallback extends BluetoothGattCallback {\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\toverride onServicesDiscovered(gatt : BluetoothGatt, status : Int) : void {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:108','ak onServicesDiscovered')\r\n\t\tconst deviceId = gatt.getDevice().getAddress();\r\n\t\tif (status == BluetoothGatt.GATT_SUCCESS) {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:111',`服务发现成功: ${deviceId}`);\r\n\t\t\tserviceDiscovered.set(deviceId, true);\r\n\t\t\t// 统一回调所有等待 getServices 的调用\r\n\t\t\tconst waiters = serviceDiscoveryWaiters.get(deviceId);\r\n\t\t\tif (waiters != null && waiters.length > 0) {\r\n\t\t\t\tconst services = gatt.getServices();\r\n\t\t\t\tconst result : BleService[] = [];\r\n\t\t\t\tif (services != null) {\r\n\t\t\t\t\tconst servicesList = services;\r\n\t\t\t\t\tconst size = servicesList.size;\r\n\t\t\t\t\tfor (let i = 0; i < size; i++) {\r\n\t\tconst service = servicesList.get(i as Int);\r\n\t\t\t\t\t\tif (service != null) {\r\n\t\t\t\t\t\t\tconst bleService : BleService = {\r\n\t\t\t\t\t\t\t\tuuid: service.getUuid().toString(),\r\n\t\t\t\t\t\t\t\tisPrimary: service.getType() == BluetoothGattService.SERVICE_TYPE_PRIMARY\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t\tresult.push(bleService);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tfor (let i = 0; i < waiters.length; i++) {\r\n\t\t\t\t\tconst cb = waiters[i];\r\n\t\t\t\t\tif (cb != null) { cb(result, null); }\r\n\t\t\t\t}\r\n\t\t\t\tserviceDiscoveryWaiters.delete(deviceId);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:139',`服务发现失败: ${deviceId}, status: ${status}`);\r\n\t\t\t// 失败时也要通知等待队列\r\n\t\t\tconst waiters = serviceDiscoveryWaiters.get(deviceId);\r\n\t\t\tif (waiters != null && waiters.length > 0) {\r\n\t\t\t\tfor (let i = 0; i < waiters.length; i++) {\r\n\t\t\t\t\tconst cb = waiters[i];\r\n\t\t\t\t\tif (cb != null) { cb(null, new Error('服务发现失败')); }\r\n\t\t\t\t}\r\n\t\t\t\tserviceDiscoveryWaiters.delete(deviceId);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\toverride onConnectionStateChange(gatt : BluetoothGatt, status : Int, newState : Int) : void {\r\n\t\tconst deviceId = gatt.getDevice().getAddress();\r\n\tif (newState == BluetoothGatt.STATE_CONNECTED) {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:154',`设备已连接: ${deviceId}`);\r\n\t\t\tDeviceManager.handleConnectionStateChange(deviceId, 2, null); // 2 = STATE_CONNECTED\r\n\t} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:157',`设备已断开: ${deviceId}`);\r\n\t\t\tserviceDiscovered.delete(deviceId);\r\n\t\t\tDeviceManager.handleConnectionStateChange(deviceId, 0, null); // 0 = STATE_DISCONNECTED\r\n\t\t}\r\n\t}\r\n\t\toverride onCharacteristicChanged(gatt : BluetoothGatt, characteristic : BluetoothGattCharacteristic) : void {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:163','ak onCharacteristicChanged')\r\n\t\tconst deviceId = gatt.getDevice().getAddress();\r\n\t\tconst serviceId = characteristic.getService().getUuid().toString();\r\n\t\tconst charId = characteristic.getUuid().toString();\r\n\t\tconst key = `${deviceId}|${serviceId}|${charId}|notify`;\r\n\t\tconst callback = notifyCallbacks.get(key);\r\n\t\tconst value = characteristic.getValue();\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:170','[onCharacteristicChanged]', key, value);\r\n\t\tif (callback != null && value != null) {\r\n\t\t\tconst valueLength = value.size;\r\n\t\t\tconst arr = new Uint8Array(valueLength);\r\n\t\t\tfor (let i = 0 as Int; i < valueLength; i++) {\r\n\t\t\t\tconst v = value[i as Int];\r\n\t\t\t\tarr[i] = v != null ? v : 0;\r\n\t\t\t}\r\n\t\t\t// 保存接收日志\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:179',`\r\n INSERT INTO ble_data_log (device_id, service_id, char_id, direction, data, timestamp)\r\n VALUES ('${deviceId}', '${serviceId}', '${charId}', 'recv', '${Array.from(arr).join(',')}', ${Date.now()})\r\n `)\r\n\r\n\t\t\tcallback(arr);\r\n\t\t}\r\n\t}\r\n\t\toverride onCharacteristicRead(gatt : BluetoothGatt, characteristic : BluetoothGattCharacteristic, status : Int) : void {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:188','ak onCharacteristicRead', status)\r\n\t\tconst deviceId = gatt.getDevice().getAddress();\r\n\t\tconst serviceId = characteristic.getService().getUuid().toString();\r\n\t\tconst charId = characteristic.getUuid().toString();\r\n\t\tconst key = `${deviceId}|${serviceId}|${charId}|read`;\r\n\t\tconst pending = pendingCallbacks.get(key);\r\n\t\tconst value = characteristic.getValue();\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:195','[onCharacteristicRead]', key, 'status=', status, 'value=', value);\r\n\t\tif (pending != null) {\r\n\t\t\ttry {\r\n\t\t\t\tconst timer = pending.timer;\r\n\t\t\t\tif (timer != null) {\r\n\t\t\t\t\tclearTimeout(timer);\r\n\t\t\t\t\tpending.timer = null;\r\n\t\t\t\t}\r\n\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\tif (status == BluetoothGatt.GATT_SUCCESS && value != null) {\r\n\t\t\t\t\tconst valueLength = value.size\r\n\t\t\t\t\tconst arr = new Uint8Array(valueLength);\r\n\t\t\t\t\tfor (let i = 0 as Int; i < valueLength; i++) {\r\n\t\t\t\t\t\tconst v = value[i as Int];\r\n\t\t\t\t\t\tarr[i] = v != null ? v : 0;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// resolve with ArrayBuffer\r\n\t\t\t\t\tpending.resolve(arr.buffer as ArrayBuffer);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tpending.reject(new Error('Characteristic read failed'));\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\ttry { pending.reject(e); } catch (e2) { __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:218',e2); }\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\toverride onCharacteristicWrite(gatt : BluetoothGatt, characteristic : BluetoothGattCharacteristic, status : Int) : void {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:224','ak onCharacteristicWrite', status)\r\n\t\tconst deviceId = gatt.getDevice().getAddress();\r\n\t\tconst serviceId = characteristic.getService().getUuid().toString();\r\n\t\tconst charId = characteristic.getUuid().toString();\r\n\t\tconst key = `${deviceId}|${serviceId}|${charId}|write`;\r\n\t\tconst pending = pendingCallbacks.get(key);\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:230','[onCharacteristicWrite]', key, 'status=', status);\r\n\t\tif (pending != null) {\r\n\t\t\ttry {\r\n\t\t\t\tconst timer = pending.timer;\r\n\t\t\t\tif (timer != null) {\r\n\t\t\t\t\tclearTimeout(timer);\r\n\t\t\t\t}\r\n\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\tif (status == BluetoothGatt.GATT_SUCCESS) {\r\n\t\t\t\t\tpending.resolve('ok');\r\n\t\t\t\t} else {\r\n\t\t\t\t\tpending.reject(new Error('Characteristic write failed'));\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\ttry { pending.reject(e); } catch (e2) { __f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:244',e2); }\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// 导出单例实例供外部使用\r\nexport const gattCallback = new GattCallback();\r\n\r\nexport class ServiceManager {\r\n\tprivate static instance : ServiceManager | null = null;\r\n\tprivate services = new Map<string, BleService[]>();\r\n\tprivate characteristics = new Map<string, Map<string, BleCharacteristic[]>>();\r\n\tprivate deviceManager = DeviceManager.getInstance();\r\n\tprivate constructor() { }\r\n\tstatic getInstance() : ServiceManager {\r\n\t\tif (ServiceManager.instance == null) {\r\n\t\t\tServiceManager.instance = new ServiceManager();\r\n\t\t}\r\n\t\treturn ServiceManager.instance!;\r\n\t}\r\n\r\n\tgetServices(deviceId : string, callback ?: (services : BleService[] | null, error ?: Error) => void) : any | Promise<BleService[]> {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:267','ak start getservice', deviceId);\r\n\t\tconst gatt = this.deviceManager.getGattInstance(deviceId);\r\n\t\tif (gatt == null) {\r\n\t\t\tif (callback != null) { callback(null, new AkBleErrorImpl(AkBluetoothErrorCode.DeviceNotFound, \"Device not found\", \"\")); }\r\n\t\t\treturn Promise.reject(new AkBleErrorImpl(AkBluetoothErrorCode.DeviceNotFound, \"Device not found\", \"\"));\r\n\t\t}\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:273','ak serviceDiscovered', gatt)\r\n\t\t// 如果服务已发现,直接返回\r\n\t\tif (serviceDiscovered.get(deviceId) == true) {\r\n\t\t\tconst services = gatt.getServices();\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:277',services)\r\n\t\t\tconst result : BleService[] = [];\r\n\t\t\tif (services != null) {\r\n\t\t\t\tconst servicesList = services;\r\n\t\t\t\tconst size = servicesList.size;\r\n\t\t\t\tif (size > 0) {\r\n\t\t\tfor (let i = 0 as Int; i < size; i++) {\r\n\t\t\t\tconst service = servicesList != null ? servicesList.get(i) : servicesList[i];\r\n\t\t\t\t\t\tif (service != null) {\r\n\t\t\t\t\t\t\tconst bleService : BleService = {\r\n\t\t\t\t\t\t\t\tuuid: service.getUuid().toString(),\r\n\t\t\t\t\t\t\t\tisPrimary: service.getType() == BluetoothGattService.SERVICE_TYPE_PRIMARY\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t\tresult.push(bleService);\r\n\r\n\t\t\t\t\t\t\tif (bleService.uuid == getFullUuid('0001')) {\r\n\t\t\t\t\t\t\t\tconst device = this.deviceManager.getDevice(deviceId);\r\n\t\t\t\t\t\t\t\tif (device != null) {\r\n\t\t\t\t\t\t\t\t\tdevice.serviceId = bleService.uuid;\r\n\t\t\t\t\t\t\t\t\tthis.getCharacteristics(deviceId, device.serviceId, (chars, err) => {\r\n\t\t\t\t\t\t\t\t\t\tif (err == null && chars != null) {\r\n\t\t\t\t\t\t\t\t\t\t\tconst writeChar = chars.find(c => c.uuid == getFullUuid('0010'));\r\n\t\t\t\t\t\t\t\t\t\t\tconst notifyChar = chars.find(c => c.uuid == getFullUuid('0011'));\r\n\t\t\t\t\t\t\t\t\t\t\tif (writeChar != null) device.writeCharId = writeChar.uuid;\r\n\t\t\t\t\t\t\t\t\t\t\tif (notifyChar != null) device.notifyCharId = notifyChar.uuid;\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (callback != null) { callback(result, null); }\r\n\t\t\treturn Promise.resolve(result);\r\n\t\t}\r\n\t\t// 未发现则发起服务发现并加入等待队列\r\n\t\tif (!serviceDiscoveryWaiters.has(deviceId)) {\r\n\t\t\tserviceDiscoveryWaiters.set(deviceId, []);\r\n\t\t\tgatt.discoverServices();\r\n\t\t}\r\n\t\treturn new Promise<BleService[]>((resolve, reject) => {\r\n\t\t\tconst cb = (services : BleService[] | null, error ?: Error) => {\r\n\t\t\t\tif (error != null) reject(error);\r\n\t\t\t\telse resolve(services ?? []);\r\n\t\t\t\tif (callback != null) callback(services, error);\r\n\t\t\t};\r\n\t\t\tconst arr = serviceDiscoveryWaiters.get(deviceId);\r\n\t\t\tif (arr != null) arr.push(cb);\r\n\t\t});\r\n\t}\r\n\tgetCharacteristics(deviceId : string, serviceId : string, callback : (characteristics : BleCharacteristic[] | null, error ?: Error) => void) : void {\r\n\t\tconst gatt = this.deviceManager.getGattInstance(deviceId);\r\n\t\tif (gatt == null) return callback(null, new AkBleErrorImpl(AkBluetoothErrorCode.DeviceNotFound, \"Device not found\", \"\"));\r\n\t\t// 如果服务还没发现,等待服务发现后再查特征\r\n\t\tif (serviceDiscovered.get(deviceId) !== true) {\r\n\t\t\t// 先注册到服务发现等待队列\r\n\t\t\tthis.getServices(deviceId, (services, err) => {\r\n\t\t\t\tif (err != null) {\r\n\t\t\t\t\tcallback(null, err);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.getCharacteristics(deviceId, serviceId, callback);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// 服务已发现,正常获取特征\r\n\t\tconst service = gatt.getService(UUID.fromString(serviceId));\r\n\t\tif (service == null) return callback(null, new AkBleErrorImpl(AkBluetoothErrorCode.ServiceNotFound, \"Service not found\", \"\"));\r\n\t\tconst chars = service.getCharacteristics();\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:347',chars)\r\n\t\tconst result : BleCharacteristic[] = [];\r\n\t\tif (chars != null) {\r\n\t\t\tconst characteristicsList = chars;\r\n\t\t\tconst size = characteristicsList.size;\r\n\t\t\tconst bleService : BleService = {\r\n\t\t\t\tuuid: serviceId,\r\n\t\t\t\tisPrimary: service.getType() == BluetoothGattService.SERVICE_TYPE_PRIMARY\r\n\t\t\t};\r\n\t\t\tfor (let i = 0 as Int; i < size; i++) {\r\n\t\t\t\tconst char = characteristicsList != null ? characteristicsList.get(i as Int) : characteristicsList[i];\r\n\t\t\t\tif (char != null) {\r\n\t\t\t\t\tconst props = char.getProperties();\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst charUuid = char.getUuid() != null ? char.getUuid().toString() : '';\r\n\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:362','[ServiceManager] characteristic uuid=', charUuid);\r\n\t\t\t\t\t} catch (e) { __f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:363','[ServiceManager] failed to read char uuid', e); }\r\n\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:364',props);\r\n\t\t\t\t\tconst bleCharacteristic : BleCharacteristic = {\r\n\t\t\t\t\t\tuuid: char.getUuid().toString(),\r\n\t\t\t\t\t\tservice: bleService,\r\n\t\t\t\t\t\tproperties: createCharProperties(props)\r\n\t\t\t\t\t};\r\n\t\t\t\t\tresult.push(bleCharacteristic);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tcallback(result, null);\r\n\t}\r\n\r\n\tpublic async readCharacteristic(deviceId : string, serviceId : string, characteristicId : string) : Promise<ArrayBuffer> {\r\n\t\tconst gatt = this.deviceManager.getGattInstance(deviceId);\r\n\t\tif (gatt == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.DeviceNotFound, \"Device not found\", \"\");\r\n\t\tconst service = gatt.getService(UUID.fromString(serviceId));\r\n\t\tif (service == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.ServiceNotFound, \"Service not found\", \"\");\r\n\t\tconst char = service.getCharacteristic(UUID.fromString(characteristicId));\r\n\t\tif (char == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.CharacteristicNotFound, \"Characteristic not found\", \"\");\r\n\t\tconst key = `${deviceId}|${serviceId}|${characteristicId}|read`;\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:385',key)\r\n\t\treturn new Promise<ArrayBuffer>((resolve, reject) => {\r\n\t\t\tconst timer = setTimeout(() => {\r\n\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\treject(new AkBleErrorImpl(AkBluetoothErrorCode.ConnectionTimeout, \"Connection timeout\", \"\"));\r\n\t\t\t}, 5000);\r\n\t\t\tconst resolveAdapter = (data : any) => { __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:391','read resolve:', data); resolve(data as ArrayBuffer); };\r\n\t\t\tconst rejectAdapter = (err ?: any) => { reject(new AkBleErrorImpl(AkBluetoothErrorCode.UnknownError, \"Unknown error occurred\", \"\")); };\r\n\t\t\tpendingCallbacks.set(key, new PendingCallbackImpl(resolveAdapter, rejectAdapter, timer));\r\n\t\t\tif (gatt.readCharacteristic(char) == false) {\r\n\t\t\t\tclearTimeout(timer);\r\n\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\treject(new AkBleErrorImpl(AkBluetoothErrorCode.UnknownError, \"Unknown error occurred\", \"\"));\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:400','read should be succeed', key)\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tpublic async writeCharacteristic(deviceId : string, serviceId : string, characteristicId : string, data : Uint8Array, options ?: WriteCharacteristicOptions) : Promise<boolean> {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:406','[writeCharacteristic] deviceId:', deviceId, 'serviceId:', serviceId, 'characteristicId:', characteristicId, 'data:', data);\r\n\t\tconst gatt = this.deviceManager.getGattInstance(deviceId);\r\n\t\tif (gatt == null) {\r\n\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:409','[writeCharacteristic] gatt is null');\r\n\t\t\tthrow new AkBleErrorImpl(AkBluetoothErrorCode.DeviceNotFound, \"Device not found\", \"\");\r\n\t\t}\r\n\t\tconst service = gatt.getService(UUID.fromString(serviceId));\r\n\t\tif (service == null) {\r\n\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:414','[writeCharacteristic] service is null');\r\n\t\t\tthrow new AkBleErrorImpl(AkBluetoothErrorCode.ServiceNotFound, \"Service not found\", \"\");\r\n\t\t}\r\n\t\tconst char = service.getCharacteristic(UUID.fromString(characteristicId));\r\n\t\tif (char == null) {\r\n\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:419','[writeCharacteristic] characteristic is null');\r\n\t\t\tthrow new AkBleErrorImpl(AkBluetoothErrorCode.CharacteristicNotFound, \"Characteristic not found\", \"\");\r\n\t\t}\r\n\t\tconst key = `${deviceId}|${serviceId}|${characteristicId}|write`;\r\n\t\tconst wantsNoResponse = options != null && options.waitForResponse == false;\r\n\t\tlet retryMaxAttempts = 20;\r\n\t\tlet retryDelay = 100;\r\n\t\tlet giveupTimeout = 20000;\r\n\t\tif (options != null) {\r\n\t\t\ttry {\r\n\t\t\t\tif (options.maxAttempts != null) {\r\n\t\t\t\t\tconst parsedAttempts = Math.floor(options.maxAttempts as number);\r\n\t\t\t\t\tif (!isNaN(parsedAttempts) && parsedAttempts > 0) retryMaxAttempts = parsedAttempts;\r\n\t\t\t\t}\r\n\t\t\t} catch (e) { }\r\n\t\t\ttry {\r\n\t\t\t\tif (options.retryDelayMs != null) {\r\n\t\t\t\t\tconst parsedDelay = Math.floor(options.retryDelayMs as number);\r\n\t\t\t\t\tif (!isNaN(parsedDelay) && parsedDelay >= 0) retryDelay = parsedDelay;\r\n\t\t\t\t}\r\n\t\t\t} catch (e) { }\r\n\t\t\ttry {\r\n\t\t\t\tif (options.giveupTimeoutMs != null) {\r\n\t\t\t\t\tconst parsedGiveup = Math.floor(options.giveupTimeoutMs as number);\r\n\t\t\t\t\tif (!isNaN(parsedGiveup) && parsedGiveup > 0) giveupTimeout = parsedGiveup;\r\n\t\t\t\t}\r\n\t\t\t} catch (e) { }\r\n\t\t}\r\n\t\tconst gattInstance = gatt;\r\n\t\tconst executeWrite = () : Promise<boolean> => {\r\n\r\n\t\t\treturn new Promise<boolean>((resolve) => {\r\n\t\t\t\tconst initialTimeout = Math.max(giveupTimeout + 5000, 10000);\r\n\t\t\t\tlet timer = setTimeout(() => {\r\n\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:454','[writeCharacteristic] timeout');\r\n\t\t\t\t\tresolve(false);\r\n\t\t\t\t}, initialTimeout);\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:457','[writeCharacteristic] initial timeout set to', initialTimeout, 'ms for', key);\r\n\t\t\t\tconst resolveAdapter = (data : any) => {\r\n\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:459','[writeCharacteristic] resolveAdapter called');\r\n\t\t\t\t\tresolve(true);\r\n\t\t\t\t};\r\n\t\t\t\tconst rejectAdapter = (err ?: any) => {\r\n\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:463','[writeCharacteristic] rejectAdapter called', err);\r\n\t\t\t\t\tresolve(false);\r\n\t\t\t\t};\r\n\t\t\t\tpendingCallbacks.set(key, new PendingCallbackImpl(resolveAdapter, rejectAdapter, timer));\r\n\t\t\t\tconst byteArray = new ByteArray(data.length as Int);\r\n\t\t\t\tfor (let i = 0 as Int; i < data.length; i++) {\r\n\t\t\t\t\tbyteArray[i] = data[i].toByte();\r\n\t\t\t\t}\r\n\t\t\t\tconst forceWriteTypeNoResponse = options != null && options.forceWriteTypeNoResponse == true;\r\n\t\t\t\tlet usesNoResponse = forceWriteTypeNoResponse || wantsNoResponse;\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst props = char.getProperties();\r\n\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:475','[writeCharacteristic] characteristic properties mask=', props);\r\n\t\t\t\t\tif (usesNoResponse == false) {\r\n\t\t\t\t\t\tconst supportsWriteWithResponse = (props & BluetoothGattCharacteristic.PROPERTY_WRITE) !== 0;\r\n\t\t\t\t\t\tconst supportsWriteNoResponse = (props & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) !== 0;\r\n\t\t\t\t\t\tif (supportsWriteWithResponse == false && supportsWriteNoResponse == true) {\r\n\t\t\t\t\t\t\tusesNoResponse = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (usesNoResponse) {\r\n\t\t\t\t\t\ttry { char.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); } catch (e) { }\r\n\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:485','[writeCharacteristic] using WRITE_TYPE_NO_RESPONSE');\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\ttry { char.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); } catch (e) { }\r\n\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:488','[writeCharacteristic] using WRITE_TYPE_DEFAULT');\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:491','[writeCharacteristic] failed to inspect/set write type', e);\r\n\t\t\t\t}\r\n\t\t\t\tconst maxAttempts = retryMaxAttempts;\r\n\t\t\t\tfunction attemptWrite(att : Int) : void {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tlet setOk = true;\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tconst setRes = char.setValue(byteArray);\r\n\t\t\t\t\t\t\tif (typeof setRes == 'boolean' && setRes == false) {\r\n\t\t\t\t\t\t\t\tsetOk = false;\r\n\t\t\t\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:501','[writeCharacteristic] setValue returned false for', key, 'attempt', att);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\t\tsetOk = false;\r\n\t\t\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:505','[writeCharacteristic] setValue threw for', key, 'attempt', att, e);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (setOk == false) {\r\n\t\t\t\t\t\t\tif (att >= maxAttempts) {\r\n\t\t\t\t\t\t\t\ttry { clearTimeout(timer); } catch (e) { }\r\n\t\t\t\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t\t\t\tresolve(false);\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tsetTimeout(() => { attemptWrite((att + 1) as Int); }, retryDelay);\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:518','[writeCharacteristic] attempt', att, 'calling gatt.writeCharacteristic');\r\n\t\t\t\t\t\t\tconst r = gattInstance.writeCharacteristic(char);\r\n\t\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:520','[writeCharacteristic] attempt', att, 'result=', r);\r\n\t\t\t\t\t\t\tif (r == true) {\r\n\t\t\t\t\t\t\t\tif (usesNoResponse) {\r\n\t\t\t\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:523','[writeCharacteristic] WRITE_TYPE_NO_RESPONSE success for', key);\r\n\t\t\t\t\t\t\t\t\ttry { clearTimeout(timer); } catch (e) { }\r\n\t\t\t\t\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t\t\t\t\tresolve(true);\r\n\t\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\ttry { clearTimeout(timer); } catch (e) { }\r\n\t\t\t\t\t\t\t\tconst extra = 20000;\r\n\t\t\t\t\t\t\t\ttimer = setTimeout(() => {\r\n\t\t\t\t\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:533','[writeCharacteristic] timeout after write initiated');\r\n\t\t\t\t\t\t\t\t\tresolve(false);\r\n\t\t\t\t\t\t\t\t}, extra);\r\n\t\t\t\t\t\t\t\tconst pendingEntry = pendingCallbacks.get(key);\r\n\t\t\t\t\t\t\t\tif (pendingEntry != null) pendingEntry.timer = timer;\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:541','[writeCharacteristic] attempt', att, 'exception when calling writeCharacteristic', e);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (att < maxAttempts) {\r\n\t\t\t\t\t\t\tconst nextAtt = (att + 1) as Int;\r\n\t\t\t\t\t\t\tsetTimeout(() => { attemptWrite(nextAtt); }, retryDelay);\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (usesNoResponse) {\r\n\t\t\t\t\t\t\ttry { clearTimeout(timer); } catch (e) { }\r\n\t\t\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:551','[writeCharacteristic] all attempts failed with WRITE_NO_RESPONSE for', key);\r\n\t\t\t\t\t\t\tresolve(false);\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\ttry { clearTimeout(timer); } catch (e) { }\r\n\t\t\t\t\t\tconst giveupTimeoutLocal = giveupTimeout;\r\n\t\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:557','[writeCharacteristic] all attempts failed; waiting for late callback up to', giveupTimeoutLocal, 'ms for', key);\r\n\t\t\t\t\t\tconst giveupTimer = setTimeout(() => {\r\n\t\t\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:560','[writeCharacteristic] giveup timeout expired for', key);\r\n\t\t\t\t\t\t\tresolve(false);\r\n\t\t\t\t\t\t}, giveupTimeoutLocal);\r\n\t\t\t\t\t\tconst pendingEntryAfter = pendingCallbacks.get(key);\r\n\t\t\t\t\t\tif (pendingEntryAfter != null) pendingEntryAfter.timer = giveupTimer;\r\n\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\tclearTimeout(timer);\r\n\t\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:568','[writeCharacteristic] Exception in attemptWrite', e);\r\n\t\t\t\t\t\tresolve(false);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttry {\r\n\t\t\t\t\tattemptWrite(1 as Int);\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tclearTimeout(timer);\r\n\t\t\t\t\tpendingCallbacks.delete(key);\r\n\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:578','[writeCharacteristic] Exception before attempting write', e);\r\n\t\t\t\t\tresolve(false);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t};\r\n\t\treturn enqueueDeviceWrite(deviceId, executeWrite);\r\n\t}\r\n\r\n\tpublic async subscribeCharacteristic(deviceId : string, serviceId : string, characteristicId : string, onData : BleDataReceivedCallback) : Promise<void> {\r\n\t\tconst gatt = this.deviceManager.getGattInstance(deviceId);\r\n\t\tif (gatt == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.DeviceNotFound, \"Device not found\", \"\");\r\n\t\tconst service = gatt.getService(UUID.fromString(serviceId));\r\n\t\tif (service == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.ServiceNotFound, \"Service not found\", \"\");\r\n\t\tconst char = service.getCharacteristic(UUID.fromString(characteristicId));\r\n\t\tif (char == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.CharacteristicNotFound, \"Characteristic not found\", \"\");\r\n\t\tconst key = `${deviceId}|${serviceId}|${characteristicId}|notify`;\r\n\t\tnotifyCallbacks.set(key, onData);\r\n\t\tif (gatt.setCharacteristicNotification(char, true) == false) {\r\n\t\t\tnotifyCallbacks.delete(key);\r\n\t\t\tthrow new AkBleErrorImpl(AkBluetoothErrorCode.UnknownError, \"Failed to unsubscribe characteristic\", \"\");\r\n\t\t} else {\r\n\t\t\t// 写入 CCCD 描述符,启用 notify\r\n\t\t\tconst descriptor = char.getDescriptor(UUID.fromString(\"00002902-0000-1000-8000-00805f9b34fb\"));\r\n\t\t\tif (descriptor != null) {\r\n\t\t\t\t// 设置描述符值\r\n\t\t\t\tconst value =\r\n\t\t\t\t\tBluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;\r\n\r\n\t\t\t\tdescriptor.setValue(value);\r\n\t\t\t\tconst writedescript = gatt.writeDescriptor(descriptor);\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:608','subscribeCharacteristic: CCCD written for notify', writedescript);\r\n\t\t\t} else {\r\n\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:610','subscribeCharacteristic: CCCD descriptor not found!');\r\n\t\t\t}\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:612','subscribeCharacteristic ok!!');\r\n\t\t}\r\n\t}\r\n\r\n\tpublic async unsubscribeCharacteristic(deviceId : string, serviceId : string, characteristicId : string) : Promise<void> {\r\n\t\tconst gatt = this.deviceManager.getGattInstance(deviceId);\r\n\t\tif (gatt == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.DeviceNotFound, \"Device not found\", \"\");\r\n\t\tconst service = gatt.getService(UUID.fromString(serviceId));\r\n\t\tif (service == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.ServiceNotFound, \"Service not found\", \"\");\r\n\t\tconst char = service.getCharacteristic(UUID.fromString(characteristicId));\r\n\t\tif (char == null) throw new AkBleErrorImpl(AkBluetoothErrorCode.CharacteristicNotFound, \"Characteristic not found\", \"\");\r\n\t\tconst key = `${deviceId}|${serviceId}|${characteristicId}|notify`;\r\n\t\tnotifyCallbacks.delete(key);\r\n\t\tif (gatt.setCharacteristicNotification(char, false) == false) {\r\n\t\t\tthrow new AkBleErrorImpl(AkBluetoothErrorCode.UnknownError, \"Failed to unsubscribe characteristic\", \"\");\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t// 自动发现所有服务和特征\r\n\tpublic async autoDiscoverAll(deviceId : string) : Promise<AutoDiscoverAllResult> {\r\n\t\tconst services = await this.getServices(deviceId, null) as BleService[];\r\n\t\tconst allCharacteristics : BleCharacteristic[] = [];\r\n\t\tfor (const service of services) {\r\n\t\t\tawait new Promise<void>((resolve, reject) => {\r\n\t\t\t\tthis.getCharacteristics(deviceId, service.uuid, (chars, err) => {\r\n\t\t\t\t\tif (err != null) reject(err);\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tif (chars != null) allCharacteristics.push(...chars);\r\n\t\t\t\t\t\tresolve();\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\t\treturn { services, characteristics: allCharacteristics };\r\n\t}\r\n\r\n\t// 自动订阅所有支持 notify/indicate 的特征\r\n\tpublic async subscribeAllNotifications(deviceId : string, onData : BleDataReceivedCallback) : Promise<void> {\r\n\t\tconst { services, characteristics } = await this.autoDiscoverAll(deviceId);\r\n\t\tfor (const char of characteristics) {\r\n\t\t\tif (char.properties.notify || char.properties.indicate) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait this.subscribeCharacteristic(deviceId, char.service.uuid, char.uuid, onData);\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\t// 可以选择忽略单个特征订阅失败\r\n\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/service_manager.uts:658',`订阅特征 ${char.uuid} 失败:`, e);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}","/// <reference types=\"@dcloudio/uni-app-x/types/uni/global\" />\n// 之所以又写了一份是因为外层的socketconnectSocket的时候必须传入multiple:true\n// 但是android又不能传入目前代码里又不能写条件编译之类的。\nexport function initRuntimeSocket(\n hosts: string,\n port: string,\n id: string\n): Promise<SocketTask | null> {\n if (hosts == '' || port == '' || id == '') return Promise.resolve(null)\n return hosts\n .split(',')\n .reduce<Promise<SocketTask | null>>(\n (\n promise: Promise<SocketTask | null>,\n host: string\n ): Promise<SocketTask | null> => {\n return promise.then((socket): Promise<SocketTask | null> => {\n if (socket != null) return Promise.resolve(socket)\n return tryConnectSocket(host, port, id)\n })\n },\n Promise.resolve(null)\n )\n}\n\nconst SOCKET_TIMEOUT = 500\nfunction tryConnectSocket(\n host: string,\n port: string,\n id: string\n): Promise<SocketTask | null> {\n return new Promise((resolve, reject) => {\n const socket = uni.connectSocket({\n url: `ws://${host}:${port}/${id}`,\n fail() {\n resolve(null)\n },\n })\n const timer = setTimeout(() => {\n // @ts-expect-error\n socket.close({\n code: 1006,\n reason: 'connect timeout',\n } as CloseSocketOptions)\n resolve(null)\n }, SOCKET_TIMEOUT)\n\n socket.onOpen((e) => {\n clearTimeout(timer)\n resolve(socket)\n })\n socket.onClose((e) => {\n clearTimeout(timer)\n resolve(null)\n })\n socket.onError((e) => {\n clearTimeout(timer)\n resolve(null)\n })\n })\n}\n","<script lang=\"uts\">\r\n\r\n\t// import { initTables } from './ak/sqlite.uts'\r\n\t\r\n\r\n\r\nlet firstBackTime = 0\r\nexport default {\r\n\t\tonLaunch: function () {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t\t// initTables();\r\n\r\n\t\t},\r\n\t\tonShow: function () {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function () {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t},\r\n\r\n\t\tonLastPageBackPress: function () {\r\n\t\t\tconsole.log('App LastPageBackPress')\r\n\t\t\tif (firstBackTime == 0) {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: '再按一次退出应用',\r\n\t\t\t\t\tposition: 'bottom',\r\n\t\t\t\t})\r\n\t\t\t\tfirstBackTime = Date.now()\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\tfirstBackTime = 0\r\n\t\t\t\t}, 2000)\r\n\t\t\t} else if (Date.now() - firstBackTime < 2000) {\r\n\t\t\t\tfirstBackTime = Date.now()\r\n\t\t\t\tuni.exit()\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tonExit: function () {\r\n\t\t\tconsole.log('App Exit')\r\n\t\t},\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n\t.uni-row {\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.uni-column {\r\n\t\tflex-direction: column;\r\n\t}\r\n</style>","/**\r\n * PermissionManager.uts\r\n * \r\n * Utility class for managing Android permissions throughout the app\r\n * Handles requesting permissions, checking status, and directing users to settings\r\n */\r\n\r\n/**\r\n * Common permission types that can be requested\r\n */\r\nexport enum PermissionType {\r\n BLUETOOTH = 'bluetooth',\r\n LOCATION = 'location',\r\n STORAGE = 'storage',\r\n CAMERA = 'camera',\r\n MICROPHONE = 'microphone',\r\n NOTIFICATIONS = 'notifications',\r\n CALENDAR = 'calendar',\r\n CONTACTS = 'contacts',\r\n SENSORS = 'sensors'\r\n}\r\n\r\n/**\r\n * Result of a permission request\r\n */\r\ntype PermissionResult = {\r\n granted: boolean;\r\n grantedPermissions: string[];\r\n deniedPermissions: string[];\r\n}\r\n\r\n/**\r\n * Manages permission requests and checks throughout the app\r\n */\r\nexport class PermissionManager {\r\n /**\r\n * Maps permission types to the actual Android permission strings\r\n */\r\n private static getPermissionsForType(type: PermissionType): string[] {\r\n switch (type) {\r\n case PermissionType.BLUETOOTH:\r\n return [\r\n 'android.permission.BLUETOOTH_SCAN',\r\n 'android.permission.BLUETOOTH_CONNECT',\r\n 'android.permission.BLUETOOTH_ADVERTISE'\r\n ];\r\n case PermissionType.LOCATION:\r\n return [\r\n 'android.permission.ACCESS_FINE_LOCATION',\r\n 'android.permission.ACCESS_COARSE_LOCATION'\r\n ];\r\n case PermissionType.STORAGE:\r\n return [\r\n 'android.permission.READ_EXTERNAL_STORAGE',\r\n 'android.permission.WRITE_EXTERNAL_STORAGE'\r\n ];\r\n case PermissionType.CAMERA:\r\n return ['android.permission.CAMERA'];\r\n case PermissionType.MICROPHONE:\r\n return ['android.permission.RECORD_AUDIO'];\r\n case PermissionType.NOTIFICATIONS:\r\n return ['android.permission.POST_NOTIFICATIONS'];\r\n case PermissionType.CALENDAR:\r\n return [\r\n 'android.permission.READ_CALENDAR',\r\n 'android.permission.WRITE_CALENDAR'\r\n ];\r\n case PermissionType.CONTACTS:\r\n return [\r\n 'android.permission.READ_CONTACTS',\r\n 'android.permission.WRITE_CONTACTS'\r\n ];\r\n case PermissionType.SENSORS:\r\n return ['android.permission.BODY_SENSORS'];\r\n default:\r\n return [];\r\n }\r\n }\r\n \r\n /**\r\n * Get appropriate display name for a permission type\r\n */\r\n private static getPermissionDisplayName(type: PermissionType): string {\r\n switch (type) {\r\n case PermissionType.BLUETOOTH:\r\n return '蓝牙';\r\n case PermissionType.LOCATION:\r\n return '位置';\r\n case PermissionType.STORAGE:\r\n return '存储';\r\n case PermissionType.CAMERA:\r\n return '相机';\r\n case PermissionType.MICROPHONE:\r\n return '麦克风';\r\n case PermissionType.NOTIFICATIONS:\r\n return '通知';\r\n case PermissionType.CALENDAR:\r\n return '日历';\r\n case PermissionType.CONTACTS:\r\n return '联系人';\r\n case PermissionType.SENSORS:\r\n return '身体传感器';\r\n default:\r\n return '未知权限';\r\n }\r\n }\r\n \r\n /**\r\n * Check if a permission is granted\r\n * @param type The permission type to check\r\n * @returns True if the permission is granted, false otherwise\r\n */\r\n static isPermissionGranted(type: PermissionType): boolean {\r\n\r\n try {\r\n const permissions = this.getPermissionsForType(type);\r\n const activity = UTSAndroid.getUniActivity();\r\n \r\n if (activity == null || permissions.length === 0) {\r\n return false;\r\n }\r\n \r\n // Check each permission in the group\r\n for (const permission of permissions) {\r\n if (!UTSAndroid.checkSystemPermissionGranted(activity, [permission])) {\r\n return false;\r\n }\r\n }\r\n \r\n return true;\r\n } catch (e) {\r\n __f__('error','at ak/PermissionManager.uts:132',`Error checking ${type} permission:`, e);\r\n return false;\r\n }\r\n\r\n \r\n\r\n\r\n\r\n }\r\n \r\n /**\r\n * Request a permission from the user\r\n * @param type The permission type to request\r\n * @param callback Function to call with the result of the permission request\r\n * @param showRationale Whether to show a rationale dialog if permission was previously denied\r\n */\r\n static requestPermission(\r\n type: PermissionType,\r\n callback: (result: PermissionResult) => void,\r\n showRationale: boolean = true\r\n ): void {\r\n\r\n try {\r\n const permissions = this.getPermissionsForType(type);\r\n const activity = UTSAndroid.getUniActivity();\r\n \r\n if (activity == null || permissions.length === 0) {\r\n callback({\r\n granted: false,\r\n grantedPermissions: [],\r\n deniedPermissions: permissions\r\n });\r\n return;\r\n }\r\n \r\n // Check if already granted\r\n let allGranted = true;\r\n for (const permission of permissions) {\r\n if (!UTSAndroid.checkSystemPermissionGranted(activity, [permission])) {\r\n allGranted = false;\r\n break;\r\n }\r\n }\r\n \r\n if (allGranted) {\r\n callback({\r\n granted: true,\r\n grantedPermissions: permissions,\r\n deniedPermissions: []\r\n });\r\n return;\r\n }\r\n \r\n // Request the permissions\r\n UTSAndroid.requestSystemPermission(\r\n activity,\r\n permissions,\r\n (granted: boolean, grantedPermissions: string[]) => {\r\n if (granted) {\r\n callback({\r\n granted: true,\r\n grantedPermissions: grantedPermissions,\r\n deniedPermissions: []\r\n });\r\n } else if (showRationale) {\r\n // Show rationale dialog\r\n this.showPermissionRationale(type, callback);\r\n } else {\r\n // Just report the denial\r\n callback({\r\n granted: false,\r\n grantedPermissions: grantedPermissions,\r\n deniedPermissions: this.getDeniedPermissions(permissions, grantedPermissions)\r\n });\r\n }\r\n },\r\n (denied: boolean, deniedPermissions: string[]) => {\r\n callback({\r\n granted: false,\r\n grantedPermissions: this.getGrantedPermissions(permissions, deniedPermissions),\r\n deniedPermissions: deniedPermissions\r\n });\r\n }\r\n );\r\n } catch (e) {\r\n __f__('error','at ak/PermissionManager.uts:217',`Error requesting ${type} permission:`, e);\r\n callback({\r\n granted: false,\r\n grantedPermissions: [],\r\n deniedPermissions: this.getPermissionsForType(type)\r\n });\r\n }\r\n\r\n \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n }\r\n \r\n /**\r\n * Show a rationale dialog explaining why the permission is needed\r\n */\r\n private static showPermissionRationale(\r\n type: PermissionType,\r\n callback: (result: PermissionResult) => void\r\n ): void {\r\n const permissionName = this.getPermissionDisplayName(type);\r\n \r\n uni.showModal({\r\n title: '权限申请',\r\n content: `需要${permissionName}权限才能使用相关功能`,\r\n confirmText: '去设置',\r\n cancelText: '取消',\r\n success: (result) => {\r\n if (result.confirm) {\r\n this.openAppSettings();\r\n callback({\r\n granted: false,\r\n grantedPermissions: [],\r\n deniedPermissions: this.getPermissionsForType(type)\r\n });\r\n } else {\r\n callback({\r\n granted: false,\r\n grantedPermissions: [],\r\n deniedPermissions: this.getPermissionsForType(type)\r\n });\r\n }\r\n }\r\n });\r\n }\r\n \r\n /**\r\n * Open the app settings page\r\n */\r\n static openAppSettings(): void {\r\n\r\n try {\r\n const context = UTSAndroid.getAppContext();\r\n if (context != null) {\r\n const intent = new android.content.Intent();\r\n intent.setAction(\"android.settings.APPLICATION_DETAILS_SETTINGS\");\r\n const uri = android.net.Uri.fromParts(\"package\", context.getPackageName(), null);\r\n intent.setData(uri);\r\n intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);\r\n context.startActivity(intent);\r\n }\r\n } catch (e) {\r\n __f__('error','at ak/PermissionManager.uts:285','Failed to open app settings', e);\r\n uni.showToast({\r\n title: '请手动前往系统设置修改应用权限',\r\n icon: 'none',\r\n duration: 3000\r\n });\r\n }\r\n\r\n \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n }\r\n \r\n /**\r\n * Helper to get the list of granted permissions\r\n */\r\n private static getGrantedPermissions(allPermissions: string[], deniedPermissions: string[]): string[] {\r\n return allPermissions.filter(p => !deniedPermissions.includes(p));\r\n }\r\n \r\n /**\r\n * Helper to get the list of denied permissions\r\n */\r\n private static getDeniedPermissions(allPermissions: string[], grantedPermissions: string[]): string[] {\r\n return allPermissions.filter(p => !grantedPermissions.includes(p));\r\n }\r\n \r\n /**\r\n * Request multiple permission types at once\r\n * @param types Array of permission types to request\r\n * @param callback Function to call when all permissions have been processed\r\n */\r\n static requestMultiplePermissions(\r\n types: PermissionType[],\r\n callback: (results: Map<PermissionType, PermissionResult>) => void\r\n ): void {\r\n if (types.length === 0) {\r\n callback(new Map());\r\n return;\r\n }\r\n \r\n const results = new Map<PermissionType, PermissionResult>();\r\n let remaining = types.length;\r\n \r\n for (const type of types) {\r\n this.requestPermission(\r\n type,\r\n (result) => {\r\n results.set(type, result);\r\n remaining--;\r\n \r\n if (remaining === 0) {\r\n callback(results);\r\n }\r\n },\r\n true\r\n );\r\n }\r\n }\r\n \r\n /**\r\n * Convenience method to request Bluetooth permissions\r\n * @param callback Function to call after the permission request\r\n */\r\n static requestBluetoothPermissions(callback: (granted: boolean) => void): void {\r\n this.requestPermission(PermissionType.BLUETOOTH, (result) => {\r\n // For Bluetooth, we also need location permissions on Android\r\n if (result.granted) {\r\n this.requestPermission(PermissionType.LOCATION, (locationResult) => {\r\n callback(locationResult.granted);\r\n });\r\n } else {\r\n callback(false);\r\n }\r\n });\r\n }\r\n}","import { initRuntimeSocket } from './socket'\n\nexport function initRuntimeSocketService(): Promise<boolean> {\n const hosts: string = process.env.UNI_SOCKET_HOSTS\n const port: string = process.env.UNI_SOCKET_PORT\n const id: string = process.env.UNI_SOCKET_ID\n if (hosts == '' || port == '' || id == '') return Promise.resolve(false)\n let socketTask: SocketTask | null = null\n __registerWebViewUniConsole(\n (): string => {\n return process.env.UNI_CONSOLE_WEBVIEW_EVAL_JS_CODE\n },\n (data: string) => {\n socketTask?.send({\n data,\n } as SendSocketMessageOptions)\n }\n )\n return Promise.resolve()\n .then((): Promise<boolean> => {\n return initRuntimeSocket(hosts, port, id).then((socket): boolean => {\n if (socket == null) {\n return false\n }\n socketTask = socket\n return true\n })\n })\n .catch((): boolean => {\n return false\n })\n}\n\ninitRuntimeSocketService()\n","// 蓝牙相关接口和类型定义\r\n\r\n// 基础设备信息类型\r\nexport type BleDeviceInfo = {\r\n\tdeviceId : string;\r\n\tname : string;\r\n\tRSSI ?: number;\r\n\tconnected ?: boolean;\r\n\t// 新增\r\n\tserviceId ?: string;\r\n\twriteCharId ?: string;\r\n\tnotifyCharId ?: string;\r\n}\r\nexport type AutoDiscoverAllResult = {\r\n\tservices : BleService[];\r\n\tcharacteristics : BleCharacteristic[];\r\n}\r\n\r\n// 服务信息类型\r\nexport type BleServiceInfo = {\r\n\tuuid : string;\r\n\tisPrimary : boolean;\r\n}\r\n\r\n// 特征值属性类型\r\nexport type BleCharacteristicProperties = {\r\n\tread : boolean;\r\n\twrite : boolean;\r\n\tnotify : boolean;\r\n\tindicate : boolean;\r\n\twriteWithoutResponse ?: boolean;\r\n\tcanRead ?: boolean;\r\n\tcanWrite ?: boolean;\r\n\tcanNotify ?: boolean;\r\n}\r\n\r\n// 特征值信息类型\r\nexport type BleCharacteristicInfo = {\r\n\tuuid : string;\r\n\tserviceId : string;\r\n\tproperties : BleCharacteristicProperties;\r\n}\r\n\r\n// 错误状态码\r\nexport enum BleErrorCode {\r\n\tUNKNOWN_ERROR = 0,\r\n\tBLUETOOTH_UNAVAILABLE = 1,\r\n\tPERMISSION_DENIED = 2,\r\n\tDEVICE_NOT_CONNECTED = 3,\r\n\tSERVICE_NOT_FOUND = 4,\r\n\tCHARACTERISTIC_NOT_FOUND = 5,\r\n\tOPERATION_TIMEOUT = 6\r\n}\r\n\r\n// 命令类型\r\nexport enum CommandType {\r\n\tBATTERY = 1,\r\n\tDEVICE_INFO = 2,\r\n\tCUSTOM = 99,\r\n\tTestBatteryLevel = 0x01\r\n}\r\n\r\n// 错误接口\r\nexport type BleError {\r\n\terrCode : number;\r\n\terrMsg : string;\r\n\terrSubject ?: string;\r\n}\r\n\r\n\r\n// 连接选项\r\nexport type BleConnectOptions = {\r\n\tdeviceId : string;\r\n\ttimeout ?: number;\r\n\tsuccess ?: (result : any) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// 断开连接选项\r\nexport type BleDisconnectOptions = {\r\n\tdeviceId : string;\r\n\tsuccess ?: (result : any) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// 获取特征值选项\r\nexport type BleCharacteristicOptions = {\r\n\tdeviceId : string;\r\n\tserviceId : string;\r\n\tcharacteristicId : string;\r\n\tsuccess ?: (result : any) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// 写入特征值选项\r\nexport type BleWriteOptions = {\r\n\tdeviceId : string;\r\n\tserviceId : string;\r\n\tcharacteristicId : string;\r\n\tvalue : Uint8Array;\r\n\twriteType ?: number;\r\n\tsuccess ?: (result : any) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// Options for writeCharacteristic helper\r\nexport type WriteCharacteristicOptions = {\r\n\twaitForResponse ?: boolean;\r\n\tmaxAttempts ?: number;\r\n\tretryDelayMs ?: number;\r\n\tgiveupTimeoutMs ?: number;\r\n\tforceWriteTypeNoResponse ?: boolean;\r\n}\r\n\r\n// 通知特征值回调函数\r\nexport type BleNotifyCallback = (data : Uint8Array) => void;\r\n\r\n// 通知特征值选项\r\nexport type BleNotifyOptions = {\r\n\tdeviceId : string;\r\n\tserviceId : string;\r\n\tcharacteristicId : string;\r\n\tstate ?: boolean; // true: 启用通知false: 禁用通知\r\n\tonCharacteristicValueChange : BleNotifyCallback;\r\n\tsuccess ?: (result : any) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// 获取服务选项\r\nexport type BleDeviceServicesOptions = {\r\n\tdeviceId : string;\r\n\tsuccess ?: (result : BleServicesResult) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// 获取特征值选项\r\nexport type BleDeviceCharacteristicsOptions = {\r\n\tdeviceId : string;\r\n\tserviceId : string;\r\n\tsuccess ?: (result : BleCharacteristicsResult) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// 蓝牙扫描选项\r\nexport type BluetoothScanOptions = {\r\n\tservices ?: string[];\r\n\ttimeout ?: number;\r\n\tonDeviceFound ?: (device : BleDeviceInfo) => void;\r\n\tsuccess ?: (result : BleScanResult) => void;\r\n\tfail ?: (error : BleError) => void;\r\n\tcomplete ?: (result : any) => void;\r\n}\r\n\r\n// 扫描结果\r\n\r\n// 服务结果\r\nexport type BleServicesResult = {\r\n\tservices : BleServiceInfo[];\r\n\terrMsg ?: string;\r\n}\r\n\r\n// 特征值结果\r\nexport type BleCharacteristicsResult = {\r\n\tcharacteristics : BleCharacteristicInfo[];\r\n\terrMsg ?: string;\r\n}\r\n\r\n// 定义连接状态枚举\r\nexport enum BLE_CONNECTION_STATE {\r\n\tDISCONNECTED = 0,\r\n\tCONNECTING = 1,\r\n\tCONNECTED = 2,\r\n\tDISCONNECTING = 3\r\n}\r\n\r\n// 电池状态类型定义\r\nexport type BatteryStatus = {\r\n\tbatteryLevel : number; // 电量百分比\r\n\tisCharging : boolean; // 充电状态\r\n}\r\n\r\n// 蓝牙服务接口类型定义 - 转换为type类型\r\nexport type BleService = {\r\n\tuuid : string;\r\n\tisPrimary : boolean;\r\n}\r\n\r\n// 蓝牙特征值接口定义 - 转换为type类型\r\nexport type BleCharacteristic = {\r\n\tuuid : string;\r\n\tservice : BleService;\r\n\tproperties : BleCharacteristicProperties;\r\n}\r\n\r\n// PendingPromise接口定义\r\nexport interface PendingCallback {\r\n\tresolve : (data : any) => void;\r\n\treject : (err ?: any) => void;\r\n\ttimer ?: number;\r\n}\r\n\r\n// 蓝牙相关接口和类型定义\r\nexport type BleDevice = {\r\n\tdeviceId : string;\r\n\tname : string;\r\n\trssi ?: number;\r\n\tlastSeen ?: number; // 新增\r\n\t// 新增\r\n\tserviceId ?: string;\r\n\twriteCharId ?: string;\r\n\tnotifyCharId ?: string;\r\n}\r\n\r\n// BLE常规选项\r\nexport type BleOptions = {\r\n\ttimeout ?: number;\r\n\tsuccess ?: (result : any) => void;\r\n\tfail ?: (error : any) => void;\r\n\tcomplete ?: () => void;\r\n}\r\n\r\nexport type BleConnectionState = number; // 0: DISCONNECTED, 1: CONNECTING, 2: CONNECTED, 3: DISCONNECTING\r\n\r\nexport type BleConnectOptionsExt = {\r\n\ttimeout ?: number;\r\n\tservices ?: string[];\r\n\trequireResponse ?: boolean;\r\n\tautoReconnect ?: boolean;\r\n\tmaxAttempts ?: number;\r\n\tinterval ?: number;\r\n};\r\n\r\n// 回调函数类型\r\nexport type BleDeviceFoundCallback = (device : BleDevice) => void;\r\nexport type BleConnectionStateChangeCallback = (deviceId : string, state : BleConnectionState) => void;\r\n\r\nexport type BleDataPayload = {\r\n\tdeviceId : string;\r\n\tserviceId ?: string;\r\n\tcharacteristicId ?: string;\r\n\tdata : string | ArrayBuffer;\r\n\tformat ?: number; // 0: JSON, 1: XML, 2: RAW\r\n}\r\n\r\nexport type BleDataSentCallback = (payload : BleDataPayload, success : boolean, error ?: BleError) => void;\r\nexport type BleErrorCallback = (error : BleError) => void;\r\n\r\n// 健康数据类型定义\r\nexport enum HealthDataType {\r\n\tHEART_RATE = 1,\r\n\tBLOOD_OXYGEN = 2,\r\n\tTEMPERATURE = 3,\r\n\tSTEP_COUNT = 4,\r\n\tSLEEP_DATA = 5,\r\n\tHEALTH_DATA = 6\r\n}\r\n\r\n// Platform-specific services should be imported from per-platform entrypoints\r\n// (e.g. './app-android/index.uts' or './web/index.uts').\r\n// Avoid re-exporting platform modules at the SDK root to prevent bundlers\r\n// Platform-specific services should be imported from per-platform entrypoints\r\n// (e.g. './app-android/index.uts' or './web/index.uts').\r\n// Avoid re-exporting platform modules at the SDK root to prevent bundlers\r\n// from pulling android.* symbols into web bundles.\r\n// If a typed ambient reference is required, declare the shape here instead of importing implementation.\r\n// Example lightweight typed placeholder (do not import platform code here):\r\n// export type BluetoothService = any; // platform-specific implementation exported from platform index files\r\n\r\n\r\n\r\n// ====== 新增多协议、统一事件、协议适配、状态管理支持 ======\r\nexport type BleProtocolType =\r\n\t| 'standard'\r\n\t| 'custom'\r\n\t| 'health'\r\n\t| 'ibeacon'\r\n\t| 'mesh';\r\n\r\nexport type BleEvent =\r\n\t| 'deviceFound'\r\n\t| 'scanFinished'\r\n\t| 'connectionStateChanged'\r\n\t| 'dataReceived'\r\n\t| 'dataSent'\r\n\t| 'error'\r\n\t| 'servicesDiscovered'\r\n\t| 'connected' // 新增\r\n\t| 'disconnected'; // 新增\r\n\r\n// 事件回调参数\r\nexport type BleEventPayload = {\r\n\tevent : BleEvent;\r\n\tdevice ?: BleDevice;\r\n\tprotocol ?: BleProtocolType;\r\n\tstate ?: BleConnectionState;\r\n\tdata ?: ArrayBuffer | string | object;\r\n\tformat ?: string;\r\n\terror ?: BleError;\r\n\textra ?: any;\r\n}\r\n\r\n// 事件回调函数\r\nexport type BleEventCallback = (payload : BleEventPayload) => void;\r\n\r\n// 多协议设备信息(去除交叉类型,直接展开字段)\r\nexport type MultiProtocolDevice = {\r\n\tdeviceId : string;\r\n\tname : string;\r\n\trssi ?: number;\r\n\tprotocol : BleProtocolType;\r\n};\r\n\r\nexport type ScanDevicesOptions = {\r\n\tprotocols ?: BleProtocolType[];\r\n\toptionalServices ?: string[];\r\n\ttimeout ?: number;\r\n\tonDeviceFound ?: (device : BleDevice) => void;\r\n\tonScanFinished ?: () => void;\r\n};\r\n// Named payload type used by sendData\r\nexport type SendDataPayload = {\r\n\tdeviceId : string;\r\n\tserviceId ?: string;\r\n\tcharacteristicId ?: string;\r\n\tdata : string | ArrayBuffer;\r\n\tformat ?: number;\r\n\tprotocol : BleProtocolType;\r\n}\r\n// 协议处理器接口(为 protocol-handler 适配器预留)\r\nexport type ScanHandler = {\r\n\tprotocol : BleProtocolType;\r\n\tscanDevices ?: (options : ScanDevicesOptions) => Promise<void>;\r\n\tconnect : (device : BleDevice, options ?: BleConnectOptionsExt) => Promise<void>;\r\n\tdisconnect : (device : BleDevice) => Promise<void>;\r\n\t// Optional: send arbitrary data via the protocol's write characteristic\r\n\tsendData ?: (device : BleDevice, payload : SendDataPayload, options ?: BleOptions) => Promise<void>;\r\n\t// Optional: try to connect and discover service/characteristic ids for this device\r\n\tautoConnect ?: (device : BleDevice, options ?: BleConnectOptionsExt) => Promise<AutoBleInterfaces>;\r\n\r\n}\r\n\r\n\r\n// 自动发现服务和特征返回类型\r\nexport type AutoBleInterfaces = {\r\n\tserviceId : string;\r\n\twriteCharId : string;\r\n\tnotifyCharId : string;\r\n}\r\nexport type ResponseCallbackEntry = {\r\n\tcb : (data : Uint8Array) => boolean | void;\r\n\tmulti : boolean;\r\n};\r\n\r\n// Result returned by a DFU control parser. Use a plain string `type` to keep\r\n// the generated Kotlin simple and avoid inline union types which the generator\r\n// does not handle well.\r\nexport type ControlParserResult = {\r\n\ttype : string; // e.g. 'progress', 'success', 'error', 'info'\r\n\tprogress ?: number;\r\n\terror ?: any;\r\n}\r\n\r\n// DFU types\r\nexport type DfuOptions = {\r\n\tmtu ?: number;\r\n\tuseNordic ?: boolean;\r\n\t// If true, the DFU upload will await a write response per-packet. Set false to use\r\n\t// WRITE_NO_RESPONSE (fire-and-forget) for higher throughput. Default: false.\r\n\twaitForResponse ?: boolean;\r\n\t// Maximum number of outstanding NO_RESPONSE writes to allow before throttling.\r\n\t// This implements a simple sliding window. Default: 32.\r\n\tmaxOutstanding ?: number;\r\n\t// Per-chunk sleep (ms) to yield to event loop / Android BLE stack. Default: 2.\r\n\twriteSleepMs ?: number;\r\n\t// Retry delay (ms) used by the Android write helper when gatt.writeCharacteristic\r\n\t// returns false. Smaller values can improve throughput on congested stacks.\r\n\twriteRetryDelayMs ?: number;\r\n\t// Maximum number of immediate write attempts before falling back to the give-up timeout.\r\n\twriteMaxAttempts ?: number;\r\n\t// Timeout (ms) to wait for a late onCharacteristicWrite callback after all retries fail.\r\n\twriteGiveupTimeoutMs ?: number;\r\n\t// Packet Receipt Notification (PRN) window size in packets. If set, DFU\r\n\t// manager will send a Set PRN command to the device and wait for PRN\r\n\t// notifications after this many packets. Default: 12.\r\n\tprn ?: number;\r\n\t// Timeout (ms) to wait for a PRN notification once the window is reached.\r\n\t// Default: 10000 (10s).\r\n\tprnTimeoutMs ?: number;\r\n\t// When true, disable PRN waits automatically after the first timeout to prevent\r\n\t// repeated long stalls on devices that do not send PRNs. Default: true.\r\n\tdisablePrnOnTimeout ?: boolean;\r\n\t// Time (ms) to wait for outstanding fire-and-forget writes to drain before issuing\r\n\t// the activate/validate control command. Default: 3000.\r\n\tdrainOutstandingTimeoutMs ?: number;\r\n\tcontrolTimeout ?: number;\r\n\tonProgress ?: (percent : number) => void;\r\n\tonLog ?: (message : string) => void;\r\n\tcontrolParser ?: (data : Uint8Array) => ControlParserResult | null;\r\n}\r\n\r\nexport type DfuManagerType = {\r\n\tstartDfu : (deviceId : string, firmwareBytes : Uint8Array, options ?: DfuOptions) => Promise<void>;\r\n}\r\n\r\n// Lightweight runtime / UTS shims and missing types\r\n// These are conservative placeholders to satisfy typings used across platform files.\r\n// UTSJSONObject: bundler environments used by the build may not support\r\n// TypeScript-style index signatures in this .uts context. Use a conservative\r\n// 'any' alias so generated code doesn't rely on unsupported syntax while\r\n// preserving a usable type at the source level.\r\nexport type UTSJSONObject = any;\r\n\r\n// ByteArray / Int are used in the Android platform code to interop with Java APIs.\r\n// Define minimal aliases so source can compile. Runtime uses Uint8Array and number.\r\nexport type ByteArray = any; // runtime will use Java byte[] via UTS bridge; keep as any here\r\n\r\n// Callback types used by service_manager and index wrappers\r\nexport type BleDataReceivedCallback = (data: Uint8Array) => void;\r\nexport type BleScanResult = {\r\n\tdeviceId: string;\r\n\tname?: string;\r\n\trssi?: number;\r\n\tadvertising?: any;\r\n};\r\n\r\n// Minimal UI / framework placeholders (some files reference these in types only)\r\nexport type ComponentPublicInstance = any;\r\nexport type UniElement = any;\r\nexport type UniPage = any;\r\n\r\n// Platform service placeholder (actual implementation exported from platform index files)\r\n// Provide a lightweight, strongly-shaped class skeleton so source-level code\r\n// (and the code generator) can rely on concrete method names and signatures.\r\n// Implementations are platform-specific and exported from per-platform index\r\n// files (e.g. './app-android/index.uts' or './web/index.uts'). This class is\r\n// intentionally thin — it declares method signatures used across pages and\r\n// platform shims so the generator emits resolvable Kotlin symbols.\r\nexport class BluetoothService {\r\n\t// Event emitter style\r\n\ton(event: BleEvent | string, callback: BleEventCallback): void {}\r\n\toff(event: BleEvent | string, callback?: BleEventCallback): void {}\r\n\r\n\t// Scanning / discovery\r\n\tscanDevices(options?: ScanDevicesOptions): Promise<void> { return Promise.resolve(); }\r\n\r\n\t// Connection management\r\n\tconnectDevice(deviceId: string, protocol?: string, options?: BleConnectOptionsExt): Promise<void> { return Promise.resolve(); }\r\n\tdisconnectDevice(deviceId: string, protocol?: string): Promise<void> { return Promise.resolve(); }\r\n\tgetConnectedDevices(): MultiProtocolDevice[] { return []; }\r\n\r\n\t// Services / characteristics\r\n\tgetServices(deviceId: string): Promise<BleService[]> { return Promise.resolve([]); }\r\n\tgetCharacteristics(deviceId: string, serviceId: string): Promise<BleCharacteristic[]> { return Promise.resolve([]); }\r\n\r\n\t// Read / write / notify\r\n\treadCharacteristic(deviceId: string, serviceId: string, characteristicId: string): Promise<ArrayBuffer> { return Promise.resolve(new ArrayBuffer(0)); }\r\n\twriteCharacteristic(deviceId: string, serviceId: string, characteristicId: string, value: Uint8Array | ArrayBuffer, options?: WriteCharacteristicOptions): Promise<boolean> { return Promise.resolve(true); }\r\n\tsubscribeCharacteristic(deviceId: string, serviceId: string, characteristicId: string, callback: BleNotifyCallback): Promise<void> { return Promise.resolve(); }\r\n\tunsubscribeCharacteristic(deviceId: string, serviceId: string, characteristicId: string): Promise<void> { return Promise.resolve(); }\r\n\r\n\t\t// Convenience helpers\r\n\t\tgetAutoBleInterfaces(deviceId: string): Promise<AutoBleInterfaces> {\r\n\t\t\tconst res: AutoBleInterfaces = { serviceId: '', writeCharId: '', notifyCharId: '' };\r\n\t\t\treturn Promise.resolve(res);\r\n\t\t}\r\n}\r\n\r\n// Runtime protocol handler base class. Exporting a concrete class ensures the\r\n// generator emits a resolvable runtime type that platform handlers can extend.\r\n// Source-level code can still use the ScanHandler type for typing.\r\n// Runtime ProtocolHandler is implemented in `protocol_handler.uts`.\r\n// Keep the public typing in this file minimal to avoid duplicate runtime\r\n// declarations. Consumers that need the runtime class should import it from\r\n// './protocol_handler.uts'.","// Minimal ProtocolHandler runtime class used by pages and components.\r\n// This class adapts the platform `BluetoothService` to a small protocol API\r\n// expected by pages: setConnectionParameters, initialize, testBatteryLevel,\r\n// testVersionInfo. Implemented conservatively to avoid heavy dependencies.\r\n\r\nimport type { BluetoothService, AutoBleInterfaces, AutoDiscoverAllResult, BleService, BleCharacteristic, BleProtocolType, BleDevice, ScanDevicesOptions, BleConnectOptionsExt, SendDataPayload, BleOptions } from './interface.uts'\r\n\r\nexport class ProtocolHandler {\r\n\t// bluetoothService may be omitted for lightweight wrappers; allow null\r\n\tbluetoothService: BluetoothService | null = null\r\n\tprotocol: BleProtocolType = 'standard'\r\n\tdeviceId: string | null = null\r\n\tserviceId: string | null = null\r\n\twriteCharId: string | null = null\r\n\tnotifyCharId: string | null = null\r\n\tinitialized: boolean = false\r\n\r\n\t// Accept an optional BluetoothService so wrapper subclasses can call\r\n\t// `super()` without forcing a runtime instance.\r\n\tconstructor(bluetoothService?: BluetoothService) {\r\n\t\tif (bluetoothService != null) this.bluetoothService = bluetoothService\r\n\t}\r\n\r\n\tsetConnectionParameters(deviceId: string, serviceId: string, writeCharId: string, notifyCharId: string) {\r\n\t\tthis.deviceId = deviceId\r\n\t\tthis.serviceId = serviceId\r\n\t\tthis.writeCharId = writeCharId\r\n\t\tthis.notifyCharId = notifyCharId\r\n\t}\r\n\r\n\t// initialize: optional setup, returns a Promise that resolves when ready\r\n\tasync initialize(): Promise<void> {\r\n\t\t// Simple async initializer — keep implementation minimal and generator-friendly.\r\n\t\ttry {\r\n\t\t\t// If bluetoothService exposes any protocol-specific setup, call it here.\r\n\t\t\tthis.initialized = true\r\n\t\t\treturn\r\n\t\t} catch (e) {\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\t// Protocol lifecycle / operations — default no-ops so generated code has\r\n\t// concrete member references and platform-specific handlers can override.\r\n\tasync scanDevices(options?: ScanDevicesOptions): Promise<void> { return; }\r\n\tasync connect(device: BleDevice, options?: BleConnectOptionsExt): Promise<void> { return; }\r\n\tasync disconnect(device: BleDevice): Promise<void> { return; }\r\n\tasync sendData(device: BleDevice, payload?: SendDataPayload, options?: BleOptions): Promise<void> { return; }\r\n\tasync autoConnect(device: BleDevice, options?: BleConnectOptionsExt): Promise<AutoBleInterfaces> { return { serviceId: '', writeCharId: '', notifyCharId: '' }; }\r\n\r\n\t// Example: testBatteryLevel will attempt to read the battery characteristic\r\n\t// if write/notify-based protocol is not available. Returns number percentage.\r\n\tasync testBatteryLevel(): Promise<number> {\r\n\t\tif (this.deviceId == null) throw new Error('deviceId not set')\r\n\t\t// copy to local so Kotlin generator can smart-cast the value across awaits\r\n\t\tconst deviceId = this.deviceId\r\n\t\t// try reading standard Battery characteristic (180F -> 2A19)\r\n\t\tif (this.bluetoothService == null) throw new Error('bluetoothService not set')\r\n\t\tconst services = await this.bluetoothService.getServices(deviceId)\r\n\r\n\t\r\n\tlet found: BleService | null = null\r\n\t\tfor (let i = 0; i < services.length; i++) {\r\n\t\t\tconst s = services[i]\r\n\t\t\tconst uuidCandidate: string | null = (s != null && s.uuid != null ? s.uuid : null)\r\n\t\t\tconst uuid = uuidCandidate != null ? ('' + uuidCandidate).toLowerCase() : ''\r\n\t\t\tif (uuid.indexOf('180f') !== -1) { found = s; break }\r\n\t\t}\r\n\t\tif (found == null) {\r\n\t\t\t// fallback: if writeCharId exists and notify available use protocol (not implemented)\r\n\t\t\treturn 0\r\n\t\t}\r\n\tconst foundUuid = found!.uuid\r\n\tconst charsRaw = await this.bluetoothService.getCharacteristics(deviceId, foundUuid)\r\n\tconst chars: BleCharacteristic[] = charsRaw\r\n\tconst batChar = chars.find((c: BleCharacteristic) => ((c.properties != null && c.properties.read) || (c.uuid != null && ('' + c.uuid).toLowerCase().includes('2a19'))))\r\n\t\tif (batChar == null) return 0\r\n\tconst buf = await this.bluetoothService.readCharacteristic(deviceId, foundUuid, batChar.uuid)\r\n\t\tconst arr = new Uint8Array(buf)\r\n\t\tif (arr.length > 0) {\r\n\t\t\treturn arr[0]\r\n\t\t}\r\n\t\treturn 0\r\n\t}\r\n\r\n\t// testVersionInfo: try to read Device Information characteristics or return empty\r\n\tasync testVersionInfo(hw: boolean): Promise<string> {\r\n\t\t// copy to local so Kotlin generator can smart-cast the value across awaits\r\n\t\tconst deviceId = this.deviceId\r\n\t\tif (deviceId == null) return ''\r\n\t\t// Device Information service 180A, characteristics: 2A26 (SW), 2A27 (HW) sometimes\r\n\t\tif (this.bluetoothService == null) return ''\r\n\t\tconst _services = await this.bluetoothService.getServices(deviceId)\r\n\t\tconst services2: BleService[] = _services \r\n\t\tlet found2: BleService | null = null\r\n\t\tfor (let i = 0; i < services2.length; i++) {\r\n\t\t\tconst s = services2[i]\r\n\t\t\tconst uuidCandidate: string | null = (s != null && s.uuid != null ? s.uuid : null)\r\n\t\t\tconst uuid = uuidCandidate != null ? ('' + uuidCandidate).toLowerCase() : ''\r\n\t\t\tif (uuid.indexOf('180a') !== -1) { found2 = s; break }\r\n\t\t}\r\n\t\tif (found2 == null) return ''\r\n\t\tconst _found2 = found2\r\n\t\tconst found2Uuid = _found2!.uuid\r\n\t\tconst chars = await this.bluetoothService.getCharacteristics(deviceId, found2Uuid)\r\n\t\tconst target = chars.find((c) => {\r\n\t\t\tconst id = ('' + c.uuid).toLowerCase()\r\n\t\t\tif (hw) return id.includes('2a27') || id.includes('hardware')\r\n\t\t\treturn id.includes('2a26') || id.includes('software')\r\n\t\t})\r\n\t\tif (target == null) return ''\r\n\tconst buf = await this.bluetoothService.readCharacteristic(deviceId, found2Uuid, target.uuid)\r\n\ttry { return new TextDecoder().decode(new Uint8Array(buf)) } catch (e) { return '' }\r\n\t}\r\n}\r\n","// Minimal error definitions used across the BLE module.\r\n// Keep this file small and avoid runtime dependencies; it's mainly for typing and\r\n// simple runtime error construction used by native platform code.\r\n\r\nexport enum AkBluetoothErrorCode {\r\n\tUnknownError = 0,\r\n\tDeviceNotFound = 1,\r\n\tServiceNotFound = 2,\r\n\tCharacteristicNotFound = 3,\r\n\tConnectionTimeout = 4,\r\n\tUnspecified = 99\r\n}\r\n\r\nexport class AkBleErrorImpl extends Error {\r\n\tpublic code: AkBluetoothErrorCode;\r\n\tpublic detail: any|null;\n\tconstructor(code: AkBluetoothErrorCode, message?: string, detail: any|null = null) {\r\n\t\tsuper(message ?? AkBleErrorImpl.defaultMessage(code));\r\n\t\tthis.name = 'AkBleError';\r\n\t\tthis.code = code;\r\n\t\tthis.detail = detail;\r\n\t}\r\n\tstatic defaultMessage(code: AkBluetoothErrorCode) {\r\n\t\tswitch (code) {\r\n\t\t\tcase AkBluetoothErrorCode.DeviceNotFound: return 'Device not found';\r\n\t\t\tcase AkBluetoothErrorCode.ServiceNotFound: return 'Service not found';\r\n\t\t\tcase AkBluetoothErrorCode.CharacteristicNotFound: return 'Characteristic not found';\r\n\t\t\tcase AkBluetoothErrorCode.ConnectionTimeout: return 'Connection timed out';\r\n\t\t\tcase AkBluetoothErrorCode.UnknownError: default: return 'Unknown Bluetooth error';\r\n\t\t}\r\n\t}\r\n}\r\n\r\nexport default AkBleErrorImpl;\r\n","import type {\r\n\tBleDevice,\r\n\tBleConnectionState,\r\n\tBleEvent,\r\n\tBleEventCallback,\r\n\tBleEventPayload,\r\n\tBleScanResult,\r\n\tBleConnectOptionsExt,\r\n\tAutoBleInterfaces,\r\n\tBleDataPayload,\r\n\tSendDataPayload,\r\n\tBleOptions,\r\n\tMultiProtocolDevice,\r\n\tScanHandler,\r\n\tBleProtocolType,\r\n\tScanDevicesOptions\r\n} from '../interface.uts';\r\nimport { ProtocolHandler } from '../protocol_handler.uts';\r\nimport { BluetoothService } from '../interface.uts';\r\nimport { DeviceManager } from './device_manager.uts';\r\n\r\n// Shape used when callers register plain objects as handlers. Using a named\r\n// type keeps member access explicit so the code generator emits valid Kotlin\r\n// member references instead of trying to access properties on Any.\r\ntype RawProtocolHandler = {\r\n\tprotocol?: BleProtocolType;\r\n\tscanDevices?: (options?: ScanDevicesOptions) => Promise<void>;\r\n\tconnect?: (device: BleDevice, options?: BleConnectOptionsExt) => Promise<void>;\r\n\tdisconnect?: (device: BleDevice) => Promise<void>;\r\n\tsendData?: (device: BleDevice, payload?: SendDataPayload, options?: BleOptions) => Promise<void>;\r\n\tautoConnect?: (device: BleDevice, options?: BleConnectOptionsExt) => Promise<AutoBleInterfaces>;\r\n}\r\n\r\n// 设备上下文\r\nclass DeviceContext {\r\n\tdevice : BleDevice;\r\n\tprotocol : BleProtocolType;\r\n\tstate : BleConnectionState;\r\n\thandler : ProtocolHandler;\r\n\tconstructor(device : BleDevice, protocol : BleProtocolType, handler : ProtocolHandler) {\r\n\t\tthis.device = device;\r\n\t\tthis.protocol = protocol;\r\n\t\tthis.state = 0; // DISCONNECTED\r\n\t\tthis.handler = handler;\r\n\t}\r\n}\r\n\r\nconst deviceMap = new Map<string, DeviceContext>(); // key: deviceId|protocol\r\n// Single active protocol handler (no multi-protocol registration)\r\nlet activeProtocol: BleProtocolType = 'standard';\r\nlet activeHandler: ProtocolHandler | null = null;\r\n// 事件监听注册表\r\nconst eventListeners = new Map<BleEvent, Set<BleEventCallback>>();\r\n\r\nfunction emit(event : BleEvent, payload : BleEventPayload) {\r\n\tif (event === 'connectionStateChanged') {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:57','[AKBLE][LOG] bluetooth_manager.uts emit connectionStateChanged', payload)\r\n\t}\r\n\tconst listeners = eventListeners.get(event);\r\n\tif (listeners != null) {\r\n\t\tlisteners.forEach(cb => {\r\n\t\t\ttry { cb(payload); } catch (e) { }\r\n\t\t});\r\n\t}\r\n}\r\nclass ProtocolHandlerWrapper extends ProtocolHandler {\r\n\tprivate _raw: RawProtocolHandler | null;\r\n\tconstructor(raw?: RawProtocolHandler) {\r\n\t\t// pass a lightweight BluetoothService instance to satisfy generators\r\n\t\tsuper(new BluetoothService());\r\n\t\tthis._raw = (raw != null) ? raw : null;\r\n\t}\r\n\toverride async scanDevices(options?: ScanDevicesOptions): Promise<void> {\r\n\t\tconst rawTyped = this._raw;\r\n\t\tif (rawTyped != null && typeof rawTyped.scanDevices === 'function') {\r\n\t\t\tawait rawTyped.scanDevices(options);\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\toverride async connect(device: BleDevice, options?: BleConnectOptionsExt): Promise<void> {\r\n\t\tconst rawTyped = this._raw;\r\n\t\tif (rawTyped != null && typeof rawTyped.connect === 'function') {\r\n\t\t\tawait rawTyped.connect(device, options);\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\toverride async disconnect(device: BleDevice): Promise<void> {\r\n\t\tconst rawTyped = this._raw;\r\n\t\tif (rawTyped != null && typeof rawTyped.disconnect === 'function') {\r\n\t\t\tawait rawTyped.disconnect(device);\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\toverride async sendData(device: BleDevice, payload?: SendDataPayload, options?: BleOptions): Promise<void> {\r\n\t\tconst rawTyped = this._raw;\r\n\t\tif (rawTyped != null && typeof rawTyped.sendData === 'function') {\r\n\t\t\tawait rawTyped.sendData(device, payload, options);\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\toverride async autoConnect(device: BleDevice, options?: BleConnectOptionsExt): Promise<AutoBleInterfaces> {\r\n\t\tconst rawTyped = this._raw;\r\n\t\tif (rawTyped != null && typeof rawTyped.autoConnect === 'function') {\r\n\t\t\treturn await rawTyped.autoConnect(device, options);\r\n\t\t}\r\n\t\treturn { serviceId: '', writeCharId: '', notifyCharId: '' };\r\n\t}\r\n}\r\n\r\n// Strong runtime detector for plain object handlers (no Type Predicate)\r\n// Note: the UTS bundler doesn't support TypeScript type predicates (x is T),\r\n// and it doesn't accept the 'unknown' type. This returns a boolean and\r\n// callers must cast the value to RawProtocolHandler after the function\r\n// returns true.\r\nfunction isRawProtocolHandler(x: any): boolean {\r\n\tif (x == null || typeof x !== 'object') return false;\r\n\tconst r = x as Record<string, unknown>;\r\n\tif (typeof r['scanDevices'] === 'function') return true;\r\n\tif (typeof r['connect'] === 'function') return true;\r\n\tif (typeof r['disconnect'] === 'function') return true;\r\n\tif (typeof r['sendData'] === 'function') return true;\r\n\tif (typeof r['autoConnect'] === 'function') return true;\r\n\tif (typeof r['protocol'] === 'string') return true;\r\n\treturn false;\r\n}\r\n\r\nexport const registerProtocolHandler = (handler : any) => {\r\n\tif (handler == null) return;\r\n\t// Determine protocol value defensively. Default to 'standard' when unknown.\r\n\tlet proto: BleProtocolType = 'standard';\r\n\tif (handler instanceof ProtocolHandler) {\r\n\t\ttry { proto = (handler as ProtocolHandler).protocol as BleProtocolType; } catch (e) { }\r\n\t\tactiveHandler = handler as ProtocolHandler;\r\n\t} else if (isRawProtocolHandler(handler)) {\r\n\t\ttry { proto = (handler as RawProtocolHandler).protocol as BleProtocolType; } catch (e) { }\r\n\t\tactiveHandler = new ProtocolHandlerWrapper(handler as RawProtocolHandler);\r\n\t\t(activeHandler as ProtocolHandler).protocol = proto;\r\n\t} else {\r\n\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:139','[AKBLE] registerProtocolHandler: unsupported handler type, ignoring', handler);\r\n\t\treturn;\r\n\t}\r\n\tactiveProtocol = proto;\r\n}\r\n\r\n\r\nexport const scanDevices = async (options ?: ScanDevicesOptions) : Promise<void> => {\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:147','[AKBLE] start scan', options)\r\n\t// Determine which protocols to run: either user-specified or all registered\r\n\t// Single active handler flow\r\n\tif (activeHandler == null) {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:151','[AKBLE] no active scan handler registered')\r\n\t\treturn\r\n\t}\r\n\tconst handler = activeHandler as ProtocolHandler;\r\n\tconst scanOptions : ScanDevicesOptions = {\r\n\t\tonDeviceFound: (device : BleDevice) => emit('deviceFound', { event: 'deviceFound', device }),\r\n\t\tonScanFinished: () => emit('scanFinished', { event: 'scanFinished' })\r\n\t}\r\n\ttry {\r\n\t\tawait handler.scanDevices(scanOptions)\r\n\t} catch (e) {\r\n\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:162','[AKBLE] scanDevices handler error', e)\r\n\t}\r\n}\r\n\r\n\r\nexport const connectDevice = async (deviceId : string, protocol : BleProtocolType, options ?: BleConnectOptionsExt) : Promise<void> => {\r\n\tconst handler = activeHandler;\r\n\tif (handler == null) throw new Error('No protocol handler');\r\n\tconst device : BleDevice = { deviceId, name: '', rssi: 0 }; // 可扩展\r\n\tawait handler.connect(device, options);\r\n\tconst ctx = new DeviceContext(device, protocol, handler);\r\n\tctx.state = 2; // CONNECTED\r\n\tdeviceMap.set(getDeviceKey(deviceId, protocol), ctx);\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:175',deviceMap)\r\n\temit('connectionStateChanged', { event: 'connectionStateChanged', device, protocol, state: 2 });\r\n}\r\n\r\nexport const disconnectDevice = async (deviceId : string, protocol : BleProtocolType) : Promise<void> => {\r\n\tconst ctx = deviceMap.get(getDeviceKey(deviceId, protocol));\r\n\tif (ctx == null || ctx.handler == null) return;\r\n\tawait ctx.handler.disconnect(ctx.device);\r\n\tctx.state = 0;\r\n\temit('connectionStateChanged', { event: 'connectionStateChanged', device: ctx.device, protocol, state: 0 });\r\n\tdeviceMap.delete(getDeviceKey(deviceId, protocol));\r\n}\r\nexport const sendData = async (payload : SendDataPayload, options ?: BleOptions) : Promise<void> => {\r\n\tconst ctx = deviceMap.get(getDeviceKey(payload.deviceId, payload.protocol));\r\n\tif (ctx == null) throw new Error('Device not connected');\r\n\t// copy to local non-null variable so generator can smart-cast across awaits\r\n\tconst deviceCtx = ctx as DeviceContext;\r\n\tif (deviceCtx.handler == null) throw new Error('sendData not supported for this protocol');\r\n\tawait deviceCtx.handler.sendData(deviceCtx.device, payload, options);\r\n\temit('dataSent', { event: 'dataSent', device: deviceCtx.device, protocol: payload.protocol, data: payload.data });\r\n}\r\n\r\nexport const getConnectedDevices = () : MultiProtocolDevice[] => {\r\n\tconst result : MultiProtocolDevice[] = [];\r\n\tdeviceMap.forEach((ctx : DeviceContext) => {\r\n\t\tconst dev : MultiProtocolDevice = {\r\n\t\t\tdeviceId: ctx.device.deviceId,\r\n\t\t\tname: ctx.device.name,\r\n\t\t\trssi: ctx.device.rssi,\r\n\t\t\tprotocol: ctx.protocol\r\n\t\t};\r\n\t\tresult.push(dev);\r\n\t});\r\n\treturn result;\r\n}\r\n\r\nexport const getConnectionState = (deviceId : string, protocol : BleProtocolType) : BleConnectionState => {\r\n\tconst ctx = deviceMap.get(getDeviceKey(deviceId, protocol));\r\n\tif (ctx == null) return 0;\r\n\treturn ctx.state;\r\n}\r\n\r\nexport const on = (event : BleEvent, callback : BleEventCallback) => {\r\n\tif (!eventListeners.has(event)) eventListeners.set(event, new Set());\r\n\teventListeners.get(event)!.add(callback);\r\n}\r\n\r\nexport const off = (event : BleEvent, callback ?: BleEventCallback) => {\r\n\tif (callback == null) {\r\n\t\teventListeners.delete(event);\r\n\t} else {\r\n\t\teventListeners.get(event)?.delete(callback as BleEventCallback);\r\n\t}\r\n}\r\n\r\nfunction getDeviceKey(deviceId : string, protocol : BleProtocolType) : string {\r\n\treturn `${deviceId}|${protocol}`;\r\n}\r\n\r\nexport const autoConnect = async (deviceId : string, protocol : BleProtocolType, options ?: BleConnectOptionsExt) : Promise<AutoBleInterfaces> => {\r\n\tconst handler = activeHandler;\r\n\tif (handler == null) throw new Error('autoConnect not supported for this protocol');\r\n\tconst device : BleDevice = { deviceId, name: '', rssi: 0 };\r\n\t// safe call - handler.autoConnect exists on ProtocolHandler\r\n\treturn await handler.autoConnect(device, options) as AutoBleInterfaces;\r\n}\r\n\r\n// Ensure there is at least one handler registered so callers can scan/connect\r\n// without needing to import a registry module. This creates a minimal default\r\n// ProtocolHandler backed by a BluetoothService instance.\r\ntry {\r\n\tif (activeHandler == null) {\r\n\t\t// Create a DeviceManager-backed raw handler that delegates to native code\r\n\t\tconst _dm = DeviceManager.getInstance();\r\n\t\tconst _raw: RawProtocolHandler = {\r\n\t\t\tprotocol: 'standard',\r\n\t\t\tscanDevices: (options?: ScanDevicesOptions) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst scanOptions = options != null ? options : {} as ScanDevicesOptions;\r\n\t\t\t\t\t_dm.startScan(scanOptions);\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:256','[AKBLE] DeviceManager.startScan failed', e);\r\n\t\t\t\t}\r\n\t\t\t\treturn Promise.resolve();\r\n\t\t\t},\r\n\t\t\tconnect: (device, options?: BleConnectOptionsExt) => {\r\n\t\t\t\treturn _dm.connectDevice(device.deviceId, options);\r\n\t\t\t},\r\n\t\t\tdisconnect: (device) => {\r\n\t\t\t\treturn _dm.disconnectDevice(device.deviceId);\r\n\t\t\t},\r\n\t\t\tautoConnect: (device, options?: any) => {\r\n\t\t\t\t// DeviceManager does not provide an autoConnect helper; return default\r\n\t\t\t\tconst result: AutoBleInterfaces = { serviceId: '', writeCharId: '', notifyCharId: '' };\r\n\t\t\t\treturn Promise.resolve(result);\r\n\t\t\t}\r\n\t\t};\r\n\t\tconst _wrapper = new ProtocolHandlerWrapper(_raw);\r\n\t\tactiveHandler = _wrapper;\r\n\t\tactiveProtocol = _raw.protocol as BleProtocolType;\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:275','[AKBLE] default protocol handler (BluetoothService-backed) registered', activeProtocol);\r\n\t}\r\n} catch (e) {\r\n\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/bluetooth_manager.uts:278','[AKBLE] failed to register default protocol handler', e);\r\n}","import * as BluetoothManager from './bluetooth_manager.uts';\r\nimport { ServiceManager } from './service_manager.uts';\r\nimport type { ScanDevicesOptions, BleConnectOptionsExt, MultiProtocolDevice, BleEvent, BleEventCallback, BleService, BleCharacteristic, WriteCharacteristicOptions, AutoBleInterfaces, BleDataReceivedCallback } from '../interface.uts';\r\nimport { DeviceManager } from './device_manager.uts';\r\n\r\nconst serviceManager = ServiceManager.getInstance();\r\n\r\nexport class BluetoothService {\r\n scanDevices(options?: ScanDevicesOptions) { return BluetoothManager.scanDevices(options); }\r\n connectDevice(deviceId: string, protocol: string, options?: BleConnectOptionsExt) { return BluetoothManager.connectDevice(deviceId, protocol, options); }\r\n disconnectDevice(deviceId: string, protocol: string) { return BluetoothManager.disconnectDevice(deviceId, protocol); }\r\n getConnectedDevices(): MultiProtocolDevice[] { return BluetoothManager.getConnectedDevices(); }\r\n on(event: BleEvent, callback: BleEventCallback) { return BluetoothManager.on(event, callback); }\r\n off(event: BleEvent, callback?: BleEventCallback) { return BluetoothManager.off(event, callback); }\r\n getServices(deviceId: string): Promise<BleService[]> {\r\n return new Promise((resolve, reject) => {\r\n serviceManager.getServices(deviceId, (list, err) => {\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:18','getServices:', list, err); // 新增日志\r\n if (err != null) reject(err);\r\n else resolve((list as BleService[]) ?? []);\r\n });\r\n });\r\n }\r\n getCharacteristics(deviceId: string, serviceId: string): Promise<BleCharacteristic[]> {\r\n return new Promise((resolve, reject) => {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:26',deviceId,serviceId)\r\n serviceManager.getCharacteristics(deviceId, serviceId, (list, err) => {\r\n if (err != null) reject(err);\r\n else resolve((list as BleCharacteristic[]) ?? []);\r\n });\r\n });\r\n }\r\n /**\r\n * 自动发现服务和特征返回可用的写入和通知特征ID\r\n * @param deviceId 设备ID\r\n * @returns {Promise<AutoBleInterfaces>}\r\n */\r\n async getAutoBleInterfaces(deviceId: string): Promise<AutoBleInterfaces> {\r\n // 1. 获取服务列表\r\n const services = await this.getServices(deviceId);\r\n if (services == null || services.length == 0) throw new Error('未发现服务');\r\n\r\n // 2. 选择目标服务优先bae前缀可根据需要调整\r\n let serviceId = '';\r\n for (let i = 0; i < services.length; i++) {\r\n const s = services[i];\r\n const uuidCandidate: string | null = (s.uuid != null ? s.uuid : null)\r\n const uuid: string = uuidCandidate != null ? uuidCandidate : ''\r\n // prefer regex test to avoid nullable receiver calls in generated Kotlin\r\n if (/^bae/i.test(uuid)) {\r\n serviceId = uuid\r\n break;\r\n }\r\n }\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:55',serviceId)\r\n if (serviceId == null || serviceId == '') serviceId = services[0].uuid;\r\n\r\n // 3. 获取特征列表\r\n const characteristics = await this.getCharacteristics(deviceId, serviceId);\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:60',characteristics)\r\n if (characteristics == null || characteristics.length == 0) throw new Error('未发现特征值');\r\n\r\n // 4. 筛选write和notify特征\r\n let writeCharId = '';\r\n let notifyCharId = '';\r\n for (let i = 0; i < characteristics.length; i++) {\r\n\t\t\r\n const c = characteristics[i];\r\n\t __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:69',c)\r\n if ((writeCharId == null || writeCharId == '') && c.properties != null && (c.properties.write || c.properties.writeWithoutResponse==true)) writeCharId = c.uuid;\r\n if ((notifyCharId == null || notifyCharId == '') && c.properties != null && (c.properties.notify || c.properties.indicate)) notifyCharId = c.uuid;\r\n }\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:73',serviceId, writeCharId, notifyCharId);\r\n if ((writeCharId == null || writeCharId == '') || (notifyCharId == null || notifyCharId == '')) throw new Error('未找到合适的写入或通知特征');\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:75',serviceId, writeCharId, notifyCharId);\r\n // // 发现服务和特征后\r\n\tconst deviceManager = DeviceManager.getInstance();\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:78',deviceManager);\r\n const device = deviceManager.getDevice(deviceId);\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:80',deviceId,device)\r\n device!.serviceId = serviceId;\r\n device!.writeCharId = writeCharId;\r\n device!.notifyCharId = notifyCharId;\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/index.uts:84',device);\r\n return { serviceId, writeCharId, notifyCharId };\r\n }\r\n async subscribeCharacteristic(deviceId: string, serviceId: string, characteristicId: string, onData: BleDataReceivedCallback): Promise<void> {\r\n return serviceManager.subscribeCharacteristic(deviceId, serviceId, characteristicId, onData);\r\n }\r\n async readCharacteristic(deviceId: string, serviceId: string, characteristicId: string): Promise<ArrayBuffer> {\r\n return serviceManager.readCharacteristic(deviceId, serviceId, characteristicId);\r\n }\r\n async writeCharacteristic(deviceId: string, serviceId: string, characteristicId: string, data: Uint8Array, options?: WriteCharacteristicOptions): Promise<boolean> {\r\n return serviceManager.writeCharacteristic(deviceId, serviceId, characteristicId, data, options);\r\n }\r\n async unsubscribeCharacteristic(deviceId: string, serviceId: string, characteristicId: string): Promise<void> {\r\n return serviceManager.unsubscribeCharacteristic(deviceId, serviceId, characteristicId);\r\n }\r\n async autoDiscoverAll(deviceId: string): Promise<any> {\r\n return serviceManager.autoDiscoverAll(deviceId);\r\n }\r\n async subscribeAllNotifications(deviceId: string, onData: BleDataReceivedCallback): Promise<void> {\r\n return serviceManager.subscribeAllNotifications(deviceId, onData);\r\n }\r\n}\r\n\r\nexport const bluetoothService = new BluetoothService();\r\n\r\n// Ensure protocol handlers are registered when this module is imported.\r\n // import './protocol_registry.uts';\r\n","import { BleService } from '../interface.uts'\r\nimport type { WriteCharacteristicOptions, DfuOptions, ControlParserResult } from '../interface.uts'\r\nimport { DeviceManager } from './device_manager.uts'\r\nimport { ServiceManager } from './service_manager.uts'\r\nimport BluetoothGatt from 'android.bluetooth.BluetoothGatt'\r\nimport BluetoothGattCharacteristic from 'android.bluetooth.BluetoothGattCharacteristic'\r\nimport BluetoothGattDescriptor from 'android.bluetooth.BluetoothGattDescriptor'\r\nimport UUID from 'java.util.UUID'\r\n\r\n// 通用 Nordic DFU UUIDs (常见设备可能使用这些;如厂商自定义请替换)\r\nconst DFU_SERVICE_UUID = '0000fe59-0000-1000-8000-00805f9b34fb'\r\nconst DFU_CONTROL_POINT_UUID = '8ec90001-f315-4f60-9fb8-838830daea50'\r\nconst DFU_PACKET_UUID = '8ec90002-f315-4f60-9fb8-838830daea50'\r\n\r\ntype DfuSession = {\r\n\tresolve : () => void;\r\n\treject : (err ?: any) => void;\r\n\tonProgress ?: (p : number) => void;\r\n\tonLog ?: (s : string) => void;\r\n\tcontrolParser ?: (data : Uint8Array) => ControlParserResult | null;\r\n\t// Nordic 专用字段\r\n\tbytesSent ?: number;\r\n\ttotalBytes ?: number;\r\n\tuseNordic ?: boolean;\r\n\t// PRN (packet receipt notification) support\r\n\tprn ?: number;\r\n\tpacketsSincePrn ?: number;\r\n\tprnResolve ?: () => void;\r\n\tprnReject ?: (err ?: any) => void;\r\n}\r\n\r\n\r\n\r\nexport class DfuManager {\r\n\t// 会话表,用于把 control-point 通知路由到当前 DFU 流程\r\n\tprivate sessions : Map<string, DfuSession> = new Map();\r\n\r\n\t// 简化:只实现最基本的 GATT-based DFU 上传逻辑,需按设备协议调整 control point 的命令/解析\r\n\r\n\t// Emit a DFU lifecycle event for a session. name should follow Nordic listener names\r\n\tprivate _emitDfuEvent(deviceId : string, name : string, payload ?: any) {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:42','[DFU][Event]', name, deviceId, payload ?? '');\r\n\t\tconst s = this.sessions.get(deviceId);\r\n\t\tif (s == null) return;\r\n\t\tif (typeof s.onLog == 'function') {\r\n\t\t\ttry {\r\n\t\t\t\tconst logFn = s.onLog as (msg : string) => void;\r\n\t\t\t\tlogFn(`[${name}] ${payload != null ? JSON.stringify(payload) : ''}`);\r\n\t\t\t} catch (e) { }\r\n\t\t}\r\n\t\tif (name == 'onProgress' && typeof s.onProgress == 'function' && typeof payload == 'number') {\r\n\t\t\ttry { s.onProgress(payload); } catch (e) { }\r\n\t\t}\r\n\t}\r\n\r\n\tasync startDfu(deviceId : string, firmwareBytes : Uint8Array, options ?: DfuOptions) : Promise<void> {\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:57','startDfu 0')\r\n\t\tconst deviceManager = DeviceManager.getInstance();\r\n\t\tconst serviceManager = ServiceManager.getInstance();\r\n __f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:60','startDfu 1')\r\n\t\tconst gatt : BluetoothGatt | null = deviceManager.getGattInstance(deviceId);\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:62','startDfu 2')\r\n\t\tif (gatt == null) throw new Error('Device not connected');\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:64','[DFU] startDfu start deviceId=', deviceId, 'firmwareBytes=', firmwareBytes != null ? firmwareBytes.length : 0, 'options=', options);\r\n\t\ttry {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:66','[DFU] requesting high connection priority for', deviceId);\r\n\t\t\tgatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);\r\n\t\t} catch (e) {\r\n\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:69','[DFU] requestConnectionPriority failed', e);\r\n\t\t}\r\n\r\n\t\t// 发现服务并特征\r\n\t\t// ensure services discovered before accessing GATT; serviceManager exposes Promise-based API\r\n\t\tawait serviceManager.getServices(deviceId, null);\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:75','[DFU] services ensured for', deviceId);\r\n\t\tconst dfuService = gatt.getService(UUID.fromString(DFU_SERVICE_UUID));\r\n\t\tif (dfuService == null) throw new Error('DFU service not found');\r\n\t\tconst controlChar = dfuService.getCharacteristic(UUID.fromString(DFU_CONTROL_POINT_UUID));\r\n\t\tconst packetChar = dfuService.getCharacteristic(UUID.fromString(DFU_PACKET_UUID));\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:80','[DFU] dfuService=', dfuService != null ? dfuService.getUuid().toString() : null, 'controlChar=', controlChar != null ? controlChar.getUuid().toString() : null, 'packetChar=', packetChar != null ? packetChar.getUuid().toString() : null);\r\n\t\tif (controlChar == null || packetChar == null) throw new Error('DFU characteristics missing');\r\n\t\tconst packetProps = packetChar.getProperties();\r\n\t\tconst supportsWriteWithResponse = (packetProps & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0;\r\n\t\tconst supportsWriteNoResponse = (packetProps & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0;\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:85','[DFU] packet characteristic props mask=', packetProps, 'supportsWithResponse=', supportsWriteWithResponse, 'supportsNoResponse=', supportsWriteNoResponse);\r\n\r\n\t// Allow caller to request a desired MTU via options for higher throughput\r\n\tconst desiredMtu = (options != null && typeof options.mtu == 'number') ? options.mtu : 247;\r\n\t\ttry {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:90','[DFU] requesting MTU=', desiredMtu, 'for', deviceId);\r\n\t\t\tawait this._requestMtu(gatt, desiredMtu, 8000);\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:92','[DFU] requestMtu completed for', deviceId);\r\n\t\t} catch (e) {\r\n\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:94','[DFU] requestMtu failed or timed out, continue with default.', e);\r\n\t\t}\r\n\t\tconst mtu = desiredMtu; // 假定成功或使用期望值\r\n\tconst chunkSize = Math.max(20, mtu - 3);\r\n\r\n\t\t// small helper to convert a byte (possibly signed) to a two-digit hex string\r\n\t\tconst byteToHex = (b : number) => {\r\n\t\t\tconst v = (b < 0) ? (b + 256) : b;\r\n\t\t\tlet s = v.toString(16);\r\n\t\t\tif (s.length < 2) s = '0' + s;\r\n\t\t\treturn s;\r\n\t\t};\r\n\r\n\t// Parameterize PRN window and timeout via options early so they are available\r\n\t\t// for session logging. Defaults: prn = 12 packets, prnTimeoutMs = 10000 ms\r\n\t\tlet prnWindow = 0;\r\n\t\tif (options != null && typeof options.prn == 'number') {\r\n\t\t\tprnWindow = Math.max(0, Math.floor(options.prn));\r\n\t\t}\r\n\t\tconst prnTimeoutMs = (options != null && typeof options.prnTimeoutMs == 'number') ? Math.max(1000, Math.floor(options.prnTimeoutMs)) : 8000;\r\n\t\tconst disablePrnOnTimeout = !(options != null && options.disablePrnOnTimeout == false);\r\n\r\n\t\t// 订阅 control point 通知并将通知路由到会话处理器\r\n\t\tconst controlHandler = (data : Uint8Array) => {\r\n\t\t\t// 交给会话处理器解析并触发事件\r\n\t\t\ttry {\r\n\t\t\t\tconst hexParts: string[] = [];\r\n\t\t\t\tfor (let i = 0; i < data.length; i++) {\r\n\t\t\t\t\tconst v = data[i] as number;\r\n\t\t\t\t\thexParts.push(byteToHex(v));\r\n\t\t\t\t}\r\n\t\t\t\tconst hex = hexParts.join(' ');\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:126','[DFU] control notification callback invoked for', deviceId, 'raw=', Array.from(data), 'hex=', hex);\r\n\t\t\t} catch (e) {\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:128','[DFU] control notification callback invoked for', deviceId, 'raw=', Array.from(data));\r\n\t\t\t}\r\n\t\t\tthis._handleControlNotification(deviceId, data);\r\n\t\t};\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:132','[DFU] subscribing control point for', deviceId);\r\n\t\tawait serviceManager.subscribeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_CONTROL_POINT_UUID, controlHandler);\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:134','[DFU] subscribeCharacteristic returned for', deviceId);\r\n\r\n\t\t// 保存会话回调(用于 waitForControlEvent; 支持 Nordic 模式追踪已发送字节\r\n\t\tthis.sessions.set(deviceId, {\r\n\t\t\tresolve: () => { },\r\n\t\t\treject: (err ?: any) => {__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:139',err) },\r\n\t\t\tonProgress: null,\r\n\t\t\tonLog: null,\r\n\t\t\tcontrolParser: (data : Uint8Array) => this._defaultControlParser(data),\r\n\t\t\tbytesSent: 0,\r\n\t\t\ttotalBytes: firmwareBytes.length,\r\n\t\t\tuseNordic: options != null && options.useNordic == true,\r\n\t\t\tprn: null,\r\n\t\t\tpacketsSincePrn: 0,\r\n\t\t\tprnResolve: null,\r\n\t\t\tprnReject: null\r\n\t\t});\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:151','[DFU] session created for', deviceId, 'totalBytes=', firmwareBytes.length);\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:152','[DFU] DFU session details:', { deviceId: deviceId, totalBytes: firmwareBytes.length, chunkSize: chunkSize, prnWindow: prnWindow, prnTimeoutMs: prnTimeoutMs });\r\n\r\n\t\t// wire options callbacks into the session (if provided)\r\n\t\tconst sessRef = this.sessions.get(deviceId);\r\n\t\tif (sessRef != null) {\r\n\t\t\tsessRef.onProgress = (options != null && typeof options.onProgress == 'function') ? options.onProgress : null;\r\n\t\t\tsessRef.onLog = (options != null && typeof options.onLog == 'function') ? options.onLog : null;\r\n\t\t}\r\n\r\n\t\t// emit initial lifecycle events (Nordic-like)\r\n\tthis._emitDfuEvent(deviceId, 'onDeviceConnecting', null);\r\n\r\n\t\t// 写入固件数据(非常保守的实现:逐包写入并等待短延迟)\r\n\t\t// --- PRN setup (optional, Nordic-style flow) ---\r\n\t\t// Parameterize PRN window and timeout via options: options.prn, options.prnTimeoutMs\r\n\t\t// Defaults were set earlier; build PRN payload using arithmetic to avoid\r\n\t\t// bitwise operators which don't map cleanly to generated Kotlin.\r\n\t\tif (prnWindow > 0) {\r\n\t\t\ttry {\r\n\t\t\t\t// send Set PRN to device (format: [OP_CODE_SET_PRN, prn LSB, prn MSB])\r\n\t\t\t\t// WARNING: Ensure your device uses the same opcode/format; change if needed.\r\n\t\t\t\tconst prnLsb = prnWindow % 256;\r\n\t\t\t\tconst prnMsb = Math.floor(prnWindow / 256) % 256;\r\n\t\t\t\tconst prnPayload = new Uint8Array([0x02, prnLsb, prnMsb]);\r\n\t\t\t\tawait serviceManager.writeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_CONTROL_POINT_UUID, prnPayload, null);\r\n\t\t\t\tconst sess0 = this.sessions.get(deviceId);\r\n\t\t\t\tif (sess0 != null) {\r\n\t\t\t\t\tsess0.useNordic = true;\r\n\t\t\t\t\tsess0.prn = prnWindow;\r\n\t\t\t\t\tsess0.packetsSincePrn = 0;\r\n\t\t\t\t\tsess0.controlParser = (data : Uint8Array) => this._nordicControlParser(data);\r\n\t\t\t\t}\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:184','[DFU] Set PRN sent (prn=', prnWindow, ') for', deviceId);\r\n\t\t\t} catch (e) {\r\n\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:186','[DFU] Set PRN failed (continuing without PRN):', e);\r\n\t\t\t\tconst sessFallback = this.sessions.get(deviceId);\r\n\t\t\t\tif (sessFallback != null) sessFallback.prn = 0;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:191','[DFU] PRN disabled (prnWindow=', prnWindow, ') for', deviceId);\r\n\t\t}\r\n\r\n\t// 写入固件数据(逐包写入并根据 options.waitForResponse 选择是否等待响应)\r\n\t\tlet offset = 0;\r\n\t\tconst total = firmwareBytes.length;\r\n\tthis._emitDfuEvent(deviceId, 'onDfuProcessStarted', null);\r\n\tthis._emitDfuEvent(deviceId, 'onUploadingStarted', null);\r\n\t\t// Track outstanding write operations when using fire-and-forget mode so we can\r\n\t\t// log and throttle if the Android stack becomes overwhelmed.\r\n\t\tlet outstandingWrites = 0;\r\n\t\t// read tuning parameters from options in a safe, generator-friendly way\r\n\t\tlet configuredMaxOutstanding = 2;\r\n\t\tlet writeSleepMs = 0;\r\n\t\tlet writeRetryDelay = 100;\r\n\t\tlet writeMaxAttempts = 12;\r\n\t\tlet writeGiveupTimeout = 60000;\r\n\t\tlet drainOutstandingTimeout = 3000;\r\n\t\tlet failureBackoffMs = 0;\r\n\r\n\t\t// throughput measurement\r\n\t\tlet throughputWindowBytes = 0;\r\n\t\tlet lastThroughputTime = Date.now();\r\n\t\tfunction _logThroughputIfNeeded(force ?: boolean) {\r\n\t\t\ttry {\r\n\t\t\t\tconst now = Date.now();\r\n\t\t\t\tconst elapsed = now - lastThroughputTime;\r\n\t\t\t\tif (force == true || elapsed >= 1000) {\r\n\t\t\t\t\tconst bytes = throughputWindowBytes;\r\n\t\t\t\t\tconst bps = Math.floor((bytes * 1000) / Math.max(1, elapsed));\r\n\t\t\t\t\t// reset window\r\n\t\t\t\t\tthroughputWindowBytes = 0;\r\n\t\t\t\t\tlastThroughputTime = now;\r\n\t\t\t\t\tconst human = `${bps} B/s`;\r\n\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:225','[DFU] throughput:', human, 'elapsedMs=', elapsed);\r\n\t\t\t\t\tconst s = this.sessions.get(deviceId);\r\n\t\t\t\t\tif (s != null && typeof s.onLog == 'function') {\r\n\t\t\t\t\t\ttry { s.onLog?.invoke('[DFU] throughput: ' + human); } catch (e) { }\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} catch (e) { }\r\n\t\t}\r\n\r\n\t\tfunction _safeErr(e ?: any) {\r\n\t\t\ttry {\r\n\t\t\t\tif (e == null) return '';\r\n\t\t\t\tif (typeof e == 'string') return e;\r\n\t\t\t\ttry { return JSON.stringify(e); } catch (e2) { }\r\n\t\t\t\ttry { return (e as any).toString(); } catch (e3) { }\r\n\t\t\t\treturn '';\r\n\t\t\t} catch (e4) { return ''; }\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tif (options != null) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (options.maxOutstanding != null) {\r\n\t\t\t\t\t\tconst parsed = Math.floor(options.maxOutstanding as number);\r\n\t\t\t\t\t\tif (!isNaN(parsed) && parsed > 0) configuredMaxOutstanding = parsed;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) { }\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (options.writeSleepMs != null) {\r\n\t\t\t\t\t\tconst parsedWs = Math.floor(options.writeSleepMs as number);\r\n\t\t\t\t\t\tif (!isNaN(parsedWs) && parsedWs >= 0) writeSleepMs = parsedWs;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) { }\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (options.writeRetryDelayMs != null) {\r\n\t\t\t\t\t\tconst parsedRetry = Math.floor(options.writeRetryDelayMs as number);\r\n\t\t\t\t\t\tif (!isNaN(parsedRetry) && parsedRetry >= 0) writeRetryDelay = parsedRetry;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) { }\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (options.writeMaxAttempts != null) {\r\n\t\t\t\t\t\tconst parsedAttempts = Math.floor(options.writeMaxAttempts as number);\r\n\t\t\t\t\t\tif (!isNaN(parsedAttempts) && parsedAttempts > 0) writeMaxAttempts = parsedAttempts;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) { }\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (options.writeGiveupTimeoutMs != null) {\r\n\t\t\t\t\t\tconst parsedGiveupTimeout = Math.floor(options.writeGiveupTimeoutMs as number);\r\n\t\t\t\t\t\tif (!isNaN(parsedGiveupTimeout) && parsedGiveupTimeout > 0) writeGiveupTimeout = parsedGiveupTimeout;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) { }\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (options.drainOutstandingTimeoutMs != null) {\r\n\t\t\t\t\t\tconst parsedDrain = Math.floor(options.drainOutstandingTimeoutMs as number);\r\n\t\t\t\t\t\tif (!isNaN(parsedDrain) && parsedDrain >= 0) drainOutstandingTimeout = parsedDrain;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) { }\r\n\t\t\t}\r\n\t\t\tif (configuredMaxOutstanding < 1) configuredMaxOutstanding = 1;\r\n\t\t\tif (writeSleepMs < 0) writeSleepMs = 0;\r\n\t\t} catch (e) { }\r\n\t\t\tif (supportsWriteWithResponse == false && supportsWriteNoResponse == true) {\r\n\t\t\t\tif (configuredMaxOutstanding > 1) configuredMaxOutstanding = 1;\r\n\t\t\t\tif (writeSleepMs < 15) writeSleepMs = 15;\r\n\t\t\t\tif (writeRetryDelay < 150) writeRetryDelay = 150;\r\n\t\t\t\tif (writeMaxAttempts < 40) writeMaxAttempts = 40;\r\n\t\t\t\tif (writeGiveupTimeout < 120000) writeGiveupTimeout = 120000;\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:291','[DFU] packet char only supports WRITE_NO_RESPONSE; serializing writes with conservative pacing');\r\n\t\t\t}\r\n\t\tconst maxOutstandingCeiling = configuredMaxOutstanding;\r\n\t\tlet adaptiveMaxOutstanding = configuredMaxOutstanding;\r\n\t\tconst minOutstandingWindow = 1;\r\n\r\n\t\twhile (offset < total) {\r\n\t\t\tconst end = Math.min(offset + chunkSize, total);\r\n\t\t\tconst slice = firmwareBytes.subarray(offset, end);\r\n\t\t\t// Decide whether to wait for response per-chunk. Honor characteristic support.\r\n\t\t\t// Generator-friendly: avoid 'undefined' and use explicit boolean check.\r\n\t\t\tlet finalWaitForResponse = true;\r\n\t\t\tif (options != null) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst maybe = options.waitForResponse;\r\n\t\t\t\t\tif (maybe == true && supportsWriteWithResponse == false && supportsWriteNoResponse == true) {\r\n\t\t\t\t\t\t// caller requested response but characteristic cannot provide it; keep true to ensure we await the write promise.\r\n\t\t\t\t\t\tfinalWaitForResponse = true;\r\n\t\t\t\t\t} else if (maybe == false) {\r\n\t\t\t\t\t\tfinalWaitForResponse = false;\r\n\t\t\t\t\t} else if (maybe == true) {\r\n\t\t\t\t\t\tfinalWaitForResponse = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) { finalWaitForResponse = true; }\r\n\t\t\t}\r\n\r\n\t\t\tconst writeOpts: WriteCharacteristicOptions = {\r\n\t\t\t\twaitForResponse: finalWaitForResponse,\r\n\t\t\t\tretryDelayMs: writeRetryDelay,\r\n\t\t\t\tmaxAttempts: writeMaxAttempts,\r\n\t\t\t\tgiveupTimeoutMs: writeGiveupTimeout,\r\n\t\t\t\tforceWriteTypeNoResponse: finalWaitForResponse == false\r\n\t\t\t};\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:324','[DFU] writing packet chunk offset=', offset, 'len=', slice.length, 'waitForResponse=', finalWaitForResponse, 'outstanding=', outstandingWrites);\r\n\r\n\t\t\t// Fire-and-forget path: do not await the write if waitForResponse == false.\r\n\t\t\tif (finalWaitForResponse == false) {\r\n\t\t\t\tif (failureBackoffMs > 0) {\r\n\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:329','[DFU] applying failure backoff', failureBackoffMs, 'ms before next write for', deviceId);\r\n\t\t\t\t\tawait this._sleep(failureBackoffMs);\r\n\t\t\t\t\tfailureBackoffMs = Math.floor(failureBackoffMs / 2);\r\n\t\t\t\t}\r\n\t\t\t\twhile (outstandingWrites >= adaptiveMaxOutstanding) {\r\n\t\t\t\t\tawait this._sleep(Math.max(1, writeSleepMs));\r\n\t\t\t\t}\r\n\t\t\t\t// increment outstanding counter and kick the write without awaiting.\r\n\t\t\t\toutstandingWrites = outstandingWrites + 1;\r\n\t\t\t\t// fire-and-forget: start the write but don't await its Promise\r\n\t\t\t\tconst writeOffset = offset;\r\n\t\t\t\tserviceManager.writeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_PACKET_UUID, slice, writeOpts).then((res) => {\r\n\t\t\t\t\toutstandingWrites = Math.max(0, outstandingWrites - 1);\r\n\t\t\t\t\tif (res == true) {\r\n\t\t\t\t\t\tif (adaptiveMaxOutstanding < maxOutstandingCeiling) {\r\n\t\t\t\t\t\t\tadaptiveMaxOutstanding = Math.min(maxOutstandingCeiling, adaptiveMaxOutstanding + 1);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (failureBackoffMs > 0) failureBackoffMs = Math.floor(failureBackoffMs / 2);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// log occasional completions\r\n\t\t\t\t\tif ((outstandingWrites & 0x1f) == 0) {\r\n\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:350','[DFU] write completion callback, outstandingWrites=', outstandingWrites, 'adaptiveWindow=', adaptiveMaxOutstanding, 'device=', deviceId);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// detect write failure signaled by service manager\r\n\t\t\t\t\tif (res !== true) {\r\n\t\t\t\t\t\tadaptiveMaxOutstanding = Math.max(minOutstandingWindow, Math.floor(adaptiveMaxOutstanding / 2));\r\n\t\t\t\t\t\tfailureBackoffMs = Math.min(200, Math.max(failureBackoffMs, Math.max(5, writeRetryDelay)));\r\n\t\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:356','[DFU] writeCharacteristic returned false for device=', deviceId, 'offset=', writeOffset, 'adaptiveWindow now=', adaptiveMaxOutstanding);\r\n\t\t\t\t\t\ttry { this._emitDfuEvent(deviceId, 'onError', { phase: 'write', offset: writeOffset, reason: 'write returned false' }); } catch (e) { }\r\n\t\t\t\t\t}\r\n\t\t\t\t}).catch((e) => {\r\n\t\t\t\t\toutstandingWrites = Math.max(0, outstandingWrites - 1);\r\n\t\t\t\t\tadaptiveMaxOutstanding = Math.max(minOutstandingWindow, Math.floor(adaptiveMaxOutstanding / 2));\r\n\t\t\t\t\tfailureBackoffMs = Math.min(200, Math.max(failureBackoffMs, Math.max(5, writeRetryDelay)));\r\n\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:363','[DFU] fire-and-forget write failed for device=', deviceId, e, 'adaptiveWindow now=', adaptiveMaxOutstanding);\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst errMsg ='[DFU] fire-and-forget write failed for device=';\r\n\t\t\t\t\t\tthis._emitDfuEvent(deviceId, 'onError', { phase: 'write', offset: writeOffset, reason: errMsg });\r\n\t\t\t\t\t} catch (e2) { }\r\n\t\t\t\t});\r\n\t\t\t\t// account bytes for throughput\r\n\t\t\t\tthroughputWindowBytes += slice.length;\r\n\t\t\t\t_logThroughputIfNeeded(false);\r\n\t\t\t} else {\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:373','[DFU] awaiting write for chunk offset=', offset);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst writeResult = await serviceManager.writeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_PACKET_UUID, slice, writeOpts);\r\n\t\t\t\t\tif (writeResult !== true) {\r\n\t\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:377','[DFU] writeCharacteristic(await) returned false at offset=', offset, 'device=', deviceId);\r\n\t\t\t\t\t\ttry { this._emitDfuEvent(deviceId, 'onError', { phase: 'write', offset: offset, reason: 'write returned false' }); } catch (e) { }\r\n\t\t\t\t\t\t// abort DFU by throwing\r\n\t\t\t\t\t\tthrow new Error('write failed');\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:383','[DFU] awaiting write failed at offset=', offset, 'device=', deviceId, e);\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst errMsg = '[DFU] awaiting write failed ';\r\n\t\t\t\t\t\tthis._emitDfuEvent(deviceId, 'onError', { phase: 'write', offset: offset, reason: errMsg });\r\n\t\t\t\t\t} catch (e2) { }\r\n\t\t\t\t\tthrow e;\r\n\t\t\t\t}\r\n\t\t\t\t// account bytes for throughput\r\n\t\t\t\tthroughputWindowBytes += slice.length;\r\n\t\t\t\t_logThroughputIfNeeded(false);\r\n\t\t\t}\r\n\t\t\t// update PRN counters and wait when window reached\r\n\t\t\tconst sessAfter = this.sessions.get(deviceId);\r\n\t\t\tif (sessAfter != null && sessAfter.useNordic == true && typeof sessAfter.prn == 'number' && (sessAfter.prn ?? 0) > 0) {\r\n\t\t\t\tsessAfter.packetsSincePrn = (sessAfter.packetsSincePrn ?? 0) + 1;\r\n\t\t\t\tif ((sessAfter.packetsSincePrn ?? 0) >= (sessAfter.prn ?? 0) && (sessAfter.prn ?? 0) > 0) {\r\n\t\t\t\t\t// wait for PRN (device notification) before continuing\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:401','[DFU] reached PRN window, waiting for PRN for', deviceId, 'packetsSincePrn=', sessAfter.packetsSincePrn, 'prn=', sessAfter.prn);\r\n\t\t\t\t\t\tawait this._waitForPrn(deviceId, prnTimeoutMs);\r\n\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:403','[DFU] PRN received, resuming transfer for', deviceId);\r\n\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:405','[DFU] PRN wait failed/timed out, continuing anyway for', deviceId, e);\r\n\t\t\t\t\t\tif (disablePrnOnTimeout) {\r\n\t\t\t\t\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:407','[DFU] disabling PRN waits after timeout for', deviceId);\r\n\t\t\t\t\t\t\tsessAfter.prn = 0;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// reset counter\r\n\t\t\t\t\tsessAfter.packetsSincePrn = 0;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\toffset = end;\r\n\t\t\t// 如果启用 nordic 模式,统计已发送字节\r\n\t\t\tconst sess = this.sessions.get(deviceId);\r\n\t\t\tif (sess != null && typeof sess.bytesSent == 'number') {\r\n\t\t\t\tsess.bytesSent = (sess.bytesSent ?? 0) + slice.length;\r\n\t\t\t}\r\n\t\t\t// 简单节流与日志,避免过快。默认睡眠非常短以提高吞吐量; 可在设备上调节\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:422','[DFU] wrote chunk for', deviceId, 'offset=', offset, '/', total, 'chunkSize=', slice.length, 'bytesSent=', sess != null ? sess.bytesSent : null, 'outstanding=', outstandingWrites);\r\n\t\t\t// emit upload progress event (percent) if available\r\n\t\t\tif (sess != null && typeof sess.bytesSent == 'number' && typeof sess.totalBytes == 'number') {\r\n\t\t\t\tconst p = Math.floor((sess.bytesSent / sess.totalBytes) * 100);\r\n\t\t\t\tthis._emitDfuEvent(deviceId, 'onProgress', p);\r\n\t\t\t}\r\n\t\t\t// yield to event loop and avoid starving the Android BLE stack\r\n\t\t\tawait this._sleep(Math.max(0, writeSleepMs));\r\n\t\t}\r\n\t// wait for outstanding writes to drain before continuing with control commands\r\n\tif (outstandingWrites > 0) {\r\n\t\tconst drainStart = Date.now();\r\n\t\twhile (outstandingWrites > 0 && (Date.now() - drainStart) < drainOutstandingTimeout) {\r\n\t\t\tawait this._sleep(Math.max(0, writeSleepMs));\r\n\t\t}\r\n\t\tif (outstandingWrites > 0) {\r\n\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:438','[DFU] outstandingWrites remain after drain timeout, continuing with', outstandingWrites);\r\n\t\t} else {\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:440','[DFU] outstandingWrites drained before control phase');\r\n\t\t}\r\n\t}\r\n\tthis._emitDfuEvent(deviceId, 'onUploadingCompleted', null);\r\n\r\n\t\t\t// force final throughput log before activate/validate\r\n\t\t\t_logThroughputIfNeeded(true);\r\n\r\n\t\t// 发送 activate/validate 命令到 control point需根据设备协议实现\r\n\t\t// 下面为占位:请替换为实际的 opcode\r\n\t\t// 在写入前先启动控制结果等待,防止设备快速响应导致丢失通知\r\n\t\tconst controlTimeout = 20000;\r\n\t\tconst controlResultPromise = this._waitForControlResult(deviceId, controlTimeout);\r\n\t\ttry {\r\n\t\t\t// control writes: pass undefined options explicitly to satisfy the generator/typechecker\r\n\t\t\tconst activatePayload = new Uint8Array([0x04]);\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:456','[DFU] sending activate/validate payload=', Array.from(activatePayload));\r\n\t\t\tawait serviceManager.writeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_CONTROL_POINT_UUID, activatePayload, null);\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:458','[DFU] activate/validate write returned for', deviceId);\r\n\t\t} catch (e) {\r\n\t\t\t// 写入失败时取消控制等待,避免悬挂定时器\r\n\t\t\ttry {\r\n\t\t\t\tconst sessOnWriteFail = this.sessions.get(deviceId);\r\n\t\t\t\tif (sessOnWriteFail != null && typeof sessOnWriteFail.reject == 'function') {\r\n\t\t\t\t\tsessOnWriteFail.reject(e);\r\n\t\t\t\t}\r\n\t\t\t} catch (rejectErr) { }\r\n\t\t\tawait controlResultPromise.catch(() => { });\r\n\t\t\ttry { await serviceManager.unsubscribeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_CONTROL_POINT_UUID); } catch (e2) { }\r\n\t\t\tthis.sessions.delete(deviceId);\r\n\t\t\tthrow e;\r\n\t\t}\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:472','[DFU] sent control activate/validate command to control point for', deviceId);\r\n\t\tthis._emitDfuEvent(deviceId, 'onValidating', null);\r\n\r\n\t// 等待 control-point 返回最终结果(成功或失败),超时可配置\r\n\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:476','[DFU] waiting for control result (timeout=', controlTimeout, ') for', deviceId);\r\n\ttry {\r\n\t\tawait controlResultPromise;\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:479','[DFU] control result resolved for', deviceId);\r\n\t} catch (err) {\r\n\t\t// 清理订阅后抛出\r\n\t\ttry { await serviceManager.unsubscribeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_CONTROL_POINT_UUID); } catch (e) { }\r\n\t\tthis.sessions.delete(deviceId);\r\n\t\tthrow err;\r\n\t}\r\n\r\n\t\t// 取消订阅\r\n\t\ttry {\r\n\t\t\tawait serviceManager.unsubscribeCharacteristic(deviceId, DFU_SERVICE_UUID, DFU_CONTROL_POINT_UUID);\r\n\t\t} catch (e) { }\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:491','[DFU] unsubscribed control point for', deviceId);\r\n\r\n\t\t// 清理会话\r\n\t\tthis.sessions.delete(deviceId);\r\n\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:495','[DFU] session cleared for', deviceId);\r\n\r\n\t\treturn;\r\n\t}\r\n\r\n\tasync _requestMtu(gatt : BluetoothGatt, mtu : number, timeoutMs : number) : Promise<void> {\r\n\t\treturn new Promise<void>((resolve, reject) => {\r\n\t\t\t// 在当前项目BluetoothGattCallback.onMtuChanged 未被封装;简单发起请求并等待短超时\r\n\t\t\ttry {\r\n\t\t\t\tconst ok = gatt.requestMtu(Math.floor(mtu) as Int);\r\n\t\t\t\tif (!ok) {\r\n\t\t\t\t\treturn reject(new Error('requestMtu failed'));\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\treturn reject(e);\r\n\t\t\t}\r\n\t\t\t// 无 callback 监听时退回,等待一小段时间以便成功\r\n\t\t\tsetTimeout(() => resolve(), Math.min(2000, timeoutMs));\r\n\t\t});\r\n\t}\r\n\r\n\t_sleep(ms : number) {\r\n\t\treturn new Promise<void>((r) => { setTimeout(() => { r() }, ms); });\r\n\t}\r\n\r\n\t_waitForPrn(deviceId : string, timeoutMs : number) : Promise<void> {\r\n\t\tconst session = this.sessions.get(deviceId);\r\n\t\tif (session == null) return Promise.reject(new Error('no dfu session'));\r\n\t\treturn new Promise<void>((resolve, reject) => {\r\n\t\t\tconst timer = setTimeout(() => {\r\n\t\t\t\t// timeout waiting for PRN\r\n\t\t\t\t// clear pending handlers\r\n\t\t\t\tsession.prnResolve = null;\r\n\t\t\t\tsession.prnReject = null;\r\n\t\t\t\treject(new Error('PRN timeout'));\r\n\t\t\t}, timeoutMs);\r\n\t\t\tconst prnResolve = () => {\r\n\t\t\t\tclearTimeout(timer);\r\n\t\t\t\tresolve();\r\n\t\t\t};\r\n\t\t\tconst prnReject = (err ?: any) => {\r\n\t\t\t\tclearTimeout(timer);\r\n\t\t\t\treject(err);\r\n\t\t\t};\r\n\t\t\tsession.prnResolve = prnResolve;\r\n\t\t\tsession.prnReject = prnReject;\r\n\t\t});\r\n\t}\r\n\r\n\t// 默认 control point 解析器(非常通用的尝试解析:如果设备发送 progress byte 或成功码)\r\n\t_defaultControlParser(data : Uint8Array) : ControlParserResult | null {\r\n\t\t// 假设协议:第一个字节为 opcode, 第二字节可为状态或进度\r\n\t\tif (data == null || data.length === 0) return null;\r\n\t\tconst op = data[0];\r\n\t\t// Nordic-style response: [0x10, requestOp, resultCode]\r\n\t\tif (op === 0x10 && data.length >= 3) {\r\n\t\t\tconst requestOp = data[1];\r\n\t\t\tconst resultCode = data[2];\r\n\t\t\tif (resultCode === 0x01) {\r\n\t\t\t\treturn { type: 'success' };\r\n\t\t\t}\r\n\t\t\treturn { type: 'error', error: { requestOp: requestOp, resultCode: resultCode, raw: Array.from(data) } };\r\n\t\t}\r\n\t\t// Nordic PRN notification: [0x11, LSB, MSB] -> return as progress (bytes received)\r\n\t\tif (op === 0x11 && data.length >= 3) {\r\n\t\t\tconst lsb = data[1];\r\n\t\t\tconst msb = data[2];\r\n\t\t\tconst received = (msb << 8) | lsb;\r\n\t\t\treturn { type: 'progress', progress: received };\r\n\t\t}\r\n\t\t// vendor-specific opcode example: 0x60 may mean 'response/progress' for some firmwares\r\n\t\tif (op === 0x60) {\r\n\t\t\tif (data.length >= 3) {\r\n\t\t\t\tconst requestOp = data[1];\r\n\t\t\t\tconst status = data[2];\r\n\t\t\t\t// Known success/status codes observed in field devices\r\n\t\t\t\tif (status === 0x00 || status === 0x01 || status === 0x0A) {\r\n\t\t\t\t\treturn { type: 'success' };\r\n\t\t\t\t}\r\n\t\t\t\treturn { type: 'error', error: { requestOp: requestOp, resultCode: status, raw: Array.from(data) } };\r\n\t\t\t}\r\n\t\t\tif (data.length >= 2) {\r\n\t\t\t\treturn { type: 'progress', progress: data[1] };\r\n\t\t\t}\r\n\t\t}\r\n\t\t// 通用进度回退:若第二字节位于 0-100 之间,当作百分比\r\n\t\tif (data.length >= 2) {\r\n\t\t\tconst maybeProgress = data[1];\r\n\t\t\tif (maybeProgress >= 0 && maybeProgress <= 100) {\r\n\t\t\t\treturn { type: 'progress', progress: maybeProgress };\r\n\t\t\t}\r\n\t\t}\r\n\t\t// 若找到明显的 success opcode (示例 0x01) 或 error 0xFF\r\n\t\tif (op === 0x01) return { type: 'success' };\r\n\t\tif (op === 0xFF) return { type: 'error', error: data };\r\n\t\treturn { type: 'info' };\r\n\t}\r\n\r\n\t// Nordic DFU control-parser支持 Response and Packet Receipt Notification\r\n\t_nordicControlParser(data : Uint8Array) : ControlParserResult | null {\r\n\t\t// Nordic opcodes (简化):\r\n\t\t// - 0x10 : Response (opcode, requestOp, resultCode)\r\n\t\t// - 0x11 : Packet Receipt Notification (opcode, value LSB, value MSB)\r\n\t\tif (data == null || data.length == 0) return null;\r\n\t\tconst op = data[0];\r\n\t\tif (op == 0x11 && data.length >= 3) {\r\n\t\t\t// packet receipt notif: bytes received (little endian)\r\n\t\t\tconst lsb = data[1];\r\n\t\t\tconst msb = data[2];\r\n\t\t\tconst received = (msb << 8) | lsb;\r\n\t\t\t// Return received bytes as progress value; parser does not resolve device-specific session here.\r\n\t\t\treturn { type: 'progress', progress: received };\r\n\t\t}\r\n\t\t// Nordic vendor-specific progress/response opcode (example 0x60)\r\n\t\tif (op == 0x60) {\r\n\t\t\tif (data.length >= 3) {\r\n\t\t\t\tconst requestOp = data[1];\r\n\t\t\t\tconst status = data[2];\r\n\t\t\t\tif (status == 0x00 || status == 0x01 || status == 0x0A) {\r\n\t\t\t\t\treturn { type: 'success' };\r\n\t\t\t\t}\r\n\t\t\t\treturn { type: 'error', error: { requestOp, resultCode: status, raw: Array.from(data) } };\r\n\t\t\t}\r\n\t\t\tif (data.length >= 2) {\r\n\t\t\t\treturn { type: 'progress', progress: data[1] };\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Response: check result code for success (0x01 may indicate success in some stacks)\r\n\t\tif (op == 0x10 && data.length >= 3) {\r\n\t\t\tconst requestOp = data[1];\r\n\t\t\tconst resultCode = data[2];\r\n\t\t\t// Nordic resultCode 0x01 = SUCCESS typically\r\n\t\t\tif (resultCode == 0x01) return { type: 'success' };\r\n\t\t\telse return { type: 'error', error: { requestOp, resultCode } };\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\t_handleControlNotification(deviceId : string, data : Uint8Array) {\r\n\t\tconst session = this.sessions.get(deviceId);\r\n\t\tif (session == null) {\r\n\t\t\t__f__('warn','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:636','[DFU] control notification received but no session for', deviceId, 'data=', Array.from(data));\r\n\t\t\treturn;\r\n\t\t}\r\n\t\ttry {\r\n\t\t\t// human readable opcode mapping\r\n\t\t\tlet opcodeName = 'unknown';\r\n\t\t\tswitch (data[0]) {\r\n\t\t\t\tcase 0x10: opcodeName = 'Response'; break;\r\n\t\t\t\tcase 0x11: opcodeName = 'PRN'; break;\r\n\t\t\t\tcase 0x60: opcodeName = 'VendorProgress'; break;\r\n\t\t\t\tcase 0x01: opcodeName = 'SuccessOpcode'; break;\r\n\t\t\t\tcase 0xFF: opcodeName = 'ErrorOpcode'; break;\r\n\t\t\t}\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:649','[DFU] _handleControlNotification deviceId=', deviceId, 'opcode=0x' + data[0].toString(16), 'name=', opcodeName, 'raw=', Array.from(data));\r\n\t\t\tconst parsed = session.controlParser != null ? session.controlParser(data) : null;\r\n\t\t\tif (session.onLog != null) session.onLog('DFU control notify: ' + Array.from(data).join(','));\r\n\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:652','[DFU] parsed control result=', parsed);\r\n\t\t\tif (parsed == null) return;\r\n\t\t\tif (parsed.type == 'progress' && parsed.progress != null) {\r\n\t\t\t\t// 如果在 nordic 模式 parsed.progress 可能是已接收字节数,则转换为百分比\r\n\t\t\t\tif (session.useNordic == true && session.totalBytes != null && session.totalBytes > 0) {\r\n\t\t\t\t\t\tconst percent = Math.floor((parsed.progress / session.totalBytes) * 100);\r\n\t\t\t\t\tsession.onProgress?.(percent);\r\n\t\t\t\t\t\t// If we have written all bytes locally, log that event\r\n\t\t\t\t\t\tif (session.bytesSent != null && session.totalBytes != null && session.bytesSent >= session.totalBytes) {\r\n\t\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:661','[DFU] all bytes written locally for', deviceId, 'bytesSent=', session.bytesSent, 'total=', session.totalBytes);\r\n\t\t\t\t\t\t\t// emit uploading completed once\r\n\t\t\t\t\t\t\tthis._emitDfuEvent(deviceId, 'onUploadingCompleted', null);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t// If a PRN wait is pending, resolve it (PRN indicates device received packets)\r\n\t\t\t\t\tif (typeof session.prnResolve == 'function') {\r\n\t\t\t\t\t\ttry { session.prnResolve(); } catch (e) { }\r\n\t\t\t\t\t\tsession.prnResolve = null;\r\n\t\t\t\t\t\tsession.prnReject = null;\r\n\t\t\t\t\t\tsession.packetsSincePrn = 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst progress = parsed.progress\r\n\t\t\t\t\tif (progress != null) {\r\n\t\t\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:675','[DFU] progress for', deviceId, 'progress=', progress);\r\n\t\t\t\t\t\tsession.onProgress?.(progress);\r\n\t\t\t\t\t\t// also resolve PRN if was waiting (in case device reports numeric progress)\r\n\t\t\t\t\t\tif (typeof session.prnResolve == 'function') {\r\n\t\t\t\t\t\t\ttry { session.prnResolve(); } catch (e) { }\r\n\t\t\t\t\t\t\tsession.prnResolve = null;\r\n\t\t\t\t\t\t\tsession.prnReject = null;\r\n\t\t\t\t\t\t\tsession.packetsSincePrn = 0;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else if (parsed.type == 'success') {\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:687','[DFU] parsed success for', deviceId, 'resolving session');\r\n\t\t\t\tsession.resolve();\r\n\t\t\t\t// Log final device-acknowledged success\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:690','[DFU] device reported DFU success for', deviceId);\r\n\t\t\t\tthis._emitDfuEvent(deviceId, 'onDfuCompleted', null);\r\n\t\t\t} else if (parsed.type == 'error') {\r\n\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:693','[DFU] parsed error for', deviceId, parsed.error);\r\n\t\t\t\tsession.reject(parsed.error ?? new Error('DFU device error'));\r\n\t\t\t\tthis._emitDfuEvent(deviceId, 'onError', parsed.error ?? {});\r\n\t\t\t} else {\r\n\t\t\t\t// info - just log\r\n\t\t\t}\r\n\t\t} catch (e) {\r\n\t\t\tsession.onLog?.('control parse error: ' + e);\r\n\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:701','[DFU] control parse exception for', deviceId, e);\r\n\t\t}\r\n\t}\r\n\r\n\t_waitForControlResult(deviceId : string, timeoutMs : number) : Promise<void> {\r\n\t\tconst session = this.sessions.get(deviceId);\r\n\t\tif (session == null) return Promise.reject(new Error('no dfu session'));\r\n\t\treturn new Promise<void>((resolve, reject) => {\r\n\t\t\t// wrap resolve/reject to clear timer\r\n\t\t\tconst timer = setTimeout(() => {\r\n\t\t\t\t// 超时\r\n\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:712','[DFU] _waitForControlResult timeout for', deviceId);\r\n\t\t\t\treject(new Error('DFU control timeout'));\r\n\t\t\t}, timeoutMs);\r\n\t\t\tconst origResolve = () => {\r\n\t\t\t\tclearTimeout(timer);\r\n\t\t\t\t__f__('log','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:717','[DFU] _waitForControlResult resolved for', deviceId);\r\n\t\t\t\tresolve();\r\n\t\t\t};\r\n\t\t\tconst origReject = (err ?: any) => {\r\n\t\t\t\tclearTimeout(timer);\r\n\t\t\t\t__f__('error','at uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts:722','[DFU] _waitForControlResult rejected for', deviceId, 'err=', err);\r\n\t\t\t\treject(err);\r\n\t\t\t};\r\n\t\t\t// replace session handlers temporarily (guard nullable)\r\n\t\t\tif (session != null) {\r\n\t\t\t\tsession.resolve = origResolve;\r\n\t\t\t\tsession.reject = origReject;\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}\r\n\r\nexport const dfuManager = new DfuManager();","<template>\r\n\t<scroll-view direction=\"vertical\" class=\"container\">\r\n\t\t<view class=\"section\">\r\n\t\t\t<button @click=\"scanDevices\" :disabled=\"scanning\">{{ scanning ? '正在扫描...' : '扫描设备' }}</button>\r\n\t\t\t<!-- \t\t\t<view style=\"display:flex; flex-direction:row; margin-left:12px; align-items:center\">\r\n\t\t\t\t<text style=\"margin-right:8px\">预设:</text>\r\n\t\t\t\t<radio-group :modelValue=\"presetSelected\" @change=\"onPresetChange\">\r\n\t\t\t\t\t<view v-for=\"(opt, index) in presetOptions\" :key=\"index\"\r\n\t\t\t\t\t\tstyle=\"margin-right:8px; display:flex; align-items:center\">\r\n\t\t\t\t\t\t<radio :value=\"opt['value'] as string\" />\r\n\t\t\t\t\t\t<text style=\"margin-left:4px\">{{ opt['label'] as string }}</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</radio-group>\r\n\t\t\t</view> -->\r\n\t\t\t<input v-model=\"optionalServicesInput\" placeholder=\"可选服务 UUID, 逗号分隔\" style=\"margin-left:12px; width: 40%\" />\r\n\t\t\t<button @click=\"autoConnect\" :disabled=\"connecting || devices.length == 0\"\r\n\t\t\t\tstyle=\"margin-left:12px;\">{{ connecting ? '正在自动连接...' : '自动连接' }}</button>\r\n\t\t\t<!-- Debug: show devices count and raw devices for troubleshooting -->\r\n\t\t\t<view>\r\n\t\t\t\t<text>设备计数: {{ devices.length }}</text>\r\n\t\t\t\t<text style=\"font-size:12px; color:gray\">{{ _fmt(devices) }}</text>\r\n\t\t\t</view>\r\n\t\t\t<view v-if=\"devices.length\">\r\n\t\t\t\t<text>已发现设备:</text>\r\n\t\t\t\t<view v-for=\"item in devices\" :key=\"item.deviceId\" class=\"device-item\">\r\n\t\t\t\t\t<text>{{ item.name!='' ? item.name : '未知设备' }} ({{ item.deviceId }})</text>\r\n\t\t\t\t\t<button @click=\"connect(item.deviceId)\">连接</button>\r\n\r\n\t\t\t\t\t<button v-if=\"connectedIds.includes(item.deviceId)\" @click=\"disconnect(item.deviceId)\"\r\n\t\t\t\t\t\t:disabled=\"disconnecting\">断开</button>\r\n\t\t\t\t\t<button v-if=\"connectedIds.includes(item.deviceId)\"\r\n\t\t\t\t\t\t@click=\"showServices(item.deviceId)\">查看服务</button>\r\n\t\t\t\t\t<button v-if=\"connectedIds.includes(item.deviceId)\"\r\n\t\t\t\t\t\t@click=\"autoDiscoverInterfaces(item.deviceId)\">自动发现接口</button>\r\n\t\t\t\t\t<button v-if=\"connectedIds.includes(item.deviceId)\"\r\n\t\t\t\t\t\t@click=\"getDeviceInfo(item.deviceId)\">设备信息</button>\r\n\r\n\t\t\t\t\t<!-- DFU 按钮,仅在 APP-ANDROID 可见 -->\r\n\r\n\t\t\t\t\t<button v-if=\"connectedIds.includes(item.deviceId)\" @click=\"startDfuFlow(item.deviceId)\">DFU\r\n\t\t\t\t\t\t升级</button>\r\n\t\t\t\t\t<button v-if=\"connectedIds.includes(item.deviceId)\"\r\n\t\t\t\t\t\t@click=\"startDfuFlow(item.deviceId, '/static/OmFw2510150943.zip')\">使用内置固件 DFU</button>\r\n\r\n\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\t\t<view class=\"section\">\r\n\t\t\t<text>日志:</text>\r\n\t\t\t<scroll-view direction=\"vertical\" style=\"height:240px;\">\r\n\t\t\t\t<text v-for=\"(log, idx) in logs\" :key=\"idx\" style=\"font-size:12px;\">{{ log }}</text>\r\n\t\t\t</scroll-view>\r\n\t\t</view>\r\n\t\t<view v-if=\"showingServicesFor\">\r\n\t\t\t<view class=\"section\">\r\n\t\t\t\t<text>设备 {{ showingServicesFor }} 的服务:</text>\r\n\t\t\t\t<view v-if=\"services.length\">\r\n\t\t\t\t\t<view v-for=\"srv in services\" :key=\"srv.uuid\" class=\"service-item\">\r\n\t\t\t\t\t\t<text>{{ srv.uuid }}</text>\r\n\t\t\t\t\t\t<button @click=\"showCharacteristics(showingServicesFor, srv.uuid)\">查看特征</button>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view v-else><text>无服务</text></view>\r\n\t\t\t\t<button @click=\"closeServices\">关闭</button>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\t\t<view v-if=\"showingCharacteristicsFor\">\r\n\t\t\t<view class=\"section\">\r\n\t\t\t\t<text>服务 的特征:</text>\r\n\t\t\t\t<view v-if=\"characteristics.length\">\r\n\t\t\t\t\t<view v-for=\"char in characteristics\" :key=\"char.uuid\" class=\"char-item\">\r\n\t\t\t\t\t\t<text>{{ char.uuid }} [{{ charProps(char) }}]</text>\r\n\t\t\t\t\t\t<view style=\"display:flex; flex-direction:row; margin-top:6px\">\r\n\t\t\t\t\t\t\t<button v-if=\"char.properties?.read\"\r\n\t\t\t\t\t\t\t\t@click=\"readCharacteristic(showingCharacteristicsFor.deviceId, showingCharacteristicsFor.serviceId, char.uuid)\">读取</button>\r\n\t\t\t\t\t\t\t<button v-if=\"char.properties?.write\"\r\n\t\t\t\t\t\t\t\t@click=\"writeCharacteristic(showingCharacteristicsFor.deviceId, showingCharacteristicsFor.serviceId, char.uuid)\">写入(测试)</button>\r\n\t\t\t\t\t\t\t<button v-if=\"char.properties?.notify\"\r\n\t\t\t\t\t\t\t\t@click=\"toggleNotify(showingCharacteristicsFor.deviceId, showingCharacteristicsFor.serviceId, char.uuid)\">{{ isNotifying(char.uuid) ? '取消订阅' : '订阅' }}</button>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view v-else><text>无特征</text></view>\r\n\t\t\t\t<button @click=\"closeCharacteristics\">关闭</button>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\t</scroll-view>\r\n</template>\r\n\r\n<script lang=\"uts\">\r\n\timport { BluetoothService } from '@/uni_modules/ak-sbsrv/utssdk/interface.uts'\r\n\t// Platform-specific entrypoint: import the platform index per build target to avoid bundler including Android-only code in web builds\r\n\r\n\timport { bluetoothService } from '@/uni_modules/ak-sbsrv/utssdk/app-android/index.uts'\r\n\r\n\r\n\r\n\r\n\timport type { BleDevice, BleService, BleCharacteristic } from '@/uni_modules/ak-sbsrv/utssdk/interface.uts'\r\n\timport { ProtocolHandler } from '@/uni_modules/ak-sbsrv/utssdk/protocol_handler.uts'\r\n\r\n\r\n\timport { dfuManager } from '@/uni_modules/ak-sbsrv/utssdk/app-android/dfu_manager.uts'\r\n\r\n\timport { PermissionManager } from '@/ak/PermissionManager.uts'\r\n\ttype ShowingCharacteristicsFor = {\r\n\t\tdeviceId : string,\r\n\t\tserviceId : string\r\n\t}\r\n\r\n\texport default {\r\n\t\tdata() {\r\n\t\t\treturn {\r\n\t\t\t\tscanning: false,\r\n\t\t\t\tconnecting: false,\r\n\t\t\t\tdisconnecting: false,\r\n\t\t\t\tdevices: [] as BleDevice[],\r\n\t\t\t\tconnectedIds: [] as string[],\r\n\t\t\t\tlogs: [] as string[],\r\n\t\t\t\tshowingServicesFor: '',\r\n\t\t\t\tservices: [] as BleService[],\r\n\t\t\t\tshowingCharacteristicsFor: { deviceId: '', serviceId: '' } as ShowingCharacteristicsFor,\r\n\t\t\t\tcharacteristics: [] as BleCharacteristic[],\r\n\t\t\t\t// 新增协议相关参数\r\n\t\t\t\tprotocolDeviceId: '',\r\n\t\t\t\tprotocolServiceId: '',\r\n\t\t\t\tprotocolWriteCharId: '',\r\n\t\t\t\tprotocolNotifyCharId: '',\r\n\t\t\t\t// protocol handler instances/cache\r\n\t\t\t\tprotocolHandlerMap: new Map<string, ProtocolHandler>(),\r\n\t\t\t\tprotocolHandler: null as ProtocolHandler | null,\r\n\t\t\t\t// optional services input (comma-separated UUIDs)\r\n\t\t\t\toptionalServicesInput: '',\r\n\t\t\t\t// presets for common BLE services (label -> UUID). 'custom' allows free-form input.\r\n\t\t\t\tpresetOptions: [\r\n\t\t\t\t\t{ label: '无', value: '' },\r\n\t\t\t\t\t{ label: 'Battery Service (180F)', value: '0000180f-0000-1000-8000-00805f9b34fb' },\r\n\t\t\t\t\t{ label: 'Device Information (180A)', value: '0000180a-0000-1000-8000-00805f9b34fb' },\r\n\t\t\t\t\t{ label: 'Generic Attribute (1801)', value: '00001801-0000-1000-8000-00805f9b34fb' },\r\n\t\t\t\t\t{ label: 'Nordic DFU', value: '00001530-1212-efde-1523-785feabcd123' },\r\n\t\t\t\t\t{ label: 'Nordic UART (NUS)', value: '6e400001-b5a3-f393-e0a9-e50e24dcca9e' },\r\n\t\t\t\t\t{ label: '自定义', value: 'custom' }\r\n\t\t\t\t],\r\n\t\t\t\tpresetSelected: '',\r\n\t\t\t\t// map of characteristicId -> boolean (is currently subscribed)\r\n\t\t\t\tnotifyingMap: new Map<string, boolean>(),\r\n\t\t\t}\r\n\t\t},\r\n\t\tmounted() {\r\n\t\t\tPermissionManager.requestBluetoothPermissions((granted : boolean) => {\r\n\t\t\t\tif (!granted) {\r\n\t\t\t\t\tuni.showToast({ title: '请授权蓝牙和定位权限', icon: 'none' });\r\n\t\t\t\t}\r\n\r\n\r\n\t\t\t});\r\n\t\t\tthis.log('页面 mounted: 初始化事件监听和蓝牙权限请求完成')\r\n\t\t\t// deviceFound - only accept devices whose name starts with 'CF' or 'BCL'\r\n\t\t\tbluetoothService.on('deviceFound', (payload) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t// this.log('[event] deviceFound -> ' + this._fmt(payload))\r\n\t\t\t\t\t// console.log('[event] deviceFound -> ' + this._fmt(payload))\r\n\t\t\t\t\t// payload can be UTSJSONObject-like or plain object. Normalize.\r\n\t\t\t\t\tlet rawDevice = payload?.device;\r\n\t\t\t\t\tif (rawDevice == null) {\r\n\t\t\t\t\t\tthis.log('[event] deviceFound - payload.device is null, ignoring');\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// extract name\r\n\t\t\t\t\tlet name : string | null = rawDevice.name;\r\n\r\n\t\t\t\t\tif (name == null) {\r\n\t\t\t\t\t\tthis.log('[event] deviceFound - 无名称,忽略: ' + this._fmt(rawDevice as any))\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tconst n = name as string;\r\n\t\t\t\t\tif (!(n.startsWith('CF') || n.startsWith('BCL'))) {\r\n\t\t\t\t\t\tthis.log('[event] deviceFound - 名称不匹配前缀,忽略: ' + n)\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tconst exists = this.devices.some(d => d != null && d.name == n);\r\n\r\n\t\t\t\t\tif (!exists) {\r\n\t\t\t\t\t\t// rawDevice is non-null here per earlier guard\r\n\t\t\t\t\t\tthis.devices.push(rawDevice as BleDevice);\r\n\t\t\t\t\t\tconst deviceIdStr = (rawDevice.deviceId != null) ? rawDevice.deviceId : '';\r\n\t\t\t\t\t\tthis.log('发现设备: ' + n + ' (' + deviceIdStr + ')');\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst deviceIdStr = (rawDevice.deviceId != null) ? rawDevice.deviceId : '';\r\n\t\t\t\t\t\tthis.log('发现重复设备: ' + n + ' (' + deviceIdStr + ')')\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tthis.log('[error] deviceFound handler error: ' + getErrorMessage(err))\r\n\t\t\t\t\tconsole.log(err)\r\n\t\t\t\t}\r\n\t\t\t})\r\n\r\n\t\t\t// scanFinished\r\n\t\t\tbluetoothService.on('scanFinished', (payload) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tthis.scanning = false\r\n\t\t\t\t\tthis.log('[event] scanFinished -> ' + this._fmt(payload))\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tthis.log('[error] scanFinished handler error: ' + getErrorMessage(err))\r\n\t\t\t\t}\r\n\t\t\t})\r\n\r\n\t\t\t// connectionStateChanged\r\n\t\t\tbluetoothService.on('connectionStateChanged', (payload) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tthis.log('[event] connectionStateChanged -> ' + this._fmt(payload))\r\n\t\t\t\t\tif (payload != null) {\r\n\t\t\t\t\t\tconst device = payload.device\r\n\t\t\t\t\t\tconst state = payload.state\r\n\t\t\t\t\t\tthis.log(`设备 ${device?.deviceId} 连接状态变为: ${state}`)\r\n\t\t\t\t\t\t// maintain connectedIds\r\n\t\t\t\t\t\tif (state == 2) {\r\n\t\t\t\t\t\t\tif (device != null && device.deviceId != null && !this.connectedIds.includes(device.deviceId)) {\r\n\t\t\t\t\t\t\t\tthis.connectedIds.push(device.deviceId)\r\n\t\t\t\t\t\t\t\tthis.log(`已记录已连接设备: ${device.deviceId}`)\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else if (state == 0) {\r\n\t\t\t\t\t\t\tif (device != null && device.deviceId != null) {\r\n\t\t\t\t\t\t\t\tthis.connectedIds = this.connectedIds.filter(id => id !== device.deviceId)\r\n\t\t\t\t\t\t\t\tthis.log(`已移除已断开设备: ${device.deviceId}`)\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tthis.log('[error] connectionStateChanged handler error: ' + getErrorMessage(err))\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t},\r\n\t\tmethods: {\r\n\t\t\tasync startDfuFlow(deviceId : string, staticFilePath : string = '') {\r\n\t\t\t\tif (staticFilePath != null && staticFilePath !== '') {\r\n\t\t\t\t\tthis.log('DFU 开始: 使用内置固件文件 ' + staticFilePath)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.log('DFU 开始: 请选择固件文件')\r\n\t\t\t\t}\r\n\t\t\t\ttry {\r\n\t\t\t\t\tlet chosenPath : string | null = null\r\n\t\t\t\t\tlet fileName : string | null = null\r\n\t\t\t\t\tif (staticFilePath != null && staticFilePath !== '') {\r\n\t\t\t\t\t\t// Use the app's bundled static file path\r\n\t\t\t\t\t\tchosenPath = staticFilePath.replace(/^\\/+/, '')\r\n\t\t\t\t\t\tconst tmpName = staticFilePath.split(/[\\/]/).pop()\r\n\t\t\t\t\t\tfileName = (tmpName != null && tmpName !== '') ? tmpName : staticFilePath\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst res = await new Promise<any>((resolve, reject) => {\r\n\t\t\t\t\t\t\tuni.chooseFile({ count: 1, success: (r) => resolve(r), fail: (e) => reject(e) })\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tconsole.log(res)\r\n\t\t\t\t\t\t// Generator-friendly: avoid property iteration or bracket indexing.\r\n\t\t\t\t\t\t// Serialize and regex-match common file fields (path/uri/tempFilePath/name).\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tconst s = (() => { try { return JSON.stringify(res); } catch (e) { return ''; } })()\r\n\t\t\t\t\t\t\tconst m = s.match(/\"(?:path|uri|tempFilePath|temp_file_path|tempFilePath|name)\"\\s*:\\s*\"([^\"]+)\"/i)\r\n\t\t\t\t\t\t\tif (m != null && m.length >= 2) {\r\n\t\t\t\t\t\t\t\tconst capturedCandidate : string | null = (m[1] != null ? m[1] : null)\r\n\t\t\t\t\t\t\t\tconst captured : string = capturedCandidate != null ? capturedCandidate : ''\r\n\t\t\t\t\t\t\t\tif (captured !== '') {\r\n\t\t\t\t\t\t\t\t\tchosenPath = captured\r\n\t\t\t\t\t\t\t\t\tconst toTest : string = captured\r\n\t\t\t\t\t\t\t\t\tif (!(/^[a-zA-Z]:\\\\|^\\\\\\//.test(toTest) || /:\\/\\//.test(toTest))) {\r\n\t\t\t\t\t\t\t\t\t\tconst m2 = s.match(/\"(?:path|uri|tempFilePath|temp_file_path|tempFilePath)\"\\s*:\\s*\"([^\"]+)\"/i)\r\n\t\t\t\t\t\t\t\t\t\tif (m2 != null && m2.length >= 2 && m2[1] != null) {\r\n\t\t\t\t\t\t\t\t\t\t\tconst pathCandidate : string = m2[1] != null ? ('' + m2[1]) : ''\r\n\t\t\t\t\t\t\t\t\t\t\tif (pathCandidate !== '') chosenPath = pathCandidate\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tconst nameMatch = s.match(/\"name\"\\s*:\\s*\"([^\"]+)\"/i)\r\n\t\t\t\t\t\t\tif (nameMatch != null && nameMatch.length >= 2 && nameMatch[1] != null) {\r\n\t\t\t\t\t\t\t\tconst nm : string = nameMatch[1] != null ? ('' + nameMatch[1]) : ''\r\n\t\t\t\t\t\t\t\tif (nm !== '') fileName = nm\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} catch (err) { /* ignore */ }\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (chosenPath == null || chosenPath == '') {\r\n\t\t\t\t\t\tthis.log('未选择文件')\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// filePath is non-null and non-empty here\r\n\t\t\t\t\tconst fpStr : string = chosenPath as string\r\n\t\t\t\t\tconst lastSeg = fpStr.split(/[\\/]/).pop();\r\n\t\t\t\t\tconst displayName = (fileName != null && fileName !== '') ? fileName : (lastSeg != null && lastSeg !== '' ? lastSeg : fpStr)\r\n\t\t\t\t\tthis.log('已选文件: ' + displayName + ' 路径: ' + fpStr)\r\n\t\t\t\t\tconst bytes = await this._readFileAsUint8Array(fpStr)\r\n\t\t\t\t\tthis.log('固件读取完成, 大小: ' + bytes.length)\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tawait dfuManager.startDfu(deviceId, bytes, {\r\n\t\t\t\t\t\t\tuseNordic: false,\r\n\t\t\t\t\t\t\tonProgress: (p : number) => this.log('DFU 进度: ' + p + '%'),\r\n\t\t\t\t\t\t\tonLog: (s : string) => this.log('DFU: ' + s),\r\n\t\t\t\t\t\t\tcontrolTimeout: 30000\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tthis.log('DFU 完成')\r\n\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\tthis.log('DFU 失败: ' + getErrorMessage(e))\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tconsole.log('选择或读取固件失败: ' + e)\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t_readFileAsUint8Array(path : string) : Promise<Uint8Array> {\r\n\t\t\t\treturn new Promise((resolve, reject) => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconsole.log('should readfile')\r\n\t\t\t\t\t\tconst fsm = uni.getFileSystemManager()\r\n\t\t\t\t\t\tconsole.log(fsm)\r\n\t\t\t\t\t\t// Read file as ArrayBuffer directly to avoid base64 encoding issues\r\n\t\t\t\t\t\tfsm.readFile({\r\n\t\t\t\t\t\t\tfilePath: path, success: (res) => {\r\n\t\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\t\tconst data = res.data as ArrayBuffer\r\n\t\t\t\t\t\t\t\t\tconst arr = new Uint8Array(data)\r\n\t\t\t\t\t\t\t\t\tresolve(arr)\r\n\t\t\t\t\t\t\t\t} catch (e) { reject(e) }\r\n\t\t\t\t\t\t\t}, fail: (err) => { reject(err) }\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t} catch (e) { reject(e) }\r\n\t\t\t\t})\r\n\t\t\t},\r\n\r\n\t\t\tlog(msg : string) {\r\n\t\t\t\tconst ts = new Date().toISOString();\r\n\t\t\t\tthis.logs.unshift(`[${ts}] ${msg}`)\r\n\t\t\t\tif (this.logs.length > 100) this.logs.length = 100\r\n\t\t\t},\r\n\t\t\t_fmt(obj : any) : string {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif (obj == null) return 'null'\r\n\t\t\t\t\tif (typeof obj == 'string') return obj\r\n\t\t\t\t\treturn JSON.stringify(obj)\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\treturn '' + obj\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tonPresetChange(e : any) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t// Some platforms emit { detail: { value: 'x' } }, others emit { value: 'x' } or just 'x'.\r\n\t\t\t\t\t// Serialize and regex-extract to avoid direct property access that the UTS->Kotlin generator may emit incorrectly.\r\n\t\t\t\t\tconst s = (() => { try { return JSON.stringify(e); } catch (err) { return ''; } })()\r\n\t\t\t\t\tlet val : string = this.presetSelected\r\n\t\t\t\t\t// try detail.value first\r\n\t\t\t\t\tconst m = s.match(/\"detail\"\\s*:\\s*\\{[^}]*\"value\"\\s*:\\s*\"([^\\\"]+)\"/i)\r\n\t\t\t\t\tif (m != null && m.length >= 2 && m[1] != null) {\r\n\t\t\t\t\t\tval = '' + m[1]\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst m2 = s.match(/\"value\"\\s*:\\s*\"([^\\\"]+)\"/i)\r\n\t\t\t\t\t\tif (m2 != null && m2.length >= 2 && m2[1] != null) {\r\n\t\t\t\t\t\t\tval = '' + m2[1]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.presetSelected = val\r\n\t\t\t\t\tif (val == 'custom' || val == '') {\r\n\t\t\t\t\t\tthis.log('已选择预设: ' + (val == 'custom' ? '自定义' : '无'))\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.optionalServicesInput = val;\r\n\t\t\t\t\tthis.log('已选择预设服务 UUID: ' + val)\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tthis.log('[error] onPresetChange: ' + getErrorMessage(err))\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tscanDevices() {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tthis.scanning = true\r\n\t\t\t\t\tthis.devices = []\r\n\t\t\t\t\t// prepare optional services: prefer free-form input, otherwise use selected preset (unless preset is 'custom' or empty)\r\n\t\t\t\t\tlet raw = (this.optionalServicesInput != null ? this.optionalServicesInput : '').trim();\r\n\t\t\t\t\tif (raw.length == 0 && this.presetSelected != null && this.presetSelected !== '' && this.presetSelected !== 'custom') {\r\n\t\t\t\t\t\traw = this.presetSelected;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// normalize helper: expand 16-bit UUIDs like '180F' to full 128-bit UUIDs\r\n\t\t\t\t\tconst normalize = (s : string) => {\r\n\t\t\t\t\t\tif (s == null || s.length == 0) return '';\r\n\t\t\t\t\t\tconst u = s.toLowerCase().replace(/^0x/, '').trim();\r\n\t\t\t\t\t\tconst hex = u.replace(/[^0-9a-f]/g, '');\r\n\t\t\t\t\t\tif (/^[0-9a-f]{4}$/.test(hex)) return `0000${hex}-0000-1000-8000-00805f9b34fb`;\r\n\t\t\t\t\t\treturn s;\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst optionalServices = raw.length > 0 ? raw.split(',').map(s => normalize(s.trim())).filter(s => s.length > 0) : []\r\n\t\t\t\t\tthis.log('开始扫描... optionalServices=' + JSON.stringify(optionalServices))\r\n\t\t\t\t\tbluetoothService.scanDevices({ \"protocols\": ['BLE'], \"optionalServices\": optionalServices })\r\n\t\t\t\t\t\t.then(() => {\r\n\t\t\t\t\t\t\tthis.log('scanDevices resolved')\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\t.catch((e) => {\r\n\t\t\t\t\t\t\tthis.log('[error] scanDevices failed: ' + getErrorMessage(e))\r\n\t\t\t\t\t\t\tthis.scanning = false\r\n\t\t\t\t\t\t})\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tthis.log('[error] scanDevices thrown: ' + getErrorMessage(err))\r\n\t\t\t\t\tthis.scanning = false\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tconnect(deviceId : string) {\r\n\t\t\t\tthis.connecting = true\r\n\t\t\t\tthis.log(`connect start -> ${deviceId}`)\r\n\t\t\t\ttry {\r\n\t\t\t\t\tbluetoothService.connectDevice(deviceId, 'BLE', { timeout: 10000 }).then(() => {\r\n\t\t\t\t\t\tif (!this.connectedIds.includes(deviceId)) this.connectedIds.push(deviceId)\r\n\t\t\t\t\t\tthis.log('连接成功: ' + deviceId)\r\n\t\t\t\t\t}).catch((e) => {\r\n\t\t\t\t\t\tthis.log('连接失败: ' + getErrorMessage(e!));\r\n\t\t\t\t\t}).finally(() => {\r\n\t\t\t\t\t\tthis.connecting = false\r\n\t\t\t\t\t\tthis.log(`connect finished -> ${deviceId}`)\r\n\t\t\t\t\t})\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tthis.log('[error] connect thrown: ' + getErrorMessage(err))\r\n\t\t\t\t\tthis.connecting = false\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tdisconnect(deviceId : string) {\r\n\t\t\t\tif (!this.connectedIds.includes(deviceId)) return\r\n\t\t\t\tthis.disconnecting = true\r\n\t\t\t\tthis.log(`disconnect start -> ${deviceId}`)\r\n\t\t\t\tbluetoothService.disconnectDevice(deviceId, 'BLE').then(() => {\r\n\t\t\t\t\tthis.log('已断开: ' + deviceId)\r\n\t\t\t\t\tthis.connectedIds = this.connectedIds.filter(id => id !== deviceId)\r\n\t\t\t\t\t// 清理协议处理器缓存\r\n\t\t\t\t\tthis.protocolHandlerMap.delete(deviceId)\r\n\t\t\t\t}).catch((e) => {\r\n\t\t\t\t\tthis.log('断开失败: ' + getErrorMessage(e!));\r\n\t\t\t\t}).finally(() => {\r\n\t\t\t\t\tthis.disconnecting = false\r\n\t\t\t\t\tthis.log(`disconnect finished -> ${deviceId}`)\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t\tshowServices(deviceId : string) {\r\n\t\t\t\tthis.showingServicesFor = deviceId\r\n\t\t\t\tthis.services = []\r\n\t\t\t\tthis.log(`showServices start -> ${deviceId}`)\r\n\t\t\t\tbluetoothService.getServices(deviceId).then((list) => {\r\n\t\t\t\t\tthis.log('showServices result -> ' + this._fmt(list))\r\n\t\t\t\t\tthis.services = list as BleService[]\r\n\t\t\t\t\tthis.log('服务数: ' + (list != null ? list.length : 0) + ' [' + deviceId + ']');\r\n\t\t\t\t}).catch((e) => {\r\n\t\t\t\t\tthis.log('获取服务失败: ' + getErrorMessage(e!));\r\n\t\t\t\t}).finally(() => {\r\n\t\t\t\t\tthis.log(`showServices finished -> ${deviceId}`)\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\tcloseServices() {\r\n\t\t\t\tthis.showingServicesFor = ''\r\n\t\t\t\tthis.services = []\r\n\t\t\t},\r\n\t\t\tshowCharacteristics(deviceId : string, serviceId : string) {\r\n\t\t\t\tthis.showingCharacteristicsFor = { deviceId, serviceId }\r\n\t\t\t\tthis.characteristics = []\r\n\t\t\t\tbluetoothService.getCharacteristics(deviceId, serviceId).then((list) => {\r\n\t\t\t\t\tthis.characteristics = list as BleCharacteristic[]\r\n\t\t\t\t\tconsole.log('特征数: ' + (list != null ? list.length : 0) + ' [' + deviceId + ']');\r\n\t\t\t\t\t// 自动查找可用的写入和通知特征\r\n\t\t\t\t\tconst writeChar = this.characteristics.find(c => c.properties.write)\r\n\t\t\t\t\tconst notifyChar = this.characteristics.find(c => c.properties.notify)\r\n\t\t\t\t\tif (writeChar != null && notifyChar != null) {\r\n\t\t\t\t\t\tthis.protocolDeviceId = deviceId\r\n\t\t\t\t\t\tthis.protocolServiceId = serviceId\r\n\t\t\t\t\t\tthis.protocolWriteCharId = writeChar.uuid\r\n\t\t\t\t\t\tthis.protocolNotifyCharId = notifyChar.uuid\r\n\t\t\t\t\t\tlet abs = bluetoothService as BluetoothService\r\n\t\t\t\t\t\tthis.protocolHandler = new ProtocolHandler(abs)\r\n\t\t\t\t\t\tlet handler = this.protocolHandler\r\n\t\t\t\t\t\thandler?.setConnectionParameters(deviceId, serviceId, writeChar.uuid, notifyChar.uuid)\r\n\t\t\t\t\t\thandler?.initialize()?.then(() => {\r\n\t\t\t\t\t\t\tconsole.log(\"协议处理器已初始化,可进行协议测试\")\r\n\t\t\t\t\t\t})?.catch(e => {\r\n\t\t\t\t\t\t\tconsole.log(\"协议处理器初始化失败: \" + getErrorMessage(e!))\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t}\r\n\t\t\t\t}).catch((e) => {\r\n\t\t\t\t\tconsole.log('获取特征失败: ' + getErrorMessage(e!));\r\n\t\t\t\t});\r\n\t\t\t\t// tracking notifying state\r\n\t\t\t\t// this.$set(this, 'notifyingMap', this.notifyingMap || {});\r\n\t\t\t},\r\n\t\t\tcloseCharacteristics() {\r\n\t\t\t\tthis.showingCharacteristicsFor = { deviceId: '', serviceId: '' }\r\n\t\t\t\tthis.characteristics = []\r\n\t\t\t},\r\n\t\t\tcharProps(char : BleCharacteristic) : string {\r\n\t\t\t\tconst p = char.properties\r\n\t\t\t\tconst parts = [] as string[]\r\n\t\t\t\tif (p.read) parts.push('R')\r\n\t\t\t\tif (p.write) parts.push('W')\r\n\t\t\t\tif (p.notify) parts.push('N')\r\n\t\t\t\tif (p.indicate) parts.push('I')\r\n\t\t\t\treturn parts.join('/')\r\n\t\t\t\t// return [p.read ? 'R' : '', p.write ? 'W' : '', p.notify ? 'N' : '', p.indicate ? 'I' : ''].filter(Boolean).join('/')\r\n\t\t\t},\r\n\t\t\tisNotifying(uuid : string) {\r\n\t\t\t\treturn this.notifyingMap.has(uuid) && this.notifyingMap.get(uuid) == true\r\n\t\t\t},\r\n\t\t\tasync readCharacteristic(deviceId : string, serviceId : string, charId : string) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tthis.log(`readCharacteristic ${charId} ...`)\r\n\t\t\t\t\tconst buf = await bluetoothService.readCharacteristic(deviceId, serviceId, charId)\r\n\t\t\t\t\tlet text = ''\r\n\t\t\t\t\ttry { text = new TextDecoder().decode(new Uint8Array(buf)) } catch (e) { text = '' }\r\n\t\t\t\t\tconst hex = Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join(' ')\r\n\t\t\t\t\tconsole.log(`读取 ${charId}: text='${text}' hex='${hex}'`)\r\n\t\t\t\t\tthis.log(`读取 ${charId}: text='${text}' hex='${hex}'`)\r\n\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tthis.log('读取特征失败: ' + getErrorMessage(e))\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tasync writeCharacteristic(deviceId : string, serviceId : string, charId : string) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst payload = new Uint8Array([0x01])\r\n\t\t\t\t\tconst ok = await bluetoothService.writeCharacteristic(deviceId, serviceId, charId, payload, null)\r\n\t\t\t\t\tif (ok) this.log(`写入 ${charId} 成功`);\r\n\t\t\t\t\telse this.log(`写入 ${charId} 失败`);\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tthis.log('写入特征失败: ' + getErrorMessage(e))\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tasync toggleNotify(deviceId : string, serviceId : string, charId : string) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst map = this.notifyingMap\r\n\t\t\t\t\tconst cur = map.get(charId) == true\r\n\t\t\t\t\tif (cur) {\r\n\t\t\t\t\t\t// unsubscribe\r\n\t\t\t\t\t\tawait bluetoothService.unsubscribeCharacteristic(deviceId, serviceId, charId)\r\n\t\t\t\t\t\tmap.set(charId, false)\r\n\t\t\t\t\t\tthis.log(`取消订阅 ${charId}`)\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// subscribe with callback\r\n\t\t\t\t\t\tawait bluetoothService.subscribeCharacteristic(deviceId, serviceId, charId, (payload : any) => {\r\n\t\t\t\t\t\t\tlet data : ArrayBuffer | null = null\r\n\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\tif (payload instanceof ArrayBuffer) {\r\n\t\t\t\t\t\t\t\t\tdata = payload\r\n\t\t\t\t\t\t\t\t} else if (payload != null && typeof payload == 'string') {\r\n\t\t\t\t\t\t\t\t\t// some runtimes deliver base64 strings\r\n\t\t\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\t\t\tconst s = atob(payload)\r\n\t\t\t\t\t\t\t\t\t\tconst tmp = new Uint8Array(s.length)\r\n\t\t\t\t\t\t\t\t\t\tfor (let i = 0; i < s.length; i++) {\r\n\t\t\t\t\t\t\t\t\t\t\tconst ch = s.charCodeAt(i)\r\n\t\t\t\t\t\t\t\t\t\t\ttmp[i] = (ch == null) ? 0 : (ch & 0xff)\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\tdata = tmp.buffer\r\n\t\t\t\t\t\t\t\t\t} catch (e) { data = null }\r\n\t\t\t\t\t\t\t\t} else if (payload != null && (payload as UTSJSONObject).get('data') instanceof ArrayBuffer) {\r\n\t\t\t\t\t\t\t\t\tdata = (payload as UTSJSONObject).get('data') as ArrayBuffer\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tconst arr = data != null ? new Uint8Array(data) : new Uint8Array([])\r\n\t\t\t\t\t\t\t\tconst hex = Array.from(arr).map(b => b.toString(16).padStart(2, '0')).join(' ')\r\n\t\t\t\t\t\t\t\tthis.log(`notify ${charId}: ${hex}`)\r\n\t\t\t\t\t\t\t} catch (e) { this.log('notify callback error: ' + getErrorMessage(e)) }\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tmap.set(charId, true)\r\n\t\t\t\t\t\tthis.log(`订阅 ${charId}`)\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tthis.log('订阅/取消订阅失败: ' + getErrorMessage(e))\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tautoConnect() {\r\n\t\t\t\tif (this.connecting) return;\r\n\t\t\t\tthis.connecting = true;\r\n\t\t\t\tconst toConnect = this.devices.filter(d => !this.connectedIds.includes(d.deviceId));\r\n\t\t\t\tif (toConnect.length == 0) {\r\n\t\t\t\t\tthis.log('没有可自动连接的设备');\r\n\t\t\t\t\tthis.connecting = false;\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tlet successCount = 0;\r\n\t\t\t\tlet failCount = 0;\r\n\t\t\t\tlet finished = 0;\r\n\t\t\t\ttoConnect.forEach(device => {\r\n\t\t\t\t\tbluetoothService.connectDevice(device.deviceId, 'BLE', { timeout: 10000 }).then(() => {\r\n\t\t\t\t\t\tif (!this.connectedIds.includes(device.deviceId)) this.connectedIds.push(device.deviceId);\r\n\t\t\t\t\t\tthis.log('自动连接成功: ' + device.deviceId);\r\n\t\t\t\t\t\tsuccessCount++;\r\n\t\t\t\t\t\t//\tthis.getOrInitProtocolHandler(device.deviceId);\r\n\t\t\t\t\t}).catch((e) => {\r\n\t\t\t\t\t\tthis.log('自动连接失败: ' + device.deviceId + ' ' + getErrorMessage(e!));\r\n\t\t\t\t\t\tfailCount++;\r\n\t\t\t\t\t}).finally(() => {\r\n\t\t\t\t\t\tfinished++;\r\n\t\t\t\t\t\tif (finished == toConnect.length) {\r\n\t\t\t\t\t\t\tthis.connecting = false;\r\n\t\t\t\t\t\t\tthis.log(`自动连接完成,成功${successCount},失败${failCount}`);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\tautoDiscoverInterfaces(deviceId : string) {\r\n\t\t\t\tthis.log('自动发现接口中...')\r\n\t\t\t\tbluetoothService.getAutoBleInterfaces(deviceId)\r\n\t\t\t\t\t.then((res) => {\r\n\t\t\t\t\t\tconsole.log(res)\r\n\t\t\t\t\t\tthis.log('自动发现接口成功: ' + JSON.stringify(res))\r\n\t\t\t\t\t})\r\n\t\t\t\t\t.catch((e) => {\r\n\t\t\t\t\t\tconsole.log(e)\r\n\t\t\t\t\t\tthis.log('自动发现接口失败: ' + getErrorMessage(e!))\r\n\t\t\t\t\t})\r\n\t\t\t},\r\n\t\t\t// 新增:测试电量功能\r\n\t\t\tasync getOrInitProtocolHandler(deviceId : string) : Promise<ProtocolHandler> {\r\n\t\t\t\tlet handler = this.protocolHandlerMap.get(deviceId);\r\n\t\t\t\tif (handler == null) {\r\n\t\t\t\t\t// 自动发现接口\r\n\t\t\t\t\tconst res = await bluetoothService.getAutoBleInterfaces(deviceId);\r\n\t\t\t\t\thandler = new ProtocolHandler(bluetoothService as BluetoothService);\r\n\t\t\t\t\thandler.setConnectionParameters(deviceId, res.serviceId, res.writeCharId, res.notifyCharId);\r\n\t\t\t\t\tawait handler.initialize();\r\n\t\t\t\t\tthis.protocolHandlerMap.set(deviceId, handler);\r\n\t\t\t\t\tthis.log(`协议处理器已初始化: ${deviceId}`);\r\n\t\t\t\t}\r\n\t\t\t\treturn handler!;\r\n\t\t\t},\r\n\r\n\t\t\tasync getDeviceInfo(deviceId : string) {\r\n\t\t\t\tthis.log('获取设备信息中...');\r\n\t\t\t\ttry {\r\n\t\t\t\t\t// First try protocol handler (if device exposes custom protocol)\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst handler = await this.getOrInitProtocolHandler(deviceId);\r\n\t\t\t\t\t\t// 获取电量\r\n\t\t\t\t\t\tconst battery = await handler.testBatteryLevel();\r\n\t\t\t\t\t\tthis.log('协议: 电量: ' + battery);\r\n\t\t\t\t\t\t// 获取软件/硬件版本\r\n\t\t\t\t\t\tconst swVersion = await handler.testVersionInfo(false);\r\n\t\t\t\t\t\tthis.log('协议: 软件版本: ' + swVersion);\r\n\t\t\t\t\t\tconst hwVersion = await handler.testVersionInfo(true);\r\n\t\t\t\t\t\tthis.log('协议: 硬件版本: ' + hwVersion);\r\n\t\t\t\t\t} catch (protoErr) {\r\n\t\t\t\t\t\tthis.log('协议处理器不可用或初始化失败,继续使用通用 GATT 查询: ' + ((protoErr != null && protoErr instanceof Error) ? protoErr.message : this._fmt(protoErr)));\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Additionally, attempt to read standard services: Generic Access (0x1800), Generic Attribute (0x1801), Battery (0x180F)\r\n\t\t\t\t\tconst stdServices = ['1800', '1801', '180f'].map(s => {\r\n\t\t\t\t\t\tconst hex = s.toLowerCase().replace(/^0x/, '');\r\n\t\t\t\t\t\treturn /^[0-9a-f]{4}$/.test(hex) ? `0000${hex}-0000-1000-8000-00805f9b34fb` : s;\r\n\t\t\t\t\t});\r\n\t\t\t\t\t// fetch services once to avoid repeated GATT server queries\r\n\t\t\t\t\tconst services = await bluetoothService.getServices(deviceId);\r\n\t\t\t\t\tfor (const svc of stdServices) {\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tthis.log('读取服务: ' + svc);\r\n\t\t\t\t\t\t\t// find matching service\r\n\t\t\t\t\t\t\tconst found = services.find((x : any) => {\r\n\t\t\t\t\t\t\t\tconst uuid = (x as UTSJSONObject).get('uuid')\r\n\t\t\t\t\t\t\t\treturn uuid != null && uuid.toString().toLowerCase() == svc.toLowerCase()\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\tif (found == null) {\r\n\t\t\t\t\t\t\t\tthis.log('未发现服务 ' + svc + '(需重新扫描并包含 optionalServices');\r\n\t\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tconst chars = await bluetoothService.getCharacteristics(deviceId, found?.uuid as string);\r\n\t\t\t\t\t\t\tconsole.log(`服务 ${svc} 包含 ${chars.length} 个特征`, chars);\r\n\t\t\t\t\t\t\tfor (const c of chars) {\r\n\t\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\t\tif (c.properties?.read == true) {\r\n\t\t\t\t\t\t\t\t\t\tconst buf = await bluetoothService.readCharacteristic(deviceId, found?.uuid as string, c.uuid);\r\n\t\t\t\t\t\t\t\t\t\t// try to decode as utf8 then hex\r\n\t\t\t\t\t\t\t\t\t\tlet text = '';\r\n\t\t\t\t\t\t\t\t\t\ttry { text = new TextDecoder().decode(new Uint8Array(buf)); } catch (e) { text = ''; }\r\n\t\t\t\t\t\t\t\t\t\tconst hex = Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join(' ');\r\n\t\t\t\t\t\t\t\t\t\tconsole.log(`特征 ${c.uuid} 读取: text='${text}' hex='${hex}'`);\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\tconsole.log(`特征 ${c.uuid} 不可读`);\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\t\t\t\tconsole.log(`读取特征 ${c.uuid} 失败: ${getErrorMessage(e)}`);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\t\tconsole.log('查询服务 ' + svc + ' 失败: ' + getErrorMessage(e));\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tconsole.log('获取设备信息失败: ' + getErrorMessage(e));\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tfunction getErrorMessage(e : Error | string | null) : string {\r\n\t\tif (e == null) return '';\r\n\t\tif (typeof e == 'string') return e;\r\n\t\ttry {\r\n\t\t\treturn JSON.stringify(e);\r\n\t\t} catch (err) {\r\n\t\t\treturn '' + e;\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style scoped>\r\n\t.container {\r\n\t\tpadding: 16px;\r\n\t\tflex: 1;\r\n\t}\r\n\r\n\t.section {\r\n\t\tmargin-bottom: 18px;\r\n\t}\r\n\r\n\t.device-item {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\tflex-wrap: wrap;\r\n\t}\r\n\r\n\t.service-item,\r\n\t.char-item {\r\n\t\tmargin: 6px 0;\r\n\t}\r\n\r\n\tbutton {\r\n\t\tmargin-left: 8px;\r\n\t}\r\n</style>","import 'F:/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts';import App from './App.uvue'\r\n\r\nimport { createSSRApp } from 'vue'\r\nexport function createApp() {\r\n\tconst app = createSSRApp(App)\r\n\treturn {\r\n\t\tapp\r\n\t}\r\n}\nexport function main(app: IApp) {\n definePageRoutes();\n defineAppConfig();\n (createApp()['app'] as VueApp).mount(app, GenUniApp());\n}\n\nexport class UniAppConfig extends io.dcloud.uniapp.appframe.AppConfig {\n override name: string = \"akbleserver\"\n override appid: string = \"__UNI__95B2570\"\n override versionName: string = \"1.0.1\"\n override versionCode: string = \"101\"\n override uniCompilerVersion: string = \"4.76\"\n \n constructor() { super() }\n}\n\nimport GenPagesAkbletestClass from './pages/akbletest.uvue'\nfunction definePageRoutes() {\n__uniRoutes.push({ path: \"pages/akbletest\", component: GenPagesAkbletestClass, meta: { isQuit: true } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"akble\"]]) } as UniPageRoute)\n}\nconst __uniTabBar: Map<string, any | null> | null = null\nconst __uniLaunchPage: Map<string, any | null> = _uM([[\"url\",\"pages/akbletest\"],[\"style\",_uM([[\"navigationBarTitleText\",\"akble\"]])]])\nfunction defineAppConfig(){\n __uniConfig.entryPagePath = '/pages/akbletest'\n __uniConfig.globalStyle = _uM([[\"navigationBarTextStyle\",\"black\"],[\"navigationBarTitleText\",\"体测训练\"],[\"navigationBarBackgroundColor\",\"#F8F8F8\"],[\"backgroundColor\",\"#F8F8F8\"]])\n __uniConfig.getTabBarConfig = ():Map<string, any> | null => null\n __uniConfig.tabBar = __uniConfig.getTabBarConfig()\n __uniConfig.conditionUrl = ''\n __uniConfig.uniIdRouter = _uM()\n \n __uniConfig.ready = true\n}\n","export type GetBatteryInfoSuccess = {\n\terrMsg : string,\n\t/**\n\t* 设备电量范围1 - 100\n\t*/\n\tlevel : number,\n\t/**\n\t* 是否正在充电中\n\t*/\n\tisCharging : boolean\n}\n\nexport type GetBatteryInfoOptions = {\n\t/**\n\t\t* 接口调用结束的回调函数(调用成功、失败都会执行)\n\t\t*/\n\tsuccess ?: (res : GetBatteryInfoSuccess) => void\n\t/**\n\t\t* 接口调用失败的回调函数\n\t\t*/\n\tfail ?: (res : UniError) => void\n\t/**\n\t\t* 接口调用成功的回调\n\t\t*/\n\tcomplete ?: (res : any) => void\n}\n\nexport type GetBatteryInfoResult = {\n\t/**\n\t* 设备电量范围1 - 100\n\t*/\n\tlevel : number,\n\t/**\n\t* 是否正在充电中\n\t*/\n\tisCharging : boolean\n}\n\n/**\n * 错误码\n * - 1001 getAppContext is null\n */\nexport type GetBatteryInfoErrorCode = 1001 ;\n/**\n * GetBatteryInfo 的错误回调参数\n */\nexport interface GetBatteryInfoFail extends IUniError {\n errCode : GetBatteryInfoErrorCode\n};\n\n/**\n* 获取电量信息\n* @param {GetBatteryInfoOptions} options\n*\n*\n* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html\n* @platforms APP-IOS = ^9.0,APP-ANDROID = ^22\n* @since 3.6.11\n*\n* @assert () => success({errCode: 0, errSubject: \"uni-getBatteryInfo\", errMsg: \"getBatteryInfo:ok\", level: 60, isCharging: false })\n* @assert () => fail({errCode: 1001, errSubject: \"uni-getBatteryInfo\", errMsg: \"getBatteryInfo:fail getAppContext is null\" })\n*/\nexport type GetBatteryInfo = (options : GetBatteryInfoOptions) => void\n\n\nexport type GetBatteryInfoSync = () => GetBatteryInfoResult\n\ninterface Uni {\n\n\t/**\n\t * 获取电池电量信息\n\t * @description 获取电池电量信息\n\t * @param {GetBatteryInfoOptions} options\n\t * @example\n\t * ```typescript\n\t * uni.getBatteryInfo({\n\t *\t\tsuccess(res) {\n\t *\t\t\tconsole.log(res);\n\t *\t\t}\n\t * })\n\t * ```\n\t * @remark\n\t * - 该接口需要同步调用\n\t * @uniPlatform {\n\t * \"app\": {\n\t * \"android\": {\n\t * \"osVer\": \"4.4.4\",\n\t * \"uniVer\": \"3.6.11\",\n\t * \"unixVer\": \"3.9.0\"\n\t * },\n\t * \"ios\": {\n\t * \"osVer\": \"12.0\",\n\t * \"uniVer\": \"3.6.11\",\n\t * \"unixVer\": \"4.11\"\n\t * }\n\t * },\n\t * \"web\": {\n\t * \"uniVer\": \"3.6.11\",\n\t * \"unixVer\": \"4.0\"\n\t * }\n\t * }\n\t * @uniVueVersion 2,3 //支持的vue版本\n\t *\n\t */\n\tgetBatteryInfo (options : GetBatteryInfoOptions) : void,\n\t/**\n\t * 同步获取电池电量信息\n\t * @description 获取电池电量信息\n\t * @example\n\t * ```typescript\n\t * uni.getBatteryInfo()\n\t * ```\n\t * @remark\n\t * - 该接口需要同步调用\n\t * @uniPlatform {\n\t * \"app\": {\n\t * \"android\": {\n\t * \"osVer\": \"4.4.4\",\n\t * \"uniVer\": \"3.6.11\",\n\t * \"unixVer\": \"3.9.0\"\n\t * },\n\t * \"ios\": {\n\t * \"osVer\": \"12.0\",\n\t * \"uniVer\": \"3.6.11\",\n\t * \"unixVer\": \"4.11\"\n\t * }\n\t * },\n\t * \"web\": {\n\t * \"uniVer\": \"3.6.11\",\n\t * \"unixVer\": \"4.0\"\n\t * }\n\t * }\n\t * @uniVueVersion 2,3 //支持的vue版本\n\t *\n\t */\n\tgetBatteryInfoSync():GetBatteryInfoResult\n\n}\n"],"names":[],"mappings":"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"}