11package com.reactnativebledidcomm
22
3- import android.annotation.SuppressLint
4- import android.bluetooth.*
5- import android.bluetooth.le.AdvertiseCallback
6- import android.bluetooth.le.ScanCallback
7- import android.bluetooth.le.ScanResult
8- import android.util.Log
93import androidx.annotation.RequiresPermission
104import com.facebook.react.bridge.*
11- import com.facebook.react.modules.core.DeviceEventManagerModule
125import com.reactnativebledidcomm.central.CentralManager
136import com.reactnativebledidcomm.central.CentralManagerException
147import com.reactnativebledidcomm.peripheral.PeripheralManager
158import com.reactnativebledidcomm.peripheral.PeripheralManagerException
16- import java.util.*
9+ import java.util.UUID
1710
1811class BleDidcommModule (private val context : ReactApplicationContext ) :
1912 ReactContextBaseJavaModule (context) {
@@ -44,7 +37,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
4437 promise : Promise ,
4538 ) {
4639 try {
47- this .peripheralManager = PeripheralManager (context, gattServerCallback )
40+ this .peripheralManager = PeripheralManager (context)
4841 promise.resolve(null )
4942 } catch (e: Exception ) {
5043 promise.reject(" error" , e)
@@ -127,7 +120,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
127120 try {
128121 val centralManager =
129122 this .centralManager ? : throw CentralManagerException .NotStarted ()
130- centralManager.scan(bluetoothScanCallback )
123+ centralManager.scan()
131124 promise.resolve(null )
132125 } catch (e: Exception ) {
133126 promise.reject(" error" , e)
@@ -140,7 +133,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
140133 try {
141134 val peripheralManager =
142135 this .peripheralManager ? : throw PeripheralManagerException .NotStarted ()
143- peripheralManager.advertise(deviceAdvertiseCallback )
136+ peripheralManager.advertise()
144137 promise.resolve(null )
145138 } catch (e: Exception ) {
146139 promise.reject(" error" , e)
@@ -153,7 +146,7 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
153146 try {
154147 val centralManager =
155148 this .centralManager ? : throw CentralManagerException .NotStarted ()
156- centralManager.connect(peripheralId, gattClientCallback )
149+ centralManager.connect(peripheralId)
157150 promise.resolve(null )
158151 } catch (e: Exception ) {
159152 promise.reject(" error" , e)
@@ -193,219 +186,4 @@ class BleDidcommModule(private val context: ReactApplicationContext) :
193186 @ReactMethod
194187 fun removeListeners (@Suppress(" UNUSED_PARAMETER" ) count : Int ) {
195188 }
196-
197- private fun sendEvent (event : BleDidcommEvent , params : WritableMap ? ) {
198- this .context
199- .getJSModule(DeviceEventManagerModule .RCTDeviceEventEmitter ::class .java)
200- .emit(event.token, params)
201- }
202-
203- private val gattClientCallback = object : BluetoothGattCallback () {
204- var message: ByteArray = byteArrayOf()
205-
206- // Triggered when client receives an indication
207- override fun onCharacteristicChanged (
208- gatt : BluetoothGatt ,
209- characteristic : BluetoothGattCharacteristic ,
210- ) {
211- super .onCharacteristicChanged(gatt, characteristic)
212- val msg = characteristic.value
213- if (msg.toString(Charsets .UTF_8 ) == " EOM" ) {
214- val params = Arguments .createMap().apply {
215- putString(" message" , message.toString(Charsets .UTF_8 ))
216- }
217- sendEvent(BleDidcommEvent .OnReceivedNotification , params)
218- message = byteArrayOf()
219- } else {
220- message + = msg
221- }
222- }
223-
224- // Triggered when the client is ready to send the next message
225- override fun onCharacteristicWrite (
226- gatt : BluetoothGatt ,
227- characteristic : BluetoothGattCharacteristic ,
228- status : Int ,
229- ) {
230- super .onCharacteristicWrite(gatt, characteristic, status)
231- if (status == BluetoothGatt .GATT_SUCCESS ) {
232- centralManager?.isPeripheralReady = true
233- }
234- }
235-
236- // Triggered when the MTU has been changed.
237- @SuppressLint(" MissingPermission" )
238- override fun onMtuChanged (gatt : BluetoothGatt , mtu : Int , status : Int ) {
239- super .onMtuChanged(gatt, mtu, status)
240- if (status != BluetoothGatt .GATT_SUCCESS ) {
241- Log .e(Constants .TAG , " error occurred while requesting MTU. Status $status " )
242- return
243- }
244- centralManager?.connectedMtu = mtu
245- gatt.discoverServices()
246- }
247-
248- // Triggered when client discovered services
249- @SuppressLint(" MissingPermission" )
250- override fun onServicesDiscovered (gatt : BluetoothGatt , status : Int ) {
251- super .onServicesDiscovered(gatt, status)
252- val service = gatt.getService(centralManager?.serviceUUID)
253-
254- centralManager?.writeCharacteristic =
255- service.getCharacteristic(centralManager?.writeCharacteristicUUID)
256-
257- centralManager?.indicationCharacteristic =
258- service.getCharacteristic(centralManager?.indicationCharacteristicUUID)
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)
265- }
266-
267- // Triggered when the connection state is updated
268- @SuppressLint(" MissingPermission" )
269- override fun onConnectionStateChange (gatt : BluetoothGatt , status : Int , newState : Int ) {
270- super .onConnectionStateChange(gatt, status, newState)
271- val params = Arguments .createMap().apply {
272- putString(" identifier" , gatt.device.address)
273- }
274- if (newState == BluetoothProfile .STATE_CONNECTED ) {
275- gatt.requestMtu(512 )
276- centralManager?.stopScan()
277- sendEvent(BleDidcommEvent .OnConnectedPeripheral , params)
278- } else if (newState == BluetoothProfile .STATE_DISCONNECTED ) {
279- sendEvent(BleDidcommEvent .OnDisconnectedPeripheral , params)
280- centralManager?.connectedPeripheral = null
281- }
282- }
283- }
284-
285- private val bluetoothScanCallback = object : ScanCallback () {
286- override fun onScanResult (callbackType : Int , result : ScanResult ? ) {
287- super .onScanResult(callbackType, result)
288- val device = result?.device ? : return
289- centralManager?.discoveredPeripherals?.add(device)
290- val params = Arguments .createMap().apply {
291- putString(" identifier" , device.address)
292- }
293- sendEvent(BleDidcommEvent .OnDiscoverPeripheral , params)
294- }
295- }
296-
297- private val gattServerCallback = object : BluetoothGattServerCallback () {
298- var message: ByteArray = byteArrayOf()
299-
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
308- @SuppressLint(" MissingPermission" )
309- override fun onCharacteristicWriteRequest (
310- device : BluetoothDevice ,
311- requestId : Int ,
312- characteristic : BluetoothGattCharacteristic ? ,
313- preparedWrite : Boolean ,
314- responseNeeded : Boolean ,
315- offset : Int ,
316- value : ByteArray ,
317- ) {
318- super .onCharacteristicWriteRequest(
319- device,
320- requestId,
321- characteristic,
322- preparedWrite,
323- responseNeeded,
324- offset,
325- value,
326- )
327-
328- if (" EOM" == value.toString(Charsets .UTF_8 )) {
329- val params = Arguments .createMap().apply {
330- putString(" message" , message.toString(Charsets .UTF_8 ))
331- }
332- sendEvent(BleDidcommEvent .OnReceivedWriteWithoutResponse , params)
333- message = byteArrayOf()
334- } else {
335- message + = value
336- }
337-
338- if (responseNeeded) {
339- peripheralManager?.gattServer?.sendResponse(
340- device,
341- requestId,
342- BluetoothGatt .GATT_SUCCESS ,
343- offset,
344- value,
345- )
346- }
347- }
348-
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
374- override fun onNotificationSent (device : BluetoothDevice ? , status : Int ) {
375- super .onNotificationSent(device, status)
376- if (status == BluetoothGatt .GATT_SUCCESS ) {
377- peripheralManager?.isConnectedClientReady = true
378- }
379- }
380-
381- // TODO: can we do this without this function?
382- @SuppressLint(" MissingPermission" )
383- override fun onExecuteWrite (device : BluetoothDevice ? , requestId : Int , execute : Boolean ) {
384- super .onExecuteWrite(device, requestId, execute)
385- peripheralManager?.gattServer?.sendResponse(
386- device,
387- requestId,
388- BluetoothGatt .GATT_SUCCESS ,
389- 0 ,
390- null ,
391- )
392- }
393-
394- // Triggered when the connection state is updated for the peripheral
395- @SuppressLint(" MissingPermission" )
396- override fun onConnectionStateChange (device : BluetoothDevice , status : Int , newState : Int ) {
397- super .onConnectionStateChange(device, status, newState)
398- if (newState == BluetoothProfile .STATE_CONNECTED ) {
399- peripheralManager?.connectedClient = device
400- } else if (newState == BluetoothProfile .STATE_DISCONNECTED ) {
401- peripheralManager?.connectedClient = null
402- val params = Arguments .createMap().apply {
403- putString(" identifier" , device.address)
404- }
405- sendEvent(BleDidcommEvent .OnDisconnectedCentral , params)
406- }
407- }
408- }
409-
410- private val deviceAdvertiseCallback = object : AdvertiseCallback () {}
411189}
0 commit comments