mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-08-24 16:21:16 +02:00
Pebble: WIP support for flashing language files (.pbl)
NOTES: - YOU SHOULD NOT TRY THIS YET ;) - This was only tested with the unoffical japansese language pack - Problably needs proper crc calculation (I just hardcoded the one for the japanese language pack)
This commit is contained in:
parent
7dce1d62b0
commit
5860c4f4f9
@ -125,6 +125,7 @@
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pbz" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pbz" />
|
||||
|
||||
<data android:pathPattern="/.*\\.pbl" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -170,6 +171,7 @@
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pbz" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pbz" />
|
||||
|
||||
<data android:pathPattern="/.*\\.pbl" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- to receive the firmwares from the donwload content provider -->
|
||||
|
@ -41,7 +41,7 @@ public class MiBandFWHelper {
|
||||
this.uri = uri;
|
||||
cr = context.getContentResolver();
|
||||
|
||||
String pebblePattern = ".*\\.(pbw|pbz)";
|
||||
String pebblePattern = ".*\\.(pbw|pbz|pbl)";
|
||||
|
||||
if (uri.getPath().matches(pebblePattern)) {
|
||||
throw new IOException("Firmware has a filename that looks like a Pebble app/firmware.");
|
||||
|
@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -50,6 +51,7 @@ public class PBWReader {
|
||||
private GBDeviceApp app;
|
||||
private ArrayList<PebbleInstallable> pebbleInstallables;
|
||||
private boolean isFirmware = false;
|
||||
private boolean isLanguage = false;
|
||||
private boolean isValid = false;
|
||||
private String hwRevision = null;
|
||||
private short mSdkVersion;
|
||||
@ -58,14 +60,25 @@ public class PBWReader {
|
||||
private int mFlags;
|
||||
|
||||
public PBWReader(Uri uri, Context context, String platform) {
|
||||
this.uri = uri;
|
||||
cr = context.getContentResolver();
|
||||
|
||||
if (uri.toString().endsWith(".pbl") && platform.equals("aplite")) {
|
||||
// language file
|
||||
app = new GBDeviceApp(UUID.randomUUID(), "Language File", "unknown", "unknown", GBDeviceApp.Type.UNKNOWN);
|
||||
File f = new File(uri.getPath());
|
||||
pebbleInstallables = new ArrayList<>();
|
||||
pebbleInstallables.add(new PebbleInstallable("lang", (int) f.length(), (int)4218691521L, PebbleProtocol.PUTBYTES_TYPE_FILE));
|
||||
isValid = true;
|
||||
isLanguage = true;
|
||||
return;
|
||||
}
|
||||
|
||||
String platformDir = "";
|
||||
if (!uri.toString().endsWith(".pbz") && !platform.equals("aplite")) {
|
||||
platformDir = platform + "/";
|
||||
}
|
||||
|
||||
this.uri = uri;
|
||||
cr = context.getContentResolver();
|
||||
|
||||
InputStream fin;
|
||||
try {
|
||||
fin = new BufferedInputStream(cr.openInputStream(uri));
|
||||
@ -186,6 +199,10 @@ public class PBWReader {
|
||||
return isFirmware;
|
||||
}
|
||||
|
||||
public boolean isLanguage() {
|
||||
return isLanguage;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return isValid;
|
||||
}
|
||||
@ -194,11 +211,13 @@ public class PBWReader {
|
||||
return app;
|
||||
}
|
||||
|
||||
public ZipInputStream getInputStreamFile(String filename) {
|
||||
public InputStream getInputStreamFile(String filename) {
|
||||
InputStream fin;
|
||||
try {
|
||||
fin = new BufferedInputStream(cr.openInputStream(uri));
|
||||
|
||||
if (isLanguage) {
|
||||
return fin;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
|
@ -26,7 +26,6 @@ import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||
@ -75,7 +74,7 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
|
||||
private PBWReader mPBWReader = null;
|
||||
private int mAppInstallToken = -1;
|
||||
private ZipInputStream mZis = null;
|
||||
private InputStream mFis = null;
|
||||
private PebbleAppInstallState mInstallState = PebbleAppInstallState.UNKNOWN;
|
||||
private PebbleInstallable[] mPebbleInstallables = null;
|
||||
private int mCurrentInstallableIndex = -1;
|
||||
@ -223,11 +222,11 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
case START_INSTALL:
|
||||
LOG.info("start installing app binary");
|
||||
PebbleInstallable pi = mPebbleInstallables[mCurrentInstallableIndex];
|
||||
mZis = mPBWReader.getInputStreamFile(pi.getFileName());
|
||||
mFis = mPBWReader.getInputStreamFile(pi.getFileName());
|
||||
mCRC = pi.getCRC();
|
||||
mBinarySize = pi.getFileSize();
|
||||
mBytesWritten = 0;
|
||||
writeInstallApp(mPebbleProtocol.encodeUploadStart(pi.getType(), mInstallSlot, mBinarySize));
|
||||
writeInstallApp(mPebbleProtocol.encodeUploadStart(pi.getType(), mInstallSlot, mBinarySize, mPBWReader.isLanguage() ? "lang" : null));
|
||||
mAppInstallToken = -1;
|
||||
mInstallState = PebbleAppInstallState.WAIT_TOKEN;
|
||||
break;
|
||||
@ -241,7 +240,7 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
case UPLOAD_CHUNK:
|
||||
int bytes = 0;
|
||||
do {
|
||||
int read = mZis.read(buffer, bytes, 2000 - bytes);
|
||||
int read = mFis.read(buffer, bytes, 2000 - bytes);
|
||||
if (read <= 0) break;
|
||||
bytes += read;
|
||||
} while (bytes < 2000);
|
||||
@ -285,7 +284,12 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
} else if (mPebbleProtocol.isFw3x) {
|
||||
finishInstall(false); // FIXME: dont know yet how to detect success
|
||||
} else {
|
||||
writeInstallApp(mPebbleProtocol.encodeAppRefresh(mInstallSlot));
|
||||
if (mPBWReader.isLanguage()) {
|
||||
finishInstall(false);
|
||||
write(mPebbleProtocol.encodeReboot());
|
||||
} else {
|
||||
writeInstallApp(mPebbleProtocol.encodeAppRefresh(mInstallSlot));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -589,8 +593,16 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
}
|
||||
} else {
|
||||
mIsInstalling = true;
|
||||
mInstallState = PebbleAppInstallState.WAIT_SLOT;
|
||||
writeInstallApp(mPebbleProtocol.encodeAppDelete(app.getUUID()));
|
||||
if (mPBWReader.isLanguage()) {
|
||||
mInstallSlot = 0;
|
||||
mInstallState = PebbleAppInstallState.START_INSTALL;
|
||||
|
||||
// unblock HACK
|
||||
writeInstallApp(mPebbleProtocol.encodeGetTime());
|
||||
} else {
|
||||
mInstallState = PebbleAppInstallState.WAIT_SLOT;
|
||||
writeInstallApp(mPebbleProtocol.encodeAppDelete(app.getUUID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -612,14 +624,14 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
|
||||
mPBWReader = null;
|
||||
mIsInstalling = false;
|
||||
if (mZis != null) {
|
||||
if (mFis != null) {
|
||||
try {
|
||||
mZis.close();
|
||||
mFis.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
mZis = null;
|
||||
mFis = null;
|
||||
mAppInstallToken = -1;
|
||||
mInstallSlot = -2;
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
public static final byte PUTBYTES_TYPE_SYSRESOURCES = 3;
|
||||
public static final byte PUTBYTES_TYPE_RESOURCES = 4;
|
||||
public static final byte PUTBYTES_TYPE_BINARY = 5;
|
||||
static final byte PUTBYTES_TYPE_FILE = 6;
|
||||
public static final byte PUTBYTES_TYPE_FILE = 6;
|
||||
public static final byte PUTBYTES_TYPE_WORKER = 7;
|
||||
|
||||
static final byte RESET_REBOOT = 0;
|
||||
@ -1027,7 +1027,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
}
|
||||
|
||||
/* pebble specific install methods */
|
||||
public byte[] encodeUploadStart(byte type, int app_id, int size) {
|
||||
public byte[] encodeUploadStart(byte type, int app_id, int size, String filename) {
|
||||
short length;
|
||||
if (isFw3x) {
|
||||
length = LENGTH_UPLOADSTART_3X;
|
||||
@ -1035,6 +1035,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
} else {
|
||||
length = LENGTH_UPLOADSTART_2X;
|
||||
}
|
||||
|
||||
if (type == PUTBYTES_TYPE_FILE && filename != null) {
|
||||
length += filename.getBytes().length + 1;
|
||||
}
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort(length);
|
||||
@ -1042,12 +1047,19 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
buf.put(PUTBYTES_INIT);
|
||||
buf.putInt(size);
|
||||
buf.put(type);
|
||||
|
||||
if (isFw3x) {
|
||||
buf.putInt(app_id);
|
||||
} else {
|
||||
// slot
|
||||
buf.put((byte) app_id);
|
||||
}
|
||||
|
||||
if (type == PUTBYTES_TYPE_FILE && filename != null) {
|
||||
buf.put(filename.getBytes());
|
||||
buf.put((byte) 0);
|
||||
}
|
||||
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user