mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 18:15:49 +01:00
Pebble: implement weather related protocol encoding
this is not yet connected to anything...
This commit is contained in:
parent
b045d5ac26
commit
240c81ecb4
@ -87,8 +87,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
static final byte BLOBDB_APP = 2;
|
static final byte BLOBDB_APP = 2;
|
||||||
static final byte BLOBDB_REMINDER = 3;
|
static final byte BLOBDB_REMINDER = 3;
|
||||||
static final byte BLOBDB_NOTIFICATION = 4;
|
static final byte BLOBDB_NOTIFICATION = 4;
|
||||||
|
static final byte BLOBDB_WEATHER = 5;
|
||||||
static final byte BLOBDB_CANNED_MESSAGES = 6;
|
static final byte BLOBDB_CANNED_MESSAGES = 6;
|
||||||
static final byte BLOBDB_PREFERENCES = 7;
|
static final byte BLOBDB_PREFERENCES = 7;
|
||||||
|
static final byte BLOBDB_APPSETTINGS = 9;
|
||||||
static final byte BLOBDB_APPGLANCE = 11;
|
static final byte BLOBDB_APPGLANCE = 11;
|
||||||
|
|
||||||
static final byte BLOBDB_SUCCESS = 1;
|
static final byte BLOBDB_SUCCESS = 1;
|
||||||
@ -378,6 +380,8 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
|
|
||||||
private static final UUID UUID_ZERO = new UUID(0, 0);
|
private static final UUID UUID_ZERO = new UUID(0, 0);
|
||||||
|
|
||||||
|
private static final UUID UUID_LOCATION = UUID.fromString("2c7e6a86-51e5-4ddd-b606-db43d1e4ad28"); // might be the location of "Berlin" or "Auto"
|
||||||
|
|
||||||
private final Map<UUID, AppMessageHandler> mAppMessageHandlers = new HashMap<>();
|
private final Map<UUID, AppMessageHandler> mAppMessageHandlers = new HashMap<>();
|
||||||
|
|
||||||
public PebbleProtocol(GBDevice device) {
|
public PebbleProtocol(GBDevice device) {
|
||||||
@ -534,7 +538,15 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] encodeFindDevice(boolean start) {
|
public byte[] encodeFindDevice(boolean start) {
|
||||||
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);
|
||||||
|
int ts = (int) (System.currentTimeMillis() / 1000);
|
||||||
|
|
||||||
|
if (start) {
|
||||||
|
return encodeActivateWeather(true);
|
||||||
|
} else {
|
||||||
|
//return encodeWeatherPin(ts, "Weather", "1°/-1°", "Gadgetbridge is Sunny", "Berlin", 37);
|
||||||
|
return encodeWeatherForecast(ts, "Berlin", 0, 5, -5, 1, "Sexy", 7, 2, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private 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) {
|
||||||
@ -765,6 +777,21 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
activate ? new byte[]{0x01} : new byte[]{0x00});
|
activate ? new byte[]{0x01} : new byte[]{0x00});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] encodeActivateWeather(boolean activate) {
|
||||||
|
if (activate) {
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(0x61);
|
||||||
|
buf.put((byte) 1);
|
||||||
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
buf.putLong(UUID_LOCATION.getMostSignificantBits());
|
||||||
|
buf.putLong(UUID_LOCATION.getLeastSignificantBits());
|
||||||
|
// disable remaining 5 possible location
|
||||||
|
buf.put(new byte[60 - 16]);
|
||||||
|
return encodeBlobdb("weatherApp", BLOBDB_INSERT, BLOBDB_APPSETTINGS, buf.array());
|
||||||
|
} else {
|
||||||
|
return encodeBlobdb("weatherApp", BLOBDB_DELETE, BLOBDB_APPSETTINGS, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
byte[] encodeReportDataLogSessions() {
|
byte[] encodeReportDataLogSessions() {
|
||||||
return encodeSimpleMessage(ENDPOINT_DATALOG, DATALOG_REPORTSESSIONS);
|
return encodeSimpleMessage(ENDPOINT_DATALOG, DATALOG_REPORTSESSIONS);
|
||||||
}
|
}
|
||||||
@ -1005,6 +1032,149 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] encodeWeatherPin(int timestamp, String title, String subtitle, String body, String location, int iconId) {
|
||||||
|
final short NOTIFICATION_PIN_LENGTH = 46;
|
||||||
|
final short ACTION_LENGTH_MIN = 10;
|
||||||
|
|
||||||
|
String[] parts = {title, subtitle, body, location, "test", "test"};
|
||||||
|
|
||||||
|
// Calculate length first
|
||||||
|
byte actions_count = 1;
|
||||||
|
short actions_length;
|
||||||
|
String remove_string = "Remove";
|
||||||
|
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + remove_string.getBytes().length);
|
||||||
|
|
||||||
|
byte attributes_count = 3;
|
||||||
|
short attributes_length = (short) (21 + actions_length);
|
||||||
|
if (parts != null) {
|
||||||
|
for (String s : parts) {
|
||||||
|
if (s == null || s.equals("")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attributes_count++;
|
||||||
|
attributes_length += (3 + s.getBytes().length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID uuid = UUID.fromString("61b22bc8-1e29-460d-a236-3fe409a43901");
|
||||||
|
|
||||||
|
short pin_length = (short) (NOTIFICATION_PIN_LENGTH + attributes_length);
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(pin_length);
|
||||||
|
|
||||||
|
// pin (46 bytes)
|
||||||
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
buf.putLong(uuid.getMostSignificantBits());
|
||||||
|
buf.putLong(uuid.getLeastSignificantBits());
|
||||||
|
buf.putLong(uuid.getMostSignificantBits());
|
||||||
|
buf.putLong(uuid.getLeastSignificantBits() | 0xff);
|
||||||
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
buf.putInt(timestamp); // 32-bit timestamp
|
||||||
|
buf.putShort((short) 0); // duration
|
||||||
|
buf.put((byte) 0x02); // type (0x02 = pin)
|
||||||
|
buf.putShort((short) 0x0001); // flags 0x0001 = ?
|
||||||
|
buf.put((byte) 0x06); // layout (0x06 = weather)
|
||||||
|
buf.putShort(attributes_length); // total length of all attributes and actions in bytes
|
||||||
|
buf.put(attributes_count);
|
||||||
|
buf.put(actions_count);
|
||||||
|
|
||||||
|
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 > 512) partlength = 512;
|
||||||
|
if (attribute_id == 4) {
|
||||||
|
buf.put((byte) 11);
|
||||||
|
} else if (attribute_id == 5) {
|
||||||
|
buf.put((byte) 25);
|
||||||
|
} else if (attribute_id == 6) {
|
||||||
|
buf.put((byte) 26);
|
||||||
|
} else {
|
||||||
|
buf.put(attribute_id);
|
||||||
|
}
|
||||||
|
buf.putShort((short) partlength);
|
||||||
|
buf.put(s.getBytes(), 0, partlength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.put((byte) 4); // icon
|
||||||
|
buf.putShort((short) 4); // length of int
|
||||||
|
buf.putInt(0x80000000 | iconId);
|
||||||
|
|
||||||
|
buf.put((byte) 6); // icon
|
||||||
|
buf.putShort((short) 4); // length of int
|
||||||
|
buf.putInt(0x80000000 | iconId);
|
||||||
|
|
||||||
|
buf.put((byte) 14); // last updated
|
||||||
|
buf.putShort((short) 4); // length of int
|
||||||
|
buf.putInt(timestamp);
|
||||||
|
|
||||||
|
// remove action
|
||||||
|
buf.put((byte) 123); // action id
|
||||||
|
buf.put((byte) 0x09); // remove
|
||||||
|
buf.put((byte) 0x01); // number attributes
|
||||||
|
buf.put((byte) 0x01); // attribute id (title)
|
||||||
|
buf.putShort((short) remove_string.getBytes().length);
|
||||||
|
buf.put(remove_string.getBytes());
|
||||||
|
|
||||||
|
return encodeBlobdb(uuid, BLOBDB_INSERT, BLOBDB_PIN, buf.array());
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] encodeWeatherForecast(int timestamp, String location, int tempNow, int tempHighToday, int tempLowToday, int conditionCodeToday, String conditionToday, int tempHighTomorrow, int tempLowTomorrow, int conditionCodeTomorrow) {
|
||||||
|
final short WEATHER_FORECAST_LENGTH = 20;
|
||||||
|
|
||||||
|
String[] parts = {location, conditionToday};
|
||||||
|
|
||||||
|
// Calculate length first
|
||||||
|
short attributes_length = 0;
|
||||||
|
if (parts != null) {
|
||||||
|
for (String s : parts) {
|
||||||
|
if (s == null || s.equals("")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attributes_length += (2 + s.getBytes().length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
short pin_length = (short) (WEATHER_FORECAST_LENGTH + attributes_length);
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(pin_length);
|
||||||
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
buf.put((byte) 3); // unknown, always 3?
|
||||||
|
buf.putShort((short) tempNow);
|
||||||
|
buf.put((byte) 1);
|
||||||
|
buf.putShort((short) tempHighToday);
|
||||||
|
buf.putShort((short) tempLowToday);
|
||||||
|
buf.put((byte) 4);
|
||||||
|
buf.putShort((short) tempHighTomorrow);
|
||||||
|
buf.putShort((short) tempLowTomorrow);
|
||||||
|
buf.putInt(timestamp);
|
||||||
|
buf.put((byte) 0); // automatic location
|
||||||
|
buf.putShort(attributes_length);
|
||||||
|
|
||||||
|
// Encode Pascal-Style Strings
|
||||||
|
if (parts != null) {
|
||||||
|
for (String s : parts) {
|
||||||
|
if (s == null || s.equals("")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int partlength = s.getBytes().length;
|
||||||
|
if (partlength > 512) partlength = 512;
|
||||||
|
buf.putShort((short) partlength);
|
||||||
|
buf.put(s.getBytes(), 0, partlength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return encodeBlobdb(UUID_LOCATION, BLOBDB_INSERT, BLOBDB_WEATHER, buf.array());
|
||||||
|
}
|
||||||
|
|
||||||
private 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user