Attach packet drivers to initially empty ETCP connections. Share BLE neighbor tracking and group fallback between desktop and Android in cgathui_common. Deliver join links through a dedicated Write/Indicate characteristic with independent fragmentation queues, application acknowledgements, deduplication and bounded retries. Merge LAN/BLE discovery and add a separate Bluetooth invitation reception setting to both clients. Validation: 230 core tests, BLE transport/BlueZ/UI tests, ASAN/UBSAN, Linux GUI and Android builds, and Windows backend cross-compilation. Physical Android/Linux invitation exchange passed with either GATT initiator. The Android-initiated run also verified all 32 ETCP packets of 1500 bytes; the desktop-initiated load run reached 7/32 within its 45-second time limit.
63 lines
3.6 KiB
C++
63 lines
3.6 KiB
C++
/* Настоящий frontend и C-транспорт, управляемый backend без радио/системной шины. */
|
|
#include "../transport/desktop_ble.h"
|
|
#include "../../../lib/ble/ble_backend.h"
|
|
#include "../../../lib/ble/ble_identity.h"
|
|
#include "../../../lib/u_async.h"
|
|
#include "../../../lib/debug_config.h"
|
|
#include <QtTest>
|
|
#include <memory>
|
|
|
|
struct ble_backend { ble_transport* owner = nullptr; };
|
|
static ble_backend backend;
|
|
static int creations, destructions, advertisements;
|
|
static QByteArray advertised;
|
|
extern "C" ble_backend* ble_backend_create(ble_transport* owner, UASYNC*, const ble_config*) {
|
|
backend.owner = owner; ++creations; return &backend;
|
|
}
|
|
extern "C" void ble_backend_destroy(ble_backend*) { backend.owner = nullptr; ++destructions; }
|
|
extern "C" int ble_backend_advertise(ble_backend*, const uint8_t* data, size_t len) {
|
|
advertised = QByteArray(reinterpret_cast<const char*>(data), int(len)); ++advertisements; return 0;
|
|
}
|
|
extern "C" int ble_backend_connect(ble_backend*, ble_link_id, const ble_endpoint*) { return BLE_ERROR; }
|
|
extern "C" void ble_backend_close(ble_backend*, ble_link_id) {}
|
|
extern "C" int ble_backend_send(ble_backend*, ble_link_id, enum ble_channel, const uint8_t*, size_t) { return BLE_ERROR; }
|
|
|
|
class DesktopBleTest : public QObject {
|
|
Q_OBJECT
|
|
private slots:
|
|
void policyAndDiscovery() {
|
|
debug_config_init();
|
|
auto destroy = [](UASYNC* ua) { uasync_destroy(ua, 0); };
|
|
std::unique_ptr<UASYNC, decltype(destroy)> ua(uasync_create(), destroy); QVERIFY(ua);
|
|
DesktopBle radio(ua.get(), 1);
|
|
radio.apply(0, "Desktop"); QVERIFY(!radio.transport()); QCOMPARE(creations, 0);
|
|
radio.apply(3, "Desktop"); QVERIFY(radio.transport()); QCOMPARE(creations, 1);
|
|
QCOMPARE(radio.snapshot().state, BLE_STARTING); QCOMPARE(advertisements, 0);
|
|
ble_endpoint endpoint{}; strcpy(endpoint.id, "peer");
|
|
QCOMPARE(ble_backend_incoming(backend.owner, &endpoint), ble_link_id(0));
|
|
ble_backend_status(backend.owner, 1, "ready"); QCOMPARE(advertisements, 1);
|
|
ble_identity identity{};
|
|
QCOMPARE(ble_identity_decode(&identity, reinterpret_cast<const uint8_t*>(advertised.constData()), advertised.size()), 0);
|
|
QCOMPARE(identity.node_id, uint64_t(1)); QCOMPARE(QByteArray(identity.name), QByteArray("Desktop"));
|
|
radio.apply(3, "Desktop"); QCOMPARE(advertisements, 1);
|
|
radio.apply(7, "Renamed"); QCOMPARE(advertisements, 2);
|
|
QVERIFY(ble_backend_incoming(backend.owner, &endpoint) != 0);
|
|
uint8_t bytes[24]; int length = ble_identity_encode(bytes, 2, "Android");
|
|
ble_backend_broadcast(backend.owner, &endpoint, bytes, length, -42);
|
|
const auto peers = radio.snapshot().peers;
|
|
QCOMPARE(peers.size(), 1); QVERIFY(peers.first().contains("Android")); QVERIFY(peers.first().contains("-42"));
|
|
ble_backend_broadcast(backend.owner, &endpoint, bytes, length, -40);
|
|
QCOMPARE(radio.snapshot().peers.size(), 1);
|
|
radio.apply(1, "Renamed"); QVERIFY(advertised.isEmpty());
|
|
QCOMPARE(ble_backend_incoming(backend.owner, &endpoint), ble_link_id(0));
|
|
radio.apply(0, "Renamed"); QVERIFY(!radio.transport()); QCOMPARE(destructions, 1);
|
|
QVERIFY(radio.snapshot().peers.isEmpty()); QCOMPARE(radio.snapshot().state, BLE_CLOSED);
|
|
radio.apply(1, "Renamed"); QCOMPARE(creations, 2);
|
|
ble_backend_status(backend.owner, 0, "adapter is off");
|
|
QCOMPARE(radio.snapshot().reason, QString("adapter is off"));
|
|
radio.apply(0, "Renamed"); QCOMPARE(destructions, 2);
|
|
}
|
|
};
|
|
QTEST_GUILESS_MAIN(DesktopBleTest)
|
|
#include "test_desktop_ble.moc"
|