Files
MeshCore/test/fixtures/morse_reply_companion.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.8 KiB
C++

namespace mesh { struct Packet { bool radio_reply=false; }; }
struct ContactInfo {
struct { uint8_t pub_key[32]={}; } id;
bool allowed=true;
bool isRemoteCLIAllowed() const { return allowed; }
};
static uint32_t millis() { return 100; }
#define PUB_KEY_SIZE 32
#define TXT_TYPE_CLI_COMMAND 1
struct MyMesh {
mesh::MorseReplyHandoff _morse_reply;
bool _morse_reply_admission=false;
TestRadio radio;
unsigned active=0, forwarded=0;
uint32_t handled_timestamp=0;
MyMesh() { radio.rx_supported=true; }
void markConnectionActive(const ContactInfo&) { ++active; }
void queueMessage(const ContactInfo&,uint8_t,mesh::Packet*,uint32_t,const void*,size_t,const char*) { ++forwarded; }
bool handleCommand(const char* text,uint32_t timestamp,char* reply) {
handled_timestamp=timestamp;
return mesh::handleMorseReplyCommand(_morse_reply,&radio,text,reply,160,millis())
|| mesh::handleMorseCommand(&radio,text,reply,160);
}
void onCLICommandRecv(const ContactInfo&,mesh::Packet*,uint32_t,const char*,char*);
void onCLIReplyPrepared(const ContactInfo&,mesh::Packet*);
void onCLIReplyQueued(const ContactInfo&,mesh::Packet*,bool);
};
@METHODS@
int main() {
ContactInfo actor, other; actor.id.pub_key[0]=1; other.id.pub_key[0]=2;
mesh::Packet reply_packet, copy;
char reply[160]={};
for (unsigned failure=0; failure<3; ++failure) {
MyMesh node;
node.onCLICommandRecv(actor,nullptr,0,"morse listen 1",reply);
assert(node.handled_timestamp==1 && node._morse_reply_admission && node._morse_reply.pending());
assert(node.active==1 && !node.radio.rx_starts);
node.onCLIReplyPrepared(other,&reply_packet);
assert(!node._morse_reply.ownsReply(&reply_packet));
if (failure==0) {
node.onCLIReplyPrepared(actor,&reply_packet);
assert(reply_packet.radio_reply && node._morse_reply.ownsReply(&reply_packet));
node._morse_reply.copy(&reply_packet,&copy);
node.onCLIReplyQueued(actor,&reply_packet,true);
assert(!node._morse_reply_admission);
node._morse_reply.complete(&reply_packet);
assert(!node._morse_reply.service(&node.radio,100,true,true,902100,25));
node._morse_reply.complete(&copy);
assert(node._morse_reply.service(&node.radio,100,true,true,902100,25));
assert(node.radio.rx_starts==1 && node.radio.rx_duration==60000);
} else {
node.onCLIReplyPrepared(actor,failure==1 ? nullptr : &reply_packet);
node.onCLIReplyQueued(actor,failure==1 ? nullptr : &reply_packet,false);
assert(!node._morse_reply_admission && !node._morse_reply.pending() && !node.radio.rx_starts);
}
}
MyMesh denied; actor.allowed=false;
denied.onCLICommandRecv(actor,nullptr,0,"morse listen 1",reply);
assert(denied.forwarded==1 && !denied.handled_timestamp && !denied._morse_reply.pending());
}