@@ -89,6 +89,9 @@ public class BluetoothLePlugin extends CordovaPlugin {
89
89
//Quick Writes
90
90
private LinkedList <byte []> queueQuick = new LinkedList <byte []>();
91
91
92
+ //Peripheral queue
93
+ private LinkedList <Operation > peripheralQueue = new LinkedList <Operation >();
94
+
92
95
//Object keys
93
96
private final String keyStatus = "status" ;
94
97
private final String keyError = "error" ;
@@ -127,6 +130,7 @@ public class BluetoothLePlugin extends CordovaPlugin {
127
130
private final String keyConnectionPriority = "connectionPriority" ;
128
131
private final String keyMtu = "mtu" ;
129
132
private final String keyPin = "pin" ;
133
+ private final String keySent = "sent" ;
130
134
private final String keyQueue = "queue" ;
131
135
132
136
//Write Types
@@ -155,6 +159,7 @@ public class BluetoothLePlugin extends CordovaPlugin {
155
159
private final String statusRssi = "rssi" ;
156
160
private final String statusConnectionPriorityRequested = "connectionPriorityRequested" ;
157
161
private final String statusMtu = "mtu" ;
162
+ private final String statusNotified = "notified" ;
158
163
159
164
//Properties
160
165
private final String propertyBroadcast = "broadcast" ;
@@ -212,6 +217,7 @@ public class BluetoothLePlugin extends CordovaPlugin {
212
217
private final String errorRequestConnectionPriority = "requestConnectPriority" ;
213
218
private final String errorMtu = "mtu" ;
214
219
private final String errorRetrievePeripheralsByAddress = "retrievePeripheralsByAddress" ;
220
+ private final String errorNotify = "notify" ;
215
221
216
222
//Error Messages
217
223
//Initialization
@@ -414,7 +420,9 @@ public boolean execute(String action, final JSONArray args, final CallbackContex
414
420
} else if ("respond" .equals (action )) {
415
421
respondAction (args , callbackContext );
416
422
} else if ("notify" .equals (action )) {
417
- notifyAction (args , callbackContext );
423
+ Operation operation = new Operation ("notify" , args , callbackContext );
424
+ peripheralQueue .add (operation );
425
+ peripheralQueueStart ();
418
426
} else if ("setPin" .equals (action )) {
419
427
setPinAction (args , callbackContext );
420
428
} else if ("retrievePeripheralsByAddress" .equals (action )) {
@@ -822,15 +830,18 @@ private void respondAction(JSONArray args, CallbackContext callbackContext) {
822
830
}
823
831
}
824
832
825
- private void notifyAction (JSONArray args , CallbackContext callbackContext ) {
833
+ private boolean notifyAction (Operation operation ) {
834
+ JSONArray args = operation .args ;
835
+ CallbackContext callbackContext = operation .callbackContext ;
836
+
826
837
JSONObject obj = getArgsObject (args );
827
838
if (isNotArgsObject (obj , callbackContext )) {
828
- return ;
839
+ return false ;
829
840
}
830
841
831
842
String address = getAddress (obj );
832
843
if (isNotAddress (address , callbackContext )) {
833
- return ;
844
+ return false ;
834
845
}
835
846
BluetoothDevice device = bluetoothAdapter .getRemoteDevice (address );
836
847
@@ -841,6 +852,7 @@ private void notifyAction(JSONArray args, CallbackContext callbackContext) {
841
852
addProperty (returnObj , "error" , "service" );
842
853
addProperty (returnObj , "message" , "Service not found" );
843
854
callbackContext .error (returnObj );
855
+ return false ;
844
856
}
845
857
846
858
UUID characteristicUuid = getUUID (obj .optString ("characteristic" , null ));
@@ -850,6 +862,7 @@ private void notifyAction(JSONArray args, CallbackContext callbackContext) {
850
862
addProperty (returnObj , "error" , "characteristic" );
851
863
addProperty (returnObj , "message" , "Characteristic not found" );
852
864
callbackContext .error (returnObj );
865
+ return false ;
853
866
}
854
867
855
868
byte [] value = getPropertyBytes (obj , "value" );
@@ -859,6 +872,7 @@ private void notifyAction(JSONArray args, CallbackContext callbackContext) {
859
872
addProperty (returnObj , "error" , "respond" );
860
873
addProperty (returnObj , "message" , "Failed to set value" );
861
874
callbackContext .error (returnObj );
875
+ return false ;
862
876
}
863
877
864
878
BluetoothGattDescriptor descriptor = characteristic .getDescriptor (clientConfigurationDescriptorUuid );
@@ -869,14 +883,16 @@ private void notifyAction(JSONArray args, CallbackContext callbackContext) {
869
883
isIndicate = true ;
870
884
}
871
885
872
- //Wait for onNotificationSent event
873
886
boolean result = gattServer .notifyCharacteristicChanged (device , characteristic , isIndicate );
874
887
if (!result ) {
875
888
JSONObject returnObj = new JSONObject ();
876
889
addProperty (returnObj , "error" , "notify" );
877
890
addProperty (returnObj , "message" , "Failed to notify" );
878
891
callbackContext .error (returnObj );
892
+ return false ;
879
893
}
894
+
895
+ return true ;
880
896
}
881
897
882
898
public void hasPermissionAction (CallbackContext callbackContext ) {
@@ -3243,6 +3259,38 @@ private void queueRemove(HashMap<Object, Object> connection) {
3243
3259
queueNext (connection );
3244
3260
}
3245
3261
3262
+ private void peripheralQueueStart () {
3263
+ if (peripheralQueue .size () > 1 ) {
3264
+ return ;
3265
+ }
3266
+
3267
+ peripheralQueueNext ();
3268
+ }
3269
+
3270
+ private void peripheralQueueNext () {
3271
+ Operation operation = peripheralQueue .peek ();
3272
+
3273
+ boolean result = notifyAction (operation );
3274
+
3275
+ if (!result ) {
3276
+ peripheralQueueRemove ();
3277
+ }
3278
+ }
3279
+
3280
+ private void peripheralQueueRemove () {
3281
+ if (peripheralQueue .size () == 0 ) {
3282
+ return ;
3283
+ }
3284
+
3285
+ peripheralQueue .poll ();
3286
+
3287
+ if (peripheralQueue .size () == 0 ) {
3288
+ return ;
3289
+ }
3290
+
3291
+ peripheralQueueNext ();
3292
+ }
3293
+
3246
3294
private HashMap <Object , Object > EnsureCallback (UUID characteristicUuid , HashMap <Object , Object > connection ) {
3247
3295
HashMap <Object , Object > characteristicCallbacks = (HashMap <Object , Object >) connection .get (characteristicUuid );
3248
3296
@@ -4630,6 +4678,36 @@ public void onMtuChanged(BluetoothDevice device, int mtu) {
4630
4678
}
4631
4679
4632
4680
public void onNotificationSent (BluetoothDevice device , int status ) {
4681
+ Operation operation = peripheralQueue .peek ();
4682
+
4683
+ JSONArray args = operation .args ;
4684
+ CallbackContext callbackContext = operation .callbackContext ;
4685
+
4686
+ peripheralQueueRemove ();
4687
+
4688
+ //If no callback, just return
4689
+ if (callbackContext == null ) {
4690
+ return ;
4691
+ }
4692
+
4693
+ JSONObject obj = getArgsObject (args );
4694
+
4695
+ JSONObject returnObj = new JSONObject ();
4696
+
4697
+ addDevice (returnObj , device );
4698
+
4699
+ //If successfully notified, return value
4700
+ if (status == BluetoothGatt .GATT_SUCCESS ) {
4701
+ addProperty (returnObj , keyStatus , statusNotified );
4702
+ addProperty (returnObj , keySent , true );
4703
+ callbackContext .success (returnObj );
4704
+ } else {
4705
+ //Else it failed
4706
+ addProperty (returnObj , keyError , errorNotify );
4707
+ callbackContext .error (returnObj );
4708
+ }
4709
+
4710
+ //TODO: Remove code below (kept for backward compatibility)
4633
4711
if (initPeripheralCallback == null ) {
4634
4712
return ;
4635
4713
}
0 commit comments