Verify BLE ACK timeout independently of local completion

This commit is contained in:
evgeny committed 2026-10-29 22:17:57 +01:00
1 parent b31b772e66
commit c43726c17d
2 files changed
+11 -4

No files matched your search

+1 -1
View File
@@ -38,7 +38,7 @@ add_executable(test_ble_transport tests/test_ble_transport.c)
target_link_libraries(test_ble_transport PRIVATE vibechat_ble_core)
set_target_properties(test_ble_transport PROPERTIES AUTOMOC OFF)
add_test(NAME test_ble_transport COMMAND test_ble_transport)
set_tests_properties(test_ble_transport PROPERTIES TIMEOUT 30)
set_tests_properties(test_ble_transport PROPERTIES TIMEOUT 60) # Включает настоящий 15s ACK watchdog.
add_executable(ble_probe tests/ble_probe.c)
target_link_libraries(ble_probe PRIVATE vibechat_ble)
set_target_properties(ble_probe PROPERTIES AUTOMOC OFF)
+10 -3
View File
@@ -16,6 +16,7 @@ static struct ble_backend* backends[3];
static unsigned int mtu = 23;
static int hold, drop, reject_peer, ready_count, writable_count;
static int hold_ack;
static unsigned ack_timeouts;
static uint64_t data_wire_bytes[3];
static ble_link_id incoming_ids[3];
static void run(void* arg);
@@ -83,7 +84,8 @@ static void run(void* arg) {
}
static int validate(void* arg, ble_link_id id, uint64_t node) { (void)arg; (void)id; (void)node; return !reject_peer; }
static void connection(void* arg, ble_link_id id, uint64_t node, enum ble_state s, const char* reason) {
(void)arg; (void)id; (void)node; (void)reason; if (s == BLE_READY) ready_count++;
(void)arg; (void)id; (void)node; if (s == BLE_READY) ready_count++;
if (s == BLE_CLOSED && !strcmp(reason, "ACK progress timeout")) ack_timeouts++;
}
static void writable(void* arg, ble_link_id id) { (void)arg; (void)id; writable_count++; }
static void drain(struct UASYNC* ua) {
@@ -162,7 +164,7 @@ static void exercise(unsigned int test_mtu) {
static void exercise_flow(void) {
mtu = 517; hold = drop = reject_peer = hold_ack = 0;
struct UASYNC* ua = uasync_create(); CHECK(ua);
struct ble_config cfg = {.node_id = 1}; cfg.callbacks.writable = writable;
struct ble_config cfg = {.node_id = 1}; cfg.callbacks.writable = writable; cfg.callbacks.connection = connection;
struct ble_transport* a = ble_create(ua, &cfg); cfg.node_id = 2;
struct ble_transport* b = ble_create(ua, &cfg); CHECK(a && b && !ble_start(a) && !ble_start(b)); drain(ua);
struct ble_endpoint ep = {"1"}; ble_link_id id = ble_connect(a, &ep, 2); CHECK(id); drain(ua);
@@ -210,8 +212,13 @@ static void exercise_flow(void) {
struct fake_link* sender = slot(backends[0], id); CHECK(sender);
uint8_t future[2] = {(uint8_t)((receiver->ack_id + 1) >> 8), (uint8_t)(receiver->ack_id + 1)};
ble_backend_received(a, id, BLE_WIRE_ACK, future, 2); CHECK(!ble_tx_ready(a, id));
/* Локальный send завершается, но peer исчез: независимый от pending watchdog закрывает линк через 15s. */
ack_timeouts = 0;
uint64_t started = get_time_us(); CHECK(!ble_tx_put(b, other, frame(1, 0)));
while (!ack_timeouts && get_time_us() - started < 17000000) uasync_poll(ua, 1000);
CHECK(ack_timeouts == 1 && get_time_us() - started >= 15000000 && !ble_tx_ready(b, other));
ble_destroy(a); ble_destroy(b); uasync_destroy(ua, 0);
puts("BLE flow PASS (12500-byte duplex bound, ACK >=15ms, duplicate ACK, resume, 70000 IDs, invalid ACK, teardown)");
puts("BLE flow PASS (12500-byte duplex bound, ACK >=15ms, duplicate ACK, resume, 70000 IDs, invalid ACK, timeout, teardown)");
}
int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN);