Skip to content

Commit 191b63e

Browse files
committed
Added the ability to set some write once 'factory' settings
By adding the header `X-Storage: factory` to the HTTP on the first call the settings will be saved to a different area of flash. This allows for unique IDs and passwords to be set at the factory that will be preserved after a factory reset.
1 parent 15f74d8 commit 191b63e

File tree

6 files changed

+103
-61
lines changed

6 files changed

+103
-61
lines changed

platformio.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ lib_deps =
3434
3535
jeremypoulter/[email protected]
3636
jeremypoulter/Micro [email protected]
37-
jeremypoulter/[email protected].4
37+
jeremypoulter/[email protected].5
3838
jeremypoulter/[email protected]
3939
jeremypoulter/[email protected]
4040
jeremypoulter/[email protected]
@@ -68,6 +68,7 @@ build_flags =
6868
-D CS_PLATFORM=CS_P_ESP32
6969
-D MG_ENABLE_SSL=1
7070
-D MG_ENABLE_HTTP_STREAMING_MULTIPART=1
71+
-D MG_ENABLE_EXTRA_ERRORS_DESC=1
7172
-D MG_SSL_MBED_DUMMY_RANDOM=1
7273
-D MG_SSL_IF=MG_SSL_IF_MBEDTLS
7374
-D MG_SSL_IF_MBEDTLS_FREE_CERTS=1

src/app_config.cpp

Lines changed: 66 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@
1616
#include <Arduino.h>
1717
#include <EEPROM.h> // Save config settings
1818
#include <ConfigJson.h>
19+
#include <LITTLEFS.h>
1920

20-
#define EEPROM_SIZE 4096
21-
#define CHECKSUM_SEED 128
21+
#define EEPROM_SIZE 4096
22+
23+
#define CONFIG_OFFSET 0
24+
#define CONFIG_SIZE 3072
25+
26+
#define FACTORY_OFFSET CONFIG_SIZE
27+
#define FACTORY_SIZE 1024
2228

2329
// Wifi Network Strings
2430
String esid;
@@ -115,7 +121,7 @@ ConfigOpt *opts[] =
115121

116122
// Language String
117123
new ConfigOptDefenition<String>(lang, "", "lang", "lan"),
118-
124+
119125
// Web server authentication (leave blank for none)
120126
new ConfigOptDefenition<String>(www_username, "", "www_username", "au"),
121127
new ConfigOptSecret(www_password, "", "www_password", "ap"),
@@ -203,11 +209,13 @@ ConfigOpt *opts[] =
203209
new ConfigOptVirtualBool(flagsOpt, CONFIG_OCPP_ACCESS_SUSPEND, CONFIG_OCPP_ACCESS_SUSPEND, "ocpp_suspend_evse", "ops"),
204210
new ConfigOptVirtualBool(flagsOpt, CONFIG_OCPP_ACCESS_ENERGIZE, CONFIG_OCPP_ACCESS_ENERGIZE, "ocpp_energize_plug", "opn"),
205211
new ConfigOptVirtualBool(flagsOpt, CONFIG_RFID, CONFIG_RFID, "rfid_enabled", "rf"),
212+
new ConfigOptVirtualBool(flagsOpt, CONFIG_FACTORY_WRITE_LOCK, CONFIG_FACTORY_WRITE_LOCK, "factory_write_lock", "fwl"),
206213
new ConfigOptVirtualMqttProtocol(flagsOpt, "mqtt_protocol", "mprt"),
207214
new ConfigOptVirtualChargeMode(flagsOpt, "charge_mode", "chmd")
208215
};
209216

210-
ConfigJson config(opts, sizeof(opts) / sizeof(opts[0]), EEPROM_SIZE);
217+
ConfigJson user_config(opts, sizeof(opts) / sizeof(opts[0]), EEPROM_SIZE, CONFIG_OFFSET);
218+
ConfigJson factory_config(opts, sizeof(opts) / sizeof(opts[0]), EEPROM_SIZE, FACTORY_OFFSET);
211219

212220
// -------------------------------------------------------------------
213221
// Reset EEPROM, wipes all settings
@@ -217,7 +225,7 @@ ResetEEPROM() {
217225
EEPROM.begin(EEPROM_SIZE);
218226

219227
//DEBUG.println("Erasing EEPROM");
220-
for (int i = 0; i < EEPROM_SIZE; ++i) {
228+
for (int i = CONFIG_OFFSET; i < (CONFIG_OFFSET + CONFIG_SIZE); ++i) {
221229
EEPROM.write(i, 0xff);
222230
//DEBUG.print("#");
223231
}
@@ -230,9 +238,10 @@ ResetEEPROM() {
230238
void
231239
config_load_settings()
232240
{
233-
config.onChanged(config_changed);
241+
user_config.onChanged(config_changed);
234242

235-
if(!config.load()) {
243+
factory_config.load(false);
244+
if(!user_config.load(true)) {
236245
DBUGF("No JSON config found, trying v1 settings");
237246
config_load_v1_settings();
238247
}
@@ -279,46 +288,48 @@ void config_changed(String name)
279288
}
280289
}
281290

282-
void config_commit()
291+
void config_commit(bool factory)
283292
{
293+
ConfigJson &config = factory ? factory_config : user_config;
294+
config.set("factory_write_lock", true);
284295
config.commit();
285296
}
286297

287298
bool config_deserialize(String& json) {
288-
return config.deserialize(json.c_str());
299+
return user_config.deserialize(json.c_str());
289300
}
290301

291302
bool config_deserialize(const char *json)
292303
{
293-
return config.deserialize(json);
304+
return user_config.deserialize(json);
294305
}
295306

296307
bool config_deserialize(DynamicJsonDocument &doc)
297308
{
298-
return config.deserialize(doc);
309+
return user_config.deserialize(doc);
299310
}
300311

301312
bool config_serialize(String& json, bool longNames, bool compactOutput, bool hideSecrets)
302313
{
303-
return config.serialize(json, longNames, compactOutput, hideSecrets);
314+
return user_config.serialize(json, longNames, compactOutput, hideSecrets);
304315
}
305316

306317
bool config_serialize(DynamicJsonDocument &doc, bool longNames, bool compactOutput, bool hideSecrets)
307318
{
308-
return config.serialize(doc, longNames, compactOutput, hideSecrets);
319+
return user_config.serialize(doc, longNames, compactOutput, hideSecrets);
309320
}
310321

311322
void config_set(const char *name, uint32_t val) {
312-
config.set(name, val);
323+
user_config.set(name, val);
313324
}
314325
void config_set(const char *name, String val) {
315-
config.set(name, val);
326+
user_config.set(name, val);
316327
}
317328
void config_set(const char *name, bool val) {
318-
config.set(name, val);
329+
user_config.set(name, val);
319330
}
320331
void config_set(const char *name, double val) {
321-
config.set(name, val);
332+
user_config.set(name, val);
322333
}
323334

324335
void config_save_emoncms(bool enable, String server, String node, String apikey,
@@ -329,12 +340,12 @@ void config_save_emoncms(bool enable, String server, String node, String apikey,
329340
newflags |= CONFIG_SERVICE_EMONCMS;
330341
}
331342

332-
config.set("emoncms_server", server);
333-
config.set("emoncms_node", node);
334-
config.set("emoncms_apikey", apikey);
335-
config.set("emoncms_fingerprint", fingerprint);
336-
config.set("flags", newflags);
337-
config.commit();
343+
user_config.set("emoncms_server", server);
344+
user_config.set("emoncms_node", node);
345+
user_config.set("emoncms_apikey", apikey);
346+
user_config.set("emoncms_fingerprint", fingerprint);
347+
user_config.set("flags", newflags);
348+
user_config.commit();
338349
}
339350

340351
void
@@ -352,23 +363,23 @@ config_save_mqtt(bool enable, int protocol, String server, uint16_t port, String
352363
}
353364
newflags |= protocol << 4;
354365

355-
config.set("mqtt_server", server);
356-
config.set("mqtt_port", port);
357-
config.set("mqtt_topic", topic);
358-
config.set("mqtt_user", user);
359-
config.set("mqtt_pass", pass);
360-
config.set("mqtt_solar", solar);
361-
config.set("mqtt_grid_ie", grid_ie);
362-
config.set("mqtt_live_pwr", live_pwr);
363-
config.set("flags", newflags);
364-
config.commit();
366+
user_config.set("mqtt_server", server);
367+
user_config.set("mqtt_port", port);
368+
user_config.set("mqtt_topic", topic);
369+
user_config.set("mqtt_user", user);
370+
user_config.set("mqtt_pass", pass);
371+
user_config.set("mqtt_solar", solar);
372+
user_config.set("mqtt_grid_ie", grid_ie);
373+
user_config.set("mqtt_live_pwr", live_pwr);
374+
user_config.set("flags", newflags);
375+
user_config.commit();
365376
}
366377

367378
void
368379
config_save_admin(String user, String pass) {
369-
config.set("www_username", user);
370-
config.set("www_password", pass);
371-
config.commit();
380+
user_config.set("www_username", user);
381+
user_config.set("www_password", pass);
382+
user_config.commit();
372383
}
373384

374385
void
@@ -379,9 +390,9 @@ config_save_sntp(bool sntp_enable, String tz)
379390
newflags |= CONFIG_SERVICE_SNTP;
380391
}
381392

382-
config.set("time_zone", tz);
383-
config.set("flags", newflags);
384-
config.commit();
393+
user_config.set("time_zone", tz);
394+
user_config.set("flags", newflags);
395+
user_config.commit();
385396

386397
config_set_timezone(tz);
387398
}
@@ -400,17 +411,17 @@ void config_set_timezone(String tz)
400411

401412
void
402413
config_save_advanced(String hostname, String sntp_host) {
403-
config.set("hostname", hostname);
404-
config.set("sntp_hostname", sntp_host);
405-
config.commit();
414+
user_config.set("hostname", hostname);
415+
user_config.set("sntp_hostname", sntp_host);
416+
user_config.commit();
406417
}
407418

408419
void
409420
config_save_wifi(String qsid, String qpass)
410421
{
411-
config.set("ssid", qsid);
412-
config.set("pass", qpass);
413-
config.commit();
422+
user_config.set("ssid", qsid);
423+
user_config.set("pass", qpass);
424+
user_config.commit();
414425
}
415426

416427
void
@@ -421,9 +432,9 @@ config_save_ohm(bool enable, String qohm)
421432
newflags |= CONFIG_SERVICE_OHM;
422433
}
423434

424-
config.set("ohm", qohm);
425-
config.set("flags", newflags);
426-
config.commit();
435+
user_config.set("ohm", qohm);
436+
user_config.set("flags", newflags);
437+
user_config.commit();
427438
}
428439

429440
void
@@ -432,19 +443,20 @@ config_save_rfid(bool enable, String storage){
432443
if(enable) {
433444
newflags |= CONFIG_RFID;
434445
}
435-
config.set("flags", newflags);
436-
config.set("rfid_storage", rfid_storage);
437-
config.commit();
446+
user_config.set("flags", newflags);
447+
user_config.set("rfid_storage", rfid_storage);
448+
user_config.commit();
438449
}
439450

440451
void
441452
config_save_flags(uint32_t newFlags) {
442-
config.set("flags", newFlags);
443-
config.commit();
453+
user_config.set("flags", newFlags);
454+
user_config.commit();
444455
}
445456

446457
void
447458
config_reset() {
448459
ResetEEPROM();
449-
config.reset();
460+
LittleFS.format();
461+
config_load_settings();
450462
}

src/app_config.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
extern String esid;
1717
extern String epass;
1818

19-
// Language
19+
// Language
2020
extern String lang;
2121

2222
// Web server authentication (leave blank for none)
@@ -93,7 +93,7 @@ extern uint32_t flags;
9393
#define CONFIG_RFID (1 << 18)
9494
#define CONFIG_SERVICE_CUR_SHAPER (1 << 19)
9595
#define CONFIG_MQTT_RETAINED (1 << 20)
96-
96+
#define CONFIG_FACTORY_WRITE_LOCK (1 << 21)
9797

9898
inline bool config_emoncms_enabled() {
9999
return CONFIG_SERVICE_EMONCMS == (flags & CONFIG_SERVICE_EMONCMS);
@@ -163,6 +163,10 @@ inline bool config_rfid_enabled() {
163163
return CONFIG_RFID == (flags & CONFIG_RFID);
164164
}
165165

166+
inline bool config_factory_write_lock() {
167+
return CONFIG_FACTORY_WRITE_LOCK == (flags & CONFIG_FACTORY_WRITE_LOCK);
168+
}
169+
166170
// Ohm Connect Settings
167171
extern String ohm;
168172

@@ -233,7 +237,7 @@ void config_set(const char *name, double val);
233237
bool config_deserialize(String& json);
234238
bool config_deserialize(const char *json);
235239
bool config_deserialize(DynamicJsonDocument &doc);
236-
void config_commit();
240+
void config_commit(bool factory = false);
237241

238242
// Write config settings to JSON object
239243
bool config_serialize(String& json, bool longNames = true, bool compactOutput = false, bool hideSecrets = false);

src/app_config_v1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#define EEPROM_MQTT_PORT_SIZE 4
2626
#define EEPROM_SNTP_HOST_SIZE 45
2727
#define EEPROM_TIME_ZONE_SIZE 80
28-
#define EEPROM_SIZE 1024
28+
#define EEPROM_SIZE 4096
2929

3030
#define EEPROM_ESID_START 0
3131
#define EEPROM_ESID_END (EEPROM_ESID_START + EEPROM_ESID_SIZE)

src/web_server_config.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ typedef const __FlashStringHelper *fstr_t;
1515

1616
uint32_t config_version = 0;
1717

18+
extern bool isPositive(MongooseHttpServerRequest *request, const char *param);
19+
1820
// -------------------------------------------------------------------
1921
// Returns OpenEVSE Config json
2022
// url: /config
@@ -79,8 +81,17 @@ handleConfigPost(MongooseHttpServerRequest *request, MongooseHttpServerResponseS
7981
bool config_modified = false;
8082

8183
// Update WiFi module config
82-
if(config_deserialize(doc)) {
83-
config_commit();
84+
MongooseString storage = request->headers("X-Storage");
85+
if(storage.equals("factory") && config_factory_write_lock())
86+
{
87+
response->setCode(423);
88+
response->print("{\"msg\":\"Factory settings locked\"}");
89+
return;
90+
}
91+
92+
if(config_deserialize(doc))
93+
{
94+
config_commit(storage.equals("factory"));
8495
config_modified = true;
8596
DBUGLN("Config updated");
8697
}

test/config.http

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,17 @@ Content-Type: application/json
252252
"pass": "{{pass}}"
253253
}
254254

255+
###
256+
257+
# Set a factory username/password
258+
259+
POST {{baseUrl}}/config?factory=true HTTP/1.1
260+
Content-Type: application/json
261+
Authorization: Basic admin:admin
262+
X-Storage: factory
263+
264+
{
265+
"www_username": "admin",
266+
"www_password": "admin"
267+
}
268+

0 commit comments

Comments
 (0)