#include "ble_identity.h" #include "../debug_config.h" #include /* Строгая проверка scalar value: запрещены overlong, surrogate и > U+10FFFF. */ static int character(const unsigned char* p, size_t n) { unsigned v; int k; if (!n || !p[0]) return -1; if (p[0] < 128) return 1; if (p[0] >= 0xc2 && p[0] <= 0xdf) { k = 2; v = p[0] & 31; } else if (p[0] >= 0xe0 && p[0] <= 0xef) { k = 3; v = p[0] & 15; } else if (p[0] >= 0xf0 && p[0] <= 0xf4) { k = 4; v = p[0] & 7; } else return -1; if (n < (size_t)k) return -1; for (int i = 1; i < k; i++) { if ((p[i] & 0xc0) != 0x80) return -1; v = (v << 6) | (p[i] & 63); } if ((k == 3 && v < 0x800) || (k == 4 && v < 0x10000) || (v >= 0xd800 && v <= 0xdfff) || v > 0x10ffff) return -1; return k; } int ble_identity_encode(uint8_t out[24], uint64_t id, const char* name) { if (!out || !id || !name) goto invalid; size_t length = strlen(name), offset = 0; while (offset < length) { int n = character((const unsigned char*)name + offset, length - offset); if (n < 0) goto invalid; if (offset + n > 13) break; offset += n; } out[0] = 'V'; out[1] = 'C'; out[2] = 1; for (int i = 10; i >= 3; i--) { out[i] = id; id >>= 8; } memcpy(out + 11, name, offset); return (int)(11 + offset); invalid: DEBUG_WARN(DEBUG_CATEGORY_DISCOVERY, "BLE identity encode: invalid ID/name"); return -1; } int ble_identity_decode(struct ble_identity* out, const uint8_t* data, size_t size) { if (!out || !data || size < 11 || size > 24 || data[0] != 'V' || data[1] != 'C' || data[2] != 1) return -1; struct ble_identity result = {0}; for (int i = 3; i < 11; i++) result.node_id = (result.node_id << 8) | data[i]; if (!result.node_id) goto invalid; for (size_t pos = 11; pos < size;) { int n = character(data + pos, size - pos); if (n < 0) goto invalid; pos += n; } memcpy(result.name, data + 11, size - 11); *out = result; return 0; invalid: DEBUG_WARN(DEBUG_CATEGORY_DISCOVERY, "BLE identity decode: invalid ID/UTF-8"); return -1; }