Wait for the radio from the repeater's own loop
This commit is contained in:
1 parent
435c740e5a
commit
c313658b88
3 files changed
+21
-8
No files matched your search
@@ -13393,7 +13393,7 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char *
|
||||
|
||||
void MyMesh::loop() {
|
||||
#if MESH_ENABLE_DIRECT_OTA_ADMIN
|
||||
direct_ota_admin.service(*this, millis());
|
||||
direct_ota_admin.service(*this, millis(), !hasPendingRadioWork());
|
||||
#endif
|
||||
#if defined(WITH_WEBCONFIG) || defined(ETHERNET_ENABLED)
|
||||
_local_cli_output.service();
|
||||
|
||||
@@ -146,14 +146,15 @@ public:
|
||||
if (phase_ != Idle) finish("admin session expired", true);
|
||||
}
|
||||
}
|
||||
void service(Mesh& mesh, uint32_t now) {
|
||||
void service(Mesh& mesh, uint32_t now, bool radio_idle) {
|
||||
tick(now);
|
||||
if (phase_ == Proof && expired(now, proof_retry_at_) && proof_attempts_ < 3) {
|
||||
if (!queueReturnPath(mesh)) { clearSession(); finish("login return path queue failed", true); }
|
||||
return; // radio_idle was sampled before this new PATH was queued
|
||||
}
|
||||
// PATH has lower queue priority than CLI. Wait until its transmission and
|
||||
// retries finish before admitting the proof, rather than relying on delay.
|
||||
if (phase_ == ReturnPath && !mesh.hasPendingRadioWork()) {
|
||||
if (phase_ == ReturnPath && radio_idle) {
|
||||
phase_ = Proof;
|
||||
if (!queueCommand(mesh, "get public.key", now)) { clearSession(); finish("login proof queue failed", true); }
|
||||
else proof_retry_at_ = now + 8000;
|
||||
|
||||
@@ -80,6 +80,7 @@ struct Mesh {
|
||||
Packet* createPathReturn(const uint8_t*,const uint8_t*,const uint8_t*,uint8_t,uint8_t,const uint8_t*,size_t);
|
||||
Packet* createPathReturn(const Identity& dest,const uint8_t* secret,const uint8_t* path,uint8_t length,uint8_t type,const uint8_t* extra,size_t size){uint8_t hash[1];dest.copyHashTo(hash);return createPathReturn(hash,secret,path,length,type,extra,size);}
|
||||
bool sendDirect(Packet* p,const uint8_t* path,uint8_t length){assert(p&&path==nullptr&&length==0&&p->tx_radio==RADIO_TX_PRIMARY);if(type==PAYLOAD_TYPE_PATH)sent.assign(p->payload,p->payload+p->payload_len);pending=send_ok;return send_ok;}
|
||||
protected:
|
||||
bool hasPendingRadioWork()const{return pending;}
|
||||
};
|
||||
@PATH_BUILDER@
|
||||
@@ -92,6 +93,7 @@ using Client=mesh::DirectOtaAdminClient;
|
||||
static uint32_t millis(){return 100;}
|
||||
struct UsbRole:mesh::Mesh {
|
||||
Client direct_ota_admin;
|
||||
void loop(){ @SERVICE_CALL@ }
|
||||
void dispatch(uint32_t sender_timestamp,void* sender,char* command,char* reply,bool usb_origin){
|
||||
@USB_GATE@
|
||||
strcpy(reply,"not a peer command");
|
||||
@@ -153,8 +155,8 @@ static void authenticate(Client& c,mesh::Mesh& radio,uint32_t now=100){
|
||||
// by authenticated ciphertext containing empty return path + dummy payload.
|
||||
assert(radio.sent.size()==10&&radio.sent[0]==0x11&&radio.sent[1]==0x55);
|
||||
assert(radio.sent[2]==0xCA&&radio.sent[3]==0xFE&&radio.sent[4]==0&&radio.sent[5]==0xFF);
|
||||
c.service(radio,now+3);assert(radio.type==PAYLOAD_TYPE_PATH); // do not overtake the PATH
|
||||
radio.pending=false;c.service(radio,now+4);
|
||||
c.service(radio,now+3,!radio.pending);assert(radio.type==PAYLOAD_TYPE_PATH); // do not overtake the PATH
|
||||
radio.pending=false;c.service(radio,now+4,!radio.pending);
|
||||
assert(radio.type==PAYLOAD_TYPE_TXT_MSG&&radio.sent[4]==12);
|
||||
std::string proof(radio.sent.begin()+5,radio.sent.begin()+8);
|
||||
assert(std::string(radio.sent.begin()+8,radio.sent.end())=="get public.key");
|
||||
@@ -247,10 +249,17 @@ int main(){
|
||||
Client retries;discover(retries,radio,10);command(retries,radio,"ota.peer login "+key+" password",6011);
|
||||
mesh::Packet direct;uint8_t accepted_login[13]{};uint32_t stamp=60000;memcpy(accepted_login,&stamp,4);accepted_login[7]=3;
|
||||
retries.onData(radio,&direct,PAYLOAD_TYPE_RESPONSE,accepted_login,sizeof(accepted_login),6012);
|
||||
radio.pending=false;retries.service(radio,6013);assert(radio.type==PAYLOAD_TYPE_TXT_MSG);
|
||||
for(uint32_t now:{14013U,22014U}){retries.service(radio,now);assert(radio.type==PAYLOAD_TYPE_PATH);radio.pending=false;retries.service(radio,now+1);}
|
||||
const int attempts=radio.calls;retries.service(radio,30015);assert(radio.calls==attempts);
|
||||
radio.pending=false;retries.service(radio,6013,!radio.pending);assert(radio.type==PAYLOAD_TYPE_TXT_MSG);
|
||||
for(uint32_t now:{14013U,22014U}){radio.pending=false;retries.service(radio,now,!radio.pending);assert(radio.type==PAYLOAD_TYPE_PATH);radio.pending=false;retries.service(radio,now+1,!radio.pending);}
|
||||
const int attempts=radio.calls;retries.service(radio,30015,!radio.pending);assert(radio.calls==attempts);
|
||||
retries.tick(36011);assert(!retries.hasSession());
|
||||
// Execute the production MyMesh loop call with Dispatcher-like protection.
|
||||
// Only the derived mesh may inspect its protected radio-work state.
|
||||
UsbRole integration;discover(integration.direct_ota_admin,integration,10);
|
||||
command(integration.direct_ota_admin,integration,"ota.peer login "+key+" password",6011);
|
||||
integration.direct_ota_admin.onData(integration,&direct,PAYLOAD_TYPE_RESPONSE,accepted_login,sizeof(accepted_login),6012);
|
||||
integration.loop();assert(integration.type==PAYLOAD_TYPE_PATH);
|
||||
integration.pending=false;integration.loop();assert(integration.type==PAYLOAD_TYPE_TXT_MSG);
|
||||
}
|
||||
'''
|
||||
|
||||
@@ -266,6 +275,9 @@ class DirectOtaAdminClientTest(unittest.TestCase):
|
||||
end += 1
|
||||
code = HARNESS.replace('@ECHO_LOOP@',source[start:end])
|
||||
mesh_source = (ROOT/'examples/simple_repeater/MyMesh.cpp').read_text()
|
||||
start = mesh_source.index('direct_ota_admin.service(')
|
||||
end = mesh_source.index(';',start)+1
|
||||
code = code.replace('@SERVICE_CALL@', mesh_source[start:end])
|
||||
start = mesh_source.index('if (mesh::DirectOtaAdminClient::isCommand(command))')
|
||||
opening = mesh_source.index('{',start)
|
||||
end,depth=opening+1,1
|
||||
|
||||
Reference in new issue
Block a user