Testcases for firmware checking
This commit is contained in:
parent
c2ae9ec530
commit
6d8d6d5bc8
|
@ -4,6 +4,8 @@ apply plugin: 'pmd'
|
||||||
|
|
||||||
def ABORT_ON_CHECK_FAILURE=false
|
def ABORT_ON_CHECK_FAILURE=false
|
||||||
|
|
||||||
|
tasks.withType(Test) { systemProperty 'MiFirmwareDir', System.getProperty('MiFirmwareDir', null) }
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.2"
|
buildToolsVersion "23.0.2"
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FW1 is Mi Band firmware
|
* FW1 is Mi Band firmware
|
||||||
* FW2 is heartrate firmware
|
* FW2 is heartrate firmware
|
||||||
*/
|
*/
|
||||||
public class Mi1SInfo {
|
public class Mi1SInfo {
|
||||||
|
|
||||||
public static int getFirmware2OffsetIn(byte[] wholeFirmwareBytes)
|
public static int getFirmware2OffsetIn(@NonNull byte[] wholeFirmwareBytes)
|
||||||
{
|
{
|
||||||
return (wholeFirmwareBytes[26] & 255) << 24
|
return (wholeFirmwareBytes[26] & 255) << 24
|
||||||
| (wholeFirmwareBytes[27] & 255) << 16
|
| (wholeFirmwareBytes[27] & 255) << 16
|
||||||
|
@ -14,7 +16,7 @@ public class Mi1SInfo {
|
||||||
| (wholeFirmwareBytes[29] & 255);
|
| (wholeFirmwareBytes[29] & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getFirmware2LengthIn(byte[] wholeFirmwareBytes)
|
public static int getFirmware2LengthIn(@NonNull byte[] wholeFirmwareBytes)
|
||||||
{
|
{
|
||||||
return (wholeFirmwareBytes[30] & 255) << 24
|
return (wholeFirmwareBytes[30] & 255) << 24
|
||||||
| (wholeFirmwareBytes[31] & 255) << 16
|
| (wholeFirmwareBytes[31] & 255) << 16
|
||||||
|
@ -22,7 +24,7 @@ public class Mi1SInfo {
|
||||||
| (wholeFirmwareBytes[33] & 255);
|
| (wholeFirmwareBytes[33] & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getFirmware1OffsetIn(byte[] wholeFirmwareBytes)
|
public static int getFirmware1OffsetIn(@NonNull byte[] wholeFirmwareBytes)
|
||||||
{
|
{
|
||||||
return (wholeFirmwareBytes[12] & 255) << 24
|
return (wholeFirmwareBytes[12] & 255) << 24
|
||||||
| (wholeFirmwareBytes[13] & 255) << 16
|
| (wholeFirmwareBytes[13] & 255) << 16
|
||||||
|
@ -30,7 +32,7 @@ public class Mi1SInfo {
|
||||||
| (wholeFirmwareBytes[15] & 255);
|
| (wholeFirmwareBytes[15] & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getFirmware1LengthIn(byte[] wholeFirmwareBytes)
|
public static int getFirmware1LengthIn(@NonNull byte[] wholeFirmwareBytes)
|
||||||
{
|
{
|
||||||
return (wholeFirmwareBytes[16] & 255) << 24
|
return (wholeFirmwareBytes[16] & 255) << 24
|
||||||
| (wholeFirmwareBytes[17] & 255) << 16
|
| (wholeFirmwareBytes[17] & 255) << 16
|
||||||
|
@ -38,7 +40,7 @@ public class Mi1SInfo {
|
||||||
| (wholeFirmwareBytes[19] & 255);
|
| (wholeFirmwareBytes[19] & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getFirmware1VersionFrom(byte[] wholeFirmwareBytes)
|
public static int getFirmware1VersionFrom(@NonNull byte[] wholeFirmwareBytes)
|
||||||
{
|
{
|
||||||
return (wholeFirmwareBytes[8] & 255) << 24
|
return (wholeFirmwareBytes[8] & 255) << 24
|
||||||
| (wholeFirmwareBytes[9] & 255) << 16
|
| (wholeFirmwareBytes[9] & 255) << 16
|
||||||
|
@ -46,7 +48,7 @@ public class Mi1SInfo {
|
||||||
| wholeFirmwareBytes[11] & 255;
|
| wholeFirmwareBytes[11] & 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getFirmware2VersionFrom(byte[] wholeFirmwareBytes)
|
public static int getFirmware2VersionFrom(@NonNull byte[] wholeFirmwareBytes)
|
||||||
{
|
{
|
||||||
return (wholeFirmwareBytes[22] & 255) << 24
|
return (wholeFirmwareBytes[22] & 255) << 24
|
||||||
| (wholeFirmwareBytes[23] & 255) << 16
|
| (wholeFirmwareBytes[23] & 255) << 16
|
||||||
|
@ -56,11 +58,11 @@ public class Mi1SInfo {
|
||||||
|
|
||||||
// FIXME: this method is wrong. We don't know a way to check if a firmware file
|
// FIXME: this method is wrong. We don't know a way to check if a firmware file
|
||||||
// contains one or more firmwares.
|
// contains one or more firmwares.
|
||||||
public static boolean isSingleMiBandFirmware(byte[] wholeFirmwareBytes) {
|
public static boolean isSingleMiBandFirmware(@NonNull byte[] wholeFirmwareBytes) {
|
||||||
if ((wholeFirmwareBytes[7] & 255) != 1) {
|
if ((wholeFirmwareBytes[7] & 255) != 1) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandFWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
|
|
||||||
|
public class FirmwareTest {
|
||||||
|
|
||||||
|
private static final long MAX_FILE_SIZE_BYTES = 1024 * 1024; // 1MB
|
||||||
|
private static final int MI_FW_VERSION = 0; // FIXME
|
||||||
|
private static final int MI1A_FW_VERSION = 0; // FIXME
|
||||||
|
private static final int MI1S_FW1_VERSION = 0;
|
||||||
|
private static final int MI1S_FW2_VERSION = 0;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFirmwareMi() throws Exception{
|
||||||
|
byte[] wholeFw = getFirmwareMi();
|
||||||
|
Assert.assertNotNull(wholeFw);
|
||||||
|
|
||||||
|
Assert.assertTrue(Mi1SInfo.isSingleMiBandFirmware(wholeFw));
|
||||||
|
int calculatedLength = Mi1SInfo.getFirmware1LengthIn(wholeFw);
|
||||||
|
Assert.assertTrue("Unexpected firmware length: " + wholeFw.length, calculatedLength < wholeFw.length);
|
||||||
|
int calculatedVersion = Mi1SInfo.getFirmware1VersionFrom(wholeFw);
|
||||||
|
// Assert.assertEquals("Unexpected firmware version: " + calculatedVersion, MI_FW_VERSION, calculatedVersion);
|
||||||
|
|
||||||
|
String version = MiBandFWHelper.formatFirmwareVersion(calculatedVersion);
|
||||||
|
Assert.assertTrue(version.startsWith("1."));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFirmwareMi1A() throws Exception{
|
||||||
|
byte[] wholeFw = getFirmwareMi1A();
|
||||||
|
Assert.assertNotNull(wholeFw);
|
||||||
|
|
||||||
|
Assert.assertTrue(Mi1SInfo.isSingleMiBandFirmware(wholeFw));
|
||||||
|
int calculatedLength = Mi1SInfo.getFirmware1LengthIn(wholeFw);
|
||||||
|
Assert.assertTrue("Unexpected firmware length: " + wholeFw.length, calculatedLength < wholeFw.length);
|
||||||
|
int calculatedVersion = Mi1SInfo.getFirmware1VersionFrom(wholeFw);
|
||||||
|
// Assert.assertEquals("Unexpected firmware version: " + calculatedVersion, MI1A_FW_VERSION, calculatedVersion);
|
||||||
|
|
||||||
|
String version = MiBandFWHelper.formatFirmwareVersion(calculatedVersion);
|
||||||
|
Assert.assertTrue(version.startsWith("5."));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFirmwareMi1S() throws Exception{
|
||||||
|
byte[] wholeFw = getFirmwareMi1S();
|
||||||
|
Assert.assertNotNull(wholeFw);
|
||||||
|
|
||||||
|
Assert.assertFalse(Mi1SInfo.isSingleMiBandFirmware(wholeFw));
|
||||||
|
|
||||||
|
// Mi Band version
|
||||||
|
int calculatedLengthFw1 = Mi1SInfo.getFirmware1LengthIn(wholeFw);
|
||||||
|
int calculatedOffsetFw1 = Mi1SInfo.getFirmware1OffsetIn(wholeFw);
|
||||||
|
int endIndexFw1 = calculatedOffsetFw1 + calculatedLengthFw1;
|
||||||
|
|
||||||
|
int calculatedLengthFw2 = Mi1SInfo.getFirmware2LengthIn(wholeFw);
|
||||||
|
int calculatedOffsetFw2 = Mi1SInfo.getFirmware2OffsetIn(wholeFw);
|
||||||
|
int endIndexFw2 = calculatedOffsetFw2 + calculatedLengthFw2;
|
||||||
|
|
||||||
|
Assert.assertTrue(endIndexFw1 <= wholeFw.length - calculatedLengthFw2);
|
||||||
|
Assert.assertTrue(endIndexFw2 <= wholeFw.length);
|
||||||
|
|
||||||
|
Assert.assertTrue(endIndexFw1 <= calculatedOffsetFw2);
|
||||||
|
int calculatedVersionFw1 = Mi1SInfo.getFirmware1VersionFrom(wholeFw);
|
||||||
|
// Assert.assertEquals("Unexpected firmware 1 version: " + calculatedVersionFw1, MI1S_FW1_VERSION, calculatedVersionFw1);
|
||||||
|
String version1 = MiBandFWHelper.formatFirmwareVersion(calculatedVersionFw1);
|
||||||
|
Assert.assertTrue(version1.startsWith("4."));
|
||||||
|
|
||||||
|
// HR version
|
||||||
|
int calculatedVersionFw2 = Mi1SInfo.getFirmware2VersionFrom(wholeFw);
|
||||||
|
// Assert.assertEquals("Unexpected firmware 2 version: " + calculatedVersionFw2, MI1S_FW2_VERSION, calculatedVersionFw2);
|
||||||
|
String version2 = MiBandFWHelper.formatFirmwareVersion(calculatedVersionFw2);
|
||||||
|
Assert.assertTrue(version2.startsWith("1."));
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getFirmwareDir() {
|
||||||
|
String path = System.getProperty("MiFirmwareDir");
|
||||||
|
Assert.assertNotNull(path);
|
||||||
|
File dir = new File(path);
|
||||||
|
Assert.assertTrue(dir.isDirectory());
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getFirmwareMi() throws IOException {
|
||||||
|
return getFirmware(new File(getFirmwareDir(), "Mili.fw"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getFirmwareMi1A() throws IOException {
|
||||||
|
return getFirmware(new File(getFirmwareDir(), "Mili_1a.fw"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getFirmwareMi1S() throws IOException {
|
||||||
|
return getFirmware(new File(getFirmwareDir(), "Mili_hr.fw"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getFirmware(File aFile) throws IOException {
|
||||||
|
Assert.assertNotNull(aFile);
|
||||||
|
try (FileInputStream stream = new FileInputStream(aFile)) {
|
||||||
|
return FileUtils.readAll(stream, MAX_FILE_SIZE_BYTES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue