mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-26 02:25:50 +01:00
Zepp OS: Fix AGPS uploads
Regression introduced by 34fd18885a
- UIHH upload is needed for AGPS
updates on older devices.
This commit is contained in:
parent
2a377ba5ab
commit
944e0d92a7
@ -28,12 +28,15 @@ import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.CRC32;
|
||||
@ -43,10 +46,13 @@ import java.util.zip.ZipFile;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.UIHHContainer;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.CheckSums;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBZipFile;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.ZipFileException;
|
||||
|
||||
public class ZeppOsFwHelper {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ZeppOsFwHelper.class);
|
||||
@ -106,7 +112,7 @@ public class ZeppOsFwHelper {
|
||||
zpkCacheDir.mkdir();
|
||||
|
||||
try {
|
||||
file = File.createTempFile("fwhelper","bin", context.getCacheDir());
|
||||
file = File.createTempFile("fwhelper", "bin", context.getCacheDir());
|
||||
file.deleteOnExit();
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to create temp file for zpk", e);
|
||||
@ -136,6 +142,12 @@ public class ZeppOsFwHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
final byte[] header = getHeader(file, 4);
|
||||
if (header == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Arrays.equals(header, GBZipFile.ZIP_HEADER)) {
|
||||
try (ZipFile zipFile = new ZipFile(file, java.util.zip.ZipFile.OPEN_READ)) {
|
||||
processZipFile(zipFile);
|
||||
} catch (final ZipException e) {
|
||||
@ -143,8 +155,64 @@ public class ZeppOsFwHelper {
|
||||
} catch (final IOException e) {
|
||||
LOG.warn("Error while processing {}", uri, e);
|
||||
}
|
||||
} else if (Arrays.equals(header, UIHHContainer.UIHH_HEADER)) {
|
||||
// FIXME: This should be refactored to avoid pulling the entire file to memory
|
||||
// However, it's currently only used for agps updates, which are usually just ~140KB
|
||||
try (InputStream in = new BufferedInputStream(uriHelper.openInputStream())) {
|
||||
final byte[] fullFile = FileUtils.readAll(in, 32 * 1024 * 1024); // 32MB
|
||||
processAsUihh(fullFile);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to read full uihh from file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO process as UIHH
|
||||
private void processAsUihh(byte[] bytes) {
|
||||
final UIHHContainer uihh = UIHHContainer.fromRawBytes(bytes);
|
||||
if (uihh == null) {
|
||||
LOG.warn("Invalid UIHH file");
|
||||
return;
|
||||
}
|
||||
|
||||
final Set<UIHHContainer.FileType> agpsEpoTypes = new HashSet<>();
|
||||
UIHHContainer.FileEntry uihhFirmwareZipFile = null;
|
||||
boolean hasChangelog = false;
|
||||
for (final UIHHContainer.FileEntry file : uihh.getFiles()) {
|
||||
switch (file.getType()) {
|
||||
case FIRMWARE_ZIP:
|
||||
uihhFirmwareZipFile = file;
|
||||
continue;
|
||||
case FIRMWARE_CHANGELOG:
|
||||
hasChangelog = true;
|
||||
continue;
|
||||
case AGPS_EPO_GR_3:
|
||||
case AGPS_EPO_GAL_7:
|
||||
case AGPS_EPO_BDS_3:
|
||||
agpsEpoTypes.add(file.getType());
|
||||
continue;
|
||||
default:
|
||||
LOG.warn("Unexpected file for {}", file.getType());
|
||||
}
|
||||
}
|
||||
|
||||
if (uihhFirmwareZipFile != null && hasChangelog) {
|
||||
// UIHH firmware update
|
||||
final GBZipFile zipFile = new GBZipFile(uihhFirmwareZipFile.getContent());
|
||||
final byte[] firmwareBin;
|
||||
try {
|
||||
firmwareBin = zipFile.getFileFromZip("META/firmware.bin");
|
||||
} catch (final ZipFileException e) {
|
||||
LOG.error("Failed to read zip from UIHH", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCompatibleFirmwareBin(firmwareBin)) {
|
||||
firmwareType = HuamiFirmwareType.FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG;
|
||||
}
|
||||
} else if (agpsEpoTypes.size() == 3) {
|
||||
// AGPS EPO update
|
||||
firmwareType = HuamiFirmwareType.AGPS_UIHH;
|
||||
}
|
||||
}
|
||||
|
||||
private void processZipFile(final ZipFile zipFile) {
|
||||
@ -252,7 +320,7 @@ public class ZeppOsFwHelper {
|
||||
|
||||
final File zpkFile;
|
||||
try {
|
||||
zpkFile = File.createTempFile("zpk","zip", context.getCacheDir());
|
||||
zpkFile = File.createTempFile("zpk", "zip", context.getCacheDir());
|
||||
zpkFile.deleteOnExit();
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to create temp file for zpk", e);
|
||||
@ -432,6 +500,23 @@ public class ZeppOsFwHelper {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static byte[] getHeader(final File file, final int bytes) {
|
||||
final byte[] header = new byte[bytes];
|
||||
|
||||
try (InputStream is = new FileInputStream(file)) {
|
||||
if (is.read(header) != header.length) {
|
||||
LOG.warn("Read unexpected number of header bytes");
|
||||
return null;
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Error while reading header bytes", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
public static boolean searchString(final byte[] fwBytes, final String str) {
|
||||
final byte[] strBytes = (str + "\0").getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
|
@ -642,11 +642,13 @@ public final class ZeppOsSupport extends HuamiSupport implements ZeppOsFileTrans
|
||||
return;
|
||||
}
|
||||
|
||||
new ZeppOsFirmwareUpdateOperation(Uri.parse(uihhFile.toURI().toString()), this).perform();
|
||||
new ZeppOsFirmwareUpdateOperation(
|
||||
Uri.parse(uihhFile.toURI().toString()),
|
||||
this
|
||||
).perform();
|
||||
}
|
||||
|
||||
} catch (final Exception e) {
|
||||
GB.toast(getContext(), "AGPS file cannot be installed: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
GB.toast(getContext(), "AGPS install error: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -661,14 +663,16 @@ public final class ZeppOsSupport extends HuamiSupport implements ZeppOsFileTrans
|
||||
fileTransferService
|
||||
).perform();
|
||||
} catch (final Exception e) {
|
||||
GB.toast(getContext(), "Gpx route file cannot be installed: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
GB.toast(getContext(), "Gpx install error: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
new ZeppOsFirmwareUpdateOperation(uri, this).perform();
|
||||
} catch (final IOException ex) {
|
||||
GB.toast(getContext(), "Firmware cannot be installed: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
|
||||
GB.toast(getContext(), "Firmware install error: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user