Skip to content

Commit 872424e

Browse files
authoredFeb 19, 2023
Merge pull request #263 from theheraldproject/develop
Prepping release 2.2.0
2 parents 1c15f3e + 324df4a commit 872424e

File tree

8 files changed

+239
-46
lines changed

8 files changed

+239
-46
lines changed
 

‎app/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ android {
1313
minSdkVersion 21
1414
targetSdkVersion 31
1515
versionCode 2
16-
versionName "2.1.1"
16+
versionName "2.2.0"
1717

1818
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1919
}

‎herald/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55
}
66

77
group = 'io.heraldprox'
8-
version = '2.1.1'
8+
version = '2.2.0'
99

1010
apply plugin: 'com.android.library'
1111

@@ -17,7 +17,7 @@ android {
1717
minSdkVersion 21
1818
targetSdkVersion 31
1919
versionCode 2
20-
versionName "2.1.1"
20+
versionName "2.2.0"
2121

2222
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2323
consumerProguardFiles "consumer-rules.pro"

‎herald/src/main/java/io/heraldprox/herald/sensor/ble/BLESensorConfiguration.java

+66-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package io.heraldprox.herald.sensor.ble;
66

77
import androidx.annotation.NonNull;
8+
import androidx.annotation.Nullable;
89

910
import io.heraldprox.herald.sensor.data.SensorLoggerLevel;
1011
import io.heraldprox.herald.sensor.datatype.Data;
@@ -32,7 +33,7 @@ public class BLESensorConfiguration {
3233
* <br>- Switch to 16-bit UUID by setting the value xxxx in base UUID 0000xxxx-0000-1000-8000-00805F9B34FB
3334
*/
3435
@NonNull
35-
public static UUID legacyHeraldServiceUUID = UUID.fromString("428132af-4746-42d3-801e-4572d65bfd9b");
36+
public final static UUID legacyHeraldServiceUUID = UUID.fromString("428132af-4746-42d3-801e-4572d65bfd9b");
3637
public static boolean legacyHeraldServiceDetectionEnabled = true;
3738

3839
/**
@@ -47,7 +48,20 @@ public class BLESensorConfiguration {
4748
* <br>- Switch to 16-bit UUID by setting the value xxxx in base UUID 0000xxxx-0000-1000-8000-00805F9B34FB
4849
*/
4950
@NonNull
50-
public static UUID linuxFoundationServiceUUID = UUID.fromString("0000FCF6-0000-1000-8000-00805F9B34FB");
51+
public final static UUID linuxFoundationServiceUUID = UUID.fromString("0000FCF6-0000-1000-8000-00805F9B34FB");
52+
53+
/**
54+
* Enables detection of the current standard Herald service UUID.
55+
* Enabled by default
56+
* @since v2.2 February 2023
57+
*/
58+
public static boolean standardHeraldServiceDetectionEnabled = true;
59+
/**
60+
* Enables advertising of the current standard Herald service UUID.
61+
* Enabled by default
62+
* @since v2.2 February 2023
63+
*/
64+
public static boolean standardHeraldServiceAdvertisingEnabled = true;
5165

5266
/**
5367
* Signaling characteristic for controlling connection between peripheral and central, e.g. keep each other from suspend state
@@ -69,6 +83,52 @@ public class BLESensorConfiguration {
6983
@NonNull
7084
public final static UUID payloadCharacteristicUUID = UUID.fromString("3e98c0f8-8f05-4829-a121-43e38f8933e7");
7185

86+
// MARK:- Custom Service UUID interoperability - Since v2.2
87+
/**
88+
* A custom service UUID to use for a Herald service. Required for custom apps (without Herald interop).
89+
*
90+
* @since v2.2 February 2023
91+
* @note Requires customHeraldServiceDetectionEnabled to be set to true to enable.
92+
*/
93+
@Nullable
94+
public static UUID customServiceUUID = null;
95+
/**
96+
* Whether to detect a custom service UUID. Disabled by default.
97+
* Doesn't affect advertising.
98+
* in preference to the default Linux Foundation Herald UUID if specified.
99+
* Only takes effect if customServiceUUID is set to a valid non-null UUID.
100+
*
101+
* @since v2.2 February 2023
102+
*/
103+
public static boolean customServiceDetectionEnabled = false;
104+
/**
105+
* Whether to advertise using the main customServiceUUID instead of the standard Herald
106+
* Service UUID.
107+
*
108+
* @since v2.2 February 2023
109+
*/
110+
public static boolean customServiceAdvertisingEnabled = false;
111+
/**
112+
* Additional UUIDs beyond just customServiceUUID to detect. Useful for 'legacy' custom
113+
* application detections. You do not have to include customServiceUUID in this list.
114+
*
115+
* @since v2.2 February 2023
116+
* @note Requires customHeraldServiceDetectionEnabled to be set to true to enable.
117+
*/
118+
@Nullable
119+
public static UUID[] customAdditionalServiceUUIDs = null;
120+
/**
121+
* The custom manufacturer ID to use. Note this MUST be a Bluetooth SIG registered ID to
122+
* ensure there is no interference.
123+
* Note that if this is not specified, then the default Linux Foundation Herald service
124+
* manufacturer ID will be used.
125+
*
126+
* @since v2.2 February 2023
127+
* @note Requires customHeraldServiceDetectionEnabled to be set to true to enable.
128+
* @note Requires pseudoDeviceAddress to be enabled.
129+
*/
130+
static int customManufacturerIdForSensor = 0;
131+
72132
// MARK:- Interoperability with OpenTrace
73133

74134
/**
@@ -254,7 +314,9 @@ public class BLESensorConfiguration {
254314
* This was introduced in v2.1.0-beta4 as a controllable flag. Prior to this the feature was
255315
* always enabled. Additional Pseudo mac logic and read logic on iOS was added in the v2.1.0
256316
* release such that this is only required on very old/misbehaving Android sets. It has been
257-
* decided to DISABLE this from v2.1.0 onwards. If required, extra logic will be added to Herald
317+
* decided to DISABLE this for v2.1.0 onwards. It was reenabled in V2.2.0 due to certain
318+
* versions of iOS incorrectly raising existing Bluetooth devices as 'newly detected'.
319+
* If required, extra logic will be added to Herald
258320
* to detect on an Android device when it is 'misbehaving' by rotating it's MAC too much, and
259321
* if this is the case, this flag will be dynamically enabled for just that device.
260322
* <br><br>
@@ -269,7 +331,7 @@ public class BLESensorConfiguration {
269331
*
270332
* @since v2.1.0-beta4
271333
*/
272-
public static boolean pseudoDeviceAddressEnabled = false;
334+
public static boolean pseudoDeviceAddressEnabled = true;
273335

274336
/**
275337
* Interrogate standard Bluetooth services to obtain device make/model data

‎herald/src/main/java/io/heraldprox/herald/sensor/ble/BLETimer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void run() {
7777
try {
7878
delegate.bleTimer(System.currentTimeMillis());
7979
} catch (Throwable e) {
80-
logger.fault("delegate execution failed", e);
80+
logger.fault("delegate execution failed {}", e);
8181
}
8282
}
8383
}

‎herald/src/main/java/io/heraldprox/herald/sensor/ble/ConcreteBLEDatabase.java

+6
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ private PseudoDeviceAddress pseudoDeviceAddress(@NonNull final ScanResult scanRe
153153
if (null != data && data.length > 0) {
154154
return new PseudoDeviceAddress(data);
155155
}
156+
} else if (BLESensorConfiguration.customServiceDetectionEnabled &&
157+
0 != BLESensorConfiguration.customManufacturerIdForSensor) {
158+
final byte[] data = scanRecord.getManufacturerSpecificData(BLESensorConfiguration.customManufacturerIdForSensor);
159+
if (null != data && data.length > 0) {
160+
return new PseudoDeviceAddress(data);
161+
}
156162
}
157163
// Not found
158164
return null;

‎herald/src/main/java/io/heraldprox/herald/sensor/ble/ConcreteBLEReceiver.java

+95-9
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import android.content.pm.PackageManager;
2323
import android.os.Build;
2424
import android.os.ParcelUuid;
25-
import android.util.Log;
2625

2726
import androidx.annotation.NonNull;
2827
import androidx.annotation.Nullable;
@@ -431,11 +430,33 @@ private void scanForPeripherals(@NonNull final BluetoothLeScanner bluetoothLeSca
431430
// Scan for HERALD protocol service on iOS (background) devices
432431
filter.add(new ScanFilter.Builder().setManufacturerData(
433432
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+
}
439460
// Scan for OpenTrace protocol service on iOS and Android devices
440461
if (BLESensorConfiguration.interopOpenTraceEnabled) {
441462
filter.add(new ScanFilter.Builder().setServiceUuid(
@@ -578,6 +599,13 @@ private List<BLEDevice> didDiscover() {
578599
device.txPower(new BLE_TxPower(txPowerLevel));
579600
}
580601
}
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+
}
581609
// Identify operating system from scan record where possible
582610
// - Sensor service found + Manufacturer is Apple -> iOS (Foreground)
583611
// - Sensor service found + Manufacturer not Apple -> Android
@@ -645,7 +673,23 @@ private static boolean hasSensorService(@NonNull final ScanResult scanResult) {
645673
return false;
646674
}
647675
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)) {
649693
return true;
650694
}
651695
if (BLESensorConfiguration.legacyHeraldServiceDetectionEnabled &&
@@ -1020,6 +1064,20 @@ public void onServicesDiscovered(@NonNull final BluetoothGatt gatt, final int st
10201064

10211065
// Sensor characteristics
10221066
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+
}
10231081
if (null == service && BLESensorConfiguration.interopOpenTraceEnabled) {
10241082
service = gatt.getService(BLESensorConfiguration.interopOpenTraceServiceUUID);
10251083
}
@@ -1050,7 +1108,7 @@ public void onServicesDiscovered(@NonNull final BluetoothGatt gatt, final int st
10501108
// offering sensor services.
10511109
}
10521110
} else {
1053-
logger.debug("onServicesDiscovered, found sensor service (device={})", device);
1111+
logger.debug("onServicesDiscovered, found sensor service (device={},service={})", device,service.getUuid());
10541112
device.invalidateCharacteristics();
10551113
for (final BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
10561114
// Confirm operating system with signal characteristic
@@ -1142,6 +1200,7 @@ private BluetoothGattCharacteristic serviceCharacteristic(@NonNull final Bluetoo
11421200
*/
11431201
@NonNull
11441202
private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
1203+
logger.debug("nextTaskForDevice, called for device (device={})", device);
11451204
// No task for devices marked as .ignore
11461205
if (device.ignore()) {
11471206
logger.debug("nextTaskForDevice, ignore (device={},ignoreExpiresIn={})", device, device.timeIntervalUntilIgnoreExpires());
@@ -1154,6 +1213,7 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
11541213
}
11551214
// No task for devices marked as receive only (no advert to connect to)
11561215
if (device.receiveOnly()) {
1216+
logger.debug("nextTaskForDevice, receive only so next is nothing (device={})", device);
11571217
return NextTask.nothing;
11581218
}
11591219
// Device introspection to resolve device model if enabled and possible
@@ -1169,13 +1229,15 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
11691229
// Resolve or confirm operating system by reading payload which
11701230
// triggers characteristic discovery to confirm the operating system
11711231
if (device.operatingSystem() == BLEDeviceOperatingSystem.unknown ||
1172-
device.operatingSystem() == BLEDeviceOperatingSystem.ios_tbc) {
1232+
device.operatingSystem() == BLEDeviceOperatingSystem.ios_tbc ||
1233+
device.operatingSystem() == BLEDeviceOperatingSystem.android_tbc) {
11731234
logger.debug("nextTaskForDevice (device={},task=readPayload|OS)", device);
11741235
return NextTask.readPayload;
11751236
}
11761237
// Immediate send is supported only if service and characteristics
11771238
// have been discovered, and operating system has been confirmed
11781239
if (null != device.immediateSendData()) {
1240+
logger.debug("nextTaskForDevice (device={},task=immediateSend)", device);
11791241
return NextTask.immediateSend;
11801242
}
11811243
// Get payload as top priority
@@ -1222,6 +1284,17 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
12221284
logger.debug("nextTaskForDevice (device={},task=writePayloadUpdate,elapsed={})", device, device.timeIntervalSinceLastWritePayload());
12231285
return NextTask.writePayload;
12241286
}
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+
}
12251298
}
12261299
// Write payload sharing data to iOS
12271300
if (device.operatingSystem() == BLEDeviceOperatingSystem.ios && !device.protocolIsOpenTrace()) {
@@ -1234,6 +1307,7 @@ private NextTask nextTaskForDevice(@NonNull final BLEDevice device) {
12341307
return NextTask.writePayloadSharing;
12351308
}
12361309
}
1310+
logger.debug("nextTaskForDevice (device={},task=nothing)",device);
12371311
return NextTask.nothing;
12381312
}
12391313

@@ -1413,6 +1487,12 @@ private void writeSignalCharacteristic(@NonNull final BluetoothGatt gatt, @NonNu
14131487
} else {
14141488
logger.debug("writeSignalCharacteristic to iOS (task={},dataLength={},device={})", task, data.length, device);
14151489
// => 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+
}
14161496
}
14171497
return;
14181498
}
@@ -1425,6 +1505,12 @@ private void writeSignalCharacteristic(@NonNull final BluetoothGatt gatt, @NonNu
14251505
} else {
14261506
logger.debug("writeSignalCharacteristic to Android (task={},dataLength={},device={})", task, data.length, device);
14271507
// => 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+
}
14281514
}
14291515
}
14301516
}

0 commit comments

Comments
 (0)
Failed to load comments.