diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 40f1ceeb..bfb31075 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -231,6 +231,17 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no file.read((uint8_t *)&_prefs.autoadd_config, sizeof(_prefs.autoadd_config)); // 87 file.read((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)); // 88 file.read((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89 + if (file.available() >= (int)sizeof(_prefs.wifi_powersave)) { + file.read((uint8_t *)&_prefs.wifi_powersave, sizeof(_prefs.wifi_powersave)); // 90 + } + if (file.available() >= (int)sizeof(_prefs.wifi_ssid)) { + file.read((uint8_t *)_prefs.wifi_ssid, sizeof(_prefs.wifi_ssid)); // 91 + _prefs.wifi_ssid[sizeof(_prefs.wifi_ssid) - 1] = 0; + } + if (file.available() >= (int)sizeof(_prefs.wifi_pwd)) { + file.read((uint8_t *)_prefs.wifi_pwd, sizeof(_prefs.wifi_pwd)); // 124 + _prefs.wifi_pwd[sizeof(_prefs.wifi_pwd) - 1] = 0; + } file.close(); } @@ -269,6 +280,9 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_ file.write((uint8_t *)&_prefs.autoadd_config, sizeof(_prefs.autoadd_config)); // 87 file.write((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)); // 88 file.write((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89 + file.write((uint8_t *)&_prefs.wifi_powersave, sizeof(_prefs.wifi_powersave)); // 90 + file.write((uint8_t *)_prefs.wifi_ssid, sizeof(_prefs.wifi_ssid)); // 91 + file.write((uint8_t *)_prefs.wifi_pwd, sizeof(_prefs.wifi_pwd)); // 124 file.close(); } diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 60a5a75f..ca254a50 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -2,6 +2,9 @@ #include // needed for PlatformIO #include +#if defined(ESP32) + #include +#endif #define CMD_APP_START 1 #define CMD_SEND_TXT_MSG 2 @@ -141,6 +144,49 @@ #define AUTO_ADD_ROOM_SERVER (1 << 3) // 0x08 - auto-add Room Server (ADV_TYPE_ROOM) #define AUTO_ADD_SENSOR (1 << 4) // 0x10 - auto-add Sensor (ADV_TYPE_SENSOR) +#if defined(ESP32) +static wifi_ps_type_t toEspPowerSave(uint8_t mode) { + switch (mode) { + case 1: + return WIFI_PS_MIN_MODEM; + case 2: + return WIFI_PS_MAX_MODEM; + default: + return WIFI_PS_NONE; + } +} + +static const char* getPowerSaveLabel(uint8_t mode) { + switch (mode) { + case 1: + return "min"; + case 2: + return "max"; + default: + return "none"; + } +} + +static const char* getWifiStateLabel(wl_status_t status) { + switch (status) { + case WL_CONNECTED: + return "connected"; + case WL_NO_SSID_AVAIL: + return "no_ssid"; + case WL_CONNECT_FAILED: + return "connect_failed"; + case WL_CONNECTION_LOST: + return "connection_lost"; + case WL_DISCONNECTED: + return "disconnected"; + case WL_IDLE_STATUS: + return "idle"; + default: + return "unknown"; + } +} +#endif + void MyMesh::writeOKFrame() { uint8_t buf[1]; buf[0] = RESP_CODE_OK; @@ -868,6 +914,17 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe _prefs.rx_boosted_gain = 1; // enabled by default #endif #endif +#if defined(ESP32) + _prefs.wifi_powersave = 0; + _prefs.wifi_ssid[0] = 0; + _prefs.wifi_pwd[0] = 0; + #ifdef WIFI_SSID + StrHelper::strncpy(_prefs.wifi_ssid, WIFI_SSID, sizeof(_prefs.wifi_ssid)); + #endif + #ifdef WIFI_PWD + StrHelper::strncpy(_prefs.wifi_pwd, WIFI_PWD, sizeof(_prefs.wifi_pwd)); + #endif +#endif } void MyMesh::begin(bool has_display) { @@ -1934,9 +1991,74 @@ void MyMesh::checkCLIRescueCmd() { _prefs.ble_pin = atoi(&config[4]); savePrefs(); Serial.printf(" > pin is now %06d\n", _prefs.ble_pin); +#if defined(ESP32) + } else if (memcmp(config, "wifi.ssid ", 10) == 0) { + StrHelper::strncpy(_prefs.wifi_ssid, &config[10], sizeof(_prefs.wifi_ssid)); + savePrefs(); + if (_prefs.wifi_ssid[0]) { + WiFi.mode(WIFI_STA); + WiFi.setSleep(toEspPowerSave(_prefs.wifi_powersave)); + WiFi.begin(_prefs.wifi_ssid, _prefs.wifi_pwd); + } + Serial.printf(" > wifi.ssid is now: %s\n", _prefs.wifi_ssid[0] ? _prefs.wifi_ssid : "-"); + } else if (memcmp(config, "wifi.pwd ", 9) == 0) { + StrHelper::strncpy(_prefs.wifi_pwd, &config[9], sizeof(_prefs.wifi_pwd)); + savePrefs(); + if (_prefs.wifi_ssid[0]) { + WiFi.mode(WIFI_STA); + WiFi.setSleep(toEspPowerSave(_prefs.wifi_powersave)); + WiFi.begin(_prefs.wifi_ssid, _prefs.wifi_pwd); + } + Serial.println(" > wifi.pwd updated"); + } else if (memcmp(config, "wifi.powersaving ", 17) == 0) { + uint8_t next_mode = 0xFF; + if (strcmp(&config[17], "none") == 0) { + next_mode = 0; + } else if (strcmp(&config[17], "min") == 0) { + next_mode = 1; + } else if (strcmp(&config[17], "max") == 0) { + next_mode = 2; + } + if (next_mode <= 2) { + _prefs.wifi_powersave = next_mode; + savePrefs(); + WiFi.setSleep(toEspPowerSave(_prefs.wifi_powersave)); + Serial.printf(" > wifi.powersaving is now: %s\n", getPowerSaveLabel(_prefs.wifi_powersave)); + } else { + Serial.println(" Error: bad wifi.powersaving"); + } +#endif } else { Serial.printf(" Error: unknown config: %s\n", config); } + } else if (strcmp(cli_command, "get wifi.ssid") == 0) { +#if defined(ESP32) + Serial.printf(" > %s\n", _prefs.wifi_ssid[0] ? _prefs.wifi_ssid : "-"); +#else + Serial.println(" Error: wifi unsupported"); +#endif + } else if (strcmp(cli_command, "get wifi.powersaving") == 0) { +#if defined(ESP32) + Serial.printf(" > %s\n", getPowerSaveLabel(_prefs.wifi_powersave)); +#else + Serial.println(" Error: wifi unsupported"); +#endif + } else if (strcmp(cli_command, "get wifi.status") == 0) { +#if defined(ESP32) + wl_status_t status = WiFi.status(); + if (_prefs.wifi_ssid[0] == 0) { + Serial.println(" > ssid:- status:off code:255 state:unconfigured"); + } else if (status == WL_CONNECTED) { + Serial.printf(" > ssid:%s status:connected code:%d state:%s ip:%s\n", _prefs.wifi_ssid, + static_cast(status), getWifiStateLabel(status), WiFi.localIP().toString().c_str()); + } else { + const char* overall = (status == WL_IDLE_STATUS) ? "connecting" : "disconnected"; + Serial.printf(" > ssid:%s status:%s code:%d state:%s\n", _prefs.wifi_ssid, overall, + static_cast(status), getWifiStateLabel(status)); + } +#else + Serial.println(" Error: wifi unsupported"); +#endif } else if (strcmp(cli_command, "rebuild") == 0) { bool success = _store->formatFileSystem(); if (success) { diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index 3b02f5f6..0b17a509 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -94,6 +94,11 @@ public: const char *getNodeName(); NodePrefs *getNodePrefs(); uint32_t getBLEPin(); +#if defined(ESP32) + const char* getWifiSSID() const { return _prefs.wifi_ssid; } + const char* getWifiPassword() const { return _prefs.wifi_pwd; } + uint8_t getWifiPowerSaveMode() const { return _prefs.wifi_powersave; } +#endif void loop(); void handleCmdFrame(size_t len); diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index 557be306..66817f88 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -32,4 +32,7 @@ struct NodePrefs { // persisted to file uint8_t client_repeat; uint8_t path_hash_mode; // which path mode to use when sending uint8_t autoadd_max_hops; // 0 = no limit, 1 = direct (0 hops), N = up to N-1 hops (max 64) -}; \ No newline at end of file + uint8_t wifi_powersave; // 0 = none, 1 = min, 2 = max + char wifi_ssid[33]; + char wifi_pwd[65]; +}; diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 876dc9c3..e3ffbf63 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -195,7 +195,11 @@ void setup() { #ifdef WIFI_SSID board.setInhibitSleep(true); // prevent sleep when WiFi is active - WiFi.begin(WIFI_SSID, WIFI_PWD); + WiFi.mode(WIFI_STA); + WiFi.setSleep(static_cast(the_mesh.getWifiPowerSaveMode())); + if (the_mesh.getWifiSSID()[0]) { + WiFi.begin(the_mesh.getWifiSSID(), the_mesh.getWifiPassword()); + } serial_interface.begin(TCP_PORT); #elif defined(BLE_PIN_CODE) serial_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name, the_mesh.getBLEPin());