Keep BLE discovery summaries at ten-second intervals

This commit is contained in:
evgeny committed 2026-10-30 11:21:04 +01:00
1 parent 2a19c08d62
commit eeb2373599
3 files changed
+33 -4

No files matched your search

+29 -2
View File
@@ -208,14 +208,15 @@ test_ble_bluez: отдельный dbus-run-session с подставным Blue
test_ble_winrt (Windows): объявления с настоящим QueryInterface без EventArgs2 (1809)
и с EventArgs2 (2004), сохранение адреса/типа; настоящий mailbox и hresult_error без радио; исключение
одного link не останавливает другого, ошибка radio прекращает доставку batch,
shutdown отменяет posted_task и поздние callbacks. Тест можно запускать в Wine;
shutdown отменяет диагностический таймер, posted_task и поздние callbacks. Тест можно запускать в Wine;
он не проверяет драйвер, доступность Bluetooth API и физическую передачу.
ble_probe 3: ручная проверка реального радио (scan, GATT registration, публикация
и замена тестового manufacturer-объявления); не подключается к чужим устройствам.
Успех требует READY радио, первоначальной и обновлённой публикации. Одного
scan/GATT ready недостаточно. Для диагностики ожидания ресурсов: ble_probe 15.
Логи: discovery=debug. INFO — состояния и режим DATA; DEBUG — подписки и сводка трафика;
WARN/ERROR — причины отброса/отказа. Содержимое кадров/объявлений не выводится.
WARN/ERROR — причины отброса/отказа. Для объявлений выводятся заголовок/версия и node_id;
полный payload не выводится.
Отладка Bluetooth на Windows
---------------------------
@@ -233,6 +234,32 @@ INFO: семейство/версия Windows (major.minor.build.revision и Dev
само отсутствие нового интерфейса не переводит radio в failed.
Waiting и Stopping publisher
имеют разные причины состояния; Waiting означает ожидание ресурсов публикации.
Если Waiting длится не менее 10 секунд, ближайшая периодическая сводка выдаёт WARN
один раз за этот период ожидания; последующие сводки содержат waiting_ms.
Выход из Waiting пишет длительность и новое состояние. Это диагностика, без
автоматического перезапуска или изменения политики публикации/сканирования.
При пустом списке устройств смотреть две сводки discovery=debug каждые 10 секунд
и при остановке (счётчики накопительные, включая нулевой приём):
- BLE WinRT scan totals: events — все callbacks watcher, no_manufacturer — нет
manufacturer-полей, other_company — нет нужного company_id, matching_events —
события с нужным company_id, forwarded_fields — переданные общему слою поля,
oversized_fields — поля длиннее BLE_BROADCAST_MAX. Одно событие может содержать
несколько полей; Windows callbacks обновляют счётчики параллельно со снимком.
publisher_state — последнее событие состояния (-1: publisher ещё не создан).
- BLE discovery totals: received — поступившие в driver поля, accepted —
добавления/обновления соседа, self — собственный node_id, full — нет места;
отдельные счётчики неверных аргументов/длины/заголовка/версии/ID/UTF-8.
BLE discovery packet показывает endpoint, RSSI, длину, первые два байта header
(ожидается 5643), принятую version (-1: байта нет), expected и конкретный reason.
Причины: accepted, self-node-id, neighbor-table-full, invalid-argument,
invalid-length, foreign-header, version-mismatch, zero-node-id, invalid-utf8.
Первые три случая каждой причины за жизнь driver пишутся в WARN (отказ) либо DEBUG
(приём/свой ID), все остальные — в TRACE и в счётчики. oversized в WinRT ограничен
аналогично. При ошибке decode peer=0: частичный результат не используется.
version-mismatch требует сравнить версии сборок обоих участников; это не ошибка
радиодрайвера. events>0 сам по себе не означает приём объявления VibeChat.
DEBUG: адаптер (BLE, central/peripheral, extended advertising, поддержка 2M/Coded),
этап/результат каждой служебной async-операции, состояния рекламы и сканирования,
+1 -1
View File
@@ -148,7 +148,7 @@ struct WinState : std::enable_shared_from_this<WinState> {
auto& s = *static_cast<WinState*>(arg); s.diagnostics_timer = nullptr;
s.discovery_stats("periodic");
if (s.stopped) return;
s.diagnostics_timer = uasync_set_timeout(s.ua, 10000, &s, diagnostics_tick, "ble_winrt_diagnostics");
s.diagnostics_timer = uasync_set_timeout(s.ua, 100000, &s, diagnostics_tick, "ble_winrt_diagnostics"); /* 10s, TB=0.1ms. */
if (!s.diagnostics_timer) DEBUG_WARN(CAT, "BLE WinRT diagnostics timer allocation failed; periodic summaries unavailable");
}
static void dispatch(void* arg) {
+3 -1
View File
@@ -53,6 +53,7 @@ struct ble_etcp {
struct ble_neighbor neighbors[BLE_NEIGHBORS_MAX];
uint64_t broadcast_received, broadcast_accepted, broadcast_self, broadcast_full;
uint64_t broadcast_invalid[1 - BLE_IDENTITY_ERR_UTF8]; /* Индекс — минус код decode; счётчики за жизнь driver. */
uint64_t broadcast_stats_us; /* Последняя сводка; основной tick остаётся раз в секунду. */
uint64_t retry[BLE_NEIGHBORS_MAX];
struct ble_etcp_link* links[BLE_LINKS_MAX];
ble_link_id rejected[BLE_LINKS_MAX]; /* Закрыть вне BLE callback при отказе выделения ctx. */
@@ -536,8 +537,8 @@ static void run(void* arg) {
}
static void tick(void* arg) {
struct ble_etcp* d = arg; d->timer = NULL;
broadcast_stats(d, "periodic");
uint64_t now = get_time_us();
if (now - d->broadcast_stats_us >= 10000000) { broadcast_stats(d, "periodic"); d->broadcast_stats_us = now; }
for (int i = 0; i < BLE_NEIGHBORS_MAX; i++) {
struct ble_neighbor* n = &d->neighbors[i];
if (n->identity.node_id && now - n->seen_us > BLE_NEIGHBOR_TTL_US) {
@@ -556,6 +557,7 @@ struct ble_etcp* ble_etcp_create(struct UASYNC* ua, struct UTUN_INSTANCE* inst,
struct ble_etcp* d = u_calloc(1, sizeof(*d));
if (!d) { DEBUG_ERROR(CAT, "BLE driver allocation failed"); return NULL; }
d->ua = ua; d->instance = inst; d->observer = *cfg;
d->broadcast_stats_us = get_time_us();
struct ble_config c = *cfg; c.arg = d;
c.callbacks = (struct ble_callbacks){broadcast, status, advertising, validate, connection, received, writable, invite_received, invite_writable};
if (inst) c.tx_limit = 1;