mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-26 00:21:45 +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.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
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");
|
final byte[] firmwareBin = getFileFromZip(uihhFirmwareZipFile.getContent(), "META/firmware.bin");
|
||||||
|
|
||||||
if (isCompatibleFirmwareBin(firmwareBin)) {
|
if (isCompatibleFirmwareBin(firmwareBin)) {
|
||||||
// TODO: Firmware upgrades with UIHH files are untested, so they are disabled
|
return HuamiFirmwareType.FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG;
|
||||||
return HuamiFirmwareType.INVALID;
|
|
||||||
//return HuamiFirmwareType.FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +147,34 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
return null;
|
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) {
|
private boolean isCompatibleFirmwareBin(final byte[] firmwareBin) {
|
||||||
if (firmwareBin == null) {
|
if (firmwareBin == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,6 +33,7 @@ public class MiBand7FirmwareInfo extends Huami2021FirmwareInfo {
|
|||||||
private static final Map<Integer, String> crcToVersion = new HashMap<Integer, String>() {{
|
private static final Map<Integer, String> crcToVersion = new HashMap<Integer, String>() {{
|
||||||
// firmware
|
// firmware
|
||||||
put(26036, "1.20.3.1");
|
put(26036, "1.20.3.1");
|
||||||
|
put(55449, "1.27.0.4");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public MiBand7FirmwareInfo(final byte[] bytes) {
|
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()));
|
builder.add(new SetDeviceBusyAction(getDevice(), getContext().getString(R.string.updating_firmware), getContext()));
|
||||||
int fwSize = getFirmwareInfo().getSize();
|
int fwSize = getFirmwareInfo().getSize();
|
||||||
byte[] sizeBytes = BLETypeConversions.fromUint32(fwSize);
|
byte[] sizeBytes = BLETypeConversions.fromUint32(fwSize);
|
||||||
int crc32 = firmwareInfo.getCrc32();
|
byte[] bytes = buildFirmwareInfoCommand();
|
||||||
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]
|
|
||||||
};
|
|
||||||
|
|
||||||
if (getFirmwareInfo().getFirmwareType() == HuamiFirmwareType.WATCHFACE) {
|
if (getFirmwareInfo().getFirmwareType() == HuamiFirmwareType.WATCHFACE) {
|
||||||
byte[] fwBytes = firmwareInfo.getBytes();
|
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() {
|
public boolean requestParameters() {
|
||||||
try {
|
try {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -24,7 +25,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
|
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.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.HuamiFirmwareType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
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);
|
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
|
@Override
|
||||||
protected void handleNotificationNotif(byte[] value) {
|
protected void handleNotificationNotif(byte[] value) {
|
||||||
super.handleNotificationNotif(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