From ce2f0bc0d0bab371277dc0a4f56f874bb36501ba Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Apr 2024 13:54:01 +0200 Subject: [PATCH 1/6] Define "HardwareAdapterDetails" interface Define a Information only interface for a Hardware Adapter. These info should also be available if other adapter-libs are added. --- src/adapters/adapter.ts | 6 ++++++ src/adapters/simpleble.ts | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/adapters/adapter.ts b/src/adapters/adapter.ts index cb43550b..bbcf5640 100644 --- a/src/adapters/adapter.ts +++ b/src/adapters/adapter.ts @@ -48,4 +48,10 @@ export interface Adapter extends EventEmitter { disableNotify: (handle: string) => Promise; readDescriptor: (handle: string) => Promise; writeDescriptor: (handle: string, value: DataView) => Promise; + +/** Basic Hardware Details for an Hardware adapter. */ +export interface HardwareAdapterDetails { + identifier: string; + address: string; + active: boolean; } diff --git a/src/adapters/simpleble.ts b/src/adapters/simpleble.ts index 0ee81b6b..2d5c8dc3 100644 --- a/src/adapters/simpleble.ts +++ b/src/adapters/simpleble.ts @@ -85,10 +85,7 @@ export interface Peripheral { } /** SimpleBLE Adapter. */ -export interface Adapter { - identifier: string; - address: string; - active: boolean; +export interface Adapter extends HardwareAdapterDetails { peripherals: Peripheral[]; pairedPeripherals: Peripheral[]; scanFor(ms: number): boolean; From 08e683f4daf4cff067e72a6bcbcf705d1ab70ff5 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Apr 2024 13:55:20 +0200 Subject: [PATCH 2/6] Add methods to get HW Adapters Enhance the "Adapter" interface with methods to get and define he HW Adapter to use --- src/adapters/adapter.ts | 3 +++ src/adapters/simpleble-adapter.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/adapters/adapter.ts b/src/adapters/adapter.ts index bbcf5640..a173bc1b 100644 --- a/src/adapters/adapter.ts +++ b/src/adapters/adapter.ts @@ -48,6 +48,9 @@ export interface Adapter extends EventEmitter { disableNotify: (handle: string) => Promise; readDescriptor: (handle: string) => Promise; writeDescriptor: (handle: string, value: DataView) => Promise; + useHardwareAdapter: (adapterIndex: number) => void; + getHardwareAdapters: () => Array; +} /** Basic Hardware Details for an Hardware adapter. */ export interface HardwareAdapterDetails { diff --git a/src/adapters/simpleble-adapter.ts b/src/adapters/simpleble-adapter.ts index cc34b47c..e3b5490d 100644 --- a/src/adapters/simpleble-adapter.ts +++ b/src/adapters/simpleble-adapter.ts @@ -53,6 +53,24 @@ export class SimplebleAdapter extends EventEmitter implements BluetoothAdapter { private descriptors = new Map(); private charEvents = new Map void>(); + getHardwareAdapters() { + return getAdapters().map( + ({ identifier, address, active }) => + ({ identifier, address, active }) + ); + } + + useHardwareAdapter(adapterIndex: number) { + if (this.adapter !== undefined) { + throw new Error('Can not change adapter after already used.'); + } + const adapter = getAdapters()[adapterIndex]; + if (adapter === undefined) { + throw new Error(`Adapter ${adapterIndex} not found.`); + } + this.adapter = getAdapters()[adapterIndex]; + } + private validDevice(device: Partial, serviceUUIDs: Array): boolean { if (serviceUUIDs.length === 0) { // Match any device From 67f766bd7bef6ef0de22fb6497aa308424c23c59 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Apr 2024 13:55:54 +0200 Subject: [PATCH 3/6] SimpleBLE Adapter extends basic info --- src/adapters/simpleble.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/adapters/simpleble.ts b/src/adapters/simpleble.ts index 2d5c8dc3..4beee7d1 100644 --- a/src/adapters/simpleble.ts +++ b/src/adapters/simpleble.ts @@ -23,6 +23,8 @@ * SOFTWARE. */ +import { HardwareAdapterDetails } from './adapter'; + // eslint-disable-next-line @typescript-eslint/no-var-requires const simpleble = require('bindings')('simpleble.node'); module.exports = simpleble; From 66636118e53a9dedaa3855b981b9d980d7dd7134 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Apr 2024 13:59:26 +0200 Subject: [PATCH 4/6] Add HW Adapter definition to constructor Adds the HW Adapter Index as option to the constructor like other "non Webbluetooth spec" options and set this. --- src/bluetooth.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/bluetooth.ts b/src/bluetooth.ts index 368241f0..dd1101ef 100644 --- a/src/bluetooth.ts +++ b/src/bluetooth.ts @@ -27,6 +27,7 @@ import { adapter, EVENT_ENABLED } from './adapters'; import { BluetoothDeviceImpl, BluetoothDeviceEvents } from './device'; import { BluetoothUUID } from './uuid'; import { EventDispatcher, DOMEvent } from './events'; +import { HardwareAdapterDetails } from './adapters/adapter'; /** * Bluetooth Options interface @@ -51,6 +52,11 @@ export interface BluetoothOptions { * An optional referring device */ referringDevice?: BluetoothDevice; + + /** + * An optional BLE Hardware Adapter index to use + */ + hardwareAdapterIndex?: number; } /** @@ -88,6 +94,9 @@ export class BluetoothImpl extends EventDispatcher implements B if (options.scanTime) { this.scanTime = options.scanTime * 1000; } + if (typeof options.hardwareAdapterIndex === 'number') { + adapter.useHardwareAdapter(options.hardwareAdapterIndex); + } adapter.on(EVENT_ENABLED, _value => { this.dispatchEvent(new DOMEvent(this, 'availabilitychanged')); @@ -405,3 +414,7 @@ export class BluetoothImpl extends EventDispatcher implements B throw new Error('requestLEScan error: method not implemented.'); } } + +export function getHardwareAdapters(): HardwareAdapterDetails[] { + return adapter.getHardwareAdapters(); +} From 17bd00bffc3d7e04173233b57297f03cd69f7c55 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Apr 2024 14:00:58 +0200 Subject: [PATCH 5/6] Expose simpleBle "getHardwareAdapters" method In order to allow getting list of adapter we expose a "adapter" specific method. If you have a better idea just tell me, but for me this was the one that fits the "mostly compatible webbbluetooth interface" the best. --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index cbdcf322..b9ad28e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,7 +23,7 @@ * SOFTWARE. */ -import { BluetoothImpl, BluetoothOptions } from './bluetooth'; +import { BluetoothImpl, BluetoothOptions, getHardwareAdapters } from './bluetooth'; /** * Default bluetooth instance synonymous with `navigator.bluetooth` @@ -33,7 +33,7 @@ export const bluetooth = new BluetoothImpl(); /** * Bluetooth class for creating new instances */ -export { BluetoothImpl as Bluetooth, BluetoothOptions }; +export { BluetoothImpl as Bluetooth, BluetoothOptions, getHardwareAdapters as getSimpleBleHardwareAdapters }; /** * Helper methods and enums From fda4fbe48b6a4fd5accd9054085d5dae535abff1 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 20 Apr 2024 14:01:13 +0200 Subject: [PATCH 6/6] Add example --- examples/list-adapters.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 examples/list-adapters.js diff --git a/examples/list-adapters.js b/examples/list-adapters.js new file mode 100644 index 00000000..3357a166 --- /dev/null +++ b/examples/list-adapters.js @@ -0,0 +1,28 @@ +/* +* Node Web Bluetooth +* Copyright (c) 2022 Rob Moran +* +* The MIT License (MIT) +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ + +const webbluetooth = require("../"); + +console.log(webbluetooth.getSimpleBleHardwareAdapters());