diff --git a/src/android/BluetoothLePlugin.java b/src/android/BluetoothLePlugin.java index 9d7d3f1..e4a535d 100644 --- a/src/android/BluetoothLePlugin.java +++ b/src/android/BluetoothLePlugin.java @@ -89,9 +89,6 @@ public class BluetoothLePlugin extends CordovaPlugin { //Quick Writes private LinkedList queueQuick = new LinkedList(); - //Queueing - private LinkedList queue = new LinkedList(); - //Object keys private final String keyStatus = "status"; private final String keyError = "error"; @@ -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"; @@ -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)) { @@ -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)); @@ -1497,6 +1493,10 @@ private void connectAction(JSONArray args, CallbackContext callbackContext) { } connection.put(keyPeripheral, bluetoothGatt); + + LinkedList queue = new LinkedList(); + + connection.put(keyQueue, queue); } private void reconnectAction(JSONArray args, CallbackContext callbackContext) { @@ -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) { @@ -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)) { @@ -1783,8 +1774,6 @@ private boolean readAction(Operation operation) { return false; } - operation.device = device; - return true; } @@ -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)) { @@ -1891,8 +1877,6 @@ private boolean subscribeAction(Operation operation) { return false; } - operation.device = device; - return true; } @@ -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)) { @@ -1984,8 +1965,6 @@ private boolean unsubscribeAction(Operation operation) { return false; } - operation.device = device; - return true; } @@ -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)) { @@ -2073,8 +2049,6 @@ private boolean writeAction(Operation operation) { return false; } - operation.device = device; - return true; } @@ -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)) { @@ -2292,8 +2263,6 @@ private boolean readDescriptorAction(Operation operation) { return false; } - operation.device = device; - return true; } @@ -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)) { @@ -2394,8 +2360,6 @@ private boolean writeDescriptorAction(Operation operation) { return false; } - operation.device = device; - return true; } @@ -3202,7 +3166,31 @@ 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 connection = connections.get(address); + + if (connection != null) { + LinkedList queue = (LinkedList) connection.get(keyQueue); + queue.add(operation); + queueStart(connection); + } + } + + private void queueStart(HashMap connection) { + LinkedList queue = (LinkedList) 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 @@ -3210,10 +3198,11 @@ private void queueStart() { } //Added to queue and immediately ready for processing - queueNext(); + queueNext(connection); } - private void queueNext() { + private void queueNext(HashMap connection) { + LinkedList queue = (LinkedList) connection.get(keyQueue); //Start to process the next command Operation operation = queue.peek(); //If the operation was unsuccessful, remove immediately and start next @@ -3232,11 +3221,12 @@ private void queueNext() { result = unsubscribeAction(operation); } if (!result) { - queueRemove(); + queueRemove(connection); } } - private void queueRemove() { + private void queueRemove(HashMap connection) { + LinkedList queue = (LinkedList) connection.get(keyQueue); //Ensure the queue has something in it, this should never be empty if (queue.size() == 0) { return; @@ -3250,7 +3240,7 @@ private void queueRemove() { } //Start the next item - queueNext(); + queueNext(connection); } private HashMap EnsureCallback(UUID characteristicUuid, HashMap connection) { @@ -4013,19 +4003,20 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState BluetoothDevice device = gatt.getDevice(); String address = device.getAddress(); + HashMap connection = connections.get(address); + if (connection == null) { + return; + } + //Check for queued operations in progress on this device if (newState == BluetoothProfile.STATE_DISCONNECTED) { + LinkedList queue = (LinkedList) 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 connection = connections.get(address); - if (connection == null) { - return; - } - CallbackContext callbackContext = (CallbackContext) connection.get(operationConnect); JSONObject returnObj = new JSONObject(); @@ -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(); @@ -4155,6 +4144,8 @@ public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic return; } + queueRemove(connection); + UUID characteristicUuid = characteristic.getUuid(); CallbackContext callbackContext = GetCallback(characteristicUuid, connection, operationRead); @@ -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(); @@ -4230,6 +4219,8 @@ public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristi return; } + queueRemove(connection); + UUID characteristicUuid = characteristic.getUuid(); CallbackContext callbackContext = GetCallback(characteristicUuid, connection, operationWrite); @@ -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(); @@ -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(); @@ -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(); @@ -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(); diff --git a/src/android/Operation.java b/src/android/Operation.java index 1fdeceb..6be710f 100644 --- a/src/android/Operation.java +++ b/src/android/Operation.java @@ -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;