100 lines
3.4 KiB
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()");
|
|
}
|
|
}
|