Define BLE v5 visibility, admission and bounded publication contracts
This commit is contained in:
1 parent
5deb6de7ee
commit
d00a642c49
3 files changed
+19
-11
No files matched your search
@@ -329,6 +329,7 @@ int ble_advertise(struct ble_transport* t, const void* data, size_t len) {
|
||||
return ble_backend_advertise(t->backend, data, len);
|
||||
}
|
||||
ble_link_id ble_connect(struct ble_transport* t, const struct ble_endpoint* ep, uint64_t peer) {
|
||||
if (!peer) { DEBUG_ERROR(CAT, "BLE connect requires expected peer service identity"); return 0; }
|
||||
if (!t || !t->ready) { DEBUG_WARN(CAT, "BLE connect before ready"); return 0; }
|
||||
struct ble_connection* c = new_link(t, ep, 1, peer);
|
||||
if (!c) return 0;
|
||||
|
||||
@@ -39,7 +39,7 @@ struct ble_advertising_power {
|
||||
/* Копия возможностей активного радио, без I/O; NULL/не готово возвращает неизвестные значения. Только uasync. */
|
||||
struct ble_advertising_power ble_get_advertising_power(const struct ble_transport* transport);
|
||||
struct ble_callbacks {
|
||||
/* Объявление нужного company_id; буфер заимствован до возврата. RSSI=127 означает неизвестный. */
|
||||
/* Node UUID из объявления сервиса: общий ble_identity bytes; буфер заимствован. 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 не подтверждает приём. */
|
||||
@@ -52,14 +52,14 @@ struct ble_callbacks {
|
||||
};
|
||||
struct ble_config {
|
||||
uint64_t node_id; /* Ненулевой ID для HELLO; не криптографическое доказательство. */
|
||||
uint16_t company_id; /* Manufacturer ID, одинаковый у участников. 0xffff только для разработки. */
|
||||
uint16_t company_id; /* Необязательные метаданные имени Android; адресация определяется UUID, а не manufacturer. */
|
||||
const char* adapter; /* Linux: hci0 либо NULL (первый адаптер); Windows: NULL. Копируется. */
|
||||
struct ble_callbacks callbacks;
|
||||
void* arg; /* Заимствованный контекст callbacks, живёт до destroy. */
|
||||
unsigned tx_limit; /* Целых TX-пакетов, включая фрагментируемый: 0=64, 1..64. */
|
||||
unsigned tx_window; /* DATA в очереди/отправке/ожидании удалённого ACK: 0=BLE_TX_WINDOW_FRAMES, 1..64. */
|
||||
uint8_t initial_advertisement[BLE_BROADCAST_MAX]; /* Начальное объявление; копируется вместе с config. */
|
||||
size_t initial_advertisement_size; /* 0: выключено; 1..24: Windows запускает publisher до GATT. */
|
||||
size_t initial_advertisement_size; /* 0: скрыть идентичность в advertising; 1..24: объявлять node UUID сервиса. */
|
||||
};
|
||||
/* Создать остановленный transport. ua/config заимствованы только ua; возвращает handle или NULL с логом. */
|
||||
struct ble_transport* ble_create(struct UASYNC* ua, const struct ble_config* config);
|
||||
@@ -67,13 +67,14 @@ struct ble_transport* ble_create(struct UASYNC* ua, const struct ble_config* con
|
||||
int ble_start(struct ble_transport* transport);
|
||||
/* Остановить свои объявления/scan/сессии, завершить pending и освободить очереди. Идемпотентно, вне callbacks. */
|
||||
void ble_stop(struct ble_transport* transport);
|
||||
/* Разрешить/запретить новые входящие; запрет закрывает текущие входящие. По умолчанию разрешены. */
|
||||
/* Разрешить/запретить наши новые входящие сессии; запрет закрывает текущие входящие. Общий ACL ОС этим не управляется. */
|
||||
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-объявление сервиса независимо. */
|
||||
/* Задать метаданные ble_identity и публиковать node UUID сервиса. NULL,0 скрывает UUID/метаданные в advertising.
|
||||
* Сервис остаётся зарегистрированным для известных адресов; допуск определяет ble_set_incoming, не видимость.
|
||||
* Регистрация не гарантирует выход в эфир/получение. Собственное имя Windows выбирается ОС. */
|
||||
int ble_advertise(struct ble_transport* transport, const void* data, size_t len);
|
||||
/* Самостоятельно выполнить connect/discovery/subscribe/HELLO. expected_node=0 не проверяет ID ответа.
|
||||
/* Самостоятельно выполнить connect/discovery/subscribe/HELLO. expected_node ненулевой, задаёт UUID сервиса и ID ответа.
|
||||
* Handle либо 0 при отказе. Готовность/ошибка — connection; физическое ACL может обслуживать другие сервисы. */
|
||||
ble_link_id ble_connect(struct ble_transport* transport, const struct ble_endpoint* endpoint, uint64_t expected_node);
|
||||
/* Копировать направление существующего GATT в outgoing (0/1). 0 — успех, -1 — неверный handle/аргументы с логом. */
|
||||
|
||||
+10
-4
@@ -285,7 +285,8 @@ struct WinState : std::enable_shared_from_this<WinState> {
|
||||
parameters.IsConnectable(true); parameters.IsDiscoverable(broadcast_enabled);
|
||||
DEBUG_INFO(CAT, "BLE WinRT start single GATT advertisement UUID=%s connectable=1 discoverable=%d",
|
||||
service_uuid.c_str(), broadcast_enabled);
|
||||
service_requested = true; publication_deadline = get_time_us() + 20000000;
|
||||
service_requested = true;
|
||||
if (!publication_deadline) publication_deadline = get_time_us() + 20000000;
|
||||
step("GattServiceProvider.StartAdvertising"); provider.StartAdvertising(parameters);
|
||||
}
|
||||
/* Один GATT provider обслуживает и обнаружение, и подключения; отдельного publisher нет. */
|
||||
@@ -304,11 +305,14 @@ struct WinState : std::enable_shared_from_this<WinState> {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (status == GattServiceProviderAdvertisementStatus::Started) {
|
||||
if (status == GattServiceProviderAdvertisementStatus::Started ||
|
||||
status == GattServiceProviderAdvertisementStatus::StartedWithoutAllAdvertisementData) {
|
||||
if (status != GattServiceProviderAdvertisementStatus::Started)
|
||||
DEBUG_WARN(CAT, "BLE WinRT advertising omitted some fields UUID=%s; confirm service UUID on scanner", service_uuid.c_str());
|
||||
publication_deadline = 0; service_ready = true;
|
||||
ble_backend_advertising(owner, broadcast_enabled ? BLE_READY : BLE_CLOSED, "GATT discovery publication applied"); ready();
|
||||
} else if (status == GattServiceProviderAdvertisementStatus::Aborted) radio_error("GATT advertising aborted", error);
|
||||
else if (service_requested) fail("GATT advertisement stopped unexpectedly");
|
||||
else if (service_requested && service_ready) fail("GATT advertisement stopped unexpectedly");
|
||||
}
|
||||
/* Только доступные Win11 API: фактические параметры отделены от запрошенного профиля. */
|
||||
void log_connection(ble_link_id id) {
|
||||
@@ -792,6 +796,7 @@ extern "C" struct ble_backend* ble_backend_create(struct ble_transport* owner, s
|
||||
auto state = std::make_shared<WinState>(); state->owner = owner; state->ua = ua; state->company = cfg->company_id;
|
||||
state->broadcast_size = cfg->initial_advertisement_size;
|
||||
state->broadcast_enabled = state->broadcast_size != 0;
|
||||
state->publication_deadline = get_time_us() + 20000000;
|
||||
char uuid[37]; if (ble_service_uuid_encode(uuid, cfg->node_id)) return nullptr; state->service_uuid = uuid;
|
||||
if (state->broadcast_size > state->broadcast.size()) { DEBUG_ERROR(CAT, "BLE WinRT initial advertisement too large"); return nullptr; }
|
||||
if (state->broadcast_size) std::memcpy(state->broadcast.data(), cfg->initial_advertisement, state->broadcast_size);
|
||||
@@ -827,9 +832,10 @@ extern "C" struct ble_backend* ble_backend_create(struct ble_transport* owner, s
|
||||
if (!adapter.IsLowEnergySupported() || !adapter.IsCentralRoleSupported() || !adapter.IsPeripheralRoleSupported()) {
|
||||
s.fail("adapter lacks BLE central/peripheral support"); return;
|
||||
}
|
||||
s.adapter_ready = true; WinState::diagnostics_tick(&s);
|
||||
s.adapter_ready = true;
|
||||
s.ensure_service();
|
||||
});
|
||||
WinState::diagnostics_tick(state.get());
|
||||
void* memory = u_malloc(sizeof(ble_backend));
|
||||
if (!memory) { DEBUG_ERROR(CAT, "BLE WinRT allocation failed"); state->shutdown(); return nullptr; }
|
||||
return new(memory) ble_backend{state};
|
||||
|
||||
Reference in new issue
Block a user