Pebble: experiment with extensible notifications
This allows lot more flexible notifications including custom actions (replys, etc) When used without actions it could serve as a simple replacement for the current notifications. The main showstopper is that I do not know how to assign icons (mail, chat) to these. Unfortunately I ended up in recovery when playing around with unknown parameters trial&error style.
This commit is contained in:
parent
2b98620ee0
commit
55400817b4
|
@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
@ -27,6 +28,9 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PebbleProtocol.class);
|
||||
|
||||
// set to false AT YOUR OWN RISK. I ended up in recovery
|
||||
static private final boolean USE_OLD_NOTIFICATION_PROTOCOL = true;
|
||||
|
||||
static final short ENDPOINT_FIRMWARE = 1;
|
||||
static final short ENDPOINT_TIME = 11;
|
||||
static final short ENDPOINT_FIRMWAREVERSION = 16;
|
||||
|
@ -43,6 +47,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
static final short ENDPOINT_APP = 2004;
|
||||
static final short ENDPOINT_APPLOGS = 2006;
|
||||
static final short ENDPOINT_NOTIFICATION = 3000;
|
||||
static final short ENDPOINT_EXTENSIBLENOTIFS = 3010;
|
||||
static final short ENDPOINT_RESOURCE = 4000;
|
||||
static final short ENDPOINT_SYSREG = 5000;
|
||||
static final short ENDPOINT_FCTREG = 5001;
|
||||
|
@ -153,10 +158,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
static final short LENGTH_SYSTEMMESSAGE = 2;
|
||||
|
||||
private static final String[] hwRevisions = {"unknown", "ev1", "ev2", "ev2_3", "ev2_4", "v1_5", "v2_0"};
|
||||
|
||||
private static Random mRandom = new Random();
|
||||
static byte last_id = -1;
|
||||
// FIXME: this does not belong here
|
||||
static final UUID WeatherNeatUUID = UUID.fromString("3684003b-a685-45f9-a713-abc6364ba051");
|
||||
static byte last_id = -1;
|
||||
|
||||
private static byte[] encodeMessage(short endpoint, byte type, int cookie, String[] parts) {
|
||||
// Calculate length first
|
||||
|
@ -207,12 +212,16 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
Long ts = System.currentTimeMillis() / 1000;
|
||||
TimeZone tz = SimpleTimeZone.getDefault();
|
||||
ts += (tz.getOffset(ts) + tz.getDSTSavings()) / 1000;
|
||||
String tsstring = ts.toString(); // SIC
|
||||
String[] parts = {from, body, tsstring};
|
||||
|
||||
if (USE_OLD_NOTIFICATION_PROTOCOL) {
|
||||
String[] parts = {from, body, ts.toString()};
|
||||
return encodeMessage(ENDPOINT_NOTIFICATION, NOTIFICATION_SMS, 0, parts);
|
||||
}
|
||||
|
||||
String[] parts = {from, null, body};
|
||||
return encodeExtensibleNotification(mRandom.nextInt(), (int) (ts & 0xffffffff), parts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encodeEmail(String from, String subject, String body) {
|
||||
Long ts = System.currentTimeMillis() / 1000;
|
||||
|
@ -246,6 +255,71 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
return buf.array();
|
||||
}
|
||||
|
||||
private static byte[] encodeExtensibleNotification(int id, int timestamp, String[] parts) {
|
||||
// Calculate length first
|
||||
byte attributes_count = 0;
|
||||
|
||||
int length = 21;
|
||||
if (parts != null) {
|
||||
for (String s : parts) {
|
||||
if (s == null || s.equals("")) {
|
||||
continue;
|
||||
}
|
||||
attributes_count++;
|
||||
length += (3 + s.getBytes().length);
|
||||
}
|
||||
}
|
||||
|
||||
// Encode Prefix
|
||||
ByteBuffer buf = ByteBuffer.allocate(length + LENGTH_PREFIX);
|
||||
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort((short) (length));
|
||||
buf.putShort(ENDPOINT_EXTENSIBLENOTIFS);
|
||||
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN); // !
|
||||
|
||||
buf.put((byte) 0x00); // ?
|
||||
buf.put((byte) 0x01); // add notifications
|
||||
buf.putInt(0x00000002); // flags - ?
|
||||
buf.putInt(id);
|
||||
buf.putInt(0x00000000); // ANCS id
|
||||
buf.putInt(timestamp);
|
||||
buf.put((byte) 0x01); // layout - ?
|
||||
buf.put(attributes_count); // length attributes
|
||||
buf.put((byte) 0); // len 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);
|
||||
}
|
||||
}
|
||||
// ACTION
|
||||
/*
|
||||
buf.put((byte) 0x01);
|
||||
buf.put((byte) 0x02);
|
||||
buf.put((byte) 0x01);
|
||||
|
||||
String actionstring = "test";
|
||||
|
||||
buf.put((byte) 0x01);
|
||||
buf.putShort((short) 4);
|
||||
buf.put(actionstring.getBytes(), 0, 4);
|
||||
*/
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
public byte[] encodeGetTime() {
|
||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_GETTIME);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
|
|
Loading…
Reference in New Issue