Skip to content

Add error-aware SX126x receive hook#2131

Open
robekl wants to merge 1 commit intomeshcore-dev:devfrom
robekl:fix/sx126x-hook-error-aware-receive
Open

Add error-aware SX126x receive hook#2131
robekl wants to merge 1 commit intomeshcore-dev:devfrom
robekl:fix/sx126x-hook-error-aware-receive

Conversation

@robekl
Copy link
Contributor

@robekl robekl commented Mar 23, 2026

Summary

This change makes MeshCore's SX126x-family receive path error-aware at the wrapper boundary instead of relying exclusively on RadioLib's high-level packet-length helper.

For SX1262, SX1268, LLCC68, and STM32WLx integrations, MeshCore now reads receive metadata through a dedicated low-level hook path that can propagate failures from GET_RX_BUFFER_STATUS and the subsequent buffer read. The common wrapper logic treats those failures as receive errors instead of collapsing them into a benign-looking empty packet.

The result is that SX126x-family boards no longer silently treat metadata-read failures as "no packet" when a receive interrupt has already fired.

Problem Addressed

MeshCore's generic RadioLibWrapper::recvRaw() used getPacketLength() before calling readData(). On SX126x-family radios, that path depended on RadioLib behavior that can fail open when receive metadata cannot be read successfully.

In practice, that means a real metadata-read failure can be misinterpreted as a valid zero-length outcome, which causes MeshCore to drop the receive event without incrementing receive-error stats and without surfacing that the radio operation failed.

This change closes that gap for the SX126x-family radios MeshCore actively uses.

Approach

The implementation adds a wrapper hook for metadata-aware raw reads and uses it only where MeshCore has the radio-specific knowledge needed to do better than the generic PhysicalLayer API:

  • the common wrapper gains a default hook that preserves existing generic behavior
  • SX126x-family wrappers override that hook
  • SX126x-family custom radio classes provide a low-level tryReadData(...) path that:
    • checks the stream state first
    • preserves RadioLib timeout and CRC behavior
    • reads RX buffer status directly
    • preserves implicit-header cached-length semantics
    • propagates metadata-read and buffer-read failures

The shared SX126x receive logic is centralized in one helper so the four supported SX126x-family classes do not diverge.

Why This Tradeoff Is Good

This is a deliberate middle path between two broader alternatives:

  1. A RadioLib-level refactor to introduce new public error-aware receive metadata APIs.
  2. A larger MeshCore-side rewrite that bypasses more of RadioLib's higher-level receive behavior for every radio family.

Those alternatives are reasonable long-term directions, but they are larger in scope and carry more compatibility and maintenance risk.

This change is a good tradeoff because it:

  • fixes the specific live issue on MeshCore's active SX126x-family receive path
  • keeps the change local to MeshCore's existing radio integration layer
  • avoids broad API churn in RadioLib or MeshCore's generic radio abstraction
  • preserves current behavior for non-SX126x radios
  • creates a reusable hook boundary for future radio-family-specific receive fixes

Broader RadioLib Error-Model Context

The larger problem behind this bug is that some RadioLib convenience APIs return only values, not values plus status. Once a helper such as getPacketLength() collapses an SPI or command failure into an ordinary-looking value, MeshCore no longer has enough information at the wrapper layer to tell the difference between:

  • a legitimate radio state
  • a transport or metadata-read failure that happened underneath it

That limitation is not uniform across all radios. In some places RadioLib still exposes lower-level operations with a real error channel, and in others the higher-level helper has already erased it. That is why a full library-wide fix would likely require a broader RadioLib API refactor rather than just more MeshCore wrapper code.

This PR does not claim to solve that general problem. It addresses one concrete case where MeshCore can recover correctness locally: the SX126x-family receive path still gives MeshCore enough low-level access to read buffer metadata directly and preserve the failure signal. That makes this a bounded fix with clear value, while leaving room for a larger RadioLib-side cleanup later if the project wants a consistent error-aware model across all radio families.

Validation

  • focused host-side wrapper test for hook behavior and receive-error accounting
  • Heltec_v3_repeater build
  • wio-e5_repeater build

Notes

This PR intentionally does not try to solve the broader RadioLib error-model problem across every radio family. It addresses the concrete SX126x-family receive-metadata failure mode in MeshCore with a bounded change that is easy to review and reason about.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant