2024-03-23 15:32:57 +01:00
|
|
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit;
|
|
|
|
|
2024-04-13 20:29:41 +02:00
|
|
|
import androidx.annotation.NonNull;
|
2024-04-02 15:10:28 +02:00
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
|
|
|
|
|
2024-03-23 15:32:57 +01:00
|
|
|
public class RecordHeader {
|
|
|
|
private final boolean definition;
|
|
|
|
private final boolean developerData;
|
2024-04-29 00:54:21 +02:00
|
|
|
private final int localMessageType;
|
2024-03-23 15:32:57 +01:00
|
|
|
private final Integer timeOffset;
|
|
|
|
|
2024-04-29 00:54:21 +02:00
|
|
|
public RecordHeader(boolean definition, boolean developerData, int localMessageType, Integer timeOffset) {
|
2024-03-23 15:32:57 +01:00
|
|
|
this.definition = definition;
|
|
|
|
this.developerData = developerData;
|
2024-04-29 00:54:21 +02:00
|
|
|
this.localMessageType = localMessageType;
|
2024-03-23 15:32:57 +01:00
|
|
|
this.timeOffset = timeOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
//see https://github.com/polyvertex/fitdecode/blob/master/fitdecode/reader.py#L512
|
|
|
|
public RecordHeader(byte header) {
|
2024-04-29 00:54:21 +02:00
|
|
|
if ((header & 0x80) == 0x80) { //compressed timestamp
|
2024-03-23 15:32:57 +01:00
|
|
|
definition = false;
|
|
|
|
developerData = false;
|
2024-04-29 00:54:21 +02:00
|
|
|
localMessageType = (header >> 5) & 0x3;
|
2024-03-23 15:32:57 +01:00
|
|
|
timeOffset = header & 0x1f;
|
|
|
|
} else {
|
|
|
|
definition = ((header & 0x40) == 0x40);
|
|
|
|
developerData = ((header & 0x20) == 0x20);
|
2024-04-29 00:54:21 +02:00
|
|
|
localMessageType = header & 0xf;
|
2024-03-23 15:32:57 +01:00
|
|
|
timeOffset = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-29 00:54:21 +02:00
|
|
|
public int getLocalMessageType() {
|
|
|
|
return localMessageType;
|
2024-04-05 14:54:25 +02:00
|
|
|
}
|
|
|
|
|
2024-04-29 00:54:21 +02:00
|
|
|
@Nullable
|
2024-04-05 14:54:25 +02:00
|
|
|
public Integer getTimeOffset() {
|
|
|
|
return timeOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isCompressedTimestamp() {
|
|
|
|
return timeOffset != null;
|
|
|
|
}
|
|
|
|
|
2024-03-23 15:32:57 +01:00
|
|
|
public boolean isDeveloperData() {
|
|
|
|
return developerData;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isDefinition() {
|
|
|
|
return definition;
|
|
|
|
}
|
|
|
|
|
|
|
|
public byte generateOutgoingDefinitionPayload() {
|
2024-04-29 00:54:21 +02:00
|
|
|
if (!definition && !developerData) {
|
|
|
|
assert timeOffset != null;
|
|
|
|
return (byte) (timeOffset | (((byte) localMessageType) << 5));
|
|
|
|
}
|
|
|
|
byte base = (byte) localMessageType;
|
2024-03-23 15:32:57 +01:00
|
|
|
if (definition)
|
|
|
|
base = (byte) (base | 0x40);
|
|
|
|
if (developerData)
|
|
|
|
base = (byte) (base | 0x20);
|
|
|
|
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
public byte generateOutgoingDataPayload() { //TODO: unclear if correct
|
2024-04-29 00:54:21 +02:00
|
|
|
if (!definition && !developerData) {
|
|
|
|
assert timeOffset != null;
|
|
|
|
return (byte) (timeOffset | (((byte) localMessageType) << 5));
|
|
|
|
}
|
|
|
|
byte base = (byte) localMessageType;
|
2024-03-23 15:32:57 +01:00
|
|
|
if (developerData)
|
|
|
|
base = (byte) (base | 0x20);
|
|
|
|
|
|
|
|
return base;
|
|
|
|
}
|
2024-04-02 15:10:28 +02:00
|
|
|
|
2024-04-13 20:29:41 +02:00
|
|
|
@NonNull
|
|
|
|
@Override
|
2024-04-02 15:10:28 +02:00
|
|
|
public String toString() {
|
2024-04-29 00:54:21 +02:00
|
|
|
return "Local Message: " + localMessageType;
|
2024-04-02 15:10:28 +02:00
|
|
|
}
|
2024-03-23 15:32:57 +01:00
|
|
|
}
|