diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index cee3a008..264b451b 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -120,7 +120,7 @@ struct NeighbourInfo { int8_t snr; // multiplied by 4, user should divide to get float value }; -#define CLI_REPLY_DELAY_MILLIS 1000 +#define CLI_REPLY_DELAY_MILLIS 600 class MyMesh : public mesh::Mesh, public CommonCLICallbacks { FILESYSTEM* _fs; @@ -134,6 +134,11 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { NeighbourInfo neighbours[MAX_NEIGHBOURS]; #endif CayenneLPP telemetry; + unsigned long set_radio_at, revert_radio_at; + float pending_freq; + float pending_bw; + uint8_t pending_sf; + uint8_t pending_cr; ClientInfo* putClient(const mesh::Identity& id) { uint32_t min_time = 0xFFFFFFFF; @@ -558,6 +563,7 @@ public: { memset(known_clients, 0, sizeof(known_clients)); next_local_advert = next_flood_advert = 0; + set_radio_at = revert_radio_at = 0; _logging = false; #if MAX_NEIGHBOURS @@ -609,6 +615,16 @@ public: _cli.savePrefs(_fs); } + void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override { + set_radio_at = futureMillis(2000); // give CLI reply some time to be sent back, before applying temp radio params + pending_freq = freq; + pending_bw = bw; + pending_sf = sf; + pending_cr = cr; + + revert_radio_at = futureMillis(2000 + timeout_mins*60*1000); // schedule when to revert radio params + } + bool formatFileSystem() override { #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM) return InternalFS.format(); @@ -734,6 +750,19 @@ public: updateAdvertTimer(); // schedule next local advert } + + if (set_radio_at && millisHasNowPassed(set_radio_at)) { // apply pending (temporary) radio params + set_radio_at = 0; // clear timer + radio_set_params(pending_freq, pending_bw, pending_sf, pending_cr); + MESH_DEBUG_PRINTLN("Temp radio params"); + } + + if (revert_radio_at && millisHasNowPassed(revert_radio_at)) { // revert radio params to orig + revert_radio_at = 0; // clear timer + radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr); + MESH_DEBUG_PRINTLN("Radio params restored"); + } + #ifdef DISPLAY_CLASS ui_task.loop(); #endif diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index 1ab08d9b..c9feaa68 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -165,6 +165,11 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { int next_post_idx; PostInfo posts[MAX_UNSYNCED_POSTS]; // cyclic queue CayenneLPP telemetry; + unsigned long set_radio_at, revert_radio_at; + float pending_freq; + float pending_bw; + uint8_t pending_sf; + uint8_t pending_cr; ClientInfo* putClient(const mesh::Identity& id) { for (int i = 0; i < num_clients; i++) { @@ -721,6 +726,7 @@ public: { next_local_advert = next_flood_advert = 0; _logging = false; + set_radio_at = revert_radio_at = 0; // defaults memset(&_prefs, 0, sizeof(_prefs)); @@ -778,6 +784,16 @@ public: _cli.savePrefs(_fs); } + void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override { + set_radio_at = futureMillis(2000); // give CLI reply some time to be sent back, before applying temp radio params + pending_freq = freq; + pending_bw = bw; + pending_sf = sf; + pending_cr = cr; + + revert_radio_at = futureMillis(2000 + timeout_mins*60*1000); // schedule when to revert radio params + } + bool formatFileSystem() override { #if defined(NRF52_PLATFORM) return InternalFS.format(); @@ -922,6 +938,18 @@ public: updateAdvertTimer(); // schedule next local advert } + if (set_radio_at && millisHasNowPassed(set_radio_at)) { // apply pending (temporary) radio params + set_radio_at = 0; // clear timer + radio_set_params(pending_freq, pending_bw, pending_sf, pending_cr); + MESH_DEBUG_PRINTLN("Temp radio params"); + } + + if (revert_radio_at && millisHasNowPassed(revert_radio_at)) { // revert radio params to orig + revert_radio_at = 0; // clear timer + radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr); + MESH_DEBUG_PRINTLN("Radio params restored"); + } + #ifdef DISPLAY_CLASS ui_task.loop(); #endif diff --git a/examples/simple_sensor/SensorMesh.cpp b/examples/simple_sensor/SensorMesh.cpp index abdc7182..0816af72 100644 --- a/examples/simple_sensor/SensorMesh.cpp +++ b/examples/simple_sensor/SensorMesh.cpp @@ -722,6 +722,7 @@ SensorMesh::SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::Millise dirty_contacts_expiry = 0; last_read_time = 0; num_alert_tasks = 0; + set_radio_at = revert_radio_at = 0; // defaults memset(&_prefs, 0, sizeof(_prefs)); @@ -772,6 +773,16 @@ bool SensorMesh::formatFileSystem() { #endif } +void SensorMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) { + set_radio_at = futureMillis(2000); // give CLI reply some time to be sent back, before applying temp radio params + pending_freq = freq; + pending_bw = bw; + pending_sf = sf; + pending_cr = cr; + + revert_radio_at = futureMillis(2000 + timeout_mins*60*1000); // schedule when to revert radio params +} + void SensorMesh::sendSelfAdvertisement(int delay_millis) { mesh::Packet* pkt = createSelfAdvert(); if (pkt) { @@ -847,6 +858,18 @@ void SensorMesh::loop() { updateAdvertTimer(); // schedule next local advert } + if (set_radio_at && millisHasNowPassed(set_radio_at)) { // apply pending (temporary) radio params + set_radio_at = 0; // clear timer + radio_set_params(pending_freq, pending_bw, pending_sf, pending_cr); + MESH_DEBUG_PRINTLN("Temp radio params"); + } + + if (revert_radio_at && millisHasNowPassed(revert_radio_at)) { // revert radio params to orig + revert_radio_at = 0; // clear timer + radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr); + MESH_DEBUG_PRINTLN("Radio params restored"); + } + uint32_t curr = getRTCClock()->getCurrentTime(); if (curr >= last_read_time + SENSOR_READ_INTERVAL_SECS) { telemetry.reset(); diff --git a/examples/simple_sensor/SensorMesh.h b/examples/simple_sensor/SensorMesh.h index 3f687c3f..ea6bec74 100644 --- a/examples/simple_sensor/SensorMesh.h +++ b/examples/simple_sensor/SensorMesh.h @@ -90,6 +90,7 @@ public: } const uint8_t* getSelfIdPubKey() override { return self_id.pub_key; } void clearStats() override { } + void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override; float getTelemValue(uint8_t channel, uint8_t type); @@ -154,6 +155,11 @@ private: int matching_peer_indexes[MAX_SEARCH_RESULTS]; int num_alert_tasks; Trigger* alert_tasks[MAX_CONCURRENT_ALERTS]; + unsigned long set_radio_at, revert_radio_at; + float pending_freq; + float pending_bw; + uint8_t pending_sf; + uint8_t pending_cr; void loadContacts(); void saveContacts(); diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index afb7dfbc..e036f0c0 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -132,7 +132,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch if (memcmp(command, "reboot", 6) == 0) { _board->reboot(); // doesn't return } else if (memcmp(command, "advert", 6) == 0) { - _callbacks->sendSelfAdvertisement(400); + _callbacks->sendSelfAdvertisement(1500); // longer delay, give CLI response time to be sent first strcpy(reply, "OK - Advert sent"); } else if (memcmp(command, "clock sync", 10) == 0) { uint32_t curr = getRTCClock()->getCurrentTime(); @@ -280,19 +280,25 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch strcpy(reply, _prefs->disable_fwd ? "OK - repeat is now OFF" : "OK - repeat is now ON"); } else if (memcmp(config, "radio ", 6) == 0) { strcpy(tmp, &config[6]); - const char *parts[4]; - int num = mesh::Utils::parseTextParts(tmp, parts, 4); + const char *parts[5]; + int num = mesh::Utils::parseTextParts(tmp, parts, 5); float freq = num > 0 ? atof(parts[0]) : 0.0f; float bw = num > 1 ? atof(parts[1]) : 0.0f; uint8_t sf = num > 2 ? atoi(parts[2]) : 0; uint8_t cr = num > 3 ? atoi(parts[3]) : 0; + int temp_timeout_mins = num > 4 ? atoi(parts[4]) : 0; if (freq >= 300.0f && freq <= 2500.0f && sf >= 7 && sf <= 12 && cr >= 5 && cr <= 8 && bw >= 7.0f && bw <= 500.0f) { - _prefs->sf = sf; - _prefs->cr = cr; - _prefs->freq = freq; - _prefs->bw = bw; - _callbacks->savePrefs(); - strcpy(reply, "OK - reboot to apply"); + if (temp_timeout_mins > 0) { + _callbacks->applyTempRadioParams(freq, bw, sf, cr, temp_timeout_mins); + sprintf(reply, "OK - temp params for %d mins", temp_timeout_mins); + } else { + _prefs->sf = sf; + _prefs->cr = cr; + _prefs->freq = freq; + _prefs->bw = bw; + _callbacks->savePrefs(); + strcpy(reply, "OK - reboot to apply"); + } } else { strcpy(reply, "Error, invalid radio params"); } diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index 91a5bd3b..e2608379 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -45,6 +45,7 @@ public: virtual void formatNeighborsReply(char *reply) = 0; virtual const uint8_t* getSelfIdPubKey() = 0; virtual void clearStats() = 0; + virtual void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) = 0; }; class CommonCLI {