[bluetooth.generic] Enable BLE notification for linked channels (#10122)

* [bluetooth] Add BluetoothDevice.isNotifying()
* [bluetooth] Improve Characteristic properties support
* [bluez] Improve Characteristic properties support
* [bluetooth] Add BluetoothDevice.canNotify()
* [bluez] Also catch DBusExecutionException on read value
* [bluetooth.generic] Activate notifications for linked channels where characteristics are able to notify
* [bluez] Adjust javadoc
* [bluegiga] Add BluetoothDevice.isNotifying() support
* [bluegiga] Fix notification enabled check
* [bluetooth] move canNotify() to Characteristic
* [bluegiga] rename notificationEnabled to notifying
* [bluetooth.generic] use handlerToChannels to subscribe to notifications
* [bluetooth.generic] implement TODOs of canRead()/canWrite()
* [bluetooth.generic] optimize ChannelUID
* [bluetooth.generic] use channelUids for link check

Signed-off-by: Peter Rosenberg <prosenb.dev@gmail.com>
This commit is contained in:
Pete
2021-02-16 21:26:34 +01:00
committed by GitHub
parent 596b261d47
commit 7abeb97396
9 changed files with 270 additions and 22 deletions

View File

@@ -57,6 +57,7 @@ import com.github.hypfvieh.bluetooth.wrapper.BluetoothGattService;
*
* @author Kai Kreuzer - Initial contribution and API
* @author Benjamin Lafois - Replaced tinyB with bluezDbus
* @author Peter Rosenberg - Improve notifications and properties support
*
*/
@NonNullByDefault
@@ -399,6 +400,7 @@ public class BlueZBluetoothDevice extends BaseBluetoothDevice implements BlueZEv
for (BluetoothGattCharacteristic dBusBlueZCharacteristic : dBusBlueZService.getGattCharacteristics()) {
BluetoothCharacteristic characteristic = new BluetoothCharacteristic(
UUID.fromString(dBusBlueZCharacteristic.getUuid()), 0);
convertCharacteristicProperties(dBusBlueZCharacteristic, characteristic);
for (BluetoothGattDescriptor dBusBlueZDescriptor : dBusBlueZCharacteristic.getGattDescriptors()) {
BluetoothDescriptor descriptor = new BluetoothDescriptor(characteristic,
@@ -414,6 +416,42 @@ public class BlueZBluetoothDevice extends BaseBluetoothDevice implements BlueZEv
return true;
}
/**
* Convert the flags of BluetoothGattCharacteristic to the int bitset used by BluetoothCharacteristic.
*
* @param dBusBlueZCharacteristic source characteristic to read the flags from
* @param characteristic destination characteristic to write to properties to
*/
private void convertCharacteristicProperties(BluetoothGattCharacteristic dBusBlueZCharacteristic,
BluetoothCharacteristic characteristic) {
int properties = 0;
for (String property : dBusBlueZCharacteristic.getFlags()) {
switch (property) {
case "broadcast":
properties |= BluetoothCharacteristic.PROPERTY_BROADCAST;
break;
case "read":
properties |= BluetoothCharacteristic.PROPERTY_READ;
break;
case "write-without-response":
properties |= BluetoothCharacteristic.PROPERTY_WRITE_NO_RESPONSE;
break;
case "write":
properties |= BluetoothCharacteristic.PROPERTY_WRITE;
break;
case "notify":
properties |= BluetoothCharacteristic.PROPERTY_NOTIFY;
break;
case "indicate":
properties |= BluetoothCharacteristic.PROPERTY_INDICATE;
break;
}
}
characteristic.setProperties(properties);
}
@Override
public boolean readCharacteristic(BluetoothCharacteristic characteristic) {
BluetoothGattCharacteristic c = getDBusBlueZCharacteristicByUUID(characteristic.getUuid().toString());
@@ -428,7 +466,8 @@ public class BlueZBluetoothDevice extends BaseBluetoothDevice implements BlueZEv
characteristic.setValue(value);
notifyListeners(BluetoothEventType.CHARACTERISTIC_READ_COMPLETE, characteristic,
BluetoothCompletionStatus.SUCCESS);
} catch (DBusException e) {
} catch (DBusException | DBusExecutionException e) {
// DBusExecutionException is thrown if the value cannot be read
logger.debug("Exception occurred when trying to read characteristic '{}': {}", characteristic.getUuid(),
e.getMessage());
notifyListeners(BluetoothEventType.CHARACTERISTIC_READ_COMPLETE, characteristic,
@@ -438,6 +477,18 @@ public class BlueZBluetoothDevice extends BaseBluetoothDevice implements BlueZEv
return true;
}
@Override
public boolean isNotifying(BluetoothCharacteristic characteristic) {
BluetoothGattCharacteristic c = getDBusBlueZCharacteristicByUUID(characteristic.getUuid().toString());
if (c != null) {
Boolean isNotifying = c.isNotifying();
return Objects.requireNonNullElse(isNotifying, false);
} else {
logger.warn("Characteristic '{}' is missing on device '{}'.", characteristic.getUuid(), address);
return false;
}
}
@Override
public boolean disableNotifications(BluetoothCharacteristic characteristic) {
BluetoothGattCharacteristic c = getDBusBlueZCharacteristicByUUID(characteristic.getUuid().toString());