Files
MeshCore/test/fixtures/morse_reply_loop.cpp
mikecarper 0be4c7488c Add bounded Morse receive and negotiated RS232 autosleep
Add native narrow-band CW capture, ACK-first remote sessions, retained LoRa-readable pages, checked restoration and transport-safe progress. Add stock-compatible negotiated heartbeat/autosleep and recovery. Include host regressions and identity-bound HIL runners; keep unverified faster tuning HIL-only and document outstanding hardware validation.
2026-10-13 01:24:39 -07:00

61 lines
2.4 KiB
C++

#include <helpers/MorseLoopPolicy.h>
static uint32_t now_ms = 100;
uint32_t millis() { return now_ms; }
#define PUB_KEY_SIZE 32
struct ClientInfo {
struct { uint8_t pub_key[32] = {}; } id;
bool admin = true;
bool isAdmin() const { return admin; }
};
struct ACL {
std::vector<ClientInfo> clients;
size_t requested_key_size = 0;
const ClientInfo* getClient(const uint8_t* key, size_t size) {
requested_key_size = size;
assert(size == 32);
for (const auto& client : clients) if (!memcmp(client.id.pub_key, key, size)) return &client;
return nullptr;
}
};
struct Callbacks { TestRadio* radio; mesh::Radio* getProfileRadio() { return radio; } };
struct CommonCLI {
mesh::MorseReplyHandoff _morse_reply;
ACL* _acl;
Callbacks* _callbacks;
struct Profiles { unsigned loops = 0; void loop() { ++loops; } } _radio_profiles;
unsigned management_loops = 0;
CommonCLI(ACL& acl, Callbacks& callbacks) : _acl(&acl), _callbacks(&callbacks) {}
void loopManagement() { ++management_loops; }
void loop();
};
@LOOP@
int main() {
const uint8_t key[32] = {1, 2, 3, 4};
for (int scenario = 0; scenario < 5; ++scenario) {
TestRadio radio; radio.rx_supported = true;
ACL acl; ClientInfo actor; memcpy(actor.id.pub_key, key, 32); acl.clients.push_back(actor);
Callbacks callbacks{&radio}; CommonCLI cli(acl, callbacks);
int packet;
cli._morse_reply.beginCommand(key);
assert(cli._morse_reply.stage(902100, 25, 60000, now_ms));
cli._morse_reply.endCommand(); cli._morse_reply.prepareReply(&packet);
cli._morse_reply.armReply(&packet, true);
cli.loop(); assert(radio.rx_starts == 0); // shared loop must still wait for PHY completion
cli._morse_reply.complete(&packet);
if (scenario == 0) acl.clients[0].admin = false;
if (scenario == 1) { acl.clients[0].id.pub_key[31] = 1; } // reused slot, same short key
if (scenario == 2) {
acl.clients[0].id.pub_key[31] = 1; acl.clients.push_back(actor); // original full identity moved
}
if (scenario == 3) mesh::usable = false;
if (scenario == 4) mesh::current.frequency_khz = 902101;
cli.loop();
const bool allowed = scenario == 2;
assert(radio.rx_starts == unsigned(allowed) && !cli._morse_reply.pending());
assert(acl.requested_key_size == 32 && cli._radio_profiles.loops == unsigned(allowed ? 1 : 2));
assert(cli.management_loops == unsigned(allowed ? 1 : 2));
mesh::usable = true; mesh::current = mesh::MorseSettings();
}
}