diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java index 415d45ff9..291cb9367 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java @@ -30,5 +30,6 @@ public class HuamiDeviceEvent { public static final byte BUTTON_PRESSED_LONG = 0x0b; public static final byte TICK_30MIN = 0x0e; // unsure public static final byte FIND_PHONE_STOP = 0x0f; + public static final byte MTU_REQUEST = 0x16; public static final byte MUSIC_CONTROL = (byte) 0xfe; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 5af18112f..579fda7b8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -164,7 +164,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { }; private BluetoothGattCharacteristic characteristicHRControlPoint; - protected BluetoothGattCharacteristic characteristicChunked; + private BluetoothGattCharacteristic characteristicChunked; private boolean needsAuth; private volatile boolean telephoneRinging; @@ -181,6 +181,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { private MusicSpec bufferMusicSpec = null; private MusicStateSpec bufferMusicStateSpec = null; private boolean heartRateNotifyEnabled; + private int mMTU = 23; public HuamiSupport() { this(LOG); @@ -293,13 +294,13 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { builder.notify(getCharacteristic(GattService.UUID_SERVICE_CURRENT_TIME), enable); // Notify CHARACTERISTIC9 to receive random auth code builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUTH), enable); + builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT), enable); return this; } public HuamiSupport enableFurtherNotifications(TransactionBuilder builder, boolean enable) { builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), enable); builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO), enable); - builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT), enable); builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUDIO), enable); builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUDIODATA), enable); @@ -1212,11 +1213,34 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } evaluateGBDeviceEvent(deviceEventMusicControl); break; + case HuamiDeviceEvent.MTU_REQUEST: + int mtu = (value[2] & 0xff) << 8 | value[1] & 0xff; + LOG.info("device announced MTU of " + mtu); + mMTU = mtu; + /* + * not really sure if this would make sense, is this event already a proof of a successful MTU + * negotiation initiated by the Huami device, and acknowledged by the phone? do we really have to + * requestMTU() from our side after receiving this? + * / + if (mMTU != mtu) { + requestMTU(mtu); + } + */ + break; default: LOG.warn("unhandled event " + value[0]); } } + private void requestMTU(int mtu) { + if (GBApplication.isRunningLollipopOrLater()) { + new TransactionBuilder("requestMtu") + .requestMtu(mtu) + .queue(getQueue()); + mMTU = mtu; + } + } + private void acknowledgeFindPhone() { try { TransactionBuilder builder = performInitialized("acknowledge find phone"); @@ -2174,8 +2198,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } - protected void writeToChunked(TransactionBuilder builder, int type, byte[] data) { - final int MAX_CHUNKLENGTH = 17; + private void writeToChunked(TransactionBuilder builder, int type, byte[] data) { + final int MAX_CHUNKLENGTH = mMTU - 6; int remaining = data.length; byte count = 0; while (remaining > 0) { @@ -2275,4 +2299,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { public UpdateFirmwareOperation createUpdateFirmwareOperation(Uri uri) { return new UpdateFirmwareOperation(uri, this); } + + public int getMTU() { + return mMTU; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java index 07ca209cd..5b9179101 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java @@ -232,7 +232,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { private boolean sendFirmwareData(HuamiFirmwareInfo info) { byte[] fwbytes = info.getBytes(); int len = fwbytes.length; - final int packetLength = 20; + final int packetLength = getSupport().getMTU() - 3; int packets = len / packetLength; try {