Pebble: Experiment with 3.x compatible notifications
This will most probably not work, but please test if you can ;)
This commit is contained in:
parent
4908fe7a53
commit
a07aed62ad
|
@ -86,6 +86,9 @@ public class GB {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String hexdump(byte[] buffer, int offset, int length) {
|
public static String hexdump(byte[] buffer, int offset, int length) {
|
||||||
|
if (length == -1 ) {
|
||||||
|
length = buffer.length;
|
||||||
|
}
|
||||||
final char[] hexArray = "0123456789ABCDEF".toCharArray();
|
final char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||||
char[] hexChars = new char[length * 2];
|
char[] hexChars = new char[length * 2];
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
|
|
|
@ -28,7 +28,6 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(PebbleProtocol.class);
|
private static final Logger LOG = LoggerFactory.getLogger(PebbleProtocol.class);
|
||||||
|
|
||||||
static final short ENDPOINT_FIRMWARE = 1;
|
|
||||||
static final short ENDPOINT_TIME = 11;
|
static final short ENDPOINT_TIME = 11;
|
||||||
static final short ENDPOINT_FIRMWAREVERSION = 16;
|
static final short ENDPOINT_FIRMWAREVERSION = 16;
|
||||||
public static final short ENDPOINT_PHONEVERSION = 17;
|
public static final short ENDPOINT_PHONEVERSION = 17;
|
||||||
|
@ -52,6 +51,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
public static final short ENDPOINT_DATALOG = 6778;
|
public static final short ENDPOINT_DATALOG = 6778;
|
||||||
static final short ENDPOINT_RUNKEEPER = 7000;
|
static final short ENDPOINT_RUNKEEPER = 7000;
|
||||||
static final short ENDPOINT_SCREENSHOT = 8000;
|
static final short ENDPOINT_SCREENSHOT = 8000;
|
||||||
|
static final short ENDPOINT_BLOBDB = (short) 45531; // 3.x only
|
||||||
static final short ENDPOINT_PUTBYTES = (short) 48879;
|
static final short ENDPOINT_PUTBYTES = (short) 48879;
|
||||||
|
|
||||||
static final byte NOTIFICATION_EMAIL = 0;
|
static final byte NOTIFICATION_EMAIL = 0;
|
||||||
|
@ -223,7 +223,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
|
|
||||||
if (isFw3x) {
|
if (isFw3x) {
|
||||||
String[] parts = {from, null, body};
|
String[] parts = {from, null, body};
|
||||||
return encodeExtensibleNotification(mRandom.nextInt(), (int) (ts & 0xffffffff), parts);
|
return encodeBlobdbNotification((int) (ts & 0xffffffff), parts);
|
||||||
} else {
|
} else {
|
||||||
String[] parts = {from, body, ts.toString()};
|
String[] parts = {from, body, ts.toString()};
|
||||||
return encodeMessage(ENDPOINT_NOTIFICATION, NOTIFICATION_SMS, 0, parts);
|
return encodeMessage(ENDPOINT_NOTIFICATION, NOTIFICATION_SMS, 0, parts);
|
||||||
|
@ -238,7 +238,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
|
|
||||||
if (isFw3x) {
|
if (isFw3x) {
|
||||||
String[] parts = {from, subject, body};
|
String[] parts = {from, subject, body};
|
||||||
return encodeExtensibleNotification(mRandom.nextInt(), (int) (ts & 0xffffffff), parts);
|
return encodeBlobdbNotification((int) (ts & 0xffffffff), parts);
|
||||||
} else {
|
} else {
|
||||||
String[] parts = {from, body, ts.toString(), subject};
|
String[] parts = {from, body, ts.toString(), subject};
|
||||||
return encodeMessage(ENDPOINT_NOTIFICATION, NOTIFICATION_EMAIL, 0, parts);
|
return encodeMessage(ENDPOINT_NOTIFICATION, NOTIFICATION_EMAIL, 0, parts);
|
||||||
|
@ -331,6 +331,78 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static byte[] encodeBlobdbNotification(int timestamp, String[] parts) {
|
||||||
|
// Calculate length first
|
||||||
|
final short BLOBDB_LENGTH = 23;
|
||||||
|
final short NOTIFICATION_PIN_LENGTH = 46;
|
||||||
|
|
||||||
|
byte attributes_count = 0;
|
||||||
|
|
||||||
|
int attributes_length = 0;
|
||||||
|
if (parts != null) {
|
||||||
|
for (String s : parts) {
|
||||||
|
if (s == null || s.equals("")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attributes_count++;
|
||||||
|
attributes_length += (3 + s.getBytes().length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = BLOBDB_LENGTH + NOTIFICATION_PIN_LENGTH + attributes_length;
|
||||||
|
|
||||||
|
// Encode Prefix
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(length + LENGTH_PREFIX);
|
||||||
|
|
||||||
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
buf.putShort((short) (length));
|
||||||
|
buf.putShort(ENDPOINT_BLOBDB);
|
||||||
|
|
||||||
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
// blobdb - 23 bytes
|
||||||
|
buf.put((byte) 0x01); // insert
|
||||||
|
buf.putShort((short) mRandom.nextInt()); // token
|
||||||
|
buf.put((byte) 0x04); // db id (0x04 = notification)
|
||||||
|
buf.put((byte) 16); // uuid length
|
||||||
|
byte[] uuid_buf = new byte[16];
|
||||||
|
mRandom.nextBytes(uuid_buf);
|
||||||
|
buf.put(uuid_buf); // random UUID
|
||||||
|
buf.putShort((short) (NOTIFICATION_PIN_LENGTH + attributes_length)); // length of the encapsulated data
|
||||||
|
|
||||||
|
// pin - 46 bytes
|
||||||
|
buf.put(uuid_buf); // random UUID
|
||||||
|
Arrays.fill(uuid_buf, (byte) 0);
|
||||||
|
buf.put(uuid_buf); // parent UUID
|
||||||
|
buf.putInt(timestamp); // 32-bit timestamp
|
||||||
|
buf.putShort((short) 0); // duration
|
||||||
|
buf.put((byte) 0x01); // type (0x01 = notification)
|
||||||
|
buf.putShort((short) 0x0010); // flags 0x0010 = read?
|
||||||
|
buf.put((byte) 0x01); // layout (0x01 = default?)
|
||||||
|
buf.putShort((short) attributes_length); // total length of all attributes in bytes
|
||||||
|
buf.put(attributes_count); // count attributes
|
||||||
|
buf.put((byte) 0); // count actions - none so far
|
||||||
|
|
||||||
|
byte attribute_id = 0;
|
||||||
|
// Encode Pascal-Style Strings
|
||||||
|
if (parts != null) {
|
||||||
|
for (String s : parts) {
|
||||||
|
attribute_id++;
|
||||||
|
if (s == null || s.equals("")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int partlength = s.getBytes().length;
|
||||||
|
if (partlength > 255) partlength = 255;
|
||||||
|
buf.put(attribute_id);
|
||||||
|
buf.putShort((short) partlength);
|
||||||
|
buf.put(s.getBytes(), 0, partlength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.array();
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] encodeGetTime() {
|
public byte[] encodeGetTime() {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_GETTIME);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_GETTIME);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
|
Loading…
Reference in New Issue