@capacitor-community/bluetooth-le 7.1.1 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -161
- package/android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/BluetoothLe.kt +47 -21
- package/android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/Device.kt +87 -36
- package/dist/docs.json +957 -890
- package/dist/esm/bleClient.d.ts +3 -2
- package/dist/esm/bleClient.js +18 -6
- package/dist/esm/bleClient.js.map +1 -1
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/conversion.d.ts +12 -0
- package/dist/esm/conversion.js +33 -0
- package/dist/esm/conversion.js.map +1 -1
- package/dist/esm/definitions.d.ts +42 -3
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/queue.js.map +1 -1
- package/dist/esm/timeout.js.map +1 -1
- package/dist/esm/validators.js.map +1 -1
- package/dist/esm/web.d.ts +1 -0
- package/dist/esm/web.js +66 -3
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +118 -8
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +118 -8
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/DeviceListView.swift +121 -0
- package/ios/Plugin/DeviceManager.swift +114 -13
- package/ios/Plugin/Plugin.swift +61 -6
- package/package.json +13 -3
package/dist/esm/web.js
CHANGED
|
@@ -80,11 +80,15 @@ export class BluetoothLeWeb extends WebPlugin {
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
onAdvertisementReceived(event) {
|
|
83
|
-
var _a, _b;
|
|
83
|
+
var _a, _b, _c;
|
|
84
84
|
const deviceId = event.device.id;
|
|
85
85
|
this.deviceMap.set(deviceId, event.device);
|
|
86
86
|
const isNew = !this.discoveredDevices.has(deviceId);
|
|
87
|
-
|
|
87
|
+
// Apply service data filtering client-side (Web Bluetooth API doesn't support it in scan filters)
|
|
88
|
+
if (((_a = this.requestBleDeviceOptions) === null || _a === void 0 ? void 0 : _a.serviceData) && !this.matchesServiceDataFilter(event)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (isNew || ((_b = this.requestBleDeviceOptions) === null || _b === void 0 ? void 0 : _b.allowDuplicates)) {
|
|
88
92
|
this.discoveredDevices.set(deviceId, true);
|
|
89
93
|
const device = this.getBleDevice(event.device);
|
|
90
94
|
const result = {
|
|
@@ -94,7 +98,7 @@ export class BluetoothLeWeb extends WebPlugin {
|
|
|
94
98
|
txPower: event.txPower,
|
|
95
99
|
manufacturerData: mapToObject(event.manufacturerData),
|
|
96
100
|
serviceData: mapToObject(event.serviceData),
|
|
97
|
-
uuids: (
|
|
101
|
+
uuids: (_c = event.uuids) === null || _c === void 0 ? void 0 : _c.map(webUUIDToString),
|
|
98
102
|
};
|
|
99
103
|
this.notifyListeners('onScanResult', result);
|
|
100
104
|
}
|
|
@@ -315,12 +319,71 @@ export class BluetoothLeWeb extends WebPlugin {
|
|
|
315
319
|
});
|
|
316
320
|
}
|
|
317
321
|
for (const manufacturerData of (_b = options === null || options === void 0 ? void 0 : options.manufacturerData) !== null && _b !== void 0 ? _b : []) {
|
|
322
|
+
// Cast to any to avoid type incompatibility - conversion is handled in bleClient.ts
|
|
318
323
|
filters.push({
|
|
319
324
|
manufacturerData: [manufacturerData],
|
|
320
325
|
});
|
|
321
326
|
}
|
|
327
|
+
// Note: Web Bluetooth API does not support service data in scan filters.
|
|
328
|
+
// Service data filtering will be done client-side in onAdvertisementReceived.
|
|
329
|
+
// We still accept serviceData in options for API consistency across platforms.
|
|
322
330
|
return filters;
|
|
323
331
|
}
|
|
332
|
+
matchesServiceDataFilter(event) {
|
|
333
|
+
var _a;
|
|
334
|
+
const filters = (_a = this.requestBleDeviceOptions) === null || _a === void 0 ? void 0 : _a.serviceData;
|
|
335
|
+
if (!filters || filters.length === 0) {
|
|
336
|
+
return true; // No filters, accept all
|
|
337
|
+
}
|
|
338
|
+
if (!event.serviceData) {
|
|
339
|
+
return false; // No service data in advertisement
|
|
340
|
+
}
|
|
341
|
+
// Check if any filter matches (OR logic)
|
|
342
|
+
for (const filter of filters) {
|
|
343
|
+
const serviceData = event.serviceData.get(filter.serviceUuid);
|
|
344
|
+
if (!serviceData) {
|
|
345
|
+
continue; // This filter doesn't match, try next
|
|
346
|
+
}
|
|
347
|
+
// If we have service data for this UUID
|
|
348
|
+
if (!filter.dataPrefix) {
|
|
349
|
+
return true; // Filter matched by service UUID alone
|
|
350
|
+
}
|
|
351
|
+
// Check data prefix (DataView on web)
|
|
352
|
+
const data = new Uint8Array(serviceData.buffer);
|
|
353
|
+
const prefixView = filter.dataPrefix;
|
|
354
|
+
if (data.length < prefixView.byteLength) {
|
|
355
|
+
continue; // Data too short
|
|
356
|
+
}
|
|
357
|
+
// Apply mask if provided
|
|
358
|
+
if (filter.mask) {
|
|
359
|
+
const maskView = filter.mask;
|
|
360
|
+
let matches = true;
|
|
361
|
+
for (let i = 0; i < prefixView.byteLength; i++) {
|
|
362
|
+
if ((data[i] & maskView.getUint8(i)) !== (prefixView.getUint8(i) & maskView.getUint8(i))) {
|
|
363
|
+
matches = false;
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (matches) {
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
// Check if data starts with prefix
|
|
373
|
+
let matches = true;
|
|
374
|
+
for (let i = 0; i < prefixView.byteLength; i++) {
|
|
375
|
+
if (data[i] !== prefixView.getUint8(i)) {
|
|
376
|
+
matches = false;
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (matches) {
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return false; // No filter matched
|
|
386
|
+
}
|
|
324
387
|
getDeviceFromMap(deviceId) {
|
|
325
388
|
const device = this.deviceMap.get(deviceId);
|
|
326
389
|
if (device === undefined) {
|
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\r\n\r\nimport { hexStringToDataView, mapToObject, webUUIDToString } from './conversion';\r\nimport type {\r\n BleCharacteristic,\r\n BleCharacteristicProperties,\r\n BleDescriptor,\r\n BleService,\r\n TimeoutOptions,\r\n BleDevice,\r\n BleServices,\r\n BluetoothLePlugin,\r\n BooleanResult,\r\n DeviceIdOptions,\r\n GetConnectedDevicesOptions,\r\n GetDevicesOptions,\r\n GetDevicesResult,\r\n ReadDescriptorOptions,\r\n ReadOptions,\r\n ReadResult,\r\n ReadRssiResult,\r\n RequestBleDeviceOptions,\r\n ScanResultInternal,\r\n WriteOptions,\r\n WriteDescriptorOptions,\r\n GetMtuResult,\r\n RequestConnectionPriorityOptions,\r\n} from './definitions';\r\nimport { runWithTimeout } from './timeout';\r\n\r\nexport class BluetoothLeWeb extends WebPlugin implements BluetoothLePlugin {\r\n private deviceMap = new Map<string, BluetoothDevice>();\r\n private discoveredDevices = new Map<string, boolean>();\r\n private scan: BluetoothLEScan | null = null;\r\n private requestBleDeviceOptions: RequestBleDeviceOptions | undefined;\r\n private DEFAULT_CONNECTION_TIMEOUT = 10000;\r\n\r\n async initialize(): Promise<void> {\r\n if (typeof navigator === 'undefined' || !navigator.bluetooth) {\r\n throw this.unavailable('Web Bluetooth API not available in this browser.');\r\n }\r\n const isAvailable = await navigator.bluetooth.getAvailability();\r\n if (!isAvailable) {\r\n throw this.unavailable('No Bluetooth radio available.');\r\n }\r\n }\r\n\r\n async isEnabled(): Promise<BooleanResult> {\r\n // not available on web\r\n return { value: true };\r\n }\r\n\r\n async requestEnable(): Promise<void> {\r\n throw this.unavailable('requestEnable is not available on web.');\r\n }\r\n\r\n async enable(): Promise<void> {\r\n throw this.unavailable('enable is not available on web.');\r\n }\r\n\r\n async disable(): Promise<void> {\r\n throw this.unavailable('disable is not available on web.');\r\n }\r\n\r\n async startEnabledNotifications(): Promise<void> {\r\n // not available on web\r\n }\r\n\r\n async stopEnabledNotifications(): Promise<void> {\r\n // not available on web\r\n }\r\n\r\n async isLocationEnabled(): Promise<BooleanResult> {\r\n throw this.unavailable('isLocationEnabled is not available on web.');\r\n }\r\n\r\n async openLocationSettings(): Promise<void> {\r\n throw this.unavailable('openLocationSettings is not available on web.');\r\n }\r\n\r\n async openBluetoothSettings(): Promise<void> {\r\n throw this.unavailable('openBluetoothSettings is not available on web.');\r\n }\r\n\r\n async openAppSettings(): Promise<void> {\r\n throw this.unavailable('openAppSettings is not available on web.');\r\n }\r\n\r\n async setDisplayStrings(): Promise<void> {\r\n // not available on web\r\n }\r\n\r\n async requestDevice(options?: RequestBleDeviceOptions): Promise<BleDevice> {\r\n const filters = this.getFilters(options);\r\n const device = await navigator.bluetooth.requestDevice({\r\n filters: filters.length ? filters : undefined,\r\n optionalServices: options?.optionalServices,\r\n acceptAllDevices: filters.length === 0,\r\n });\r\n this.deviceMap.set(device.id, device);\r\n const bleDevice = this.getBleDevice(device);\r\n return bleDevice;\r\n }\r\n\r\n async requestLEScan(options?: RequestBleDeviceOptions): Promise<void> {\r\n this.requestBleDeviceOptions = options;\r\n const filters = this.getFilters(options);\r\n await this.stopLEScan();\r\n this.discoveredDevices = new Map<string, boolean>();\r\n navigator.bluetooth.removeEventListener(\r\n 'advertisementreceived',\r\n this.onAdvertisementReceivedCallback as EventListener,\r\n );\r\n navigator.bluetooth.addEventListener('advertisementreceived', this.onAdvertisementReceivedCallback);\r\n this.scan = await navigator.bluetooth.requestLEScan({\r\n filters: filters.length ? filters : undefined,\r\n acceptAllAdvertisements: filters.length === 0,\r\n keepRepeatedDevices: options?.allowDuplicates,\r\n });\r\n }\r\n\r\n private onAdvertisementReceivedCallback = this.onAdvertisementReceived.bind(this);\r\n\r\n private onAdvertisementReceived(event: BluetoothAdvertisingEvent): void {\r\n const deviceId = event.device.id;\r\n this.deviceMap.set(deviceId, event.device);\r\n const isNew = !this.discoveredDevices.has(deviceId);\r\n if (isNew || this.requestBleDeviceOptions?.allowDuplicates) {\r\n this.discoveredDevices.set(deviceId, true);\r\n const device = this.getBleDevice(event.device);\r\n const result: ScanResultInternal = {\r\n device,\r\n localName: device.name,\r\n rssi: event.rssi,\r\n txPower: event.txPower,\r\n manufacturerData: mapToObject(event.manufacturerData),\r\n serviceData: mapToObject(event.serviceData),\r\n uuids: event.uuids?.map(webUUIDToString),\r\n };\r\n this.notifyListeners('onScanResult', result);\r\n }\r\n }\r\n\r\n async stopLEScan(): Promise<void> {\r\n if (this.scan?.active) {\r\n this.scan.stop();\r\n }\r\n this.scan = null;\r\n }\r\n\r\n async getDevices(options: GetDevicesOptions): Promise<GetDevicesResult> {\r\n const devices = await navigator.bluetooth.getDevices();\r\n const bleDevices = devices\r\n .filter((device) => options.deviceIds.includes(device.id))\r\n .map((device) => {\r\n this.deviceMap.set(device.id, device);\r\n const bleDevice = this.getBleDevice(device);\r\n return bleDevice;\r\n });\r\n return { devices: bleDevices };\r\n }\r\n\r\n async getConnectedDevices(_options: GetConnectedDevicesOptions): Promise<GetDevicesResult> {\r\n const devices = await navigator.bluetooth.getDevices();\r\n const bleDevices = devices\r\n .filter((device) => {\r\n return device.gatt?.connected;\r\n })\r\n .map((device) => {\r\n this.deviceMap.set(device.id, device);\r\n const bleDevice = this.getBleDevice(device);\r\n return bleDevice;\r\n });\r\n return { devices: bleDevices };\r\n }\r\n\r\n async getBondedDevices(): Promise<GetDevicesResult> {\r\n return {} as Promise<GetDevicesResult>;\r\n }\r\n\r\n async connect(options: DeviceIdOptions & TimeoutOptions): Promise<void> {\r\n const device = this.getDeviceFromMap(options.deviceId);\r\n device.removeEventListener('gattserverdisconnected', this.onDisconnectedCallback);\r\n device.addEventListener('gattserverdisconnected', this.onDisconnectedCallback);\r\n const timeoutError = Symbol();\r\n if (device.gatt === undefined) {\r\n throw new Error('No gatt server available.');\r\n }\r\n try {\r\n const timeout = options.timeout ?? this.DEFAULT_CONNECTION_TIMEOUT;\r\n await runWithTimeout(device.gatt.connect(), timeout, timeoutError);\r\n } catch (error) {\r\n // cancel pending connect call, does not work yet in chromium because of a bug:\r\n // https://bugs.chromium.org/p/chromium/issues/detail?id=684073\r\n await device.gatt?.disconnect();\r\n if (error === timeoutError) {\r\n throw new Error('Connection timeout');\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n private onDisconnectedCallback = this.onDisconnected.bind(this);\r\n\r\n private onDisconnected(event: Event): void {\r\n const deviceId = (event.target as BluetoothDevice).id;\r\n const key = `disconnected|${deviceId}`;\r\n this.notifyListeners(key, null);\r\n }\r\n\r\n async createBond(_options: DeviceIdOptions): Promise<void> {\r\n throw this.unavailable('createBond is not available on web.');\r\n }\r\n\r\n async isBonded(_options: DeviceIdOptions): Promise<BooleanResult> {\r\n throw this.unavailable('isBonded is not available on web.');\r\n }\r\n\r\n async disconnect(options: DeviceIdOptions): Promise<void> {\r\n this.getDeviceFromMap(options.deviceId).gatt?.disconnect();\r\n }\r\n\r\n async getServices(options: DeviceIdOptions): Promise<BleServices> {\r\n const services = (await this.getDeviceFromMap(options.deviceId).gatt?.getPrimaryServices()) ?? [];\r\n const bleServices: BleService[] = [];\r\n for (const service of services) {\r\n const characteristics = await service.getCharacteristics();\r\n const bleCharacteristics: BleCharacteristic[] = [];\r\n for (const characteristic of characteristics) {\r\n bleCharacteristics.push({\r\n uuid: characteristic.uuid,\r\n properties: this.getProperties(characteristic),\r\n descriptors: await this.getDescriptors(characteristic),\r\n });\r\n }\r\n bleServices.push({ uuid: service.uuid, characteristics: bleCharacteristics });\r\n }\r\n return { services: bleServices };\r\n }\r\n\r\n private async getDescriptors(characteristic: BluetoothRemoteGATTCharacteristic): Promise<BleDescriptor[]> {\r\n try {\r\n const descriptors = await characteristic.getDescriptors();\r\n return descriptors.map((descriptor) => ({\r\n uuid: descriptor.uuid,\r\n }));\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n private getProperties(characteristic: BluetoothRemoteGATTCharacteristic): BleCharacteristicProperties {\r\n return {\r\n broadcast: characteristic.properties.broadcast,\r\n read: characteristic.properties.read,\r\n writeWithoutResponse: characteristic.properties.writeWithoutResponse,\r\n write: characteristic.properties.write,\r\n notify: characteristic.properties.notify,\r\n indicate: characteristic.properties.indicate,\r\n authenticatedSignedWrites: characteristic.properties.authenticatedSignedWrites,\r\n reliableWrite: characteristic.properties.reliableWrite,\r\n writableAuxiliaries: characteristic.properties.writableAuxiliaries,\r\n };\r\n }\r\n\r\n private async getCharacteristic(\r\n options: ReadOptions | WriteOptions,\r\n ): Promise<BluetoothRemoteGATTCharacteristic | undefined> {\r\n const service = await this.getDeviceFromMap(options.deviceId).gatt?.getPrimaryService(options?.service);\r\n return service?.getCharacteristic(options?.characteristic);\r\n }\r\n\r\n private async getDescriptor(\r\n options: ReadDescriptorOptions | WriteDescriptorOptions,\r\n ): Promise<BluetoothRemoteGATTDescriptor | undefined> {\r\n const characteristic = await this.getCharacteristic(options);\r\n return characteristic?.getDescriptor(options?.descriptor);\r\n }\r\n\r\n async discoverServices(_options: DeviceIdOptions): Promise<void> {\r\n throw this.unavailable('discoverServices is not available on web.');\r\n }\r\n\r\n async getMtu(_options: DeviceIdOptions): Promise<GetMtuResult> {\r\n throw this.unavailable('getMtu is not available on web.');\r\n }\r\n\r\n async requestConnectionPriority(_options: RequestConnectionPriorityOptions): Promise<void> {\r\n throw this.unavailable('requestConnectionPriority is not available on web.');\r\n }\r\n\r\n async readRssi(_options: DeviceIdOptions): Promise<ReadRssiResult> {\r\n throw this.unavailable('readRssi is not available on web.');\r\n }\r\n\r\n async read(options: ReadOptions): Promise<ReadResult> {\r\n const characteristic = await this.getCharacteristic(options);\r\n const value = await characteristic?.readValue();\r\n return { value };\r\n }\r\n\r\n async write(options: WriteOptions): Promise<void> {\r\n const characteristic = await this.getCharacteristic(options);\r\n let dataView: DataView;\r\n if (typeof options.value === 'string') {\r\n dataView = hexStringToDataView(options.value);\r\n } else {\r\n dataView = options.value;\r\n }\r\n await characteristic?.writeValueWithResponse(dataView);\r\n }\r\n\r\n async writeWithoutResponse(options: WriteOptions): Promise<void> {\r\n const characteristic = await this.getCharacteristic(options);\r\n let dataView: DataView;\r\n if (typeof options.value === 'string') {\r\n dataView = hexStringToDataView(options.value);\r\n } else {\r\n dataView = options.value;\r\n }\r\n await characteristic?.writeValueWithoutResponse(dataView);\r\n }\r\n\r\n async readDescriptor(options: ReadDescriptorOptions): Promise<ReadResult> {\r\n const descriptor = await this.getDescriptor(options);\r\n const value = await descriptor?.readValue();\r\n return { value };\r\n }\r\n\r\n async writeDescriptor(options: WriteDescriptorOptions): Promise<void> {\r\n const descriptor = await this.getDescriptor(options);\r\n let dataView: DataView;\r\n if (typeof options.value === 'string') {\r\n dataView = hexStringToDataView(options.value);\r\n } else {\r\n dataView = options.value;\r\n }\r\n await descriptor?.writeValue(dataView);\r\n }\r\n\r\n async startNotifications(options: ReadOptions): Promise<void> {\r\n const characteristic = await this.getCharacteristic(options);\r\n characteristic?.removeEventListener('characteristicvaluechanged', this.onCharacteristicValueChangedCallback);\r\n characteristic?.addEventListener('characteristicvaluechanged', this.onCharacteristicValueChangedCallback);\r\n await characteristic?.startNotifications();\r\n }\r\n\r\n private onCharacteristicValueChangedCallback = this.onCharacteristicValueChanged.bind(this);\r\n\r\n private onCharacteristicValueChanged(event: Event): void {\r\n const characteristic = event.target as BluetoothRemoteGATTCharacteristic;\r\n const key = `notification|${characteristic.service?.device.id}|${characteristic.service?.uuid}|${characteristic.uuid}`;\r\n this.notifyListeners(key, {\r\n value: characteristic.value,\r\n });\r\n }\r\n\r\n async stopNotifications(options: ReadOptions): Promise<void> {\r\n const characteristic = await this.getCharacteristic(options);\r\n await characteristic?.stopNotifications();\r\n }\r\n\r\n private getFilters(options?: RequestBleDeviceOptions): BluetoothLEScanFilter[] {\r\n const filters: BluetoothLEScanFilter[] = [];\r\n for (const service of options?.services ?? []) {\r\n filters.push({\r\n services: [service],\r\n name: options?.name,\r\n namePrefix: options?.namePrefix,\r\n });\r\n }\r\n if ((options?.name || options?.namePrefix) && filters.length === 0) {\r\n filters.push({\r\n name: options.name,\r\n namePrefix: options.namePrefix,\r\n });\r\n }\r\n for (const manufacturerData of options?.manufacturerData ?? []) {\r\n filters.push({\r\n manufacturerData: [manufacturerData],\r\n });\r\n }\r\n return filters;\r\n }\r\n\r\n private getDeviceFromMap(deviceId: string): BluetoothDevice {\r\n const device = this.deviceMap.get(deviceId);\r\n if (device === undefined) {\r\n throw new Error('Device not found. Call \"requestDevice\", \"requestLEScan\" or \"getDevices\" first.');\r\n }\r\n return device;\r\n }\r\n\r\n private getBleDevice(device: BluetoothDevice): BleDevice {\r\n const bleDevice: BleDevice = {\r\n deviceId: device.id,\r\n // use undefined instead of null if name is not available\r\n name: device.name ?? undefined,\r\n };\r\n return bleDevice;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport { hexStringToDataView, mapToObject, webUUIDToString } from './conversion';\nimport type {\n BleCharacteristic,\n BleCharacteristicProperties,\n BleDescriptor,\n BleService,\n TimeoutOptions,\n BleDevice,\n BleServices,\n BluetoothLePlugin,\n BooleanResult,\n DeviceIdOptions,\n GetConnectedDevicesOptions,\n GetDevicesOptions,\n GetDevicesResult,\n ReadDescriptorOptions,\n ReadOptions,\n ReadResult,\n ReadRssiResult,\n RequestBleDeviceOptions,\n ScanResultInternal,\n WriteOptions,\n WriteDescriptorOptions,\n GetMtuResult,\n RequestConnectionPriorityOptions,\n} from './definitions';\nimport { runWithTimeout } from './timeout';\n\nexport class BluetoothLeWeb extends WebPlugin implements BluetoothLePlugin {\n private deviceMap = new Map<string, BluetoothDevice>();\n private discoveredDevices = new Map<string, boolean>();\n private scan: BluetoothLEScan | null = null;\n private requestBleDeviceOptions: RequestBleDeviceOptions | undefined;\n private DEFAULT_CONNECTION_TIMEOUT = 10000;\n\n async initialize(): Promise<void> {\n if (typeof navigator === 'undefined' || !navigator.bluetooth) {\n throw this.unavailable('Web Bluetooth API not available in this browser.');\n }\n const isAvailable = await navigator.bluetooth.getAvailability();\n if (!isAvailable) {\n throw this.unavailable('No Bluetooth radio available.');\n }\n }\n\n async isEnabled(): Promise<BooleanResult> {\n // not available on web\n return { value: true };\n }\n\n async requestEnable(): Promise<void> {\n throw this.unavailable('requestEnable is not available on web.');\n }\n\n async enable(): Promise<void> {\n throw this.unavailable('enable is not available on web.');\n }\n\n async disable(): Promise<void> {\n throw this.unavailable('disable is not available on web.');\n }\n\n async startEnabledNotifications(): Promise<void> {\n // not available on web\n }\n\n async stopEnabledNotifications(): Promise<void> {\n // not available on web\n }\n\n async isLocationEnabled(): Promise<BooleanResult> {\n throw this.unavailable('isLocationEnabled is not available on web.');\n }\n\n async openLocationSettings(): Promise<void> {\n throw this.unavailable('openLocationSettings is not available on web.');\n }\n\n async openBluetoothSettings(): Promise<void> {\n throw this.unavailable('openBluetoothSettings is not available on web.');\n }\n\n async openAppSettings(): Promise<void> {\n throw this.unavailable('openAppSettings is not available on web.');\n }\n\n async setDisplayStrings(): Promise<void> {\n // not available on web\n }\n\n async requestDevice(options?: RequestBleDeviceOptions): Promise<BleDevice> {\n const filters = this.getFilters(options);\n const device = await navigator.bluetooth.requestDevice({\n filters: filters.length ? filters : undefined,\n optionalServices: options?.optionalServices,\n acceptAllDevices: filters.length === 0,\n });\n this.deviceMap.set(device.id, device);\n const bleDevice = this.getBleDevice(device);\n return bleDevice;\n }\n\n async requestLEScan(options?: RequestBleDeviceOptions): Promise<void> {\n this.requestBleDeviceOptions = options;\n const filters = this.getFilters(options);\n await this.stopLEScan();\n this.discoveredDevices = new Map<string, boolean>();\n navigator.bluetooth.removeEventListener(\n 'advertisementreceived',\n this.onAdvertisementReceivedCallback as EventListener,\n );\n navigator.bluetooth.addEventListener('advertisementreceived', this.onAdvertisementReceivedCallback);\n this.scan = await navigator.bluetooth.requestLEScan({\n filters: filters.length ? filters : undefined,\n acceptAllAdvertisements: filters.length === 0,\n keepRepeatedDevices: options?.allowDuplicates,\n });\n }\n\n private onAdvertisementReceivedCallback = this.onAdvertisementReceived.bind(this);\n\n private onAdvertisementReceived(event: BluetoothAdvertisingEvent): void {\n const deviceId = event.device.id;\n this.deviceMap.set(deviceId, event.device);\n const isNew = !this.discoveredDevices.has(deviceId);\n\n // Apply service data filtering client-side (Web Bluetooth API doesn't support it in scan filters)\n if (this.requestBleDeviceOptions?.serviceData && !this.matchesServiceDataFilter(event)) {\n return;\n }\n\n if (isNew || this.requestBleDeviceOptions?.allowDuplicates) {\n this.discoveredDevices.set(deviceId, true);\n const device = this.getBleDevice(event.device);\n const result: ScanResultInternal = {\n device,\n localName: device.name,\n rssi: event.rssi,\n txPower: event.txPower,\n manufacturerData: mapToObject(event.manufacturerData),\n serviceData: mapToObject(event.serviceData),\n uuids: event.uuids?.map(webUUIDToString),\n };\n this.notifyListeners('onScanResult', result);\n }\n }\n\n async stopLEScan(): Promise<void> {\n if (this.scan?.active) {\n this.scan.stop();\n }\n this.scan = null;\n }\n\n async getDevices(options: GetDevicesOptions): Promise<GetDevicesResult> {\n const devices = await navigator.bluetooth.getDevices();\n const bleDevices = devices\n .filter((device) => options.deviceIds.includes(device.id))\n .map((device) => {\n this.deviceMap.set(device.id, device);\n const bleDevice = this.getBleDevice(device);\n return bleDevice;\n });\n return { devices: bleDevices };\n }\n\n async getConnectedDevices(_options: GetConnectedDevicesOptions): Promise<GetDevicesResult> {\n const devices = await navigator.bluetooth.getDevices();\n const bleDevices = devices\n .filter((device) => {\n return device.gatt?.connected;\n })\n .map((device) => {\n this.deviceMap.set(device.id, device);\n const bleDevice = this.getBleDevice(device);\n return bleDevice;\n });\n return { devices: bleDevices };\n }\n\n async getBondedDevices(): Promise<GetDevicesResult> {\n return {} as Promise<GetDevicesResult>;\n }\n\n async connect(options: DeviceIdOptions & TimeoutOptions): Promise<void> {\n const device = this.getDeviceFromMap(options.deviceId);\n device.removeEventListener('gattserverdisconnected', this.onDisconnectedCallback);\n device.addEventListener('gattserverdisconnected', this.onDisconnectedCallback);\n const timeoutError = Symbol();\n if (device.gatt === undefined) {\n throw new Error('No gatt server available.');\n }\n try {\n const timeout = options.timeout ?? this.DEFAULT_CONNECTION_TIMEOUT;\n await runWithTimeout(device.gatt.connect(), timeout, timeoutError);\n } catch (error) {\n // cancel pending connect call, does not work yet in chromium because of a bug:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=684073\n await device.gatt?.disconnect();\n if (error === timeoutError) {\n throw new Error('Connection timeout');\n } else {\n throw error;\n }\n }\n }\n\n private onDisconnectedCallback = this.onDisconnected.bind(this);\n\n private onDisconnected(event: Event): void {\n const deviceId = (event.target as BluetoothDevice).id;\n const key = `disconnected|${deviceId}`;\n this.notifyListeners(key, null);\n }\n\n async createBond(_options: DeviceIdOptions): Promise<void> {\n throw this.unavailable('createBond is not available on web.');\n }\n\n async isBonded(_options: DeviceIdOptions): Promise<BooleanResult> {\n throw this.unavailable('isBonded is not available on web.');\n }\n\n async disconnect(options: DeviceIdOptions): Promise<void> {\n this.getDeviceFromMap(options.deviceId).gatt?.disconnect();\n }\n\n async getServices(options: DeviceIdOptions): Promise<BleServices> {\n const services = (await this.getDeviceFromMap(options.deviceId).gatt?.getPrimaryServices()) ?? [];\n const bleServices: BleService[] = [];\n for (const service of services) {\n const characteristics = await service.getCharacteristics();\n const bleCharacteristics: BleCharacteristic[] = [];\n for (const characteristic of characteristics) {\n bleCharacteristics.push({\n uuid: characteristic.uuid,\n properties: this.getProperties(characteristic),\n descriptors: await this.getDescriptors(characteristic),\n });\n }\n bleServices.push({ uuid: service.uuid, characteristics: bleCharacteristics });\n }\n return { services: bleServices };\n }\n\n private async getDescriptors(characteristic: BluetoothRemoteGATTCharacteristic): Promise<BleDescriptor[]> {\n try {\n const descriptors = await characteristic.getDescriptors();\n return descriptors.map((descriptor) => ({\n uuid: descriptor.uuid,\n }));\n } catch {\n return [];\n }\n }\n\n private getProperties(characteristic: BluetoothRemoteGATTCharacteristic): BleCharacteristicProperties {\n return {\n broadcast: characteristic.properties.broadcast,\n read: characteristic.properties.read,\n writeWithoutResponse: characteristic.properties.writeWithoutResponse,\n write: characteristic.properties.write,\n notify: characteristic.properties.notify,\n indicate: characteristic.properties.indicate,\n authenticatedSignedWrites: characteristic.properties.authenticatedSignedWrites,\n reliableWrite: characteristic.properties.reliableWrite,\n writableAuxiliaries: characteristic.properties.writableAuxiliaries,\n };\n }\n\n private async getCharacteristic(\n options: ReadOptions | WriteOptions,\n ): Promise<BluetoothRemoteGATTCharacteristic | undefined> {\n const service = await this.getDeviceFromMap(options.deviceId).gatt?.getPrimaryService(options?.service);\n return service?.getCharacteristic(options?.characteristic);\n }\n\n private async getDescriptor(\n options: ReadDescriptorOptions | WriteDescriptorOptions,\n ): Promise<BluetoothRemoteGATTDescriptor | undefined> {\n const characteristic = await this.getCharacteristic(options);\n return characteristic?.getDescriptor(options?.descriptor);\n }\n\n async discoverServices(_options: DeviceIdOptions): Promise<void> {\n throw this.unavailable('discoverServices is not available on web.');\n }\n\n async getMtu(_options: DeviceIdOptions): Promise<GetMtuResult> {\n throw this.unavailable('getMtu is not available on web.');\n }\n\n async requestConnectionPriority(_options: RequestConnectionPriorityOptions): Promise<void> {\n throw this.unavailable('requestConnectionPriority is not available on web.');\n }\n\n async readRssi(_options: DeviceIdOptions): Promise<ReadRssiResult> {\n throw this.unavailable('readRssi is not available on web.');\n }\n\n async read(options: ReadOptions): Promise<ReadResult> {\n const characteristic = await this.getCharacteristic(options);\n const value = await characteristic?.readValue();\n return { value };\n }\n\n async write(options: WriteOptions): Promise<void> {\n const characteristic = await this.getCharacteristic(options);\n let dataView: DataView;\n if (typeof options.value === 'string') {\n dataView = hexStringToDataView(options.value);\n } else {\n dataView = options.value;\n }\n await characteristic?.writeValueWithResponse(dataView);\n }\n\n async writeWithoutResponse(options: WriteOptions): Promise<void> {\n const characteristic = await this.getCharacteristic(options);\n let dataView: DataView;\n if (typeof options.value === 'string') {\n dataView = hexStringToDataView(options.value);\n } else {\n dataView = options.value;\n }\n await characteristic?.writeValueWithoutResponse(dataView);\n }\n\n async readDescriptor(options: ReadDescriptorOptions): Promise<ReadResult> {\n const descriptor = await this.getDescriptor(options);\n const value = await descriptor?.readValue();\n return { value };\n }\n\n async writeDescriptor(options: WriteDescriptorOptions): Promise<void> {\n const descriptor = await this.getDescriptor(options);\n let dataView: DataView;\n if (typeof options.value === 'string') {\n dataView = hexStringToDataView(options.value);\n } else {\n dataView = options.value;\n }\n await descriptor?.writeValue(dataView);\n }\n\n async startNotifications(options: ReadOptions): Promise<void> {\n const characteristic = await this.getCharacteristic(options);\n characteristic?.removeEventListener('characteristicvaluechanged', this.onCharacteristicValueChangedCallback);\n characteristic?.addEventListener('characteristicvaluechanged', this.onCharacteristicValueChangedCallback);\n await characteristic?.startNotifications();\n }\n\n private onCharacteristicValueChangedCallback = this.onCharacteristicValueChanged.bind(this);\n\n private onCharacteristicValueChanged(event: Event): void {\n const characteristic = event.target as BluetoothRemoteGATTCharacteristic;\n const key = `notification|${characteristic.service?.device.id}|${characteristic.service?.uuid}|${characteristic.uuid}`;\n this.notifyListeners(key, {\n value: characteristic.value,\n });\n }\n\n async stopNotifications(options: ReadOptions): Promise<void> {\n const characteristic = await this.getCharacteristic(options);\n await characteristic?.stopNotifications();\n }\n\n private getFilters(options?: RequestBleDeviceOptions): BluetoothLEScanFilter[] {\n const filters: BluetoothLEScanFilter[] = [];\n for (const service of options?.services ?? []) {\n filters.push({\n services: [service],\n name: options?.name,\n namePrefix: options?.namePrefix,\n });\n }\n if ((options?.name || options?.namePrefix) && filters.length === 0) {\n filters.push({\n name: options.name,\n namePrefix: options.namePrefix,\n });\n }\n for (const manufacturerData of options?.manufacturerData ?? []) {\n // Cast to any to avoid type incompatibility - conversion is handled in bleClient.ts\n filters.push({\n manufacturerData: [manufacturerData as any],\n });\n }\n // Note: Web Bluetooth API does not support service data in scan filters.\n // Service data filtering will be done client-side in onAdvertisementReceived.\n // We still accept serviceData in options for API consistency across platforms.\n return filters;\n }\n\n private matchesServiceDataFilter(event: BluetoothAdvertisingEvent): boolean {\n const filters = this.requestBleDeviceOptions?.serviceData;\n if (!filters || filters.length === 0) {\n return true; // No filters, accept all\n }\n\n if (!event.serviceData) {\n return false; // No service data in advertisement\n }\n\n // Check if any filter matches (OR logic)\n for (const filter of filters) {\n const serviceData = event.serviceData.get(filter.serviceUuid);\n if (!serviceData) {\n continue; // This filter doesn't match, try next\n }\n\n // If we have service data for this UUID\n if (!filter.dataPrefix) {\n return true; // Filter matched by service UUID alone\n }\n\n // Check data prefix (DataView on web)\n const data = new Uint8Array(serviceData.buffer);\n const prefixView = filter.dataPrefix as DataView;\n\n if (data.length < prefixView.byteLength) {\n continue; // Data too short\n }\n\n // Apply mask if provided\n if (filter.mask) {\n const maskView = filter.mask as DataView;\n let matches = true;\n for (let i = 0; i < prefixView.byteLength; i++) {\n if ((data[i] & maskView.getUint8(i)) !== (prefixView.getUint8(i) & maskView.getUint8(i))) {\n matches = false;\n break;\n }\n }\n if (matches) {\n return true;\n }\n } else {\n // Check if data starts with prefix\n let matches = true;\n for (let i = 0; i < prefixView.byteLength; i++) {\n if (data[i] !== prefixView.getUint8(i)) {\n matches = false;\n break;\n }\n }\n if (matches) {\n return true;\n }\n }\n }\n\n return false; // No filter matched\n }\n\n private getDeviceFromMap(deviceId: string): BluetoothDevice {\n const device = this.deviceMap.get(deviceId);\n if (device === undefined) {\n throw new Error('Device not found. Call \"requestDevice\", \"requestLEScan\" or \"getDevices\" first.');\n }\n return device;\n }\n\n private getBleDevice(device: BluetoothDevice): BleDevice {\n const bleDevice: BleDevice = {\n deviceId: device.id,\n // use undefined instead of null if name is not available\n name: device.name ?? undefined,\n };\n return bleDevice;\n }\n}\n"]}
|
package/dist/plugin.cjs.js
CHANGED
|
@@ -128,6 +128,39 @@ function mapToObject(map) {
|
|
|
128
128
|
obj[key.toString()] = value;
|
|
129
129
|
});
|
|
130
130
|
return obj;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Convert Data or Uint8Array to Uint8Array.
|
|
134
|
+
* @param value DataView, Uint8Array, or undefined
|
|
135
|
+
* @return Uint8Array or undefined
|
|
136
|
+
*/
|
|
137
|
+
function toUint8Array(value) {
|
|
138
|
+
if (value === undefined) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
if (typeof value === 'string') {
|
|
142
|
+
const dataView = hexStringToDataView(value);
|
|
143
|
+
return new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength);
|
|
144
|
+
}
|
|
145
|
+
if (value instanceof DataView) {
|
|
146
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
147
|
+
}
|
|
148
|
+
return value; // Already Uint8Array
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Convert Data, Uint8Array, or string to hex string.
|
|
152
|
+
* @param value DataView, Uint8Array, or undefined
|
|
153
|
+
* @return hex string or undefined
|
|
154
|
+
*/
|
|
155
|
+
function toHexString(value) {
|
|
156
|
+
if (value === undefined) {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
if (value instanceof DataView) {
|
|
160
|
+
return dataViewToHexString(value);
|
|
161
|
+
}
|
|
162
|
+
// Uint8Array
|
|
163
|
+
return dataViewToHexString(new DataView(value.buffer, value.byteOffset, value.byteLength));
|
|
131
164
|
}
|
|
132
165
|
|
|
133
166
|
const BluetoothLe = core.registerPlugin('BluetoothLe', {
|
|
@@ -445,7 +478,7 @@ class BleClientClass {
|
|
|
445
478
|
descriptor, value: writeValue }, options));
|
|
446
479
|
});
|
|
447
480
|
}
|
|
448
|
-
async startNotifications(deviceId, service, characteristic, callback) {
|
|
481
|
+
async startNotifications(deviceId, service, characteristic, callback, options) {
|
|
449
482
|
service = parseUUID(service);
|
|
450
483
|
characteristic = parseUUID(characteristic);
|
|
451
484
|
await this.queue(async () => {
|
|
@@ -456,11 +489,9 @@ class BleClientClass {
|
|
|
456
489
|
callback(this.convertValue(event === null || event === undefined ? undefined : event.value));
|
|
457
490
|
});
|
|
458
491
|
this.eventListeners.set(key, listener);
|
|
459
|
-
await BluetoothLe.startNotifications({
|
|
460
|
-
deviceId,
|
|
492
|
+
await BluetoothLe.startNotifications(Object.assign({ deviceId,
|
|
461
493
|
service,
|
|
462
|
-
characteristic,
|
|
463
|
-
});
|
|
494
|
+
characteristic }, options));
|
|
464
495
|
});
|
|
465
496
|
}
|
|
466
497
|
async stopNotifications(deviceId, service, characteristic) {
|
|
@@ -485,6 +516,20 @@ class BleClientClass {
|
|
|
485
516
|
if (options.optionalServices) {
|
|
486
517
|
options.optionalServices = options.optionalServices.map(parseUUID);
|
|
487
518
|
}
|
|
519
|
+
if (options.serviceData && core.Capacitor.getPlatform() !== 'web') {
|
|
520
|
+
// Native platforms: convert to hex strings
|
|
521
|
+
options.serviceData = options.serviceData.map((filter) => (Object.assign(Object.assign({}, filter), { serviceUuid: parseUUID(filter.serviceUuid), dataPrefix: toHexString(filter.dataPrefix), mask: toHexString(filter.mask) })));
|
|
522
|
+
}
|
|
523
|
+
if (options.manufacturerData) {
|
|
524
|
+
if (core.Capacitor.getPlatform() !== 'web') {
|
|
525
|
+
// Native platforms: convert to hex strings
|
|
526
|
+
options.manufacturerData = options.manufacturerData.map((filter) => (Object.assign(Object.assign({}, filter), { dataPrefix: toHexString(filter.dataPrefix), mask: toHexString(filter.mask) })));
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
// Web platform: convert to Uint8Array for Web Bluetooth API
|
|
530
|
+
options.manufacturerData = options.manufacturerData.map((filter) => (Object.assign(Object.assign({}, filter), { dataPrefix: toUint8Array(filter.dataPrefix), mask: toUint8Array(filter.mask) })));
|
|
531
|
+
}
|
|
532
|
+
}
|
|
488
533
|
return options;
|
|
489
534
|
}
|
|
490
535
|
convertValue(value) {
|
|
@@ -598,11 +643,15 @@ class BluetoothLeWeb extends core.WebPlugin {
|
|
|
598
643
|
});
|
|
599
644
|
}
|
|
600
645
|
onAdvertisementReceived(event) {
|
|
601
|
-
var _a, _b;
|
|
646
|
+
var _a, _b, _c;
|
|
602
647
|
const deviceId = event.device.id;
|
|
603
648
|
this.deviceMap.set(deviceId, event.device);
|
|
604
649
|
const isNew = !this.discoveredDevices.has(deviceId);
|
|
605
|
-
|
|
650
|
+
// Apply service data filtering client-side (Web Bluetooth API doesn't support it in scan filters)
|
|
651
|
+
if (((_a = this.requestBleDeviceOptions) === null || _a === undefined ? undefined : _a.serviceData) && !this.matchesServiceDataFilter(event)) {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
if (isNew || ((_b = this.requestBleDeviceOptions) === null || _b === undefined ? undefined : _b.allowDuplicates)) {
|
|
606
655
|
this.discoveredDevices.set(deviceId, true);
|
|
607
656
|
const device = this.getBleDevice(event.device);
|
|
608
657
|
const result = {
|
|
@@ -612,7 +661,7 @@ class BluetoothLeWeb extends core.WebPlugin {
|
|
|
612
661
|
txPower: event.txPower,
|
|
613
662
|
manufacturerData: mapToObject(event.manufacturerData),
|
|
614
663
|
serviceData: mapToObject(event.serviceData),
|
|
615
|
-
uuids: (
|
|
664
|
+
uuids: (_c = event.uuids) === null || _c === undefined ? undefined : _c.map(webUUIDToString),
|
|
616
665
|
};
|
|
617
666
|
this.notifyListeners('onScanResult', result);
|
|
618
667
|
}
|
|
@@ -833,12 +882,71 @@ class BluetoothLeWeb extends core.WebPlugin {
|
|
|
833
882
|
});
|
|
834
883
|
}
|
|
835
884
|
for (const manufacturerData of (_b = options === null || options === undefined ? undefined : options.manufacturerData) !== null && _b !== undefined ? _b : []) {
|
|
885
|
+
// Cast to any to avoid type incompatibility - conversion is handled in bleClient.ts
|
|
836
886
|
filters.push({
|
|
837
887
|
manufacturerData: [manufacturerData],
|
|
838
888
|
});
|
|
839
889
|
}
|
|
890
|
+
// Note: Web Bluetooth API does not support service data in scan filters.
|
|
891
|
+
// Service data filtering will be done client-side in onAdvertisementReceived.
|
|
892
|
+
// We still accept serviceData in options for API consistency across platforms.
|
|
840
893
|
return filters;
|
|
841
894
|
}
|
|
895
|
+
matchesServiceDataFilter(event) {
|
|
896
|
+
var _a;
|
|
897
|
+
const filters = (_a = this.requestBleDeviceOptions) === null || _a === undefined ? undefined : _a.serviceData;
|
|
898
|
+
if (!filters || filters.length === 0) {
|
|
899
|
+
return true; // No filters, accept all
|
|
900
|
+
}
|
|
901
|
+
if (!event.serviceData) {
|
|
902
|
+
return false; // No service data in advertisement
|
|
903
|
+
}
|
|
904
|
+
// Check if any filter matches (OR logic)
|
|
905
|
+
for (const filter of filters) {
|
|
906
|
+
const serviceData = event.serviceData.get(filter.serviceUuid);
|
|
907
|
+
if (!serviceData) {
|
|
908
|
+
continue; // This filter doesn't match, try next
|
|
909
|
+
}
|
|
910
|
+
// If we have service data for this UUID
|
|
911
|
+
if (!filter.dataPrefix) {
|
|
912
|
+
return true; // Filter matched by service UUID alone
|
|
913
|
+
}
|
|
914
|
+
// Check data prefix (DataView on web)
|
|
915
|
+
const data = new Uint8Array(serviceData.buffer);
|
|
916
|
+
const prefixView = filter.dataPrefix;
|
|
917
|
+
if (data.length < prefixView.byteLength) {
|
|
918
|
+
continue; // Data too short
|
|
919
|
+
}
|
|
920
|
+
// Apply mask if provided
|
|
921
|
+
if (filter.mask) {
|
|
922
|
+
const maskView = filter.mask;
|
|
923
|
+
let matches = true;
|
|
924
|
+
for (let i = 0; i < prefixView.byteLength; i++) {
|
|
925
|
+
if ((data[i] & maskView.getUint8(i)) !== (prefixView.getUint8(i) & maskView.getUint8(i))) {
|
|
926
|
+
matches = false;
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
if (matches) {
|
|
931
|
+
return true;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
else {
|
|
935
|
+
// Check if data starts with prefix
|
|
936
|
+
let matches = true;
|
|
937
|
+
for (let i = 0; i < prefixView.byteLength; i++) {
|
|
938
|
+
if (data[i] !== prefixView.getUint8(i)) {
|
|
939
|
+
matches = false;
|
|
940
|
+
break;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (matches) {
|
|
944
|
+
return true;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
return false; // No filter matched
|
|
949
|
+
}
|
|
842
950
|
getDeviceFromMap(deviceId) {
|
|
843
951
|
const device = this.deviceMap.get(deviceId);
|
|
844
952
|
if (device === undefined) {
|
|
@@ -872,5 +980,7 @@ exports.mapToObject = mapToObject;
|
|
|
872
980
|
exports.numberToUUID = numberToUUID;
|
|
873
981
|
exports.numbersToDataView = numbersToDataView;
|
|
874
982
|
exports.textToDataView = textToDataView;
|
|
983
|
+
exports.toHexString = toHexString;
|
|
984
|
+
exports.toUint8Array = toUint8Array;
|
|
875
985
|
exports.webUUIDToString = webUUIDToString;
|
|
876
986
|
//# sourceMappingURL=plugin.cjs.js.map
|