Conversation
sendMspReply() kept the "header already sent" flag in a function local static that is cleared only after the last chunk of a reply. When a new request arrives while a reply is still being sent, handleMspFrame() discards that reply through initSharedMsp(), but the flag stayed set, so the first chunk of the next reply went out as a continuation frame: a status byte only, without the payload size and without the function byte. A consumer cannot tell which request such a reply belongs to and parses the payload at the wrong offset. Both transports reach this: the SmartPort handler feeds every incoming MSP payload to handleMspFrame() while a reply is pending, and the CRSF buffer loop processes several queued requests in a row. Move the flag to the module state and clear it in initSharedMsp(), so a reply that starts after a discarded one carries a full header again: status, size, function for MSPv1, status, flags, function, size for MSPv2, matching the request layout described by MSP_INDEX_*. Send a reply that exactly fills the last frame as the final chunk as well, instead of announcing a further chunk that then carried nothing but a continuation status byte. Fixes iNavFlight#10667
Raffi1202
marked this pull request as ready for review
September 11, 2026 15:40
Contributor
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
PR Summary by QodoRestart MSP telemetry reply framing after discarded replies
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can switch off images and animations for a plain-text comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
MSPv1 replies sent over CRSF telemetry arrive without the function byte: after the length byte the payload follows directly (#10667, captured on INAV 8.0.0). The receiving side cannot tell which request a reply belongs to and parses the payload at the wrong offset.
Cause
On maintenance-10.x the v1 reply header already contains the function byte (
src/main/telemetry/msp_shared.c:229), but the same symptom is still produced by stale reply state.headerSentis a function-local static insendMspReply()(msp_shared.c:209) and is cleared only after the last chunk (:261). When a new request arrives while a reply is still being sent,handleMspFrame()discards that reply throughinitSharedMsp()(:119-125,:66-77), which does not touchheaderSent. The first chunk of the next reply then takes the continuation branch (:237): status byte only, no size, no function byte. Both transports reach this: SmartPort passes every incoming MSP payload tohandleMspFrame()while a reply is pending (smartport.c:450), and CRSF drains several queued requests in one loop (crsf.c:128-136).Change
Moves the flag to file scope as
replyHeaderSentand clears it ininitSharedMsp(), so a reply that follows a discarded one starts with a full header again. Changes the chunk test atmsp_shared.c:244from>=to>, so a payload that exactly fills the frame is sent as the last chunk instead of being followed by a frame that holds only a continuation status byte.Test
Not run on hardware or SITL. Cause verified by reading
msp_shared.c:209-261,crsf.c:128-136andsmartport.c:450on maintenance-10.x;src/test/has no test that referencesmsp_shared.c.Flash / RAM
Not measured yet. The upstream firmware CI has not been released for this PR, so no size report exists.
Docs
No documentation change needed: nothing under docs/ describes the MSP-over-telemetry frame layout or chunking (checked docs/Telemetry.md, docs/Rx.md, docs/development/msp/).