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 f3e1e274d..82b84ccca 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 @@ -17,18 +17,70 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm; import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; +import nodomain.freeyourgadget.gadgetbridge.util.Version; public class AlarmsSetRequest extends FilePutRequest { public AlarmsSetRequest(Alarm[] alarms, FossilWatchAdapter adapter) { - super((short) 0x0A00, createFileFromAlarms(alarms), adapter); + super((short) 0x0A00, createFileFromAlarms(alarms, isNewFormat(adapter)), isNewFormat(adapter) ? (short) 3 : (short) 2, adapter); // TODO version 3 } - static byte[] createFileFromAlarms(Alarm[] alarms){ - ByteBuffer buffer = ByteBuffer.allocate(alarms.length * 3); - for(Alarm alarm : alarms) buffer.put(alarm.getData()); + 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); + matcher.find(); + String thisVersion = matcher.group(0); + + int result = newFormatVersion.compareTo(new Version(thisVersion)); + + return result != 1; + } + + static public byte[] createFileFromAlarms(Alarm[] alarms, boolean newFormat) { + ByteBuffer buffer; + if (!newFormat) { + buffer = ByteBuffer.allocate(alarms.length * 3); + for (Alarm alarm : alarms) buffer.put(alarm.getData()); + } else { + String label = "Brr Brr"; + String message = "I am an alarm"; + + label = label.substring(0, Math.min(label.length(), 15)); + message = message.substring(0, Math.min(message.length(), 50)); + + int SIZE_ALARM = 17 + label.length() + message.length(); + int sizeAll = alarms.length * SIZE_ALARM; + buffer = ByteBuffer.allocate(sizeAll); // 4 for overall length + buffer.order(ByteOrder.LITTLE_ENDIAN); + + for (Alarm alarm : alarms) { + buffer.put((byte) 0x00); // dunno why + buffer.putShort((short) (SIZE_ALARM - 3)); // alarm size, 0 above does not count + buffer.put((byte) 0x00); // prolly entry id time data + buffer.putShort((short) 3); // prolly entry length + buffer.put(alarm.getData()); + + buffer.put((byte) 0x01); // another entry id label + buffer.putShort((short) (label.length() + 1)); // entry length + buffer.put(label.getBytes()); + buffer.put((byte) 0x00); // null terminator + + buffer.put((byte) 0x02); // entry id subtext + buffer.putShort((short) (message.length() + 1)); // entry length + buffer.put(message.getBytes()); + buffer.put((byte) 0x00); // null terminator + } + } return buffer.array(); } 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 1b95b01a7..5f42de634 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 @@ -37,7 +37,7 @@ public class FilePutRequest extends FossilRequest { private ArrayList packets = new ArrayList<>(); - private short handle; + private short handle, fileVersion; private FossilWatchAdapter adapter; @@ -45,9 +45,10 @@ public class FilePutRequest extends FossilRequest { private int fullCRC; - public FilePutRequest(short handle, byte[] file, FossilWatchAdapter adapter) { + public FilePutRequest(short handle, byte[] file, short fileVersion, FossilWatchAdapter adapter) { this.handle = handle; this.adapter = adapter; + this.fileVersion = fileVersion; int fileLength = file.length + 16; ByteBuffer buffer = this.createBuffer(); @@ -63,6 +64,10 @@ public class FilePutRequest extends FossilRequest { state = UploadState.INITIALIZED; } + public FilePutRequest(short handle, byte[] file, FossilWatchAdapter adapter) { + this(handle, file, (short) 2, adapter); + } + public short getHandle() { return handle; } @@ -83,7 +88,7 @@ public class FilePutRequest extends FossilRequest { TransactionBuilder transactionBuilder = new TransactionBuilder("file upload"); BluetoothGattCharacteristic uploadCharacteristic = adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0004-957f-7d4a-34a6-74696673696d")); - this.prepareFilePackets(this.file); + this.prepareFilePackets(this.file, this.fileVersion); for (byte[] packet : packets) { transactionBuilder.write(uploadCharacteristic, packet); @@ -188,15 +193,14 @@ public class FilePutRequest extends FossilRequest { return this.state == UploadState.UPLOADED; } - private void prepareFilePackets(byte[] file) { + private void prepareFilePackets(byte[] file, short fileVersion) { int maxPacketSize = adapter.getMTU() - 4; ByteBuffer buffer = ByteBuffer.allocate(file.length + 12 + 4); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putShort(handle); - buffer.put((byte) 2); - buffer.put((byte) 0); + buffer.putShort(fileVersion); buffer.putInt(0); buffer.putInt(file.length);