GBDeviceProtocol::decodeResponse() now returns an array GBDeviceEvents
This allowed to remove some ugly hacks from pebble code, when encoding a response in a GBDeviceEventSendBytes and at the same time trying to notify generic code via another GBDeviceEnvent.
This commit is contained in:
parent
027e6fe8c3
commit
44c7f99c58
|
@ -33,7 +33,7 @@ public class GadgetbridgePblSupport {
|
|||
mPebbleProtocol = pebbleProtocol;
|
||||
}
|
||||
|
||||
public GBDeviceEvent handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||
int timestamp = 0;
|
||||
for (Pair<Integer, Object> pair : pairs) {
|
||||
switch (pair.first) {
|
||||
|
@ -75,6 +75,6 @@ public class GadgetbridgePblSupport {
|
|||
}
|
||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||
sendBytes.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
||||
return sendBytes;
|
||||
return new GBDeviceEvent[]{sendBytes};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.util.Pair;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
@ -41,7 +40,6 @@ public class MorpheuzSupport {
|
|||
public static final UUID uuid = UUID.fromString("5be44f1d-d262-4ea6-aa30-ddbec1e3cab2");
|
||||
private final PebbleProtocol mPebbleProtocol;
|
||||
|
||||
private boolean sent_to_gadgetbridge = false;
|
||||
// data received from Morpheuz in native format
|
||||
private int smartalarm_from = -1; // time in minutes relative from 0:00 for smart alarm (earliest)
|
||||
private int smartalarm_to = -1;// time in minutes relative from 0:00 for smart alarm (latest)
|
||||
|
@ -57,21 +55,15 @@ public class MorpheuzSupport {
|
|||
private byte[] encodeMorpheuzMessage(int key, int value) {
|
||||
ArrayList<Pair<Integer, Object>> pairs = new ArrayList<>();
|
||||
pairs.add(new Pair<Integer, Object>(key, value));
|
||||
byte[] ackMessage = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
||||
byte[] testMessage = mPebbleProtocol.encodeApplicationMessagePush(PebbleProtocol.ENDPOINT_APPLICATIONMESSAGE, uuid, pairs);
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(ackMessage.length + testMessage.length);
|
||||
|
||||
// encode ack and put in front of push message (hack for acknowledging the last message)
|
||||
buf.put(ackMessage);
|
||||
buf.put(testMessage);
|
||||
|
||||
return buf.array();
|
||||
return mPebbleProtocol.encodeApplicationMessagePush(PebbleProtocol.ENDPOINT_APPLICATIONMESSAGE, uuid, pairs);
|
||||
}
|
||||
|
||||
public GBDeviceEvent handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||
int ctrl_message = 0;
|
||||
GBDeviceEventSleepMonitorResult sleepMonitorResult = null;
|
||||
|
||||
for (Pair<Integer, Object> pair : pairs) {
|
||||
int ctrl_message = 0;
|
||||
switch (pair.first) {
|
||||
case KEY_TRANSMIT:
|
||||
case KEY_GONEOFF:
|
||||
|
@ -79,22 +71,11 @@ public class MorpheuzSupport {
|
|||
alarm_gone_off = (int) pair.second;
|
||||
LOG.info("got gone off: " + alarm_gone_off / 60 + ":" + alarm_gone_off % 60);
|
||||
}
|
||||
/* super-ugly hack: if if did not notice GadgetBridge yet, do so and delay confirmation so Morpheuz
|
||||
* will resend gone off data. The second time, we acknowledge it.
|
||||
*
|
||||
* this can be fixed by allowing to return multiple GBDeviceCommands
|
||||
*/
|
||||
if (sent_to_gadgetbridge) {
|
||||
ctrl_message = MorpheuzSupport.CTRL_VERSION_DONE | MorpheuzSupport.CTRL_GONEOFF_DONE | MorpheuzSupport.CTRL_TRANSMIT_DONE | MorpheuzSupport.CTRL_SET_LAST_SENT;
|
||||
} else {
|
||||
GBDeviceEventSleepMonitorResult sleepMonitorResult = new GBDeviceEventSleepMonitorResult();
|
||||
sleepMonitorResult.smartalarm_from = smartalarm_from;
|
||||
sleepMonitorResult.smartalarm_to = smartalarm_to;
|
||||
sleepMonitorResult.alarm_gone_off = alarm_gone_off;
|
||||
sleepMonitorResult.recording_base_timestamp = recording_base_timestamp;
|
||||
sent_to_gadgetbridge = true;
|
||||
return sleepMonitorResult;
|
||||
}
|
||||
sleepMonitorResult = new GBDeviceEventSleepMonitorResult();
|
||||
sleepMonitorResult.smartalarm_from = smartalarm_from;
|
||||
sleepMonitorResult.smartalarm_to = smartalarm_to;
|
||||
sleepMonitorResult.alarm_gone_off = alarm_gone_off;
|
||||
sleepMonitorResult.recording_base_timestamp = recording_base_timestamp;
|
||||
break;
|
||||
case KEY_POINT:
|
||||
if (recording_base_timestamp == -1) {
|
||||
|
@ -140,7 +121,6 @@ public class MorpheuzSupport {
|
|||
case KEY_VERSION:
|
||||
LOG.info("got version: " + ((float) ((int) pair.second) / 10.0f));
|
||||
ctrl_message = MorpheuzSupport.CTRL_VERSION_DONE | MorpheuzSupport.CTRL_SET_LAST_SENT;
|
||||
sent_to_gadgetbridge = false;
|
||||
break;
|
||||
case KEY_BASE:
|
||||
// fix timestamp
|
||||
|
@ -156,14 +136,20 @@ public class MorpheuzSupport {
|
|||
LOG.info("unhandled key: " + pair.first);
|
||||
break;
|
||||
}
|
||||
if (ctrl_message > 0) {
|
||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||
sendBytes.encodedBytes = encodeMorpheuzMessage(MorpheuzSupport.KEY_CTRL, ctrl_message);
|
||||
return sendBytes;
|
||||
}
|
||||
}
|
||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||
sendBytes.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
||||
return sendBytes;
|
||||
|
||||
// always ack
|
||||
GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes();
|
||||
sendBytesAck.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
||||
|
||||
// sometimes send control message
|
||||
GBDeviceEventSendBytes sendBytesCtrl = null;
|
||||
if (ctrl_message > 0) {
|
||||
sendBytesCtrl = new GBDeviceEventSendBytes();
|
||||
sendBytesCtrl.encodedBytes = encodeMorpheuzMessage(MorpheuzSupport.KEY_CTRL, ctrl_message);
|
||||
}
|
||||
|
||||
// ctrl and sleep monitor might be null, thats okay
|
||||
return new GBDeviceEvent[]{sendBytesAck, sendBytesCtrl, sleepMonitorResult};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,12 +237,17 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
|||
mInStream.skip(2);
|
||||
}
|
||||
|
||||
GBDeviceEvent deviceEvent = mPebbleProtocol.decodeResponse(buffer);
|
||||
if (deviceEvent == null) {
|
||||
GBDeviceEvent deviceEvents[] = mPebbleProtocol.decodeResponse(buffer);
|
||||
if (deviceEvents == null) {
|
||||
LOG.info("unhandled message to endpoint " + endpoint + " (" + length + " bytes)");
|
||||
} else {
|
||||
if (!evaluateGBDeviceEventPebble(deviceEvent)) {
|
||||
mPebbleSupport.evaluateGBDeviceEvent(deviceEvent);
|
||||
for (GBDeviceEvent deviceEvent : deviceEvents) {
|
||||
if (deviceEvent == null) {
|
||||
continue;
|
||||
}
|
||||
if (!evaluateGBDeviceEventPebble(deviceEvent)) {
|
||||
mPebbleSupport.evaluateGBDeviceEvent(deviceEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
|
|
@ -1059,15 +1059,31 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
return null;
|
||||
}
|
||||
|
||||
private GBDeviceEventDismissNotification decodeNotificationAction(ByteBuffer buf) {
|
||||
private GBDeviceEventDismissNotification decodeNotificationAction2x(ByteBuffer buf) {
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
byte command = buf.get();
|
||||
if (command == 0x02) { // dismiss notification ?
|
||||
if (isFw3x) {
|
||||
buf.getLong(); // skip 8 bytes of UUID
|
||||
buf.getInt(); // skip 4 bytes of UUID
|
||||
int id = buf.getInt();
|
||||
short action = buf.getShort(); // at least the low byte should be the action - or not?
|
||||
if (action == 0x0001) {
|
||||
GBDeviceEventDismissNotification devEvtDismissNotification = new GBDeviceEventDismissNotification();
|
||||
devEvtDismissNotification.notificationID = id;
|
||||
return devEvtDismissNotification;
|
||||
}
|
||||
LOG.info("unexpected paramerter in dismiss action: " + action);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private GBDeviceEventDismissNotification decodeNotificationAction3x(ByteBuffer buf) {
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
byte command = buf.get();
|
||||
if (command == 0x02) { // dismiss notification ?
|
||||
buf.getLong(); // skip 8 bytes of UUID
|
||||
buf.getInt(); // skip 4 bytes of UUID
|
||||
int id = buf.getInt();
|
||||
short action = buf.getShort(); // at least the low byte should be the action - or not?
|
||||
if (action == 0x0001) {
|
||||
|
@ -1114,26 +1130,31 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
private GBDeviceEventSendBytes decodeDatalog(ByteBuffer buf, short length) {
|
||||
byte command = buf.get();
|
||||
byte id = buf.get();
|
||||
if (command == DATALOG_TIMEOUT) {
|
||||
LOG.info("DATALOG TIMEOUT. id=" + (id & 0xff) + " - ignoring");
|
||||
return null;
|
||||
}
|
||||
if (command == DATALOG_SENDDATA) {
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
int items_left = buf.getInt();
|
||||
int crc = buf.getInt();
|
||||
LOG.info("DATALOG SENDDATA. id=" + (id & 0xff) + ", items_left=" + items_left + ", total length=" + (length - 9));
|
||||
} else if (command == DATALOG_OPENSESSION) {
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
long uuid_high = buf.getLong();
|
||||
long uuid_low = buf.getLong();
|
||||
UUID uuid = new UUID(uuid_high, uuid_low);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
int timestamp = buf.getInt();
|
||||
int log_tag = buf.getInt();
|
||||
byte item_type = buf.get();
|
||||
short item_size = buf.get();
|
||||
LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", item_type=" + item_type + ", item_size=" + item_size);
|
||||
switch (command) {
|
||||
case DATALOG_TIMEOUT:
|
||||
LOG.info("DATALOG TIMEOUT. id=" + (id & 0xff) + " - ignoring");
|
||||
return null;
|
||||
case DATALOG_SENDDATA:
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
int items_left = buf.getInt();
|
||||
int crc = buf.getInt();
|
||||
LOG.info("DATALOG SENDDATA. id=" + (id & 0xff) + ", items_left=" + items_left + ", total length=" + (length - 9));
|
||||
break;
|
||||
case DATALOG_OPENSESSION:
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
long uuid_high = buf.getLong();
|
||||
long uuid_low = buf.getLong();
|
||||
UUID uuid = new UUID(uuid_high, uuid_low);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
int timestamp = buf.getInt();
|
||||
int log_tag = buf.getInt();
|
||||
byte item_type = buf.get();
|
||||
short item_size = buf.get();
|
||||
LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", item_type=" + item_type + ", item_size=" + item_size);
|
||||
break;
|
||||
default:
|
||||
LOG.info("unknown DATALOG command: " + (command & 0xff));
|
||||
break;
|
||||
}
|
||||
LOG.info("sending ACK (0x85)");
|
||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||
|
@ -1142,12 +1163,12 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GBDeviceEvent decodeResponse(byte[] responseData) {
|
||||
public GBDeviceEvent[] decodeResponse(byte[] responseData) {
|
||||
ByteBuffer buf = ByteBuffer.wrap(responseData);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
short length = buf.getShort();
|
||||
short endpoint = buf.getShort();
|
||||
GBDeviceEvent devEvt = null;
|
||||
GBDeviceEvent devEvts[] = null;
|
||||
byte pebbleCmd = -1;
|
||||
switch (endpoint) {
|
||||
case ENDPOINT_MUSICCONTROL:
|
||||
|
@ -1178,7 +1199,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
devEvt = musicCmd;
|
||||
devEvts = new GBDeviceEvent[]{musicCmd};
|
||||
break;
|
||||
case ENDPOINT_PHONECONTROL:
|
||||
pebbleCmd = buf.get();
|
||||
|
@ -1191,7 +1212,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
LOG.info("Unknown PHONECONTROL event" + pebbleCmd);
|
||||
break;
|
||||
}
|
||||
devEvt = callCmd;
|
||||
devEvts = new GBDeviceEvent[]{callCmd};
|
||||
break;
|
||||
case ENDPOINT_FIRMWAREVERSION:
|
||||
pebbleCmd = buf.get();
|
||||
|
@ -1213,7 +1234,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
} else if (hwRev == -3) { // basalt emulator
|
||||
versionCmd.hwVersion = "dvt";
|
||||
}
|
||||
devEvt = versionCmd;
|
||||
devEvts = new GBDeviceEvent[]{versionCmd};
|
||||
break;
|
||||
case ENDPOINT_APPMANAGER:
|
||||
pebbleCmd = buf.get();
|
||||
|
@ -1253,12 +1274,12 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
break;
|
||||
}
|
||||
}
|
||||
devEvt = appInfoCmd;
|
||||
devEvts = new GBDeviceEvent[]{appInfoCmd};
|
||||
break;
|
||||
case APPMANAGER_GETUUIDS:
|
||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||
sendBytes.encodedBytes = encodeSimpleMessage(ENDPOINT_APPMANAGER, APPMANAGER_GETAPPBANKSTATUS);
|
||||
devEvt = sendBytes;
|
||||
devEvts = new GBDeviceEvent[]{sendBytes};
|
||||
tmpUUIDS.clear();
|
||||
slotsUsed = buf.getInt();
|
||||
for (int i = 0; i < slotsUsed; i++) {
|
||||
|
@ -1282,7 +1303,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
deleteRes.event = GBDeviceEventAppManagement.Event.FAILURE;
|
||||
break;
|
||||
}
|
||||
devEvt = deleteRes;
|
||||
devEvts = new GBDeviceEvent[]{deleteRes};
|
||||
break;
|
||||
default:
|
||||
LOG.info("Unknown APPMANAGER event" + pebbleCmd);
|
||||
|
@ -1303,7 +1324,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
installRes.event = GBDeviceEventAppManagement.Event.FAILURE;
|
||||
break;
|
||||
}
|
||||
devEvt = installRes;
|
||||
devEvts = new GBDeviceEvent[]{installRes};
|
||||
break;
|
||||
case ENDPOINT_APPLICATIONMESSAGE:
|
||||
pebbleCmd = buf.get();
|
||||
|
@ -1317,13 +1338,13 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
LOG.info("got APPLICATIONMESSAGE PUSH from UUID " + uuid);
|
||||
if (WeatherNeatSupport.uuid.equals(uuid)) {
|
||||
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
||||
devEvt = mWeatherNeatSupport.handleMessage(dict);
|
||||
devEvts = mWeatherNeatSupport.handleMessage(dict);
|
||||
} else if (MorpheuzSupport.uuid.equals(uuid)) {
|
||||
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
||||
devEvt = mMorpheuzSupport.handleMessage(dict);
|
||||
devEvts = mMorpheuzSupport.handleMessage(dict);
|
||||
} else if (GadgetbridgePblSupport.uuid.equals(uuid)) {
|
||||
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
||||
devEvt = mGadgetbridgePblSupport.handleMessage(dict);
|
||||
devEvts = mGadgetbridgePblSupport.handleMessage(dict);
|
||||
}
|
||||
break;
|
||||
case APPLICATIONMESSAGE_ACK:
|
||||
|
@ -1346,33 +1367,35 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||
LOG.info("Pebble asked for Phone/App Version - repLYING!");
|
||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||
sendBytes.encodedBytes = encodePhoneVersion(PHONEVERSION_REMOTE_OS_ANDROID);
|
||||
devEvt = sendBytes;
|
||||
devEvts = new GBDeviceEvent[]{sendBytes};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ENDPOINT_DATALOG:
|
||||
devEvt = decodeDatalog(buf, length);
|
||||
devEvts = new GBDeviceEvent[]{decodeDatalog(buf, length)};
|
||||
break;
|
||||
case ENDPOINT_SCREENSHOT:
|
||||
devEvt = decodeScreenshot(buf, length);
|
||||
devEvts = new GBDeviceEvent[]{decodeScreenshot(buf, length)};
|
||||
break;
|
||||
case ENDPOINT_EXTENSIBLENOTIFS:
|
||||
devEvts = new GBDeviceEvent[]{decodeNotificationAction2x(buf)};
|
||||
break;
|
||||
case ENDPOINT_NOTIFICATIONACTION:
|
||||
devEvt = decodeNotificationAction(buf);
|
||||
devEvts = new GBDeviceEvent[]{decodeNotificationAction3x(buf)};
|
||||
break;
|
||||
case ENDPOINT_PING:
|
||||
devEvt = decodePing(buf);
|
||||
devEvts = new GBDeviceEvent[]{decodePing(buf)};
|
||||
break;
|
||||
case ENDPOINT_APPFETCH:
|
||||
devEvt = decodeAppFetch(buf);
|
||||
devEvts = new GBDeviceEvent[]{decodeAppFetch(buf)};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return devEvt;
|
||||
return devEvts;
|
||||
}
|
||||
|
||||
public void setForceProtocol(boolean force) {
|
||||
|
|
|
@ -48,9 +48,9 @@ public class WeatherNeatSupport {
|
|||
return buf.array();
|
||||
}
|
||||
|
||||
public GBDeviceEvent handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||
sendBytes.encodedBytes = encodeWeatherNeatMessage("Berlin", "22 C", "cloudy", 0);
|
||||
return sendBytes;
|
||||
return new GBDeviceEvent[] {sendBytes};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public abstract class GBDeviceProtocol {
|
|||
return null;
|
||||
}
|
||||
|
||||
public GBDeviceEvent decodeResponse(byte[] responseData) {
|
||||
public GBDeviceEvent[] decodeResponse(byte[] responseData) {
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue