Skip to content

Commit 76a460b

Browse files
committed
backport #1297
Backport #1297 for v11
1 parent 92e05c5 commit 76a460b

File tree

3 files changed

+101
-67
lines changed

3 files changed

+101
-67
lines changed

android/src/main/java/it/innove/BleManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,8 @@ private void disconnectPeripherals() {
720720
if (peripheral.isConnected()) {
721721
peripheral.disconnect(null, true);
722722
}
723+
peripheral.errorAndClearAllCallbacks("disconnected by BleManager");
724+
peripheral.resetQueuesAndBuffers();
723725
}
724726
}
725727
}

android/src/main/java/it/innove/DefaultScanManager.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import android.annotation.SuppressLint;
88
import android.bluetooth.BluetoothAdapter;
99
import android.bluetooth.BluetoothDevice;
10+
import android.bluetooth.BluetoothDevice;
11+
import android.bluetooth.le.BluetoothLeScanner;
1012
import android.bluetooth.le.ScanCallback;
1113
import android.bluetooth.le.ScanFilter;
1214
import android.bluetooth.le.ScanRecord;
@@ -45,7 +47,9 @@ public void stopScan(Callback callback) {
4547
// update scanSessionId to prevent stopping next scan by running timeout thread
4648
scanSessionId.incrementAndGet();
4749

48-
getBluetoothAdapter().getBluetoothLeScanner().stopScan(mScanCallback);
50+
final BluetoothLeScanner scanner = getBluetoothAdapter().getBluetoothLeScanner();
51+
if (scanner != null)
52+
scanner.stopScan(mScanCallback);
4953
isScanning = false;
5054
callback.invoke();
5155
}
@@ -173,7 +177,8 @@ public void run() {
173177
// check current scan session was not stopped
174178
if (scanSessionId.intValue() == currentScanSession) {
175179
if (btAdapter.getState() == BluetoothAdapter.STATE_ON) {
176-
btAdapter.getBluetoothLeScanner().stopScan(mScanCallback);
180+
final BluetoothLeScanner scanner = btAdapter.getBluetoothLeScanner();
181+
if (scanner != null) scanner.stopScan(mScanCallback);
177182
isScanning = false;
178183
}
179184

android/src/main/java/it/innove/Peripheral.java

Lines changed: 92 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import android.bluetooth.BluetoothGattService;
1313
import android.bluetooth.BluetoothProfile;
1414
import android.bluetooth.BluetoothStatusCodes;
15+
1516
import android.content.Context;
1617
import android.os.Build;
1718
import 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

Comments
 (0)