Record BLE throughput results and harden the hardware probe
This commit is contained in:
1 parent
3def3f5af2
commit
33b4f0acc8
3 files changed
+85
-8
No files matched your search
@@ -99,6 +99,11 @@ Instrumentation восстанавливает Bluetooth-политику в fin
|
||||
THROUGHPUT считает verified_bytes_each_direction и aggregate_bytes_per_second
|
||||
за время от первого send до последнего проверенного echo, без GATT/ETCP handshake.
|
||||
Это двунаправленный echo goodput, не скорость PHY. Неполный прогон имеет ненулевой exit.
|
||||
При неполном прогоне THROUGHPUT complete=0 учитывает всё окно до остановки,
|
||||
включая простой после последнего echo; RESULT failed=1 и ERROR содержат target/sent/verified.
|
||||
До первого send разрыв/смена адреса возвращает пробу к discovery; разрыв во время
|
||||
передачи завершает её с ошибкой. UTUN_TEST_DEBUG=1 включает ETCP trace/connection debug
|
||||
на desktop для подробного разбора ACK/RTO без изменения штатных фильтров приложения.
|
||||
Перед пробой выключить BLE обычного desktop GUI: два сервиса с одинаковыми UUID
|
||||
на одном адаптере делают GATT discovery неоднозначным.
|
||||
|
||||
@@ -165,3 +170,32 @@ LAN-приглашения или исходящую отправку. Ново
|
||||
Это не полный нагрузочный проход обратной роли.
|
||||
- Windows backend проверен кросс-компиляцией MinGW/C++WinRT, без физического Win BT.
|
||||
- Общие тесты: 230/230; отдельные BLE/BlueZ/UI и ASAN/UBSAN пройдены.
|
||||
|
||||
Write Without Response / Notification: проверка 2026-10-29
|
||||
--------------------------------------------------------
|
||||
Android, BlueZ и WinRT используют быстрый DATA, INVITE сохраняет Request/Indication.
|
||||
Android HIGH/MTU517/2M сохранены; WinRT запрашивает ThroughputOptimized при наличии
|
||||
API Windows 11. BlueZ D-Bus не предоставляет аналогичного per-link профиля.
|
||||
Desktop GUI/Linux, Android APK+instrumentation (arm64/x86_64), WinRT cross-build PASS.
|
||||
./check.sh: 230/230 + proxy/burst/load; BLE common/BlueZ/identity/ETCP/UI: 5/5;
|
||||
BLE ASAN/UBSAN: 3/3; Android app/router unit tests: 770/770.
|
||||
|
||||
Телефон RZ8R72MG64B, один desktop BLE-сервис на адаптере:
|
||||
- Android central: 512/512 ETCP echo по 1500 байт, window=16, по 768000 байт
|
||||
в каждом направлении за 61.694 с; суммарный goodput 24897 B/s (12448 B/s
|
||||
на направление). Приглашения 939 байт и ACK приложений прошли в обе стороны.
|
||||
PHY2M TX/RX, MTU517; для Android central подтверждён interval=12 (15 ms).
|
||||
- Сырой BLE, Android central: 96/96 echo, по 45636 байт за 4.473 с,
|
||||
суммарно 20407 B/s. Размеры пакетов различаются, напрямую с ETCP не сравнивать.
|
||||
- Desktop central: приглашения/ACK прошли, но за окно 85 с ETCP подтвердил
|
||||
только 20/512 echo. Повтор без приглашений, window=1: 0/32 echo за окно 65 с,
|
||||
после первого send 50.060 с повторялись INIT/INIT_RESPONSE и DATA RTO,
|
||||
DATA_RTT_us=0; BLE-сборщик не регистрировал отбросов. Причина не установлена;
|
||||
исправление этого сбоя не входит в подтверждённый результат профиля скорости.
|
||||
|
||||
Журналы текущего сеанса: /tmp/ble-speed-android-central-{desktop,logcat}.log,
|
||||
/tmp/ble-speed-desktop-central-{desktop,logcat}.log,
|
||||
/tmp/ble-speed-desktop-central-serial-retry-desktop.log и
|
||||
/tmp/ble-speed-desktop-central-serial-live-logcat.log.
|
||||
После аппаратных проб обычный desktop VibeChat перезапущен новой сборкой;
|
||||
Android instrumentation восстановила обычную Bluetooth-политику в finally.
|
||||
@@ -4,6 +4,21 @@
|
||||
|
||||
## Текущие задачи
|
||||
|
||||
[ ] **BLE/ETCP: повторные INIT и отсутствие DATA ACK при desktop central** — 29.10.2026.
|
||||
После включения Write Without Response/Notification GATT/MTU517 и PHY2M работают,
|
||||
но desktop central подтвердил 20/512 echo за 85 с; повтор window=1 — 0/32 за 65 с.
|
||||
На desktop повторяются INIT/INIT_RESPONSE и DATA RTO с DATA_RTT_us=0;
|
||||
BLE-сборщик не регистрирует потерь фрагментов. Точная причина не установлена.
|
||||
Android central: 512/512 echo и приглашения в обе стороны, суммарный goodput 24897 B/s.
|
||||
Результаты, параметры проб и пути диагностических журналов: [ble_etcp.txt](ble_etcp.txt).
|
||||
|
||||
[+] **BLE: DATA без ATT ACK и профиль скорости desktop/Android** — 29.10.2026.
|
||||
Write Without Response/Notification для DATA в Android/BlueZ/WinRT; INVITE сохраняет Request/Indication.
|
||||
Android HIGH/MTU517/2M, Windows ThroughputOptimized с проверкой API и фактическими параметрами.
|
||||
Сводка скорости/очередей/ожиданий GATT; нагрузочная проба с ограниченным окном и проверкой содержимого.
|
||||
Общие тесты 230/230 + proxy/burst/load, BLE 5/5, ASAN/UBSAN 3/3, Android unit 770/770.
|
||||
Desktop и APK собираются; WinRT cross-build PASS. Ограничение обратной роли вынесено выше.
|
||||
|
||||
[ ] **Windows: единые UTF-8 пути конфигурации** — 29.10.2026.
|
||||
GUI передаёт toUtf8, а config_parser/config_updater используют fopen и ANSI Win32 API.
|
||||
Перевести эти операции на существующий file_io с wide-путями, проверить профиль в каталоге с кириллицей.
|
||||
|
||||
@@ -18,7 +18,7 @@ static unsigned verified;
|
||||
static uint64_t transfer_started, transfer_finished;
|
||||
static int invitations, invitation_sent, invitation_received, invitation_delivered;
|
||||
static char invitation_link[LOCAL_TRANSPORT_DATA_MAX + 1];
|
||||
static int failed, radio_ready;
|
||||
static int failed, radio_ready, connection_closed;
|
||||
static struct ble_etcp* driver;
|
||||
static struct UTUN_INSTANCE* instance;
|
||||
static void event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int len) {
|
||||
@@ -37,8 +37,15 @@ static void event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int
|
||||
}
|
||||
static void receive(struct ETCP_CONN* conn, struct ll_entry* e) {
|
||||
(void)conn;
|
||||
if (e->len != 1500) failed = 1;
|
||||
for (unsigned i = 1; i < e->len; i++) if (e->dgram[i] != (uint8_t)(verified + i * 37)) failed = 1;
|
||||
if (e->len != 1500) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DISCOVERY, "BLE probe size mismatch packet=%u expected=1500 actual=%u", verified, e->len);
|
||||
failed = 1;
|
||||
}
|
||||
for (unsigned i = 1; i < e->len; i++) if (e->dgram[i] != (uint8_t)(verified + i * 37)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DISCOVERY, "BLE probe byte mismatch packet=%u offset=%u expected=%u actual=%u",
|
||||
verified, i, (uint8_t)(verified + i * 37), e->dgram[i]);
|
||||
failed = 1; break;
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_DISCOVERY, "VERIFY ETCP packet=%u bytes=%u ok=%d", verified, e->len, !failed);
|
||||
verified++; transfer_finished = get_time_us();
|
||||
queue_dgram_free(e); queue_entry_free(e);
|
||||
@@ -51,6 +58,10 @@ static void status(void* arg, enum ble_state s, const char* reason) {
|
||||
if (ble_advertise(ble_etcp_radio(driver), bytes, n)) failed = 1;
|
||||
}
|
||||
}
|
||||
static void connection(void* arg, ble_link_id id, uint64_t peer, enum ble_state state, const char* reason) {
|
||||
(void)arg; (void)id; (void)peer; (void)reason;
|
||||
if (state == BLE_CLOSED) connection_closed = 1;
|
||||
}
|
||||
int main(int argc, char** argv) {
|
||||
int seconds = argc > 1 ? atoi(argv[1]) : 60;
|
||||
unsigned packets = argc > 4 ? (unsigned)atoi(argv[4]) : 32;
|
||||
@@ -64,6 +75,10 @@ int main(int argc, char** argv) {
|
||||
snprintf(config, sizeof(config), "[global]\nmy_private_key=%s\nmy_public_key=%s\nauto_sockets=no\n[ntp]\nenabled=no\n", priv, pub);
|
||||
instance = utun_instance_create_from_str(ua, config);
|
||||
if (!instance) { uasync_destroy(ua, 0); return 1; }
|
||||
if (getenv("UTUN_TEST_DEBUG")) {
|
||||
debug_set_category_level(DEBUG_CATEGORY_ETCP, DEBUG_LEVEL_TRACE);
|
||||
debug_set_category_level(DEBUG_CATEGORY_CONNECTION, DEBUG_LEVEL_DEBUG);
|
||||
}
|
||||
invitations = argc > 3 && !strcmp(argv[3], "invites");
|
||||
if (invitations) {
|
||||
struct InviteData invite = {.channelId = 0x424c4554455354ULL, .join_key = 123, .addrCount = 24};
|
||||
@@ -75,7 +90,8 @@ int main(int argc, char** argv) {
|
||||
if (invite_link_encode(&invite, NULL, invitation_link, sizeof(invitation_link)) < 0) failed = 1;
|
||||
chat_event_set_handler(instance, event); chat_setting_set(instance, "bluetooth_invites_enabled", "1");
|
||||
}
|
||||
struct ble_config c = {.node_id = instance->node_id, .company_id = 0xffff}; c.callbacks.status = status;
|
||||
struct ble_config c = {.node_id = instance->node_id, .company_id = 0xffff};
|
||||
c.callbacks.status = status; c.callbacks.connection = connection;
|
||||
driver = ble_etcp_create(ua, instance, &c);
|
||||
if (!driver || etcp_bind(instance, ETCP_ID_BLE_PROBE, receive) || ble_start(ble_etcp_radio(driver))) failed = 1;
|
||||
uint64_t end = get_time_us() + (uint64_t)seconds * 1000000, peer = 0, retry = 0;
|
||||
@@ -84,6 +100,12 @@ int main(int argc, char** argv) {
|
||||
while (!failed && (verified < packets || (invitations && (!invitation_received || !invitation_delivered))) && get_time_us() < end) {
|
||||
uasync_poll(ua, 100);
|
||||
if (failed) break;
|
||||
if (connection_closed) {
|
||||
connection_closed = 0;
|
||||
if (transfer_started) { DEBUG_ERROR(DEBUG_CATEGORY_DISCOVERY, "BLE probe connection lost during transfer"); failed = 1; break; }
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DISCOVERY, "BLE probe connection closed before transfer; retrying discovery");
|
||||
peer = 0; retry = get_time_us() + 1000000;
|
||||
}
|
||||
if (!peer && dial && radio_ready && get_time_us() >= retry) {
|
||||
struct ble_neighbor neighbors[BLE_NEIGHBORS_MAX]; size_t n = ble_etcp_neighbors(driver, neighbors, BLE_NEIGHBORS_MAX);
|
||||
for (size_t i = 0; i < n; i++) if (!strcmp(neighbors[i].identity.name, "ETCP-probe")) {
|
||||
@@ -110,12 +132,18 @@ int main(int argc, char** argv) {
|
||||
if (etcp_send(conn, e)) { queue_dgram_free(e); queue_entry_free(e); failed = 1; }
|
||||
else { if (!transfer_started) transfer_started = get_time_us(); sent++; }
|
||||
}
|
||||
uint64_t measured_end = verified == packets ? transfer_finished : get_time_us();
|
||||
if (verified != packets || (invitations && (!invitation_delivered || invitation_received != 1))) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DISCOVERY, "BLE probe incomplete target=%u sent=%u verified=%u invite_delivered=%d invite_received=%d",
|
||||
packets, sent, verified, invitation_delivered, invitation_received);
|
||||
failed = 1;
|
||||
}
|
||||
ble_etcp_destroy(driver); utun_instance_destroy(instance); uasync_destroy(ua, 0);
|
||||
printf("RESULT BLE ETCP sent=%u verified=%u bytes=%u failed=%d\n", sent, verified, verified * 1500, failed);
|
||||
if (transfer_started && transfer_finished > transfer_started) {
|
||||
double elapsed = (transfer_finished - transfer_started) / 1000000.0;
|
||||
printf("THROUGHPUT window=%u verified_bytes_each_direction=%u seconds=%.3f aggregate_bytes_per_second=%.0f\n",
|
||||
window, verified * 1500, elapsed, verified * 3000.0 / elapsed);
|
||||
if (transfer_started && measured_end > transfer_started) {
|
||||
double elapsed = (measured_end - transfer_started) / 1000000.0;
|
||||
printf("THROUGHPUT complete=%d window=%u verified_bytes_each_direction=%u seconds=%.3f aggregate_bytes_per_second=%.0f\n",
|
||||
!failed, window, verified * 1500, elapsed, verified * 3000.0 / elapsed);
|
||||
}
|
||||
if (invitations) printf("RESULT BLE invitations sent=%d delivered=%d received=%d\n", invitation_sent, invitation_delivered, invitation_received);
|
||||
return failed || verified != packets || (invitations && (!invitation_delivered || invitation_received != 1));
|
||||
|
||||
Reference in new issue
Block a user