1212import android .bluetooth .BluetoothGattService ;
1313import android .bluetooth .BluetoothProfile ;
1414import android .bluetooth .BluetoothStatusCodes ;
15+
1516import android .content .Context ;
1617import android .os .Build ;
1718import android .os .Handler ;
@@ -156,14 +157,9 @@ public void connect(final Callback callback, Activity activity, ReadableMap opti
156157
157158 public void disconnect (final Callback callback , final boolean force ) {
158159 mainHandler .post (() -> {
159- for (Callback connectCallback : connectCallbacks ) {
160- connectCallback .invoke ("Disconnect called before connect callback invoked" );
161- }
162- connectCallbacks .clear ();
160+ errorAndClearAllCallbacks ("Disconnect called before the command completed" );
161+ resetQueuesAndBuffers ();
163162 connected = false ;
164- clearBuffers ();
165- commandQueue .clear ();
166- commandQueueBusy = false ;
167163
168164 if (gatt != null ) {
169165 try {
@@ -293,15 +289,83 @@ public BluetoothDevice getDevice() {
293289 public void onServicesDiscovered (BluetoothGatt gatt , int status ) {
294290 super .onServicesDiscovered (gatt , status );
295291 mainHandler .post (() -> {
296- for (Callback retrieveServicesCallback : retrieveServicesCallbacks ) {
297- WritableMap map = this .asWritableMap (gatt );
298- retrieveServicesCallback .invoke (null , map );
292+ if (gatt == null ) {
293+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks ) {
294+ retrieveServicesCallback .invoke ("Error during service retrieval: gatt is null" );
295+ }
296+ }
297+ else if (status == BluetoothGatt .GATT_SUCCESS )
298+ {
299+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks ) {
300+ WritableMap map = this .asWritableMap (gatt );
301+ retrieveServicesCallback .invoke (null , map );
302+ }
303+ }
304+ else {
305+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks ) {
306+ retrieveServicesCallback .invoke ("Error during service retrieval." );
307+ }
299308 }
300309 retrieveServicesCallbacks .clear ();
301310 completedCommand ();
302311 });
303312 }
304313
314+ public void errorAndClearAllCallbacks (final String errorMessage ) {
315+
316+ for (Callback writeCallback : writeCallbacks ) {
317+ writeCallback .invoke (errorMessage );
318+ }
319+ writeCallbacks .clear ();
320+
321+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks ) {
322+ retrieveServicesCallback .invoke (errorMessage );
323+ }
324+ retrieveServicesCallbacks .clear ();
325+
326+ for (Callback readRSSICallback : readRSSICallbacks ) {
327+ readRSSICallback .invoke (errorMessage );
328+ }
329+ readRSSICallbacks .clear ();
330+
331+ for (Callback registerNotifyCallback : registerNotifyCallbacks ) {
332+ registerNotifyCallback .invoke (errorMessage );
333+ }
334+ registerNotifyCallbacks .clear ();
335+
336+ for (Callback requestMTUCallback : requestMTUCallbacks ) {
337+ requestMTUCallback .invoke (errorMessage );
338+ }
339+ requestMTUCallbacks .clear ();
340+
341+ for (Callback readCallback : readCallbacks ) {
342+ readCallback .invoke (errorMessage );
343+ }
344+ readCallbacks .clear ();
345+
346+ for (Callback readDescriptorCallback : readDescriptorCallbacks ) {
347+ readDescriptorCallback .invoke (errorMessage );
348+ }
349+ readDescriptorCallbacks .clear ();
350+
351+ for (Callback callback : writeDescriptorCallbacks ) {
352+ callback .invoke (errorMessage );
353+ }
354+ writeDescriptorCallbacks .clear ();
355+
356+ for (Callback connectCallback : connectCallbacks ) {
357+ connectCallback .invoke (errorMessage );
358+ }
359+ connectCallbacks .clear ();
360+ }
361+
362+ public void resetQueuesAndBuffers () {
363+ writeQueue .clear ();
364+ commandQueue .clear ();
365+ commandQueueBusy = false ;
366+ connected = false ;
367+ clearBuffers ();
368+ }
305369 @ Override
306370 public void onConnectionStateChange (BluetoothGatt gatta , int status , final int newState ) {
307371
@@ -311,7 +375,7 @@ public void onConnectionStateChange(BluetoothGatt gatta, int status, final int n
311375 mainHandler .post (() -> {
312376 gatt = gatta ;
313377
314- if (status != BluetoothGatt .GATT_SUCCESS ) {
378+ if (gatt != null && status != BluetoothGatt .GATT_SUCCESS ) {
315379 gatt .close ();
316380 }
317381
@@ -329,59 +393,13 @@ public void onConnectionStateChange(BluetoothGatt gatta, int status, final int n
329393
330394 } else if (newState == BluetoothProfile .STATE_DISCONNECTED || status != BluetoothGatt .GATT_SUCCESS ) {
331395
332- for (Callback writeCallback : writeCallbacks ) {
333- writeCallback .invoke ("Device disconnected" );
334- }
335- writeCallbacks .clear ();
336-
337- for (Callback retrieveServicesCallback : retrieveServicesCallbacks ) {
338- retrieveServicesCallback .invoke ("Device disconnected" );
339- }
340- retrieveServicesCallbacks .clear ();
341-
342- for (Callback readRSSICallback : readRSSICallbacks ) {
343- readRSSICallback .invoke ("Device disconnected" );
344- }
345- readRSSICallbacks .clear ();
346-
347- for (Callback registerNotifyCallback : registerNotifyCallbacks ) {
348- registerNotifyCallback .invoke ("Device disconnected" );
349- }
350- registerNotifyCallbacks .clear ();
351-
352- for (Callback requestMTUCallback : requestMTUCallbacks ) {
353- requestMTUCallback .invoke ("Device disconnected" );
354- }
355- requestMTUCallbacks .clear ();
356-
357- for (Callback readCallback : readCallbacks ) {
358- readCallback .invoke ("Device disconnected" );
359- }
360- readCallbacks .clear ();
361-
362- for (Callback readDescriptorCallback : readDescriptorCallbacks ) {
363- readDescriptorCallback .invoke ("Device disconnected" );
364- }
365- readDescriptorCallbacks .clear ();
366-
367- for (Callback callback : writeDescriptorCallbacks ) {
368- callback .invoke ("Device disconnected" );
369- }
370- writeDescriptorCallbacks .clear ();
371-
372- for (Callback connectCallback : connectCallbacks ) {
373- connectCallback .invoke ("Connection error" );
396+ errorAndClearAllCallbacks ("Device disconnected" );
397+ resetQueuesAndBuffers ();
398+ if (gatt != null ) {
399+ gatt .disconnect ();
400+ gatt .close ();
374401 }
375- connectCallbacks .clear ();
376402
377- writeQueue .clear ();
378- commandQueue .clear ();
379- commandQueueBusy = false ;
380- connected = false ;
381- clearBuffers ();
382-
383- gatt .disconnect ();
384- gatt .close ();
385403 gatt = null ;
386404 sendConnectionEvent (device , "BleManagerDisconnectPeripheral" , BluetoothGatt .GATT_SUCCESS );
387405
@@ -888,7 +906,9 @@ private byte[] copyOf(byte[] source) {
888906 }
889907
890908 private boolean enqueue (Runnable command ) {
909+
891910 final boolean result = commandQueue .add (command );
911+
892912 if (result ) {
893913 nextCommand ();
894914 } else {
@@ -918,9 +938,9 @@ private void nextCommand() {
918938
919939 // Check if we still have a valid gatt object
920940 if (gatt == null ) {
921- Log .d (BleManager .LOG_TAG , "Error, gatt is null" );
922- commandQueue . clear ( );
923- commandQueueBusy = false ;
941+ Log .d (BleManager .LOG_TAG , "Error, gatt is null. Fill all callbacks with an error " );
942+ errorAndClearAllCallbacks ( "Gatt is null" );
943+ resetQueuesAndBuffers () ;
924944 return ;
925945 }
926946
@@ -968,6 +988,10 @@ public void readRSSI(final Callback callback) {
968988 public void refreshCache (Callback callback ) {
969989 enqueue (() -> {
970990 try {
991+ if (gatt == null ) {
992+ throw new Exception ("gatt is null" );
993+ }
994+
971995 Method localMethod = gatt .getClass ().getMethod ("refresh" , new Class [0 ]);
972996 boolean res = (Boolean ) localMethod .invoke (gatt , new Object [0 ]);
973997 callback .invoke (null , res );
@@ -1215,6 +1239,9 @@ private BluetoothGattCharacteristic findWritableCharacteristic(BluetoothGattServ
12151239 writeProperty = BluetoothGattCharacteristic .PROPERTY_WRITE_NO_RESPONSE ;
12161240 }
12171241
1242+ if (service == null ) {
1243+ throw new Exception ("Service is null." );
1244+ }
12181245 List <BluetoothGattCharacteristic > characteristics = service .getCharacteristics ();
12191246 for (BluetoothGattCharacteristic characteristic : characteristics ) {
12201247 if ((characteristic .getProperties () & writeProperty ) != 0
0 commit comments