@@ -15,7 +15,6 @@ import com.reactnativebledidcomm.peripheral.PeripheralManager
1515import com.reactnativebledidcomm.peripheral.PeripheralManagerException
1616import java.util.*
1717
18-
1918class BleDidcommModule (private val context : ReactApplicationContext ) :
2019 ReactContextBaseJavaModule (context) {
2120 private var centralManager: CentralManager ? = null
@@ -28,7 +27,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
2827 @ReactMethod
2928 fun startCentral (
3029 @Suppress(" UNUSED_PARAMETER" ) options : ReadableMap ,
31- promise : Promise
30+ promise : Promise ,
3231 ) {
3332 try {
3433 this .centralManager = CentralManager (context)
@@ -42,10 +41,10 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
4241 @RequiresPermission(value = " android.permission.BLUETOOTH_CONNECT" )
4342 fun startPeripheral (
4443 @Suppress(" UNUSED_PARAMETER" ) options : ReadableMap ,
45- promise : Promise
44+ promise : Promise ,
4645 ) {
4746 try {
48- this .peripheralManager = PeripheralManager (context, GattServerCallback () )
47+ this .peripheralManager = PeripheralManager (context, gattServerCallback )
4948 promise.resolve(null )
5049 } catch (e: Exception ) {
5150 promise.reject(" error" , e)
@@ -55,7 +54,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
5554 @ReactMethod
5655 fun shutdownCentral (
5756 @Suppress(" UNUSED_PARAMETER" ) options : ReadableMap ,
58- promise : Promise
57+ promise : Promise ,
5958 ) {
6059 try {
6160 this .centralManager?.shutdownCentral()
@@ -69,7 +68,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
6968 @ReactMethod
7069 fun shutdownPeripheral (
7170 @Suppress(" UNUSED_PARAMETER" ) options : ReadableMap ,
72- promise : Promise
71+ promise : Promise ,
7372 ) {
7473 try {
7574 this .peripheralManager?.shutdownPeripheral()
@@ -85,15 +84,15 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
8584 serviceUUID : String ,
8685 writeCharacteristicUUID : String ,
8786 indicationCharacteristicUUID : String ,
88- promise : Promise
87+ promise : Promise ,
8988 ) {
9089 try {
9190 val centralManager =
9291 this .centralManager ? : throw CentralManagerException .NotStarted ()
9392 centralManager.setService(
9493 UUID .fromString(serviceUUID),
9594 UUID .fromString(writeCharacteristicUUID),
96- UUID .fromString(indicationCharacteristicUUID)
95+ UUID .fromString(indicationCharacteristicUUID),
9796 )
9897 promise.resolve(null )
9998 } catch (e: Exception ) {
@@ -106,15 +105,15 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
106105 serviceUUID : String ,
107106 writeCharacteristicUUID : String ,
108107 indicationCharacteristicUUID : String ,
109- promise : Promise
108+ promise : Promise ,
110109 ) {
111110 try {
112111 val peripheralManager =
113112 this .peripheralManager ? : throw PeripheralManagerException .NotStarted ()
114113 peripheralManager.setService(
115114 UUID .fromString(serviceUUID),
116115 UUID .fromString(writeCharacteristicUUID),
117- UUID .fromString(indicationCharacteristicUUID)
116+ UUID .fromString(indicationCharacteristicUUID),
118117 )
119118 promise.resolve(null )
120119 } catch (e: Exception ) {
@@ -128,7 +127,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
128127 try {
129128 val centralManager =
130129 this .centralManager ? : throw CentralManagerException .NotStarted ()
131- centralManager.scan(BluetoothScanCallback () )
130+ centralManager.scan(bluetoothScanCallback )
132131 promise.resolve(null )
133132 } catch (e: Exception ) {
134133 promise.reject(" error" , e)
@@ -141,7 +140,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
141140 try {
142141 val peripheralManager =
143142 this .peripheralManager ? : throw PeripheralManagerException .NotStarted ()
144- peripheralManager.advertise(DeviceAdvertiseCallback () )
143+ peripheralManager.advertise(deviceAdvertiseCallback )
145144 promise.resolve(null )
146145 } catch (e: Exception ) {
147146 promise.reject(" error" , e)
@@ -154,7 +153,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
154153 try {
155154 val centralManager =
156155 this .centralManager ? : throw CentralManagerException .NotStarted ()
157- centralManager.connect(peripheralId, GattClientCallback () )
156+ centralManager.connect(peripheralId, gattClientCallback )
158157 promise.resolve(null )
159158 } catch (e: Exception ) {
160159 promise.reject(" error" , e)
@@ -187,12 +186,10 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
187186 }
188187 }
189188
190-
191189 @ReactMethod
192190 fun addListener (@Suppress(" UNUSED_PARAMETER" ) eventName : String ) {
193191 }
194192
195-
196193 @ReactMethod
197194 fun removeListeners (@Suppress(" UNUSED_PARAMETER" ) count : Int ) {
198195 }
@@ -203,12 +200,13 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
203200 .emit(event.token, params)
204201 }
205202
206- private inner class GattClientCallback : BluetoothGattCallback () {
203+ private val gattClientCallback = object : BluetoothGattCallback () {
207204 var message: ByteArray = byteArrayOf()
208205
206+ // Triggered when client receives an indication
209207 override fun onCharacteristicChanged (
210208 gatt : BluetoothGatt ,
211- characteristic : BluetoothGattCharacteristic
209+ characteristic : BluetoothGattCharacteristic ,
212210 ) {
213211 super .onCharacteristicChanged(gatt, characteristic)
214212 val msg = characteristic.value
@@ -223,61 +221,68 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
223221 }
224222 }
225223
224+ // Triggered when the client is ready to send the next message
226225 override fun onCharacteristicWrite (
227226 gatt : BluetoothGatt ,
228227 characteristic : BluetoothGattCharacteristic ,
229- status : Int
228+ status : Int ,
230229 ) {
231230 super .onCharacteristicWrite(gatt, characteristic, status)
232231 if (status == BluetoothGatt .GATT_SUCCESS ) {
233232 centralManager?.isPeripheralReady = true
234233 }
235234 }
236235
236+ // Triggered when the MTU has been changed.
237237 @SuppressLint(" MissingPermission" )
238- override fun onMtuChanged (gatt : BluetoothGatt ? , mtu : Int , status : Int ) {
238+ override fun onMtuChanged (gatt : BluetoothGatt , mtu : Int , status : Int ) {
239239 super .onMtuChanged(gatt, mtu, status)
240240 if (status != BluetoothGatt .GATT_SUCCESS ) {
241241 Log .e(Constants .TAG , " error occurred while requesting MTU. Status $status " )
242242 return
243243 }
244244 centralManager?.connectedMtu = mtu
245- val descriptor =
246- centralManager?.indicationCharacteristic?.getDescriptor(UUID .fromString(Constants .CCC_DESCRIPTOR_UUID ))
247- descriptor?.value = BluetoothGattDescriptor .ENABLE_INDICATION_VALUE
248- gatt?.writeDescriptor(descriptor)
245+ gatt.discoverServices()
249246 }
250247
248+ // Triggered when client discovered services
251249 @SuppressLint(" MissingPermission" )
252250 override fun onServicesDiscovered (gatt : BluetoothGatt , status : Int ) {
253251 super .onServicesDiscovered(gatt, status)
254252 val service = gatt.getService(centralManager?.serviceUUID)
253+
255254 centralManager?.writeCharacteristic =
256255 service.getCharacteristic(centralManager?.writeCharacteristicUUID)
256+
257257 centralManager?.indicationCharacteristic =
258258 service.getCharacteristic(centralManager?.indicationCharacteristicUUID)
259- gatt.setCharacteristicNotification(centralManager?.indicationCharacteristic, true )
260- gatt.requestMtu(512 )
259+
260+ val indicationCharacteristic = centralManager?.indicationCharacteristic ? : return
261+ gatt.setCharacteristicNotification(indicationCharacteristic, true )
262+ val descriptor = indicationCharacteristic.getDescriptor(UUID .fromString(Constants .CCC_DESCRIPTOR_UUID ))
263+ descriptor?.value = BluetoothGattDescriptor .ENABLE_INDICATION_VALUE
264+ gatt.writeDescriptor(descriptor)
261265 }
262266
267+ // Triggered when the connection state is updated
263268 @SuppressLint(" MissingPermission" )
264269 override fun onConnectionStateChange (gatt : BluetoothGatt , status : Int , newState : Int ) {
265270 super .onConnectionStateChange(gatt, status, newState)
266271 val params = Arguments .createMap().apply {
267272 putString(" identifier" , gatt.device.address)
268273 }
269274 if (newState == BluetoothProfile .STATE_CONNECTED ) {
270- sendEvent(BleDidcommEvent .OnConnectedPeripheral , params)
271- gatt.discoverServices()
275+ gatt.requestMtu(512 )
272276 centralManager?.stopScan()
277+ sendEvent(BleDidcommEvent .OnConnectedPeripheral , params)
273278 } else if (newState == BluetoothProfile .STATE_DISCONNECTED ) {
274279 sendEvent(BleDidcommEvent .OnDisconnectedPeripheral , params)
275280 centralManager?.connectedPeripheral = null
276281 }
277282 }
278283 }
279284
280- private inner class BluetoothScanCallback : ScanCallback () {
285+ private val bluetoothScanCallback = object : ScanCallback () {
281286 override fun onScanResult (callbackType : Int , result : ScanResult ? ) {
282287 super .onScanResult(callbackType, result)
283288 val device = result?.device ? : return
@@ -289,9 +294,17 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
289294 }
290295 }
291296
292- private inner class GattServerCallback : BluetoothGattServerCallback () {
297+ private val gattServerCallback = object : BluetoothGattServerCallback () {
293298 var message: ByteArray = byteArrayOf()
294299
300+ // Triggered when the mtu is updated for the peripheral
301+ override fun onMtuChanged (device : BluetoothDevice , mtu : Int ) {
302+ super .onMtuChanged(device, mtu)
303+ peripheralManager?.connectedMtu = mtu
304+ }
305+
306+ // Triggered the peripheral received a write request.
307+ // It appends it to a buffer and when "EOM" is received, it will emit a React Native event
295308 @SuppressLint(" MissingPermission" )
296309 override fun onCharacteristicWriteRequest (
297310 device : BluetoothDevice ,
@@ -300,7 +313,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
300313 preparedWrite : Boolean ,
301314 responseNeeded : Boolean ,
302315 offset : Int ,
303- value : ByteArray
316+ value : ByteArray ,
304317 ) {
305318 super .onCharacteristicWriteRequest(
306319 device,
@@ -309,7 +322,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
309322 preparedWrite,
310323 responseNeeded,
311324 offset,
312- value
325+ value,
313326 )
314327
315328 if (" EOM" == value.toString(Charsets .UTF_8 )) {
@@ -328,18 +341,44 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
328341 requestId,
329342 BluetoothGatt .GATT_SUCCESS ,
330343 offset,
331- value
344+ value,
332345 )
333346 }
334347 }
335348
349+ override fun onDescriptorWriteRequest (
350+ device : BluetoothDevice ,
351+ requestId : Int ,
352+ descriptor : BluetoothGattDescriptor ,
353+ preparedWrite : Boolean ,
354+ responseNeeded : Boolean ,
355+ offset : Int ,
356+ value : ByteArray ,
357+ ) {
358+ super .onDescriptorWriteRequest(
359+ device,
360+ requestId,
361+ descriptor,
362+ preparedWrite,
363+ responseNeeded,
364+ offset,
365+ value,
366+ )
367+ val params = Arguments .createMap().apply {
368+ putString(" identifier" , device.address)
369+ }
370+ sendEvent(BleDidcommEvent .OnConnectedCentral , params)
371+ }
372+
373+ // Triggered when the peripheral is ready to send again
336374 override fun onNotificationSent (device : BluetoothDevice ? , status : Int ) {
337375 super .onNotificationSent(device, status)
338376 if (status == BluetoothGatt .GATT_SUCCESS ) {
339377 peripheralManager?.isConnectedClientReady = true
340378 }
341379 }
342380
381+ // TODO: can we do this without this function?
343382 @SuppressLint(" MissingPermission" )
344383 override fun onExecuteWrite (device : BluetoothDevice ? , requestId : Int , execute : Boolean ) {
345384 super .onExecuteWrite(device, requestId, execute)
@@ -348,46 +387,25 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
348387 requestId,
349388 BluetoothGatt .GATT_SUCCESS ,
350389 0 ,
351- null
390+ null ,
352391 )
353392 }
354393
394+ // Triggered when the connection state is updated for the peripheral
355395 @SuppressLint(" MissingPermission" )
356396 override fun onConnectionStateChange (device : BluetoothDevice , status : Int , newState : Int ) {
357397 super .onConnectionStateChange(device, status, newState)
358- val params = Arguments .createMap().apply {
359- putString(" identifier" , device.address)
360- }
361398 if (newState == BluetoothProfile .STATE_CONNECTED ) {
362399 peripheralManager?.connectedClient = device
363- peripheralManager?.gattClientCallback = GattClientMtuOnlyCallback ()
364- device.connectGatt(context, false , peripheralManager?.gattClientCallback)
365- sendEvent(BleDidcommEvent .OnConnectedCentral , params)
366400 } else if (newState == BluetoothProfile .STATE_DISCONNECTED ) {
367- sendEvent(BleDidcommEvent .OnDisconnectedCentral , params)
368401 peripheralManager?.connectedClient = null
402+ val params = Arguments .createMap().apply {
403+ putString(" identifier" , device.address)
404+ }
405+ sendEvent(BleDidcommEvent .OnDisconnectedCentral , params)
369406 }
370407 }
371408 }
372409
373- private inner class GattClientMtuOnlyCallback : BluetoothGattCallback () {
374- @SuppressLint(" MissingPermission" )
375- override fun onConnectionStateChange (gatt : BluetoothGatt , status : Int , newState : Int ) {
376- super .onConnectionStateChange(gatt, status, newState)
377- if (newState == BluetoothProfile .STATE_CONNECTED ) {
378- gatt.requestMtu(512 )
379- }
380- }
381-
382- override fun onMtuChanged (gatt : BluetoothGatt ? , mtu : Int , status : Int ) {
383- super .onMtuChanged(gatt, mtu, status)
384- if (status != BluetoothGatt .GATT_SUCCESS ) {
385- Log .e(Constants .TAG , " error occurred while requesting the MTU. Status: $status " )
386- return
387- }
388- peripheralManager?.connectedMtu = mtu
389- }
390- }
391-
392- private inner class DeviceAdvertiseCallback : AdvertiseCallback ()
410+ private val deviceAdvertiseCallback = object : AdvertiseCallback () {}
393411}
0 commit comments