22
22
import android .content .pm .PackageManager ;
23
23
import android .os .Build ;
24
24
import android .os .ParcelUuid ;
25
- import android .util .Log ;
26
25
27
26
import androidx .annotation .NonNull ;
28
27
import androidx .annotation .Nullable ;
@@ -431,11 +430,33 @@ private void scanForPeripherals(@NonNull final BluetoothLeScanner bluetoothLeSca
431
430
// Scan for HERALD protocol service on iOS (background) devices
432
431
filter .add (new ScanFilter .Builder ().setManufacturerData (
433
432
BLESensorConfiguration .manufacturerIdForApple , new byte [0 ], new byte [0 ]).build ());
434
- // Scan for HERALD protocol service on Android or iOS (foreground) devices
435
- filter .add (new ScanFilter .Builder ().setServiceUuid (
436
- new ParcelUuid (BLESensorConfiguration .linuxFoundationServiceUUID ),
437
- new ParcelUuid (new UUID (0xFFFFFFFFFFFFFFFFL , 0 )))
438
- .build ());
433
+
434
+ // This logic added in v2.2 to enable disabling of standard herald device detection and
435
+ // detection of custom application IDs
436
+ if (BLESensorConfiguration .customServiceDetectionEnabled ) {
437
+ if (null != BLESensorConfiguration .customServiceUUID ) {
438
+ filter .add (new ScanFilter .Builder ().setServiceUuid (
439
+ new ParcelUuid (BLESensorConfiguration .customServiceUUID ),
440
+ new ParcelUuid (new UUID (0xFFFFFFFFFFFFFFFFL , 0 )))
441
+ .build ());
442
+ }
443
+ if (null != BLESensorConfiguration .customAdditionalServiceUUIDs ) {
444
+ for (int idx = 0 ;idx < BLESensorConfiguration .customAdditionalServiceUUIDs .length ;idx ++) {
445
+ filter .add (new ScanFilter .Builder ().setServiceUuid (
446
+ new ParcelUuid (BLESensorConfiguration .customAdditionalServiceUUIDs [idx ]),
447
+ new ParcelUuid (new UUID (0xFFFFFFFFFFFFFFFFL , 0 )))
448
+ .build ());
449
+ }
450
+ }
451
+ }
452
+ // This is useful for a custom application.
453
+ if (BLESensorConfiguration .standardHeraldServiceDetectionEnabled ) {
454
+ // Scan for HERALD protocol service on Android or iOS (foreground) devices
455
+ filter .add (new ScanFilter .Builder ().setServiceUuid (
456
+ new ParcelUuid (BLESensorConfiguration .linuxFoundationServiceUUID ),
457
+ new ParcelUuid (new UUID (0xFFFFFFFFFFFFFFFFL , 0 )))
458
+ .build ());
459
+ }
439
460
// Scan for OpenTrace protocol service on iOS and Android devices
440
461
if (BLESensorConfiguration .interopOpenTraceEnabled ) {
441
462
filter .add (new ScanFilter .Builder ().setServiceUuid (
@@ -578,6 +599,13 @@ private List<BLEDevice> didDiscover() {
578
599
device .txPower (new BLE_TxPower (txPowerLevel ));
579
600
}
580
601
}
602
+ if (device .operatingSystem () == BLEDeviceOperatingSystem .ios ||
603
+ device .operatingSystem () == BLEDeviceOperatingSystem .ios_tbc ||
604
+ device .operatingSystem () == BLEDeviceOperatingSystem .android ||
605
+ device .operatingSystem () == BLEDeviceOperatingSystem .android_tbc ) {
606
+ logger .debug ("didDiscover, OS already known (device={})" ,device );
607
+ continue ;
608
+ }
581
609
// Identify operating system from scan record where possible
582
610
// - Sensor service found + Manufacturer is Apple -> iOS (Foreground)
583
611
// - Sensor service found + Manufacturer not Apple -> Android
@@ -645,7 +673,23 @@ private static boolean hasSensorService(@NonNull final ScanResult scanResult) {
645
673
return false ;
646
674
}
647
675
for (final ParcelUuid serviceUuid : serviceUuids ) {
648
- if (serviceUuid .getUuid ().equals (BLESensorConfiguration .linuxFoundationServiceUUID )) {
676
+ // Since v2.2 try custom service UUID(s) first
677
+ if (BLESensorConfiguration .customServiceDetectionEnabled ) {
678
+ if (null != BLESensorConfiguration .customServiceUUID &&
679
+ serviceUuid .getUuid ().equals (BLESensorConfiguration .customServiceUUID )) {
680
+ return true ;
681
+ }
682
+ if (null != BLESensorConfiguration .customAdditionalServiceUUIDs ) {
683
+ for (int idx = 0 ; idx < BLESensorConfiguration .customAdditionalServiceUUIDs .length ;idx ++) {
684
+ if (serviceUuid .getUuid ().equals (BLESensorConfiguration .customAdditionalServiceUUIDs [idx ])) {
685
+ return true ;
686
+ }
687
+ }
688
+ }
689
+ }
690
+ // Extra if term added in v2.2 so a custom app doesn't accidentally detect normal standard Herald devices
691
+ if (BLESensorConfiguration .standardHeraldServiceDetectionEnabled &&
692
+ serviceUuid .getUuid ().equals (BLESensorConfiguration .linuxFoundationServiceUUID )) {
649
693
return true ;
650
694
}
651
695
if (BLESensorConfiguration .legacyHeraldServiceDetectionEnabled &&
@@ -1020,6 +1064,20 @@ public void onServicesDiscovered(@NonNull final BluetoothGatt gatt, final int st
1020
1064
1021
1065
// Sensor characteristics
1022
1066
BluetoothGattService service = gatt .getService (BLESensorConfiguration .linuxFoundationServiceUUID );
1067
+ // Since v2.2 override if a custom UUID is specified
1068
+ if (BLESensorConfiguration .customServiceDetectionEnabled ) {
1069
+ service = null ; // Ensure we don't accidentally re-enable Herald detection
1070
+ // Try the main custom one first (if not null)
1071
+ if (null != BLESensorConfiguration .customServiceUUID ) {
1072
+ service = gatt .getService (BLESensorConfiguration .customServiceUUID );
1073
+ }
1074
+ if (null == service && null != BLESensorConfiguration .customAdditionalServiceUUIDs ) {
1075
+ // Now try any additional custom service UUIDs
1076
+ for (int idx = 0 ;null == service && idx < BLESensorConfiguration .customAdditionalServiceUUIDs .length ; idx ++) {
1077
+ service = gatt .getService (BLESensorConfiguration .customAdditionalServiceUUIDs [idx ]);
1078
+ }
1079
+ }
1080
+ }
1023
1081
if (null == service && BLESensorConfiguration .interopOpenTraceEnabled ) {
1024
1082
service = gatt .getService (BLESensorConfiguration .interopOpenTraceServiceUUID );
1025
1083
}
@@ -1050,7 +1108,7 @@ public void onServicesDiscovered(@NonNull final BluetoothGatt gatt, final int st
1050
1108
// offering sensor services.
1051
1109
}
1052
1110
} else {
1053
- logger .debug ("onServicesDiscovered, found sensor service (device={})" , device );
1111
+ logger .debug ("onServicesDiscovered, found sensor service (device={},service={} )" , device , service . getUuid () );
1054
1112
device .invalidateCharacteristics ();
1055
1113
for (final BluetoothGattCharacteristic characteristic : service .getCharacteristics ()) {
1056
1114
// Confirm operating system with signal characteristic
@@ -1142,6 +1200,7 @@ private BluetoothGattCharacteristic serviceCharacteristic(@NonNull final Bluetoo
1142
1200
*/
1143
1201
@ NonNull
1144
1202
private NextTask nextTaskForDevice (@ NonNull final BLEDevice device ) {
1203
+ logger .debug ("nextTaskForDevice, called for device (device={})" , device );
1145
1204
// No task for devices marked as .ignore
1146
1205
if (device .ignore ()) {
1147
1206
logger .debug ("nextTaskForDevice, ignore (device={},ignoreExpiresIn={})" , device , device .timeIntervalUntilIgnoreExpires ());
@@ -1154,6 +1213,7 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
1154
1213
}
1155
1214
// No task for devices marked as receive only (no advert to connect to)
1156
1215
if (device .receiveOnly ()) {
1216
+ logger .debug ("nextTaskForDevice, receive only so next is nothing (device={})" , device );
1157
1217
return NextTask .nothing ;
1158
1218
}
1159
1219
// Device introspection to resolve device model if enabled and possible
@@ -1169,13 +1229,15 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
1169
1229
// Resolve or confirm operating system by reading payload which
1170
1230
// triggers characteristic discovery to confirm the operating system
1171
1231
if (device .operatingSystem () == BLEDeviceOperatingSystem .unknown ||
1172
- device .operatingSystem () == BLEDeviceOperatingSystem .ios_tbc ) {
1232
+ device .operatingSystem () == BLEDeviceOperatingSystem .ios_tbc ||
1233
+ device .operatingSystem () == BLEDeviceOperatingSystem .android_tbc ) {
1173
1234
logger .debug ("nextTaskForDevice (device={},task=readPayload|OS)" , device );
1174
1235
return NextTask .readPayload ;
1175
1236
}
1176
1237
// Immediate send is supported only if service and characteristics
1177
1238
// have been discovered, and operating system has been confirmed
1178
1239
if (null != device .immediateSendData ()) {
1240
+ logger .debug ("nextTaskForDevice (device={},task=immediateSend)" , device );
1179
1241
return NextTask .immediateSend ;
1180
1242
}
1181
1243
// Get payload as top priority
@@ -1222,6 +1284,17 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
1222
1284
logger .debug ("nextTaskForDevice (device={},task=writePayloadUpdate,elapsed={})" , device , device .timeIntervalSinceLastWritePayload ());
1223
1285
return NextTask .writePayload ;
1224
1286
}
1287
+ } else {
1288
+ // Since v2.2 - Write our payload to iOS if needed (i.e. if they haven't detected us)
1289
+ if (device .operatingSystem () == BLEDeviceOperatingSystem .ios ) {
1290
+ final TimeInterval lastTime = device .timeIntervalSinceLastWritePayload ();
1291
+ logger .debug ("nextTaskForDevice, timeSinceLastWrite (device={},task=writePayload,elapsed={})" , device , lastTime );
1292
+ // Don't forget the = to part! Because both can be never
1293
+ if (lastTime .value >= BLESensorConfiguration .payloadDataUpdateTimeInterval .value ) {
1294
+ logger .debug ("nextTaskForDevice (device={},task=writePayload,elapsed={})" , device , device .timeIntervalSinceLastWritePayload ());
1295
+ return NextTask .writePayload ;
1296
+ }
1297
+ }
1225
1298
}
1226
1299
// Write payload sharing data to iOS
1227
1300
if (device .operatingSystem () == BLEDeviceOperatingSystem .ios && !device .protocolIsOpenTrace ()) {
@@ -1234,6 +1307,7 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
1234
1307
return NextTask .writePayloadSharing ;
1235
1308
}
1236
1309
}
1310
+ logger .debug ("nextTaskForDevice (device={},task=nothing)" ,device );
1237
1311
return NextTask .nothing ;
1238
1312
}
1239
1313
@@ -1413,6 +1487,12 @@ private void writeSignalCharacteristic(@NonNull final BluetoothGatt gatt, @NonNu
1413
1487
} else {
1414
1488
logger .debug ("writeSignalCharacteristic to iOS (task={},dataLength={},device={})" , task , data .length , device );
1415
1489
// => onCharacteristicWrite
1490
+ // Assume it succeeds without acknowledgement
1491
+ if (task == NextTask .writePayload ) {
1492
+ device .registerWritePayload ();
1493
+ } else if (task == NextTask .writePayloadSharing ) {
1494
+ device .registerWritePayloadSharing ();
1495
+ }
1416
1496
}
1417
1497
return ;
1418
1498
}
@@ -1425,6 +1505,12 @@ private void writeSignalCharacteristic(@NonNull final BluetoothGatt gatt, @NonNu
1425
1505
} else {
1426
1506
logger .debug ("writeSignalCharacteristic to Android (task={},dataLength={},device={})" , task , data .length , device );
1427
1507
// => onCharacteristicWrite
1508
+ // Assume it succeeds without acknowledgement
1509
+ if (task == NextTask .writePayload ) {
1510
+ device .registerWritePayload ();
1511
+ } else if (task == NextTask .writePayloadSharing ) {
1512
+ device .registerWritePayloadSharing ();
1513
+ }
1428
1514
}
1429
1515
}
1430
1516
}
0 commit comments