diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java index 4d5d5e4753..ee2fd10b96 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java @@ -190,6 +190,11 @@ public class PebbleCoordinator extends AbstractBLClassicDeviceCoordinator { return true; } + @Override + public boolean supportsDebugLogs(@NonNull GBDevice device) { + return true; + } + @Override public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) { final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 7ff38a2f8b..c5f4be7107 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -65,6 +66,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec.Action; +import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.model.weather.Weather; import nodomain.freeyourgadget.gadgetbridge.model.weather.WeatherMapper; @@ -733,6 +735,26 @@ public class PebbleProtocol extends GBDeviceProtocol { return encodeSimpleMessage(ENDPOINT_DATALOG, DATALOG_REPORTSESSIONS); } + @Override + public byte[] encodeFetchRecordedData(int dataTypes) { + if (dataTypes == RecordedDataTypes.TYPE_DEBUGLOGS) { + return encodeRequestLogDump(0, 0); + } + return null; + } + + byte[] encodeRequestLogDump(int generation, int cookie) { + final short LENGTH_REQUEST_LOGDUMP = 5; + ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REQUEST_LOGDUMP); + buf.order(ByteOrder.BIG_ENDIAN); + buf.putShort(LENGTH_REQUEST_LOGDUMP); + buf.putShort(ENDPOINT_LOGDUMP); + buf.put((byte) generation); + buf.putInt(cookie); + + return buf.array(); + } + private byte[] encodeBlobDBClear(byte database) { final short LENGTH_BLOBDB_CLEAR = 4; ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_BLOBDB_CLEAR); @@ -2060,7 +2082,20 @@ public class PebbleProtocol extends GBDeviceProtocol { int lineNumber = buf.getShort() & 0xffff; String fileName = getFixedString(buf, 16); String message = getFixedString(buf, messageLength); - LOG.debug("APP_LOGS ({}) from uuid {} in {}:{} {}", logLevel, uuid, fileName, lineNumber, message); + LOG.debug("APP_LOGS: {} : ({}) from uuid {} in {}:{} {}", DateTimeUtils.formatIso8601(new Date(timestamp * 1000L)), logLevel, uuid, fileName, lineNumber, message); + } + + private void decodeLogDump(ByteBuffer buf) { + int logLevel = buf.get() & 0xff; + int cookie = buf.getInt(); + int timestamp = buf.getInt(); + buf.get(); + buf.order(ByteOrder.LITTLE_ENDIAN); + int length = buf.getShort(); + short lineNumber = buf.getShort(); + String fileName = getFixedString(buf, 15); + String message = getFixedString(buf, length); + LOG.debug("PEBBLE LOG_DUMP: {} : ({}) in {}:{} {}", DateTimeUtils.formatIso8601(new Date(timestamp * 1000L)), logLevel, fileName, lineNumber, message); } private GBDeviceEvent decodeSystemMessage(ByteBuffer buf) { @@ -2561,6 +2596,9 @@ public class PebbleProtocol extends GBDeviceProtocol { case ENDPOINT_APPLOGS: decodeAppLogs(buf); break; + case ENDPOINT_LOGDUMP: + decodeLogDump(buf); + break; case ENDPOINT_VOICECONTROL: devEvts = new GBDeviceEvent[]{decodeVoiceControl(buf)}; break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java index e2af73d137..cda11e6327 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java @@ -214,7 +214,7 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport @Override public void onFetchRecordedData(int dataTypes) { - byte[] bytes = gbDeviceProtocol.encodeSynchronizeActivityData(); + byte[] bytes = gbDeviceProtocol.encodeFetchRecordedData(dataTypes); sendToDevice(bytes); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java index 69ebaebd74..3442508ac0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java @@ -117,11 +117,6 @@ public abstract class GBDeviceProtocol { return null; } - @Nullable - public byte[] encodeSynchronizeActivityData() { - return null; - } - @Nullable public byte[] encodeReset(int flags) { return null; @@ -217,6 +212,11 @@ public abstract class GBDeviceProtocol { return null; } + @Nullable + public byte[] encodeFetchRecordedData(int dataTypes) { + return null; + } + protected DevicePrefs getDevicePrefs() { return GBApplication.getDevicePrefs(getDevice()); }