Skip to content

Dispatcher: skip the periodic AGC reset while packets are being received - #3752

Open
AlexandrTyshchenko wants to merge 63 commits into
meshcore-dev:mainfrom
AlexandrTyshchenko:feature/agc-reset-when-idle
Open

AlexandrTyshchenko wants to merge 63 commits into
meshcore-dev:mainfrom
AlexandrTyshchenko:feature/agc-reset-when-idle

Conversation

@AlexandrTyshchenko

Copy link
Copy Markdown

Problem

With agc.reset.interval > 0, Dispatcher::loop() calls resetAGC() on a fixed timer
(restarted only after a TX). Each reset puts the radio into warm sleep, recalibrates and
re-arms RX, so the node is deaf for that time. On a busy channel this costs packets every
interval, although the gain cannot be stuck: packets are still being decoded.

Change

When the AGC timer fires:

  • skip the reset if a valid packet was received within the last reset interval
    (the gain is fine), or if a packet is queued for transmit;
  • reset anyway at least once per AGC_FORCED_RESET_MILLIS (default 24 h, overridable
    build flag), and on the first tick after boot;
  • otherwise reset as before.

"Valid packet" means one that passed tryParsePacket() (set right after logRx()), so
corrupt/garbage receptions don't count as hearing.

This is the same logic Meshtastic uses on develop
(RadioLibInterface::periodicRadioMaintenance(): check every 60 s, reset only if nothing
was decoded for AGC_IDLE_RESET_MS = 60 s, forced every AGC_FORCED_RESET_MS = 24 h,
never with TX queued). Here the idle window is the configured agc.reset.interval itself.

Nodes with agc.reset.interval 0 (the default) are not affected. MESH_DEBUG builds log
each decision (AGC reset / AGC reset skipped, last rx N ms ago / ... tx queued).

Testing

ProMicro nRF52840 + E22-400M22S (SX1268), repeater, MESH_DEBUG, agc.reset.interval 8:

  • quiet channel: reset every 8 s;
  • adverts received at t and t+6 s: the next two resets skipped
    (last rx 923 ms ago, last rx 1673 ms ago);
  • after 8 s with nothing received: resets resumed;
  • no RX/TX errors; the node has since run with agc.reset.interval 60.

Builds: ProMicro_repeater, RAK_4631_repeater, Heltec_v3_repeater.

Not tested: the 24 h forced reset (logic only), and the "TX queued" branch was not hit
in the bench run.

Notes

marcelverdult and others added 30 commits September 26, 2026 20:39
Housekeeping: removed unnecessary space
Fix: tz_offset should allow for half hour timezone offsets
…ditional-display

Remove BLE screen when BLE not available
'get tz.offset' printed one decimal, so a UTC+5:45 offset (5.75)
read back as 5.8. Print two decimals when the offset is on a quarter
hour (x.25 / x.75); everything else keeps one decimal.
…e-wifi

added dynamic wifi to: lilygo t-beam supreme sx1262
…ft-wifi-enable

Fix: Added WiFi to TFT BLE version of Heltec V4
…ect-display

New AutoDetectDisplay for SH1106 and SSD1306
CMD_SEND_CHANNEL_TXT_MSG reads txt_type, channel_idx and a 4 byte timestamp, so
the frame needs 7 bytes before the text starts, and the branch had no length
guard. For a shorter frame "len - i" is computed in size_t, wraps, and reaches
sendGroupMessage() as a negative int. The clamp there tests
"text_len + prefix_len > MAX_TEXT_LEN", which a negative value passes, and the
following memcpy() converts the length back to a size_t: a 3 byte frame asks for
4294967292 bytes into a 197 byte stack buffer.

Two guards, because there are two mistakes. The branch now states its minimum
like most other branches of handleCmdFrame do, so a frame below 7 bytes is
answered through the existing path instead of being parsed. And
sendGroupMessage() refuses a negative length the way sendGroupData() in the same
file already does, which protects every other caller.

A frame of exactly 7 bytes keeps working and sends an empty message, as before.

Evidence. On a T-Echo running dev 428a95c, built with
FIRMWARE_BUILD_DATE "f1-dev" and confirmed by "ver => v1.18.0 (Build: f1-dev)":

  CH_TXT len=7    -> RESP_CODE_OK
  GET_STATS core  -> uptime=78s
  CH_TXT len=3    -> NO REPLY
  DEVICE_QUERY    -> NO REPLY  (three times over 8 s, node never came back)
"set af nan" is accepted and stores a NaN in airtime_factor, the duty cycle
budget the roles hand to their airtime accounting. strtof() consumes the
token, so the parse guard does not fire, and no ordered comparison is true for
a NaN, so "af < 0 || af > 9" cannot reject it. "set dutycycle" writes the same
field and has the same hole.

Both commands now check the text before it is parsed: after optional white
space and sign, a number has to start with a digit or a '.'. That refuses
"nan", "inf" and their variants, and keeps every spelling that was accepted
before (signs, leading white space, ".5"). The ranges and both reply strings
are unchanged.

The check is on the text rather than on the parsed float on purpose. nRF52
builds use -Ofast, and under -ffast-math the compiler may assume a float is
never NaN or infinite. A test on the value, even one that reads its bits, can
then be folded away: clang does exactly that with a bit test at -Ofast, while
arm-none-eabi-gcc keeps it. A character test does not depend on that.
Broken out from PR meshcore-dev#3496 which has been open for a month.
…idate/af-nan-text-check

Refuse nan and inf for the airtime factor (set af, set dutycycle)
…idate/companion-channel-txt-min-len

Fix companion crash on a short CMD_SEND_CHANNEL_TXT_MSG frame
fdlamotte and others added 30 commits October 24, 2026 19:50
…nion

ThinknodeM5: enable wifi in usb companion
…dem-usbcdc-tx-buffer

Fix broken KISS modem build on 6 ESP32-S3 platforms
…quarter-hours

Show quarter-hour timezone offsets with two decimals
Tested on a Heltec V4 repeater with the counter seeded at 65530.

Fixes meshcore-dev#3255

Co-Authored-By: Claude Opus 5.5 <[email protected]>
ESP32Board.h defined _rtc_backup_time and _rtc_backup_magic as static in the
header, so every translation unit that includes it has its own copy, and the
inline members of ESP32RTCClock read and write the copy of the unit they are
compiled in. Today one unit per image uses them; a second one could restore a
copy that setCurrentTime() never wrote. The header now declares them, and
ESP32Board.cpp defines them once.
…non-contact-slots

Skip empty anon contact slots in peer/contact lookups (prevent null-key ECDH sink)
…-prefs-signed-tx-power

Fix unsigned conversion of negative TX power in CommonRadioPrefs
…-m8-sensors

Fix ThinkNode M8 repeater/room server build: compile sensor helpers for all envs
T-Echo used the fallback GxEPD2_150_BN; on my unit every refresh hit the
10 s busy timeout. Switch to GxEPD2_154_D67 like Meshtastic.
…o-eink-driver

T-Echo: use GxEPD2_154_D67 e-ink driver
…te_changed

Remove unused buttonStateChanged from some variants
Fix LR2021 hot frequency change over BLE
…sp32-rtc-backup-once

Define the RTC backup of ESP32RTCClock once instead of per translation unit
…up-count-wrap

Saturate duplicate packet stats instead of wrapping
ui: add some parameters to the cli (mostly regarding eink behaviour)
'sensor list' appended 'name=value' lines into the 160-byte CLI reply with
unbounded sprintf, only checking the position before each write (< 134).
A single long value (or several medium ones) could write past the end of
the buffer.

Write each entry with snprintf against the remaining space, keep room for
the '... next:N' paging hint, and move entries that do not fit to the next
page. Also guard against NULL names/values from a sensor manager.
Add CLI command to toggle the buzzer for companions
…or-list-overflow

Fix possible reply buffer overflow in 'sensor list'
A reset takes the radio off the air. As in Meshtastic (develop), skip the
periodic reset if a packet was decoded within the last reset interval or
a packet is queued for transmit; the gain is not stuck then. Still reset
at least once per AGC_FORCED_RESET_MILLIS (default 24 h). Only matters
when agc.reset.interval > 0.

This branch has not been deployed

No deployments
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.