Repository navigation
Conversation
A collision now says where it landed. More than one destroyed symbol inside the eight-symbol header block, coded at CR 4/8, is a header the receiver could not read; anything else lost is a payload that failed its CRC. The firmware's chip is told the same through a new bridge kind, 0x0A, and raises HeaderErr, or RxDone beside CrcErr, as the part does. Waveform mode takes the answer from the demodulator. Before, a lost frame reached the firmware as nothing at all, so every error path in a radio driver went unexercised. A node that does not know the kind skips it, as it skips any kind, and behaves as it always has.
This was referenced Oct 16, 2026
Open
A native bridge built before kind 0x0A ends its connection on any kind it does not know, so sending it to today's published builds stopped those nodes and failed the run. A node now says it takes the kind with bit 0 of byte 47 of its radio stats record, which every engine reads on length; one that does not say so is sent nothing, as before. The Renode peripheral's handler is withdrawn until Renode can say so too.
…ng to a sized slice
…ilure 3 A frame swamped by interference the receiver could not capture over is told to the chip by when the interference arrived. Arriving while the preamble was still to be found, it left nothing to lock onto, which the part reports by raising nothing; the chip model takes back the HeaderValid it raised from the carrier's length and leaves PreambleDetected latched. Arriving later, it found a receiver that had locked, and is a header or CRC error as before. In waveform mode a frame with no preamble lock is the same third case. Sent only to a node whose radio stats record sets bit 1 of byte 47, because a chip older than virtual-sx1262 ABI 1.7 reads failure 3 as a CRC error.
This branch has not been deployed
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.
What
A frame a receiver locked onto and then lost now reaches that node's firmware as the SX1262 reports it, instead of not at all.
0x0A:[failure][frame...], numbered asvsx_deliver_frame_failednumbers it (1 CRC, 2 header). The chip raisesHeaderErralone, orRxDonebesideCrcErrwith the corrupt bytes in the buffer.HeaderValidit raised from the carrier's length and leavesPreambleDetectedlatched, as the part leaves it. Interference arriving after the lock is a header or CRC error, as above.0x0Awith bit 0 of byte 47 of its radio stats record, which every engine reads on length. A native bridge built before this ends its connection on any kind it does not know (default: goto done), so a node that does not say so is sent nothing. Failure 3 needs bit 1 as well (Receive only what the receiver was listening for meshcore-native#30), because a chip older than ABI 1.7 reads 3 as a CRC error.Why
Before this, every failure was withheld, so a radio driver's error paths never ran in the simulator. MeshCore's
CustomSX1262::isReceiving()treats anyHeaderErras "not receiving" and clearsHeaderValidwith it, even when a newer frame'sHeaderValidsits beside a stale error. That can make a node transmit over a frame it is in the middle of receiving, and it could not be tested here, because nothing ever raisedHeaderErr.Compatibility
Today's published native builds, Renode and QEMU boards never set the bit, so they are never sent
0x0Aand behave exactly as before. A native node built with MeshBench/meshcore-native#29 sets it. Renode and QEMU boards come later: they skip unknown kinds safely, but they cannot say they take this one until their stats records grow to byte 47.The first push of this PR sent the kind to every firmware node, and CI caught it: today's native bridge hung up on it and the experiment and fixture checks failed. That is what the capability bit fixes.
Who loses a frame is unchanged: only what the losing receiver's chip is told.
Still kinder than the part
Written up as
docs/shortcomings.md3.2b:HeaderErrarrives when the packet ends, not when its header does;HeaderValidis raised from the carrier's length, not from a decoded header, and is only taken back when the frame ends without a lock;On native builds with strict receive, the detection flags now stay set as the datasheet says. Emulated boards still clear them with the carrier.
Tests
TestACollisionOnTheHeaderIsAHeaderError: a collision across the header block is reported as a header error, and one after it as a CRC failure. Fails onmain.TestTheFirmwareIsToldWhereAFrameFailed: over a real bridge, the firmware is handed0x0Awith 2 for the header case and 1 for the payload case.TestAFailedFrameReachesOnlyANodeThatTakesIt: a node that has not set the bit is sent nothing; once it has, the wire format.TestANeverLockedFrameReachesOnlyAChipThatReadsIt: failure 3 is withheld from a node that sets only bit 0, and sent once it sets bit 1.TestAFrameSwampedBeforeLockIsOneTheChipNeverLockedOnto: a stronger interferer arriving during the preamble is failure 3; arriving after the header it is a CRC failure.go testfor the engine, firmware and layout packages,go vet,gofmt, the file-length check,golangci-lintv2.12.2 on the changed packages and the lint ratchet all pass.