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.
88 lines
4.6 KiB
C
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;
|
|
}
|