Skip to content

Commit

Permalink
backport #1297
Browse files Browse the repository at this point in the history
Backport #1297 for v11
  • Loading branch information
Ville Hakulinen committed Jan 21, 2025
1 parent 92e05c5 commit 76a460b
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 67 deletions.
2 changes: 2 additions & 0 deletions android/src/main/java/it/innove/BleManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ private void disconnectPeripherals() {
if (peripheral.isConnected()) {
peripheral.disconnect(null, true);
}
peripheral.errorAndClearAllCallbacks("disconnected by BleManager");
peripheral.resetQueuesAndBuffers();
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions android/src/main/java/it/innove/DefaultScanManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
Expand Down Expand Up @@ -45,7 +47,9 @@ public void stopScan(Callback callback) {
// update scanSessionId to prevent stopping next scan by running timeout thread
scanSessionId.incrementAndGet();

getBluetoothAdapter().getBluetoothLeScanner().stopScan(mScanCallback);
final BluetoothLeScanner scanner = getBluetoothAdapter().getBluetoothLeScanner();
if (scanner != null)
scanner.stopScan(mScanCallback);
isScanning = false;
callback.invoke();
}
Expand Down Expand Up @@ -173,7 +177,8 @@ public void run() {
// check current scan session was not stopped
if (scanSessionId.intValue() == currentScanSession) {
if (btAdapter.getState() == BluetoothAdapter.STATE_ON) {
btAdapter.getBluetoothLeScanner().stopScan(mScanCallback);
final BluetoothLeScanner scanner = btAdapter.getBluetoothLeScanner();
if (scanner != null) scanner.stopScan(mScanCallback);
isScanning = false;
}

Expand Down
157 changes: 92 additions & 65 deletions android/src/main/java/it/innove/Peripheral.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes;

import android.content.Context;
import android.os.Build;
import android.os.Handler;
Expand Down Expand Up @@ -156,14 +157,9 @@ public void connect(final Callback callback, Activity activity, ReadableMap opti

public void disconnect(final Callback callback, final boolean force) {
mainHandler.post(() -> {
for (Callback connectCallback : connectCallbacks) {
connectCallback.invoke("Disconnect called before connect callback invoked");
}
connectCallbacks.clear();
errorAndClearAllCallbacks("Disconnect called before the command completed");
resetQueuesAndBuffers();
connected = false;
clearBuffers();
commandQueue.clear();
commandQueueBusy = false;

if (gatt != null) {
try {
Expand Down Expand Up @@ -293,15 +289,83 @@ public BluetoothDevice getDevice() {
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
mainHandler.post(() -> {
for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
WritableMap map = this.asWritableMap(gatt);
retrieveServicesCallback.invoke(null, map);
if (gatt == null) {
for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
retrieveServicesCallback.invoke("Error during service retrieval: gatt is null");
}
}
else if (status == BluetoothGatt.GATT_SUCCESS)
{
for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
WritableMap map = this.asWritableMap(gatt);
retrieveServicesCallback.invoke(null, map);
}
}
else {
for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
retrieveServicesCallback.invoke("Error during service retrieval.");
}
}
retrieveServicesCallbacks.clear();
completedCommand();
});
}

public void errorAndClearAllCallbacks(final String errorMessage) {

for (Callback writeCallback : writeCallbacks) {
writeCallback.invoke(errorMessage);
}
writeCallbacks.clear();

for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
retrieveServicesCallback.invoke(errorMessage);
}
retrieveServicesCallbacks.clear();

for (Callback readRSSICallback : readRSSICallbacks) {
readRSSICallback.invoke(errorMessage);
}
readRSSICallbacks.clear();

for (Callback registerNotifyCallback : registerNotifyCallbacks) {
registerNotifyCallback.invoke(errorMessage);
}
registerNotifyCallbacks.clear();

for (Callback requestMTUCallback : requestMTUCallbacks) {
requestMTUCallback.invoke(errorMessage);
}
requestMTUCallbacks.clear();

for (Callback readCallback : readCallbacks) {
readCallback.invoke(errorMessage);
}
readCallbacks.clear();

for (Callback readDescriptorCallback : readDescriptorCallbacks) {
readDescriptorCallback.invoke(errorMessage);
}
readDescriptorCallbacks.clear();

for (Callback callback : writeDescriptorCallbacks) {
callback.invoke(errorMessage);
}
writeDescriptorCallbacks.clear();

for (Callback connectCallback : connectCallbacks) {
connectCallback.invoke(errorMessage);
}
connectCallbacks.clear();
}

public void resetQueuesAndBuffers() {
writeQueue.clear();
commandQueue.clear();
commandQueueBusy = false;
connected = false;
clearBuffers();
}
@Override
public void onConnectionStateChange(BluetoothGatt gatta, int status, final int newState) {

Expand All @@ -311,7 +375,7 @@ public void onConnectionStateChange(BluetoothGatt gatta, int status, final int n
mainHandler.post(() -> {
gatt = gatta;

if (status != BluetoothGatt.GATT_SUCCESS) {
if (gatt != null && status != BluetoothGatt.GATT_SUCCESS) {
gatt.close();
}

Expand All @@ -329,59 +393,13 @@ public void onConnectionStateChange(BluetoothGatt gatta, int status, final int n

} else if (newState == BluetoothProfile.STATE_DISCONNECTED || status != BluetoothGatt.GATT_SUCCESS) {

for (Callback writeCallback : writeCallbacks) {
writeCallback.invoke("Device disconnected");
}
writeCallbacks.clear();

for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
retrieveServicesCallback.invoke("Device disconnected");
}
retrieveServicesCallbacks.clear();

for (Callback readRSSICallback : readRSSICallbacks) {
readRSSICallback.invoke("Device disconnected");
}
readRSSICallbacks.clear();

for (Callback registerNotifyCallback : registerNotifyCallbacks) {
registerNotifyCallback.invoke("Device disconnected");
}
registerNotifyCallbacks.clear();

for (Callback requestMTUCallback : requestMTUCallbacks) {
requestMTUCallback.invoke("Device disconnected");
}
requestMTUCallbacks.clear();

for (Callback readCallback : readCallbacks) {
readCallback.invoke("Device disconnected");
}
readCallbacks.clear();

for (Callback readDescriptorCallback : readDescriptorCallbacks) {
readDescriptorCallback.invoke("Device disconnected");
}
readDescriptorCallbacks.clear();

for (Callback callback : writeDescriptorCallbacks) {
callback.invoke("Device disconnected");
}
writeDescriptorCallbacks.clear();

for (Callback connectCallback : connectCallbacks) {
connectCallback.invoke("Connection error");
errorAndClearAllCallbacks("Device disconnected");
resetQueuesAndBuffers();
if (gatt != null) {
gatt.disconnect();
gatt.close();
}
connectCallbacks.clear();

writeQueue.clear();
commandQueue.clear();
commandQueueBusy = false;
connected = false;
clearBuffers();

gatt.disconnect();
gatt.close();
gatt = null;
sendConnectionEvent(device, "BleManagerDisconnectPeripheral", BluetoothGatt.GATT_SUCCESS);

Expand Down Expand Up @@ -888,7 +906,9 @@ private byte[] copyOf(byte[] source) {
}

private boolean enqueue(Runnable command) {

final boolean result = commandQueue.add(command);

if (result) {
nextCommand();
} else {
Expand Down Expand Up @@ -918,9 +938,9 @@ private void nextCommand() {

// Check if we still have a valid gatt object
if (gatt == null) {
Log.d(BleManager.LOG_TAG, "Error, gatt is null");
commandQueue.clear();
commandQueueBusy = false;
Log.d(BleManager.LOG_TAG, "Error, gatt is null. Fill all callbacks with an error");
errorAndClearAllCallbacks("Gatt is null");
resetQueuesAndBuffers();
return;
}

Expand Down Expand Up @@ -968,6 +988,10 @@ public void readRSSI(final Callback callback) {
public void refreshCache(Callback callback) {
enqueue(() -> {
try {
if (gatt == null) {
throw new Exception("gatt is null");
}

Method localMethod = gatt.getClass().getMethod("refresh", new Class[0]);
boolean res = (Boolean) localMethod.invoke(gatt, new Object[0]);
callback.invoke(null, res);
Expand Down Expand Up @@ -1215,6 +1239,9 @@ private BluetoothGattCharacteristic findWritableCharacteristic(BluetoothGattServ
writeProperty = BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE;
}

if (service == null) {
throw new Exception("Service is null.");
}
List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
for (BluetoothGattCharacteristic characteristic : characteristics) {
if ((characteristic.getProperties() & writeProperty) != 0
Expand Down

0 comments on commit 76a460b

Please sign in to comment.