I'm using ArduinoJson to parse a file full of JSON strings that contain the SSID and password for the registered networks. I have a little web interface that runs in soft AP mode so you can scan for networks and add them to the file. Adding networks to the file works fine, but reading them back and using them as input for WiFi.begin doesn't work. It moves to status code 1, which means it failed to find a network with that SSID.
I have compared the value of the result of const char* ssid = networks[network]["ssid"];
with const char* _ssid = "MySSID";
using strcmp and it returns 0, so I can't figure out why it's not working. It works if I replace networks[network]["ssid]
with my SSID (though I need to replace the password with the string literal as well, otherwise it stays on status code 6, disconnected).
I can't figure out what it is about ArduinoJson, but it seems that the result of grabbing a string doesn't return a string that is formatted correctly for WiFi.begin, but it satisfies strcmp?
Edit: I modified the code quite a bit in an effort to get it to work. I am no longer passing the ArduinoJson object, I'm now passing a struct with the data, and it still doesn't work. Is this the work of some advanced c++ constants/pointers stuff that I don't seem to understand?
main.cpp:
#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
#include <vector>
#include <elapsedMillis.h>
#include "config.h"
#include "restserver.h"
#include "scanwifiserver.h"
AsyncWebServer *Server = new AsyncWebServer(80);
ScanWifiServer *scanWifi;
RestServer *restServer;
struct Network {
const char* ssid;
const char* password;
};
std::vector<Network> readAP(fs::FS &fs) {
//fs.remove("/ap.txt");
File file = fs.open("/ap.txt");
std::vector<Network> networks;
if (!file) {
#ifdef DEBUG
Serial.println("Failed to open file for reading");
#endif
return networks;
}
while (file.available()) {
DynamicJsonDocument n(JSON_CAPACITY);
auto s = file.readStringUntil('\n');
deserializeJson(n, s);
struct Network network = {n["ssid"], n["password"]};
networks.push_back(network);
Serial.println(networks.back().ssid);
}
file.close();
return networks;
}
void setup() {
#ifdef DEBUG
Serial.begin(BAUDRATE);
delay(2000);
#endif
SPIFFS.begin();
auto networks = readAP(SPIFFS);
if (networks.size() > 0) {
Serial.println("Networks:");
int network = 0;
Serial.println(networks.size());
while (WiFi.status() != WL_CONNECTED && network < networks.size()) {
const char* ssid = networks[network].ssid;
const char* password = networks[network].password;
Serial.printf("%s, %s\n", ssid, password);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_NO_SSID_AVAIL)
break;
delay(500);
Serial.print(WiFi.status());
}
Serial.println("");
network++;
}
if (WiFi.status() == WL_CONNECTED) Serial.println("Connected");
else networks.clear();
}
if (networks.size() == 0) {
Serial.println("Starting ScanWifiServer");
WiFi.mode(WIFI_AP);
scanWifi = new ScanWifiServer(Server);
Server->begin();
MDNS.begin("grow");
MDNS.addService("http", "tcp", 80);
}
}
void loop() {}