From 14f754306d8c9639dff5e63dd2783f7730635147 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Tue, 28 Jul 2015 19:15:25 +0200 Subject: [PATCH] Use a single queue for the whole firmware transfer. At the moment the progress bar code is not useful because the FW preparation is almost instantly done, and is the BT transfer that takes time. The transfer happens when the getQueue method is called, and there is no progress info that I can find. --- .../gadgetbridge/miband/MiBandSupport.java | 112 +++++++----------- 1 file changed, 45 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java index 565abaf2..31b989b4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java @@ -542,9 +542,15 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { int oldFwVersion = mDeviceInfo.getFirmwareVersion(); int checksum = (Integer.decode("0x" + mMacOctets[4]) << 8 | Integer.decode("0x" + mMacOctets[5])) ^ mFwHelper.getCRC16(mFwHelper.getFw()); - sendFirmwareInfo(oldFwVersion, newFwVersion, mFwHelper.getFw().length, checksum); - sendFirmwareData(mFwHelper.getFw()); - onReboot(); + if (sendFirmwareInfo(oldFwVersion, newFwVersion, mFwHelper.getFw().length, checksum)) { + //metadata were sent correctly, send the actual firmware + if(sendFirmwareData(mFwHelper.getFw())) { + //firmware was sent correctly, reboot + onReboot(); + } else { + //TODO: the firmware transfer failed, but the miband should be still functional with the old firmware. What should we do? + } + } return; } @@ -855,7 +861,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { LOG.info("MI Band pairing result: " + value); } - private void sendFirmwareInfo(int currentFwVersion, int newFwVersion, int newFwSize, int checksum) { + private boolean sendFirmwareInfo(int currentFwVersion, int newFwVersion, int newFwSize, int checksum) { byte[] fwInfo = new byte[]{ MiBandService.COMMAND_SEND_FIRMWARE_INFO, (byte) currentFwVersion, @@ -877,10 +883,12 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { builder.queue(getQueue()); } catch (IOException ex) { LOG.error("Unable to send fwInfo to MI", ex); + return false; } + return true; } - private void sendFirmwareData(byte fwbytes[]) { + private boolean sendFirmwareData(byte fwbytes[]) { int len = fwbytes.length; final int packetLength = 20; int packets = len / packetLength; @@ -888,77 +896,47 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { int firmwareProgress = 0; - for (int i = 0; i < packets; i++) { - fwChunk = Arrays.copyOfRange(fwbytes, i * packetLength, i * packetLength + packetLength); - - if (!sendFirmwareChunk(fwChunk)) { - LOG.error("Firmware chunk write failed"); - return; - } - - firmwareProgress += packetLength; - - if ((i > 0) && (i % 50 == 0)) { - if (!sendFirmwareSync()) { - GB.updateInstallNotification("Firmware sync failed", false, 0, getContext()); - LOG.error("Firmware sync failed"); - return; - } - } - GB.updateInstallNotification("Firmware update in progress", true, (firmwareProgress / len) * 100, getContext()); - LOG.info("Firmware update progress:" + firmwareProgress + " total lenL:" + len + " progress:" + firmwareProgress / len); - } - - if (!(len % packetLength == 0)) { - byte lastChunk[] = new byte[len % packetLength]; - lastChunk = Arrays.copyOfRange(fwbytes, packets * packetLength, len); - if (!sendFirmwareChunk(lastChunk)) { - LOG.error("Firmware chunk write failed"); - return; - } - firmwareProgress += len % packetLength; - } - - LOG.info("Firmware update progress:" + firmwareProgress + " total lenL:" + len + " progress:" + firmwareProgress / len); - if (firmwareProgress >= len) { - GB.updateInstallNotification("Firmware installation complete", false, 100, getContext()); - } else { - GB.updateInstallNotification("Firmware update in progress", true, (firmwareProgress / len) * 100, getContext()); - } - - if (!sendFirmwareSync()) { - LOG.error("Firmware sync failed"); - } - - } - - private boolean sendFirmwareChunk(byte fwChunk[]) { try { TransactionBuilder builder = performInitialized("send firmware packet"); - builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_FIRMWARE_DATA), fwChunk); + for (int i = 0; i < packets; i++) { + fwChunk = Arrays.copyOfRange(fwbytes, i * packetLength, i * packetLength + packetLength); + + builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_FIRMWARE_DATA), fwChunk); + firmwareProgress += packetLength; + + if ((i > 0) && (i % 50 == 0)) { + builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), new byte[]{MiBandService.COMMAND_SYNC}); + GB.updateInstallNotification("Firmware update in progress", true, (firmwareProgress / len) * 100, getContext()); + } + + LOG.info("Firmware update progress:" + firmwareProgress + " total len:" + len + " progress:" + (firmwareProgress / len)); + } + + if (!(len % packetLength == 0)) { + byte lastChunk[] = new byte[len % packetLength]; + lastChunk = Arrays.copyOfRange(fwbytes, packets * packetLength, len); + builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_FIRMWARE_DATA), lastChunk); + firmwareProgress += len % packetLength; + } + + LOG.info("Firmware update progress:" + firmwareProgress + " total len:" + len + " progress:" + (firmwareProgress / len)); + if (firmwareProgress >= len) { + builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), new byte[]{MiBandService.COMMAND_SYNC}); + GB.updateInstallNotification("Firmware installation complete", false, 100, getContext()); + } else { + GB.updateInstallNotification("Firmware write failed", false, 0, getContext()); + } + builder.queue(getQueue()); + } catch (IOException ex) { - LOG.error("Unable to send fw packet to MI", ex); - GB.updateInstallNotification("Firmware chunk write failed", false, 0, getContext()); + LOG.error("Unable to send fw to MI", ex); + GB.updateInstallNotification("Firmware write failed", false, 0, getContext()); return false; } return true; } - private boolean sendFirmwareSync() { - try { - TransactionBuilder builder = performInitialized("send firmware sync"); - builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), new byte[]{MiBandService.COMMAND_SYNC}); - builder.queue(getQueue()); - } catch (IOException ex) { - LOG.error("Unable to send firmware sync to MI", ex); - GB.updateInstallNotification("Firmwar sync failed", false, 0, getContext()); - return false; - } - return true; - } - - @Override protected TransactionBuilder createTransactionBuilder(String taskName) { return new MiBandTransactionBuilder(taskName);