mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-26 18:45:49 +01:00
Amazfit GTR 4: Fix and whitelist firmware 3.17.0.2
This commit is contained in:
parent
a1f58cff39
commit
1c93ffc3e5
@ -16,6 +16,9 @@
|
|||||||
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.devices.huami;
|
package nodomain.freeyourgadget.gadgetbridge.devices.huami;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
@ -37,11 +40,15 @@ import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuamiExtendedActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.HuamiExtendedActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsConfigService;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsConfigService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiLanguageType;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiLanguageType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType;
|
||||||
|
|
||||||
public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
||||||
|
@Override
|
||||||
|
public abstract AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsHeartRateMeasurement(final GBDevice device) {
|
public boolean supportsHeartRateMeasurement(final GBDevice device) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -28,7 +28,6 @@ import nodomain.freeyourgadget.gadgetbridge.R;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiFirmwareInfo;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiFirmwareInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareInfo;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||||
|
|
||||||
public abstract class HuamiFWHelper extends AbstractMiBandFWHelper {
|
public abstract class HuamiFWHelper extends AbstractMiBandFWHelper {
|
||||||
@ -124,6 +123,12 @@ public abstract class HuamiFWHelper extends AbstractMiBandFWHelper {
|
|||||||
return firmwareInfo.getFirmwareType();
|
return firmwareInfo.getFirmwareType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unsetFwBytes() {
|
||||||
|
super.unsetFwBytes();
|
||||||
|
firmwareInfo.unsetFwBytes();
|
||||||
|
}
|
||||||
|
|
||||||
public AbstractHuamiFirmwareInfo getFirmwareInfo() {
|
public AbstractHuamiFirmwareInfo getFirmwareInfo() {
|
||||||
return firmwareInfo;
|
return firmwareInfo;
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ import androidx.annotation.NonNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
public class AmazfitBand7Coordinator extends Huami2021Coordinator {
|
public class AmazfitBand7Coordinator extends Huami2021Coordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitBand7Coordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AmazfitBand7Coordinator.class);
|
||||||
@ -56,7 +56,7 @@ public class AmazfitBand7Coordinator extends Huami2021Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||||
final AmazfitBand7FWInstallHandler handler = new AmazfitBand7FWInstallHandler(uri, context);
|
final AmazfitBand7FWInstallHandler handler = new AmazfitBand7FWInstallHandler(uri, context);
|
||||||
return handler.isValid() ? handler : null;
|
return handler.isValid() ? handler : null;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
class AmazfitBand7FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
class AmazfitBand7FWInstallHandler extends AbstractHuami2021FWInstallHandler {
|
||||||
AmazfitBand7FWInstallHandler(final Uri uri, final Context context) {
|
AmazfitBand7FWInstallHandler(final Uri uri, final Context context) {
|
||||||
super(uri, context);
|
super(uri, context);
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ import androidx.annotation.NonNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
public class AmazfitGTR3Coordinator extends Huami2021Coordinator {
|
public class AmazfitGTR3Coordinator extends Huami2021Coordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTR3Coordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTR3Coordinator.class);
|
||||||
@ -56,7 +56,7 @@ public class AmazfitGTR3Coordinator extends Huami2021Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||||
final AmazfitGTR3FWInstallHandler handler = new AmazfitGTR3FWInstallHandler(uri, context);
|
final AmazfitGTR3FWInstallHandler handler = new AmazfitGTR3FWInstallHandler(uri, context);
|
||||||
return handler.isValid() ? handler : null;
|
return handler.isValid() ? handler : null;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
class AmazfitGTR3FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
class AmazfitGTR3FWInstallHandler extends AbstractHuami2021FWInstallHandler {
|
||||||
AmazfitGTR3FWInstallHandler(Uri uri, Context context) {
|
AmazfitGTR3FWInstallHandler(Uri uri, Context context) {
|
||||||
super(uri, context);
|
super(uri, context);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
public class AmazfitGTR4Coordinator extends Huami2021Coordinator {
|
public class AmazfitGTR4Coordinator extends Huami2021Coordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTR4Coordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTR4Coordinator.class);
|
||||||
@ -56,7 +57,7 @@ public class AmazfitGTR4Coordinator extends Huami2021Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||||
final AmazfitGTR4FWInstallHandler handler = new AmazfitGTR4FWInstallHandler(uri, context);
|
final AmazfitGTR4FWInstallHandler handler = new AmazfitGTR4FWInstallHandler(uri, context);
|
||||||
return handler.isValid() ? handler : null;
|
return handler.isValid() ? handler : null;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
class AmazfitGTR4FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
class AmazfitGTR4FWInstallHandler extends AbstractHuami2021FWInstallHandler {
|
||||||
AmazfitGTR4FWInstallHandler(final Uri uri, final Context context) {
|
AmazfitGTR4FWInstallHandler(final Uri uri, final Context context) {
|
||||||
super(uri, context);
|
super(uri, context);
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ import androidx.annotation.NonNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
public class AmazfitGTS3Coordinator extends Huami2021Coordinator {
|
public class AmazfitGTS3Coordinator extends Huami2021Coordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTS3Coordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTS3Coordinator.class);
|
||||||
@ -56,7 +56,7 @@ public class AmazfitGTS3Coordinator extends Huami2021Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||||
final AmazfitGTS3FWInstallHandler handler = new AmazfitGTS3FWInstallHandler(uri, context);
|
final AmazfitGTS3FWInstallHandler handler = new AmazfitGTS3FWInstallHandler(uri, context);
|
||||||
return handler.isValid() ? handler : null;
|
return handler.isValid() ? handler : null;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
class AmazfitGTS3FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
class AmazfitGTS3FWInstallHandler extends AbstractHuami2021FWInstallHandler {
|
||||||
AmazfitGTS3FWInstallHandler(Uri uri, Context context) {
|
AmazfitGTS3FWInstallHandler(Uri uri, Context context) {
|
||||||
super(uri, context);
|
super(uri, context);
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ import androidx.annotation.NonNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
public class AmazfitGTS4Coordinator extends Huami2021Coordinator {
|
public class AmazfitGTS4Coordinator extends Huami2021Coordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTS4Coordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTS4Coordinator.class);
|
||||||
@ -56,7 +56,7 @@ public class AmazfitGTS4Coordinator extends Huami2021Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||||
final AmazfitGTS4FWInstallHandler handler = new AmazfitGTS4FWInstallHandler(uri, context);
|
final AmazfitGTS4FWInstallHandler handler = new AmazfitGTS4FWInstallHandler(uri, context);
|
||||||
return handler.isValid() ? handler : null;
|
return handler.isValid() ? handler : null;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
class AmazfitGTS4FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
class AmazfitGTS4FWInstallHandler extends AbstractHuami2021FWInstallHandler {
|
||||||
AmazfitGTS4FWInstallHandler(final Uri uri, final Context context) {
|
AmazfitGTS4FWInstallHandler(final Uri uri, final Context context) {
|
||||||
super(uri, context);
|
super(uri, context);
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ import androidx.annotation.NonNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
public class MiBand7Coordinator extends Huami2021Coordinator {
|
public class MiBand7Coordinator extends Huami2021Coordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(MiBand7Coordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(MiBand7Coordinator.class);
|
||||||
@ -56,7 +56,7 @@ public class MiBand7Coordinator extends Huami2021Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||||
final MiBand7FWInstallHandler handler = new MiBand7FWInstallHandler(uri, context);
|
final MiBand7FWInstallHandler handler = new MiBand7FWInstallHandler(uri, context);
|
||||||
return handler.isValid() ? handler : null;
|
return handler.isValid() ? handler : null;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||||
|
|
||||||
class MiBand7FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
class MiBand7FWInstallHandler extends AbstractHuami2021FWInstallHandler {
|
||||||
MiBand7FWInstallHandler(Uri uri, Context context) {
|
MiBand7FWInstallHandler(Uri uri, Context context) {
|
||||||
super(uri, context);
|
super(uri, context);
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
|
|||||||
public abstract class AbstractMiBandFWHelper {
|
public abstract class AbstractMiBandFWHelper {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractMiBandFWHelper.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AbstractMiBandFWHelper.class);
|
||||||
|
|
||||||
@NonNull
|
private byte[] fw;
|
||||||
private final byte[] fw;
|
|
||||||
|
|
||||||
public AbstractMiBandFWHelper(Uri uri, Context context) throws IOException {
|
public AbstractMiBandFWHelper(Uri uri, Context context) throws IOException {
|
||||||
UriHelper uriHelper = UriHelper.get(uri, context);
|
UriHelper uriHelper = UriHelper.get(uri, context);
|
||||||
@ -104,9 +103,17 @@ public abstract class AbstractMiBandFWHelper {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public byte[] getFw() {
|
public byte[] getFw() {
|
||||||
|
if (fw == null) {
|
||||||
|
throw new IllegalStateException("fw is null");
|
||||||
|
}
|
||||||
|
|
||||||
return fw;
|
return fw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void unsetFwBytes() {
|
||||||
|
this.fw = null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isFirmwareWhitelisted() {
|
public boolean isFirmwareWhitelisted() {
|
||||||
for (int wlf : getWhitelistedFirmwareVersions()) {
|
for (int wlf : getWhitelistedFirmwareVersions()) {
|
||||||
if (wlf == getFirmwareVersion()) {
|
if (wlf == getFirmwareVersion()) {
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/* Copyright (C) 2022 José Rebelo
|
||||||
|
|
||||||
|
This file is part of Gadgetbridge.
|
||||||
|
|
||||||
|
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Gadgetbridge is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
|
||||||
|
public abstract class AbstractHuami2021FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
||||||
|
public AbstractHuami2021FWInstallHandler(final Uri uri, final Context context) {
|
||||||
|
super(uri, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartInstall(GBDevice device) {
|
||||||
|
// Unset the firmware bytes
|
||||||
|
// Huami2021 firmwares are large (> 130MB). With the current architecture, the update operation
|
||||||
|
// will re-read them to memory, and we run out-of-memory.
|
||||||
|
helper.unsetFwBytes();
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.util.CheckSums;
|
import nodomain.freeyourgadget.gadgetbridge.util.CheckSums;
|
||||||
|
|
||||||
public abstract class AbstractHuamiFirmwareInfo {
|
public abstract class AbstractHuamiFirmwareInfo {
|
||||||
private final byte[] bytes;
|
private byte[] bytes;
|
||||||
|
|
||||||
private final int crc16;
|
private final int crc16;
|
||||||
private final int crc32;
|
private final int crc32;
|
||||||
@ -78,6 +78,10 @@ public abstract class AbstractHuamiFirmwareInfo {
|
|||||||
return firmwareType;
|
return firmwareType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void unsetFwBytes() {
|
||||||
|
this.bytes = null;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String toVersion(int crc16);
|
public abstract String toVersion(int crc16);
|
||||||
|
|
||||||
public abstract boolean isGenerallyCompatibleWith(GBDevice device);
|
public abstract boolean isGenerallyCompatibleWith(GBDevice device);
|
||||||
|
@ -28,15 +28,18 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
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.ZipFile;
|
import nodomain.freeyourgadget.gadgetbridge.util.ZipFile;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.ZipFileException;
|
||||||
|
|
||||||
|
|
||||||
public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Huami2021FirmwareInfo.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Huami2021FirmwareInfo.class);
|
||||||
|
|
||||||
|
private final String preComputedVersion;
|
||||||
|
|
||||||
public Huami2021FirmwareInfo(final byte[] bytes) {
|
public Huami2021FirmwareInfo(final byte[] bytes) {
|
||||||
super(bytes);
|
super(bytes);
|
||||||
|
this.preComputedVersion = preComputeVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,11 +47,6 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
*/
|
*/
|
||||||
public abstract String deviceName();
|
public abstract String deviceName();
|
||||||
|
|
||||||
/**
|
|
||||||
* The expected firmware header bytes, to search on firmware.bin in order to determine compatibility.
|
|
||||||
*/
|
|
||||||
public abstract byte[] getExpectedFirmwareHeader();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HuamiFirmwareType determineFirmwareType(final byte[] bytes) {
|
protected HuamiFirmwareType determineFirmwareType(final byte[] bytes) {
|
||||||
if (ArrayUtils.equals(bytes, UIHHContainer.UIHH_HEADER, 0)) {
|
if (ArrayUtils.equals(bytes, UIHHContainer.UIHH_HEADER, 0)) {
|
||||||
@ -83,7 +81,14 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (uihhFirmwareZipFile != null && hasChangelog) {
|
if (uihhFirmwareZipFile != null && hasChangelog) {
|
||||||
byte[] firmwareBin = ZipFile.tryReadFileQuick(uihhFirmwareZipFile.getContent(), "META/firmware.bin");
|
final ZipFile zipFile = new ZipFile(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 HuamiFirmwareType.INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
if (isCompatibleFirmwareBin(firmwareBin)) {
|
if (isCompatibleFirmwareBin(firmwareBin)) {
|
||||||
return HuamiFirmwareType.FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG;
|
return HuamiFirmwareType.FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG;
|
||||||
@ -94,12 +99,32 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private HuamiFirmwareType handleZipPackage(byte[] bytes) {
|
private HuamiFirmwareType handleZipPackage(byte[] bytes) {
|
||||||
final byte[] firmwareBin = ZipFile.tryReadFileQuick(bytes, "META/firmware.bin");
|
final ZipFile zipFile = new ZipFile(bytes);
|
||||||
|
final byte[] firmwareBin;
|
||||||
|
try {
|
||||||
|
firmwareBin = zipFile.getFileFromZip("META/firmware.bin");
|
||||||
|
} catch (final ZipFileException e) {
|
||||||
|
LOG.error("Failed to get firmware.bin from zip file", e);
|
||||||
|
return HuamiFirmwareType.FIRMWARE;
|
||||||
|
}
|
||||||
|
|
||||||
if (isCompatibleFirmwareBin(firmwareBin)) {
|
if (isCompatibleFirmwareBin(firmwareBin)) {
|
||||||
return HuamiFirmwareType.FIRMWARE;
|
return HuamiFirmwareType.FIRMWARE;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String appType = getAppType();
|
final JSONObject appJson = getAppJson(zipFile);
|
||||||
|
if (appJson == null) {
|
||||||
|
return HuamiFirmwareType.INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String appType;
|
||||||
|
try {
|
||||||
|
appType = appJson.getJSONObject("app").getString("appType");
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOG.error("Failed to get appType from app.json", e);
|
||||||
|
return HuamiFirmwareType.INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
switch (appType) {
|
switch (appType) {
|
||||||
case "watchface":
|
case "watchface":
|
||||||
return HuamiFirmwareType.WATCHFACE;
|
return HuamiFirmwareType.WATCHFACE;
|
||||||
@ -119,6 +144,11 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
return crcMapVersion;
|
return crcMapVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return preComputedVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String preComputeVersion() {
|
||||||
|
try {
|
||||||
switch (firmwareType) {
|
switch (firmwareType) {
|
||||||
case FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG:
|
case FIRMWARE_UIHH_2021_ZIP_WITH_CHANGELOG:
|
||||||
final UIHHContainer uihh = UIHHContainer.fromRawBytes(getBytes());
|
final UIHHContainer uihh = UIHHContainer.fromRawBytes(getBytes());
|
||||||
@ -129,18 +159,21 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
case FIRMWARE:
|
case FIRMWARE:
|
||||||
return getFirmwareVersion(getBytes());
|
return getFirmwareVersion(getBytes());
|
||||||
case WATCHFACE:
|
case WATCHFACE:
|
||||||
final String watchfaceName = getAppName();
|
final String watchfaceName = getAppName(new ZipFile(getBytes()));
|
||||||
if (watchfaceName == null) {
|
if (watchfaceName == null) {
|
||||||
return "(unknown watchface)";
|
return "(unknown watchface)";
|
||||||
}
|
}
|
||||||
return String.format("%s (watchface)", watchfaceName);
|
return String.format("%s (watchface)", watchfaceName);
|
||||||
case APP:
|
case APP:
|
||||||
final String appName = getAppName();
|
final String appName = getAppName(new ZipFile(getBytes()));
|
||||||
if (appName == null) {
|
if (appName == null) {
|
||||||
return "(unknown app)";
|
return "(unknown app)";
|
||||||
}
|
}
|
||||||
return String.format("%s (app)", appName);
|
return String.format("%s (app)", appName);
|
||||||
}
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOG.error("Failed to pre compute version", e);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -150,7 +183,7 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
throw new IllegalStateException("Can only repack FIRMWARE");
|
throw new IllegalStateException("Can only repack FIRMWARE");
|
||||||
}
|
}
|
||||||
|
|
||||||
final UIHHContainer uihh = packFirmwareInUIHH();
|
final UIHHContainer uihh = packFirmwareInUIHH(getBytes());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Constructor<? extends Huami2021FirmwareInfo> constructor = this.getClass().getConstructor(byte[].class);
|
final Constructor<? extends Huami2021FirmwareInfo> constructor = this.getClass().getConstructor(byte[].class);
|
||||||
@ -160,7 +193,7 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIHHContainer packFirmwareInUIHH() {
|
private static UIHHContainer packFirmwareInUIHH(final byte[] zipBytes) {
|
||||||
final UIHHContainer uihh = new UIHHContainer();
|
final UIHHContainer uihh = new UIHHContainer();
|
||||||
final byte[] timestampBytes = BLETypeConversions.fromUint32((int) (System.currentTimeMillis() / 1000L));
|
final byte[] timestampBytes = BLETypeConversions.fromUint32((int) (System.currentTimeMillis() / 1000L));
|
||||||
final String changelogText = "Unknown changelog";
|
final String changelogText = "Unknown changelog";
|
||||||
@ -168,23 +201,18 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
timestampBytes,
|
timestampBytes,
|
||||||
changelogText.getBytes(StandardCharsets.UTF_8)
|
changelogText.getBytes(StandardCharsets.UTF_8)
|
||||||
);
|
);
|
||||||
uihh.addFile(UIHHContainer.FileType.FIRMWARE_ZIP, getBytes());
|
uihh.addFile(UIHHContainer.FileType.FIRMWARE_ZIP, zipBytes);
|
||||||
uihh.addFile(UIHHContainer.FileType.FIRMWARE_CHANGELOG, changelogBytes);
|
uihh.addFile(UIHHContainer.FileType.FIRMWARE_CHANGELOG, changelogBytes);
|
||||||
return uihh;
|
return uihh;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCompatibleFirmwareBin(final byte[] firmwareBin) {
|
private boolean isCompatibleFirmwareBin(final byte[] firmwareBin) {
|
||||||
if (firmwareBin == null) {
|
if (firmwareBin == null) {
|
||||||
|
LOG.error("firmware bin is null");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ArrayUtils.equals(firmwareBin, getExpectedFirmwareHeader(), 0)) {
|
if (!searchString(firmwareBin, deviceName())) {
|
||||||
LOG.warn("Unexpected firmware header: {}", GB.hexdump(Arrays.copyOfRange(firmwareBin, 0, getExpectedFirmwareHeader().length + 3)));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// On the MB7, this only works for firmwares > 1.8.5.1, not for any older firmware
|
|
||||||
if (!searchString32BitAligned(firmwareBin, deviceName() + "\0")) {
|
|
||||||
LOG.warn("Failed to find {} in fwBytes", deviceName());
|
LOG.warn("Failed to find {} in fwBytes", deviceName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -192,11 +220,13 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFirmwareVersion(final byte[] fwbytes) {
|
public static String getFirmwareVersion(final byte[] fwBytes) {
|
||||||
final byte[] firmwareBin = ZipFile.tryReadFileQuick(fwbytes, "META/firmware.bin");
|
final ZipFile zipFile = new ZipFile(fwBytes);
|
||||||
|
final byte[] firmwareBin;
|
||||||
if (firmwareBin == null) {
|
try {
|
||||||
LOG.warn("Failed to read firmware.bin");
|
firmwareBin = zipFile.getFileFromZip("META/firmware.bin");
|
||||||
|
} catch (final ZipFileException e) {
|
||||||
|
LOG.error("Failed to get firmware.bin from zip", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,34 +255,30 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
return new String(Arrays.copyOfRange(firmwareBin, startIdx, endIdx));
|
return new String(Arrays.copyOfRange(firmwareBin, startIdx, endIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAppName() {
|
public String getAppName(final ZipFile zipFile) {
|
||||||
final byte[] appJsonBin = ZipFile.tryReadFileQuick(getBytes(), "app.json");
|
|
||||||
if (appJsonBin == null) {
|
|
||||||
LOG.warn("Failed to get app.json from zip");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final String appJsonString = new String(appJsonBin, StandardCharsets.UTF_8)
|
|
||||||
// Remove UTF-8 BOM if present
|
|
||||||
.replace("\uFEFF", "");
|
|
||||||
final JSONObject jsonObject = new JSONObject(appJsonString);
|
|
||||||
// TODO check i18n section?
|
// TODO check i18n section?
|
||||||
// TODO Show preview icon?
|
// TODO Show preview icon?
|
||||||
final String appName = jsonObject.getJSONObject("app").getString("appName");
|
|
||||||
|
|
||||||
return String.format("%s", appName);
|
final JSONObject appJson = getAppJson(zipFile);
|
||||||
|
if (appJson == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return appJson.getJSONObject("app").getString("appName");
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
LOG.error("Failed to parse app.json", e);
|
LOG.error("Failed to get appName from app.json", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAppType() {
|
private static JSONObject getAppJson(final ZipFile zipFile) {
|
||||||
final byte[] appJsonBin = ZipFile.tryReadFileQuick(getBytes(), "app.json");
|
final byte[] appJsonBin;
|
||||||
if (appJsonBin == null) {
|
try {
|
||||||
LOG.warn("Failed to get app.json from zip");
|
appJsonBin = zipFile.getFileFromZip("app.json");
|
||||||
|
} catch (final ZipFileException e) {
|
||||||
|
LOG.error("Failed to read app.json", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,12 +286,30 @@ public abstract class Huami2021FirmwareInfo extends AbstractHuamiFirmwareInfo {
|
|||||||
final String appJsonString = new String(appJsonBin, StandardCharsets.UTF_8)
|
final String appJsonString = new String(appJsonBin, StandardCharsets.UTF_8)
|
||||||
// Remove UTF-8 BOM if present
|
// Remove UTF-8 BOM if present
|
||||||
.replace("\uFEFF", "");
|
.replace("\uFEFF", "");
|
||||||
final JSONObject jsonObject = new JSONObject(appJsonString);
|
return new JSONObject(appJsonString);
|
||||||
return jsonObject.getJSONObject("app").getString("appType");
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
LOG.error("Failed to parse app.json", e);
|
LOG.error("Failed to parse app.json", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean searchString(final byte[] fwBytes, final String str) {
|
||||||
|
final byte[] strBytes = (str + "\0").getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
for (int i = 0; i < fwBytes.length - strBytes.length + 1; i++) {
|
||||||
|
boolean found = true;
|
||||||
|
for (int j = 0; j < strBytes.length; j++) {
|
||||||
|
if (fwBytes[i + j] != strBytes[j]) {
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,6 @@ public class AmazfitBand7FirmwareInfo extends Huami2021FirmwareInfo {
|
|||||||
return HuamiConst.AMAZFIT_BAND7_NAME;
|
return HuamiConst.AMAZFIT_BAND7_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getExpectedFirmwareHeader() {
|
|
||||||
return new byte[]{0x51, 0x71};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
||||||
return isHeaderValid() && device.getType() == DeviceType.AMAZFITBAND7;
|
return isHeaderValid() && device.getType() == DeviceType.AMAZFITBAND7;
|
||||||
|
@ -43,11 +43,6 @@ public class AmazfitGTR3FirmwareInfo extends Huami2021FirmwareInfo {
|
|||||||
return HuamiConst.AMAZFIT_GTR3_NAME;
|
return HuamiConst.AMAZFIT_GTR3_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getExpectedFirmwareHeader() {
|
|
||||||
return new byte[]{0x00, 0x00, 0x50}; // Probably bogus, only checked against 2 firmware files
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
||||||
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTR3;
|
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTR3;
|
||||||
|
@ -27,6 +27,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.Huami2021Firmw
|
|||||||
public class AmazfitGTR4FirmwareInfo extends Huami2021FirmwareInfo {
|
public class AmazfitGTR4FirmwareInfo 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(1699, "3.17.0.2");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public AmazfitGTR4FirmwareInfo(final byte[] bytes) {
|
public AmazfitGTR4FirmwareInfo(final byte[] bytes) {
|
||||||
@ -38,11 +39,6 @@ public class AmazfitGTR4FirmwareInfo extends Huami2021FirmwareInfo {
|
|||||||
return HuamiConst.AMAZFIT_GTR4_NAME;
|
return HuamiConst.AMAZFIT_GTR4_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getExpectedFirmwareHeader() {
|
|
||||||
return new byte[]{(byte) 0x51, (byte) 0x71, (byte) 0x9c}; // Probably bogus, only checked against 1 firmware files
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
||||||
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTR4;
|
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTR4;
|
||||||
|
@ -43,11 +43,6 @@ public class AmazfitGTS3FirmwareInfo extends Huami2021FirmwareInfo {
|
|||||||
return HuamiConst.AMAZFIT_GTS3_NAME;
|
return HuamiConst.AMAZFIT_GTS3_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getExpectedFirmwareHeader() {
|
|
||||||
return new byte[]{0x00, 0x00, 0x50}; // Probably bogus, only checked against 2 firmware files
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
||||||
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTS3;
|
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTS3;
|
||||||
|
@ -38,11 +38,6 @@ public class AmazfitGTS4FirmwareInfo extends Huami2021FirmwareInfo {
|
|||||||
return HuamiConst.AMAZFIT_GTS4_NAME;
|
return HuamiConst.AMAZFIT_GTS4_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getExpectedFirmwareHeader() {
|
|
||||||
return new byte[]{(byte) 0x51, (byte) 0x71, (byte) 0x9c}; // Probably bogus, only checked against 1 firmware files
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
||||||
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTS4;
|
return isHeaderValid() && device.getType() == DeviceType.AMAZFITGTS4;
|
||||||
|
@ -43,11 +43,6 @@ public class MiBand7FirmwareInfo extends Huami2021FirmwareInfo {
|
|||||||
return HuamiConst.XIAOMI_SMART_BAND7_NAME;
|
return HuamiConst.XIAOMI_SMART_BAND7_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getExpectedFirmwareHeader() {
|
|
||||||
return new byte[]{0x51, 0x71};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
public boolean isGenerallyCompatibleWith(final GBDevice device) {
|
||||||
return isHeaderValid() && device.getType() == DeviceType.MIBAND7;
|
return isHeaderValid() && device.getType() == DeviceType.MIBAND7;
|
||||||
|
@ -79,28 +79,6 @@ public class ZipFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to obtain file from ZIP file without much hassle, but is not safe.<br>
|
|
||||||
* Please only use this in place of old code where correctness of the result is checked only later on.<br>
|
|
||||||
* Use getFileFromZip of ZipFile instance instead.
|
|
||||||
* @param zipBytes
|
|
||||||
* @param path Path of the file in the ZIP file.
|
|
||||||
* @return Contents of requested file or null.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Nullable
|
|
||||||
public static byte[] tryReadFileQuick(final byte[] zipBytes, final String path) {
|
|
||||||
try {
|
|
||||||
return new ZipFile(zipBytes).getFileFromZip(path);
|
|
||||||
} catch (ZipFileException e) {
|
|
||||||
LOG.error("Quick ZIP reading failed.", e);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.error("Unable to close ZipFile.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] readAllBytes(final InputStream is) throws IOException {
|
private static byte[] readAllBytes(final InputStream is) throws IOException {
|
||||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user