Files
utun2/lib/ble/ble_transport.h
T
evgeny ba1c4cf160 Add cross-platform BLE transport and Bluetooth settings
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.
2026-10-29 10:51:19 +01:00

68 lines
5.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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