Skip to content

Commit

Permalink
Merge pull request #694 from VinardoZzZ2000/feat/per-device-queues
Browse files Browse the repository at this point in the history
Android: Per-peripheral operation queueing
  • Loading branch information
randdusing authored Jun 22, 2021
2 parents 4cc8b7d + 103a7f7 commit cf89748
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 75 deletions.
139 changes: 65 additions & 74 deletions src/android/BluetoothLePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ public class BluetoothLePlugin extends CordovaPlugin {
//Quick Writes
private LinkedList<byte[]> queueQuick = new LinkedList<byte[]>();

//Queueing
private LinkedList<Operation> queue = new LinkedList<Operation>();

//Object keys
private final String keyStatus = "status";
private final String keyError = "error";
Expand Down Expand Up @@ -130,6 +127,7 @@ public class BluetoothLePlugin extends CordovaPlugin {
private final String keyConnectionPriority = "connectionPriority";
private final String keyMtu = "mtu";
private final String keyPin = "pin";
private final String keyQueue = "queue";

//Write Types
private final String writeTypeNoResponse = "noResponse";
Expand Down Expand Up @@ -353,30 +351,24 @@ public boolean execute(String action, final JSONArray args, final CallbackContex
discoverAction(args, callbackContext);
} else if ("read".equals(action)) {
Operation operation = new Operation("read", args, callbackContext);
queue.add(operation);
queueStart();
queueAdd(operation);
} else if ("subscribe".equals(action)) {
Operation operation = new Operation("subscribe", args, callbackContext);
queue.add(operation);
queueStart();
queueAdd(operation);
} else if ("unsubscribe".equals(action)) {
Operation operation = new Operation("unsubscribe", args, callbackContext);
queue.add(operation);
queueStart();
queueAdd(operation);
} else if ("write".equals(action)) {
Operation operation = new Operation("write", args, callbackContext);
queue.add(operation);
queueStart();
queueAdd(operation);
} else if ("writeQ".equals(action)) {
writeQAction(args, callbackContext);
} else if ("readDescriptor".equals(action)) {
Operation operation = new Operation("readDescriptor", args, callbackContext);
queue.add(operation);
queueStart();
queueAdd(operation);
} else if ("writeDescriptor".equals(action)) {
Operation operation = new Operation("writeDescriptor", args, callbackContext);
queue.add(operation);
queueStart();
queueAdd(operation);
} else if ("rssi".equals(action)) {
rssiAction(args, callbackContext);
} else if ("isInitialized".equals(action)) {
Expand Down Expand Up @@ -747,10 +739,14 @@ private void startAdvertisingAction(JSONArray args, CallbackContext callbackCont
dataBuilder.addManufacturerData(manufacturerId, manufacturerSpecificData);
}

//dataBuilder.addServiceData();
UUID uuid = getUUID(obj.optString("service", null));
if (uuid != null) {
dataBuilder.addServiceUuid(new ParcelUuid(uuid));
byte[] serviceData = getPropertyBytes(obj, "serviceData");
if (serviceData != null) {
dataBuilder.addServiceData(new ParcelUuid(uuid), serviceData);
} else {
dataBuilder.addServiceUuid(new ParcelUuid(uuid));
}
}

dataBuilder.setIncludeDeviceName(obj.optBoolean("includeDeviceName", true));
Expand Down Expand Up @@ -1497,6 +1493,10 @@ private void connectAction(JSONArray args, CallbackContext callbackContext) {
}

connection.put(keyPeripheral, bluetoothGatt);

LinkedList<Operation> queue = new LinkedList<Operation>();

connection.put(keyQueue, queue);
}

private void reconnectAction(JSONArray args, CallbackContext callbackContext) {
Expand Down Expand Up @@ -1637,12 +1637,6 @@ private void closeAction(JSONArray args, CallbackContext callbackContext) {
connections.remove(device.getAddress());

callbackContext.success(returnObj);

//Check for queued operations in progress on this device
Operation operation = queue.peek();
if (operation != null && operation.device != null && operation.device.getAddress().equals(address)) {
queueRemove();
}
}

private void discoverAction(JSONArray args, CallbackContext callbackContext) {
Expand Down Expand Up @@ -1727,9 +1721,6 @@ private boolean readAction(Operation operation) {
}

JSONObject obj = getArgsObject(args);
if (isNotArgsObject(obj, callbackContext)) {
return false;
}

String address = getAddress(obj);
if (isNotAddress(address, callbackContext)) {
Expand Down Expand Up @@ -1783,8 +1774,6 @@ private boolean readAction(Operation operation) {
return false;
}

operation.device = device;

return true;
}

Expand All @@ -1797,9 +1786,6 @@ private boolean subscribeAction(Operation operation) {
}

JSONObject obj = getArgsObject(args);
if (isNotArgsObject(obj, callbackContext)) {
return false;
}

String address = getAddress(obj);
if (isNotAddress(address, callbackContext)) {
Expand Down Expand Up @@ -1891,8 +1877,6 @@ private boolean subscribeAction(Operation operation) {
return false;
}

operation.device = device;

return true;
}

Expand All @@ -1905,9 +1889,6 @@ private boolean unsubscribeAction(Operation operation) {
}

JSONObject obj = getArgsObject(args);
if (isNotArgsObject(obj, callbackContext)) {
return false;
}

String address = getAddress(obj);
if (isNotAddress(address, callbackContext)) {
Expand Down Expand Up @@ -1984,8 +1965,6 @@ private boolean unsubscribeAction(Operation operation) {
return false;
}

operation.device = device;

return true;
}

Expand All @@ -1998,9 +1977,6 @@ private boolean writeAction(Operation operation) {
}

JSONObject obj = getArgsObject(args);
if (isNotArgsObject(obj, callbackContext)) {
return false;
}

String address = getAddress(obj);
if (isNotAddress(address, callbackContext)) {
Expand Down Expand Up @@ -2073,8 +2049,6 @@ private boolean writeAction(Operation operation) {
return false;
}

operation.device = device;

return true;
}

Expand Down Expand Up @@ -2229,9 +2203,6 @@ private boolean readDescriptorAction(Operation operation) {
}

JSONObject obj = getArgsObject(args);
if (isNotArgsObject(obj, callbackContext)) {
return false;
}

String address = getAddress(obj);
if (isNotAddress(address, callbackContext)) {
Expand Down Expand Up @@ -2292,8 +2263,6 @@ private boolean readDescriptorAction(Operation operation) {
return false;
}

operation.device = device;

return true;
}

Expand All @@ -2306,9 +2275,6 @@ private boolean writeDescriptorAction(Operation operation) {
}

JSONObject obj = getArgsObject(args);
if (isNotArgsObject(obj, callbackContext)) {
return false;
}

String address = getAddress(obj);
if (isNotAddress(address, callbackContext)) {
Expand Down Expand Up @@ -2394,8 +2360,6 @@ private boolean writeDescriptorAction(Operation operation) {
return false;
}

operation.device = device;

return true;
}

Expand Down Expand Up @@ -3202,18 +3166,43 @@ private BluetoothGattDescriptor getDescriptor(JSONObject obj, BluetoothGattChara
}

//Helpers for Callbacks
private void queueStart() {
private void queueAdd(Operation operation) {
JSONArray args = operation.args;
CallbackContext callbackContext = operation.callbackContext;

JSONObject obj = getArgsObject(args);
if (isNotArgsObject(obj, callbackContext)) {
return;
}

String address = getAddress(obj);
if (isNotAddress(address, callbackContext)) {
return;
}

HashMap<Object, Object> connection = connections.get(address);

if (connection != null) {
LinkedList<Operation> queue = (LinkedList<Operation>) connection.get(keyQueue);
queue.add(operation);
queueStart(connection);
}
}

private void queueStart(HashMap<Object, Object> connection) {
LinkedList<Operation> queue = (LinkedList<Operation>) connection.get(keyQueue);
//Attempt to start the queue whenever a new operation is added
if (queue.size() > 1) {
//There was already something in the queue so wait for queueNext to be called
return;
}

//Added to queue and immediately ready for processing
queueNext();
queueNext(connection);
}

private void queueNext() {
private void queueNext(HashMap<Object, Object> connection) {
LinkedList<Operation> queue = (LinkedList<Operation>) connection.get(keyQueue);
//Start to process the next command
Operation operation = queue.peek();
//If the operation was unsuccessful, remove immediately and start next
Expand All @@ -3232,11 +3221,12 @@ private void queueNext() {
result = unsubscribeAction(operation);
}
if (!result) {
queueRemove();
queueRemove(connection);
}
}

private void queueRemove() {
private void queueRemove(HashMap<Object, Object> connection) {
LinkedList<Operation> queue = (LinkedList<Operation>) connection.get(keyQueue);
//Ensure the queue has something in it, this should never be empty
if (queue.size() == 0) {
return;
Expand All @@ -3250,7 +3240,7 @@ private void queueRemove() {
}

//Start the next item
queueNext();
queueNext(connection);
}

private HashMap<Object, Object> EnsureCallback(UUID characteristicUuid, HashMap<Object, Object> connection) {
Expand Down Expand Up @@ -4013,19 +4003,20 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();

HashMap<Object, Object> connection = connections.get(address);
if (connection == null) {
return;
}

//Check for queued operations in progress on this device
if (newState == BluetoothProfile.STATE_DISCONNECTED) {
LinkedList<Operation> queue = (LinkedList<Operation>) connection.get(keyQueue);
Operation operation = queue.peek();
if (operation != null && operation.device != null && operation.device.getAddress().equals(address)) {
queueRemove();
if (operation != null) {
queueRemove(connection);
}
}

HashMap<Object, Object> connection = connections.get(address);
if (connection == null) {
return;
}

CallbackContext callbackContext = (CallbackContext) connection.get(operationConnect);

JSONObject returnObj = new JSONObject();
Expand Down Expand Up @@ -4144,8 +4135,6 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) {

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
queueRemove();

//Get the connected device
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();
Expand All @@ -4155,6 +4144,8 @@ public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic
return;
}

queueRemove(connection);

UUID characteristicUuid = characteristic.getUuid();

CallbackContext callbackContext = GetCallback(characteristicUuid, connection, operationRead);
Expand Down Expand Up @@ -4219,8 +4210,6 @@ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteris

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
queueRemove();

//Get the connected device
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();
Expand All @@ -4230,6 +4219,8 @@ public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristi
return;
}

queueRemove(connection);

UUID characteristicUuid = characteristic.getUuid();

CallbackContext callbackContext = GetCallback(characteristicUuid, connection, operationWrite);
Expand Down Expand Up @@ -4288,8 +4279,6 @@ public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristi

@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
queueRemove();

//Get the connected device
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();
Expand All @@ -4299,6 +4288,8 @@ public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descrip
return;
}

queueRemove(connection);

BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
UUID characteristicUuid = characteristic.getUuid();
UUID descriptorUuid = descriptor.getUuid();
Expand Down Expand Up @@ -4332,8 +4323,6 @@ public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descrip

@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
queueRemove();

//Get the connected device
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();
Expand All @@ -4343,6 +4332,8 @@ public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descri
return;
}

queueRemove(connection);

BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
UUID characteristicUuid = characteristic.getUuid();
UUID descriptorUuid = descriptor.getUuid();
Expand Down
1 change: 0 additions & 1 deletion src/android/Operation.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public class Operation {
public String type;
public JSONArray args;
public CallbackContext callbackContext;
public BluetoothDevice device;

public Operation(String type, JSONArray args, CallbackContext callbackContext) {
this.type = type;
Expand Down

0 comments on commit cf89748

Please sign in to comment.