From 510d13037a06dfe75d6fdeac9eded5408b40e83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20B=C3=B6hler?= Date: Mon, 28 Jan 2019 20:25:16 +0100 Subject: [PATCH 1/5] Add alarm configuration and fix a few small bugs --- .../casiogb6900/CasioGB6900Constants.java | 1 + .../CasioGB6900DeviceCoordinator.java | 2 +- .../casiogb6900/CasioGB6900DeviceSupport.java | 28 +++++++++++++++++-- .../casiogb6900/CasioHandlerThread.java | 5 +++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java index af779fc2c..52fc0ea49 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java @@ -74,6 +74,7 @@ public final class CasioGB6900Constants { public static final UUID TX_POWER_LEVEL_CHARACTERISTIC_UUID = UUID.fromString("00002a07-0000-1000-8000-00805f9b34fb"); // Settings public static final UUID CASIO_SETTING_FOR_BLE_CHARACTERISTIC_UUID = UUID.fromString("26eb000f-b012-49a8-b1f8-394fb2032b0f"); + public static final UUID CASIO_SETTING_FOR_ALM_CHARACTERISTIC_UUID = UUID.fromString("26eb0013-b012-49a8-b1f8-394fb2032b0f"); // Notification Types diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java index df9986f76..ae44233e0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java @@ -118,7 +118,7 @@ public class CasioGB6900DeviceCoordinator extends AbstractDeviceCoordinator { @Override public int getAlarmSlotCount() { - return 0; // 4 regular and one snooze but not yet implemented + return 5; // 4 regular and one snooze but not yet implemented } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java index d82dc19fc..1d82a4c50 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java @@ -148,7 +148,6 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { mCasioCharacteristics.clear(); mCasioCharacteristics.add(getCharacteristic(CasioGB6900Constants.CASIO_A_NOT_COM_SET_NOT)); mCasioCharacteristics.add(getCharacteristic(CasioGB6900Constants.CASIO_A_NOT_W_REQ_NOT)); - mCasioCharacteristics.add(getCharacteristic(CasioGB6900Constants.FUNCTION_SWITCH_CHARACTERISTIC)); mCasioCharacteristics.add(getCharacteristic(CasioGB6900Constants.ALERT_LEVEL_CHARACTERISTIC_UUID)); mCasioCharacteristics.add(getCharacteristic(CasioGB6900Constants.RINGER_CONTROL_POINT)); } @@ -239,8 +238,8 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { LOG.info("Initialization done, setting state to INITIALIZED"); if(mHandlerThread == null) { mHandlerThread = new CasioHandlerThread(getDevice(), getContext(), this); - mHandlerThread.start(); } + mHandlerThread.start(); gbDevice.setState(GBDevice.State.INITIALIZED); gbDevice.sendDeviceUpdateIntent(getContext()); handled = true; @@ -445,7 +444,30 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onSetAlarms(ArrayList alarms) { - + int alarmOffset = 4; + byte[] data = new byte[20]; + for(int i=0; i Date: Mon, 28 Jan 2019 20:25:32 +0100 Subject: [PATCH 2/5] Improve find device service (now always beeps) --- .../devices/casiogb6900/CasioGB6900Constants.java | 4 ++++ .../casiogb6900/CasioGB6900DeviceSupport.java | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java index 52fc0ea49..b2b97d738 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java @@ -29,6 +29,10 @@ public final class CasioGB6900Constants { public static final UUID CCC_DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); + // Immediate Alert + + public static final UUID IMMEDIATE_ALERT_SERVICE_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb"); + // Alert public static final UUID ALERT_SERVICE_UUID = UUID.fromString("26eb0000-b012-49a8-b1f8-394fb2032b0f"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java index 1d82a4c50..7870e0f5b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java @@ -74,6 +74,7 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { addSupportedService(CasioGB6900Constants.MORE_ALERT_SERVICE_UUID); addSupportedService(CasioGB6900Constants.TX_POWER_SERVICE_UUID); addSupportedService(CasioGB6900Constants.LINK_LOSS_SERVICE); + addSupportedService(CasioGB6900Constants.IMMEDIATE_ALERT_SERVICE_UUID); mThread = new CasioGATTThread(getContext(), this); } @@ -605,7 +606,18 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { @Override public void onFindDevice(boolean start) { if(start) { - showNotification(CasioGB6900Constants.SNS_NOTIFICATION_ID, "You found it!", ""); + try { + TransactionBuilder builder = performInitialized("findDevice"); + byte value[] = new byte[]{GattCharacteristic.HIGH_ALERT}; + + BluetoothGattService service = mBtGatt.getService(CasioGB6900Constants.IMMEDIATE_ALERT_SERVICE_UUID); + BluetoothGattCharacteristic charact = service.getCharacteristic(CasioGB6900Constants.ALERT_LEVEL_CHARACTERISTIC_UUID); + builder.write(charact, value); + LOG.info("onFindDevice sent"); + builder.queue(getQueue()); + } catch (IOException e) { + LOG.warn("showNotification failed: " + e.getMessage()); + } } } From fc17dec87b08ec5415c8f46a1936cbb426a8697f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20B=C3=B6hler?= Date: Mon, 28 Jan 2019 20:26:02 +0100 Subject: [PATCH 3/5] Add explicit support for GB-6900B, GB-X6900B and GB-5600B --- .../casiogb6900/CasioGB6900Constants.java | 6 ++- .../devices/casiogb6900/CasioGATTServer.java | 54 +++++++++++++++---- .../casiogb6900/CasioGB6900DeviceSupport.java | 15 ++++++ 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java index b2b97d738..b701a6f0b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java @@ -88,5 +88,9 @@ public final class CasioGB6900Constants { public static final byte SNS_NOTIFICATION_ID = 13; public static final byte SMS_NOTIFICATION_ID = 5; - + public enum Model { + MODEL_CASIO_GENERIC, + MODEL_CASIO_6900B, + MODEL_CASIO_5600B + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGATTServer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGATTServer.java index 75ab2a7f1..4515f2553 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGATTServer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGATTServer.java @@ -101,6 +101,40 @@ class CasioGATTServer extends BluetoothGattServerCallback { LOG.warn("error sending response"); } } + private GBDeviceEventMusicControl.Event parse3Button(int button) { + GBDeviceEventMusicControl.Event event; + switch(button) { + case 3: + event = GBDeviceEventMusicControl.Event.NEXT; + break; + case 2: + event = GBDeviceEventMusicControl.Event.PREVIOUS; + break; + case 1: + event = GBDeviceEventMusicControl.Event.PLAYPAUSE; + break; + default: + LOG.warn("Unhandled button received: " + button); + event = GBDeviceEventMusicControl.Event.UNKNOWN; + } + return event; + } + + private GBDeviceEventMusicControl.Event parse2Button(int button) { + GBDeviceEventMusicControl.Event event; + switch(button) { + case 2: + event = GBDeviceEventMusicControl.Event.PLAYPAUSE; + break; + case 1: + event = GBDeviceEventMusicControl.Event.NEXT; + break; + default: + LOG.warn("Unhandled button received: " + button); + event = GBDeviceEventMusicControl.Event.UNKNOWN; + } + return event; + } @Override public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, @@ -119,21 +153,23 @@ class CasioGATTServer extends BluetoothGattServerCallback { if((value[0] & 0x03) == 0) { int button = value[1] & 0x0f; LOG.info("Button pressed: " + button); - switch(button) { - case 3: - musicCmd.event = GBDeviceEventMusicControl.Event.NEXT; + switch(mDeviceSupport.getModel()) + { + case MODEL_CASIO_5600B: + musicCmd.event = parse2Button(button); break; - case 2: - musicCmd.event = GBDeviceEventMusicControl.Event.PREVIOUS; + case MODEL_CASIO_6900B: + musicCmd.event = parse3Button(button); break; - case 1: - musicCmd.event = GBDeviceEventMusicControl.Event.PLAYPAUSE; + case MODEL_CASIO_GENERIC: + musicCmd.event = parse3Button(button); break; default: - LOG.warn("Unhandled button received: " + button); + LOG.warn("Unhandled device"); return; } mDeviceSupport.evaluateGBDeviceEvent(musicCmd); + mDeviceSupport.evaluateGBDeviceEvent(musicCmd); } else { LOG.info("received from device: " + value.toString()); @@ -145,7 +181,7 @@ class CasioGATTServer extends BluetoothGattServerCallback { LOG.info("Connection state change for device: " + device.getAddress() + " status = " + status + " newState = " + newState); if (newState == BluetoothGattServer.STATE_DISCONNECTED) { - + LOG.info("CASIO GATT server noticed disconnect."); } if (newState == BluetoothGattServer.STATE_CONNECTED) { GBDevice.State devState = mDeviceSupport.getDevice().getState(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java index 7870e0f5b..7fb879259 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java @@ -60,6 +60,7 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { private MusicSpec mBufferMusicSpec = null; private MusicStateSpec mBufferMusicStateSpec = null; private BluetoothGatt mBtGatt = null; + private CasioGB6900Constants.Model mModel = CasioGB6900Constants.Model.MODEL_CASIO_GENERIC; public CasioGB6900DeviceSupport() { super(LOG); @@ -117,6 +118,16 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { protected TransactionBuilder initializeDevice(TransactionBuilder builder) { LOG.info("Initializing"); + String name = gbDevice.getName(); + + if(name.contains("5600B")) { + mModel = CasioGB6900Constants.Model.MODEL_CASIO_5600B; + } else if(name.contains("6900B")) { + mModel = CasioGB6900Constants.Model.MODEL_CASIO_6900B; + } else { + mModel = CasioGB6900Constants.Model.MODEL_CASIO_GENERIC; + } + gbDevice.setState(GBDevice.State.INITIALIZING); gbDevice.sendDeviceUpdateIntent(getContext()); @@ -133,6 +144,10 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { return builder; } + CasioGB6900Constants.Model getModel() { + return mModel; + } + // FIXME: Replace hardcoded values by configuration private void configureWatch(TransactionBuilder builder) { if (mBtGatt == null) From 9774dbfba9f6c612a3893f3f37d08716616720a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20B=C3=B6hler?= Date: Mon, 28 Jan 2019 20:26:19 +0100 Subject: [PATCH 4/5] Read/write connection parameters and try to improve stability --- .../casiogb6900/CasioGB6900DeviceSupport.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java index 7fb879259..a6650f739 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java @@ -61,6 +61,9 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { private MusicStateSpec mBufferMusicStateSpec = null; private BluetoothGatt mBtGatt = null; private CasioGB6900Constants.Model mModel = CasioGB6900Constants.Model.MODEL_CASIO_GENERIC; + private byte[] mBleSettings = null; + + private static final int mCasioSleepTime = 80; public CasioGB6900DeviceSupport() { super(LOG); @@ -158,6 +161,7 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { BluetoothGattService llService = mBtGatt.getService(CasioGB6900Constants.LINK_LOSS_SERVICE); BluetoothGattCharacteristic charact = llService.getCharacteristic(CasioGB6900Constants.ALERT_LEVEL_CHARACTERISTIC_UUID); builder.write(charact, value); + builder.wait(mCasioSleepTime); } private void addCharacteristics() { @@ -171,6 +175,7 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { public boolean enableNotifications(TransactionBuilder builder, boolean enable) { for(BluetoothGattCharacteristic charact : mCasioCharacteristics) { builder.notify(charact, enable); + builder.wait(mCasioSleepTime); } return true; } @@ -246,6 +251,39 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { } } + private void readBleSettings() { + try { + TransactionBuilder builder = performInitialized("readBleSettings"); + builder.read(getCharacteristic(CasioGB6900Constants.CASIO_SETTING_FOR_BLE_CHARACTERISTIC_UUID)); + builder.queue(getQueue()); + } catch(IOException e) { + LOG.error("Error reading BLE settings: " + e.getMessage()); + } + } + + private void configureBleSettings() { + // These values seem to improve connection stability _on my phone_ + // Maybe they should be configurable? + int slaveLatency = 2; + int connInterval = 300; + + mBleSettings[5] = (byte)(connInterval & 0xff); + mBleSettings[6] = (byte)((connInterval >> 8) & 0xff); + mBleSettings[7] = (byte)(slaveLatency & 0xff); + mBleSettings[8] = (byte)((slaveLatency >> 8) & 0xff); + + mBleSettings[9] = 0; // Setting for Disconnect!? + } + + private void writeBleSettings() { + try { + TransactionBuilder builder = performInitialized("writeBleSettings"); + builder.write(getCharacteristic(CasioGB6900Constants.CASIO_SETTING_FOR_BLE_CHARACTERISTIC_UUID), mBleSettings); + builder.queue(getQueue()); + } catch(IOException e) { + LOG.error("Error writing BLE settings: " + e.getMessage()); + } + } private boolean handleInitResponse(byte data) { boolean handled = false; switch(data) @@ -258,6 +296,7 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { mHandlerThread.start(); gbDevice.setState(GBDevice.State.INITIALIZED); gbDevice.sendDeviceUpdateIntent(getContext()); + readBleSettings(); handled = true; break; default: @@ -352,6 +391,63 @@ public class CasioGB6900DeviceSupport extends AbstractBTLEDeviceSupport { } LOG.info(str); } + else if(characteristicUUID.equals(CasioGB6900Constants.CASIO_SETTING_FOR_BLE_CHARACTERISTIC_UUID)) { + mBleSettings = data; + String str = "Read Casio Setting for BLE: "; + for(int i=0; i> 6) & 0x03; + //LOG.info("Call Alert: " + callAlert); + //int mailAlert = (data[0] >> 2) & 0x03; + //LOG.info("Mail Alert: " + mailAlert); + //int snsAlert = (data[2] >> 4) & 0x03; + //LOG.info("SNS Alert: " + snsAlert); + //int calAlert = (data[1] >> 6) & 0x03; + //LOG.info("Calendart Alert: " + calAlert); + //int otherAlert = (data[0] & 0x03); + //LOG.info("Other Alert: " + otherAlert); + //int vibrationValue = (data[3] & 0x0f); + //LOG.info("Vibration Value: " + vibrationValue); + //int alarmValue = (data[3] >> 4) & 0x0f; + // Vibration pattern; A = 0, B = 1, C = 2 + //LOG.info("Alarm Value: " + alarmValue); + //int animationValue = data[4] & 0x40; + // Length of Alarm, only 2, 5 and 10 possible + //LOG.info("Animation Value: " + animationValue); + // 0 = on + // 64 = off + //int useDisableMtuReqBit = data[4] & 0x08; + // 8 = on + // 0 = off!? + //LOG.info("useDisableMtuReqBit: " + useDisableMtuReqBit); + + //int slaveLatency = ((data[7] & 0xff) | ((data[8] & 0xff) << 8)); + //int connInterval = ((data[5] & 0xff) | ((data[6] & 0xff) << 8)); + //LOG.info("Slave Latency: " + slaveLatency); + //LOG.info("Connection Interval: " + connInterval); + //LOG.info(str); + + configureBleSettings(); + writeBleSettings(); + } else { return super.onCharacteristicRead(gatt, characteristic, status); } From fd68cf455fefcf1397b0a8698438b5ad00626170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20B=C3=B6hler?= Date: Mon, 28 Jan 2019 20:31:03 +0100 Subject: [PATCH 5/5] Fix misleading comment --- .../devices/casiogb6900/CasioGB6900DeviceCoordinator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java index ae44233e0..296ca4505 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java @@ -118,7 +118,7 @@ public class CasioGB6900DeviceCoordinator extends AbstractDeviceCoordinator { @Override public int getAlarmSlotCount() { - return 5; // 4 regular and one snooze but not yet implemented + return 5; // 4 regular and one snooze } @Override