Integrate shared C transport with desktop and Android frontends, add radio probes and detailed Windows diagnostics, and fix GUI build dependencies and early configuration startup errors.
68 lines
5.8 KiB
C
68 lines
5.8 KiB
C
/* BLE transport без Qt: create → start → advertise/connect → tx_put/rx_get → destroy.
|
||
* Все API и callbacks принадлежат переданному uasync-потоку; callbacks не вызывают stop/destroy/disconnect.
|
||
* Объявление — повторяемые ОС байты, не надёжная датаграмма. node_id в HELLO не аутентифицирован.
|
||
* Один сервис обслуживает независимые соединения; данные — непрозрачные кадры 1..1500 байт.
|
||
* Целые кадры находятся в ll_queue. На радио Write Request/Indication; своих ретрансляций нет.
|
||
* Диагностика: discovery (BLE-префикс). NULL validate разрешает запрос, как и начальная политика GUI. */
|
||
#ifndef VIBECHAT_BLE_TRANSPORT_H
|
||
#define VIBECHAT_BLE_TRANSPORT_H
|
||
#include <stddef.h>
|
||
#include <stdint.h>
|
||
#include "../ll_queue.h"
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
#define BLE_FRAME_MAX 1500
|
||
#define BLE_BROADCAST_MAX 24
|
||
#define BLE_ENDPOINT_MAX 256
|
||
#define BLE_LINKS_MAX 16
|
||
#define BLE_QUEUE_MAX 64
|
||
struct ble_transport;
|
||
struct UASYNC;
|
||
typedef uint64_t ble_link_id;
|
||
enum ble_result { BLE_OK = 0, BLE_ERROR = -1, BLE_WOULD_BLOCK = -2, BLE_NOT_READY = -3 };
|
||
enum ble_state { BLE_STARTING, BLE_READY, BLE_CLOSED };
|
||
struct ble_endpoint { char id[BLE_ENDPOINT_MAX]; }; /* Непрозрачный адрес backend, копируется целиком. */
|
||
struct ble_callbacks {
|
||
/* Объявление нужного company_id; буфер заимствован до возврата. RSSI=127 означает неизвестный. */
|
||
void (*broadcast)(void* arg, const struct ble_endpoint* endpoint, const uint8_t* data, size_t len, int rssi);
|
||
void (*status)(void* arg, enum ble_state state, const char* reason); /* Состояние радио, reason заимствован. */
|
||
void (*advertising)(void* arg, enum ble_state state, const char* reason); /* Публикация bytes: READY не подтверждает приём. */
|
||
int (*validate)(void* arg, ble_link_id link, uint64_t node_id); /* Ненулевой результат разрешает HELLO. */
|
||
void (*connection)(void* arg, ble_link_id link, uint64_t node_id, enum ble_state state, const char* reason);
|
||
void (*received)(void* arg, ble_link_id link); /* rx_get до NULL; допустим синхронный drain. */
|
||
void (*writable)(void* arg, ble_link_id link); /* После заполнения TX снова можно вызвать tx_put. */
|
||
};
|
||
struct ble_config {
|
||
uint64_t node_id; /* Ненулевой ID для HELLO; не криптографическое доказательство. */
|
||
uint16_t company_id; /* Manufacturer ID, одинаковый у участников. 0xffff только для разработки. */
|
||
const char* adapter; /* Linux: hci0 либо NULL (первый адаптер); Windows: NULL. Копируется. */
|
||
struct ble_callbacks callbacks;
|
||
void* arg; /* Заимствованный контекст callbacks, живёт до destroy. */
|
||
};
|
||
/* Создать остановленный transport. ua/config заимствованы только ua; возвращает handle или NULL с логом. */
|
||
struct ble_transport* ble_create(struct UASYNC* ua, const struct ble_config* config);
|
||
/* Начать регистрацию сервиса/scan; 0 означает запуск, готовность сообщает status. Повторный start — ошибка. */
|
||
int ble_start(struct ble_transport* transport);
|
||
/* Остановить свои объявления/scan/сессии, завершить pending и освободить очереди. Идемпотентно, вне callbacks. */
|
||
void ble_stop(struct ble_transport* transport);
|
||
/* Разрешить/запретить новые входящие; запрет закрывает текущие входящие. По умолчанию разрешены. */
|
||
void ble_set_incoming(struct ble_transport* transport, int allowed);
|
||
void ble_destroy(struct ble_transport* transport); /* stop + free; NULL допустим. */
|
||
/* Заменить повторяемое manufacturer-объявление (0..24 байта); копирует данные. NULL,0 выключает его.
|
||
* Регистрация не гарантирует выход в эфир/получение. Собственное connectable-объявление сервиса независимо. */
|
||
int ble_advertise(struct ble_transport* transport, const void* data, size_t len);
|
||
/* Самостоятельно выполнить connect/discovery/subscribe/HELLO. expected_node=0 не проверяет ID ответа.
|
||
* Handle либо 0 при отказе. Готовность/ошибка — connection; физическое ACL может обслуживать другие сервисы. */
|
||
ble_link_id ble_connect(struct ble_transport* transport, const struct ble_endpoint* endpoint, uint64_t expected_node);
|
||
void ble_disconnect(struct ble_transport* transport, ble_link_id link);
|
||
/* Принять целый ll_entry в TX. При 0 владение передано; при любом отказе entry остаётся вызывающему.
|
||
* entry должен быть вне очереди, dgram!=NULL, len=1..1500. Заполнение: WOULD_BLOCK, затем writable. */
|
||
int ble_tx_put(struct ble_transport* transport, ble_link_id link, struct ll_entry* entry);
|
||
/* Извлечь целый кадр из RX или NULL; вызывающий освобождает queue_dgram_free + queue_entry_free. */
|
||
struct ll_entry* ble_rx_get(struct ble_transport* transport, ble_link_id link);
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif
|