Merge branch 'master' into liveview
This commit is contained in:
commit
219cc7bff1
|
@ -17,7 +17,7 @@ need to create an account and transmit any of your data to the vendor's servers.
|
||||||
* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round
|
* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round
|
||||||
* Pebble 2 (experimental, PAIR WITHIN GADGETBRIDGE)
|
* Pebble 2 (experimental, PAIR WITHIN GADGETBRIDGE)
|
||||||
* Mi Band, Mi Band 1A, Mi Band 1S
|
* Mi Band, Mi Band 1A, Mi Band 1S
|
||||||
* Mi Band 2 (notifications, alarms and heart rate measurement only)
|
* Mi Band 2
|
||||||
* Vibratissimo (experimental)
|
* Vibratissimo (experimental)
|
||||||
|
|
||||||
## Features (Pebble)
|
## Features (Pebble)
|
||||||
|
@ -58,6 +58,7 @@ For more information read [this wiki article](https://github.com/Freeyourgadget/
|
||||||
|
|
||||||
* Discovery and pairing
|
* Discovery and pairing
|
||||||
* Mi Band notifications (LEDs + vibration) for
|
* Mi Band notifications (LEDs + vibration) for
|
||||||
|
* Display live activity data (alpha)
|
||||||
* Incoming calls
|
* Incoming calls
|
||||||
* SMS received
|
* SMS received
|
||||||
* K-9 mails received
|
* K-9 mails received
|
||||||
|
@ -82,9 +83,10 @@ For more information read [this wiki article](https://github.com/Freeyourgadget/
|
||||||
* K-9 mails received
|
* K-9 mails received
|
||||||
* Conversations messages
|
* Conversations messages
|
||||||
* Generic Android notifications
|
* Generic Android notifications
|
||||||
* Synchronize the time to the Mi Band
|
* Synchronize the time to the Mi Band 2
|
||||||
* Display firmware version
|
* Display firmware version
|
||||||
* Heart rate measurement (alpha)
|
* Heart rate measurement on demand and during sleep
|
||||||
|
* Synchronize activity data (alpha)
|
||||||
* Set alarms on the Mi Band 2
|
* Set alarms on the Mi Band 2
|
||||||
|
|
||||||
## How to use (Mi Band 1+2)
|
## How to use (Mi Band 1+2)
|
||||||
|
|
|
@ -25,9 +25,9 @@ public class MiBand2SampleProvider extends AbstractMiBandSampleProvider {
|
||||||
// 0 = same activity kind as before
|
// 0 = same activity kind as before
|
||||||
// 1 = light activity walking?
|
// 1 = light activity walking?
|
||||||
// 3 = definitely non-wear
|
// 3 = definitely non-wear
|
||||||
// 9 = probably deep sleep, definitely some kind of sleep
|
// 9 = probably light sleep, definitely some kind of sleep
|
||||||
// 10 = ignore, except for hr (if valid)
|
// 10 = ignore, except for hr (if valid)
|
||||||
// 11 = probably light sleep
|
// 11 = probably deep sleep
|
||||||
// 12 = definitely wake up
|
// 12 = definitely wake up
|
||||||
// 17 = definitely not sleep related
|
// 17 = definitely not sleep related
|
||||||
|
|
||||||
|
|
|
@ -500,6 +500,7 @@ class PebbleIoThread extends GBDeviceIoThread {
|
||||||
LOG.info("syncing time");
|
LOG.info("syncing time");
|
||||||
write(mPebbleProtocol.encodeSetTime());
|
write(mPebbleProtocol.encodeSetTime());
|
||||||
}
|
}
|
||||||
|
write(mPebbleProtocol.encodeEnableAppLogs(prefs.getBoolean("pebble_enable_applogs",false)));
|
||||||
write(mPebbleProtocol.encodeReportDataLogSessions());
|
write(mPebbleProtocol.encodeReportDataLogSessions());
|
||||||
gbDevice.setState(GBDevice.State.INITIALIZED);
|
gbDevice.setState(GBDevice.State.INITIALIZED);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -388,7 +388,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
|
|
||||||
private final HashMap<Byte, DatalogSession> mDatalogSessions = new HashMap<>();
|
private final HashMap<Byte, DatalogSession> mDatalogSessions = new HashMap<>();
|
||||||
|
|
||||||
private static byte[] encodeSimpleMessage(short endpoint, byte command) {
|
private byte[] encodeSimpleMessage(short endpoint, byte command) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_SIMPLEMESSAGE);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_SIMPLEMESSAGE);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort(LENGTH_SIMPLEMESSAGE);
|
buf.putShort(LENGTH_SIMPLEMESSAGE);
|
||||||
|
@ -533,7 +533,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return encodeSetCallState("Where are you?", "Gadgetbridge", start ? CallSpec.CALL_INCOMING : CallSpec.CALL_END);
|
return encodeSetCallState("Where are you?", "Gadgetbridge", start ? CallSpec.CALL_INCOMING : CallSpec.CALL_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, String[] cannedReplies) {
|
private byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, String[] cannedReplies) {
|
||||||
final short ACTION_LENGTH_MIN = 10;
|
final short ACTION_LENGTH_MIN = 10;
|
||||||
|
|
||||||
String[] parts = {title, subtitle, body};
|
String[] parts = {title, subtitle, body};
|
||||||
|
@ -1018,7 +1018,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
|
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeActionResponse2x(int id, byte actionId, int iconId, String caption) {
|
private byte[] encodeActionResponse2x(int id, byte actionId, int iconId, String caption) {
|
||||||
short length = (short) (18 + caption.getBytes().length);
|
short length = (short) (18 + caption.getBytes().length);
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
@ -1039,7 +1039,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeActionResponse(UUID uuid, int iconId, String caption) {
|
private byte[] encodeActionResponse(UUID uuid, int iconId, String caption) {
|
||||||
short length = (short) (29 + caption.getBytes().length);
|
short length = (short) (29 + caption.getBytes().length);
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
@ -1060,7 +1060,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeInstallMetadata(UUID uuid, String appName, short appVersion, short sdkVersion, int flags, int iconId) {
|
byte[] encodeInstallMetadata(UUID uuid, String appName, short appVersion, short sdkVersion, int flags, int iconId) {
|
||||||
final short METADATA_LENGTH = 126;
|
final short METADATA_LENGTH = 126;
|
||||||
|
|
||||||
byte[] name_buf = new byte[96];
|
byte[] name_buf = new byte[96];
|
||||||
|
@ -1093,7 +1093,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeGetTime() {
|
byte[] encodeGetTime() {
|
||||||
return encodeSimpleMessage(ENDPOINT_TIME, TIME_GETTIME);
|
return encodeSimpleMessage(ENDPOINT_TIME, TIME_GETTIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,7 +1314,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodePhoneVersion(byte os) {
|
private byte[] encodePhoneVersion(byte os) {
|
||||||
return encodePhoneVersion3x(os);
|
return encodePhoneVersion3x(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1393,7 +1393,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pebble specific install methods */
|
/* pebble specific install methods */
|
||||||
public byte[] encodeUploadStart(byte type, int app_id, int size, String filename) {
|
byte[] encodeUploadStart(byte type, int app_id, int size, String filename) {
|
||||||
short length;
|
short length;
|
||||||
if (mFwMajor >= 3 && (type != PUTBYTES_TYPE_FILE)) {
|
if (mFwMajor >= 3 && (type != PUTBYTES_TYPE_FILE)) {
|
||||||
length = LENGTH_UPLOADSTART_3X;
|
length = LENGTH_UPLOADSTART_3X;
|
||||||
|
@ -1429,7 +1429,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeUploadChunk(int token, byte[] buffer, int size) {
|
byte[] encodeUploadChunk(int token, byte[] buffer, int size) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCHUNK + size);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCHUNK + size);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort((short) (LENGTH_UPLOADCHUNK + size));
|
buf.putShort((short) (LENGTH_UPLOADCHUNK + size));
|
||||||
|
@ -1441,7 +1441,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeUploadCommit(int token, int crc) {
|
byte[] encodeUploadCommit(int token, int crc) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCOMMIT);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCOMMIT);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort(LENGTH_UPLOADCOMMIT);
|
buf.putShort(LENGTH_UPLOADCOMMIT);
|
||||||
|
@ -1452,7 +1452,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeUploadComplete(int token) {
|
byte[] encodeUploadComplete(int token) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCOMPLETE);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCOMPLETE);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort(LENGTH_UPLOADCOMPLETE);
|
buf.putShort(LENGTH_UPLOADCOMPLETE);
|
||||||
|
@ -1462,7 +1462,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeUploadCancel(int token) {
|
byte[] encodeUploadCancel(int token) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCANCEL);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_UPLOADCANCEL);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort(LENGTH_UPLOADCANCEL);
|
buf.putShort(LENGTH_UPLOADCANCEL);
|
||||||
|
@ -1483,11 +1483,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeInstallFirmwareStart() {
|
byte[] encodeInstallFirmwareStart() {
|
||||||
return encodeSystemMessage(SYSTEMMESSAGE_FIRMWARESTART);
|
return encodeSystemMessage(SYSTEMMESSAGE_FIRMWARESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeInstallFirmwareComplete() {
|
byte[] encodeInstallFirmwareComplete() {
|
||||||
return encodeSystemMessage(SYSTEMMESSAGE_FIRMWARECOMPLETE);
|
return encodeSystemMessage(SYSTEMMESSAGE_FIRMWARECOMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,7 +1496,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte[] encodeAppRefresh(int index) {
|
byte[] encodeAppRefresh(int index) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REFRESHAPP);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REFRESHAPP);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort(LENGTH_REFRESHAPP);
|
buf.putShort(LENGTH_REFRESHAPP);
|
||||||
|
@ -1507,7 +1507,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeDatalog(byte handle, byte reply) {
|
private byte[] encodeDatalog(byte handle, byte reply) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + 2);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + 2);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort((short) 2);
|
buf.putShort((short) 2);
|
||||||
|
@ -1532,7 +1532,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] encodePing(byte command, int cookie) {
|
private byte[] encodePing(byte command, int cookie) {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_PING);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_PING);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort(LENGTH_PING);
|
buf.putShort(LENGTH_PING);
|
||||||
|
@ -1543,6 +1543,17 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] encodeEnableAppLogs(boolean enable) {
|
||||||
|
final short LENGTH_APPLOGS = 1;
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_APPLOGS);
|
||||||
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
buf.putShort(LENGTH_APPLOGS);
|
||||||
|
buf.putShort(ENDPOINT_APPLOGS);
|
||||||
|
buf.put((byte) (enable ? 1 : 0));
|
||||||
|
|
||||||
|
return buf.array();
|
||||||
|
}
|
||||||
|
|
||||||
private ArrayList<Pair<Integer, Object>> decodeDict(ByteBuffer buf) {
|
private ArrayList<Pair<Integer, Object>> decodeDict(ByteBuffer buf) {
|
||||||
ArrayList<Pair<Integer, Object>> dict = new ArrayList<>();
|
ArrayList<Pair<Integer, Object>> dict = new ArrayList<>();
|
||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
@ -1652,8 +1663,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
length += ((String) pair.second).getBytes().length + 1;
|
length += ((String) pair.second).getBytes().length + 1;
|
||||||
} else if (pair.second instanceof byte[]) {
|
} else if (pair.second instanceof byte[]) {
|
||||||
length += ((byte[]) pair.second).length;
|
length += ((byte[]) pair.second).length;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LOG.warn("unknown type: " + pair.second.getClass().toString());
|
LOG.warn("unknown type: " + pair.second.getClass().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1700,7 +1710,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeApplicationMessageFromJSON(UUID uuid, JSONArray jsonArray) {
|
byte[] encodeApplicationMessageFromJSON(UUID uuid, JSONArray jsonArray) {
|
||||||
ArrayList<Pair<Integer, Object>> pairs = new ArrayList<>();
|
ArrayList<Pair<Integer, Object>> pairs = new ArrayList<>();
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
try {
|
try {
|
||||||
|
@ -1739,7 +1749,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return encodeApplicationMessagePush(ENDPOINT_APPLICATIONMESSAGE, uuid, pairs);
|
return encodeApplicationMessagePush(ENDPOINT_APPLICATIONMESSAGE, uuid, pairs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte reverseBits(byte in) {
|
private byte reverseBits(byte in) {
|
||||||
byte out = 0;
|
byte out = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
byte bit = (byte) (in & 1);
|
byte bit = (byte) (in & 1);
|
||||||
|
@ -1803,14 +1813,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
if (command == NOTIFICATIONACTION_INVOKE) {
|
if (command == NOTIFICATIONACTION_INVOKE) {
|
||||||
int id;
|
int id;
|
||||||
long uuid_high = 0;
|
UUID uuid = new UUID(0,0);
|
||||||
long uuid_low = 0;
|
|
||||||
if (mFwMajor >= 3) {
|
if (mFwMajor >= 3) {
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
uuid = getUUID(buf);
|
||||||
uuid_high = buf.getLong();
|
id = (int) (uuid.getLeastSignificantBits() & 0xffffffffL);
|
||||||
uuid_low = buf.getLong();
|
|
||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
id = (int) (uuid_low & 0xffffffffL);
|
|
||||||
} else {
|
} else {
|
||||||
id = buf.getInt();
|
id = buf.getInt();
|
||||||
}
|
}
|
||||||
|
@ -1880,7 +1886,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
if (mFwMajor >= 3 || needsAck2x) {
|
if (mFwMajor >= 3 || needsAck2x) {
|
||||||
sendBytesAck = new GBDeviceEventSendBytes();
|
sendBytesAck = new GBDeviceEventSendBytes();
|
||||||
if (mFwMajor >= 3) {
|
if (mFwMajor >= 3) {
|
||||||
sendBytesAck.encodedBytes = encodeActionResponse(new UUID(uuid_high, uuid_low), icon_id, caption);
|
sendBytesAck.encodedBytes = encodeActionResponse(uuid, icon_id, caption);
|
||||||
} else {
|
} else {
|
||||||
sendBytesAck.encodedBytes = encodeActionResponse2x(id, action, 6, caption);
|
sendBytesAck.encodedBytes = encodeActionResponse2x(id, action, 6, caption);
|
||||||
}
|
}
|
||||||
|
@ -1905,6 +1911,17 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void decodeAppLogs(ByteBuffer buf) {
|
||||||
|
UUID uuid = getUUID(buf);
|
||||||
|
int timestamp = buf.getInt();
|
||||||
|
int logLevel = buf.get() & 0xff;
|
||||||
|
int messageLength = buf.get() & 0xff;
|
||||||
|
int lineNumber = buf.getShort() & 0xffff;
|
||||||
|
String fileName = getFixedString(buf, 16);
|
||||||
|
String message = getFixedString(buf, messageLength);
|
||||||
|
LOG.debug("APP_LOGS from uuid " + uuid.toString() + " in " + fileName + ":" + lineNumber + " " + message);
|
||||||
|
}
|
||||||
|
|
||||||
private GBDeviceEvent decodeSystemMessage(ByteBuffer buf) {
|
private GBDeviceEvent decodeSystemMessage(ByteBuffer buf) {
|
||||||
buf.get(); // unknown;
|
buf.get(); // unknown;
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
|
@ -1925,9 +1942,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
|
|
||||||
private GBDeviceEvent[] decodeAppRunState(ByteBuffer buf) {
|
private GBDeviceEvent[] decodeAppRunState(ByteBuffer buf) {
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
long uuid_high = buf.getLong();
|
UUID uuid = getUUID(buf);
|
||||||
long uuid_low = buf.getLong();
|
|
||||||
UUID uuid = new UUID(uuid_high, uuid_low);
|
|
||||||
final String ENDPOINT_NAME = "APPRUNSTATE";
|
final String ENDPOINT_NAME = "APPRUNSTATE";
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case APPRUNSTATE_START:
|
case APPRUNSTATE_START:
|
||||||
|
@ -1976,9 +1991,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
private GBDeviceEventAppManagement decodeAppFetch(ByteBuffer buf) {
|
private GBDeviceEventAppManagement decodeAppFetch(ByteBuffer buf) {
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
if (command == 0x01) {
|
if (command == 0x01) {
|
||||||
long uuid_high = buf.getLong();
|
UUID uuid = getUUID(buf);
|
||||||
long uuid_low = buf.getLong();
|
|
||||||
UUID uuid = new UUID(uuid_high, uuid_low);
|
|
||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
int app_id = buf.getInt();
|
int app_id = buf.getInt();
|
||||||
GBDeviceEventAppManagement fetchRequest = new GBDeviceEventAppManagement();
|
GBDeviceEventAppManagement fetchRequest = new GBDeviceEventAppManagement();
|
||||||
|
@ -2011,10 +2024,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DATALOG_OPENSESSION:
|
case DATALOG_OPENSESSION:
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
UUID uuid = getUUID(buf);
|
||||||
long uuid_high = buf.getLong();
|
|
||||||
long uuid_low = buf.getLong();
|
|
||||||
UUID uuid = new UUID(uuid_high, uuid_low);
|
|
||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
int timestamp = buf.getInt();
|
int timestamp = buf.getInt();
|
||||||
int log_tag = buf.getInt();
|
int log_tag = buf.getInt();
|
||||||
|
@ -2073,7 +2083,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
short length = buf.getShort();
|
short length = buf.getShort();
|
||||||
short endpoint = buf.getShort();
|
short endpoint = buf.getShort();
|
||||||
GBDeviceEvent devEvts[] = null;
|
GBDeviceEvent devEvts[] = null;
|
||||||
byte pebbleCmd = -1;
|
byte pebbleCmd;
|
||||||
switch (endpoint) {
|
switch (endpoint) {
|
||||||
case ENDPOINT_MUSICCONTROL:
|
case ENDPOINT_MUSICCONTROL:
|
||||||
pebbleCmd = buf.get();
|
pebbleCmd = buf.get();
|
||||||
|
@ -2123,14 +2133,12 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
GBDeviceEventVersionInfo versionCmd = new GBDeviceEventVersionInfo();
|
GBDeviceEventVersionInfo versionCmd = new GBDeviceEventVersionInfo();
|
||||||
|
|
||||||
buf.getInt(); // skip
|
buf.getInt(); // skip
|
||||||
byte[] tmp = new byte[32];
|
versionCmd.fwVersion = getFixedString(buf, 32);
|
||||||
buf.get(tmp, 0, 32);
|
|
||||||
|
|
||||||
versionCmd.fwVersion = new String(tmp).trim();
|
|
||||||
|
|
||||||
mFwMajor = versionCmd.fwVersion.charAt(1) - 48;
|
mFwMajor = versionCmd.fwVersion.charAt(1) - 48;
|
||||||
LOG.info("Pebble firmware major detected as " + mFwMajor);
|
LOG.info("Pebble firmware major detected as " + mFwMajor);
|
||||||
|
|
||||||
|
byte[] tmp = new byte[9];
|
||||||
buf.get(tmp, 0, 9);
|
buf.get(tmp, 0, 9);
|
||||||
int hwRev = buf.get() + 8;
|
int hwRev = buf.get() + 8;
|
||||||
if (hwRev >= 0 && hwRev < hwRevisions.length) {
|
if (hwRev >= 0 && hwRev < hwRevisions.length) {
|
||||||
|
@ -2145,8 +2153,6 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
GBDeviceEventAppInfo appInfoCmd = new GBDeviceEventAppInfo();
|
GBDeviceEventAppInfo appInfoCmd = new GBDeviceEventAppInfo();
|
||||||
int slotCount = buf.getInt();
|
int slotCount = buf.getInt();
|
||||||
int slotsUsed = buf.getInt();
|
int slotsUsed = buf.getInt();
|
||||||
byte[] appName = new byte[32];
|
|
||||||
byte[] appCreator = new byte[32];
|
|
||||||
appInfoCmd.apps = new GBDeviceApp[slotsUsed];
|
appInfoCmd.apps = new GBDeviceApp[slotsUsed];
|
||||||
boolean[] slotInUse = new boolean[slotCount];
|
boolean[] slotInUse = new boolean[slotCount];
|
||||||
|
|
||||||
|
@ -2154,8 +2160,9 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
int id = buf.getInt();
|
int id = buf.getInt();
|
||||||
int index = buf.getInt();
|
int index = buf.getInt();
|
||||||
slotInUse[index] = true;
|
slotInUse[index] = true;
|
||||||
buf.get(appName, 0, 32);
|
String appName = getFixedString(buf, 32);
|
||||||
buf.get(appCreator, 0, 32);
|
String appCreator = getFixedString(buf, 32);
|
||||||
|
|
||||||
int flags = buf.getInt();
|
int flags = buf.getInt();
|
||||||
|
|
||||||
GBDeviceApp.Type appType;
|
GBDeviceApp.Type appType;
|
||||||
|
@ -2167,7 +2174,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
appType = GBDeviceApp.Type.APP_GENERIC;
|
appType = GBDeviceApp.Type.APP_GENERIC;
|
||||||
}
|
}
|
||||||
Short appVersion = buf.getShort();
|
Short appVersion = buf.getShort();
|
||||||
appInfoCmd.apps[i] = new GBDeviceApp(tmpUUIDS.get(i), new String(appName).trim(), new String(appCreator).trim(), appVersion.toString(), appType);
|
appInfoCmd.apps[i] = new GBDeviceApp(tmpUUIDS.get(i), appName, appCreator, appVersion.toString(), appType);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < slotCount; i++) {
|
for (int i = 0; i < slotCount; i++) {
|
||||||
if (!slotInUse[i]) {
|
if (!slotInUse[i]) {
|
||||||
|
@ -2185,9 +2192,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
tmpUUIDS.clear();
|
tmpUUIDS.clear();
|
||||||
slotsUsed = buf.getInt();
|
slotsUsed = buf.getInt();
|
||||||
for (int i = 0; i < slotsUsed; i++) {
|
for (int i = 0; i < slotsUsed; i++) {
|
||||||
long uuid_high = buf.getLong();
|
UUID uuid = getUUID(buf);
|
||||||
long uuid_low = buf.getLong();
|
|
||||||
UUID uuid = new UUID(uuid_high, uuid_low);
|
|
||||||
LOG.info("found uuid: " + uuid);
|
LOG.info("found uuid: " + uuid);
|
||||||
tmpUUIDS.add(uuid);
|
tmpUUIDS.add(uuid);
|
||||||
}
|
}
|
||||||
|
@ -2232,13 +2237,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
case ENDPOINT_LAUNCHER:
|
case ENDPOINT_LAUNCHER:
|
||||||
pebbleCmd = buf.get();
|
pebbleCmd = buf.get();
|
||||||
last_id = buf.get();
|
last_id = buf.get();
|
||||||
long uuid_high = buf.getLong();
|
UUID uuid = getUUID(buf);
|
||||||
long uuid_low = buf.getLong();
|
|
||||||
|
|
||||||
switch (pebbleCmd) {
|
switch (pebbleCmd) {
|
||||||
case APPLICATIONMESSAGE_PUSH:
|
case APPLICATIONMESSAGE_PUSH:
|
||||||
UUID uuid = new UUID(uuid_high, uuid_low);
|
|
||||||
|
|
||||||
if (endpoint == ENDPOINT_LAUNCHER) {
|
if (endpoint == ENDPOINT_LAUNCHER) {
|
||||||
LOG.info("got LAUNCHER PUSH from UUID " + uuid);
|
LOG.info("got LAUNCHER PUSH from UUID " + uuid);
|
||||||
break;
|
break;
|
||||||
|
@ -2318,6 +2320,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_APPREORDER:
|
case ENDPOINT_APPREORDER:
|
||||||
devEvts = new GBDeviceEvent[]{decodeAppReorder(buf)};
|
devEvts = new GBDeviceEvent[]{decodeAppReorder(buf)};
|
||||||
|
break;
|
||||||
|
case ENDPOINT_APPLOGS:
|
||||||
|
decodeAppLogs(buf);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2325,8 +2331,24 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return devEvts;
|
return devEvts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setForceProtocol(boolean force) {
|
void setForceProtocol(boolean force) {
|
||||||
LOG.info("setting force protocol to " + force);
|
LOG.info("setting force protocol to " + force);
|
||||||
mForceProtocol = force;
|
mForceProtocol = force;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getFixedString(ByteBuffer buf, int length) {
|
||||||
|
byte[] tmp = new byte[length];
|
||||||
|
buf.get(tmp, 0, length);
|
||||||
|
|
||||||
|
return new String(tmp).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID getUUID(ByteBuffer buf) {
|
||||||
|
ByteOrder byteOrder = buf.order();
|
||||||
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
long uuid_high = buf.getLong();
|
||||||
|
long uuid_low = buf.getLong();
|
||||||
|
buf.order(byteOrder);
|
||||||
|
return new UUID(uuid_high, uuid_low);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,9 @@
|
||||||
<string name="pref_summary_pebble_forceuntested">Enable features that are untested. ENABLE ONLY IF YOU KNOW WHAT YOU ARE DOING!</string>
|
<string name="pref_summary_pebble_forceuntested">Enable features that are untested. ENABLE ONLY IF YOU KNOW WHAT YOU ARE DOING!</string>
|
||||||
<string name="pref_title_pebble_forcele">Always prefer BLE</string>
|
<string name="pref_title_pebble_forcele">Always prefer BLE</string>
|
||||||
<string name="pref_summary_pebble_forcele">Use experimental Pebble LE support for all Pebbles instead of BT classic, requires paring a "Pebble LE" after non LE had been connected once</string>
|
<string name="pref_summary_pebble_forcele">Use experimental Pebble LE support for all Pebbles instead of BT classic, requires paring a "Pebble LE" after non LE had been connected once</string>
|
||||||
|
<string name="pref_title_pebble_enable_applogs">Enable Watch App Logging</string>
|
||||||
|
<string name="pref_summary_pebble_enable_applogs">Will cause logs from watch apps to be logged by Gadgetbridge (requires reconnect)</string>
|
||||||
|
|
||||||
<string name="pref_title_pebble_reconnect_attempts">Reconnection Attempts</string>
|
<string name="pref_title_pebble_reconnect_attempts">Reconnection Attempts</string>
|
||||||
|
|
||||||
<string name="not_connected">not connected</string>
|
<string name="not_connected">not connected</string>
|
||||||
|
|
|
@ -341,6 +341,11 @@
|
||||||
android:key="pebble_force_le"
|
android:key="pebble_force_le"
|
||||||
android:summary="@string/pref_summary_pebble_forcele"
|
android:summary="@string/pref_summary_pebble_forcele"
|
||||||
android:title="@string/pref_title_pebble_forcele" />
|
android:title="@string/pref_title_pebble_forcele" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="pebble_enable_applogs"
|
||||||
|
android:summary="@string/pref_summary_pebble_enable_applogs"
|
||||||
|
android:title="@string/pref_title_pebble_enable_applogs" />
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:digits="0123456789."
|
android:digits="0123456789."
|
||||||
android:key="pebble_emu_addr"
|
android:key="pebble_emu_addr"
|
||||||
|
|
Loading…
Reference in New Issue