Add normalradio to common CLI

This commit is contained in:
mikecarper committed 2026-08-19 12:44:49 -07:00
1 parent 0f64b293f8
commit fec74517ee
12 files changed
+67 -8

No files matched your search

+2 -2
View File
@@ -71,7 +71,7 @@ fix, no WiFi connection, an inactive bridge, or an nRF52 bootloader without
| Logging | [`get/set usb.logging`](cli_commands.md#control-live-usb-logging) | Logging artifacts; session-only live USB output gate | No | Yes | No |
| Radio | [`get radio`; `set radio ...`](cli_commands.md#view-or-change-this-nodes-radio-parameters) | All text CLI roles | Yes | Yes | Yes |
| Radio | [`get tx`; `set tx <dbm>`](cli_commands.md#view-or-change-this-nodes-transmit-power) | Board TX-power limits apply | Yes | Yes | Yes |
| Radio | [`tempradio ...`](cli_commands.md#change-the-radio-parameters-for-a-set-duration) | Full parser | Yes | Yes | Yes |
| Radio | [`tempradio ...`; `normalradio`](cli_commands.md#change-the-radio-parameters-for-a-set-duration) | Full parser | Yes | Yes | Yes |
| Radio | [`get/set/del radioat`; `get/set/del tempradioat`](cli_commands.md#schedule-radio-parameter-changes) | Full parser | Yes | Yes | Yes |
| Radio | [`get freq`; `set freq <mhz>`](cli_commands.md#view-or-change-this-nodes-frequency) | `set` is local serial only | Yes | Yes | Yes |
| Radio | [`get/set radio.rxgain`](cli_commands.md#view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-and-lr1110-v1141) | Supported radio | Feature | Feature | Feature |
@@ -229,7 +229,7 @@ fix, no WiFi connection, an inactive bridge, or an nRF52 bootloader without
| Logging | [`get/set usb.logging`](cli_commands.md#control-live-usb-logging) | Logging artifacts; session-only live USB output gate | No | Yes | No | No | Yes |
| Radio | [`get radio`; `set radio ...`](cli_commands.md#view-or-change-this-nodes-radio-parameters) | All text CLI roles | Yes | Yes | Yes | Yes | Yes |
| Radio | [`get tx`; `set tx <dbm>`](cli_commands.md#view-or-change-this-nodes-transmit-power) | Board TX-power limits apply | Yes | Yes | Yes | Yes | Yes |
| Radio | [`tempradio ...`](cli_commands.md#change-the-radio-parameters-for-a-set-duration) | Full parser | Yes | Yes | Yes | Yes | Yes |
| Radio | [`tempradio ...`; `normalradio`](cli_commands.md#change-the-radio-parameters-for-a-set-duration) | Full parser | Yes | Yes | Yes | Yes | Yes |
| Radio | [`get/set/del radioat`; `get/set/del tempradioat`](cli_commands.md#schedule-radio-parameter-changes) | Full parser | Yes | Yes | Yes | Yes | Yes |
| Radio | [`get freq`; `set freq <mhz>`](cli_commands.md#view-or-change-this-nodes-frequency) | `set` is local serial only | Yes | Yes | Yes | Yes | Yes |
| Radio | [`get/set radio.rxgain`](cli_commands.md#view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-and-lr1110-v1141) | Supported radio | Feature | Feature | Feature | Feature | Feature |
+6 -1
View File
@@ -576,6 +576,7 @@ It also does not change the node-storage capture controlled by `log start` and
#### Change the radio parameters for a set duration
**Usage:**
- `tempradio <freq>,<bw>,<sf>,<cr>,<timeout_mins>`
- `normalradio`
**Parameters:**
- `freq`: Frequency in MHz (150-2500)
@@ -584,7 +585,11 @@ It also does not change the node-storage capture controlled by `log start` and
- `cr`: Coding rate (5-8)
- `timeout_mins`: Duration in minutes (must be > 0)
**Note:** This is not saved to preferences and will clear on reboot
**Notes:**
- `tempradio` is not saved to preferences and clears on reboot.
- `normalradio` cancels pending and active temporary-radio windows, then
restores the saved radio tuple after its CLI reply has drained on the
current channel. Permanent `radioat` entries are not removed.
---
+3 -2
View File
@@ -36,8 +36,9 @@ The fourth value is the transmit coding rate. This guide uses CR5, but the parti
do not need to match.
`tempradio` is not saved and the node returns to its normal radio settings when the window ends or the node
reboots. This frequency is intended for North American configurations. Confirm that it is permitted in your
location and change it when necessary.
reboots. Current full-parser firmware also accepts `normalradio`, which cancels the temporary window and
restores the saved tuple after replying on the current channel. This frequency is intended for North American
configurations. Confirm that it is permitted in your location and change it when necessary.
## Before you start
+9 -3
View File
@@ -287,9 +287,15 @@ different problems.
After step 9 is proven, restore each saved destination and relay value exactly,
including `rxdelay`, RXPS, CPU power saving, `af`, `ota config hops`, and relay
timing. Ordinary repeater firmware does not implement `normalradio`. While the
node is still reachable on the temporary channel, shorten its lease to one
minute with the same tuple:
timing. Current full-parser repeater firmware accepts `normalradio` and restores
the saved tuple after replying on the temporary channel:
```text
normalradio
```
The historical endpoint in this pinned bundle predates that command. If it
replies `Unknown command`, shorten its lease to one minute with the same tuple:
```text
tempradio 909.950,500,5,5,1
+15
View File
@@ -4239,6 +4239,21 @@ void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr,
refreshScheduledRadioState();
}
bool MyMesh::scheduleNormalRadio() {
// Cancel every pending/active temporary entry, but leave permanent radioat
// changes intact. The saved apply waits for the CLI reply to leave the
// outbound queue before changing modulation parameters.
for (int i = 0; i < MAX_SCHEDULED_RADIO_SETTINGS; i++) {
if (!scheduled_radio_settings[i].temporary) continue;
scheduled_radio_settings[i].active = false;
scheduled_radio_settings[i].started = false;
}
temp_radio_handoff_pending = false;
refreshScheduledRadioState();
queueSavedRadioApply();
return true;
}
bool MyMesh::formatFileSystem() {
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
return InternalFS.format();
+1
View File
@@ -869,6 +869,7 @@ public:
// CommonCLICallbacks
void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override;
bool scheduleNormalRadio() override;
#if defined(ESP32_PLATFORM) || defined(USER_GPIO_CONTROL)
uint32_t getUserGpioRequestSource() const override {
return _gpio_reply_tracker.requestSource();
+10
View File
@@ -1443,6 +1443,16 @@ void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr,
revert_radio_at = futureMillis(2000 + timeout_mins * 60 * 1000); // schedule when to revert radio params
}
bool MyMesh::scheduleNormalRadio() {
// A one-tick deadline cancels a not-yet-applied window or restores an active
// one as soon as the command reply has drained from the outbound queue.
set_radio_at = 0;
revert_radio_at = futureMillis(1);
radio_apply_retry_at = 0;
radio_apply_failures = 0;
return true;
}
bool MyMesh::formatFileSystem() {
#if defined(NRF52_PLATFORM)
return InternalFS.format();
+1
View File
@@ -371,6 +371,7 @@ public:
// CommonCLICallbacks
void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override;
bool scheduleNormalRadio() override;
#if defined(ESP32_PLATFORM) || defined(USER_GPIO_CONTROL)
uint32_t getUserGpioRequestSource() const override {
return _gpio_reply_tracker.requestSource();
+10
View File
@@ -1062,6 +1062,16 @@ void SensorMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t
revert_radio_at = futureMillis(2000 + timeout_mins*60*1000); // schedule when to revert radio params
}
bool SensorMesh::scheduleNormalRadio() {
// Keep the reply on the current tuple, then let the existing safe restore
// path wait for an idle outbound queue before touching the radio.
set_radio_at = 0;
revert_radio_at = futureMillis(1);
radio_apply_retry_at = 0;
radio_apply_failures = 0;
return true;
}
void SensorMesh::sendSelfAdvertisement(int delay_millis, bool flood) {
mesh::Packet* pkt = createSelfAdvert();
if (pkt) {
+1
View File
@@ -93,6 +93,7 @@ public:
void saveIdentity(const mesh::LocalIdentity& new_id) override;
void clearStats() override { }
void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override;
bool scheduleNormalRadio() override;
#if defined(ESP32_PLATFORM) || defined(USER_GPIO_CONTROL)
uint32_t getUserGpioRequestSource() const override {
return _gpio_reply_tracker.requestSource();
+6
View File
@@ -2369,6 +2369,12 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
} else {
strcpy(reply, "ERR: bad pubkey");
}
} else if (strcmp(command, "normalradio") == 0) {
if (_callbacks->scheduleNormalRadio()) {
strcpy(reply, "OK - normal radio restore scheduled");
} else {
strcpy(reply, "Error: unsupported");
}
} else if (memcmp(command, "tempradio ", 10) == 0) {
strcpy(tmp, &command[10]);
const char *parts[5];
+3
View File
@@ -442,6 +442,9 @@ public:
virtual void saveIdentity(const mesh::LocalIdentity& new_id) = 0;
virtual void clearStats() = 0;
virtual void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) = 0;
// Cancel pending/active temporary-radio windows and restore the saved tuple
// after the command reply has drained on the current channel.
virtual bool scheduleNormalRadio() { return false; }
#if defined(ENABLE_OTA)
virtual bool isTempRadioActive() const { return false; }
#endif