diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminByteBufferReader.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminByteBufferReader.java new file mode 100644 index 000000000..7616cfa2a --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminByteBufferReader.java @@ -0,0 +1,79 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; + +public class GarminByteBufferReader { + protected final ByteBuffer byteBuffer; + + public GarminByteBufferReader(byte[] data) { + this.byteBuffer = ByteBuffer.wrap(data); + } + + public ByteBuffer asReadOnlyBuffer() { + return byteBuffer.asReadOnlyBuffer(); + } + + public void setByteOrder(ByteOrder byteOrder) { + this.byteBuffer.order(byteOrder); + } + + public int readByte() { + if (!byteBuffer.hasRemaining()) throw new IllegalStateException(); + + return Byte.toUnsignedInt(byteBuffer.get()); + } + + public int getPosition() { + return byteBuffer.position(); + } + + public int readShort() { + if (byteBuffer.remaining() < 2) throw new IllegalStateException(); + + return Short.toUnsignedInt(byteBuffer.getShort()); + } + + public int readInt() { + if (byteBuffer.remaining() < 4) throw new IllegalStateException(); + + return byteBuffer.getInt(); + } + + public long readLong() { + if (byteBuffer.remaining() < 8) throw new IllegalStateException(); + + return byteBuffer.getLong(); + } + + public float readFloat32() { + if (byteBuffer.remaining() < 4) throw new IllegalStateException(); + + return byteBuffer.getFloat(); + } + + public double readFloat64() { + if (byteBuffer.remaining() < 8) throw new IllegalStateException(); + + return byteBuffer.getDouble(); + } + + public String readString() { + final int size = readByte(); + byte[] bytes = new byte[size]; + if (byteBuffer.remaining() < size) throw new IllegalStateException(); + byteBuffer.get(bytes); + return new String(bytes, StandardCharsets.UTF_8); + } + + public byte[] readBytes(int size) { + byte[] bytes = new byte[size]; + + if (byteBuffer.remaining() < size) throw new IllegalStateException(); + byteBuffer.get(bytes); + + return bytes; + } + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/DevFieldDefinition.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/DevFieldDefinition.java index 44b30556c..aa31a34e4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/DevFieldDefinition.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/DevFieldDefinition.java @@ -2,7 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit; import java.nio.ByteBuffer; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminByteBufferReader; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; public class DevFieldDefinition { @@ -20,10 +20,10 @@ public class DevFieldDefinition { this.valueHolder = ByteBuffer.allocate(size); } - public static DevFieldDefinition parseIncoming(MessageReader reader) { - int number = reader.readByte(); - int size = reader.readByte(); - int developerDataIndex = reader.readByte(); + public static DevFieldDefinition parseIncoming(GarminByteBufferReader garminByteBufferReader) { + int number = garminByteBufferReader.readByte(); + int size = garminByteBufferReader.readByte(); + int developerDataIndex = garminByteBufferReader.readByte(); return new DevFieldDefinition(number, size, developerDataIndex, ""); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FieldDefinition.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FieldDefinition.java index 0ff9593c2..25b9f9bcb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FieldDefinition.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FieldDefinition.java @@ -2,8 +2,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit; import java.nio.ByteBuffer; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminByteBufferReader; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; public class FieldDefinition implements FieldInterface { @@ -27,11 +27,10 @@ public class FieldDefinition implements FieldInterface { this(localNumber, size, baseType, name, 1, 0); } - public static FieldDefinition parseIncoming(MessageReader reader) { - int localNumber = reader.readByte(); - int size = reader.readByte(); - int baseTypeIdentifier = reader.readByte(); - + public static FieldDefinition parseIncoming(GarminByteBufferReader garminByteBufferReader) { + int localNumber = garminByteBufferReader.readByte(); + int size = garminByteBufferReader.readByte(); + int baseTypeIdentifier = garminByteBufferReader.readByte(); BaseType baseType = BaseType.fromIdentifier(baseTypeIdentifier); if (size % baseType.getSize() != 0) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordData.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordData.java index 81af3c14d..013d05e53 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordData.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordData.java @@ -6,8 +6,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminByteBufferReader; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; @@ -44,10 +43,10 @@ public class RecordData { } - public void parseDataMessage(MessageReader reader) { - reader.setByteOrder(valueHolder.order()); + public void parseDataMessage(GarminByteBufferReader garminByteBufferReader) { + garminByteBufferReader.setByteOrder(valueHolder.order()); for (FieldData fieldData : fieldDataList) { - fieldData.parseDataMessage(reader); + fieldData.parseDataMessage(garminByteBufferReader); } } @@ -167,9 +166,9 @@ public class RecordData { valueHolder.position(position); } - public void parseDataMessage(MessageReader reader) { + private void parseDataMessage(GarminByteBufferReader garminByteBufferReader) { goToPosition(); - valueHolder.put(reader.readBytes(size)); + valueHolder.put(garminByteBufferReader.readBytes(size)); } public void encode(Object... objects) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordDefinition.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordDefinition.java index 70f5f0bdd..aabbcb6a1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordDefinition.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/RecordDefinition.java @@ -4,7 +4,7 @@ import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminByteBufferReader; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; public class RecordDefinition { @@ -33,35 +33,33 @@ public class RecordDefinition { this(recordHeader, byteOrder, mesgType, globalMesgNum, null, null); } - public static RecordDefinition parseIncoming(MessageReader reader, RecordHeader recordHeader) { + public static RecordDefinition parseIncoming(GarminByteBufferReader garminByteBufferReader, RecordHeader recordHeader) { if (!recordHeader.isDefinition()) return null; - reader.readByte();//ignore - ByteOrder byteOrder = reader.readByte() == 0x01 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; - reader.setByteOrder(byteOrder); - final int globalMesgNum = reader.readShort(); + garminByteBufferReader.readByte();//ignore + ByteOrder byteOrder = garminByteBufferReader.readByte() == 0x01 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; + garminByteBufferReader.setByteOrder(byteOrder); + final int globalMesgNum = garminByteBufferReader.readShort(); RecordDefinition definitionMessage = new RecordDefinition(recordHeader, byteOrder, recordHeader.getMesgType(), globalMesgNum); - final int numFields = reader.readByte(); + final int numFields = garminByteBufferReader.readByte(); List fieldDefinitions = new ArrayList<>(numFields); for (int i = 0; i < numFields; i++) { - fieldDefinitions.add(FieldDefinition.parseIncoming(reader)); + fieldDefinitions.add(FieldDefinition.parseIncoming(garminByteBufferReader)); } definitionMessage.setFieldDefinitions(fieldDefinitions); if (recordHeader.isDeveloperData()) { - final int numDevFields = reader.readByte(); + final int numDevFields = garminByteBufferReader.readByte(); List devFieldDefinitions = new ArrayList<>(numDevFields); for (int i = 0; i < numDevFields; i++) { - devFieldDefinitions.add(DevFieldDefinition.parseIncoming(reader)); + devFieldDefinitions.add(DevFieldDefinition.parseIncoming(garminByteBufferReader)); } definitionMessage.setDevFieldDefinitions(devFieldDefinitions); } - reader.warnIfLeftover(); - return definitionMessage; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ConfigurationMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ConfigurationMessage.java index f55168bfc..aac34cde0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ConfigurationMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ConfigurationMessage.java @@ -25,7 +25,6 @@ public class ConfigurationMessage extends GFDIMessage { public static ConfigurationMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { final int endOfPayload = reader.readByte(); ConfigurationMessage configurationMessage = new ConfigurationMessage(garminMessage, reader.readBytes(endOfPayload - reader.getPosition())); - reader.warnIfLeftover(); return configurationMessage; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/CurrentTimeRequestMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/CurrentTimeRequestMessage.java index 2f100a5a1..80db0ee14 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/CurrentTimeRequestMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/CurrentTimeRequestMessage.java @@ -18,7 +18,6 @@ public class CurrentTimeRequestMessage extends GFDIMessage { public static CurrentTimeRequestMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { final int referenceID = reader.readInt(); - reader.warnIfLeftover(); return new CurrentTimeRequestMessage(referenceID, garminMessage); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/DeviceInformationMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/DeviceInformationMessage.java index 7ed3af986..684694ae3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/DeviceInformationMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/DeviceInformationMessage.java @@ -48,7 +48,6 @@ public class DeviceInformationMessage extends GFDIMessage { final String deviceName = reader.readString(); final String deviceModel = reader.readString(); - reader.warnIfLeftover(); return new DeviceInformationMessage(garminMessage, protocolVersion, productNumber, unitNumber, softwareVersion, maxPacketSize, bluetoothFriendlyName, deviceName, deviceModel); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FindMyPhoneRequestMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FindMyPhoneRequestMessage.java index 93b299028..198ebaf95 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FindMyPhoneRequestMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FindMyPhoneRequestMessage.java @@ -17,7 +17,6 @@ public class FindMyPhoneRequestMessage extends GFDIMessage { public static FindMyPhoneRequestMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { final int duration = reader.readByte(); - reader.warnIfLeftover(); return new FindMyPhoneRequestMessage(garminMessage, duration); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDataMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDataMessage.java index 0299af594..56844792e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDataMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDataMessage.java @@ -24,7 +24,7 @@ public class FitDataMessage extends GFDIMessage { List recordDataList = new ArrayList<>(); - while (!reader.isEndOfPayload()) { + while (reader.remaining() > 0) { RecordHeader recordHeader = new RecordHeader((byte) reader.readByte()); if (recordHeader.isDefinition()) return null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDefinitionMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDefinitionMessage.java index 1bf34e896..4a48d9535 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDefinitionMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/FitDefinitionMessage.java @@ -24,7 +24,7 @@ public class FitDefinitionMessage extends GFDIMessage { public static FitDefinitionMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { List recordDefinitions = new ArrayList<>(); - while (!reader.isEndOfPayload()) { + while (reader.remaining() > 0) { RecordHeader recordHeader = new RecordHeader((byte) reader.readByte()); recordDefinitions.add(RecordDefinition.parseIncoming(reader, recordHeader)); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/GFDIMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/GFDIMessage.java index 3a517a897..358d9cf0e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/GFDIMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/GFDIMessage.java @@ -10,8 +10,10 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminByteBufferReader; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.status.GFDIStatusMessage; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.status.GenericStatusMessage; +import nodomain.freeyourgadget.gadgetbridge.util.GB; public abstract class GFDIMessage { public static final int MESSAGE_REQUEST = 5001; @@ -45,6 +47,8 @@ public abstract class GFDIMessage { } catch (Exception e) { LOG.error("UNHANDLED GFDI MESSAGE TYPE {}, MESSAGE {}", messageType, message); return new UnhandledMessage(messageType); + } finally { + messageReader.warnIfLeftover(); } } @@ -156,4 +160,53 @@ public abstract class GFDIMessage { } + protected static class MessageReader extends GarminByteBufferReader { + + private final int payloadSize; + + public MessageReader(byte[] data) { + super(data); + this.byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + this.payloadSize = readShort(); //includes CRC + checkSize(); + checkCRC(); + this.byteBuffer.limit(payloadSize - 2); //remove CRC + } + + public int remaining() { + return byteBuffer.remaining(); + } + + public void skip(int offset) { + if (remaining() < offset) throw new IllegalStateException(); + byteBuffer.position(byteBuffer.position() + offset); + } + + private void checkSize() { + if (payloadSize != byteBuffer.capacity()) { + LOG.error("Received GFDI packet with invalid length: {} vs {}", payloadSize, byteBuffer.capacity()); + throw new IllegalArgumentException("Received GFDI packet with invalid length"); + } + } + + private void checkCRC() { + final int crc = Short.toUnsignedInt(byteBuffer.getShort(payloadSize - 2)); + final int correctCrc = ChecksumCalculator.computeCrc(byteBuffer.asReadOnlyBuffer(), 0, payloadSize - 2); + if (crc != correctCrc) { + LOG.error("Received GFDI packet with invalid CRC: {} vs {}", crc, correctCrc); + throw new IllegalArgumentException("Received GFDI packet with invalid CRC"); + } + } + + public void warnIfLeftover() { + if (byteBuffer.hasRemaining() && byteBuffer.position() < (byteBuffer.limit())) { + int pos = byteBuffer.position(); + int numBytes = (byteBuffer.limit()) - byteBuffer.position(); + byte[] leftover = new byte[numBytes]; + byteBuffer.get(leftover); + byteBuffer.position(pos); + LOG.warn("Leftover bytes when parsing message. Bytes: {}, complete message: {}", GB.hexdump(leftover), GB.hexdump(byteBuffer.array())); + } + } + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MessageReader.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MessageReader.java deleted file mode 100644 index 2d9b744aa..000000000 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MessageReader.java +++ /dev/null @@ -1,131 +0,0 @@ -package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.StandardCharsets; - -import nodomain.freeyourgadget.gadgetbridge.util.GB; - -public class MessageReader { - protected static final Logger LOG = LoggerFactory.getLogger(MessageReader.class); - - private final ByteBuffer byteBuffer; - private final int payloadSize; - - public MessageReader(byte[] data) { - this.byteBuffer = ByteBuffer.wrap(data); - this.byteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.payloadSize = readShort(); - - checkSize(); - checkCRC(); - } - - public void setByteOrder(ByteOrder byteOrder) { - this.byteBuffer.order(byteOrder); - } - - public boolean isEof() { - return !byteBuffer.hasRemaining(); - } - - public boolean isEndOfPayload() { - return byteBuffer.position() >= payloadSize - 2; - } - - public int getPosition() { - return byteBuffer.position(); - } - - public void skip(int offset) { - if (byteBuffer.remaining() < offset) throw new IllegalStateException(); - byteBuffer.position(byteBuffer.position() + offset); - } - - public int readByte() { - if (!byteBuffer.hasRemaining()) throw new IllegalStateException(); - - return Byte.toUnsignedInt(byteBuffer.get()); - } - - public int readShort() { - if (byteBuffer.remaining() < 2) throw new IllegalStateException(); - - return Short.toUnsignedInt(byteBuffer.getShort()); - } - - public int readInt() { - if (byteBuffer.remaining() < 4) throw new IllegalStateException(); - - return byteBuffer.getInt(); - } - - public long readLong() { - if (byteBuffer.remaining() < 8) throw new IllegalStateException(); - - return byteBuffer.getLong(); - } - - public float readFloat32() { - if (byteBuffer.remaining() < 4) throw new IllegalStateException(); - - return byteBuffer.getFloat(); - } - - public double readFloat64() { - if (byteBuffer.remaining() < 8) throw new IllegalStateException(); - - return byteBuffer.getDouble(); - } - - public String readString() { - final int size = readByte(); - byte[] bytes = new byte[size]; - if (byteBuffer.remaining() < size) throw new IllegalStateException(); - byteBuffer.get(bytes); - return new String(bytes, StandardCharsets.UTF_8); - } - - public byte[] readBytes(int size) { - byte[] bytes = new byte[size]; - - if (byteBuffer.remaining() < size) throw new IllegalStateException(); - byteBuffer.get(bytes); - - return bytes; - } - - private int getCapacity() { - return byteBuffer.capacity(); - } - - private void checkSize() { - if (payloadSize > getCapacity()) { - LOG.error("Received GFDI packet with invalid length: {} vs {}", payloadSize, getCapacity()); - throw new IllegalArgumentException("Received GFDI packet with invalid length"); - } - } - - private void checkCRC() { - final int crc = Short.toUnsignedInt(byteBuffer.getShort(payloadSize - 2)); - final int correctCrc = ChecksumCalculator.computeCrc(byteBuffer.asReadOnlyBuffer(), 0, payloadSize - 2); - if (crc != correctCrc) { - LOG.error("Received GFDI packet with invalid CRC: {} vs {}", crc, correctCrc); - throw new IllegalArgumentException("Received GFDI packet with invalid CRC"); - } - } - - public void warnIfLeftover() { - if (byteBuffer.hasRemaining() && byteBuffer.position() < (byteBuffer.limit() - 2)) { - int pos = byteBuffer.position(); - int numBytes = (byteBuffer.limit() - 2) - byteBuffer.position(); - byte[] leftover = new byte[numBytes]; - byteBuffer.get(leftover); - byteBuffer.position(pos); - LOG.warn("Leftover bytes when parsing message. Bytes: {}, complete message: {}", GB.hexdump(leftover), GB.hexdump(byteBuffer.array())); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlCapabilitiesMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlCapabilitiesMessage.java index 72c8ce618..83489291e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlCapabilitiesMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlCapabilitiesMessage.java @@ -14,7 +14,6 @@ public class MusicControlCapabilitiesMessage extends GFDIMessage { public static MusicControlCapabilitiesMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { final int supportedCapabilities = reader.readByte(); - reader.warnIfLeftover(); return new MusicControlCapabilitiesMessage(garminMessage, supportedCapabilities); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlMessage.java index 50f6e681a..446ba4db8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/MusicControlMessage.java @@ -29,7 +29,6 @@ public class MusicControlMessage extends GFDIMessage { public static MusicControlMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { MusicControlCapabilitiesMessage.GarminMusicControlCommand command = commands[reader.readByte()]; - reader.warnIfLeftover(); return new MusicControlMessage(garminMessage, command); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ProtobufMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ProtobufMessage.java index e9bacd46f..530c99593 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ProtobufMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/ProtobufMessage.java @@ -48,7 +48,6 @@ public class ProtobufMessage extends GFDIMessage { final int protobufDataLength = reader.readInt(); final byte[] messageBytes = reader.readBytes(protobufDataLength); - reader.warnIfLeftover(); return new ProtobufMessage(garminMessage, requestID, dataOffset, totalProtobufLength, protobufDataLength, messageBytes, false); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDataStatusMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDataStatusMessage.java index b791830f3..c0b825c1e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDataStatusMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDataStatusMessage.java @@ -2,8 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.sta import androidx.annotation.Nullable; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; - public class FitDataStatusMessage extends GFDIStatusMessage { private final Status status; @@ -27,7 +25,6 @@ public class FitDataStatusMessage extends GFDIStatusMessage { final Status status = Status.fromCode(reader.readByte()); final FitDataStatusCode fitDataStatusCode = FitDataStatusCode.fromCode(reader.readByte()); - reader.warnIfLeftover(); return new FitDataStatusMessage(garminMessage, status, fitDataStatusCode); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDefinitionStatusMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDefinitionStatusMessage.java index ef3bc50a5..78b922fdb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDefinitionStatusMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/FitDefinitionStatusMessage.java @@ -2,8 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.sta import androidx.annotation.Nullable; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; - public class FitDefinitionStatusMessage extends GFDIStatusMessage { private final Status status; @@ -26,7 +24,6 @@ public class FitDefinitionStatusMessage extends GFDIStatusMessage { final Status status = Status.fromCode(reader.readByte()); final FitDefinitionStatusCode fitDefinitionStatusCode = FitDefinitionStatusCode.fromCode(reader.readByte()); - reader.warnIfLeftover(); return new FitDefinitionStatusMessage(garminMessage, status, fitDefinitionStatusCode); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/GFDIStatusMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/GFDIStatusMessage.java index 08af79a41..a2fcf7fef 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/GFDIStatusMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/GFDIStatusMessage.java @@ -2,29 +2,28 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.sta import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.GFDIMessage; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; public abstract class GFDIStatusMessage extends GFDIMessage { private Status status; public static GFDIStatusMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { - final GarminMessage originalGarminMessage = GFDIMessage.GarminMessage.fromId(reader.readShort()); + int originalMessageType = reader.readShort(); + final GarminMessage originalGarminMessage = GFDIMessage.GarminMessage.fromId(originalMessageType); if (GarminMessage.PROTOBUF_REQUEST.equals(originalGarminMessage) || GarminMessage.PROTOBUF_RESPONSE.equals(originalGarminMessage)) { - return ProtobufStatusMessage.parseIncoming(reader, garminMessage); + return ProtobufStatusMessage.parseIncoming(reader, originalGarminMessage); } else if (GarminMessage.FIT_DEFINITION.equals(originalGarminMessage)) { - return FitDefinitionStatusMessage.parseIncoming(reader, garminMessage); + return FitDefinitionStatusMessage.parseIncoming(reader, originalGarminMessage); } else if (GarminMessage.FIT_DATA.equals(originalGarminMessage)) { - return FitDataStatusMessage.parseIncoming(reader, garminMessage); + return FitDataStatusMessage.parseIncoming(reader, originalGarminMessage); } else { final Status status = Status.fromCode(reader.readByte()); if (Status.ACK == status) { LOG.info("Received ACK for message {}", originalGarminMessage.name()); } else { - LOG.warn("Received {} for message {}", status, originalGarminMessage.name()); + LOG.warn("Received {} for message {}", status, (null == originalGarminMessage) ? originalMessageType : originalGarminMessage.name()); } - reader.warnIfLeftover(); return new GenericStatusMessage(garminMessage, status); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/ProtobufStatusMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/ProtobufStatusMessage.java index d9fdf63ce..92b039e2e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/ProtobufStatusMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/messages/status/ProtobufStatusMessage.java @@ -2,7 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.sta import androidx.annotation.Nullable; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; public class ProtobufStatusMessage extends GFDIStatusMessage { @@ -35,7 +34,6 @@ public class ProtobufStatusMessage extends GFDIStatusMessage { final ProtobufChunkStatus protobufStatus = ProtobufChunkStatus.fromCode(reader.readByte()); final ProtobufStatusCode error = ProtobufStatusCode.fromCode(reader.readByte()); - reader.warnIfLeftover(); return new ProtobufStatusMessage(garminMessage, status, requestID, dataOffset, protobufStatus, error, false); }