diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 598d535f..fa9edc8c 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -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) { diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index f2b56e5e..ef451d5d 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -69,6 +69,7 @@ #include #include +#include /* -------------------------------------------------------------------------------------- */ @@ -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