Files
MeshCore/src/helpers/ClientACLFileIntegrity.h
T
mikecarper 9fd580c89e Harden marathon-tested OTA and hardware paths
Add durable TempRadio, ACL, clock, bridge, GPS/I2C, USB logging, and Indicator recovery safeguards together with expanded automation, build/profile contracts, release metadata, and the hardware validation ledger.
2026-08-30 19:26:15 -07:00

50 lines
1.3 KiB
C++

#pragma once
#include <stddef.h>
#include <stdint.h>
#include <string.h>
namespace mesh {
static const uint8_t CLIENT_ACL_CRC_MAGIC[4] = {'M', 'C', 'A', '1'};
inline uint32_t updateClientACLCRC(uint32_t crc, const uint8_t* data,
size_t length) {
while (length-- != 0) {
crc ^= *data++;
for (uint8_t bit = 0; bit < 8; bit++) {
crc = (crc >> 1) ^ (0xEDB88320UL & (uint32_t)-(int32_t)(crc & 1U));
}
}
return crc;
}
enum ClientACLImageKind {
CLIENT_ACL_IMAGE_INVALID,
CLIENT_ACL_IMAGE_LEGACY,
CLIENT_ACL_IMAGE_CRC,
};
inline ClientACLImageKind classifyClientACLImage(
const uint8_t* image, size_t size,
size_t current_record_size, size_t legacy_record_size) {
if (size >= 8 && (size - 8) % current_record_size == 0) {
const size_t payload_size = size - 8;
uint32_t stored_crc;
memcpy(&stored_crc, image + payload_size + 4, sizeof(stored_crc));
uint32_t crc = updateClientACLCRC(0xFFFFFFFFUL, image, payload_size)
^ 0xFFFFFFFFUL;
if (memcmp(image + payload_size, CLIENT_ACL_CRC_MAGIC, 4) == 0
&& stored_crc == crc) {
return CLIENT_ACL_IMAGE_CRC;
}
}
if (size % current_record_size == 0
|| size % legacy_record_size == 0) {
return CLIENT_ACL_IMAGE_LEGACY;
}
return CLIENT_ACL_IMAGE_INVALID;
}
} // namespace mesh