mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-09-27 05:17:58 +00:00
97 lines
5.8 KiB
Markdown
97 lines
5.8 KiB
Markdown
# Restoring accidentally-reverted upstream features
|
|
|
|
> **Historical recovery record, reconciled 2026-08-18.** Phase 1 and Phase 2
|
|
> described below have been implemented in the current tree. This file explains
|
|
> why the restoration occurred; use the CLI and build documentation for current
|
|
> behavior rather than treating the old “remaining” text as an active plan.
|
|
|
|
## Background
|
|
|
|
On 2026-03-20, commit `22eb9b87` - *Revert "Merge remote-tracking branch 'origin/dev' into mqtt-bridge-implementation"* - reverted an entire upstream merge to escape a bad merge state, deleting 860 lines across 66 files. That was not intentional feature removal; it wholesale dropped a batch of upstream progress. When upstream was later re-merged, some collateral came back (MicroNMEA `claim()/release()`, the GAT562 board) but several upstream features were never reconciled and remained missing.
|
|
|
|
This branch restores them. They are **pure upstream code the fork accidentally dropped**, so restoring re-aligns the fork with upstream and *reduces* the future merge-conflict surface rather than adding to it.
|
|
|
|
## Phase 1 - duty-cycle enforcement (done on this branch)
|
|
|
|
Restored the token-bucket duty-cycle enforcement and its cluster:
|
|
|
|
- `src/Dispatcher.{h,cpp}` - restored upstream's `updateTxBudget()`, `tx_budget_ms`,
|
|
`duty_cycle_window_ms`, `getRemainingTxBudget()`, `getDutyCycleWindowMs()`, and the
|
|
windowed `checkSend()`/`loop()` budget logic. The fork's MQTT **radio watchdog** was
|
|
re-applied on top as pure additions (behind `#ifdef WITH_MQTT_BRIDGE`).
|
|
- `src/helpers/StaticPoolPacketManager.{h,cpp}` - restored `getOutboundTotal()` and the
|
|
`0xFFFFFFFF` count-all sentinel in `countBefore()`.
|
|
- `src/helpers/StatsFormatHelper.h` - restored the `getOutboundTotal()` call; kept the
|
|
fork's `formatRadioDiag` template.
|
|
|
|
Net effect: these files now diverge from upstream by **watchdog additions only (0 deletions)**
|
|
instead of rewriting upstream's TX logic.
|
|
|
|
### Why this is safe (no reinterpretation of stored settings)
|
|
|
|
`getAirtimeBudgetFactor()` changed *meaning* between fork and upstream, but the resulting
|
|
duty cycle is the **same formula**:
|
|
- Fork: `next_tx = t * factor` -> duty ~ `1/(1+factor)`
|
|
- Upstream: `duty = 1/(1+factor)` enforced over a rolling window
|
|
|
|
So a device's stored `airtime_factor` (a `NodePrefs` field, unchanged) keeps its meaning.
|
|
The only behavioral difference is upstream enforces it over a 1-hour window (allowing
|
|
short bursts) instead of rigid per-packet spacing - a strict improvement, and the
|
|
mechanism that keeps EU 868 MHz nodes under the legally-mandated duty cycle.
|
|
|
|
### Must be validated on-device before merge
|
|
|
|
This touches core TX timing. Confirm on hardware - **all device-confirmed 2026-07-09/10
|
|
on a Heltec V4.2 (busy live mesh + off-frequency bench):**
|
|
- [OK] Normal traffic still flows (repeater forwards, observer uplinks).
|
|
- [OK] Sustained TX is throttled to the configured duty cycle: at `set dutycycle 1` on a
|
|
busy mesh, TX pinned to ~1% while MQTT capture continued at full rate (after the
|
|
`RxReservePacketManager` fixes below). Remote admin remains usable under throttle
|
|
with the priority-shed + stale-expiry policy.
|
|
- [OK] CAD enabled under load: TX, capture, and CLI all normal.
|
|
- [OK] The observer radio watchdog fires and recovers non-destructively: with
|
|
`radio.watchdog 1` on a silent frequency, `err_flags` bit 8 set, radio remained in
|
|
RX state through repeated recovery cycles, and packets were still received after.
|
|
Note: firings are invisible on release builds (no MESH_DEBUG) - check
|
|
`stats-radio-diag` `err_flags`; the watchdog arms only after first radio activity
|
|
(`last_active > 0`), so a radio wedged from boot is deliberately not covered.
|
|
|
|
At the time of that review, the remaining undraft recommendation was a passive
|
|
soak at the fleet-default `airtime_factor` (duty convergence, flat heap, and
|
|
continued adverts). That sentence is retained as historical validation scope,
|
|
not as the current branch's merge state.
|
|
|
|
### Known interaction: throttling starves MQTT capture (mitigated)
|
|
|
|
Found during the on-device duty-cycle load test (`set dutycycle 1`): queued
|
|
retransmissions hold static-pool packets with no expiry, so heavy throttling parks the
|
|
whole pool in the send queue. `Dispatcher::checkRecv()` then drops received packets
|
|
before `logRx()` runs, capping MQTT capture at the TX rate (each TX frees one packet
|
|
for one RX). Parked repeats also absorb every budget refill, starving the node's own
|
|
CLI responses - device-confirmed: a 1%-duty node on a busy mesh became
|
|
un-administrable within ~2 minutes. This is inherent upstream behavior - the old
|
|
fork's `next_tx` spacing had the same steady-state drain - but it defeats the
|
|
observer's purpose. Mitigated on observer builds by `RxReservePacketManager`
|
|
(`src/helpers/RxReservePacketManager.h`): priority-aware shedding below a pool
|
|
reserve (own responses/ACKs stay queueable) plus 30 s expiry of stale queued
|
|
outbound. See MQTT_INTERNALS.md "Capture vs. duty-cycle throttling".
|
|
|
|
## Phase 2 - CAD and FEM RX gain (completed)
|
|
|
|
The current tree contains both restored capabilities:
|
|
|
|
- **`cad_enabled`** is present in common preferences, load/save paths, and the
|
|
`get/set cad` CLI. Repeater, room-server, sensor, and Companion integrations
|
|
feed it to `RadioLibWrapper::setCADEnabled()`. The Cascade profile supplies
|
|
`DEFAULT_CAD_ENABLED=0` for fresh settings across all roles; saved CAD settings
|
|
take precedence after an upgrade.
|
|
- **`radio_fem_rxgain`** is persisted and exposed as
|
|
`get/set radio.fem.rxgain`. Supported boards implement
|
|
`setLoRaFemLnaEnabled()`; unsupported boards reject the operation rather than
|
|
claiming a state change. Companion protocol v13 also exposes FEM RX-gain get
|
|
and set commands.
|
|
|
|
See [CLI commands](docs/cli_commands.md) and the
|
|
[command availability matrix](docs/cli_command_availability.md) for current
|
|
syntax and build/hardware limits.
|