1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-26 15:00:13 +02:00
Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java
2021-01-10 23:38:13 +01:00

99 lines
3.5 KiB
Java

/* Copyright (C) 2019-2021 Daniel Dakhno
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.CRC32;
public class ConfigFileBuilder {
private ConfigPayload[] configs;
public ConfigFileBuilder(ConfigPayload[] configs) {
this.configs = configs;
}
public byte[] build(boolean appendChecksum) {
int payloadSize = 0;
for (ConfigPayload payload : this.configs) {
payloadSize += payload.getData().length;
}
int headerSize = 0;
for (ConfigPayload payload : this.configs) {
headerSize += payload.getHeader().length + 3; // button + version + null;
}
ByteBuffer buffer = ByteBuffer.allocate(
3 // version bytes
+ 1 // header count byte
+ headerSize
+ 1 // payload count byte
+ payloadSize
+ 1 // customization count byte
+ (appendChecksum ? 4 : 0) // checksum
);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.put(new byte[]{(byte) 0x01, (byte) 0x00, (byte) 0x00}); // version
buffer.put((byte) this.configs.length);
int buttonIndex = 0x00;
for (ConfigPayload payload : configs) {
buffer.put((byte) (buttonIndex += 0x10));
buffer.put((byte) 0x01);
buffer.put(payload.getHeader());
buffer.put((byte) 0x00);
}
ArrayList<ConfigPayload> distinctPayloads = new ArrayList<>(3);
// distinctPayloads.add(configs[0].getData());
compareLoop:
for (int payloadIndex = 0; payloadIndex < configs.length; payloadIndex++) {
for (int compareTo = 0; compareTo < distinctPayloads.size(); compareTo++) {
if (configs[payloadIndex].equals(distinctPayloads.get(compareTo))) {
continue compareLoop;
}
}
distinctPayloads.add(configs[payloadIndex]);
}
buffer.put((byte) distinctPayloads.size());
for (ConfigPayload payload : distinctPayloads) {
buffer.put(payload.getData());
}
buffer.put((byte) 0x00);
ByteBuffer buffer2 = ByteBuffer.allocate(buffer.position() + (appendChecksum ? 4 : 0));
buffer2.order(ByteOrder.LITTLE_ENDIAN);
buffer2.put(buffer.array(), 0, buffer.position());
if (!appendChecksum) return buffer2.array();
CRC32 crc = new CRC32();
crc.update(buffer.array(), 0, buffer.position());
buffer2.putInt((int) crc.getValue());
return buffer2.array();
}
}