Skip to content

Commit f0e10c4

Browse files
vincent.gillotpeitschie
authored andcommitted
feat: add skipDescriptorDiscovery option to ConnectOptions
1 parent a7ce7fe commit f0e10c4

File tree

8 files changed

+66
-22
lines changed

8 files changed

+66
-22
lines changed

README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -628,16 +628,16 @@ and [getDevices](https://developer.mozilla.org/en-US/docs/Web/API/Bluetooth/getD
628628
### connect(...)
629629

630630
```typescript
631-
connect(deviceId: string, onDisconnect?: ((deviceId: string) => void) | undefined, options?: TimeoutOptions | undefined) => Promise<void>
631+
connect(deviceId: string, onDisconnect?: ((deviceId: string) => void) | undefined, options?: ConnectClientOptions | undefined) => Promise<void>
632632
```
633633

634634
Connect to a peripheral BLE device. For an example, see [usage](#usage).
635635

636-
| Param | Type | Description |
637-
| ------------------ | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
638-
| **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) |
639-
| **`onDisconnect`** | <code>((deviceId: string) =&gt; void)</code> | Optional disconnect callback function that will be used when the device disconnects |
640-
| **`options`** | <code><a href="#timeoutoptions">TimeoutOptions</a></code> | Options for plugin call |
636+
| Param | Type | Description |
637+
| ------------------ | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
638+
| **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) |
639+
| **`onDisconnect`** | <code>((deviceId: string) =&gt; void)</code> | Optional disconnect callback function that will be used when the device disconnects |
640+
| **`options`** | <code><a href="#connectclientoptions">ConnectClientOptions</a></code> | Options for plugin call |
641641

642642
---
643643

@@ -970,6 +970,12 @@ Stop listening to the changes of the value of a characteristic. For an example,
970970
| **`uuids`** | <code>string[]</code> | Advertised services. |
971971
| **`rawAdvertisement`** | <code>[DataView](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/DataView)</code> | Raw advertisement data (**Android** only). |
972972

973+
#### ConnectClientOptions
974+
975+
| Prop | Type | Description | Default |
976+
| ----------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
977+
| **`skipDescriptorDiscovery`** | <code>boolean</code> | Skip descriptor discovery during connection to improve connection speed. When enabled, descriptors will not be available in the services structure. | <code>false</code> |
978+
973979
#### TimeoutOptions
974980

975981
| Prop | Type | Description |

android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/BluetoothLe.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,8 @@ class BluetoothLe : Plugin() {
463463
fun connect(call: PluginCall) {
464464
val device = getOrCreateDevice(call) ?: return
465465
val timeout = call.getFloat("timeout", CONNECTION_TIMEOUT)!!.toLong()
466-
device.connect(timeout) { response ->
466+
val skipDescriptorDiscovery = call.getBoolean("skipDescriptorDiscovery", false)!!
467+
device.connect(timeout, skipDescriptorDiscovery) { response ->
467468
run {
468469
if (response.success) {
469470
call.resolve()
@@ -527,6 +528,7 @@ class BluetoothLe : Plugin() {
527528
fun getServices(call: PluginCall) {
528529
val device = getDevice(call) ?: return
529530
val services = device.getServices()
531+
val skipDescriptorDiscovery = device.getSkipDescriptorDiscovery()
530532
val bleServices = JSArray()
531533
services.forEach { service ->
532534
val bleCharacteristics = JSArray()
@@ -535,10 +537,12 @@ class BluetoothLe : Plugin() {
535537
bleCharacteristic.put("uuid", characteristic.uuid)
536538
bleCharacteristic.put("properties", getProperties(characteristic))
537539
val bleDescriptors = JSArray()
538-
characteristic.descriptors.forEach { descriptor ->
539-
val bleDescriptor = JSObject()
540-
bleDescriptor.put("uuid", descriptor.uuid)
541-
bleDescriptors.put(bleDescriptor)
540+
if (!skipDescriptorDiscovery) {
541+
characteristic.descriptors.forEach { descriptor ->
542+
val bleDescriptor = JSObject()
543+
bleDescriptor.put("uuid", descriptor.uuid)
544+
bleDescriptors.put(bleDescriptor)
545+
}
542546
}
543547
bleCharacteristic.put("descriptors", bleDescriptors)
544548
bleCharacteristics.put(bleCharacteristic)

android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/Device.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class Device(
7474
private var bondStateReceiver: BroadcastReceiver? = null
7575
private val pendingBondKeys = Collections.newSetFromMap(ConcurrentHashMap<String, Boolean>())
7676
private var currentMtu = -1
77+
private var skipDescriptorDiscovery = false
7778

7879
private lateinit var callbacksHandlerThread: HandlerThread
7980
private lateinit var callbacksHandler: Handler
@@ -318,9 +319,10 @@ class Device(
318319
* - request MTU
319320
*/
320321
fun connect(
321-
timeout: Long, callback: (CallbackResponse) -> Unit
322+
timeout: Long, skipDescriptorDiscovery: Boolean, callback: (CallbackResponse) -> Unit
322323
) {
323324
val key = "connect"
325+
this.skipDescriptorDiscovery = skipDescriptorDiscovery
324326
callbackMap[key] = callback
325327
if (isConnected()) {
326328
resolve(key, "Already connected.")
@@ -478,6 +480,10 @@ class Device(
478480
return bluetoothGatt?.services ?: mutableListOf()
479481
}
480482

483+
fun getSkipDescriptorDiscovery(): Boolean {
484+
return skipDescriptorDiscovery
485+
}
486+
481487
fun discoverServices(
482488
timeout: Long, callback: (CallbackResponse) -> Unit
483489
) {

ios/Sources/BluetoothLe/Device.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Device: NSObject, CBPeripheralDelegate {
1212
private var servicesDiscovered = 0
1313
private var characteristicsCount = 0
1414
private var characteristicsDiscovered = 0
15+
private var skipDescriptorDiscovery = false
1516

1617
init(
1718
_ peripheral: CBPeripheral
@@ -48,9 +49,11 @@ class Device: NSObject, CBPeripheralDelegate {
4849

4950
func setOnConnected(
5051
_ connectionTimeout: Double,
52+
_ skipDescriptorDiscovery: Bool,
5153
_ callback: @escaping Callback
5254
) {
5355
let key = "connect"
56+
self.skipDescriptorDiscovery = skipDescriptorDiscovery
5457
self.callbackMap[key] = callback
5558
self.setTimeout(key, "Connection timeout", connectionTimeout)
5659
}
@@ -81,11 +84,19 @@ class Device: NSObject, CBPeripheralDelegate {
8184
self.servicesDiscovered += 1
8285
log("didDiscoverCharacteristicsFor", self.servicesDiscovered, self.servicesCount)
8386
self.characteristicsCount += service.characteristics?.count ?? 0
84-
for characteristic in service.characteristics ?? [] {
85-
peripheral.discoverDescriptors(for: characteristic)
87+
88+
if !self.skipDescriptorDiscovery {
89+
for characteristic in service.characteristics ?? [] {
90+
peripheral.discoverDescriptors(for: characteristic)
91+
}
8692
}
87-
// if the last service does not have characteristics, resolve the connect call now
88-
if self.servicesDiscovered >= self.servicesCount && self.characteristicsDiscovered >= self.characteristicsCount {
93+
94+
// Resolve immediately if skipping descriptor discovery or if all characteristics are discovered
95+
let shouldResolve = self.skipDescriptorDiscovery
96+
? self.servicesDiscovered >= self.servicesCount
97+
: self.servicesDiscovered >= self.servicesCount && self.characteristicsDiscovered >= self.characteristicsCount
98+
99+
if shouldResolve {
89100
self.resolve("connect", "Connection successful.")
90101
self.resolve("discoverServices", "Services discovered.")
91102
}

ios/Sources/BluetoothLe/Plugin.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ public class BluetoothLe: CAPPlugin, CAPBridgedPlugin {
279279
guard self.getDeviceManager(call) != nil else { return }
280280
guard let device = self.getDevice(call, checkConnection: false) else { return }
281281
let timeout = self.getTimeout(call, defaultTimeout: CONNECTION_TIMEOUT)
282-
device.setOnConnected(timeout, {(success, message) in
282+
let skipDescriptorDiscovery = call.getBool("skipDescriptorDiscovery") ?? false
283+
device.setOnConnected(timeout, skipDescriptorDiscovery, {(success, message) in
283284
if success {
284285
// only resolve after service discovery
285286
call.resolve()

src/bleClient.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
BleDevice,
88
BleService,
99
ConnectionPriority,
10+
ConnectClientOptions,
1011
Data,
1112
InitializeOptions,
1213
ReadResult,
@@ -151,7 +152,7 @@ export interface BleClientInterface {
151152
* @param onDisconnect Optional disconnect callback function that will be used when the device disconnects
152153
* @param options Options for plugin call
153154
*/
154-
connect(deviceId: string, onDisconnect?: (deviceId: string) => void, options?: TimeoutOptions): Promise<void>;
155+
connect(deviceId: string, onDisconnect?: (deviceId: string) => void, options?: ConnectClientOptions): Promise<void>;
155156

156157
/**
157158
* Create a bond with a peripheral BLE device.
@@ -476,7 +477,11 @@ class BleClientClass implements BleClientInterface {
476477
});
477478
}
478479

479-
async connect(deviceId: string, onDisconnect?: (deviceId: string) => void, options?: TimeoutOptions): Promise<void> {
480+
async connect(
481+
deviceId: string,
482+
onDisconnect?: (deviceId: string) => void,
483+
options?: ConnectClientOptions,
484+
): Promise<void> {
480485
await this.queue(async () => {
481486
if (onDisconnect) {
482487
const key = `disconnected|${deviceId}`;

src/definitions.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,17 @@ export interface TimeoutOptions {
181181
timeout?: number;
182182
}
183183

184+
export interface ConnectClientOptions extends TimeoutOptions {
185+
/**
186+
* Skip descriptor discovery during connection to improve connection speed.
187+
* When enabled, descriptors will not be available in the services structure.
188+
* @default false
189+
*/
190+
skipDescriptorDiscovery?: boolean;
191+
}
192+
193+
export interface ConnectOptions extends DeviceIdOptions, ConnectClientOptions {}
194+
184195
export interface RequestConnectionPriorityOptions extends DeviceIdOptions {
185196
connectionPriority: ConnectionPriority;
186197
}
@@ -365,7 +376,7 @@ export interface BluetoothLePlugin {
365376
eventName: 'onScanResult',
366377
listenerFunc: (result: ScanResultInternal) => void,
367378
): Promise<PluginListenerHandle>;
368-
connect(options: DeviceIdOptions & TimeoutOptions): Promise<void>;
379+
connect(options: ConnectOptions): Promise<void>;
369380
createBond(options: DeviceIdOptions & TimeoutOptions): Promise<void>;
370381
isBonded(options: DeviceIdOptions): Promise<BooleanResult>;
371382
disconnect(options: DeviceIdOptions): Promise<void>;

src/web.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
BleCharacteristicProperties,
77
BleDescriptor,
88
BleService,
9-
TimeoutOptions,
9+
ConnectOptions,
1010
BleDevice,
1111
BleServices,
1212
BluetoothLePlugin,
@@ -184,7 +184,7 @@ export class BluetoothLeWeb extends WebPlugin implements BluetoothLePlugin {
184184
return {} as Promise<GetDevicesResult>;
185185
}
186186

187-
async connect(options: DeviceIdOptions & TimeoutOptions): Promise<void> {
187+
async connect(options: ConnectOptions): Promise<void> {
188188
const device = this.getDeviceFromMap(options.deviceId);
189189
device.removeEventListener('gattserverdisconnected', this.onDisconnectedCallback);
190190
device.addEventListener('gattserverdisconnected', this.onDisconnectedCallback);

0 commit comments

Comments
 (0)