Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions examples/companion_radio/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1811,9 +1811,17 @@ void MyMesh::enterCLIRescue() {
_cli_rescue = true;
cli_command[0] = 0;
Serial.println("========= CLI Rescue =========");
Serial.println("Commands: set pin <n>, rebuild, erase, reboot, ls, cat, rm");
#ifdef WIFI_SSID
Serial.println("WiFi: wifi_ssid <ssid>, wifi_pwd <pwd>, wifi_commit, wifi_clear");
#endif
}

void MyMesh::checkCLIRescueCmd() {
#ifdef WIFI_SSID
static char staged_ssid[33] = {0};
static char staged_pwd[65] = {0};
#endif
int len = strlen(cli_command);
while (Serial.available() && len < sizeof(cli_command)-1) {
char c = Serial.read();
Expand Down Expand Up @@ -1975,6 +1983,40 @@ void MyMesh::checkCLIRescueCmd() {

}

#ifdef WIFI_SSID
} else if (memcmp(cli_command, "wifi_ssid ", 10) == 0) {
strncpy(staged_ssid, &cli_command[10], sizeof(staged_ssid) - 1);
staged_ssid[sizeof(staged_ssid) - 1] = 0;
Serial.printf(" > SSID staged: \"%s\" (not saved yet, use wifi_commit)\n", staged_ssid);
} else if (memcmp(cli_command, "wifi_pwd ", 9) == 0) {
strncpy(staged_pwd, &cli_command[9], sizeof(staged_pwd) - 1);
staged_pwd[sizeof(staged_pwd) - 1] = 0;
Serial.println(" > Password staged (not saved yet, use wifi_commit)");
} else if (strcmp(cli_command, "wifi_commit") == 0) {
if (staged_ssid[0] == 0 || staged_pwd[0] == 0) {
Serial.println(" Error: stage both wifi_ssid and wifi_pwd before committing");
} else {
File f = _store->getPrimaryFS()->open("/wifi_config", "w", true);
if (f) {
f.print(staged_ssid); f.print('\n');
f.print(staged_pwd); f.print('\n');
f.close();
Serial.printf(" > Saved SSID \"%s\" to flash, rebooting...\n", staged_ssid);
board.reboot();
} else {
Serial.println(" Error: failed to write /wifi_config");
}
}
} else if (strcmp(cli_command, "wifi_clear") == 0) {
_store->getPrimaryFS()->remove("/wifi_config");
Serial.println(" > /wifi_config removed, using compiled-in defaults on next boot, rebooting...");
board.reboot();
} else if (strcmp(cli_command, "wifi_show") == 0) {
Serial.printf(" Staged SSID: \"%s\"\n", staged_ssid[0] ? staged_ssid : "(none)");
Serial.printf(" Staged PWD: %s\n", staged_pwd[0] ? "(set)" : "(none)");
bool has_config = _store->getPrimaryFS()->exists("/wifi_config");
Serial.printf(" /wifi_config on flash: %s\n", has_config ? "yes" : "no (using compiled-in defaults)");
#endif
} else if (strcmp(cli_command, "reboot") == 0) {
board.reboot(); // doesn't return
} else {
Expand Down
68 changes: 67 additions & 1 deletion examples/companion_radio/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store

/* END GLOBAL OBJECTS */

#ifdef WIFI_SSID
static char _wifi_ssid[33];
static char _wifi_pwd[65];
#endif

void halt() {
while (1) ;
}
Expand Down Expand Up @@ -195,7 +200,29 @@ void setup() {

#ifdef WIFI_SSID
board.setInhibitSleep(true); // prevent sleep when WiFi is active
WiFi.begin(WIFI_SSID, WIFI_PWD);

// Load credentials from flash if provisioned via CLI rescue; fall back to compiled-in defaults
strncpy(_wifi_ssid, WIFI_SSID, sizeof(_wifi_ssid) - 1);
strncpy(_wifi_pwd, WIFI_PWD, sizeof(_wifi_pwd) - 1);
{
File wf = SPIFFS.open("/wifi_config", "r");
if (wf) {
int n = wf.readBytesUntil('\n', _wifi_ssid, sizeof(_wifi_ssid) - 1);
if (n > 0 && _wifi_ssid[n - 1] == '\r') n--; // strip \r if present
_wifi_ssid[n] = 0;
n = wf.readBytesUntil('\n', _wifi_pwd, sizeof(_wifi_pwd) - 1);
if (n > 0 && _wifi_pwd[n - 1] == '\r') n--; // strip \r if present
_wifi_pwd[n] = 0;
wf.close();
WIFI_DEBUG_PRINTLN("Loaded credentials from flash, SSID: %s", _wifi_ssid);
} else {
WIFI_DEBUG_PRINTLN("No /wifi_config found, using compiled-in SSID: %s", _wifi_ssid);
}
}

WiFi.persistent(false); // don't use/overwrite NVS-cached credentials
WiFi.mode(WIFI_STA);
WiFi.begin(_wifi_ssid, _wifi_pwd);
serial_interface.begin(TCP_PORT);
#elif defined(BLE_PIN_CODE)
serial_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name, the_mesh.getBLEPin());
Expand All @@ -218,11 +245,50 @@ void setup() {
#endif
}

#if defined(WIFI_SSID) && defined(ESP32)
static void wifi_reconnect_check() {
constexpr uint32_t CHECK_INTERVAL_MS = 5000;
constexpr uint32_t RECONNECT_AFTER_MS = 30000;

static uint32_t last_check = 0;
static uint32_t down_since = 0;

if (millis() - last_check < CHECK_INTERVAL_MS) return;
last_check = millis();

if (WiFi.status() == WL_CONNECTED) {
if (down_since != 0) {
WIFI_DEBUG_PRINTLN("Connected to %s, IP: %s", _wifi_ssid, WiFi.localIP().toString().c_str());
}
down_since = 0;
return;
}

if (down_since == 0) {
down_since = millis();
WIFI_DEBUG_PRINTLN("WiFi disconnected, waiting to reconnect...");
return;
}

if (millis() - down_since >= RECONNECT_AFTER_MS) {
WIFI_DEBUG_PRINTLN("WiFi reconnecting...");
WiFi.disconnect(true);
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(_wifi_ssid, _wifi_pwd);
down_since = 0;
}
}
#endif

void loop() {
the_mesh.loop();
sensors.loop();
#ifdef DISPLAY_CLASS
ui_task.loop();
#endif
rtc_clock.tick();
#ifdef WIFI_SSID
wifi_reconnect_check();
#endif
}