/* Copyright (C) 2023-2024 Frank Ertl
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.communication.message;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.communication.datastructures.WithingsStructure;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public abstract class AbstractMessage implements Message {
/**
* The header consist of the first byte 0x01 (probably the message format identifier),
* two bytes for the message type and 2 bytes for the actual datalength.
*/
private static final int HEADER_SIZE = 5;
protected final static short EOM_SIZE = 4;
private List dataStructures = new ArrayList();
public List getDataStructures() {
return Collections.unmodifiableList(dataStructures);
}
@Override
public void addDataStructure(WithingsStructure data) {
dataStructures.add(data);
}
@Override
public byte[] getRawData() {
short structureLength = 0;
boolean setEndOfMessage = false;
for (WithingsStructure structure : dataStructures) {
if (structure.withEndOfMessage()) {
setEndOfMessage = true;
}
structureLength += (short)(structure.getLength());
}
if (setEndOfMessage) {
structureLength += EOM_SIZE;
}
ByteBuffer rawDataBuffer = ByteBuffer.allocate(HEADER_SIZE + structureLength);
rawDataBuffer.put((byte)0x01); // <= This seems to be always 0x01 for all commands
rawDataBuffer.putShort(getType());
rawDataBuffer.putShort(structureLength);
for (WithingsStructure structure : dataStructures) {
rawDataBuffer.put(structure.getRawData());
}
if (setEndOfMessage) {
addEndOfMessageBytes(rawDataBuffer);
}
return rawDataBuffer.array();
}
@Override
public T getStructureByType(Class type) {
for (WithingsStructure structure : this.getDataStructures()) {
if (type.isInstance(structure)) {
return (T)structure;
}
}
return null;
}
private void addEndOfMessageBytes(ByteBuffer buffer) {
buffer.putShort((short)256);
buffer.putShort((short)0);
}
public String toString() {
return GB.hexdump(this.getRawData()).toLowerCase(Locale.ROOT);
}
}