Skip to content

Mark implicit ACK for MQTT as MQTT transport#8939

Merged
thebentern merged 5 commits into
meshtastic:developfrom
GUVWAF:MQTTack
Dec 12, 2025
Merged

Mark implicit ACK for MQTT as MQTT transport#8939
thebentern merged 5 commits into
meshtastic:developfrom
GUVWAF:MQTTack

Conversation

@GUVWAF

@GUVWAF GUVWAF commented Dec 11, 2025

Copy link
Copy Markdown
Member

To avoid it stopping retransmissions and hence not falling back to flooding from next-hop.

@GUVWAF GUVWAF requested a review from esev December 11, 2025 18:01
@GUVWAF GUVWAF added the bugfix Pull request that fixes bugs label Dec 11, 2025
@thebentern thebentern requested a review from Copilot December 11, 2025 18:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modifies the MQTT implicit ACK mechanism to mark ACK packets with the MQTT transport type, preventing premature termination of retransmissions and ensuring proper fallback to flooding from the next hop.

Key Changes:

  • Exposes allocAckNak method in RoutingModule for direct ACK packet manipulation
  • Updates MQTT.cpp to set transport_mechanism to MQTT for implicit ACKs
  • Removes trailing whitespace from two files

Reviewed changes

Copilot reviewed 3 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/mqtt/MQTT.cpp Modified to use allocAckNak directly and set transport_mechanism to TRANSPORT_MQTT for implicit ACKs
src/modules/RoutingModule.h Added public allocAckNak method declaration
src/modules/RoutingModule.cpp Implemented allocAckNak method that delegates to parent class
src/platform/nrf52/main-nrf52.cpp Removed trailing whitespace from comment
src/mesh/MeshModule.h Removed trailing whitespace from function declaration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@esev

esev commented Dec 12, 2025

Copy link
Copy Markdown
Contributor

MQTT might still be causing an ACK which stops the Lora retransmissions.

MQTT generates new packet id=3458476566 (0xce242a16) and it looks like that packet is responsible for the Received a ACK for 0x7eceb615, stopping retransmissions

2025-12-11 19:41:43.885	RadioIf [2016]: Corrected frequency offset: -848.624939
2025-12-11 19:41:43.887	RadioIf [2016]: Lora RX (id=0x4682ac32 fr=0xe21ce5e5 to=0xa2ebdbec, transport = 0, WantAck=1, HopLim=5 Ch=0x1f encrypted len=42 rxSNR=-9.25 rxRSSI=-103 hopStart=6)
2025-12-11 19:41:43.888	RadioIf [2016]: Packet RX: 160ms
2025-12-11 19:41:43.896	Router [2016]: Packet History - insert: Using new slot @uptime 2016.632s TRACE NEW
2025-12-11 19:41:43.897	Router [2016]: Use channel 0 (hash 0x1f)
2025-12-11 19:41:43.898	Router [2016]: Expand short PSK #1
2025-12-11 19:41:43.917	Router [2016]: Use AES128 key!
2025-12-11 19:41:43.917	Router [2016]: decoded message (id=0x4682ac32 fr=0xe21ce5e5 to=0xa2ebdbec, transport = 1, WantAck=1, HopLim=5 Ch=0x0 Portnum=70 WANTRESP rxtime=1765510903 rxSNR=-9.25 rxRSSI=-103 hopStart=6)
2025-12-11 19:41:43.918	Router [2016]: handleReceived(REMOTE) (id=0x4682ac32 fr=0xe21ce5e5 to=0xa2ebdbec, transport = 1, WantAck=1, HopLim=5 Ch=0x0 Portnum=70 WANTRESP rxtime=1765510903 rxSNR=-9.25 rxRSSI=-103 hopStart=6)
2025-12-11 19:41:43.919	Router [2016]: Module 'traceroute' wantsPacket=1
2025-12-11 19:41:43.919	Router [2016]: Received traceroute from=0xe21ce5e5, id=0x4682ac32, portnum=70, payloadlen=18
2025-12-11 19:41:43.919	Router [2016]: Route traced:#0120xe21ce5e5 --> 0x1c7a9d94 (-7.75dB) --> 0xa2ebdbec (-9.25dB)
2025-12-11 19:41:43.919	Router [2016]: Partially randomized packet id 2127476245
2025-12-11 19:41:43.920	Router [2016]: Asked module 'traceroute' to send a response
2025-12-11 19:41:43.920	Router [2016]: Module 'neighborinfo' wantsPacket=1
2025-12-11 19:41:43.920	Router [2016]: Received neighborinfo from=0xe21ce5e5, id=0x4682ac32, portnum=70, payloadlen=28
2025-12-11 19:41:43.920	Router [2016]: NeighborInfo: handleReceivedProtobuf
2025-12-11 19:41:43.921	Router [2016]: Module 'neighborinfo' considered
2025-12-11 19:41:43.921	Router [2016]: Module 'routing' wantsPacket=1
2025-12-11 19:41:43.921	Router [2016]: Received routing from=0xe21ce5e5, id=0x4682ac32, portnum=70, payloadlen=28
2025-12-11 19:41:43.924	Router [2016]: Routing sniffing (id=0x4682ac32 fr=0xe21ce5e5 to=0xa2ebdbec, transport = 1, WantAck=1, HopLim=5 Ch=0x0 Portnum=70 WANTRESP rxtime=1765510903 rxSNR=-9.25 rxRSSI=-103 hopStart=6)
2025-12-11 19:41:43.924	Router [2016]: Another module replied to this message, no need for 2nd ack
2025-12-11 19:41:43.924	Router [2016]: Delivering rx packet (id=0x4682ac32 fr=0xe21ce5e5 to=0xa2ebdbec, transport = 1, WantAck=1, HopLim=5 Ch=0x0 Portnum=70 WANTRESP rxtime=1765510903 rxSNR=-9.25 rxRSSI=-103 hopStart=6)
2025-12-11 19:41:43.924	Router [2016]: Update DB node 0xe21ce5e5, rx_time=1765510903
2025-12-11 19:41:43.925	Router [2016]: Sort took 1 milliseconds
2025-12-11 19:41:43.966	Router [2016]: Forwarding to phone (id=0x4682ac32 fr=0xe21ce5e5 to=0xa2ebdbec, transport = 1, WantAck=1, HopLim=5 Ch=0x0 Portnum=70 WANTRESP rxtime=1765510903 rxSNR=-9.25 rxRSSI=-103 hopStart=6)
2025-12-11 19:41:43.966	Router [2016]: ToPhone queue is full, drop packet
2025-12-11 19:41:43.966	Router [2016]: Module 'routing' considered
2025-12-11 19:41:43.966	Router [2016]: Send response (id=0x7eceb615 fr=0xa2ebdbec to=0xe21ce5e5, transport = 0, WantAck=1, HopLim=3 Ch=0x0 Portnum=70 requestId=4682ac32 rxtime=1765510903 priority=70)
2025-12-11 19:41:43.966	Router [2016]: Ignore update from self
2025-12-11 19:41:43.966	Router [2016]: localSend to channel 0
2025-12-11 19:41:43.966	Router [2016]: Setting next retransmission in 5532 msecs: 
2025-12-11 19:41:43.967	Router [2016]:  (id=0x7eceb615 fr=0xa2ebdbec to=0xe21ce5e5, transport = 0, WantAck=1, HopLim=3 Ch=0x0 Portnum=70 requestId=4682ac32 rxtime=1765510903 priority=70)
2025-12-11 19:41:43.967	Router [2016]: Packet History - insert: Using new slot @uptime 2016.673s TRACE NEW
2025-12-11 19:41:43.967	Router [2016]: Setting next hop for packet with dest e21ce5e5 to e5
2025-12-11 19:41:43.967	Router [2016]: Expand short PSK #1
2025-12-11 19:41:43.967	Router [2016]: Use AES128 key!
2025-12-11 19:41:43.967	Router [2016]: MQTT onSend - Publish 
2025-12-11 19:41:43.967	Router [2016]: encrypted message
2025-12-11 19:41:43.969	Router [2016]: MQTT Publish msh/station-g2/2/e/MediumFast/!a2ebdbec, 104 bytes
2025-12-11 19:41:43.969	Router [2016]: enqueue for send (id=0x7eceb615 fr=0xa2ebdbec to=0xe21ce5e5, transport = 0, WantAck=1, HopLim=3 Ch=0x1f encrypted len=55 rxtime=1765510903 hopStart=3 nextHop=0xe5 relay=0xec priority=70)
2025-12-11 19:41:43.970	Router [2016]: txGood=124,txRelay=112,rxGood=846,rxBad=263
2025-12-11 19:41:43.970	Router [2016]: tophone queue status queue is full, discard oldest
2025-12-11 19:41:43.970	Router [2016]: MQTT onSend - Publish 
2025-12-11 19:41:43.970	Router [2016]: encrypted message
2025-12-11 19:41:43.970	Router [2016]: MQTT Publish msh/station-g2/2/e/MediumFast/!a2ebdbec, 100 bytes
2025-12-11 19:41:43.980	RadioIf [2016]: Started Tx (id=0x7eceb615 fr=0xa2ebdbec to=0xe21ce5e5, transport = 0, WantAck=1, HopLim=3 Ch=0x1f encrypted len=55 rxtime=1765510903 hopStart=3 nextHop=0xe5 relay=0xec priority=70)
2025-12-11 19:41:43.980	RadioIf [2016]: 0 packets remain in the TX queue
2025-12-11 19:41:43.981	mqtt [2016]: Partially randomized packet id 3458476566
2025-12-11 19:41:43.987	mqtt [2016]: Enqueued local (id=0xce242a16 fr=0xa2ebdbec to=0xa2ebdbec, transport = 5, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 requestId=7eceb615 rxtime=1765510903 priority=120)
2025-12-11 19:41:43.987	Router [2016]: Rx someone rebroadcasting for us (id=0xce242a16 fr=0xa2ebdbec to=0xa2ebdbec, transport = 5, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 requestId=7eceb615 rxtime=1765510903 priority=120)
2025-12-11 19:41:43.987	Router [2016]: Didn't find pending packet
2025-12-11 19:41:43.988	Router [2016]: Packet History - insert: Using new slot @uptime 2016.725s TRACE NEW
2025-12-11 19:41:43.990	Router [2016]: handleReceived(REMOTE) (id=0xce242a16 fr=0xa2ebdbec to=0xa2ebdbec, transport = 5, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 requestId=7eceb615 rxtime=1765510903 priority=120)
2025-12-11 19:41:43.991	Router [2016]: Module 'neighborinfo' wantsPacket=1
2025-12-11 19:41:43.993	Router [2016]: Received neighborinfo from=0xa2ebdbec, id=0xce242a16, portnum=5, payloadlen=2
2025-12-11 19:41:43.996	Router [2016]: NeighborInfo: handleReceivedProtobuf
2025-12-11 19:41:43.996	Router [2016]: Module 'neighborinfo' considered
2025-12-11 19:41:43.997	Router [2016]: Module 'routing' wantsPacket=1
2025-12-11 19:41:43.998	Router [2016]: Received routing from=0xa2ebdbec, id=0xce242a16, portnum=5, payloadlen=2
2025-12-11 19:41:44.000	Router [2016]: Routing sniffing (id=0xce242a16 fr=0xa2ebdbec to=0xa2ebdbec, transport = 5, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 requestId=7eceb615 rxtime=1765510903 priority=120)
2025-12-11 19:41:44.003	Router [2016]: Received a ACK for 0x7eceb615, stopping retransmissions
2025-12-11 19:41:44.003	Router [2016]: Delivering rx packet (id=0xce242a16 fr=0xa2ebdbec to=0xa2ebdbec, transport = 5, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 requestId=7eceb615 rxtime=1765510903 priority=120)
2025-12-11 19:41:44.004	Router [2016]: Ignore update from self
2025-12-11 19:41:44.021	Router [2016]: Forwarding to phone (id=0xce242a16 fr=0xa2ebdbec to=0xa2ebdbec, transport = 5, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 requestId=7eceb615 rxtime=1765510903 priority=120)
2025-12-11 19:41:44.021	Router [2016]: ToPhone queue is full, drop packet
2025-12-11 19:41:44.021	Router [2016]: Module 'routing' considered
2025-12-11 19:41:44.021	mqtt [2016]: Ignore downlink message we originally sent
2025-12-11 19:41:44.169	RadioIf [2016]: Packet TX: 190ms
2025-12-11 19:41:44.170	RadioIf [2016]: Completed sending (id=0x7eceb615 fr=0xa2ebdbec to=0xe21ce5e5, transport = 0, WantAck=1, HopLim=3 Ch=0x1f encrypted len=55 rxtime=1765510903 hopStart=3 nextHop=0xe5 relay=0xec priority=70)

@GUVWAF

GUVWAF commented Dec 12, 2025

Copy link
Copy Markdown
Member Author

Ah, I see, indeed in the ReliableRouter we also check for real ACKs to stop retransmissions.
I would need to think about whether we should check for && !isFromUs() here:

if (isToUs(p)) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability)

@GUVWAF

GUVWAF commented Dec 12, 2025

Copy link
Copy Markdown
Member Author

This should be fixed now in the latest commit.

@thebentern thebentern merged commit 68250dc into meshtastic:develop Dec 12, 2025
76 of 78 checks passed
thebentern added a commit that referenced this pull request Dec 12, 2025
* Mark implicit ACK for MQTT as MQTT transport

* TRUNK

* Fix build

* Make sure implicit ACKs from MQTT do not stop retransmissions in ReliableRouter

---------

Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
@thebentern

Copy link
Copy Markdown
Contributor

@GUVWAF the test test_receiveAcksOwnSentMessages is failing now, which makes sense. I would think this is a test which simply needs to be removed since it asserts behavior we don't expect anymore?

@GUVWAF

GUVWAF commented Dec 12, 2025

Copy link
Copy Markdown
Member Author

@thebentern Ah, I think it should still work because the ACK is still generated, only the retransmissions are not stopped. But I think it's because the test expects it to be sent with sendAckNak(), which I circumvented and manually called allocAckNak() such that the transport mechanism can be set afterwards:

ackNacks_.emplace_back(err, to, idFrom, chIndex, hopLimit);

scobert969 pushed a commit to zeropt/meshtastic-firmware that referenced this pull request Dec 22, 2025
* Mark implicit ACK for MQTT as MQTT transport

* TRUNK

* Fix build

* Make sure implicit ACKs from MQTT do not stop retransmissions in ReliableRouter

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
jeek pushed a commit to jeek/Meshtastic-Exploiteers-Hacker-Pager that referenced this pull request Jun 30, 2026
* Mark implicit ACK for MQTT as MQTT transport

* TRUNK

* Fix build

* Make sure implicit ACKs from MQTT do not stop retransmissions in ReliableRouter

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
jeek pushed a commit to jeek/Meshtastic-Exploiteers-Hacker-Pager that referenced this pull request Jun 30, 2026
…astic#8947)

* Mark implicit ACK for MQTT as MQTT transport

* TRUNK

* Fix build

* Make sure implicit ACKs from MQTT do not stop retransmissions in ReliableRouter

---------

Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants