Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMiFirmwareInfo.java

100 lines
3.4 KiB
Java

package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
import android.support.annotation.NonNull;
import java.lang.reflect.Array;
import java.util.Arrays;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
public abstract class AbstractMiFirmwareInfo {
/**
* @param wholeFirmwareBytes
* @return
* @throws IllegalArgumentException when the data is not recognized as firmware data
*/
public static
@NonNull
AbstractMiFirmwareInfo determineFirmwareInfoFor(byte[] wholeFirmwareBytes) {
AbstractMiFirmwareInfo[] candidates = getFirmwareInfoCandidatesFor(wholeFirmwareBytes);
if (candidates.length == 0) {
throw new IllegalArgumentException("Unsupported data (maybe not even a firmware?).");
}
if (candidates.length == 1) {
candidates[0].checkValid();
return candidates[0];
}
throw new IllegalArgumentException("don't know for which device the firmware is, matches multiple devices");
}
private static AbstractMiFirmwareInfo[] getFirmwareInfoCandidatesFor(byte[] wholeFirmwareBytes) {
AbstractMiFirmwareInfo[] candidates = new AbstractMiFirmwareInfo[3];
int i = 0;
Mi1FirmwareInfo mi1Info = Mi1FirmwareInfo.getInstance(wholeFirmwareBytes);
if (mi1Info != null) {
candidates[i++] = mi1Info;
}
Mi1AFirmwareInfo mi1aInfo = Mi1AFirmwareInfo.getInstance(wholeFirmwareBytes);
if (mi1aInfo != null) {
candidates[i++] = mi1aInfo;
}
Mi1SFirmwareInfo mi1sInfo = Mi1SFirmwareInfo.getInstance(wholeFirmwareBytes);
if (mi1sInfo != null) {
candidates[i++] = mi1sInfo;
}
return Arrays.copyOfRange(candidates, 0, i);
}
@NonNull
protected byte[] wholeFirmwareBytes;
public AbstractMiFirmwareInfo(@NonNull byte[] wholeFirmwareBytes) {
this.wholeFirmwareBytes = wholeFirmwareBytes;
}
public abstract int getFirmwareOffset();
public abstract int getFirmwareLength();
public abstract int getFirmwareVersion();
protected abstract boolean isGenerallySupportedFirmware();
protected abstract boolean isHeaderValid();
public abstract boolean isGenerallyCompatibleWith(GBDevice device);
public @NonNull byte[] getFirmwareBytes() {
return Arrays.copyOfRange(wholeFirmwareBytes, getFirmwareOffset(), getFirmwareOffset() + getFirmwareLength());
}
public int getFirmwareVersionMajor() {
int version = getFirmwareVersion();
if (version > 0) {
return (version >> 24);
}
throw new IllegalArgumentException("bad firmware version: " + version);
}
public abstract boolean isSingleMiBandFirmware();
public void checkValid() throws IllegalArgumentException {
}
public AbstractMiFirmwareInfo getFirst() {
if (isSingleMiBandFirmware()) {
return this;
}
throw new UnsupportedOperationException(getClass().getName() + " must override getFirst() and getSecond()");
}
public AbstractMiFirmwareInfo getSecond() {
if (isSingleMiBandFirmware()) {
throw new UnsupportedOperationException(getClass().getName() + " only supports on firmware");
}
throw new UnsupportedOperationException(getClass().getName() + " must override getFirst() and getSecond()");
}
}