1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-08-03 04:21:52 +02:00

Garmin protocol: create helper class GarminByteBufferReader

separate the logic specific for GFDI messages from the generally useful logic.
Also centralize the logging in case of leftover bytes while parsing GFDI messages.
This commit is contained in:
Daniele Gobbetti 2024-04-02 14:36:35 +02:00
parent 8524426b70
commit b2f995b736
20 changed files with 166 additions and 185 deletions

View File

@ -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;
}
}

View File

@ -2,7 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit;
import java.nio.ByteBuffer; 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; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter;
public class DevFieldDefinition { public class DevFieldDefinition {
@ -20,10 +20,10 @@ public class DevFieldDefinition {
this.valueHolder = ByteBuffer.allocate(size); this.valueHolder = ByteBuffer.allocate(size);
} }
public static DevFieldDefinition parseIncoming(MessageReader reader) { public static DevFieldDefinition parseIncoming(GarminByteBufferReader garminByteBufferReader) {
int number = reader.readByte(); int number = garminByteBufferReader.readByte();
int size = reader.readByte(); int size = garminByteBufferReader.readByte();
int developerDataIndex = reader.readByte(); int developerDataIndex = garminByteBufferReader.readByte();
return new DevFieldDefinition(number, size, developerDataIndex, ""); return new DevFieldDefinition(number, size, developerDataIndex, "");

View File

@ -2,8 +2,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit;
import java.nio.ByteBuffer; 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.fit.baseTypes.BaseType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter;
public class FieldDefinition implements FieldInterface { public class FieldDefinition implements FieldInterface {
@ -27,11 +27,10 @@ public class FieldDefinition implements FieldInterface {
this(localNumber, size, baseType, name, 1, 0); this(localNumber, size, baseType, name, 1, 0);
} }
public static FieldDefinition parseIncoming(MessageReader reader) { public static FieldDefinition parseIncoming(GarminByteBufferReader garminByteBufferReader) {
int localNumber = reader.readByte(); int localNumber = garminByteBufferReader.readByte();
int size = reader.readByte(); int size = garminByteBufferReader.readByte();
int baseTypeIdentifier = reader.readByte(); int baseTypeIdentifier = garminByteBufferReader.readByte();
BaseType baseType = BaseType.fromIdentifier(baseTypeIdentifier); BaseType baseType = BaseType.fromIdentifier(baseTypeIdentifier);
if (size % baseType.getSize() != 0) { if (size % baseType.getSize() != 0) {

View File

@ -6,8 +6,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminByteBufferReader;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter;
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
@ -44,10 +43,10 @@ public class RecordData {
} }
public void parseDataMessage(MessageReader reader) { public void parseDataMessage(GarminByteBufferReader garminByteBufferReader) {
reader.setByteOrder(valueHolder.order()); garminByteBufferReader.setByteOrder(valueHolder.order());
for (FieldData fieldData : fieldDataList) { for (FieldData fieldData : fieldDataList) {
fieldData.parseDataMessage(reader); fieldData.parseDataMessage(garminByteBufferReader);
} }
} }
@ -167,9 +166,9 @@ public class RecordData {
valueHolder.position(position); valueHolder.position(position);
} }
public void parseDataMessage(MessageReader reader) { private void parseDataMessage(GarminByteBufferReader garminByteBufferReader) {
goToPosition(); goToPosition();
valueHolder.put(reader.readBytes(size)); valueHolder.put(garminByteBufferReader.readBytes(size));
} }
public void encode(Object... objects) { public void encode(Object... objects) {

View File

@ -4,7 +4,7 @@ import java.nio.ByteOrder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter;
public class RecordDefinition { public class RecordDefinition {
@ -33,35 +33,33 @@ public class RecordDefinition {
this(recordHeader, byteOrder, mesgType, globalMesgNum, null, null); 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()) if (!recordHeader.isDefinition())
return null; return null;
reader.readByte();//ignore garminByteBufferReader.readByte();//ignore
ByteOrder byteOrder = reader.readByte() == 0x01 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; ByteOrder byteOrder = garminByteBufferReader.readByte() == 0x01 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
reader.setByteOrder(byteOrder); garminByteBufferReader.setByteOrder(byteOrder);
final int globalMesgNum = reader.readShort(); final int globalMesgNum = garminByteBufferReader.readShort();
RecordDefinition definitionMessage = new RecordDefinition(recordHeader, byteOrder, recordHeader.getMesgType(), globalMesgNum); RecordDefinition definitionMessage = new RecordDefinition(recordHeader, byteOrder, recordHeader.getMesgType(), globalMesgNum);
final int numFields = reader.readByte(); final int numFields = garminByteBufferReader.readByte();
List<FieldDefinition> fieldDefinitions = new ArrayList<>(numFields); List<FieldDefinition> fieldDefinitions = new ArrayList<>(numFields);
for (int i = 0; i < numFields; i++) { for (int i = 0; i < numFields; i++) {
fieldDefinitions.add(FieldDefinition.parseIncoming(reader)); fieldDefinitions.add(FieldDefinition.parseIncoming(garminByteBufferReader));
} }
definitionMessage.setFieldDefinitions(fieldDefinitions); definitionMessage.setFieldDefinitions(fieldDefinitions);
if (recordHeader.isDeveloperData()) { if (recordHeader.isDeveloperData()) {
final int numDevFields = reader.readByte(); final int numDevFields = garminByteBufferReader.readByte();
List<DevFieldDefinition> devFieldDefinitions = new ArrayList<>(numDevFields); List<DevFieldDefinition> devFieldDefinitions = new ArrayList<>(numDevFields);
for (int i = 0; i < numDevFields; i++) { for (int i = 0; i < numDevFields; i++) {
devFieldDefinitions.add(DevFieldDefinition.parseIncoming(reader)); devFieldDefinitions.add(DevFieldDefinition.parseIncoming(garminByteBufferReader));
} }
definitionMessage.setDevFieldDefinitions(devFieldDefinitions); definitionMessage.setDevFieldDefinitions(devFieldDefinitions);
} }
reader.warnIfLeftover();
return definitionMessage; return definitionMessage;
} }

View File

@ -25,7 +25,6 @@ public class ConfigurationMessage extends GFDIMessage {
public static ConfigurationMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { public static ConfigurationMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) {
final int endOfPayload = reader.readByte(); final int endOfPayload = reader.readByte();
ConfigurationMessage configurationMessage = new ConfigurationMessage(garminMessage, reader.readBytes(endOfPayload - reader.getPosition())); ConfigurationMessage configurationMessage = new ConfigurationMessage(garminMessage, reader.readBytes(endOfPayload - reader.getPosition()));
reader.warnIfLeftover();
return configurationMessage; return configurationMessage;
} }

View File

@ -18,7 +18,6 @@ public class CurrentTimeRequestMessage extends GFDIMessage {
public static CurrentTimeRequestMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { public static CurrentTimeRequestMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) {
final int referenceID = reader.readInt(); final int referenceID = reader.readInt();
reader.warnIfLeftover();
return new CurrentTimeRequestMessage(referenceID, garminMessage); return new CurrentTimeRequestMessage(referenceID, garminMessage);
} }

View File

@ -48,7 +48,6 @@ public class DeviceInformationMessage extends GFDIMessage {
final String deviceName = reader.readString(); final String deviceName = reader.readString();
final String deviceModel = reader.readString(); final String deviceModel = reader.readString();
reader.warnIfLeftover();
return new DeviceInformationMessage(garminMessage, protocolVersion, productNumber, unitNumber, softwareVersion, maxPacketSize, bluetoothFriendlyName, deviceName, deviceModel); return new DeviceInformationMessage(garminMessage, protocolVersion, productNumber, unitNumber, softwareVersion, maxPacketSize, bluetoothFriendlyName, deviceName, deviceModel);
} }

View File

@ -17,7 +17,6 @@ public class FindMyPhoneRequestMessage extends GFDIMessage {
public static FindMyPhoneRequestMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { public static FindMyPhoneRequestMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) {
final int duration = reader.readByte(); final int duration = reader.readByte();
reader.warnIfLeftover();
return new FindMyPhoneRequestMessage(garminMessage, duration); return new FindMyPhoneRequestMessage(garminMessage, duration);
} }

View File

@ -24,7 +24,7 @@ public class FitDataMessage extends GFDIMessage {
List<RecordData> recordDataList = new ArrayList<>(); List<RecordData> recordDataList = new ArrayList<>();
while (!reader.isEndOfPayload()) { while (reader.remaining() > 0) {
RecordHeader recordHeader = new RecordHeader((byte) reader.readByte()); RecordHeader recordHeader = new RecordHeader((byte) reader.readByte());
if (recordHeader.isDefinition()) if (recordHeader.isDefinition())
return null; return null;

View File

@ -24,7 +24,7 @@ public class FitDefinitionMessage extends GFDIMessage {
public static FitDefinitionMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { public static FitDefinitionMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) {
List<RecordDefinition> recordDefinitions = new ArrayList<>(); List<RecordDefinition> recordDefinitions = new ArrayList<>();
while (!reader.isEndOfPayload()) { while (reader.remaining() > 0) {
RecordHeader recordHeader = new RecordHeader((byte) reader.readByte()); RecordHeader recordHeader = new RecordHeader((byte) reader.readByte());
recordDefinitions.add(RecordDefinition.parseIncoming(reader, recordHeader)); recordDefinitions.add(RecordDefinition.parseIncoming(reader, recordHeader));
} }

View File

@ -10,8 +10,10 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; 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.GFDIStatusMessage;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.status.GenericStatusMessage; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.status.GenericStatusMessage;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public abstract class GFDIMessage { public abstract class GFDIMessage {
public static final int MESSAGE_REQUEST = 5001; public static final int MESSAGE_REQUEST = 5001;
@ -45,6 +47,8 @@ public abstract class GFDIMessage {
} catch (Exception e) { } catch (Exception e) {
LOG.error("UNHANDLED GFDI MESSAGE TYPE {}, MESSAGE {}", messageType, message); LOG.error("UNHANDLED GFDI MESSAGE TYPE {}, MESSAGE {}", messageType, message);
return new UnhandledMessage(messageType); 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()));
}
}
}
} }

View File

@ -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()));
}
}
}

View File

@ -14,7 +14,6 @@ public class MusicControlCapabilitiesMessage extends GFDIMessage {
public static MusicControlCapabilitiesMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { public static MusicControlCapabilitiesMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) {
final int supportedCapabilities = reader.readByte(); final int supportedCapabilities = reader.readByte();
reader.warnIfLeftover();
return new MusicControlCapabilitiesMessage(garminMessage, supportedCapabilities); return new MusicControlCapabilitiesMessage(garminMessage, supportedCapabilities);
} }

View File

@ -29,7 +29,6 @@ public class MusicControlMessage extends GFDIMessage {
public static MusicControlMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { public static MusicControlMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) {
MusicControlCapabilitiesMessage.GarminMusicControlCommand command = commands[reader.readByte()]; MusicControlCapabilitiesMessage.GarminMusicControlCommand command = commands[reader.readByte()];
reader.warnIfLeftover();
return new MusicControlMessage(garminMessage, command); return new MusicControlMessage(garminMessage, command);
} }

View File

@ -48,7 +48,6 @@ public class ProtobufMessage extends GFDIMessage {
final int protobufDataLength = reader.readInt(); final int protobufDataLength = reader.readInt();
final byte[] messageBytes = reader.readBytes(protobufDataLength); final byte[] messageBytes = reader.readBytes(protobufDataLength);
reader.warnIfLeftover();
return new ProtobufMessage(garminMessage, requestID, dataOffset, totalProtobufLength, protobufDataLength, messageBytes, false); return new ProtobufMessage(garminMessage, requestID, dataOffset, totalProtobufLength, protobufDataLength, messageBytes, false);
} }

View File

@ -2,8 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.sta
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader;
public class FitDataStatusMessage extends GFDIStatusMessage { public class FitDataStatusMessage extends GFDIStatusMessage {
private final Status status; private final Status status;
@ -27,7 +25,6 @@ public class FitDataStatusMessage extends GFDIStatusMessage {
final Status status = Status.fromCode(reader.readByte()); final Status status = Status.fromCode(reader.readByte());
final FitDataStatusCode fitDataStatusCode = FitDataStatusCode.fromCode(reader.readByte()); final FitDataStatusCode fitDataStatusCode = FitDataStatusCode.fromCode(reader.readByte());
reader.warnIfLeftover();
return new FitDataStatusMessage(garminMessage, status, fitDataStatusCode); return new FitDataStatusMessage(garminMessage, status, fitDataStatusCode);
} }

View File

@ -2,8 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.sta
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader;
public class FitDefinitionStatusMessage extends GFDIStatusMessage { public class FitDefinitionStatusMessage extends GFDIStatusMessage {
private final Status status; private final Status status;
@ -26,7 +24,6 @@ public class FitDefinitionStatusMessage extends GFDIStatusMessage {
final Status status = Status.fromCode(reader.readByte()); final Status status = Status.fromCode(reader.readByte());
final FitDefinitionStatusCode fitDefinitionStatusCode = FitDefinitionStatusCode.fromCode(reader.readByte()); final FitDefinitionStatusCode fitDefinitionStatusCode = FitDefinitionStatusCode.fromCode(reader.readByte());
reader.warnIfLeftover();
return new FitDefinitionStatusMessage(garminMessage, status, fitDefinitionStatusCode); return new FitDefinitionStatusMessage(garminMessage, status, fitDefinitionStatusCode);
} }

View File

@ -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.GFDIMessage;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader;
public abstract class GFDIStatusMessage extends GFDIMessage { public abstract class GFDIStatusMessage extends GFDIMessage {
private Status status; private Status status;
public static GFDIStatusMessage parseIncoming(MessageReader reader, GarminMessage garminMessage) { 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)) { 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)) { } else if (GarminMessage.FIT_DEFINITION.equals(originalGarminMessage)) {
return FitDefinitionStatusMessage.parseIncoming(reader, garminMessage); return FitDefinitionStatusMessage.parseIncoming(reader, originalGarminMessage);
} else if (GarminMessage.FIT_DATA.equals(originalGarminMessage)) { } else if (GarminMessage.FIT_DATA.equals(originalGarminMessage)) {
return FitDataStatusMessage.parseIncoming(reader, garminMessage); return FitDataStatusMessage.parseIncoming(reader, originalGarminMessage);
} else { } else {
final Status status = Status.fromCode(reader.readByte()); final Status status = Status.fromCode(reader.readByte());
if (Status.ACK == status) { if (Status.ACK == status) {
LOG.info("Received ACK for message {}", originalGarminMessage.name()); LOG.info("Received ACK for message {}", originalGarminMessage.name());
} else { } 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); return new GenericStatusMessage(garminMessage, status);
} }
} }

View File

@ -2,7 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.sta
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageReader;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.messages.MessageWriter;
public class ProtobufStatusMessage extends GFDIStatusMessage { public class ProtobufStatusMessage extends GFDIStatusMessage {
@ -35,7 +34,6 @@ public class ProtobufStatusMessage extends GFDIStatusMessage {
final ProtobufChunkStatus protobufStatus = ProtobufChunkStatus.fromCode(reader.readByte()); final ProtobufChunkStatus protobufStatus = ProtobufChunkStatus.fromCode(reader.readByte());
final ProtobufStatusCode error = ProtobufStatusCode.fromCode(reader.readByte()); final ProtobufStatusCode error = ProtobufStatusCode.fromCode(reader.readByte());
reader.warnIfLeftover();
return new ProtobufStatusMessage(garminMessage, status, requestID, dataOffset, protobufStatus, error, false); return new ProtobufStatusMessage(garminMessage, status, requestID, dataOffset, protobufStatus, error, false);
} }