3
votes

I am using Arduino ESP8266 to store and load configuration settings on SPIFSS. I used this ConfigFile.ino as a reference example.

https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/ConfigFile/ConfigFile.ino

This function loads the configuration settings onto variables serverName and accessToken.

bool loadConfig() {
  File configFile = SPIFFS.open("/config.json", "r");
  if (!configFile) {
    Serial.println("Failed to open config file");
    return false;
  }

  size_t size = configFile.size();
  if (size > 1024) {
    Serial.println("Config file size is too large");
    return false;
  }

  // Allocate a buffer to store contents of the file.
  std::unique_ptr<char[]> buf(new char[size]);

  // We don't use String here because ArduinoJson library requires the input
  // buffer to be mutable. If you don't use ArduinoJson, you may as well
  // use configFile.readString instead.
  configFile.readBytes(buf.get(), size);

  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& json = jsonBuffer.parseObject(buf.get());

  if (!json.success()) {
    Serial.println("Failed to parse config file");
    return false;
  }

  const char* serverName = json["serverName"];
  const char* accessToken = json["accessToken"];

  // Real world application would store these values in some variables for
  // later use.

  Serial.print("Loaded serverName: ");
  Serial.println(serverName);
  Serial.print("Loaded accessToken: ");
  Serial.println(accessToken);
  return true;
}

I made some modifications to this function to load the configuration settings into a struct.

struct ConfigSettingsStruct
{
    String ssid;
    String password;
};

ConfigSettingsStruct ConfigSettings;

bool loadConfig() {
    File configFile = SPIFFS.open("/config.json", "r");
    if (!configFile) {
        Serial.println("Failed to open config file");
        return false;
    }

    size_t size = configFile.size();
    if (size > 1024) {
        Serial.println("Config file size is too large");
        return false;
    }

    // Allocate a buffer to store contents of the file.
    std::unique_ptr<char[]> buf(new char[size]);

    // We don't use String here because ArduinoJson library requires the input
    // buffer to be mutable. If you don't use ArduinoJson, you may as well
    // use configFile.readString instead.
    configFile.readBytes(buf.get(), size);

    StaticJsonBuffer<200> jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject(buf.get());

    if (!json.success()) {
        Serial.println("Failed to parse config file");
        return false;
    }

    //const char* serverName = json["serverName"];
    //const char* accessToken = json["accessToken"];

    char ssid_[30];
    strcpy(ssid_, json["ssid"]);
    ConfigSettings.ssid = String(ssid_);

    char password_[30];
    strcpy(password_, json["password"]);
    ConfigSettings.password = String(password_);

    // Real world application would store these values in some variables for
    // later use.

    Serial.print("Loaded ssid: ");
    Serial.println(ConfigSettings.ssid);
    Serial.print("Loaded password: ");
    Serial.println(ConfigSettings.password);

    return true;
}

After I download the code and run ESP8266, the WiFi chip resets with some stack error. What is wrong with my code? How can the config settings be properly loaded onto ConfigSettings?

2

2 Answers

2
votes

There is nothing wrong with your code in the question. It should work. I strongly suspect that the cause of the stack error lies elsewhere. Please check your code carefully again.

This does not count as an answer but can be helpful as a reminder to look elsewhere. You may be looking at the wrong place.

2
votes

Please notice that; you have a possible memory leak after

std::unique_ptr<char[]> buf(new char[size]);

I suggest you to use to allocate some memory via malloc (which is not stylish but classic) and free it after all. You need also close file before returns.

Also your ssid and passphrase buffer lengths are not enough. Max ssid length must be 32. Assuming that you got a psk based encryption, you need to increase pass buffer length to 64.

Tiny but; maybe you can think to add a typedef before struct define despite C++ threads them definable within the namespace.