fix(CannedMessage): keep listening after a relay ACK - #11479
Conversation
The routing handler is guarded by waitingForAck, and the relay-ACK branch clears it. So the first node that forwards our DM ends our interest in the exchange: the destination's own ACK arrives later, fails the guard at the top of the function, and is dropped. The message shows RELAYED permanently even though it was delivered, and this->ack, this->incoming and the stored AckStatus all stay at the relay result. Leave waitingForAck set on a relay ACK. A relay ACK says someone forwarded the packet, not that the recipient has it, so it is not a terminal state and there is no reason to stop watching. The state still always resolves. Either the destination ACKs, which the isFromDest branch takes and which clears the flag, or our own router runs out of retries and NAKs MAX_RETRANSMIT, which lands in the explicit-failure branch and clears it there. A later duplicate relay ACK can only rewrite RELAYED with RELAYED, and nothing can downgrade an ACKED row, because the destination ACK clears the flag and the guard then rejects everything that follows. waitingForAck has no other consumers: it is set when sending and read by wantPacket() to decide whether ROUTING_APP packets are interesting. Holding it longer only means we keep listening.
⚡ Try this PR in the Web FlasherNote Building this pull request… the flash button, badges and supported-board |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
b52e4c4 to
81c8fe6
Compare
CannedMessageModule::handleReceived()is guarded bywaitingForAck, and the relay-ACK branchclears it. So the first node that forwards our DM ends our interest in the exchange. The
destination's own ACK arrives later, fails the guard at the top of the function, and is dropped.
The message shows RELAYED permanently even though it was delivered, and
this->ack,this->incomingand the storedAckStatusall stay at the relay result.The fix leaves
waitingForAckset on a relay ACK. A relay ACK says someone forwarded the packet, notthat the recipient has it, so it is not a terminal state and there is no reason to stop watching.
The state still always resolves, which is what makes this safe rather than a hang. Either the
destination ACKs, which the
isFromDestbranch takes and which clears the flag, or our own routerruns out of retries and NAKs
MAX_RETRANSMIT, which lands in the explicit-failure branch and clearsit there.
Nothing can be downgraded. A duplicate relay ACK can only rewrite RELAYED with RELAYED, and once the
destination ACK has set ACKED the flag is clear and the guard rejects everything after it.
waitingForAckhas no other consumers: it is set when sending, and read bywantPacket()to decidewhether ROUTING_APP packets are interesting. Holding it longer only means we keep listening.
Overlap with #10921
That PR restructures this area and partially addresses the symptom: its RoutingModule hook is not
gated on
waitingForAckand matches by packetId, so the stored row does upgrade RELAYED to ACKED.This patch is written against current develop, where that has not landed.
If #10921 goes in first, this needs rewriting against its
ackStatusForRoutingResult/updateAckStatusFromRoutingmechanism rather than thegetMessages().back()block. The banner state(
this->ack,this->incoming) would still need the change here, since that hook does not touch it.Worth checking there too:
updateAckStatusFromRoutinghas no monotonicity guard, so a late orduplicate relay ACK could downgrade an ACKED row. The approach in this PR avoids that by keeping the
guard as the thing that decides when the exchange is over.
Testing: builds clean on
heltec-v4andseeed-xiao-s3. Full native suite matches a same-commitbaseline at 887 cases, 3 failed, 875 succeeded. The three are
test_fscommon_getfiles,test_lsm_standaloneandtest_gps_update_scheduling, all of which fail on clean develop too. Notethose three are unstable run to run: the same commit produced 888/6 and then 887/3 on consecutive
runs here, with
test_fscommon_getfilesfailing on leftover filesystem state, so compare against asame-commit run rather than a remembered number.
Not validated on hardware. Reproducing it needs a third node to relay, and my bench is two co-located
nodes that hear each other directly, so no relay ACK is ever generated.
🤖 Generated with Claude Code
🤝 Attestations