diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java index cb5ed147..a8741868 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java @@ -33,9 +33,10 @@ public enum AlertCategory { VoiceMail(6), Schedule(7), HighPriorityAlert(8), - InstantMessage(9); + InstantMessage(9), // 10-250 reserved for future use // 251-255 defined by service specification + Any(255); private final int id; @@ -91,5 +92,4 @@ public enum AlertCategory { return null; } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java index c470905c..ebb111ae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java @@ -16,9 +16,39 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; +import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; + /** * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.alert_notification_control_point.xml */ public class AlertNotificationControl { + private AlertCategory category; + private Command command; + public void setCategory(AlertCategory category) { + this.category = category; + } + + public void setCommand(Command command) { + this.command = command; + } + + public AlertCategory getCategory() { + return category; + } + + public Command getCommand() { + return command; + } + + /** + * Returns the formatted message to be written to the alert notification control point + * characteristic + */ + public byte[] getControlMessage() { + return new byte[] { + BLETypeConversions.fromUint8(command.getId()), + BLETypeConversions.fromUint8(category.getId()) + }; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java index 751f3d47..37f3ddc0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java @@ -39,6 +39,20 @@ public class AlertNotificationProfile exten super(support); } + public void configure(TransactionBuilder builder, AlertNotificationControl control) { + BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_NOTIFICATION_CONTROL_POINT); + if (characteristic != null) { + builder.write(characteristic, control.getControlMessage()); + } + } + + public void updateAlertLevel(TransactionBuilder builder, AlertLevel level) { + BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL); + if (characteristic != null) { + builder.write(characteristic, new byte[] {BLETypeConversions.fromUint8(level.getId())}); + } + } + public void newAlert(TransactionBuilder builder, NewAlert alert, OverflowStrategy strategy) { BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT); if (characteristic != null) { @@ -52,14 +66,20 @@ public class AlertNotificationProfile exten numChunks++; } + boolean hasAlerted = false; for (int i = 0; i < numChunks; i++) { int offset = i * MAX_MSG_LENGTH; int restLength = message.length() - offset; message = message.substring(offset, offset + Math.min(MAX_MSG_LENGTH, restLength)); - if (message.length() == 0) { + if (hasAlerted && message.length() == 0) { + // no need to do it again when there is no text content break; } writeAlertMessage(builder, characteristic, alert, message, i); + hasAlerted = true; + } + if (!hasAlerted) { + writeAlertMessage(builder, characteristic, alert, "", 1); } } else { LOG.warn("NEW_ALERT characteristic not available"); @@ -69,13 +89,18 @@ public class AlertNotificationProfile exten protected void writeAlertMessage(TransactionBuilder builder, BluetoothGattCharacteristic characteristic, NewAlert alert, String message, int chunk) { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(100); - stream.write(alert.getCategory().getId()); - stream.write(alert.getNumAlerts()); - stream.write(BLETypeConversions.toUtf8s(message)); + stream.write(BLETypeConversions.fromUint8(alert.getCategory().getId())); + stream.write(BLETypeConversions.fromUint8(alert.getNumAlerts())); + if (message.length() > 0) { + stream.write(BLETypeConversions.toUtf8s(message)); + } else { + // some write a null byte instead of leaving out this optional value +// stream.write(new byte[] {0}); + } builder.write(characteristic, stream.toByteArray()); } catch (IOException ex) { - // aint gonna happen + // ain't gonna happen LOG.error("Error writing alert message to ByteArrayOutputStream"); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java new file mode 100644 index 00000000..263f0669 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java @@ -0,0 +1,24 @@ +package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; + +/** + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.alert_notification_control_point.xml + */ +public enum Command { + EnableNewIncomingAlertNotification(0), + EnableUnreadCategoryStatusNotification(1), + DisableNewIncomingAlertNotification(2), + DisbleUnreadCategoryStatusNotification(3), + NotifyNewIncomingAlertImmediately(4), + NotifyUnreadCategoryStatusImmediately(5),; + // 6-255 reserved for future use + + private final int id; + + Command(int id) { + this.id = id; + } + + public int getId() { + return id; + } +}