1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-27 02:55:50 +01:00

Make firmware reading a bit more failsafe #30

This commit is contained in:
cpfeiffer 2015-08-04 23:02:36 +02:00
parent bdc9e70e6e
commit 910d9ef398
3 changed files with 49 additions and 36 deletions

View File

@ -8,9 +8,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Locale; import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
public class MiBandFWHelper { public class MiBandFWHelper {
private static final Logger LOG = LoggerFactory.getLogger(MiBandFWHelper.class); private static final Logger LOG = LoggerFactory.getLogger(MiBandFWHelper.class);
@ -29,41 +32,25 @@ public class MiBandFWHelper {
16779568 //1.0.9.48 tested by developer 16779568 //1.0.9.48 tested by developer
}; };
public MiBandFWHelper(Uri uri, Context context) { public MiBandFWHelper(Uri uri, Context context) throws IOException {
this.uri = uri; this.uri = uri;
cr = context.getContentResolver(); cr = context.getContentResolver();
InputStream fin; try (InputStream in = new BufferedInputStream(cr.openInputStream(uri))){
this.fw = FileUtils.readAll(in, 1024 * 1024); // 1 MB
try { if (fw.length > firmwareVersionMajor && fw[firmwareVersionMajor] != 1) {
fin = new BufferedInputStream(cr.openInputStream(uri)); throw new IOException("Firmware major version should be 1, probably this isn't a MiBand firmware.");
this.fw = new byte[fin.available()]; }
fin.read(fw);
fin.close();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); throw new IOException("Error reading firmware file: " + uri.toString(), e);
this.fw = null;
} }
if (fw[firmwareVersionMajor] != 1) {
LOG.error("Firmware major version should be 1, probably this isn't a MiBand firmware.");
this.fw = null;
}
} }
public int getFirmwareVersion() { public int getFirmwareVersion() {
if (fw == null) {
return -1;
}
return (fw[firmwareVersionMajor] << 24) | (fw[firmwareVersionMinor] << 16) | (fw[firmwareVersionRevision] << 8) | fw[firmwareVersionBuild]; return (fw[firmwareVersionMajor] << 24) | (fw[firmwareVersionMinor] << 16) | (fw[firmwareVersionRevision] << 8) | fw[firmwareVersionBuild];
} }
public String getHumanFirmwareVersion() { public String getHumanFirmwareVersion() {
if (fw == null) {
return "UNK";
}
return String.format(Locale.US, "%d.%d.%d.%d", fw[firmwareVersionMajor], fw[firmwareVersionMinor], fw[firmwareVersionRevision], fw[firmwareVersionBuild]); return String.format(Locale.US, "%d.%d.%d.%d", fw[firmwareVersionMajor], fw[firmwareVersionMinor], fw[firmwareVersionRevision], fw[firmwareVersionBuild]);
} }
@ -94,5 +81,4 @@ public class MiBandFWHelper {
crc &= 0xffff; crc &= 0xffff;
return crc; return crc;
} }
} }

View File

@ -592,6 +592,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
@Override @Override
public void onInstallApp(Uri uri) { public void onInstallApp(Uri uri) {
try {
MiBandFWHelper mFwHelper = new MiBandFWHelper(uri, getContext()); MiBandFWHelper mFwHelper = new MiBandFWHelper(uri, getContext());
String mMac = getDevice().getAddress(); String mMac = getDevice().getAddress();
String[] mMacOctets = mMac.split(":"); String[] mMacOctets = mMac.split(":");
@ -605,8 +606,9 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
newFirmware = mFwHelper.getFw(); newFirmware = mFwHelper.getFw();
//the firmware will be sent by the notification listener if the band confirms that the metadata are ok. //the firmware will be sent by the notification listener if the band confirms that the metadata are ok.
} }
} catch (IOException ex) {
return; GB.toast(getContext(), "Firmware cannot be installed: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR);
}
} }
@Override @Override

View File

@ -1,9 +1,11 @@
package nodomain.freeyourgadget.gadgetbridge.util; package nodomain.freeyourgadget.gadgetbridge.util;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -44,4 +46,27 @@ public class FileUtils {
} }
return dir; return dir;
} }
/**
* Reads the contents of the given InputStream into a byte array, but does not
* read more than maxLen bytes.
* @param in the stream to read from
* @param maxLen the maximum number of bytes to read/return
* @return the bytes read from the InputStream
* @throws IOException when reading failed or when maxLen was exceeded
*/
public static byte[] readAll(InputStream in, long maxLen) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(8192, in.available()));
byte[] buf = new byte[8192];
int read = 0;
long totalRead = 0;
while ((read = in.read(buf)) > 0) {
out.write(buf, 0, read);
totalRead += read;
if (totalRead > maxLen) {
throw new IOException("Too much data to read into memory. Got already " + totalRead + buf);
}
}
return out.toByteArray();
}
} }