Add statistics commands and response handling in MyMesh

- Introduced new commands for retrieving statistics: CMD_GET_STATS_CORE, CMD_GET_STATS_RADIO, and CMD_GET_STATS_PACKETS.
- Implemented corresponding response handling methods to format and send statistics data.
- Updated MyMesh constructor to initialize new member variables for managing statistics.
- Included StatsFormatHelper for formatting statistics replies.
This commit is contained in:
agessaman 2025-11-07 22:16:48 -08:00
parent ab0721d6df
commit df4dab8509
2 changed files with 69 additions and 1 deletions

View file

@ -52,6 +52,9 @@
#define CMD_SEND_PATH_DISCOVERY_REQ 52
#define CMD_SET_FLOOD_SCOPE 54 // v8+
#define CMD_SEND_CONTROL_DATA 55 // v8+
#define CMD_GET_STATS_CORE 56
#define CMD_GET_STATS_RADIO 57
#define CMD_GET_STATS_PACKETS 58
#define RESP_CODE_OK 0
#define RESP_CODE_ERR 1
@ -77,6 +80,9 @@
#define RESP_CODE_CUSTOM_VARS 21
#define RESP_CODE_ADVERT_PATH 22
#define RESP_CODE_TUNING_PARAMS 23
#define RESP_CODE_STATS_CORE 24
#define RESP_CODE_STATS_RADIO 25
#define RESP_CODE_STATS_PACKETS 26
#define SEND_TIMEOUT_BASE_MILLIS 500
#define FLOOD_SEND_TIMEOUT_FACTOR 16.0f
@ -704,7 +710,7 @@ uint32_t MyMesh::calcDirectTimeoutMillisFor(uint32_t pkt_airtime_millis, uint8_t
void MyMesh::onSendTimeout() {}
MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store, AbstractUITask* ui)
: BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables),
: BaseChatMesh(radio, *(_ms_clock = new ArduinoMillis()), rng, rtc, *(_pkt_mgr = new StaticPoolPacketManager(16)), tables),
_serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4), _store(&store), _ui(ui) {
_iter_started = false;
_cli_rescue = false;
@ -1529,6 +1535,45 @@ void MyMesh::handleCmdFrame(size_t len) {
} else {
writeErrFrame(ERR_CODE_NOT_FOUND);
}
} else if (cmd_frame[0] == CMD_GET_STATS_CORE) {
char json_reply[160];
formatStatsReply(json_reply);
int i = 0;
out_frame[i++] = RESP_CODE_STATS_CORE;
int json_len = strlen(json_reply);
if (i + json_len <= MAX_FRAME_SIZE) {
memcpy(&out_frame[i], json_reply, json_len);
i += json_len;
_serial->writeFrame(out_frame, i);
} else {
writeErrFrame(ERR_CODE_TABLE_FULL);
}
} else if (cmd_frame[0] == CMD_GET_STATS_RADIO) {
char json_reply[160];
formatRadioStatsReply(json_reply);
int i = 0;
out_frame[i++] = RESP_CODE_STATS_RADIO;
int json_len = strlen(json_reply);
if (i + json_len <= MAX_FRAME_SIZE) {
memcpy(&out_frame[i], json_reply, json_len);
i += json_len;
_serial->writeFrame(out_frame, i);
} else {
writeErrFrame(ERR_CODE_TABLE_FULL);
}
} else if (cmd_frame[0] == CMD_GET_STATS_PACKETS) {
char json_reply[160];
formatPacketStatsReply(json_reply);
int i = 0;
out_frame[i++] = RESP_CODE_STATS_PACKETS;
int json_len = strlen(json_reply);
if (i + json_len <= MAX_FRAME_SIZE) {
memcpy(&out_frame[i], json_reply, json_len);
i += json_len;
_serial->writeFrame(out_frame, i);
} else {
writeErrFrame(ERR_CODE_TABLE_FULL);
}
} else if (cmd_frame[0] == CMD_FACTORY_RESET && memcmp(&cmd_frame[1], "reset", 5) == 0) {
bool success = _store->formatFileSystem();
if (success) {
@ -1565,6 +1610,21 @@ void MyMesh::enterCLIRescue() {
Serial.println("========= CLI Rescue =========");
}
void MyMesh::formatStatsReply(char *reply) {
// Use StatsFormatHelper
// Note: err_flags is private in Dispatcher, so we use 0
StatsFormatHelper::formatCoreStats(reply, board, *_ms_clock, 0, _pkt_mgr);
}
void MyMesh::formatRadioStatsReply(char *reply) {
StatsFormatHelper::formatRadioStats(reply, _radio, radio_driver, getTotalAirTime(), getReceiveAirTime());
}
void MyMesh::formatPacketStatsReply(char *reply) {
StatsFormatHelper::formatPacketStats(reply, radio_driver, getNumSentFlood(), getNumSentDirect(),
getNumRecvFlood(), getNumRecvDirect());
}
void MyMesh::checkCLIRescueCmd() {
int len = strlen(cli_command);
while (Serial.available() && len < sizeof(cli_command)-1) {

View file

@ -69,6 +69,7 @@
#include <helpers/BaseChatMesh.h>
#include <helpers/TransportKeyStore.h>
#include <helpers/StatsFormatHelper.h>
/* -------------------------------------------------------------------------------------- */
@ -170,6 +171,11 @@ private:
void checkCLIRescueCmd();
void checkSerialInterface();
// Stats methods
void formatStatsReply(char *reply);
void formatRadioStatsReply(char *reply);
void formatPacketStatsReply(char *reply);
// helpers, short-cuts
void savePrefs() { _store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon); }
void saveChannels() { _store->saveChannels(this); }
@ -178,6 +184,8 @@ private:
private:
DataStore* _store;
NodePrefs _prefs;
mesh::PacketManager* _pkt_mgr; // stored for stats access
mesh::MillisecondClock* _ms_clock; // stored for stats access
uint32_t pending_login;
uint32_t pending_status;
uint32_t pending_telemetry, pending_discovery; // pending _TELEMETRY_REQ