From 0c3c7491496b7ad32c7a6945a63dc0080bd5b313 Mon Sep 17 00:00:00 2001 From: Daniel Dakhno Date: Sat, 17 Oct 2020 03:30:53 +0200 Subject: [PATCH] Fossil Hybrid: use polled supported file versions --- .../adapter/fossil/FossilWatchAdapter.java | 42 ++++++---- .../fossil_hr/FossilHRWatchAdapter.java | 5 ++ .../fossil/alarm/AlarmsSetRequest.java | 21 +---- .../fossil/device_info/DeviceInfo.java | 5 ++ .../device_info/GetDeviceInfoRequest.java | 78 +++++++++++++++++++ .../SupportedFileVersionsInfo.java | 35 +++++++++ .../requests/fossil/file/FilePutRequest.java | 2 +- .../translation/TranslationsPutRequest.java | 2 +- 8 files changed, 156 insertions(+), 34 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceInfo.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/SupportedFileVersionsInfo.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java index a3638414f..c8d2302ae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java @@ -53,6 +53,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.AlarmsSetRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.device_info.DeviceInfo; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.device_info.GetDeviceInfoRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.device_info.SupportedFileVersionsInfo; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest; @@ -87,6 +90,8 @@ public class FossilWatchAdapter extends WatchAdapter { protected Logger logger = LoggerFactory.getLogger(getClass().getSimpleName()); + SupportedFileVersionsInfo supportedFileVersions; + public FossilWatchAdapter(QHybridSupport deviceSupport) { super(deviceSupport); } @@ -98,30 +103,39 @@ public class FossilWatchAdapter extends WatchAdapter { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { queueWrite(new RequestMtuRequest(512), false); } - // queueWrite(new FileCloseRequest((short) 0xFFFF)); - // queueWrite(new ConfigurationGetRequest(this), false); + getDeviceInfos(); + } + + public short getSupportedFileVersion(FileHandle handle){ + return this.supportedFileVersions.getSupportedFileVersion(handle); + } + + protected void initializeWithSupportedFileVersions() { syncConfiguration(); syncNotificationSettings(); syncButtonSettings(); - /* queueWrite(new ButtonConfigurationGetRequest(this) { - @Override - public void onConfigurationsGet(ConfigPayload[] configs) { - super.onConfigurationsGet(configs); - - JSONArray buttons = new JSONArray(); - for (ConfigPayload payload : configs) buttons.put(String.valueOf(payload)); - String json = buttons.toString(); - getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, json)); - } - }); */ - queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false); } + protected void getDeviceInfos(){ + queueWrite(new GetDeviceInfoRequest(this){ + @Override + public void handleDeviceInfos(DeviceInfo[] deviceInfos) { + for(DeviceInfo info : deviceInfos){ + if(info instanceof SupportedFileVersionsInfo){ + FossilWatchAdapter.this.supportedFileVersions = (SupportedFileVersionsInfo) info; + initializeWithSupportedFileVersions(); + return; + } + } + } + }); + } + private void syncButtonSettings(){ String buttonConfig = getDeviceSpecificPreferences().getString(CONFIG_ITEM_BUTTONS, null); getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, buttonConfig)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 82d5a4750..aed780d25 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -137,6 +137,11 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { queueWrite(new RequestMtuRequest(512)); } + getDeviceInfos(); + } + + @Override + protected void initializeWithSupportedFileVersions() { queueWrite(new SetDeviceStateRequest(GBDevice.State.AUTHENTICATING)); negotiateSymmetricKey(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java index 11bb88e6f..1363660ab 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java @@ -29,27 +29,12 @@ import nodomain.freeyourgadget.gadgetbridge.util.Version; public class AlarmsSetRequest extends FilePutRequest { public AlarmsSetRequest(Alarm[] alarms, FossilWatchAdapter adapter) { - super(FileHandle.ALARMS, createFileFromAlarms(alarms, isNewFormat(adapter)), isNewFormat(adapter) ? (short) 3 : (short) 2, adapter); // TODO version 3 + super(FileHandle.ALARMS, createFileFromAlarms(alarms, adapter.getSupportedFileVersion(FileHandle.ALARMS)), adapter); } - static private boolean isNewFormat(FossilWatchAdapter adapter) { - GBDevice device = adapter.getDeviceSupport().getDevice(); - String firmware = device.getFirmwareVersion(); - - Version newFormatVersion = new Version("1.0.2.17"); - Pattern versionPattern = Pattern.compile("([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+)"); - Matcher matcher = versionPattern.matcher(firmware); - - if (matcher.find()) { - String thisVersion = matcher.group(0); - return newFormatVersion.compareTo(new Version(thisVersion)) != 1; - } else { - return false; - } - } - - static public byte[] createFileFromAlarms(Alarm[] alarms, boolean newFormat) { + static public byte[] createFileFromAlarms(Alarm[] alarms, short fileFormat) { ByteBuffer buffer; + boolean newFormat = fileFormat == 0x03; if (!newFormat) { buffer = ByteBuffer.allocate(alarms.length * 3); for (Alarm alarm : alarms) buffer.put(alarm.getData()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceInfo.java new file mode 100644 index 000000000..200a7f72e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceInfo.java @@ -0,0 +1,5 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.device_info; + +public interface DeviceInfo { + public void parsePayload(byte[] payload); +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java new file mode 100644 index 000000000..76a9bf864 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java @@ -0,0 +1,78 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.device_info; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicReferenceArray; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest; + +public class GetDeviceInfoRequest extends FileGetRequest { + enum INFO_CLASS{ + SUPPORTED_FILE_VERSIONS((short) 0x0a, SupportedFileVersionsInfo.class), + ; + private short identifier; + private Class itemClass; + + private INFO_CLASS(short identifier, Class itemClass){ + this.identifier = identifier; + this.itemClass = itemClass; + } + + static INFO_CLASS getByIdentifier(short identifier){ + for(INFO_CLASS infoClass : values()){ + if(infoClass.getIdentifier() == identifier) return infoClass; + } + return null; + } + + public short getIdentifier() { + return identifier; + } + + public Class getItemClass() { + return itemClass; + } + } + + public GetDeviceInfoRequest(FossilWatchAdapter adapter) { + super(FileHandle.DEVICE_INFO, adapter); + } + + @Override + public void handleFileData(byte[] fileData) { + ByteBuffer buffer = ByteBuffer.wrap(fileData); + buffer.order(ByteOrder.LITTLE_ENDIAN); + buffer.position(12); + + ArrayList deviceInfos = new ArrayList<>(); + + while(buffer.remaining() > 4){ + short type = buffer.getShort(); + int length = buffer.get(); + byte[] payload = new byte[length]; + buffer.get(payload); + + INFO_CLASS infoClass = INFO_CLASS.getByIdentifier(type); + if(infoClass == null) continue; + + Class infoC = infoClass.getItemClass(); + try { + DeviceInfo info = infoC.newInstance(); + info.parsePayload(payload); + deviceInfos.add(info); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } + } + handleDeviceInfos(deviceInfos.toArray(new DeviceInfo[0])); + } + + public void handleDeviceInfos(DeviceInfo[] deviceInfos){ + log("got infos"); + }; +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/SupportedFileVersionsInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/SupportedFileVersionsInfo.java new file mode 100644 index 000000000..65feca7a4 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/SupportedFileVersionsInfo.java @@ -0,0 +1,35 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.device_info; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle; + +public class SupportedFileVersionsInfo implements DeviceInfo { + private HashMap supportedFileVersions = new HashMap<>(); + + @Override + public void parsePayload(byte[] payload) { + ByteBuffer buffer = ByteBuffer.wrap(payload); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + while(buffer.remaining() > 0){ + byte handle = buffer.get(); + short version = buffer.getShort(); + supportedFileVersions.put(handle, version); + } + } + + public short getSupportedFileVersion(FileHandle fileHandle){ + return getSupportedFileVersion(fileHandle.getHandle()); + } + + public short getSupportedFileVersion(short fileHandle){ + return getSupportedFileVersion((byte)((fileHandle >> 8) & 0xFF)); + } + + public short getSupportedFileVersion(byte fileHandle){ + return supportedFileVersions.get(fileHandle); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java index 824d98c1c..cf34ff54f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java @@ -47,7 +47,7 @@ public class FilePutRequest extends FilePutRawRequest { private int fullCRC; public FilePutRequest(FileHandle fileHandle, byte[] file, FossilWatchAdapter adapter) { - super(fileHandle, createFilePayload(fileHandle, file, (short) 0), adapter); + super(fileHandle, createFilePayload(fileHandle, file, adapter.getSupportedFileVersion(fileHandle)), adapter); } private static byte[] createFilePayload(FileHandle fileHandle, byte[] file, short fileVersion){ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsPutRequest.java index 84658c863..8906fc5dc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsPutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsPutRequest.java @@ -9,7 +9,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos public class TranslationsPutRequest extends FilePutRequest { public TranslationsPutRequest(TranslationData translationData, FossilWatchAdapter adapter) { - super(FileHandle.ASSET_TRANSLATIONS, createPayload(translationData), (short) 0x0d02, adapter); + super(FileHandle.ASSET_TRANSLATIONS, createPayload(translationData), adapter); } private static byte[] createPayload(TranslationData translationData){