react-native-ble-nitro 1.13.0 → 1.15.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.
Files changed (60) hide show
  1. package/README.md +53 -1
  2. package/android/build.gradle +6 -0
  3. package/android/src/main/java/com/margelo/nitro/co/zyke/ble/BleNitroBleManager.kt +128 -11
  4. package/android/src/main/java/com/margelo/nitro/co/zyke/ble/CccdSubscription.kt +38 -0
  5. package/android/src/test/java/com/margelo/nitro/co/zyke/ble/CccdSubscriptionTest.kt +48 -0
  6. package/ios/BleNitroBleManager.swift +28 -3
  7. package/lib/commonjs/index.d.ts +1 -1
  8. package/lib/commonjs/index.d.ts.map +1 -1
  9. package/lib/commonjs/index.js +2 -1
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/manager.d.ts +24 -1
  12. package/lib/commonjs/manager.d.ts.map +1 -1
  13. package/lib/commonjs/manager.js +33 -1
  14. package/lib/commonjs/manager.js.map +1 -1
  15. package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts +14 -0
  16. package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts.map +1 -1
  17. package/lib/commonjs/specs/NativeBleNitro.nitro.js +7 -1
  18. package/lib/commonjs/specs/NativeBleNitro.nitro.js.map +1 -1
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.js +1 -1
  21. package/lib/manager.d.ts +24 -1
  22. package/lib/manager.js +32 -1
  23. package/lib/specs/NativeBleNitro.nitro.d.ts +14 -0
  24. package/lib/specs/NativeBleNitro.nitro.js +6 -0
  25. package/nitrogen/generated/android/c++/JAndroidConnectionPriority.hpp +61 -0
  26. package/nitrogen/generated/android/c++/JBLEDevice.hpp +9 -1
  27. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__BLEDevice___std__optional_std__variant_nitro__NullType__std__string__.hpp +4 -0
  28. package/nitrogen/generated/android/c++/JFunc_void_std__vector_BLEDevice_.hpp +4 -0
  29. package/nitrogen/generated/android/c++/JHybridNativeBleNitroFactorySpec.cpp +8 -0
  30. package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.cpp +17 -0
  31. package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.hpp +1 -0
  32. package/nitrogen/generated/android/c++/JServiceData.hpp +80 -0
  33. package/nitrogen/generated/android/c++/JServiceDataEntry.hpp +63 -0
  34. package/nitrogen/generated/android/c++/JVariant_NullType_BLEDevice.hpp +4 -0
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/AndroidConnectionPriority.kt +24 -0
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BLEDevice.kt +5 -2
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridNativeBleNitroSpec.kt +4 -0
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ServiceData.kt +38 -0
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ServiceDataEntry.kt +41 -0
  40. package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.hpp +17 -0
  41. package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Umbrella.hpp +9 -0
  42. package/nitrogen/generated/ios/c++/HybridNativeBleNitroFactorySpecSwift.hpp +6 -0
  43. package/nitrogen/generated/ios/c++/HybridNativeBleNitroSpecSwift.hpp +17 -0
  44. package/nitrogen/generated/ios/swift/AndroidConnectionPriority.swift +44 -0
  45. package/nitrogen/generated/ios/swift/BLEDevice.swift +7 -2
  46. package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec.swift +1 -0
  47. package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec_cxx.swift +12 -0
  48. package/nitrogen/generated/ios/swift/ServiceData.swift +35 -0
  49. package/nitrogen/generated/ios/swift/ServiceDataEntry.swift +34 -0
  50. package/nitrogen/generated/shared/c++/AndroidConnectionPriority.hpp +63 -0
  51. package/nitrogen/generated/shared/c++/BLEDevice.hpp +8 -1
  52. package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.cpp +1 -0
  53. package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.hpp +4 -0
  54. package/nitrogen/generated/shared/c++/ServiceData.hpp +85 -0
  55. package/nitrogen/generated/shared/c++/ServiceDataEntry.hpp +88 -0
  56. package/package.json +1 -1
  57. package/src/__tests__/index.test.ts +69 -2
  58. package/src/index.ts +3 -0
  59. package/src/manager.ts +50 -0
  60. package/src/specs/NativeBleNitro.nitro.ts +18 -1
package/README.md CHANGED
@@ -13,6 +13,7 @@ Originally developed for [Zyke Band](https://zykeband.com?utm_source=github&utm_
13
13
  - 📱 **iOS Support**: Complete iOS implementation with Swift and Core Bluetooth
14
14
  - 🤖 **Android Support**: Complete Android implementation with Kotlin and Android BLE APIs
15
15
  - 🎯 **Type-Safe**: Full TypeScript support with comprehensive type definitions
16
+ - 📡 **Advertisement Data**: Extract advertised service data and manufacturer data from scan results
16
17
  - 🔧 **Expo Ready**: Built-in Expo config plugin for easy setup
17
18
  - 🏗️ **New Architecture**: Full support for React Native's new architecture
18
19
  - ⚡ **Zero Bridge**: Direct JSI communication eliminates bridge bottlenecks
@@ -69,7 +70,7 @@ npx pod-install # iOS only
69
70
  ### Basic Setup
70
71
 
71
72
  ```typescript
72
- import { BleNitro, BleNitroManager, BLEState, AndroidScanMode, type BLEDevice } from 'react-native-ble-nitro';
73
+ import { BleNitro, BleNitroManager, BLEState, AndroidScanMode, AndroidConnectionPriority, type BLEDevice } from 'react-native-ble-nitro';
73
74
 
74
75
  // Get the singleton instance
75
76
  const ble = BleNitro.instance();
@@ -127,6 +128,16 @@ ble.startScan({
127
128
  androidScanMode: AndroidScanMode.Balanced // Optional: Android scan mode
128
129
  }, (device) => {
129
130
  console.log('Discovered device:', device);
131
+
132
+ // Advertised service data, keyed by service UUID (ArrayBuffer payloads)
133
+ device.serviceData.services.forEach(({ uuid, data }) => {
134
+ console.log(`Service data for ${uuid}:`, new Uint8Array(data));
135
+ });
136
+
137
+ // Advertised manufacturer data, keyed by company identifier
138
+ device.manufacturerData.companyIdentifiers.forEach(({ id, data }) => {
139
+ console.log(`Manufacturer data for ${id}:`, new Uint8Array(data));
140
+ });
130
141
  }, (error) => {
131
142
  // only called on Android
132
143
  console.error('Scan error:', error);
@@ -189,6 +200,18 @@ const mtu = await ble.requestMTU(deviceId, 256); // Request MTU size
189
200
  const newMTU = ble.requestMTU(deviceId, 247);
190
201
  console.log('MTU set to:', newMTU);
191
202
 
203
+ // Request Android connection priority while connected (Android only).
204
+ // Returns true if Android successfully initiated the request (the priority change
205
+ // is applied asynchronously); returns false on iOS, an error, or a disconnected device.
206
+ const priorityRequested = ble.requestConnectionPriority(deviceId, AndroidConnectionPriority.High);
207
+
208
+ // AndroidConnectionPriority options:
209
+ // AndroidConnectionPriority.High → lower latency, higher power usage
210
+ // AndroidConnectionPriority.Balanced → default balanced connection interval
211
+ // AndroidConnectionPriority.LowPower → higher latency, lower power usage
212
+ ble.requestConnectionPriority(deviceId, AndroidConnectionPriority.Balanced);
213
+ ble.requestConnectionPriority(deviceId, AndroidConnectionPriority.LowPower);
214
+
192
215
  // Read RSSI value
193
216
  const rssi = await ble.readRSSI(deviceId);
194
217
  console.log('Current RSSI:', rssi);
@@ -311,6 +334,7 @@ const deviceId = await ble.connect(
311
334
  },
312
335
  autoConnectOnAndroid,
313
336
  );
337
+ ble.requestConnectionPriority(deviceId, AndroidConnectionPriority.High);
314
338
  await ble.discoverServices(deviceId);
315
339
 
316
340
  const subscription = await ble.subscribeToCharacteristic(
@@ -427,8 +451,30 @@ interface BLEDevice {
427
451
  name: string;
428
452
  rssi: number;
429
453
  manufacturerData: ManufacturerData;
454
+ serviceData: ServiceData;
430
455
  serviceUUIDs: string[];
431
456
  isConnectable: boolean;
457
+ isConnected: boolean;
458
+ }
459
+
460
+ // Advertised manufacturer-specific data, keyed by company identifier
461
+ interface ManufacturerData {
462
+ companyIdentifiers: ManufacturerDataEntry[];
463
+ }
464
+
465
+ interface ManufacturerDataEntry {
466
+ id: string; // company identifier (hex)
467
+ data: ArrayBuffer; // raw manufacturer payload
468
+ }
469
+
470
+ // Advertised service data, keyed by service UUID
471
+ interface ServiceData {
472
+ services: ServiceDataEntry[];
473
+ }
474
+
475
+ interface ServiceDataEntry {
476
+ uuid: string; // service UUID
477
+ data: ArrayBuffer; // raw service-data payload
432
478
  }
433
479
 
434
480
  interface ScanFilter {
@@ -462,6 +508,12 @@ enum AndroidScanMode {
462
508
  Opportunistic = 'Opportunistic', // Only when other apps are scanning
463
509
  }
464
510
 
511
+ enum AndroidConnectionPriority {
512
+ Balanced = 'Balanced', // Balanced connection interval
513
+ High = 'High', // Lower latency, higher power
514
+ LowPower = 'LowPower', // Lower power, higher latency
515
+ }
516
+
465
517
  // Callback types
466
518
  type StateChangeCallback = (state: BLEState) => void;
467
519
  type ScanEventCallback = (device: BLEDevice) => void;
@@ -111,6 +111,10 @@ android {
111
111
  targetCompatibility JavaVersion.VERSION_1_8
112
112
  }
113
113
 
114
+ testOptions {
115
+ unitTests.returnDefaultValues = true
116
+ }
117
+
114
118
  sourceSets {
115
119
  main {
116
120
  if (isNewArchitectureEnabled()) {
@@ -137,4 +141,6 @@ dependencies {
137
141
 
138
142
  // Add a dependency on NitroModules
139
143
  implementation project(":react-native-nitro-modules")
144
+
145
+ testImplementation "junit:junit:4.13.2"
140
146
  }
@@ -69,6 +69,17 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
69
69
 
70
70
  // Descriptor write callback storage (key: deviceId:descriptorUuid)
71
71
  private val descriptorWriteCallbacks = ConcurrentHashMap<String, (Boolean, String) -> Unit>()
72
+
73
+ // Android permits only one outstanding ATT operation per GATT connection.
74
+ // Defer service discovery while an MTU request is in flight so the two
75
+ // procedures cannot overlap when JS calls them back-to-back.
76
+ // All three maps below are guarded by mtuGateLock, so plain HashMaps suffice.
77
+ private val mtuInFlight = HashMap<String, Boolean>()
78
+ private val pendingDiscovery = HashMap<String, () -> Unit>()
79
+ private val mtuFallbackRunnables = HashMap<String, Runnable>()
80
+ private val mtuHandler = android.os.Handler(android.os.Looper.getMainLooper())
81
+ private val mtuGateLock = Any()
82
+ private val mtuSettleFallbackMs = 1000L
72
83
 
73
84
  // Helper class to store device callbacks
74
85
  private data class DeviceCallbacks(
@@ -225,14 +236,32 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
225
236
  ManufacturerData(companyIdentifiers = entries.toTypedArray())
226
237
  } ?: ManufacturerData(companyIdentifiers = emptyArray())
227
238
 
239
+ // Extract service data
240
+ val serviceData = scanRecord?.serviceData?.let { dataMap ->
241
+ val entries = mutableListOf<ServiceDataEntry>()
242
+ for ((uuid, value) in dataMap) {
243
+ // Create direct ByteBuffer as required by ArrayBuffer.wrap()
244
+ val directBuffer = java.nio.ByteBuffer.allocateDirect(value.size)
245
+ directBuffer.put(value)
246
+ directBuffer.flip()
247
+
248
+ entries.add(ServiceDataEntry(
249
+ uuid = uuid.toString(),
250
+ data = ArrayBuffer.wrap(directBuffer)
251
+ ))
252
+ }
253
+ ServiceData(services = entries.toTypedArray())
254
+ } ?: ServiceData(services = emptyArray())
255
+
228
256
  // Extract service UUIDs
229
257
  val serviceUUIDs = scanRecord?.serviceUuids?.map { it.toString() }?.toTypedArray() ?: emptyArray()
230
-
258
+
231
259
  return BLEDevice(
232
260
  id = device.address,
233
261
  name = device.name ?: "",
234
262
  rssi = scanResult.rssi.toDouble(),
235
263
  manufacturerData = manufacturerData,
264
+ serviceData = serviceData,
236
265
  serviceUUIDs = serviceUUIDs,
237
266
  isConnectable = true, // Assume scannable devices are connectable
238
267
  isConnected = false // Scanned devices are not yet connected
@@ -268,6 +297,7 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
268
297
  override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
269
298
  when (newState) {
270
299
  BluetoothProfile.STATE_CONNECTED -> {
300
+ clearMtuGateState(deviceId)
271
301
  var connectCb: ((Boolean, String, String) -> Unit)? = null
272
302
  deviceCallbacks.compute(deviceId) { _, callbacks ->
273
303
  connectCb = callbacks?.connectCallback
@@ -277,14 +307,25 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
277
307
  }
278
308
  BluetoothProfile.STATE_DISCONNECTED -> {
279
309
  // Clean up
310
+ clearMtuGateState(deviceId)
280
311
  connectedDevices.remove(deviceId)
281
312
  val interrupted = status != BluetoothGatt.GATT_SUCCESS
282
313
  val cb = deviceCallbacks.remove(deviceId)
314
+ // If a discoverServices() call was still in flight (or deferred
315
+ // behind an MTU request), it will never receive onServicesDiscovered
316
+ // now. Fail it explicitly so the JS promise does not hang forever.
317
+ cb?.serviceDiscoveryCallback?.invoke(false, "Disconnected before service discovery completed")
283
318
  cb?.disconnectCallback?.invoke(deviceId, interrupted, if (interrupted) "Connection lost" else "")
284
319
  gatt.close()
285
320
  }
286
321
  }
287
322
  }
323
+
324
+ override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) {
325
+ // Use the deviceId captured for this callback so the gate key always
326
+ // matches the one markMtuInFlight() recorded under.
327
+ settleMtu(deviceId)
328
+ }
288
329
 
289
330
  override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
290
331
  val callbacks = deviceCallbacks[deviceId]
@@ -397,6 +438,59 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
397
438
  }
398
439
  }
399
440
 
441
+ private fun runOrDeferDiscovery(deviceId: String, startDiscovery: () -> Unit) {
442
+ val shouldStartNow = synchronized(mtuGateLock) {
443
+ if (mtuInFlight[deviceId] == true) {
444
+ pendingDiscovery[deviceId] = startDiscovery
445
+ false
446
+ } else {
447
+ true
448
+ }
449
+ }
450
+
451
+ if (shouldStartNow) {
452
+ startDiscovery()
453
+ }
454
+ }
455
+
456
+ private fun markMtuInFlight(deviceId: String) {
457
+ synchronized(mtuGateLock) {
458
+ mtuInFlight[deviceId] = true
459
+ mtuFallbackRunnables.remove(deviceId)?.let { mtuHandler.removeCallbacks(it) }
460
+ val runnable = Runnable { settleMtu(deviceId) }
461
+ mtuFallbackRunnables[deviceId] = runnable
462
+ mtuHandler.postDelayed(runnable, mtuSettleFallbackMs)
463
+ }
464
+ }
465
+
466
+ private fun settleMtu(deviceId: String) {
467
+ val discoveryToStart = synchronized(mtuGateLock) {
468
+ mtuInFlight.remove(deviceId)
469
+ mtuFallbackRunnables.remove(deviceId)?.let { mtuHandler.removeCallbacks(it) }
470
+ pendingDiscovery.remove(deviceId)
471
+ }
472
+ // settleMtu can be invoked from the binder thread (onMtuChanged) or the main
473
+ // thread (fallback). Start the deferred discovery on the main looper so GATT
474
+ // operations are always issued from a single, consistent thread.
475
+ discoveryToStart?.let { mtuHandler.post(it) }
476
+ }
477
+
478
+ private fun clearMtuGateState(deviceId: String) {
479
+ synchronized(mtuGateLock) {
480
+ mtuInFlight.remove(deviceId)
481
+ pendingDiscovery.remove(deviceId)
482
+ mtuFallbackRunnables.remove(deviceId)?.let { mtuHandler.removeCallbacks(it) }
483
+ }
484
+ }
485
+
486
+ private fun mapAndroidConnectionPriority(androidConnectionPriority: AndroidConnectionPriority): Int {
487
+ return when (androidConnectionPriority) {
488
+ AndroidConnectionPriority.HIGH -> BluetoothGatt.CONNECTION_PRIORITY_HIGH
489
+ AndroidConnectionPriority.LOWPOWER -> BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER
490
+ AndroidConnectionPriority.BALANCED -> BluetoothGatt.CONNECTION_PRIORITY_BALANCED
491
+ }
492
+ }
493
+
400
494
  /**
401
495
  * Enqueue a GATT operation to be executed sequentially.
402
496
  * Android BLE requires that only one GATT operation runs at a time.
@@ -688,6 +782,9 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
688
782
  val gatt = connectedDevices[deviceId]
689
783
  if (gatt != null) {
690
784
  val success = gatt.requestMtu(mtu.toInt())
785
+ if (success) {
786
+ markMtuInFlight(deviceId)
787
+ }
691
788
  if (success) mtu else 0.0
692
789
  } else {
693
790
  0.0
@@ -697,6 +794,15 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
697
794
  }
698
795
  }
699
796
 
797
+ override fun requestConnectionPriority(deviceId: String, androidConnectionPriority: AndroidConnectionPriority): Boolean {
798
+ return try {
799
+ val gatt = connectedDevices[deviceId] ?: return false
800
+ gatt.requestConnectionPriority(mapAndroidConnectionPriority(androidConnectionPriority))
801
+ } catch (_: Exception) {
802
+ false
803
+ }
804
+ }
805
+
700
806
  override fun readRSSI(deviceId: String, callback: (success: Boolean, rssi: Double, error: String) -> Unit) {
701
807
  try {
702
808
  val gatt = connectedDevices[deviceId]
@@ -731,14 +837,16 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
731
837
  // Store the callback for when service discovery completes
732
838
  callbacks.serviceDiscoveryCallback = callback
733
839
 
734
- // Start service discovery
735
- val success = gatt.discoverServices()
736
- if (!success) {
737
- // Clear callback and report failure immediately
738
- callbacks.serviceDiscoveryCallback = null
739
- callback(false, "Failed to start service discovery")
840
+ runOrDeferDiscovery(deviceId) {
841
+ // Start service discovery
842
+ val success = gatt.discoverServices()
843
+ if (!success) {
844
+ // Clear callback and report failure immediately
845
+ callbacks.serviceDiscoveryCallback = null
846
+ callback(false, "Failed to start service discovery")
847
+ }
848
+ // If success, the callback will be invoked in onServicesDiscovered
740
849
  }
741
- // If success, the callback will be invoked in onServicesDiscovered
742
850
  } else {
743
851
  callback(false, "Device callback not found")
744
852
  }
@@ -921,7 +1029,16 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
921
1029
 
922
1030
  val subscriptionKey = "$serviceId:$characteristicId"
923
1031
 
924
- // Write to the CCCD descriptor to enable notifications on the remote device.
1032
+ val cccdValue = when (cccdSubscriptionMode(characteristic.properties)) {
1033
+ CccdSubscriptionMode.INDICATE -> BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
1034
+ CccdSubscriptionMode.NOTIFY -> BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
1035
+ CccdSubscriptionMode.UNSUPPORTED -> {
1036
+ completionCallback(false, "Characteristic does not support notify or indicate")
1037
+ return
1038
+ }
1039
+ }
1040
+
1041
+ // Write to the CCCD descriptor to enable notifications or indications on the remote device.
925
1042
  // The update callback is stored only after the descriptor write succeeds
926
1043
  // so that isSubscribedToCharacteristic reflects actual BLE state.
927
1044
  val descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"))
@@ -930,7 +1047,7 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
930
1047
  GattOperation.WriteDescriptor(
931
1048
  gatt = gatt,
932
1049
  descriptor = descriptor,
933
- value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE,
1050
+ value = cccdValue,
934
1051
  deviceId = deviceId,
935
1052
  callback = { success, error ->
936
1053
  if (success) {
@@ -1142,4 +1259,4 @@ class BleNitroBleManager : HybridNativeBleNitroSpec() {
1142
1259
  }
1143
1260
  return promise
1144
1261
  }
1145
- }
1262
+ }
@@ -0,0 +1,38 @@
1
+ package com.margelo.nitro.co.zyke.ble
2
+
3
+ import android.bluetooth.BluetoothGattCharacteristic
4
+
5
+ /**
6
+ * The delivery mode to request via the CCCD descriptor when subscribing to a
7
+ * characteristic, derived from the characteristic's declared properties.
8
+ */
9
+ internal enum class CccdSubscriptionMode {
10
+ /** Use ENABLE_NOTIFICATION_VALUE (unacknowledged delivery). */
11
+ NOTIFY,
12
+
13
+ /** Use ENABLE_INDICATION_VALUE (acknowledged delivery). */
14
+ INDICATE,
15
+
16
+ /** The characteristic supports neither notify nor indicate. */
17
+ UNSUPPORTED,
18
+ }
19
+
20
+ /**
21
+ * Selects the CCCD subscription mode for a characteristic's [properties] bitmask.
22
+ *
23
+ * Notification is preferred when the characteristic supports both notify and
24
+ * indicate because it is unacknowledged and lower-overhead. Indication is used
25
+ * only for indicate-only characteristics. This mirrors iOS CoreBluetooth, where
26
+ * `setNotifyValue(true)` automatically selects the appropriate delivery mode.
27
+ *
28
+ * [properties] is the value of [BluetoothGattCharacteristic.getProperties].
29
+ */
30
+ internal fun cccdSubscriptionMode(properties: Int): CccdSubscriptionMode {
31
+ val supportsNotify = (properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0
32
+ val supportsIndicate = (properties and BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0
33
+ return when {
34
+ supportsNotify -> CccdSubscriptionMode.NOTIFY
35
+ supportsIndicate -> CccdSubscriptionMode.INDICATE
36
+ else -> CccdSubscriptionMode.UNSUPPORTED
37
+ }
38
+ }
@@ -0,0 +1,48 @@
1
+ package com.margelo.nitro.co.zyke.ble
2
+
3
+ import android.bluetooth.BluetoothGattCharacteristic
4
+ import org.junit.Assert.assertEquals
5
+ import org.junit.Test
6
+
7
+ /**
8
+ * Unit tests for [cccdSubscriptionMode].
9
+ *
10
+ * `PROPERTY_NOTIFY` and `PROPERTY_INDICATE` are compile-time `int` constants and
11
+ * are inlined by the compiler, so these tests run on the plain JVM without
12
+ * Robolectric or a connected device.
13
+ */
14
+ class CccdSubscriptionTest {
15
+ private val notify = BluetoothGattCharacteristic.PROPERTY_NOTIFY
16
+ private val indicate = BluetoothGattCharacteristic.PROPERTY_INDICATE
17
+ private val read = BluetoothGattCharacteristic.PROPERTY_READ
18
+
19
+ @Test
20
+ fun notifyOnly_usesNotify() {
21
+ assertEquals(CccdSubscriptionMode.NOTIFY, cccdSubscriptionMode(notify))
22
+ }
23
+
24
+ @Test
25
+ fun indicateOnly_usesIndicate() {
26
+ assertEquals(CccdSubscriptionMode.INDICATE, cccdSubscriptionMode(indicate))
27
+ }
28
+
29
+ @Test
30
+ fun supportsBoth_prefersNotify() {
31
+ assertEquals(CccdSubscriptionMode.NOTIFY, cccdSubscriptionMode(notify or indicate))
32
+ }
33
+
34
+ @Test
35
+ fun indicateWithOtherProperties_usesIndicate() {
36
+ assertEquals(CccdSubscriptionMode.INDICATE, cccdSubscriptionMode(indicate or read))
37
+ }
38
+
39
+ @Test
40
+ fun neitherNotifyNorIndicate_isUnsupported() {
41
+ assertEquals(CccdSubscriptionMode.UNSUPPORTED, cccdSubscriptionMode(read))
42
+ }
43
+
44
+ @Test
45
+ fun noProperties_isUnsupported() {
46
+ assertEquals(CccdSubscriptionMode.UNSUPPORTED, cccdSubscriptionMode(0))
47
+ }
48
+ }
@@ -164,6 +164,7 @@ public class BleNitroBleManager: HybridNativeBleNitroSpec {
164
164
  name: peripheral.name ?? "Unknown Device",
165
165
  rssi: 0, // RSSI not available for connected devices without explicit read
166
166
  manufacturerData: ManufacturerData(companyIdentifiers: []), // Not available for connected devices
167
+ serviceData: ServiceData(services: []), // Not available for connected devices
167
168
  serviceUUIDs: peripheral.services?.map { $0.uuid.uuidString } ?? [],
168
169
  isConnectable: true, // Already connected, so it was connectable
169
170
  isConnected: true
@@ -185,12 +186,13 @@ public class BleNitroBleManager: HybridNativeBleNitroSpec {
185
186
  name: peripheral.name ?? "Unknown Device",
186
187
  rssi: 0,
187
188
  manufacturerData: ManufacturerData(companyIdentifiers: []),
189
+ serviceData: ServiceData(services: []),
188
190
  serviceUUIDs: peripheral.services?.map { $0.uuid.uuidString } ?? [],
189
191
  isConnectable: true,
190
192
  isConnected: true
191
193
  )
192
194
  connectedDevices.append(device)
193
-
195
+
194
196
  // Add to our tracking dictionary
195
197
  connectedPeripherals[deviceId] = peripheral
196
198
  }
@@ -211,6 +213,7 @@ public class BleNitroBleManager: HybridNativeBleNitroSpec {
211
213
  name: peripheral.name ?? "Unknown Device",
212
214
  rssi: 0,
213
215
  manufacturerData: ManufacturerData(companyIdentifiers: []),
216
+ serviceData: ServiceData(services: []),
214
217
  serviceUUIDs: peripheral.services?.map { $0.uuid.uuidString } ?? [],
215
218
  isConnectable: true,
216
219
  isConnected: true
@@ -289,6 +292,10 @@ public class BleNitroBleManager: HybridNativeBleNitroSpec {
289
292
 
290
293
  return Double(peripheral.maximumWriteValueLength(for: .withoutResponse))
291
294
  }
295
+
296
+ public func requestConnectionPriority(deviceId: String, androidConnectionPriority: AndroidConnectionPriority) throws -> Bool {
297
+ return false
298
+ }
292
299
 
293
300
  public func readRSSI(deviceId: String, callback: @escaping (Bool, Double, String) -> Void) throws {
294
301
  guard let peripheral = connectedPeripherals[deviceId] else {
@@ -607,6 +614,7 @@ public class BleNitroBleManager: HybridNativeBleNitroSpec {
607
614
  name: peripheral.name ?? "Restored Device",
608
615
  rssi: 0, // RSSI not available for restored peripherals
609
616
  manufacturerData: ManufacturerData(companyIdentifiers: []),
617
+ serviceData: ServiceData(services: []),
610
618
  serviceUUIDs: peripheral.services?.map { $0.uuid.uuidString } ?? [],
611
619
  isConnectable: true,
612
620
  isConnected: peripheral.state == .connected
@@ -726,20 +734,37 @@ public class BleNitroBleManager: HybridNativeBleNitroSpec {
726
734
 
727
735
  // Extract manufacturer data
728
736
  let manufacturerData = extractManufacturerData(from: advertisementData)
729
-
737
+
738
+ // Extract service data
739
+ let serviceData = extractServiceData(from: advertisementData)
740
+
730
741
  // Check if connectable
731
742
  let isConnectable = (advertisementData[CBAdvertisementDataIsConnectable] as? Bool) ?? true
732
-
743
+
733
744
  return BLEDevice(
734
745
  id: deviceId,
735
746
  name: deviceName,
736
747
  rssi: rssi,
737
748
  manufacturerData: manufacturerData,
749
+ serviceData: serviceData,
738
750
  serviceUUIDs: serviceUUIDs,
739
751
  isConnectable: isConnectable,
740
752
  isConnected: peripheral.state == .connected
741
753
  )
742
754
  }
755
+
756
+ private func extractServiceData(from advertisementData: [String: Any]) -> ServiceData {
757
+ guard let serviceDataRaw = advertisementData[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] else {
758
+ return ServiceData(services: [])
759
+ }
760
+
761
+ let entries: [ServiceDataEntry] = serviceDataRaw.map { (uuid, data) in
762
+ let arrayBuffer = (try? ArrayBuffer.copy(data: data)) ?? (try! ArrayBuffer.copy(data: Data()))
763
+ return ServiceDataEntry(uuid: uuid.uuidString, data: arrayBuffer)
764
+ }
765
+
766
+ return ServiceData(services: entries)
767
+ }
743
768
 
744
769
  private func extractManufacturerData(from advertisementData: [String: Any]) -> ManufacturerData {
745
770
  guard let manufacturerDataRaw = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data else {
@@ -1,3 +1,3 @@
1
- export { type ByteArray, type ScanFilter, type BLEDevice, type ScanCallback, type ManufacturerDataEntry, type ManufacturerData, type ConnectionCallback, type DisconnectEventCallback, type OperationCallback, type CharacteristicUpdateCallback, type Subscription, type AsyncSubscription, type BleNitroManagerOptions, BLEState, AndroidScanMode, BleNitroManager, BleTimeoutError, } from "./manager";
1
+ export { type ByteArray, type ScanFilter, type BLEDevice, type ScanCallback, type ManufacturerDataEntry, type ManufacturerData, type ServiceDataEntry, type ServiceData, type ConnectionCallback, type DisconnectEventCallback, type OperationCallback, type CharacteristicUpdateCallback, type Subscription, type AsyncSubscription, type BleNitroManagerOptions, BLEState, AndroidScanMode, AndroidConnectionPriority, BleNitroManager, BleTimeoutError, } from "./manager";
2
2
  export { BleNitro } from './singleton';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,4BAA4B,EACjC,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,QAAQ,EACR,eAAe,EACf,eAAe,EACf,eAAe,GAChB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,4BAA4B,EACjC,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,QAAQ,EACR,eAAe,EACf,yBAAyB,EACzB,eAAe,EACf,eAAe,GAChB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BleNitro = exports.BleTimeoutError = exports.BleNitroManager = exports.AndroidScanMode = exports.BLEState = void 0;
3
+ exports.BleNitro = exports.BleTimeoutError = exports.BleNitroManager = exports.AndroidConnectionPriority = exports.AndroidScanMode = exports.BLEState = void 0;
4
4
  var manager_1 = require("./manager");
5
5
  Object.defineProperty(exports, "BLEState", { enumerable: true, get: function () { return manager_1.BLEState; } });
6
6
  Object.defineProperty(exports, "AndroidScanMode", { enumerable: true, get: function () { return manager_1.AndroidScanMode; } });
7
+ Object.defineProperty(exports, "AndroidConnectionPriority", { enumerable: true, get: function () { return manager_1.AndroidConnectionPriority; } });
7
8
  Object.defineProperty(exports, "BleNitroManager", { enumerable: true, get: function () { return manager_1.BleNitroManager; } });
8
9
  Object.defineProperty(exports, "BleTimeoutError", { enumerable: true, get: function () { return manager_1.BleTimeoutError; } });
9
10
  var singleton_1 = require("./singleton");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAkBmB;AAJjB,mGAAA,QAAQ,OAAA;AACR,0GAAA,eAAe,OAAA;AACf,0GAAA,eAAe,OAAA;AACf,0GAAA,eAAe,OAAA;AAGjB,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAqBmB;AALjB,mGAAA,QAAQ,OAAA;AACR,0GAAA,eAAe,OAAA;AACf,oHAAA,yBAAyB,OAAA;AACzB,0GAAA,eAAe,OAAA;AACf,0GAAA,eAAe,OAAA;AAGjB,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA"}
@@ -1,4 +1,4 @@
1
- import { BLEDevice as NativeBLEDevice, BLEState as NativeBLEState, AndroidScanMode as NativeAndroidScanMode } from './specs/NativeBleNitro';
1
+ import { BLEDevice as NativeBLEDevice, BLEState as NativeBLEState, AndroidScanMode as NativeAndroidScanMode, AndroidConnectionPriority as NativeAndroidConnectionPriority } from './specs/NativeBleNitro';
2
2
  export declare class BleTimeoutError extends Error {
3
3
  constructor(operation: string, ms: number);
4
4
  }
@@ -16,11 +16,19 @@ export interface ManufacturerDataEntry {
16
16
  export interface ManufacturerData {
17
17
  companyIdentifiers: ManufacturerDataEntry[];
18
18
  }
19
+ export interface ServiceDataEntry {
20
+ uuid: string;
21
+ data: ByteArray;
22
+ }
23
+ export interface ServiceData {
24
+ services: ServiceDataEntry[];
25
+ }
19
26
  export interface BLEDevice {
20
27
  id: string;
21
28
  name: string;
22
29
  rssi: number;
23
30
  manufacturerData: ManufacturerData;
31
+ serviceData: ServiceData;
24
32
  serviceUUIDs: string[];
25
33
  isConnectable: boolean;
26
34
  isConnected: boolean;
@@ -51,12 +59,18 @@ export declare enum AndroidScanMode {
51
59
  LowPower = "LowPower",
52
60
  Opportunistic = "Opportunistic"
53
61
  }
62
+ export declare enum AndroidConnectionPriority {
63
+ Balanced = "Balanced",
64
+ High = "High",
65
+ LowPower = "LowPower"
66
+ }
54
67
  export type BleNitroManagerOptions = {
55
68
  restoreIdentifier?: string;
56
69
  onRestoredState?: RestoreStateCallback;
57
70
  };
58
71
  export declare function mapNativeBLEStateToBLEState(nativeState: NativeBLEState): BLEState;
59
72
  export declare function mapAndroidScanModeToNativeAndroidScanMode(scanMode: AndroidScanMode): NativeAndroidScanMode;
73
+ export declare function mapAndroidConnectionPriorityToNativeAndroidConnectionPriority(priority: AndroidConnectionPriority): NativeAndroidConnectionPriority;
60
74
  export declare function convertNativeBleDeviceToBleDevice(nativeBleDevice: NativeBLEDevice): BLEDevice;
61
75
  export declare function arrayBufferToByteArray(buffer: ArrayBuffer): ByteArray;
62
76
  export declare function byteArrayToArrayBuffer(data: ByteArray): ArrayBuffer;
@@ -150,6 +164,15 @@ export declare class BleNitroManager {
150
164
  * @returns On Android: new MTU size; on iOS: current MTU size as it is handled by iOS itself; on error: -1
151
165
  */
152
166
  requestMTU(deviceId: string, mtu: number): number;
167
+ /**
168
+ * Request an Android connection priority for an active connection.
169
+ * @param deviceId ID of the device
170
+ * @param priority Desired Android connection priority
171
+ * @returns On Android: true if the request was successfully initiated (the
172
+ * priority change itself is applied asynchronously); on iOS, an error, or a
173
+ * disconnected device: false
174
+ */
175
+ requestConnectionPriority(deviceId: string, priority: AndroidConnectionPriority): boolean;
153
176
  /**
154
177
  * Read RSSI for a connected device
155
178
  * @param deviceId ID of the device
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"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"}