Texting new wifi AP array.

..and other smaller new features.

Signed-off-by: Thomas Osterried <dl9sau@darc.de>
pull/7/head
Thomas Osterried 2022-12-15 09:16:37 +01:00
rodzic fa05b426d9
commit 58322019ca
5 zmienionych plików z 398 dodań i 194 usunięć

Wyświetl plik

@ -1,7 +1,15 @@
{
"SSID1": "EnterSSIDofYourAccesspoint",
"password1": "EnterPasswordofYourAccesspoint"
"SSID2": "EnterSSIDofYour2ndAccesspoint",
"password2": "EnterPasswordofYour2ndAccesspoint",
"ap_password": "xxxxxxxxxx"
"AP": [
{
"SSID": "EnterSSIDofYourAccesspoint",
"password": "EnterPasswordofYourAccesspoint",
"prio": 1
},
{
"SSID": "EnterSSIDofYour2ndAccesspoint",
"password": "EnterPasswordofYour2ndAccesspoint"
}
],
"SelfAP_PW": "xxxxxxxxxx"
}

Wyświetl plik

@ -648,6 +648,9 @@
<div class="grid-container full">
Click <a href="/cfg">here</a> to view (backup) your current settings.
</div>
<div class="grid-container full">
Click <a href="/wificfg">here</a> to view your configured wifi settings.
</div>
<div class="grid-container full">
<h5 class="u-full-width">Firmware update</h5>
</div>
@ -672,6 +675,17 @@
</div>
</form>
</div>
<div class="grid-container full">
<h5 class="u-full-width">Save configuration</h5>
</div>
<div class="grid-container full">
Save Wifi configuration to tracker's filesystem (/wifi.cfg)
<form action="/savewifi2fs" method="post">
<div>
<input class="button-primary" type="submit" value="savewifi2fs">
</div>
</form>
</div>
</article>
</section>
<section>
@ -754,18 +768,20 @@
</ul>
data/wifi.cfg<br>
<ul>
<li>wifi.cfg has to be created manually, following the json structure in the example. The names of the variables (aka keys) must not be altered</li>
<li>wifi.cfg in the directory data contains an SSID and password of the AP for the second try described above</li>
<li>the total length of this file must not exceed 256 Byte. The password must not be shorter that 8 byte. The json structure must not be changed</li>
<li>if something is wrong or the file is missing, the complete file will be ignored and step 2 (above) will be skipped</li>
<li>To upload wifi.cfg to your board you have to do this via Upload File System image in PlatformIO!</li>
<li>wifi.cfg can to be created manually, following the json structure in the example. The names of the variables (aka keys) must not be altered</li>
<li>The preferred way is to upgrade the firmware to the newest version, make sure, that the wifi credentials are set correctly and then press the SAVEWIFI2FS Button</li>
<li>The content, what will be saved, can be viewed above.</li>
<li>wifi.cfg in the directory data contains SSID and password of up to 10 AP and a password for the local accesspoint</li>
<li>The password must not be shorter that 8 byte. The json structure must not be changed</li>
<li>if something is wrong or the file is missing, the complete file will be ignored. If credentials are available in flash memory, they will be used.</li>
<li>An alternative to upload wifi.cfg to your board is via Upload File System image in PlatformIO!</li>
<li>To find the 'Upload File System image' click the PlatformIO symbol (the little alien) on the left side, choose your configuration, click on 'Platform' and search for 'Upload File System image'. If you use platformio-cli, upload the filesystem as described below.</li>
</ul>
which WiFi is selected?<br/>
<ul>
<li>first, the SSID which is configured via the WebSite will be searched, this SSID should match SSID1 in the file</li>
<li>second, if that SSID is not found, the WiFi configured as SSID2 in data/wifi.cfg will be searched</li>
<li>third, if that SSID is also not found, a local accesspoint with the SSID "call AP" will be created. After connected to, this Webserver will be reachable with the IP Address 192.168.4.1. The password for the selfAP can be preconfigured with the key "ap_password" in this file</li>
<li>An AP entry containing the keyword "prio":1 defines the entry which is taken as first to connect before following the configured order</li>
<li>if there is nothing prioritized, then the configured order is followed. If credentials are available in flash memory, they will be used first.</li>
<li>if no connection to a configured AP could be established, a local accesspoint with the SSID "call AP" will be created. After connected to, this Webserver will be reachable with the IP Address 192.168.4.1. The password for the selfAP can be preconfigured with the key "ap_password" in this file</li>
</ul>
data/preferences.cfg<br>
<ul>

Wyświetl plik

@ -27,5 +27,12 @@ typedef struct {
extern QueueHandle_t webListReceivedQueue;
// structure for AP Array
struct AccessPoint {
char ssid[33];
char pw[64];
//uint8_t prio;
};
[[noreturn]] void taskWebServer(void *parameter);
#endif
#endif

Wyświetl plik

@ -215,12 +215,16 @@ boolean always_send_cseSpd_AND_altitude = false;
boolean webserverStarted = false;
boolean tncServer_enabled = false;
boolean gpsServer_enabled = false;
// Mapping Table {Power, max_tx_power} = {{8, 2}, {20, 5}, {28, 7}, {34, 8}, {44, 11}, {52, 13}, {56, 14}, {60, 15}, {66, 16}, {72, 18}, {80,20}}.
// We'll use "min", "low", "mid", "high", "max" -> 2dBm (1.5mW) -> 8, 11dBm (12mW) -> 44, 15dBm (32mW) -> 60, 18dBm (63mW) ->72, 20dBm (100mW) ->80
// Mapping Table {Power, max_tx_power} = {{8, 2}, {20, 5}, {28, 7}, {34, 8}, {44, 11}, {52, 13}, {56, 14}, {60, 15}, {66, 16}, {72, 18}, {80,20}}.
// We'll use "min", "low", "mid", "high", "max" -> 2dBm (1.5mW) -> 8, 11dBm (12mW) -> 44, 15dBm (32mW) -> 60, 18dBm (63mW) ->72, 20dBm (100mW) ->80
int8_t wifi_txpwr_mode_AP = 8;
int8_t wifi_txpwr_mode_STA = 80;
String preferences_as_jsonData;
extern void refill_preferences_as_jsonData();
#else
void refill_preferences_as_jsonData() { ; };
#endif
#ifdef ENABLE_PREFERENCES
String preferences_as_jsonData;
#endif
#ifdef ENABLE_OLED
boolean enabled_oled = true;
@ -321,13 +325,15 @@ int8_t wifi_connection_status_prev = -1;
String oled_wifi_SSID_curr = "";
String oled_wifi_PASS_curr = "";
String oled_wifi_IP_curr = "";
// needed here for SPIFFS WLAN Credentials:
String wifi_ModeAP_SSID;
String wifi_ModeAP_PASS;
String wifi_ModeSTA_SSID;
String wifi_ModeSTA_PASS;
// comes for SPIFFS WLAN Credentials:
String wifi_ModeSTA_SSID_fallback;
String wifi_ModeSTA_PASS_fallback;
// AP Array, currently max 10 APs possible
#define MAX_AP_CNT 10 // max number of possible APs
struct AccessPoint APs[MAX_AP_CNT];
int apcnt = 0;
#endif
#define JSON_MAX_FILE_SIZE 2560
@ -1291,9 +1297,33 @@ void sendTelemetryFrame() {
#endif
// SPIFFS for wifi.cfg, preferences.cfg, ..
#ifdef ENABLE_WIFI
// setup wifi variables. AP-array: first element with preferences from flash. increase apcnt if successfull.
void init_wifi_STA_and_AP_settings() {
wifi_ModeSTA_SSID = "";
wifi_ModeSTA_PASS = "";
apcnt = 0;
if (!preferences.getString(PREF_WIFI_PASSWORD, "").isEmpty() & !preferences.getString(PREF_WIFI_SSID, "").isEmpty()) {
// save old wifi credentials on pos 1, assuming that thhis is the best chance to reconnect
wifi_ModeSTA_PASS = preferences.getString(PREF_WIFI_PASSWORD, "");
wifi_ModeSTA_SSID = preferences.getString(PREF_WIFI_SSID, "");
strncpy(APs[apcnt].ssid, wifi_ModeSTA_SSID.c_str(),sizeof(APs[apcnt].ssid)-1);
strncpy(APs[apcnt].pw, wifi_ModeSTA_PASS.c_str(),sizeof(APs[apcnt].pw)-1);
Serial.printf("Preferences AP %s found with PW %s and stored at pos %d\r\n", APs[apcnt].ssid, APs[apcnt].pw, apcnt);
apcnt = 1;
}
if (!preferences.getString(PREF_AP_PASSWORD, "").isEmpty()) {
wifi_ModeAP_PASS = preferences.getString(PREF_AP_PASSWORD, "");
Serial.printf("Preferences Self-AP PW found %s and stored\r\n", wifi_ModeAP_PASS.c_str());
}
}
#endif // ENABLE_WIFI
// SPIFFS for wifi.cfg
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
// currently not use, uncomment at the end of setup() to see what is on the disk
Serial.printf("Listing directory: %s\r\n", dirname);
File root = fs.open(dirname);
@ -1308,16 +1338,19 @@ void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
}
File file = root.openNextFile();
while (file){
if (file.isDirectory()) {
Serial.print(" DIR : ");
while (file) {
if (file.isDirectory()) {
Serial.print(" DIR : ");
Serial.println(file.name());
if (levels){
listDir(fs, file.name(), levels -1);
}
if (levels){
listDir(fs, file.name(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
if (strlen(file.name()) < 12) {
Serial.print("\t");
}
Serial.print("\tSIZE: ");
Serial.println(file.size());
}
@ -1364,7 +1397,7 @@ int save_to_file(const String &callername, const char *filename, const String &j
// readFile - is more than reading a file from flash. It reads and parses json data in the file and assigns some of our variables.
// The correct function name would be readFile_parseJson_and_assignVariable(). This is would be too ugly.
boolean readFile(fs::FS &fs, const char *filename) {
//#define JSON_MAX_FILE_SIZE 256ß
//#define JSON_MAX_FILE_SIZE 2560
//static StaticJsonDocument<JSON_MAX_FILE_SIZE> JSONBuffer; //Memory pool
//best would be, that readFile returns a pointer to the local JSONBuffer on success, else NULL
boolean err = false;
@ -1406,7 +1439,7 @@ boolean readFile(fs::FS &fs, const char *filename) {
auto error = deserializeJson(JSONBuffer, JSONMessage);
if (error) {
Serial.print(F("deserializeJson() failed with code "));
Serial.print(F("readFile: deserializeJson() failed with code "));
Serial.println(error.c_str());
err = true;
goto end;
@ -1414,64 +1447,122 @@ boolean readFile(fs::FS &fs, const char *filename) {
#ifdef ENABLE_WIFI
if (!strcmp(filename, "/wifi.cfg")) {
String wifi_ssid_old = "";
String wifi_password_old = "";
// read old data structure, if available
const char *p;
if (JSONBuffer.containsKey("SSID1") && JSONBuffer.containsKey("password1")) {
if ((p = JSONBuffer["SSID1"]))
wifi_ModeSTA_SSID = String(p);
wifi_ssid_old = String(p);
if ((p = JSONBuffer["password1"]))
wifi_ModeSTA_PASS = String(p);
wifi_password_old = String(p);
if (!wifi_ssid_old.length() || wifi_password_old.length() < 8 || wifi_ssid_old == "EnterSSIDofYourAccesspoint") {
wifi_ssid_old = "";
wifi_password_old = "";
} else {
if (apcnt < MAX_AP_CNT && strcmp(wifi_ssid_old.c_str(), wifi_ModeSTA_SSID.c_str()) && strcmp(wifi_password_old.c_str(), wifi_ModeSTA_PASS.c_str())) {
strncpy(APs[apcnt].ssid, wifi_ssid_old.c_str(), sizeof(APs[apcnt].ssid)-1);
strncpy(APs[apcnt].pw, wifi_password_old.c_str(), sizeof(APs[apcnt].pw)-1);
Serial.printf("readFile: wifi.cfg, old structure AP %s found with PW %s (%d)\r\n", APs[apcnt].ssid, APs[apcnt].pw,apcnt);
apcnt++;
} else {
Serial.printf("readFile: wifi.cfg, Preferences AP %s found with PW %s in wifi.cfg and not stored again\r\n", wifi_ModeSTA_SSID.c_str(), wifi_ModeSTA_PASS.c_str());
}
}
}
if (JSONBuffer.containsKey("SSID2") && JSONBuffer.containsKey("password2")) {
if ((p = JSONBuffer["SSID2"]))
wifi_ModeSTA_SSID_fallback = String(p);
wifi_ssid_old = String(p);
if ((p = JSONBuffer["password2"]))
wifi_ModeSTA_PASS_fallback = String(p);
wifi_password_old = String(p);
if (!wifi_ssid_old.length() || wifi_password_old.length() < 8 || wifi_ssid_old == "EnterSSIDofYourAccesspoint") {
wifi_ssid_old = "";
wifi_password_old = "";
} else {
if (apcnt < MAX_AP_CNT && strcmp(wifi_ssid_old.c_str(), wifi_ModeSTA_SSID.c_str()) && strcmp(wifi_password_old.c_str(), wifi_ModeSTA_PASS.c_str())) {
strncpy(APs[apcnt].ssid, wifi_ssid_old.c_str(),sizeof(APs[apcnt].ssid)-1);
strncpy(APs[apcnt].pw, wifi_password_old.c_str(),sizeof(APs[apcnt].pw)-1);
Serial.printf("readFile: wifi.cfg, old structure AP %s found with PW %s (%d)\r\n", APs[apcnt].ssid, APs[apcnt].pw,apcnt);
apcnt++;
} else {
Serial.printf("readFile: wifi.cfg, Preferences AP %s found with PW %s in wifi.cfg and not stored again\r\n", wifi_ModeSTA_SSID.c_str(), wifi_ModeSTA_PASS.c_str());
}
}
}
if (JSONBuffer.containsKey("ap_password") && (p = JSONBuffer["ap_password"])) {
wifi_ModeAP_PASS = String(p);
// Key for self AP password: new syntax: "SelfAP_PW" ; old syntax: "ap_password"
if ( (JSONBuffer.containsKey("SelfAP_PW") && (p = JSONBuffer["SelfAP_PW"])) ||
(JSONBuffer.containsKey("ap_password") && (p = JSONBuffer["ap_password"])) ) {
String ap_password = String(p);
if (ap_password.length() && ap_password.length() > 7) {
wifi_ModeAP_PASS = ap_password;
Serial.printf("readFile: wifi.cfg, valid Self-AP PW to be used %s\r\n", wifi_ModeAP_PASS.c_str());
}
}
if (JSONBuffer.containsKey("AP")) {
for (JsonObject AccessPoint : JSONBuffer["AP"].as<JsonArray>()) {
if (strcmp(AccessPoint["SSID"], wifi_ModeSTA_SSID.c_str()) && strcmp(AccessPoint["password"], wifi_ModeSTA_PASS.c_str())) {
strncpy(APs[apcnt].ssid, AccessPoint["SSID"], sizeof(APs[apcnt].ssid)-1);
strncpy(APs[apcnt].pw, AccessPoint["password"], sizeof(APs[apcnt].pw)-1);
// delay(3000); // uncomment if serial prints are not showing
// uncomment if you need to see the content of the data on SPIFFS
// Serial.printf("readFile: content JSON: [%d] [%s %s]\r\n", apcnt, APs[apcnt].ssid, APs[apcnt].pw);
if (!wifi_ModeSTA_SSID.length() || wifi_ModeSTA_PASS.length() < 8 || wifi_ModeSTA_SSID == "EnterSSIDofYourAccesspoint") {
Serial.println("SSID: " + wifi_ModeSTA_SSID + " missing or PW: " + wifi_ModeSTA_PASS + " < 8 Byte, Filesize: " + String(file.size()));
wifi_ModeSTA_SSID = "";
wifi_ModeSTA_PASS = "";
if (!sizeof(APs[apcnt].ssid) || sizeof(APs[apcnt].pw) < 8 || !strcmp(APs[apcnt].ssid, "EnterSSIDofYourAccesspoint") || !strcmp(APs[apcnt].ssid, "EnterSSIDofYour2ndAccesspoint")) {
delay(3000); // something is wrong, make sure, that msg is displayed
Serial.printf("readFile: SSID: %s missing or PW: %s < 8 Byte, Filesize: %d\r\n", APs[apcnt].ssid,APs[apcnt].pw,file.size());
} else {
if (!apcnt) {
// take first configured AP as active, if nothing has been found in flash
// keyword "prio=1" will override
wifi_ModeSTA_SSID = String(APs[apcnt].ssid);
wifi_ModeSTA_PASS = String(APs[apcnt].pw);
} else {
if (AccessPoint["prio"]) {
strcpy(APs[0].ssid, APs[apcnt].ssid);
strcpy(APs[0].pw, APs[apcnt].pw);
strcpy(APs[apcnt].ssid, wifi_ModeSTA_SSID.c_str());
strcpy(APs[apcnt].pw, wifi_ModeSTA_PASS.c_str());
wifi_ModeSTA_SSID = String(APs[0].ssid);
wifi_ModeSTA_PASS = String(APs[0].pw);
}
}
Serial.printf("readFile: wifi.cfg, valid AP %s found with PW %s (%d)\r\n", APs[apcnt].ssid, APs[apcnt].pw,apcnt);
apcnt++;
}
} else {
Serial.printf("readFile: wifi.cfg, Preferences AP %s found with PW %s in wifi.cfg and not stored again\r\n", wifi_ModeSTA_SSID.c_str(), wifi_ModeSTA_PASS.c_str());
}
if (apcnt == MAX_AP_CNT) {
Serial.printf("readFile: wifi.cfg, maximum Number of possible APs (%d) reached.\r\n", MAX_AP_CNT);
break;
}
}
} else {
Serial.println("SSID: " + wifi_ModeSTA_SSID + ", PW: " + wifi_ModeSTA_PASS + ", Filesize: " + String(file.size()));
delay(3000); // something is wrong, make sure, that msg is displayed
Serial.println("readFile: wifi.cfg, no valid AP found)");
}
if (!wifi_ModeSTA_SSID_fallback.length() || wifi_ModeSTA_PASS_fallback.length() < 8 || wifi_ModeSTA_SSID_fallback == "EnterSSIDofYourAccesspoint") {
Serial.println("Fallback-SSID: " + wifi_ModeSTA_SSID_fallback + " missing or PW: " + wifi_ModeSTA_PASS_fallback + " < 8 Byte, Filesize: " + String(file.size()));
wifi_ModeSTA_SSID_fallback = "";
wifi_ModeSTA_PASS_fallback = "";
} else {
Serial.println("Fallback SSID: " + wifi_ModeSTA_SSID_fallback + ", PW: " + wifi_ModeSTA_PASS_fallback + ", Filesize: " + String(file.size()));
}
if (!wifi_ModeAP_PASS.length() || wifi_ModeAP_PASS.length() < 8) {
Serial.println("ModeAP PW missing: " + wifi_ModeAP_PASS);
} else {
Serial.println("ModeAP PW: " + wifi_ModeAP_PASS);
}
Serial.printf("readFile: wifi.cfg, %d valid entries found. AP %s is selected as frist priority\r\n", apcnt, wifi_ModeSTA_SSID.c_str());
goto end;
}
#endif // ENABLE_WIFI
if (!strcmp(filename, "/preferences.cfg")) {
if (JSONBuffer.containsKey(PREF_APRS_CALLSIGN)) {
// Serial.printf("Checked preferences.cfg: is ok. Found %s: %s. Filesize: %d\r\n", PREF_APRS_CALLSIGN, JSONBuffer[PREF_APRS_CALLSIGN], file.size());
Serial.printf("Checked preferences.cfg: is ok. Found %s. Filesize: %d\r\n", PREF_APRS_CALLSIGN, file.size());
Serial.println("Preferences: reading from /preferences.cfg");
Serial.printf("reafFile: Checked preferences.cfg: is ok. Found %s. Filesize: %d\r\n", PREF_APRS_CALLSIGN, file.size());
Serial.println("reafFile: Preferences: reading from /preferences.cfg");
load_preferences_cfg_file();
} else {
Serial.println("Preferences: /preferences.cfg not available, using default values from flash");
Serial.println("reafFile: Preferences: /preferences.cfg not available, using default values from flash");
err = true;
}
goto end;
}
Serial.printf("Found file '%s', parsed it successfully, but I don't know what to do with the json data ;)!\r\n", filename);
Serial.printf("reafFile: Found file '%s', parsed it successfully, but I don't know what to do with the json data ;)!\r\n", filename);
err = true;
end:
@ -1527,7 +1618,7 @@ void init_and_validate_aprs_position_and_icon() {
if (aprsSymbol.length() != 1)
aprsSymbol = String("[");
Serial.printf("APRS fixed position set to %s %s; icon: table %s symbol %s\r\n", aprsLatPreset.c_str(), aprsLonPreset.c_str(), aprsSymbolTable, aprsSymbol);
Serial.printf("APRS fixed position set to %s %s; icon: table %s symbol %s\r\n", aprsLatPreset.c_str(), aprsLonPreset.c_str(), aprsSymbolTable.c_str(), aprsSymbol.c_str());
}
@ -2281,6 +2372,10 @@ void setup()
preferences.begin("cfg", false);
#ifdef ENABLE_WIFI
init_wifi_STA_and_AP_settings();
#endif
// https://www.tutorialspoint.com/esp32_for_iot/esp32_for_iot_spiffs_storage.htm
// Launch SPIFFS file system
if (SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
@ -2297,14 +2392,16 @@ void setup()
if (!preferences.getBool(PREF_LORA_FREQ_PRESET_INIT)) {
// reseted? try to use /preferences.cfg
readFile(SPIFFS, "/preferences.cfg");
if (preferences.getString(PREF_WIFI_PASSWORD, "").isEmpty() ||
#ifdef ENABLE_WIFI
if (preferences.getString(PREF_WIFI_PASSWORD, "").isEmpty() ||
preferences.getString(PREF_WIFI_SSID, "").isEmpty()) {
preferences.putString(PREF_WIFI_SSID, wifi_ModeSTA_SSID);
preferences.putString(PREF_WIFI_PASSWORD, wifi_ModeSTA_PASS);
preferences.putString(PREF_AP_PASSWORD, wifi_ModeAP_PASS);
Serial.println("WiFi: Updated remote SSID: " + wifi_ModeSTA_SSID);
Serial.println("WiFi: Updated remote PW: ***");
}
preferences.putString(PREF_WIFI_SSID, wifi_ModeSTA_SSID);
preferences.putString(PREF_WIFI_PASSWORD, wifi_ModeSTA_PASS);
preferences.putString(PREF_AP_PASSWORD, wifi_ModeAP_PASS);
Serial.println("WiFi: Updated remote SSID: " + wifi_ModeSTA_SSID);
Serial.println("WiFi: Updated remote PW: ***");
}
#endif
} else {
Serial.println("Preferences: normal start, using preferences from flash");
}
@ -3322,8 +3419,11 @@ void handle_usb_serial_input(void) {
} else if (cmd == "show_preferences") {
Serial.println("*** show_preferenes:");
refill_preferences_as_jsonData();
Serial.println(preferences_as_jsonData);
Serial.printf("n***\r\n");
// local copy
String s = String(preferences_as_jsonData);
s.replace("\n", "\r\n");
Serial.print(s);
Serial.printf("***\r\n");
inputBuf = "";
return;
} else if (cmd == "preferences") {
@ -3333,6 +3433,16 @@ void handle_usb_serial_input(void) {
#endif
inputBuf = "";
return;
} else if (cmd == "dir") {
if (SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
listDir(SPIFFS, "/", 0);
SPIFFS.end();
} else {
Serial.println("*** dir: SPIFFS Mount Failed");
}
Serial.printf("***\r\n");
inputBuf = "";
return;
}
#endif
if (arg != "") {
@ -3370,7 +3480,7 @@ void handle_usb_serial_input(void) {
Serial.println(" preferences (needs to bei implemented)");
Serial.println(" show_preferences (shows preferences from flash)");
Serial.println(" save_preferences_cfg (saves running config to /preferences.cfg in filesystem)");
Serial.println(" preferences (needs to bei implemented)");
Serial.println(" dir (lists SPIFFS directory)");
#endif
Serial.println(" trace <on|off>");
Serial.println(" reboot");

Wyświetl plik

@ -7,6 +7,8 @@
#include <ArduinoJson.h>
#include <esp_task_wdt.h>
#ifdef ENABLE_WIFI
/**
* @see board_build.embed_txtfiles in platformio.ini
*/
@ -34,12 +36,11 @@ extern int8_t wifi_connection_status;
extern String wifi_ModeAP_SSID;
extern String wifi_ModeAP_PASS;
String wifi_ModeAP_PASS_default = "xxxxxxxxxx";
extern String wifi_ModeSTA_PASS;
extern String wifi_ModeSTA_SSID;
// AP Array, currently max 9 APs possible (plus 1 with SSID Self-AP with password)
#define MAX_AP_CNT 10 // max number of possible APs
extern struct AccessPoint APs[MAX_AP_CNT];
extern int apcnt;
// credentials from wifi.cfg
extern String wifi_ModeSTA_SSID_fallback;
extern String wifi_ModeSTA_PASS_fallback;
// for displaying wifi status
extern String oled_wifi_SSID_curr;
extern String oled_wifi_PASS_curr;
@ -128,6 +129,7 @@ String aprs_callsign;
// keep config stored in this global variable
extern String preferences_as_jsonData;
String wifi_config_as_jsonData;
WebServer server(80);
#ifdef KISS_PROTOCOL
@ -383,108 +385,107 @@ void handle_Restore() {
void refill_preferences_as_jsonData()
{
String s;
String jsonData = "{";
jsonData += String("\"") + PREF_WIFI_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_WIFI_PASSWORD, "").isEmpty() ? String("") : "*")) + R"(",)";
jsonData += String("\"") + PREF_AP_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_AP_PASSWORD, "").isEmpty() ? String("") : "*")) + R"(",)";
jsonData += jsonLineFromPreferenceInt(PREF_WIFI_ENABLE);
jsonData += jsonLineFromPreferenceString(PREF_WIFI_SSID);
jsonData += jsonLineFromPreferenceBool(PREF_WIFI_STA_ALLOW_FAILBACK_TO_MODE_AP_AFTER_ONCE_CONNECTED);
jsonData += jsonLineFromPreferenceInt(PREF_WIFI_TXPWR_MODE_AP);
jsonData += jsonLineFromPreferenceInt(PREF_WIFI_TXPWR_MODE_STA);
jsonData += jsonLineFromPreferenceBool(PREF_TNCSERVER_ENABLE);
jsonData += jsonLineFromPreferenceBool(PREF_GPSSERVER_ENABLE);
jsonData += jsonLineFromPreferenceString(PREF_NTP_SERVER);
jsonData += jsonLineFromPreferenceString(PREF_SYSLOG_SERVER);
jsonData += jsonLineFromPreferenceDouble(PREF_LORA_FREQ_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_SPEED_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_LORA_RX_ENABLE);
jsonData += jsonLineFromPreferenceBool(PREF_LORA_TX_ENABLE);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_TX_POWER);
jsonData += jsonLineFromPreferenceBool(PREF_LORA_AUTOMATIC_CR_ADAPTION_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_ADD_SNR_RSSI_TO_PATH_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_LORA_ADD_SNR_RSSI_TO_PATH_END_AT_KISS_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_DIGIPEATING_MODE_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_CROSS_DIGIPEATING_MODE_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_TX_BEACON_AND_KISS_TO_FREQUENCIES_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_LORA_TX_BEACON_AND_KISS_TO_APRSIS_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_LORA_TX_STATUSMESSAGE_TO_APRSIS_PRESET);
jsonData += jsonLineFromPreferenceDouble(PREF_LORA_FREQ_CROSSDIGI_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_SPEED_CROSSDIGI_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_TX_POWER_CROSSDIGI_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_RX_ON_FREQUENCIES_PRESET);
jsonData += jsonLineFromPreferenceString(PREF_APRS_CALLSIGN);
jsonData += jsonLineFromPreferenceString(PREF_APRS_RELAY_PATH);
jsonData += jsonLineFromPreferenceString(PREF_APRS_SYMBOL_TABLE);
jsonData += jsonLineFromPreferenceString(PREF_APRS_SYMBOL);
jsonData += jsonLineFromPreferenceString(PREF_APRS_COMMENT);
jsonData += jsonLineFromPreferenceString(PREF_APRS_LATITUDE_PRESET);
jsonData += jsonLineFromPreferenceString(PREF_APRS_LONGITUDE_PRESET);
jsonData += jsonLineFromPreferenceString(PREF_APRS_SENDER_BLACKLIST);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_FIXED_BEACON_INTERVAL_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_SB_MIN_INTERVAL_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_SB_MAX_INTERVAL_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_SB_MIN_SPEED_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_SB_MAX_SPEED_PRESET);
jsonData += jsonLineFromPreferenceDouble(PREF_APRS_SB_ANGLE_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_SB_TURN_SLOPE_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_SB_TURN_TIME_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_BATTERY);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_FIXED_BEACON_PRESET);
//jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_ALTITUDE);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_ALTITUDE_RATIO);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_ALWAYS_SEND_CSE_SPEED_AND_ALTITUDE);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_GPS_EN);
jsonData += jsonLineFromPreferenceBool(PREF_ACCEPT_OWN_POSITION_REPORTS_VIA_KISS);
jsonData += jsonLineFromPreferenceBool(PREF_GPS_ALLOW_SLEEP_WHILE_KISS);
jsonData += jsonLineFromPreferenceBool(PREF_ENABLE_TNC_SELF_TELEMETRY);
jsonData += jsonLineFromPreferenceInt(PREF_TNC_SELF_TELEMETRY_INTERVAL);
jsonData += jsonLineFromPreferenceInt(PREF_TNC_SELF_TELEMETRY_MIC);
jsonData += jsonLineFromPreferenceString(PREF_TNC_SELF_TELEMETRY_PATH);
jsonData += jsonLineFromPreferenceBool(PREF_DEV_OL_EN);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_CMT);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_COMMENT_RATELIMIT_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_DEV_BT_EN);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_USBSERIAL_DATA_TYPE);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_SHOW_RX_TIME);
jsonData += jsonLineFromPreferenceBool(PREF_DEV_AUTO_SHUT);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_AUTO_SHUT_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_REBOOT_INTERVAL);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_SHOW_OLED_TIME);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_CPU_FREQ);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_UNITS);
jsonData += jsonLineFromPreferenceBool(PREF_APRSIS_EN);
jsonData += jsonLineFromPreferenceString(PREF_APRSIS_SERVER_NAME);
jsonData += jsonLineFromPreferenceInt(PREF_APRSIS_SERVER_PORT);
jsonData += jsonLineFromPreferenceString(PREF_APRSIS_FILTER);
jsonData += jsonLineFromPreferenceString(PREF_APRSIS_CALLSIGN);
jsonData += jsonLineFromPreferenceString(PREF_APRSIS_PASSWORD);
jsonData += jsonLineFromPreferenceInt(PREF_APRSIS_ALLOW_INET_TO_RF);
jsonData += jsonLineFromDouble("lora_freq_rx_curr", lora_freq_rx_curr);
jsonData += jsonLineFromString("aprsis_status", aprsis_status.c_str());
jsonData += jsonLineFromInt("FreeHeap", ESP.getFreeHeap());
jsonData += jsonLineFromInt("HeapSize", ESP.getHeapSize());
jsonData += jsonLineFromInt("FreeSketchSpace", ESP.getFreeSketchSpace());
jsonData += jsonLineFromInt("PSRAMSize", ESP.getPsramSize());
jsonData += jsonLineFromInt("PSRAMFree", ESP.getFreePsram());
s = aprsLatPreset + " " + aprsLonPreset + " [" + (aprsPresetShown == "" ? "GPS" : aprsPresetShown) + "]";
jsonData += jsonLineFromString("curPos", s.c_str());
jsonData += jsonLineFromInt("UptimeMinutes", millis()/1000/60);
jsonData += jsonLineFromString("OledLine1", OledLine1.c_str());
jsonData += jsonLineFromString("OledLine2", OledLine2.c_str());
jsonData += jsonLineFromString("OledLine3", OledLine3.c_str());
s = String(OledLine4); s.replace("\xF7", "°");
jsonData += jsonLineFromString("OledLine4", s.c_str());
jsonData += jsonLineFromString("OledLine5", OledLine5.c_str(), true);
String s_tmp;
String s = "{";
s = "\n " + String("\"") + PREF_WIFI_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_WIFI_PASSWORD, "").isEmpty() ? String("") : "*")) + R"(",)";
s = "\n " + String("\"") + PREF_AP_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_AP_PASSWORD, "").isEmpty() ? String("") : "*")) + R"(",)";
s = s + "\n " + jsonLineFromPreferenceInt(PREF_WIFI_ENABLE);
s = s + "\n " + jsonLineFromPreferenceString(PREF_WIFI_SSID);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_WIFI_STA_ALLOW_FAILBACK_TO_MODE_AP_AFTER_ONCE_CONNECTED);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_WIFI_TXPWR_MODE_AP);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_WIFI_TXPWR_MODE_STA);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_TNCSERVER_ENABLE);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_GPSSERVER_ENABLE);
s = s + "\n " + jsonLineFromPreferenceString(PREF_NTP_SERVER);
s = s + "\n " + jsonLineFromPreferenceString(PREF_SYSLOG_SERVER);
s = s + "\n " + jsonLineFromPreferenceDouble(PREF_LORA_FREQ_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_LORA_SPEED_PRESET);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_LORA_RX_ENABLE);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_LORA_TX_ENABLE);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_LORA_TX_POWER);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_LORA_AUTOMATIC_CR_ADAPTION_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_LORA_ADD_SNR_RSSI_TO_PATH_PRESET);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_LORA_ADD_SNR_RSSI_TO_PATH_END_AT_KISS_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_DIGIPEATING_MODE_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_CROSS_DIGIPEATING_MODE_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_LORA_TX_BEACON_AND_KISS_TO_FREQUENCIES_PRESET);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_LORA_TX_BEACON_AND_KISS_TO_APRSIS_PRESET);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_LORA_TX_STATUSMESSAGE_TO_APRSIS_PRESET);
s = s + "\n " + jsonLineFromPreferenceDouble(PREF_LORA_FREQ_CROSSDIGI_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_LORA_SPEED_CROSSDIGI_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_LORA_TX_POWER_CROSSDIGI_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_LORA_RX_ON_FREQUENCIES_PRESET);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_CALLSIGN);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_RELAY_PATH);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_SYMBOL_TABLE);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_SYMBOL);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_COMMENT);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_LATITUDE_PRESET);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_LONGITUDE_PRESET);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRS_SENDER_BLACKLIST);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_FIXED_BEACON_INTERVAL_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_SB_MIN_INTERVAL_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_SB_MAX_INTERVAL_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_SB_MIN_SPEED_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_SB_MAX_SPEED_PRESET);
s = s + "\n " + jsonLineFromPreferenceDouble(PREF_APRS_SB_ANGLE_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_SB_TURN_SLOPE_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_SB_TURN_TIME_PRESET);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRS_SHOW_BATTERY);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRS_FIXED_BEACON_PRESET);
//s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRS_SHOW_ALTITUDE);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRS_ALTITUDE_RATIO);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRS_ALWAYS_SEND_CSE_SPEED_AND_ALTITUDE);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRS_GPS_EN);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_ACCEPT_OWN_POSITION_REPORTS_VIA_KISS);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_GPS_ALLOW_SLEEP_WHILE_KISS);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_ENABLE_TNC_SELF_TELEMETRY);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_TNC_SELF_TELEMETRY_INTERVAL);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_TNC_SELF_TELEMETRY_MIC);
s = s + "\n " + jsonLineFromPreferenceString(PREF_TNC_SELF_TELEMETRY_PATH);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_DEV_OL_EN);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRS_SHOW_CMT);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRS_COMMENT_RATELIMIT_PRESET);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_DEV_BT_EN);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_DEV_USBSERIAL_DATA_TYPE);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_DEV_SHOW_RX_TIME);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_DEV_AUTO_SHUT);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_DEV_AUTO_SHUT_PRESET);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_DEV_REBOOT_INTERVAL);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_DEV_SHOW_OLED_TIME);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_DEV_CPU_FREQ);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_DEV_UNITS);
s = s + "\n " + jsonLineFromPreferenceBool(PREF_APRSIS_EN);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRSIS_SERVER_NAME);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRSIS_SERVER_PORT);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRSIS_FILTER);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRSIS_CALLSIGN);
s = s + "\n " + jsonLineFromPreferenceString(PREF_APRSIS_PASSWORD);
s = s + "\n " + jsonLineFromPreferenceInt(PREF_APRSIS_ALLOW_INET_TO_RF);
s = s + "\n " + jsonLineFromDouble("lora_freq_rx_curr", lora_freq_rx_curr);
s = s + "\n " + jsonLineFromString("aprsis_status", aprsis_status.c_str());
s = s + "\n " + jsonLineFromInt("FreeHeap", ESP.getFreeHeap());
s = s + "\n " + jsonLineFromInt("HeapSize", ESP.getHeapSize());
s = s + "\n " + jsonLineFromInt("FreeSketchSpace", ESP.getFreeSketchSpace());
s = s + "\n " + jsonLineFromInt("PSRAMSize", ESP.getPsramSize());
s = s + "\n " + jsonLineFromInt("PSRAMFree", ESP.getFreePsram());
s_tmp = aprsLatPreset + " " + aprsLonPreset + " [" + (aprsPresetShown == "" ? "GPS" : aprsPresetShown) + "]";
s = s + jsonLineFromString("curPos", s_tmp.c_str());
s = s + "\n " + jsonLineFromInt("UptimeMinutes", millis()/1000/60);
s = s + "\n " + jsonLineFromString("OledLine1", OledLine1.c_str());
s = s + "\n " + jsonLineFromString("OledLine2", OledLine2.c_str());
s = s + "\n " + jsonLineFromString("OledLine3", OledLine3.c_str());
s_tmp = String(OledLine4); s_tmp.replace("\xF7", "°");
s = s + "\n " + jsonLineFromString("OledLine4", s_tmp.c_str());
s = s + "\n " + jsonLineFromString("OledLine5", OledLine5.c_str(), true);
jsonData += "}";
s += "\n}";
// Store copy of jsonData in our global variable
preferences_as_jsonData = String(jsonData);
preferences_as_jsonData = String(s);
}
void handle_saveCfg2FS() {
// https://www.tutorialspoint.com/esp32_for_iot/esp32_for_iot_spiffs_storage.htm
// Launch SPIFFS file system
#if defined(ENABLE_SYSLOG)
syslog_log(LOG_INFO, String("WebServer: Button save Config to Filesystem pressed."));
do_serial_println("WebServer: Button save Config to Filesystem pressed.");
@ -492,6 +493,7 @@ void handle_saveCfg2FS() {
refill_preferences_as_jsonData();
if (!preferences_as_jsonData.isEmpty()) {
// Launches SPIFFS file system
save_to_file("Webserver", "/preferences.cfg", preferences_as_jsonData);
}
@ -499,12 +501,65 @@ void handle_saveCfg2FS() {
server.send(302,"text/html", "");
}
void handle_Cfg() {
refill_preferences_as_jsonData();
server.send(200,"application/json", preferences_as_jsonData);
}
void fill_wifi_config_as_jsonData() {
int pos;
String s = "{\n \"AP\": [\n";
if (apcnt) {
for (pos = 0 ; pos < apcnt; pos++) {
s += " {\n ";
s = s + "\"SSID\": \"" + jsonEscape(String(APs[pos].ssid)) + "\"" + "\n";
s += " ";
s = s + "\"password\": \"" + jsonEscape(String(APs[pos].pw)) + "\"" + "\n";
if (!pos) {
s += " ";
s += "\"prio\": 1\n";
}
s += " }";
if (pos < apcnt-1)
s += ",";
s += "\n";
}
} else {
s += " {\n ";
s = s + "\"SSID\": \"" + jsonEscape(preferences.getString(PREF_WIFI_PASSWORD, "")) + "\",\n";
s += " ";
s = s + "\"password\": \"" + jsonEscape(preferences.getString(PREF_WIFI_PASSWORD, "")) + "\"\n";
s += " }\n";
}
s += " ],\n\n";
s = s + " \"SelfAP_PW\": \"" + jsonEscape(preferences.getString(PREF_AP_PASSWORD)) + "\"\n";
s += "}\n";
wifi_config_as_jsonData = String(s);
}
void handle_saveWifi2FS() {
#if defined(ENABLE_SYSLOG)
syslog_log(LOG_INFO, String("WebServer: Button save WifiConfig to Filesystem pressed."));
do_serial_println("WebServer: Button save WifiConfig to Filesystem pressed.");
#endif
fill_wifi_config_as_jsonData();
if (!wifi_config_as_jsonData.isEmpty()) {
// Launches SPIFFS file system
save_to_file("Webserver", "/wifi.cfg", wifi_config_as_jsonData);
}
server.sendHeader("Location", "/");
server.send(302,"text/html", "");
}
void handle_WifiCfg() {
fill_wifi_config_as_jsonData();
server.send(200,"application/json", wifi_config_as_jsonData);
}
void handle_ReceivedList() {
// DynamicJsonDocument: heap size problem? *500 is too small (json array will be truncated if received list tends tot 50 entries;
// *1000 results in '{}' on TTGO t-beam (while it's correct on TTGO lora32)
@ -1026,14 +1081,16 @@ boolean restart_STA(String use_ssid, String use_password) {
do_serial_println("WiFi: Searching for AP " + use_ssid);
while (WiFi.status() != WL_CONNECTED) {
esp_task_wdt_reset();
do_serial_println(String("WiFi: Status " + String(int(WiFi.status())) + ". Try " + retryWifi));
if (retryWifi > 30) {
esp_task_wdt_reset();
do_serial_println(String("WiFi: Status " + String(int(WiFi.status())) + ". Try " + retryWifi + ". Giving up."));
return false;
}
do_serial_println(String("WiFi: Status " + String(int(WiFi.status())) + ". Try " + retryWifi));
retryWifi += 1;
vTaskDelay(500/portTICK_PERIOD_MS);
}
// WL_CONNECTED = Status 3
do_serial_println(String("WiFi: Status " + String(int(WiFi.status())) + ". Try " + retryWifi + ". Connected."));
esp_task_wdt_reset();
return true;;
}
@ -1050,28 +1107,26 @@ void restart_AP_or_STA(void) {
String used_wifi_ModeSTA_SSID;
String used_wifi_ModeSTA_PASS;
if (wifi_ModeSTA_SSID.length() || wifi_ModeSTA_SSID_fallback.length()) {
if (apcnt) {
static boolean successfully_associated = false;
oled_wifi_SSID_curr = "[not connected]";
oled_wifi_PASS_curr = "";
oled_wifi_IP_curr = "0.0.0.0";
int pos;
start_soft_ap = false;
boolean successfully_associated = restart_STA(wifi_ModeSTA_SSID, wifi_ModeSTA_PASS);
if (successfully_associated) {
used_wifi_ModeSTA_SSID = wifi_ModeSTA_SSID;
used_wifi_ModeSTA_PASS = wifi_ModeSTA_PASS;
} else {
// second try, with the SSID and password from wifi.cfg
successfully_associated = restart_STA(wifi_ModeSTA_SSID_fallback, wifi_ModeSTA_PASS_fallback);
for (pos = 0; pos < apcnt; pos++) {
do_serial_println("Wifi: Trying AP " + String(pos) + "/" + String(apcnt) + ": SSID " + APs[pos].ssid);
successfully_associated = restart_STA(String(APs[pos].ssid), String(APs[pos].pw));
if (successfully_associated) {
used_wifi_ModeSTA_SSID = wifi_ModeSTA_SSID_fallback;
used_wifi_ModeSTA_PASS = wifi_ModeSTA_PASS_fallback;
used_wifi_ModeSTA_SSID = String(APs[pos].ssid);
used_wifi_ModeSTA_PASS = String(APs[pos].pw);
break;
}
}
if (!successfully_associated && (!mode_sta_once_successfully_connected || wifi_do_fallback_to_mode_AP)) {
start_soft_ap = true;
start_soft_ap = true;
}
} else {
@ -1657,10 +1712,12 @@ void send_to_aprsis()
server.on("/beacon", handle_Beacon);
server.on("/shutdown", handle_Shutdown);
server.on("/cfg", handle_Cfg);
server.on("/wificfg", handle_WifiCfg);
server.on("/received_list", handle_ReceivedList);
server.on("/save_aprs_cfg", handle_SaveAPRSCfg);
server.on("/save_device_cfg", handle_saveDeviceCfg);
server.on("/save2fs", handle_saveCfg2FS);
server.on("/savewifi2fs", handle_saveWifi2FS);
server.on("/restore", handle_Restore);
server.on("/update", HTTP_POST, []() {
#if defined(ENABLE_SYSLOG)
@ -1710,12 +1767,13 @@ void send_to_aprsis()
esp_task_wdt_init(120, true); //enable panic so ESP32 restarts
esp_task_wdt_add(NULL); //add current thread to WDT watch
wifi_ModeSTA_PASS = preferences.getString(PREF_WIFI_PASSWORD, "");
wifi_ModeSTA_SSID = preferences.getString(PREF_WIFI_SSID, "");
wifi_ModeAP_PASS = preferences.getString(PREF_AP_PASSWORD, "");
// 8 characters is requirements for WPA2
// May be already set by wifi.cfg
if (wifi_ModeAP_PASS.length() < 8) {
wifi_ModeAP_PASS = wifi_ModeAP_PASS_default;
wifi_ModeAP_PASS = preferences.getString(PREF_AP_PASSWORD, "");
if (wifi_ModeAP_PASS.length() < 8) {
wifi_ModeAP_PASS = wifi_ModeAP_PASS_default;
}
}
@ -1800,7 +1858,10 @@ void send_to_aprsis()
}
}
} else {
if ((wifi_ModeSTA_SSID.length() || wifi_ModeSTA_SSID_fallback.length()) && millis() - webserver_started > 60*1000L && WiFi.softAPgetStationNum() < 1) {
// If we are in self-AP-mode and remote APs are configured (but not had been reachable),
// try to give up self AP mode and try to reconnect an remote AP again. But only do this,
// if no user is currently associated with our self-AP.
if (apcnt && millis() - webserver_started > 60*1000L && WiFi.softAPgetStationNum() < 1) {
if (aprsis_client.connected()) aprsis_client.stop();
restart_AP_or_STA();
webserver_started = millis();
@ -1902,3 +1963,5 @@ void send_to_aprsis()
vTaskDelay(5/portTICK_PERIOD_MS);
}
}
#endif // ENABLE_WIFI