Prevent config corruption by checking whether memory allocation was successfull.
This commit is contained in:
parent
c1fc907ecb
commit
4053e31a5e
@ -5,6 +5,7 @@
|
||||
#include "WebApi_device.h"
|
||||
#include "WebApi_devinfo.h"
|
||||
#include "WebApi_dtu.h"
|
||||
#include "WebApi_errors.h"
|
||||
#include "WebApi_eventlog.h"
|
||||
#include "WebApi_firmware.h"
|
||||
#include "WebApi_gridprofile.h"
|
||||
@ -34,6 +35,8 @@ public:
|
||||
|
||||
static void sendTooManyRequests(AsyncWebServerRequest* request);
|
||||
|
||||
static void writeConfig(JsonObject& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!");
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ enum WebApiError {
|
||||
GenericDataTooLarge,
|
||||
GenericParseError,
|
||||
GenericValueMissing,
|
||||
GenericWriteFailed,
|
||||
|
||||
DtuBase = 2000,
|
||||
DtuSerialZero,
|
||||
|
||||
@ -26,6 +26,11 @@ bool ConfigurationClass::write()
|
||||
|
||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
|
||||
if (doc.capacity() == 0) {
|
||||
MessageOutput.println("Failed to allocate memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonObject cfg = doc.createNestedObject("cfg");
|
||||
cfg["version"] = config.Cfg.Version;
|
||||
cfg["save_count"] = config.Cfg.SaveCount;
|
||||
@ -151,6 +156,12 @@ bool ConfigurationClass::read()
|
||||
File f = LittleFS.open(CONFIG_FILENAME, "r", false);
|
||||
|
||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
|
||||
if (doc.capacity() == 0) {
|
||||
MessageOutput.println("Failed to allocate memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deserialize the JSON document
|
||||
const DeserializationError error = deserializeJson(doc, f);
|
||||
if (error) {
|
||||
@ -311,6 +322,12 @@ void ConfigurationClass::migrate()
|
||||
}
|
||||
|
||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
|
||||
if (doc.capacity() == 0) {
|
||||
MessageOutput.println("Failed to allocate memory");
|
||||
return;
|
||||
}
|
||||
|
||||
// Deserialize the JSON document
|
||||
const DeserializationError error = deserializeJson(doc, f);
|
||||
if (error) {
|
||||
|
||||
@ -101,4 +101,16 @@ void WebApiClass::sendTooManyRequests(AsyncWebServerRequest* request)
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void WebApiClass::writeConfig(JsonObject& retMsg, const WebApiError code, const String& message)
|
||||
{
|
||||
if (!Configuration.write()) {
|
||||
retMsg["message"] = "Write failed!";
|
||||
retMsg["code"] = WebApiError::GenericWriteFailed;
|
||||
} else {
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = message;
|
||||
retMsg["code"] = code;
|
||||
}
|
||||
}
|
||||
|
||||
WebApiClass WebApi;
|
||||
@ -175,11 +175,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
|
||||
Display.setLanguage(config.Display.Language);
|
||||
Display.Diagram().updatePeriod();
|
||||
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -154,11 +154,8 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
|
||||
config.Dtu.Nrf.PaLevel = root["nrf_palevel"].as<uint8_t>();
|
||||
config.Dtu.Cmt.PaLevel = root["cmt_palevel"].as<int8_t>();
|
||||
config.Dtu.Cmt.Frequency = root["cmt_frequency"].as<uint32_t>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -167,11 +167,8 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request)
|
||||
inverter->Serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
|
||||
strncpy(inverter->Name, root["name"].as<String>().c_str(), INV_MAX_NAME_STRLEN);
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Inverter created!";
|
||||
retMsg["code"] = WebApiError::InverterAdded;
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterAdded, "Inverter created!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -294,11 +291,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
||||
arrayCount++;
|
||||
}
|
||||
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["code"] = WebApiError::InverterChanged;
|
||||
retMsg["message"] = "Inverter changed!";
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterChanged, "Inverter changed!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -395,11 +388,8 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request)
|
||||
|
||||
inverter.Serial = 0;
|
||||
strncpy(inverter.Name, "", sizeof(inverter.Name));
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Inverter deleted!";
|
||||
retMsg["code"] = WebApiError::InverterDeleted;
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterDeleted, "Inverter deleted!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -466,11 +456,7 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request)
|
||||
order++;
|
||||
}
|
||||
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Inverter order saved!";
|
||||
retMsg["code"] = WebApiError::InverterOrdered;
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterOrdered, "Inverter order saved!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -334,11 +334,8 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
||||
config.Mqtt.Hass.Retain = root["mqtt_hass_retain"].as<bool>();
|
||||
config.Mqtt.Hass.IndividualPanels = root["mqtt_hass_individualpanels"].as<bool>();
|
||||
strlcpy(config.Mqtt.Hass.Topic, root["mqtt_hass_topic"].as<String>().c_str(), sizeof(config.Mqtt.Hass.Topic));
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -238,11 +238,8 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
config.WiFi.ApTimeout = root["aptimeout"].as<uint>();
|
||||
config.Mdns.Enabled = root["mdnsenabled"].as<bool>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -179,11 +179,8 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request)
|
||||
config.Ntp.Latitude = root["latitude"].as<double>();
|
||||
config.Ntp.Longitude = root["longitude"].as<double>();
|
||||
config.Ntp.SunsetType = root["sunsettype"].as<uint8_t>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -101,11 +101,8 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request)
|
||||
CONFIG_T& config = Configuration.get();
|
||||
strlcpy(config.Security.Password, root["password"].as<String>().c_str(), sizeof(config.Security.Password));
|
||||
config.Security.AllowReadonly = root["allow_readonly"].as<bool>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"1003": "Daten zu groß!",
|
||||
"1004": "Fehler beim interpretieren der Daten!",
|
||||
"1005": "Benötigte Werte fehlen!",
|
||||
"1006": "Schreiben fehlgeschlagen!",
|
||||
"2001": "Die Seriennummer darf nicht 0 sein!",
|
||||
"2002": "Das Abfraginterval muss größer als 0 sein!",
|
||||
"2003": "Ungültige Sendeleistung angegeben!",
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"1003": "Data too large!",
|
||||
"1004": "Failed to parse data!",
|
||||
"1005": "Values are missing!",
|
||||
"1006": "Write failed!",
|
||||
"2001": "Serial cannot be zero!",
|
||||
"2002": "Poll interval must be greater zero!",
|
||||
"2003": "Invalid power level setting!",
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"1003": "Données trop importantes !",
|
||||
"1004": "Échec de l'analyse des données !",
|
||||
"1005": "Certaines valeurs sont manquantes !",
|
||||
"1006": "Write failed!",
|
||||
"2001": "Le numéro de série ne peut pas être nul !",
|
||||
"2002": "L'intervalle de sondage doit être supérieur à zéro !",
|
||||
"2003": "Réglage du niveau de puissance invalide !",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user