Encode BLE node identity in versioned GATT service UUIDs
This commit is contained in:
1 parent
56a24c589f
commit
1e4fca0b25
3 files changed
+31
-3
No files matched your search
@@ -6,10 +6,10 @@
|
||||
#ifndef VIBECHAT_BLE_BACKEND_H
|
||||
#define VIBECHAT_BLE_BACKEND_H
|
||||
#include "ble_transport.h"
|
||||
#include "ble_identity.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define BLE_SERVICE_UUID "f61a9020-4abc-45ac-98e1-761df4c13811"
|
||||
#define BLE_RX_UUID "f61a9021-4abc-45ac-98e1-761df4c13811"
|
||||
#define BLE_TX_UUID "f61a9022-4abc-45ac-98e1-761df4c13811"
|
||||
#define BLE_INVITE_UUID "f61a9023-4abc-45ac-98e1-761df4c13811"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "ble_identity.h"
|
||||
#include "../debug_config.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
/* Строгая проверка scalar value: запрещены overlong, surrogate и > U+10FFFF. */
|
||||
static int character(const unsigned char* p, size_t n) {
|
||||
unsigned v; int k;
|
||||
@@ -15,6 +16,26 @@ static int character(const unsigned char* p, size_t n) {
|
||||
if ((k == 3 && v < 0x800) || (k == 4 && v < 0x10000) || (v >= 0xd800 && v <= 0xdfff) || v > 0x10ffff) return -1;
|
||||
return k;
|
||||
}
|
||||
int ble_service_uuid_encode(char out[37], uint64_t id) {
|
||||
if (!out || !id) { DEBUG_ERROR(DEBUG_CATEGORY_DISCOVERY, "BLE service UUID requires output and nonzero node ID"); return -1; }
|
||||
snprintf(out, 37, "f61a9020-%04x-4505-98e1-%012llx", (unsigned)(id >> 48), (unsigned long long)(id & UINT64_C(0xffffffffffff)));
|
||||
return 0;
|
||||
}
|
||||
int ble_service_uuid_decode(const char* uuid, uint64_t* node_id) {
|
||||
if (!uuid || !node_id || strlen(uuid) != 36) return -1;
|
||||
static const char pattern[] = BLE_SERVICE_UUID_FILTER;
|
||||
uint64_t id = 0;
|
||||
for (unsigned i = 0; i < 36; i++) {
|
||||
char c = uuid[i]; if (c >= 'A' && c <= 'F') c += 'a' - 'A';
|
||||
if ((i >= 9 && i < 13) || i >= 24) {
|
||||
unsigned value = c >= '0' && c <= '9' ? (unsigned)(c - '0') : c >= 'a' && c <= 'f' ? (unsigned)(c - 'a' + 10) : 16;
|
||||
if (value == 16) return -1;
|
||||
id = (id << 4) | value;
|
||||
} else if (c != pattern[i]) return -1;
|
||||
}
|
||||
if (!id) return -1;
|
||||
*node_id = id; return 0;
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/* Объявление VibeChat: VC, версия 4, node_id BE64, имя UTF-8 до 13 байт.
|
||||
/* Идентичность VibeChat: VC, версия5, node_id BE64, имя UTF-8 до13 байт.
|
||||
* Обнаружение/выбор endpoint идёт по UUID подключаемого GATT-сервиса; bytes — общий формат события/метаданных.
|
||||
* encode возвращает размер 11..24 либо -1; decode возвращает ble_identity_result.
|
||||
* Имя сокращается по целому символу; decode отклоняет неверный UTF-8 и нулевой ID. */
|
||||
#ifndef VIBECHAT_BLE_IDENTITY_H
|
||||
#define VIBECHAT_BLE_IDENTITY_H
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#define BLE_IDENTITY_VERSION 4 /* DATA с 16-bit flow ID; ACK использует Without Response/Notify. */
|
||||
#define BLE_IDENTITY_VERSION 5 /* node_id в UUID подключаемого сервиса; DATA/ACK сохраняют прежний формат. */
|
||||
#define BLE_SERVICE_UUID_FILTER "f61a9020-0000-4505-98e1-000000000000"
|
||||
#define BLE_SERVICE_UUID_MASK "ffffffff-0000-ffff-ffff-000000000000"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -21,6 +24,10 @@ enum ble_identity_result {
|
||||
BLE_IDENTITY_ERR_UTF8 = -6
|
||||
};
|
||||
int ble_identity_encode(uint8_t output[24], uint64_t node_id, const char* name);
|
||||
/* UUID: f61a9020-<node upper16>-4505-98e1-<node lower48>. Canonical string37 с NUL;0/-1, ID ненулевой. */
|
||||
int ble_service_uuid_encode(char output[37], uint64_t node_id);
|
||||
/* Проверить семейство/версию/ненулевой ID. Регистр hex произвольный, node_id меняется лишь при успехе;0/-1. */
|
||||
int ble_service_uuid_decode(const char* uuid, uint64_t* node_id);
|
||||
/* Разбирает data[size]; output меняется только при успехе. Ошибка — отрицательный код. */
|
||||
int ble_identity_decode(struct ble_identity* output, const uint8_t* data, size_t size);
|
||||
/* Короткое имя результата decode для диагностики; возвращает статическую строку. */
|
||||
|
||||
Reference in new issue
Block a user