mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-06-26 15:00:13 +02:00
99 lines
3.5 KiB
Java
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();
|
|
}
|
|
}
|