@@ -54,8 +54,9 @@ @implementation BLECentralPlugin
54
54
}
55
55
*/
56
56
57
- NSMutableArray *commandQueue;
58
- Boolean bleProcessing = false ;
57
+
58
+
59
+
59
60
60
61
61
62
- (void )pluginInitialize {
@@ -65,7 +66,9 @@ - (void)pluginInitialize {
65
66
66
67
[super pluginInitialize ];
67
68
68
- commandQueue = [NSMutableArray array ];
69
+ // Important note: The key to the commandQueueDict and bleProcessing is the peripheral UUID
70
+ commandQueueDict = [NSMutableDictionary new ];
71
+ bleProcessing = [NSMutableDictionary new ];
69
72
peripherals = [NSMutableSet set ];
70
73
manager = [[CBCentralManager alloc ] initWithDelegate: self queue: nil ];
71
74
@@ -93,40 +96,68 @@ - (void)pluginInitialize {
93
96
#pragma mark - Cordova Plugin Methods
94
97
95
98
96
- -(CDVInvokedUrlCommand*)commandQueuePop {
97
- @synchronized (commandQueue)
98
- {
99
- if ([commandQueue count ] == 0 ) {
100
- return nil ;
99
+ -(CDVInvokedUrlCommand*)commandQueuePop : (CDVInvokedUrlCommand*)anObject {
100
+ NSString *key = [self getKeyFromCommand: anObject];
101
+ return [self commandQueuePopKey: key];
102
+ }
103
+ -(CDVInvokedUrlCommand*)commandQueuePopKey : (NSString *)key {
104
+ @synchronized (commandQueueDict)
105
+ {
106
+ [self setCurrentCommandQueueByKey: key];
107
+
108
+ @synchronized (commandQueue)
109
+ {
110
+ if ([commandQueue count ] == 0 ) {
111
+ return nil ;
112
+ }
113
+
114
+ id queueObject = [commandQueue objectAtIndex: 0 ];
115
+
116
+ [commandQueue removeObjectAtIndex: 0 ];
117
+
118
+ return queueObject;
119
+ }
101
120
}
102
-
103
- id queueObject = [commandQueue objectAtIndex: 0 ];
104
-
105
- [commandQueue removeObjectAtIndex: 0 ];
106
-
107
- return queueObject;
108
- }
109
121
}
110
-
111
- -(CDVInvokedUrlCommand*)commandQueuePoll {
112
- @synchronized (commandQueue)
113
- {
114
- if ([commandQueue count ] == 0 ) {
115
- return nil ;
122
+ -(CDVInvokedUrlCommand*)commandQueuePollKey : (NSString *)key {
123
+
124
+ @synchronized (commandQueueDict)
125
+ {
126
+ [self setCurrentCommandQueueByKey: key];
127
+
128
+ @synchronized (commandQueue)
129
+ {
130
+
131
+ if ([commandQueue count ] == 0 ) {
132
+ return nil ;
133
+ }
134
+
135
+ id queueObject =[commandQueue objectAtIndex: 0 ];
136
+
137
+ return queueObject;
138
+ }
116
139
}
140
+ }
117
141
118
- id queueObject =[commandQueue objectAtIndex: 0 ];
119
-
120
- return queueObject ;
121
- }
142
+ -(CDVInvokedUrlCommand*) commandQueuePoll : (CDVInvokedUrlCommand*) anObject {
143
+
144
+ NSString *key = [ self getKeyFromCommand: anObject] ;
145
+ return [ self commandQueuePollKey: key];
122
146
}
123
147
124
148
// Add to the tail of the queue
125
149
-(void )commandQueuePush : (CDVInvokedUrlCommand*)anObject {
126
- @synchronized (commandQueue)
127
- {
128
- [commandQueue addObject: anObject];
129
- }
150
+
151
+ @synchronized (commandQueueDict)
152
+ {
153
+ [self setCurrentCommandQueue: anObject];
154
+
155
+ @synchronized (commandQueue)
156
+ {
157
+
158
+ [commandQueue addObject: anObject];
159
+ }
160
+ }
130
161
}
131
162
132
163
@@ -332,13 +363,36 @@ void dispatch_after_delay_on_background_queue(float delayInSeconds, dispatch_blo
332
363
dispatch_after_delay (delayInSeconds, queue, block);
333
364
}
334
365
366
+ - (NSString *)getKeyFromCommand : (CDVInvokedUrlCommand*) command {
367
+ BLECommandContext *context = [self getData: command prop: CBCharacteristicPropertyWrite];
368
+ CBPeripheral *peripheral = [context peripheral ];
369
+ NSString *key = [self keyForPeripheral: peripheral ];
370
+
371
+ return key;
372
+ }
373
+
374
+ - (void )setCurrentCommandQueue : (CDVInvokedUrlCommand*)command {
375
+
376
+ NSString *key = [self getKeyFromCommand: command];
377
+ [self setCurrentCommandQueueByKey: key];
378
+
379
+ }
380
+
381
+ - (void )setCurrentCommandQueueByKey : (NSString *) key {
382
+
383
+ commandQueue = [commandQueueDict objectForKey: key];
384
+ if (!commandQueue) {
385
+ [commandQueueDict setObject: [NSMutableArray array ] forKey: key];
386
+ commandQueue = [commandQueueDict objectForKey: key];
387
+ }
388
+
389
+ }
390
+
335
391
- (void )queueCommand : (CDVInvokedUrlCommand*)command {
336
392
337
393
[self commandQueuePush: command];
394
+ [self processCommands: command];
338
395
339
- if (!bleProcessing) {
340
- [self processCommands ];
341
- }
342
396
}
343
397
344
398
- (void )read : (CDVInvokedUrlCommand*)command {
@@ -359,42 +413,61 @@ - (void)stopNotification:(CDVInvokedUrlCommand*)command {
359
413
[self queueCommand: command];
360
414
}
361
415
362
- - (void )processCommands {
363
-
364
- if (bleProcessing) { return ; }
365
-
366
-
367
- CDVInvokedUrlCommand* command = [self commandQueuePoll ];
368
-
416
+ - (void )processCommandsKey : (NSString *)key {
417
+
418
+ [self setCurrentCommandQueueByKey: key];
419
+
420
+
421
+
422
+ if ( [[bleProcessing objectForKey: key] isEqualToString: @" true" ]) { return ; }
423
+
424
+ CDVInvokedUrlCommand* command = [self commandQueuePollKey: key];
425
+
369
426
if (command != nil ) {
370
-
371
- bleProcessing = true ;
427
+
428
+
429
+ [bleProcessing setObject: @" true" forKey: key];
430
+
372
431
if ([command.methodName isEqualToString: @" read" ]) {
373
- [self readEx: command];
432
+ [self readEx: command];
374
433
} else if ([command.methodName isEqualToString: @" write" ]) {
375
- [self writeEx: command];
434
+ [self writeEx: command];
376
435
} else if ([command.methodName isEqualToString: @" writeWithoutResponse" ]) {
377
- [self writeWithoutResponseEx: command];
436
+ [self writeWithoutResponseEx: command];
378
437
} else if ([command.methodName isEqualToString: @" startNotification" ]) {
379
438
[self startNotificationEx: command];
380
439
} else if ([command.methodName isEqualToString: @" stopNotification" ]) {
381
440
[self stopNotificationEx: command];
382
441
} else {
383
- // this shouldn't happen
384
- bleProcessing = false ;
442
+ // this shouldn't happen
443
+
444
+ [bleProcessing setObject: @" false" forKey: key];
385
445
NSLog (@" Skipping unknown command in process commands" );
386
446
}
387
447
}
448
+
449
+ }
450
+
451
+ - (void )processCommands : (CDVInvokedUrlCommand*)commandKey {
388
452
453
+ NSString *key = [self getKeyFromCommand: commandKey];
454
+ [self processCommandsKey: key];
455
+
389
456
}
390
457
391
- - (void )commandCompleted {
392
- NSLog (@" Processing Complete" );
393
- CDVInvokedUrlCommand* command = [self commandQueuePop ] ; // Pop the last command and process the next one.
394
- bleProcessing = false ;
395
- [self processCommands ];
458
+ - (void )commandCompleted : (CDVInvokedUrlCommand*)commandKey {
459
+ NSString *key = [self getKeyFromCommand: commandKey];
460
+ [self commandCompletedKey: key];
396
461
}
397
462
463
+ - (void )commandCompletedKey : (NSString *)key {
464
+ NSLog (@" Processing Complete" );
465
+ CDVInvokedUrlCommand* command = [self commandQueuePopKey: key ]; // Pop the last command and process the next one.
466
+ [bleProcessing setObject: @" false" forKey: key];
467
+ [self processCommandsKey: key];
468
+ }
469
+
470
+
398
471
399
472
#ifndef ADD_DELAYS
400
473
@@ -591,7 +664,7 @@ - (void)writeWithoutResponseEx:(CDVInvokedUrlCommand*)command {
591
664
}
592
665
[self .commandDelegate sendPluginResult: pluginResult callbackId: command.callbackId];
593
666
}
594
- [self commandCompleted ]; // Done in onWrite
667
+ [self commandCompleted: command ]; // Done in onWrite
595
668
596
669
});
597
670
// dispatch_release(queue); // release the thread if its one of ours
@@ -614,7 +687,7 @@ - (void)writeWithoutResponseEx:(CDVInvokedUrlCommand*)command {
614
687
pluginResult = [CDVPluginResult resultWithStatus: CDVCommandStatus_ERROR messageAsString: @" message was null" ];
615
688
}
616
689
[self .commandDelegate sendPluginResult: pluginResult callbackId: command.callbackId];
617
- [self commandCompleted ];
690
+ [self commandCompleted: command ];
618
691
}
619
692
620
693
}
@@ -1074,14 +1147,14 @@ - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(C
1074
1147
NSString *key = [self keyForPeripheral: peripheral andCharacteristic: characteristic];
1075
1148
NSString *notifyCallbackId = [notificationCallbacks objectForKey: key];
1076
1149
1150
+ // This is for async notifies
1077
1151
if (notifyCallbackId) {
1078
1152
NSData *data = characteristic.value ; // send RAW data to Javascript
1079
1153
1080
1154
CDVPluginResult *pluginResult = nil ;
1081
1155
pluginResult = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsArrayBuffer: data];
1082
1156
[pluginResult setKeepCallbackAsBool: TRUE ]; // keep for notification
1083
1157
[self .commandDelegate sendPluginResult: pluginResult callbackId: notifyCallbackId];
1084
- // [self commandCompleted]; This is for async notifies
1085
1158
}
1086
1159
1087
1160
NSString *readCallbackId = [readCallbacks objectForKey: key];
@@ -1092,7 +1165,7 @@ - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(C
1092
1165
CDVPluginResult *pluginResult = nil ;
1093
1166
pluginResult = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsArrayBuffer: data];
1094
1167
[self .commandDelegate sendPluginResult: pluginResult callbackId: readCallbackId];
1095
- // [self commandCompleted];
1168
+
1096
1169
1097
1170
[readCallbacks removeObjectForKey: key];
1098
1171
}
@@ -1128,7 +1201,7 @@ - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForChara
1128
1201
[self .commandDelegate sendPluginResult: pluginResult callbackId: notificationCallbackId];
1129
1202
1130
1203
}
1131
- [self commandCompleted ];
1204
+ [self commandCompletedKey: [ self keyForPeripheral: peripheral] ];
1132
1205
1133
1206
}
1134
1207
@@ -1154,7 +1227,7 @@ - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CB
1154
1227
[writeCallbacks removeObjectForKey: key];
1155
1228
1156
1229
}
1157
- [self commandCompleted ];
1230
+ [ self commandCompletedKey: [self keyForPeripheral: peripheral] ];
1158
1231
}
1159
1232
1160
1233
- (void )peripheralDidUpdateRSSI : (CBPeripheral*)peripheral error : (NSError *)error {
@@ -1178,7 +1251,7 @@ - (void)peripheral:(CBPeripheral*)peripheral didReadRSSI:(NSNumber*)rssi error:(
1178
1251
}
1179
1252
[self .commandDelegate sendPluginResult: pluginResult callbackId: readRSSICallbackId];
1180
1253
[readRSSICallbacks removeObjectForKey: readRSSICallbackId];
1181
- [self commandCompleted ];
1254
+ [ self commandCompletedKey: [self keyForPeripheral: peripheral] ];
1182
1255
}
1183
1256
}
1184
1257
@@ -1417,6 +1490,18 @@ -(NSString *) keyForPeripheral: (CBPeripheral *)peripheral andCharacteristic:(CB
1417
1490
return [NSString stringWithFormat: @" %@ |%@ " , [peripheral uuidAsString ], [characteristic UUID ]];
1418
1491
}
1419
1492
1493
+ -(NSString *) keyForPeripheral : (CBPeripheral *)peripheral {
1494
+ return [NSString stringWithFormat: @" %@ " , [peripheral uuidAsString ]];
1495
+ }
1496
+
1497
+ // Return just the peripheralKey from a key with peripheral UUID and characteristic
1498
+ -(NSString *) keyFromComplexKey : (NSString *)inKey {
1499
+ NSArray *parts = [inKey componentsSeparatedByString: @" |" ];
1500
+
1501
+ return parts[0 ];
1502
+
1503
+ }
1504
+
1420
1505
#pragma mark - util
1421
1506
1422
1507
- (NSString *) centralManagerStateToString : (int )state
0 commit comments