mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-11 09:31:59 +01:00
Zepp OS: Improve firmware upgrades
This commit is contained in:
parent
e6411b15ab
commit
cadcfb787a
@ -25,11 +25,13 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
@ -83,9 +85,7 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
||||
final byte[] firmwareBin = getFileFromZip(uihhFirmwareZipFile.getContent(), "META/firmware.bin");
|
||||
|
||||
if (isCompatibleFirmwareBin(firmwareBin)) {
|
||||
// TODO: Firmware upgrades with UIHH files are untested, so they are disabled
|
||||
return HuamiFirmwareType.INVALID;
|
||||
//return HuamiFirmwareType.FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG;
|
||||
return HuamiFirmwareType.FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG;
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,6 +147,34 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Huami2021FirmwareInfo repackFirmwareInUIHH() throws IOException {
|
||||
if (!firmwareType.equals(HuamiFirmwareType.FIRMWARE)) {
|
||||
throw new IllegalStateException("Can only repack FIRMWARE");
|
||||
}
|
||||
|
||||
final UIHHContainer uihh = packFirmwareInUIHH();
|
||||
|
||||
try {
|
||||
final Constructor<? extends Huami2021FirmwareInfo> constructor = this.getClass().getConstructor(byte[].class);
|
||||
return constructor.newInstance((Object) uihh.toRawBytes());
|
||||
} catch (final Exception e) {
|
||||
throw new IOException("Failed to construct new " + getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private UIHHContainer packFirmwareInUIHH() {
|
||||
final UIHHContainer uihh = new UIHHContainer();
|
||||
final byte[] timestampBytes = BLETypeConversions.fromUint32((int) (System.currentTimeMillis() / 1000L));
|
||||
final String changelogText = "Unknown changelog";
|
||||
final byte[] changelogBytes = BLETypeConversions.join(
|
||||
timestampBytes,
|
||||
changelogText.getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
uihh.addFile(UIHHContainer.FileType.FIRMWARE_ZIP, getBytes());
|
||||
uihh.addFile(UIHHContainer.FileType.FIRMWARE_CHANGELOG, changelogBytes);
|
||||
return uihh;
|
||||
}
|
||||
|
||||
private boolean isCompatibleFirmwareBin(final byte[] firmwareBin) {
|
||||
if (firmwareBin == null) {
|
||||
return false;
|
||||
|
@ -33,6 +33,7 @@ public class MiBand7FirmwareInfo extends Huami2021FirmwareInfo {
|
||||
private static final Map<Integer, String> crcToVersion = new HashMap<Integer, String>() {{
|
||||
// firmware
|
||||
put(26036, "1.20.3.1");
|
||||
put(55449, "1.27.0.4");
|
||||
}};
|
||||
|
||||
public MiBand7FirmwareInfo(final byte[] bytes) {
|
||||
|
@ -150,30 +150,7 @@ public class UpdateFirmwareOperation2020 extends UpdateFirmwareOperation {
|
||||
builder.add(new SetDeviceBusyAction(getDevice(), getContext().getString(R.string.updating_firmware), getContext()));
|
||||
int fwSize = getFirmwareInfo().getSize();
|
||||
byte[] sizeBytes = BLETypeConversions.fromUint32(fwSize);
|
||||
int crc32 = firmwareInfo.getCrc32();
|
||||
byte[] chunkSizeBytes = BLETypeConversions.fromUint16(mChunkLength);
|
||||
byte[] crcBytes = BLETypeConversions.fromUint32(crc32);
|
||||
byte[] bytes = new byte[]{
|
||||
COMMAND_SEND_FIRMWARE_INFO,
|
||||
getFirmwareInfo().getFirmwareType().getValue(),
|
||||
sizeBytes[0],
|
||||
sizeBytes[1],
|
||||
sizeBytes[2],
|
||||
sizeBytes[3],
|
||||
crcBytes[0],
|
||||
crcBytes[1],
|
||||
crcBytes[2],
|
||||
crcBytes[3],
|
||||
chunkSizeBytes[0],
|
||||
chunkSizeBytes[1],
|
||||
0, // ??
|
||||
0, // index
|
||||
1, // count
|
||||
sizeBytes[0], // total size? right now it is equal to the size above
|
||||
sizeBytes[1],
|
||||
sizeBytes[2],
|
||||
sizeBytes[3]
|
||||
};
|
||||
byte[] bytes = buildFirmwareInfoCommand();
|
||||
|
||||
if (getFirmwareInfo().getFirmwareType() == HuamiFirmwareType.WATCHFACE) {
|
||||
byte[] fwBytes = firmwareInfo.getBytes();
|
||||
@ -200,6 +177,34 @@ public class UpdateFirmwareOperation2020 extends UpdateFirmwareOperation {
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] buildFirmwareInfoCommand() {
|
||||
int fwSize = getFirmwareInfo().getSize();
|
||||
byte[] sizeBytes = BLETypeConversions.fromUint32(fwSize);
|
||||
int crc32 = firmwareInfo.getCrc32();
|
||||
byte[] chunkSizeBytes = BLETypeConversions.fromUint16(mChunkLength);
|
||||
byte[] crcBytes = BLETypeConversions.fromUint32(crc32);
|
||||
return new byte[]{
|
||||
COMMAND_SEND_FIRMWARE_INFO,
|
||||
getFirmwareInfo().getFirmwareType().getValue(),
|
||||
sizeBytes[0],
|
||||
sizeBytes[1],
|
||||
sizeBytes[2],
|
||||
sizeBytes[3],
|
||||
crcBytes[0],
|
||||
crcBytes[1],
|
||||
crcBytes[2],
|
||||
crcBytes[3],
|
||||
chunkSizeBytes[0],
|
||||
chunkSizeBytes[1],
|
||||
0, // 0 to update in foreground, 1 for background
|
||||
0, // index
|
||||
1, // count
|
||||
sizeBytes[0], // total size? right now it is equal to the size above
|
||||
sizeBytes[1],
|
||||
sizeBytes[2],
|
||||
sizeBytes[3]
|
||||
};
|
||||
}
|
||||
|
||||
public boolean requestParameters() {
|
||||
try {
|
||||
|
@ -16,6 +16,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@ -24,7 +25,9 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.IOException;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiFirmwareInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||
@ -42,6 +45,28 @@ public class UpdateFirmwareOperation2021 extends UpdateFirmwareOperation2020 {
|
||||
builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_CHUNKEDTRANSFER_2021_READ), enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
AbstractHuamiFirmwareInfo createFwInfo(final Uri uri, final Context context) throws IOException {
|
||||
return super.createFwInfo(uri, context);
|
||||
|
||||
/* This does not actually seem to be needed, but it's what the official app does
|
||||
final HuamiFWHelper fwHelper = getSupport().createFWHelper(uri, context);
|
||||
final AbstractHuamiFirmwareInfo firmwareInfo = fwHelper.getFirmwareInfo();
|
||||
|
||||
if (!(firmwareInfo instanceof Huami2021FirmwareInfo)) {
|
||||
throw new IllegalArgumentException("Firmware not Huami2021FirmwareInfo");
|
||||
}
|
||||
|
||||
final Huami2021FirmwareInfo firmwareInfo2021 = (Huami2021FirmwareInfo) firmwareInfo;
|
||||
if (firmwareInfo2021.getFirmwareType() == HuamiFirmwareType.FIRMWARE) {
|
||||
// This does not actually seem to be needed, but it's what the official app does
|
||||
return firmwareInfo2021.repackFirmwareInUIHH();
|
||||
}
|
||||
|
||||
return firmwareInfo;
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleNotificationNotif(byte[] value) {
|
||||
super.handleNotificationNotif(value);
|
||||
@ -59,4 +84,31 @@ public class UpdateFirmwareOperation2021 extends UpdateFirmwareOperation2020 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] buildFirmwareInfoCommand() {
|
||||
final int fwSize = firmwareInfo.getSize();
|
||||
final int crc32 = firmwareInfo.getCrc32();
|
||||
|
||||
final byte[] sizeBytes = BLETypeConversions.fromUint32(fwSize);
|
||||
final byte[] chunkSizeBytes = BLETypeConversions.fromUint16(mChunkLength);
|
||||
final byte[] crcBytes = BLETypeConversions.fromUint32(crc32);
|
||||
|
||||
return new byte[]{
|
||||
COMMAND_SEND_FIRMWARE_INFO,
|
||||
getFirmwareInfo().getFirmwareType().getValue(),
|
||||
sizeBytes[0],
|
||||
sizeBytes[1],
|
||||
sizeBytes[2],
|
||||
sizeBytes[3],
|
||||
crcBytes[0],
|
||||
crcBytes[1],
|
||||
crcBytes[2],
|
||||
crcBytes[3],
|
||||
chunkSizeBytes[0],
|
||||
chunkSizeBytes[1],
|
||||
0, // 0 to update in foreground, 1 for background
|
||||
(byte) 0xff, // ??
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user