Skip to content

Fix SX126x daemon abort when Tx power exceeds chip limit#10711

Open
lizthegrey wants to merge 3 commits into
meshtastic:developfrom
lizthegrey:fix/sx126x-reconfigure-power-assert
Open

Fix SX126x daemon abort when Tx power exceeds chip limit#10711
lizthegrey wants to merge 3 commits into
meshtastic:developfrom
lizthegrey:fix/sx126x-reconfigure-power-assert

Conversation

@lizthegrey

Copy link
Copy Markdown

What

SX126xInterface::reconfigure() aborted via assert(err == RADIOLIB_ERR_NONE) when setOutputPower() failed. power here is derived from operator-settable config (tx_power, SX126X_MAX_POWER); a value above the SX126x RadioLib limit (+22 dBm) returns RADIOLIB_ERR_INVALID_OUTPUT_POWER and aborts the daemon.

Because MeshService::reloadConfig() reconfigures the radio before saveToDisk(), the abort happens before the new config is persisted: the offending setting silently reverts and meshtasticd crash-loops with no surfaced error.

This replaces the assert with RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING) + continue — matching the setFrequency() handling 8 lines above in the same function. A bad/typo'd power value now surfaces a critical error instead of taking down the node.

fixes #10710

Testing

  • Root-caused and reproduced on hardware: meshtoad USB SX1262 stick running meshtasticd 2.7.24 on aarch64 Linux. With SX126X_MAX_POWER: 24, any runtime config change reproduced the setOutputPower err=-13 → assert abort and silent config revert; setting Tx power ≤ 22 avoided it.
  • Compiles and links clean against develop (HEAD bbcc35e): a full pio run -e native (portduino) build succeeds and produces a working meshtasticd aarch64 ELF.
  • Runtime exercise of the fixed path on hardware was not performed, to avoid commandeering the live node's radio from the running service. The change is a minimal graceful-degradation mirroring the adjacent setFrequency() handling; community verification on the attestation devices is welcome.

Notes

Only reconfigure() is affected; init() already tolerates a begin() power failure without asserting. Optionally SX126X_MAX_POWER could additionally be clamped to the chip's RadioLib maximum so the radio keeps transmitting at the legal max after a too-high setting — happy to add if preferred.

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • Bug root-caused and reproduced on hardware (meshtoad USB SX1262 / meshtasticd 2.7.24); fix compiles and links clean against develop via the native/portduino build. Runtime verification of the fixed path on-device not performed (to avoid disrupting the live node); fix mirrors the adjacent setFrequency() graceful path. Community verification welcome.

reconfigure() asserted on setOutputPower() failure. `power` is derived from
operator-settable config (tx_power, SX126X_MAX_POWER); a value above the SX126x
RadioLib limit (+22 dBm) returns RADIOLIB_ERR_INVALID_OUTPUT_POWER. The assert
aborts meshtasticd mid-reconfigure -- before reloadConfig() persists the change --
so the offending config silently reverts and the daemon crash-loops. Record a
critical error and continue instead, matching the adjacent setFrequency() handling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Jun 13, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions github-actions Bot added the bugfix Pull request that fixes bugs label Jun 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@lizthegrey, Welcome to Meshtastic!

Thanks for opening your first pull request. We really appreciate it.

We discuss work as a team in discord, please join us in the #firmware channel.
There's a big backlog of patches at the moment. If you have time,
please help us with some code review and testing of other PRs!

Welcome to the team 😄

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

Note

Copilot was unable to run its full agentic suite in this review.

Prevents meshtasticd from aborting when radio reconfiguration attempts to set an invalid SX126x TX power, instead surfacing a critical error and continuing to apply the rest of the config.

Changes:

  • Replace assert(err == RADIOLIB_ERR_NONE) after setOutputPower() with error logging + RECORD_CRITICALERROR(...).
  • Add explanatory comment describing why aborting here is harmful during reloadConfig().

Comment thread src/mesh/SX126xInterface.cpp Outdated
Comment thread src/mesh/SX126xInterface.cpp Outdated
Comment on lines +254 to +262
if (err != RADIOLIB_ERR_NONE) {
// Do not abort here: `power` is derived from operator-settable config (tx_power and
// SX126X_MAX_POWER). A value above the chip's RadioLib limit (+22 dBm for SX126x) returns
// RADIOLIB_ERR_INVALID_OUTPUT_POWER. asserting would abort the daemon mid-reconfigure, before
// reloadConfig() persists the new config, so the offending setting silently reverts and the
// daemon crash-loops. Record the error and continue, matching the setFrequency() handling above.
LOG_ERROR("SX126X setOutputPower %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Right — continuing leaves the radio at its previously applied power while config records the new value. I took the explicit-logging option ("keeping previous Tx power") rather than a clamp-to-max fallback here, because a correct clamp needs the per-chip maximum (the same SX1261-vs-SX1262 distinction noted above) and RadioLib does not expose it cleanly at this call site. I think the cleaner root-cause fix is to validate/clamp SX126X_MAX_POWER (and tx_power) against the chip limit at config-load time so an out-of-range value never reaches reconfigure() — happy to do that as a follow-up, or to add the clamp here if maintainers prefer. (6987025)

lizthegrey and others added 2 commits June 13, 2026 21:44
- Comment no longer states a universal "+22 dBm for SX126x"; notes the
  limit is the driver's max (e.g. +22 on SX1262/SX1268, lower on SX1261).
- Log the rejected `power` value and that the previous Tx power is retained,
  so the invalid setting and the resulting config/radio drift are visible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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 first-contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: meshtasticd aborts (assert in SX126xInterface::reconfigure) when Tx power exceeds the SX126x +22 dBm limit; config change silently reverts

3 participants