mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-07-28 14:09:38 +00:00
Commit 22eb9b87 ("Revert 'Merge remote-tracking branch origin/dev...'")
reverted an entire upstream merge to escape a bad merge state, dropping
860 lines across 66 files. Among the collateral never reconciled on a
later re-merge was eb4fa032's token-bucket duty-cycle enforcement — the
mechanism that keeps nodes under a configured airtime budget (and EU
868 MHz nodes under the legally-mandated duty cycle). The fork had fallen
back to fixed per-packet spacing (getAirtimeBudgetFactor reverted to 2.0),
losing the windowed enforcement.
This was never an intentional design choice, so restoring it re-aligns the
fork with upstream and REDUCES the merge-conflict surface: Dispatcher.{h,cpp}
now diverge from upstream by watchdog additions only (77 insertions, 0
deletions) instead of rewriting checkSend()/loop().
Restored from upstream: updateTxBudget/tx_budget_ms/duty_cycle_window_ms/
getRemainingTxBudget/getDutyCycleWindowMs and the windowed budget logic in
Dispatcher; getOutboundTotal() and the 0xFFFFFFFF count-all sentinel in
StaticPoolPacketManager; the getOutboundTotal() call in StatsFormatHelper.
Re-applied the fork's MQTT radio-watchdog on top as pure additions
(#ifdef WITH_MQTT_BRIDGE), keeping formatRadioDiag.
Stored airtime_factor settings keep their meaning: fork's t*factor spacing
and upstream's 1/(1+factor) windowed budget yield the same steady-state
duty cycle; upstream additionally allows short bursts within the window.
Phase 2 (CAD / radio_fem_rxgain, which touch NodePrefs persistence and
per-board FEM wiring) is documented in RESTORE_UPSTREAM_NOTES.md, not done
here. Builds: Heltec_v3 observer + plain repeater. NEEDS ON-DEVICE
duty-cycle validation before merge.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
74 lines
2.7 KiB
C++
74 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include "Mesh.h"
|
|
|
|
class StatsFormatHelper {
|
|
public:
|
|
static void formatCoreStats(char* reply,
|
|
mesh::MainBoard& board,
|
|
mesh::MillisecondClock& ms,
|
|
uint16_t err_flags,
|
|
mesh::PacketManager* mgr) {
|
|
sprintf(reply,
|
|
"{\"battery_mv\":%u,\"uptime_secs\":%u,\"errors\":%u,\"queue_len\":%u}",
|
|
board.getBattMilliVolts(),
|
|
ms.getMillis() / 1000,
|
|
err_flags,
|
|
mgr->getOutboundTotal()
|
|
);
|
|
}
|
|
|
|
template<typename RadioDriverType>
|
|
static void formatRadioStats(char* reply,
|
|
mesh::Radio* radio,
|
|
RadioDriverType& driver,
|
|
uint32_t total_air_time_ms,
|
|
uint32_t total_rx_air_time_ms) {
|
|
sprintf(reply,
|
|
"{\"noise_floor\":%d,\"last_rssi\":%d,\"last_snr\":%.2f,\"tx_air_secs\":%u,\"rx_air_secs\":%u}",
|
|
(int16_t)radio->getNoiseFloor(),
|
|
(int16_t)driver.getLastRSSI(),
|
|
driver.getLastSNR(),
|
|
total_air_time_ms / 1000,
|
|
total_rx_air_time_ms / 1000
|
|
);
|
|
}
|
|
|
|
template<typename RadioDriverType>
|
|
static void formatRadioDiag(char* reply,
|
|
mesh::Radio* radio,
|
|
RadioDriverType& driver,
|
|
mesh::MillisecondClock& ms,
|
|
uint16_t err_flags,
|
|
bool has_outbound) {
|
|
uint8_t st = radio->getRadioState();
|
|
const char* state_name = (st & 16) ? "INT_READY" : (st == 0 ? "IDLE" : (st == 1 ? "RX" : (st == 3 ? "TX_WAIT" : "?")));
|
|
unsigned long last_rx = radio->getLastRecvMillis();
|
|
unsigned long ago_secs = (last_rx > 0) ? (ms.getMillis() - last_rx) / 1000 : 0;
|
|
sprintf(reply,
|
|
"state=%d(%s), recv=%u, sent=%u, errors=%u, err_flags=%u, outbound=%s, last_rx=%lus ago",
|
|
st, state_name,
|
|
driver.getPacketsRecv(), driver.getPacketsSent(), driver.getPacketsRecvErrors(),
|
|
err_flags, has_outbound ? "yes" : "no", ago_secs);
|
|
}
|
|
|
|
template<typename RadioDriverType>
|
|
static void formatPacketStats(char* reply,
|
|
RadioDriverType& driver,
|
|
uint32_t n_sent_flood,
|
|
uint32_t n_sent_direct,
|
|
uint32_t n_recv_flood,
|
|
uint32_t n_recv_direct) {
|
|
sprintf(reply,
|
|
"{\"recv\":%u,\"sent\":%u,\"flood_tx\":%u,\"direct_tx\":%u,\"flood_rx\":%u,\"direct_rx\":%u,\"recv_errors\":%u}",
|
|
driver.getPacketsRecv(),
|
|
driver.getPacketsSent(),
|
|
n_sent_flood,
|
|
n_sent_direct,
|
|
n_recv_flood,
|
|
n_recv_direct,
|
|
driver.getPacketsRecvErrors()
|
|
);
|
|
}
|
|
};
|