Files
utun2/lib/ble/tests/ble_peer_probe.c
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

88 lines
4.6 KiB
C

/* Реальное Android↔desktop радио. Android instrumentation включает только тестовый echo.
* ble_peer_probe [connect|listen] [seconds]; 96 пакетов, TX saturation, побайтовая сверка. */
#include "ble_transport.h"
#include "ble_identity.h"
#include "u_async.h"
#include "debug_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static struct ble_transport* transport;
static ble_link_id session;
static unsigned sent, received_count, blocked;
static int failed, dial, seen, radio_ready;
static uint64_t peer, started, verified_bytes;
static const unsigned lengths[] = {1,13,14,20,244,512,1499,1500};
static unsigned length(unsigned n) { return lengths[n % 8]; }
static uint8_t probe_byte(unsigned n, unsigned i) { return (uint8_t)(n + i * 37); }
static void send_more(void* arg, ble_link_id id) {
(void)arg;
while (sent < 96) {
struct ll_entry* e = ll_alloc_lldgram(length(sent));
if (!e) { failed = 1; return; }
e->len = length(sent);
for (unsigned i = 0; i < e->len; i++) e->dgram[i] = probe_byte(sent, i);
int result = ble_tx_put(transport, id, e);
if (result != BLE_OK) {
queue_dgram_free(e); queue_entry_free(e);
if (result == BLE_WOULD_BLOCK) blocked++; else failed = 1;
return;
}
sent++;
}
}
static void received(void* arg, ble_link_id id) {
(void)arg; struct ll_entry* e;
while ((e = ble_rx_get(transport, id))) {
unsigned n = received_count;
if (n >= 96 || e->len != length(n)) failed = 1;
for (unsigned i = 0; i < e->len; i++) if (e->dgram[i] != probe_byte(n, i)) failed = 1;
printf("VERIFY packet=%u bytes=%u ok=%d\n", n, e->len, !failed); fflush(stdout);
verified_bytes += e->len; received_count++; queue_dgram_free(e); queue_entry_free(e);
}
}
static void connected(void* arg, ble_link_id id, uint64_t node, enum ble_state state, const char* reason) {
(void)arg;
printf("CONNECTION link=%llu peer=%016llx state=%d reason=%s\n", (unsigned long long)id, (unsigned long long)node, state, reason);
if (state == BLE_READY) { session = id; peer = node; started = get_time_us(); send_more(NULL, id); }
if (state == BLE_CLOSED && received_count < 96) failed = 1;
}
static void status(void* arg, enum ble_state state, const char* reason) {
(void)arg; printf("STATUS state=%d reason=%s\n", state, reason);
radio_ready = state == BLE_READY;
if (state == BLE_READY) {
uint8_t data[24]; int n = ble_identity_encode(data, 0x5643424c45544553ULL, "Desktop-test");
if (ble_advertise(transport, data, n) != BLE_OK) failed = 1;
}
}
static void broadcast(void* arg, const struct ble_endpoint* ep, const uint8_t* data, size_t len, int rssi) {
(void)arg; struct ble_identity identity;
if (ble_identity_decode(&identity, data, len) < 0) return;
if (!seen) printf("DISCOVER node=%016llx name=%s rssi=%d endpoint=%s\n",
(unsigned long long)identity.node_id, identity.name, rssi, ep->id);
seen = 1;
if (dial && radio_ready && !session) { session = ble_connect(transport, ep, identity.node_id); if (!session) failed = 1; }
}
int main(int argc, char** argv) {
dial = argc < 2 || !strcmp(argv[1], "connect");
int seconds = argc > 2 ? atoi(argv[2]) : 90;
debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO); debug_set_category_level(DEBUG_CATEGORY_DISCOVERY, DEBUG_LEVEL_DEBUG);
struct UASYNC* ua = uasync_create(); struct ble_config cfg = {0};
cfg.node_id = 0x5643424c45544553ULL; cfg.company_id = 0xffff;
cfg.callbacks.status = status; cfg.callbacks.broadcast = broadcast; cfg.callbacks.connection = connected;
cfg.callbacks.received = received; cfg.callbacks.writable = send_more;
transport = ble_create(ua, &cfg);
if (!transport || ble_start(transport) != BLE_OK) failed = 1;
uint64_t end = get_time_us() + (uint64_t)seconds * 1000000;
while (!failed && received_count < 96 && get_time_us() < end) uasync_poll(ua, 100);
int ok = !failed && received_count == 96 && seen && blocked;
printf("RESULT ok=%d sent=%u verified=%u blocked=%u discovered=%d peer=%016llx\n",
ok, sent, received_count, blocked, seen, (unsigned long long)peer);
if (started) {
double seconds = (get_time_us() - started) / 1000000.0;
printf("THROUGHPUT verified_bytes_each_direction=%llu seconds=%.3f aggregate_bytes_per_second=%.0f\n",
(unsigned long long)verified_bytes, seconds, seconds > 0 ? verified_bytes * 2 / seconds : 0);
}
ble_destroy(transport); uasync_destroy(ua, 0); return !ok;
}