From 45c40825f3d4e672b4b2a6c7ecdff5879891dddf Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 26 Dec 2019 23:05:13 +0100 Subject: [PATCH] Mi Band 4: Support MTU that gets reported from the Band In my case that boosts the MTU from 23 to 247, firmware updates and watchface istallations are extremely fast. This also affects notifications, weather etc. --- .../devices/huami/HuamiDeviceEvent.java | 1 + .../service/devices/huami/HuamiSupport.java | 36 ++++++++++++++++--- .../operations/UpdateFirmwareOperation.java | 2 +- 3 files changed, 34 insertions(+), 5 deletions(-) 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 {