From b4f7e941fa91d9d1180ac0086fefe60def1263e9 Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Sun, 23 Aug 2026 17:30:30 +1000 Subject: [PATCH] * CommonRadioPrefs refactors done --- examples/companion_radio/NodePrefs.h | 24 ++++- src/helpers/CommonCLI.cpp | 99 +----------------- src/helpers/CommonCLI.h | 24 ++++- src/helpers/CommonRadioPrefs.cpp | 147 ++++++++++++++++++++++++++- src/helpers/CommonRadioPrefs.h | 45 +++++--- 5 files changed, 220 insertions(+), 119 deletions(-) diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index 367880526..f1cb69ccb 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -78,11 +78,31 @@ private: float getBandwidth() const override { return _parent->bw; } void setBandwidth(float bw) override { _parent->bw = bw; markDirty(); } uint8_t getSpreadFactor() const override { return _parent->sf; } - void setSpreadFactor(uint8_t sf) { _parent->sf; markDirty(); } + void setSpreadFactor(uint8_t sf) override { _parent->sf; markDirty(); } uint8_t getCodingRate() const override { return _parent->cr; } - void setCodingRate(uint8_t cr) { _parent->cr = cr; markDirty(); } + void setCodingRate(uint8_t cr) override { _parent->cr = cr; markDirty(); } float getAirtimeFactor() const override { return _parent->airtime_factor; } void setAirtimeFactor(float af) override { _parent->airtime_factor = af; markDirty(); } + bool isCadEnabled() const override { return false; } + void setCadEnabled(bool en) override { /* no-op */ } + uint8_t getIntThresh() const override { return 0; } + void setIntThresh(uint8_t t) override { /* no-op */ } + uint8_t getRxGain() const override { return _parent->rx_boosted_gain; } + void setRxGain(uint8_t g) override { _parent->rx_boosted_gain = g; markDirty(); } + uint8_t getTxPower() const override { return _parent->tx_power_dbm; } + void setTxPower(uint8_t dbm) override { _parent->tx_power_dbm = dbm; markDirty(); } + float getRxDelay() const override { return _parent->rx_delay_base; } + void setRxDelay(float d) override { _parent->rx_delay_base = d; markDirty(); } + uint8_t getAgcResetInt() const override { return 0; } + void setAgcResetInt(uint8_t secs) override { /* no-op */ } + uint8_t getHashMode() const override { return _parent->path_hash_mode; } + void setHashMode(uint8_t m) override { _parent->path_hash_mode = m; markDirty(); } + uint8_t getMultiAcks() const override { return _parent->multi_acks; } + void setMultiAcks(uint8_t m) override { _parent->multi_acks = m; markDirty(); } + float getFloodTxDelay() const override { return 0.5f; } // currently hard-coded + void setFloodTxDelay(float d) override { /* no-op */ } + float getDirectTxDelay() const override { return 0.2f; } // currently hard-coded + void setDirectTxDelay(float d) override { /* no-op */ } }; RadioPrefs radio; diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index 4e7af30b0..2e9efa9c9 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -454,27 +454,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* reply) { const char* config = &command[4]; - if (memcmp(config, "af ", 3) == 0) { - _prefs->airtime_factor = atof(&config[3]); - savePrefs(); - strcpy(reply, "OK"); - } else if (memcmp(config, "int.thresh ", 11) == 0) { - _prefs->interference_threshold = atoi(&config[11]); - savePrefs(); - strcpy(reply, "OK"); - } else if (memcmp(config, "cad ", 4) == 0) { - _prefs->cad_enabled = memcmp(&config[4], "on", 2) == 0; - savePrefs(); - strcpy(reply, "OK"); - } else if (memcmp(config, "agc.reset.interval ", 19) == 0) { - _prefs->agc_reset_interval = atoi(&config[19]) / 4; - savePrefs(); - sprintf(reply, "OK - interval rounded to %d", ((uint32_t) _prefs->agc_reset_interval) * 4); - } else if (memcmp(config, "multi.acks ", 11) == 0) { - _prefs->multi_acks = atoi(&config[11]); - savePrefs(); - strcpy(reply, "OK"); - } else if (memcmp(config, "allow.read.only ", 16) == 0) { + if (memcmp(config, "allow.read.only ", 16) == 0) { _prefs->allow_read_only = memcmp(&config[16], "on", 2) == 0; savePrefs(); strcpy(reply, "OK"); @@ -527,15 +507,6 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep _prefs->disable_fwd = memcmp(&config[7], "off", 3) == 0; savePrefs(); strcpy(reply, _prefs->disable_fwd ? "OK - repeat is now OFF" : "OK - repeat is now ON"); - } else if (memcmp(config, "radio.rxgain ", 13) == 0) { - bool enabled = memcmp(&config[13], "on", 2) == 0; - _prefs->rx_boosted_gain = enabled; - savePrefs(); - if (_callbacks->setRxBoostedGain(enabled)) { - strcpy(reply, "OK"); - } else { - strcpy(reply, "Error: unsupported"); - } } else if (memcmp(config, "radio.fem.rxgain ", 17) == 0) { if (!_board->canControlLoRaFemLna()) { strcpy(reply, "Error: unsupported"); @@ -588,24 +559,6 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep _prefs->node_lon = atof(&config[4]); savePrefs(); strcpy(reply, "OK"); - } else if (memcmp(config, "rxdelay ", 8) == 0) { - float db = atof(&config[8]); - if (db >= 0 && db <= 20.0f) { - _prefs->rx_delay_base = db; - savePrefs(); - strcpy(reply, "OK"); - } else { - strcpy(reply, "Error, must be 0-20"); - } - } else if (memcmp(config, "txdelay ", 8) == 0) { - float f = atof(&config[8]); - if (f >= 0 && f <= 2.0f) { - _prefs->tx_delay_factor = f; - savePrefs(); - strcpy(reply, "OK"); - } else { - strcpy(reply, "Error, must be 0-2"); - } } else if (memcmp(config, "flood.max.unscoped ", 19) == 0) { uint8_t m = atoi(&config[19]); if (m <= 64) { @@ -633,15 +586,6 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep } else { strcpy(reply, "Error, max 64"); } - } else if (memcmp(config, "direct.txdelay ", 15) == 0) { - float f = atof(&config[15]); - if (f >= 0 && f <= 2.0f) { - _prefs->direct_tx_delay_factor = f; - savePrefs(); - strcpy(reply, "OK"); - } else { - strcpy(reply, "Error, must be 0-2"); - } } else if (memcmp(config, "owner.info ", 11) == 0) { config += 11; char *dp = _prefs->owner_info; @@ -652,16 +596,6 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep *dp = 0; savePrefs(); strcpy(reply, "OK"); - } else if (memcmp(config, "path.hash.mode ", 15) == 0) { - config += 15; - uint8_t mode = atoi(config); - if (mode < 3) { - _prefs->path_hash_mode = mode; - savePrefs(); - strcpy(reply, "OK"); - } else { - strcpy(reply, "Error, must be 0,1, or 2"); - } } else if (memcmp(config, "loop.detect ", 12) == 0) { config += 12; uint8_t mode; @@ -682,11 +616,6 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep savePrefs(); strcpy(reply, "OK"); } - } else if (memcmp(config, "tx ", 3) == 0) { - _prefs->tx_power_dbm = atoi(&config[3]); - savePrefs(); - _callbacks->setTxPower(_prefs->tx_power_dbm); - strcpy(reply, "OK"); } else if (sender_timestamp == 0 && memcmp(config, "freq ", 5) == 0) { _prefs->freq = atof(&config[5]); savePrefs(); @@ -783,17 +712,7 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* reply) { const char* config = &command[4]; - if (memcmp(config, "af", 2) == 0) { - sprintf(reply, "> %s", StrHelper::ftoa(_prefs->airtime_factor)); - } else if (memcmp(config, "int.thresh", 10) == 0) { - sprintf(reply, "> %d", (uint32_t) _prefs->interference_threshold); - } else if (memcmp(config, "cad", 3) == 0) { - sprintf(reply, "> %s", _prefs->cad_enabled ? "on" : "off"); - } else if (memcmp(config, "agc.reset.interval", 18) == 0) { - sprintf(reply, "> %d", ((uint32_t) _prefs->agc_reset_interval) * 4); - } else if (memcmp(config, "multi.acks", 10) == 0) { - sprintf(reply, "> %d", (uint32_t) _prefs->multi_acks); - } else if (memcmp(config, "allow.read.only", 15) == 0) { + if (memcmp(config, "allow.read.only", 15) == 0) { sprintf(reply, "> %s", _prefs->allow_read_only ? "on" : "off"); } else if (memcmp(config, "flood.advert.interval", 21) == 0) { sprintf(reply, "> %d", ((uint32_t) _prefs->flood_advert_interval)); @@ -814,8 +733,6 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lat)); } else if (memcmp(config, "lon", 3) == 0) { sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lon)); - } else if (memcmp(config, "radio.rxgain", 12) == 0) { - sprintf(reply, "> %s", _prefs->rx_boosted_gain ? "on" : "off"); } else if (memcmp(config, "radio.fem.rxgain", 16) == 0) { if (!_board->canControlLoRaFemLna()) { strcpy(reply, "Error: unsupported"); @@ -828,18 +745,12 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep } else { sprintf(reply, "> %s", _board->isLoRaFemPaGainEnabled() ? "on" : "off"); } - } else if (memcmp(config, "rxdelay", 7) == 0) { - sprintf(reply, "> %s", StrHelper::ftoa(_prefs->rx_delay_base)); - } else if (memcmp(config, "txdelay", 7) == 0) { - sprintf(reply, "> %s", StrHelper::ftoa(_prefs->tx_delay_factor)); } else if (memcmp(config, "flood.max.advert", 16) == 0) { sprintf(reply, "> %d", (uint32_t)_prefs->flood_max_advert); } else if (memcmp(config, "flood.max.unscoped", 18) == 0) { sprintf(reply, "> %d", (uint32_t)_prefs->flood_max_unscoped); } else if (memcmp(config, "flood.max", 9) == 0) { sprintf(reply, "> %d", (uint32_t)_prefs->flood_max); - } else if (memcmp(config, "direct.txdelay", 14) == 0) { - sprintf(reply, "> %s", StrHelper::ftoa(_prefs->direct_tx_delay_factor)); } else if (memcmp(config, "owner.info", 10) == 0) { auto start = reply; *reply++ = '>'; @@ -850,8 +761,6 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep sp++; } *reply = 0; // set null terminator - } else if (memcmp(config, "path.hash.mode", 14) == 0) { - sprintf(reply, "> %d", (uint32_t)_prefs->path_hash_mode); } else if (memcmp(config, "loop.detect", 11) == 0) { if (_prefs->loop_detect == LOOP_DETECT_OFF) { strcpy(reply, "> off"); @@ -862,10 +771,6 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep } else { strcpy(reply, "> strict"); } - } else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) { - sprintf(reply, "> %d", (int32_t) _prefs->tx_power_dbm); - } else if (memcmp(config, "freq", 4) == 0) { - sprintf(reply, "> %s", StrHelper::ftoa(_prefs->freq)); } else if (memcmp(config, "public.key", 10) == 0) { strcpy(reply, "> "); mesh::Utils::toHex(&reply[2], _callbacks->getSelfId().pub_key, PUB_KEY_SIZE); diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index 9d3caf39f..69243f52f 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -103,11 +103,31 @@ private: float getBandwidth() const override { return _parent->bw; } void setBandwidth(float bw) override { _parent->bw = bw; markDirty(); } uint8_t getSpreadFactor() const override { return _parent->sf; } - void setSpreadFactor(uint8_t sf) { _parent->sf; markDirty(); } + void setSpreadFactor(uint8_t sf) override { _parent->sf; markDirty(); } uint8_t getCodingRate() const override { return _parent->cr; } - void setCodingRate(uint8_t cr) { _parent->cr = cr; markDirty(); } + void setCodingRate(uint8_t cr) override { _parent->cr = cr; markDirty(); } float getAirtimeFactor() const override { return _parent->airtime_factor; } void setAirtimeFactor(float af) override { _parent->airtime_factor = af; markDirty(); } + bool isCadEnabled() const override { return _parent->cad_enabled; } + void setCadEnabled(bool en) override { _parent->cad_enabled; markDirty(); } + uint8_t getIntThresh() const override { return _parent->interference_threshold; } + void setIntThresh(uint8_t t) override { _parent->interference_threshold = t; markDirty(); } + uint8_t getRxGain() const override { return _parent->rx_boosted_gain; } + void setRxGain(uint8_t g) override { _parent->rx_boosted_gain = g; markDirty(); } + uint8_t getTxPower() const override { return _parent->tx_power_dbm; } + void setTxPower(uint8_t dbm) override { _parent->tx_power_dbm = dbm; markDirty(); } + float getRxDelay() const override { return _parent->rx_delay_base; } + void setRxDelay(float d) override { _parent->rx_delay_base = d; markDirty(); } + uint8_t getAgcResetInt() const override { return _parent->agc_reset_interval * 4; } + void setAgcResetInt(uint8_t secs) override { _parent->agc_reset_interval = secs / 4; markDirty(); } + uint8_t getHashMode() const override { return _parent->path_hash_mode; } + void setHashMode(uint8_t m) override { _parent->path_hash_mode = m; markDirty(); } + uint8_t getMultiAcks() const override { return _parent->multi_acks; } + void setMultiAcks(uint8_t m) override { _parent->multi_acks = m; markDirty(); } + float getFloodTxDelay() const override { return _parent->tx_delay_factor; } + void setFloodTxDelay(float d) override { _parent->tx_delay_factor = d; markDirty(); } + float getDirectTxDelay() const override { return _parent->direct_tx_delay_factor; } + void setDirectTxDelay(float d) override { _parent->direct_tx_delay_factor = d; markDirty(); } }; RadioPrefs radio; diff --git a/src/helpers/CommonRadioPrefs.cpp b/src/helpers/CommonRadioPrefs.cpp index ed198c610..275449e6b 100644 --- a/src/helpers/CommonRadioPrefs.cpp +++ b/src/helpers/CommonRadioPrefs.cpp @@ -1,6 +1,7 @@ #include "CommonRadioPrefs.h" #include "TxtDataHelpers.h" #include "Utils.h" +#include "target.h" bool CommonRadioPrefs::handleCommand(const char* command, uint32_t sender_timestamp, char* reply) { if (strcmp(command, "get radio") == 0) { @@ -24,13 +25,28 @@ bool CommonRadioPrefs::handleCommand(const char* command, uint32_t sender_timest setCodingRate(cr); setFreq(freq); setBandwidth(bw); - // NOTE: savePrefs() should be handled by caller strcpy(reply, "OK - reboot to apply"); } else { strcpy(reply, "Error, invalid radio params"); } return true; } + + if (strcmp(command, "get freq") == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(getFreq())); + return true; + } + + if (strcmp(command, "get af") == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(getAirtimeFactor())); + return true; + } + if (memcmp(command, "set af ", 7) == 0) { + setAirtimeFactor(atof(&command[7])); + strcpy(reply, "OK"); + return true; + } + if (strcmp(command, "get dutycycle") == 0) { float dc = 100.0f / (getAirtimeFactor() + 1.0f); int dc_int = (int)dc; @@ -44,7 +60,6 @@ bool CommonRadioPrefs::handleCommand(const char* command, uint32_t sender_timest strcpy(reply, "ERROR: dutycycle must be 1-100"); } else { setAirtimeFactor((100.0f / dc) - 1.0f); - // NOTE: savePrefs() should be handled by caller float actual = 100.0f / (getAirtimeFactor() + 1.0f); int a_int = (int)actual; int a_frac = (int)((actual - a_int) * 10.0f + 0.5f); @@ -52,5 +67,133 @@ bool CommonRadioPrefs::handleCommand(const char* command, uint32_t sender_timest } return true; } + + if (strcmp(command, "get int.thresh") == 0) { + sprintf(reply, "> %d", (uint32_t) getIntThresh()); + return true; + } + if (memcmp(command, "set int.thresh ", 15) == 0) { + setIntThresh(atoi(&command[15])); + strcpy(reply, "OK"); + return true; + } + + if (strcmp(command, "get cad") == 0) { + sprintf(reply, "> %s", isCadEnabled() ? "on" : "off"); + return true; + } + if (memcmp(command, "set cad ", 8) == 0) { + setCadEnabled(memcmp(&command[8], "on", 2) == 0); + strcpy(reply, "OK"); + return true; + } + + if (strcmp(command, "get radio.rxgain") == 0) { + sprintf(reply, "> %s", getRxGain() != 0 ? "on" : "off"); + return true; + } + if (memcmp(command, "set radio.rxgain ", 17) == 0) { + bool enabled = memcmp(&command[17], "on", 2) == 0; + setRxGain(enabled); + if (radio_driver.setRxBoostedGainMode(enabled)) { + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error: unsupported"); + } + return true; + } + + if (memcmp(command, "get tx", 6) == 0 && (command[6] == 0 || command[6] == ' ')) { + sprintf(reply, "> %d", (int32_t) getTxPower()); + return true; + } + if (memcmp(command, "set tx ", 7) == 0) { + setTxPower(atoi(&command[7])); + radio_driver.setTxPower(getTxPower()); + strcpy(reply, "OK"); + return true; + } + + if (strcmp(command, "get rxdelay") == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(getRxDelay())); + return true; + } + if (memcmp(command, "set rxdelay ", 12) == 0) { + float db = atof(&command[12]); + if (db >= 0 && db <= 20.0f) { + setRxDelay(db); + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error, must be 0-20"); + } + return true; + } + + if (strcmp(command, "get agc.reset.interval") == 0) { + sprintf(reply, "> %d", (uint32_t) getAgcResetInt()); + return true; + } + if (memcmp(command, "set agc.reset.interval ", 23) == 0) { + setAgcResetInt(atoi(&command[23])); + sprintf(reply, "OK - interval rounded to %d", (uint32_t) getAgcResetInt()); + return true; + } + + if (strcmp(command, "get path.hash.mode") == 0) { + sprintf(reply, "> %d", (uint32_t)getHashMode()); + return true; + } + if (memcmp(command, "set path.hash.mode ", 19) == 0) { + const char* config = command + 19; + uint8_t mode = atoi(config); + if (mode < 3) { + setHashMode(mode); + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error, must be 0,1, or 2"); + } + return true; + } + + if (strcmp(command, "get multi.acks") == 0) { + sprintf(reply, "> %d", (uint32_t) getMultiAcks()); + return true; + } + if (memcmp(command, "set multi.acks ", 15) == 0) { + setMultiAcks(atoi(&command[15])); + strcpy(reply, "OK"); + return true; + } + + if (strcmp(command, "get txdelay") == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(getFloodTxDelay())); + return true; + } + if (memcmp(command, "set txdelay ", 12) == 0) { + float f = atof(&command[12]); + if (f >= 0 && f <= 2.0f) { + setFloodTxDelay(f); + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error, must be 0-2"); + } + return true; + } + + if (strcmp(command, "get direct.txdelay") == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(getDirectTxDelay())); + return true; + } + if (memcmp(command, "set direct.txdelay ", 19) == 0) { + float f = atof(&command[19]); + if (f >= 0 && f <= 2.0f) { + setDirectTxDelay(f); + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error, must be 0-2"); + } + return true; + } + return false; // not handled } diff --git a/src/helpers/CommonRadioPrefs.h b/src/helpers/CommonRadioPrefs.h index eaec2c0aa..c2aefd98b 100644 --- a/src/helpers/CommonRadioPrefs.h +++ b/src/helpers/CommonRadioPrefs.h @@ -24,22 +24,35 @@ public: virtual float getAirtimeFactor() const = 0; virtual void setAirtimeFactor(float af) = 0; - // //def("cad", _parent->cad_enabled); - // //def("int_thr", _parent->interference_threshold); - // def("rxgain", _parent->rx_boosted_gain); - // #if 0 - // // NOTE: these cannot be set (yet) so don't load/save until we can. - // // also, fem_rxgain WAS mapped to wrong JSON property previously - // def("fem_rxgain", _parent->radio_fem_rxgain); - // def("fem_txgain", _parent->radio_fem_txgain); - // #endif - // def("tx", _parent->tx_power_dbm); - // def("rxdelay", _parent->rx_delay_base); - // //def("f_txdelay", _parent->tx_delay_factor); currently hard-coded - // //def("d_txdelay", _parent->direct_tx_delay_factor); currently hard-coded - // //def("agc_int", _parent->agc_reset_interval); - // def("hash_mode", _parent->path_hash_mode); - // def("multi_ack", _parent->multi_acks); + virtual bool isCadEnabled() const = 0; + virtual void setCadEnabled(bool en) = 0; + + virtual uint8_t getIntThresh() const = 0; + virtual void setIntThresh(uint8_t t) = 0; + + virtual uint8_t getRxGain() const = 0; + virtual void setRxGain(uint8_t g) = 0; + + virtual uint8_t getTxPower() const = 0; + virtual void setTxPower(uint8_t dbm) = 0; + + virtual float getRxDelay() const = 0; + virtual void setRxDelay(float d) = 0; + + virtual uint8_t getAgcResetInt() const = 0; + virtual void setAgcResetInt(uint8_t secs) = 0; + + virtual uint8_t getHashMode() const = 0; + virtual void setHashMode(uint8_t m) = 0; + + virtual uint8_t getMultiAcks() const = 0; + virtual void setMultiAcks(uint8_t m) = 0; + + virtual float getFloodTxDelay() const = 0; + virtual void setFloodTxDelay(float d) = 0; + + virtual float getDirectTxDelay() const = 0; + virtual void setDirectTxDelay(float d) = 0; bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply); };