Advanced locking with time-out.
Bugfixes.
This commit is contained in:
parent
ce5a81d83c
commit
85ded6e500
@ -1092,16 +1092,17 @@ void WS2812FX::deserializeMap(uint8_t n) {
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_PRINT(F("Reading LED map from "));
|
DEBUG_PRINT(F("Reading LED map from "));
|
||||||
DEBUG_PRINTLN(fileName);
|
DEBUG_PRINTLN(fileName);
|
||||||
|
|
||||||
if (!readObjectFromFile(fileName, nullptr, &doc)) {
|
if (!readObjectFromFile(fileName, nullptr, &doc)) {
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
return; //if file does not exist just exit
|
return; //if file does not exist just exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1121,7 +1122,7 @@ void WS2812FX::deserializeMap(uint8_t n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//gamma 2.8 lookup table used for color correction
|
//gamma 2.8 lookup table used for color correction
|
||||||
|
@ -410,12 +410,12 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
DEBUG_PRINTLN(F("Starting usermod config."));
|
DEBUG_PRINTLN(F("Starting usermod config."));
|
||||||
JsonObject usermods_settings = doc["um"];
|
JsonObject usermods_settings = doc["um"];
|
||||||
if (!usermods_settings.isNull()) {
|
if (!usermods_settings.isNull()) {
|
||||||
needsSave = usermods.readFromConfig(usermods_settings);
|
needsSave = !usermods.readFromConfig(usermods_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromFS) return needsSave;
|
if (fromFS) return needsSave;
|
||||||
doReboot = doc[F("rb")] | doReboot;
|
doReboot = doc[F("rb")] | doReboot;
|
||||||
return (doc["sv"] | needsSave);
|
return (doc["sv"] | true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deserializeConfigFromFS() {
|
void deserializeConfigFromFS() {
|
||||||
@ -428,9 +428,10 @@ void deserializeConfigFromFS() {
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_PRINTLN(F("Reading settings from /cfg.json..."));
|
DEBUG_PRINTLN(F("Reading settings from /cfg.json..."));
|
||||||
@ -438,14 +439,14 @@ void deserializeConfigFromFS() {
|
|||||||
success = readObjectFromFile("/cfg.json", nullptr, &doc);
|
success = readObjectFromFile("/cfg.json", nullptr, &doc);
|
||||||
if (!success) { //if file does not exist, try reading from EEPROM
|
if (!success) { //if file does not exist, try reading from EEPROM
|
||||||
deEEPSettings();
|
deEEPSettings();
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: This routine deserializes *and* applies the configuration
|
// NOTE: This routine deserializes *and* applies the configuration
|
||||||
// Therefore, must also initialize ethernet from this function
|
// Therefore, must also initialize ethernet from this function
|
||||||
bool needsSave = deserializeConfig(doc.as<JsonObject>(), true);
|
bool needsSave = deserializeConfig(doc.as<JsonObject>(), true);
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
|
|
||||||
if (needsSave) serializeConfig(); // usermods required new prameters
|
if (needsSave) serializeConfig(); // usermods required new prameters
|
||||||
}
|
}
|
||||||
@ -458,9 +459,10 @@ void serializeConfig() {
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonArray rev = doc.createNestedArray("rev");
|
JsonArray rev = doc.createNestedArray("rev");
|
||||||
@ -768,7 +770,7 @@ void serializeConfig() {
|
|||||||
File f = WLED_FS.open("/cfg.json", "w");
|
File f = WLED_FS.open("/cfg.json", "w");
|
||||||
if (f) serializeJson(doc, f);
|
if (f) serializeJson(doc, f);
|
||||||
f.close();
|
f.close();
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//settings in /wsec.json, not accessible via webserver, for passwords and tokens
|
//settings in /wsec.json, not accessible via webserver, for passwords and tokens
|
||||||
@ -778,14 +780,15 @@ bool deserializeConfigSec() {
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool success = readObjectFromFile("/wsec.json", nullptr, &doc);
|
bool success = readObjectFromFile("/wsec.json", nullptr, &doc);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,7 +822,7 @@ bool deserializeConfigSec() {
|
|||||||
CJSON(wifiLock, ota[F("lock-wifi")]);
|
CJSON(wifiLock, ota[F("lock-wifi")]);
|
||||||
CJSON(aOtaEnabled, ota[F("aota")]);
|
CJSON(aOtaEnabled, ota[F("aota")]);
|
||||||
|
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,9 +832,10 @@ void serializeConfigSec() {
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject nw = doc.createNestedObject("nw");
|
JsonObject nw = doc.createNestedObject("nw");
|
||||||
@ -867,5 +871,5 @@ void serializeConfigSec() {
|
|||||||
File f = WLED_FS.open("/wsec.json", "w");
|
File f = WLED_FS.open("/wsec.json", "w");
|
||||||
if (f) serializeJson(doc, f);
|
if (f) serializeJson(doc, f);
|
||||||
f.close();
|
f.close();
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,8 @@ void sappends(char stype, const char* key, char* val);
|
|||||||
void prepareHostname(char* hostname);
|
void prepareHostname(char* hostname);
|
||||||
void _setRandomColor(bool _sec, bool fromButton);
|
void _setRandomColor(bool _sec, bool fromButton);
|
||||||
bool isAsterisksOnly(const char* str, byte maxLen);
|
bool isAsterisksOnly(const char* str, byte maxLen);
|
||||||
|
bool requestJSONBufferLock();
|
||||||
|
void releaseJSONBufferLock();
|
||||||
|
|
||||||
//wled_eeprom.cpp
|
//wled_eeprom.cpp
|
||||||
void applyMacro(byte index);
|
void applyMacro(byte index);
|
||||||
|
@ -575,12 +575,14 @@ void decodeIRJson(uint32_t code)
|
|||||||
JsonObject fdo;
|
JsonObject fdo;
|
||||||
JsonObject jsonCmdObj;
|
JsonObject jsonCmdObj;
|
||||||
|
|
||||||
|
DEBUG_PRINTLN(F("IR JSON buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sprintf_P(objKey, PSTR("\"0x%lX\":"), (unsigned long)code);
|
sprintf_P(objKey, PSTR("\"0x%lX\":"), (unsigned long)code);
|
||||||
@ -601,6 +603,9 @@ void decodeIRJson(uint32_t code)
|
|||||||
cmdStr = fdo["cmd"].as<String>();;
|
cmdStr = fdo["cmd"].as<String>();;
|
||||||
jsonCmdObj = fdo["cmd"]; //object
|
jsonCmdObj = fdo["cmd"]; //object
|
||||||
|
|
||||||
|
// command is JSON object
|
||||||
|
//allow applyPreset() to reuse JSON buffer, or it would alloc. a second buffer and run out of mem.
|
||||||
|
//fileDoc = &doc; // used for applying presets (presets.cpp)
|
||||||
if (!cmdStr.isEmpty())
|
if (!cmdStr.isEmpty())
|
||||||
{
|
{
|
||||||
if (cmdStr.startsWith("!")) {
|
if (cmdStr.startsWith("!")) {
|
||||||
@ -635,13 +640,10 @@ void decodeIRJson(uint32_t code)
|
|||||||
}
|
}
|
||||||
colorUpdated(CALL_MODE_BUTTON);
|
colorUpdated(CALL_MODE_BUTTON);
|
||||||
} else if (!jsonCmdObj.isNull()) {
|
} else if (!jsonCmdObj.isNull()) {
|
||||||
// command is JSON object
|
|
||||||
//allow applyPreset() to reuse JSON buffer, or it would alloc. a second buffer and run out of mem.
|
|
||||||
fileDoc = &doc;
|
|
||||||
deserializeState(jsonCmdObj, CALL_MODE_BUTTON);
|
deserializeState(jsonCmdObj, CALL_MODE_BUTTON);
|
||||||
fileDoc = nullptr;
|
|
||||||
}
|
}
|
||||||
jsonBufferLock = false;
|
//fileDoc = nullptr;
|
||||||
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initIR()
|
void initIR()
|
||||||
|
@ -920,9 +920,10 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(JSON_BUFFER_SIZE);
|
AsyncJsonResponse* response = new AsyncJsonResponse(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
AsyncJsonResponse *response = new AsyncJsonResponse(&doc);
|
AsyncJsonResponse *response = new AsyncJsonResponse(&doc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -956,7 +957,7 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_LIVE_LEDS 180
|
#define MAX_LIVE_LEDS 180
|
||||||
|
@ -90,26 +90,26 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
|||||||
colorFromDecOrHexString(col, (char*)payloadStr);
|
colorFromDecOrHexString(col, (char*)payloadStr);
|
||||||
colorUpdated(CALL_MODE_DIRECT_CHANGE);
|
colorUpdated(CALL_MODE_DIRECT_CHANGE);
|
||||||
} else if (strcmp_P(topic, PSTR("/api")) == 0) {
|
} else if (strcmp_P(topic, PSTR("/api")) == 0) {
|
||||||
if (payload[0] == '{') { //JSON API
|
DEBUG_PRINTLN(F("MQTT JSON buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (payload[0] == '{') { //JSON API
|
||||||
deserializeJson(doc, payloadStr);
|
deserializeJson(doc, payloadStr);
|
||||||
fileDoc = &doc;
|
//fileDoc = &doc; // used for applying presets (presets.cpp)
|
||||||
deserializeState(doc.as<JsonObject>());
|
deserializeState(doc.as<JsonObject>());
|
||||||
fileDoc = nullptr;
|
//fileDoc = nullptr;
|
||||||
|
|
||||||
jsonBufferLock = false;
|
|
||||||
} else { //HTTP API
|
} else { //HTTP API
|
||||||
String apireq = "win&";
|
String apireq = "win&";
|
||||||
apireq += (char*)payloadStr;
|
apireq += (char*)payloadStr;
|
||||||
handleSet(nullptr, apireq);
|
handleSet(nullptr, apireq);
|
||||||
}
|
}
|
||||||
|
releaseJSONBufferLock();
|
||||||
} else if (strlen(topic) != 0) {
|
} else if (strlen(topic) != 0) {
|
||||||
// non standard topic, check with usermods
|
// non standard topic, check with usermods
|
||||||
usermods.onMqttMessage(topic, payloadStr);
|
usermods.onMqttMessage(topic, payloadStr);
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
* Methods to handle saving and loading presets to/from the filesystem
|
* Methods to handle saving and loading presets to/from the filesystem
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// called from: handleSet(), deserializeState(), applyMacro(), handlePlaylist(), checkCountdown(), checkTimers(), handleNightlight(), presetFallback()
|
||||||
|
// shortPressAction(), longPressAction(), doublePressAction(), handleSwitch(), onAlexaChange()
|
||||||
bool applyPreset(byte index, byte callMode)
|
bool applyPreset(byte index, byte callMode)
|
||||||
{
|
{
|
||||||
if (index == 0) return false;
|
if (index == 0) return false;
|
||||||
@ -19,13 +21,14 @@ bool applyPreset(byte index, byte callMode)
|
|||||||
#endif
|
#endif
|
||||||
deserializeState(fdo, callMode, index);
|
deserializeState(fdo, callMode, index);
|
||||||
} else {
|
} else {
|
||||||
DEBUGFS_PRINTLN(F("Make read buf"));
|
DEBUG_PRINTLN(F("Apply preset JSON buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
errorFlag = readObjectFromFileUsingId(filename, index, &doc) ? ERR_NONE : ERR_FS_PLOAD;
|
errorFlag = readObjectFromFileUsingId(filename, index, &doc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||||
@ -35,7 +38,7 @@ bool applyPreset(byte index, byte callMode)
|
|||||||
serializeJson(doc, Serial);
|
serializeJson(doc, Serial);
|
||||||
#endif
|
#endif
|
||||||
deserializeState(fdo, callMode, index);
|
deserializeState(fdo, callMode, index);
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errorFlag) {
|
if (!errorFlag) {
|
||||||
@ -53,13 +56,14 @@ void savePreset(byte index, bool persist, const char* pname, JsonObject saveobj)
|
|||||||
const char *filename = persist ? "/presets.json" : "/tmp.json";
|
const char *filename = persist ? "/presets.json" : "/tmp.json";
|
||||||
|
|
||||||
if (!fileDoc) {
|
if (!fileDoc) {
|
||||||
DEBUGFS_PRINTLN(F("Allocating saving buffer"));
|
DEBUG_PRINTLN(F("Save preset JSON buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sObj = doc.to<JsonObject>();
|
sObj = doc.to<JsonObject>();
|
||||||
@ -71,7 +75,7 @@ void savePreset(byte index, bool persist, const char* pname, JsonObject saveobj)
|
|||||||
|
|
||||||
writeObjectToFileUsingId(filename, index, &doc);
|
writeObjectToFileUsingId(filename, index, &doc);
|
||||||
|
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
} else { //from JSON API (fileDoc != nullptr)
|
} else { //from JSON API (fileDoc != nullptr)
|
||||||
DEBUGFS_PRINTLN(F("Reuse recv buffer"));
|
DEBUGFS_PRINTLN(F("Reuse recv buffer"));
|
||||||
sObj.remove(F("psave"));
|
sObj.remove(F("psave"));
|
||||||
|
@ -418,9 +418,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject um = doc.createNestedObject("um");
|
JsonObject um = doc.createNestedObject("um");
|
||||||
@ -497,7 +498,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
usermods.readFromConfig(um); // force change of usermod parameters
|
usermods.readFromConfig(um); // force change of usermod parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
|
|
||||||
if (subPage != 2 && (subPage != 6 || !doReboot)) serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init)
|
if (subPage != 2 && (subPage != 6 || !doReboot)) serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init)
|
||||||
if (subPage == 4) alexaInit();
|
if (subPage == 4) alexaInit();
|
||||||
|
@ -129,3 +129,27 @@ bool isAsterisksOnly(const char* str, byte maxLen)
|
|||||||
//at this point the password contains asterisks only
|
//at this point the password contains asterisks only
|
||||||
return (str[0] != 0); //false on empty string
|
return (str[0] != 0); //false on empty string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool requestJSONBufferLock()
|
||||||
|
{
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
|
while (jsonBufferLock && millis()-now < 1000) delay(1); // wait for a second for buffer lock
|
||||||
|
|
||||||
|
if (millis()-now >= 1000) return false; // waiting time-outed
|
||||||
|
|
||||||
|
jsonBufferLock = true;
|
||||||
|
fileDoc = &doc; // used for applying presets (presets.cpp)
|
||||||
|
doc.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void releaseJSONBufferLock()
|
||||||
|
{
|
||||||
|
#ifndef WLED_USE_DYNAMIC_JSON
|
||||||
|
fileDoc = nullptr;
|
||||||
|
jsonBufferLock = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2111091
|
#define VERSION 2111121
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
|
@ -385,9 +385,10 @@ void deEEP() {
|
|||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject sObj = doc.to<JsonObject>();
|
JsonObject sObj = doc.to<JsonObject>();
|
||||||
@ -473,7 +474,7 @@ void deEEP() {
|
|||||||
serializeJson(doc, f);
|
serializeJson(doc, f);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
|
|
||||||
DEBUG_PRINTLN(F("deEEP complete!"));
|
DEBUG_PRINTLN(F("deEEP complete!"));
|
||||||
}
|
}
|
||||||
|
@ -43,22 +43,24 @@ void handleSerial()
|
|||||||
}
|
}
|
||||||
else if (next == '{') { //JSON API
|
else if (next == '{') { //JSON API
|
||||||
bool verboseResponse = false;
|
bool verboseResponse = false;
|
||||||
|
DEBUG_PRINTLN(F("Serial JSON buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
Serial.setTimeout(100);
|
Serial.setTimeout(100);
|
||||||
DeserializationError error = deserializeJson(doc, Serial);
|
DeserializationError error = deserializeJson(doc, Serial);
|
||||||
if (error) {
|
if (error) {
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileDoc = &doc;
|
//fileDoc = &doc; // used for applying presets (presets.cpp)
|
||||||
verboseResponse = deserializeState(doc.as<JsonObject>());
|
verboseResponse = deserializeState(doc.as<JsonObject>());
|
||||||
fileDoc = nullptr;
|
//fileDoc = nullptr;
|
||||||
|
|
||||||
//only send response if TX pin is unused for other purposes
|
//only send response if TX pin is unused for other purposes
|
||||||
if (verboseResponse && !pinManager.isPinAllocated(1)) {
|
if (verboseResponse && !pinManager.isPinAllocated(1)) {
|
||||||
@ -70,7 +72,7 @@ void handleSerial()
|
|||||||
|
|
||||||
serializeJson(doc, Serial);
|
serializeJson(doc, Serial);
|
||||||
}
|
}
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AdaState::Header_d:
|
case AdaState::Header_d:
|
||||||
|
@ -110,12 +110,14 @@ void initServer()
|
|||||||
bool verboseResponse = false;
|
bool verboseResponse = false;
|
||||||
bool isConfig = false;
|
bool isConfig = false;
|
||||||
{ //scope JsonDocument so it releases its buffer
|
{ //scope JsonDocument so it releases its buffer
|
||||||
|
DEBUG_PRINTLN(F("HTTP JSON buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(doc, (uint8_t*)(request->_tempObject));
|
DeserializationError error = deserializeJson(doc, (uint8_t*)(request->_tempObject));
|
||||||
@ -131,13 +133,13 @@ void initServer()
|
|||||||
serializeJson(root,Serial);
|
serializeJson(root,Serial);
|
||||||
DEBUG_PRINTLN();
|
DEBUG_PRINTLN();
|
||||||
#endif
|
#endif
|
||||||
fileDoc = &doc; // used for applying presets (presets.cpp)
|
//fileDoc = &doc; // used for applying presets (presets.cpp)
|
||||||
verboseResponse = deserializeState(root);
|
verboseResponse = deserializeState(root);
|
||||||
fileDoc = nullptr;
|
//fileDoc = nullptr;
|
||||||
} else {
|
} else {
|
||||||
verboseResponse = deserializeConfig(root); //use verboseResponse to determine whether cfg change should be saved immediately
|
verboseResponse = deserializeConfig(root); //use verboseResponse to determine whether cfg change should be saved immediately
|
||||||
}
|
}
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
if (verboseResponse) {
|
if (verboseResponse) {
|
||||||
if (!isConfig) {
|
if (!isConfig) {
|
||||||
|
@ -36,18 +36,20 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
|||||||
}
|
}
|
||||||
bool verboseResponse = false;
|
bool verboseResponse = false;
|
||||||
{ //scope JsonDocument so it releases its buffer
|
{ //scope JsonDocument so it releases its buffer
|
||||||
|
DEBUG_PRINTLN(F("WS JSON receive buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(doc, data, len);
|
DeserializationError error = deserializeJson(doc, data, len);
|
||||||
JsonObject root = doc.as<JsonObject>();
|
JsonObject root = doc.as<JsonObject>();
|
||||||
if (error || root.isNull()) {
|
if (error || root.isNull()) {
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -64,15 +66,15 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
|||||||
{
|
{
|
||||||
wsLiveClientId = root["lv"] ? client->id() : 0;
|
wsLiveClientId = root["lv"] ? client->id() : 0;
|
||||||
} else {
|
} else {
|
||||||
fileDoc = &doc;
|
//fileDoc = &doc; // used for applying presets (presets.cpp)
|
||||||
verboseResponse = deserializeState(root);
|
verboseResponse = deserializeState(root);
|
||||||
fileDoc = nullptr;
|
//fileDoc = nullptr;
|
||||||
if (!interfaceUpdateCallMode) {
|
if (!interfaceUpdateCallMode) {
|
||||||
//special case, only on playlist load, avoid sending twice in rapid succession
|
//special case, only on playlist load, avoid sending twice in rapid succession
|
||||||
if (millis() - lastInterfaceUpdate > 1700) verboseResponse = false;
|
if (millis() - lastInterfaceUpdate > 1700) verboseResponse = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
//update if it takes longer than 300ms until next "broadcast"
|
//update if it takes longer than 300ms until next "broadcast"
|
||||||
if (verboseResponse && (millis() - lastInterfaceUpdate < 1700 || !interfaceUpdateCallMode)) sendDataWs(client);
|
if (verboseResponse && (millis() - lastInterfaceUpdate < 1700 || !interfaceUpdateCallMode)) sendDataWs(client);
|
||||||
@ -114,12 +116,14 @@ void sendDataWs(AsyncWebSocketClient * client)
|
|||||||
AsyncWebSocketMessageBuffer * buffer;
|
AsyncWebSocketMessageBuffer * buffer;
|
||||||
|
|
||||||
{ //scope JsonDocument so it releases its buffer
|
{ //scope JsonDocument so it releases its buffer
|
||||||
|
DEBUG_PRINTLN(F("WS JSON send buffer requested."));
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject state = doc.createNestedObject("state");
|
JsonObject state = doc.createNestedObject("state");
|
||||||
@ -129,7 +133,7 @@ void sendDataWs(AsyncWebSocketClient * client)
|
|||||||
size_t len = measureJson(doc);
|
size_t len = measureJson(doc);
|
||||||
buffer = ws.makeBuffer(len);
|
buffer = ws.makeBuffer(len);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
return; //out of memory
|
return; //out of memory
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -140,7 +144,7 @@ void sendDataWs(AsyncWebSocketClient * client)
|
|||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
serializeJson(doc, (char *)buffer->get(), len +1);
|
serializeJson(doc, (char *)buffer->get(), len +1);
|
||||||
jsonBufferLock = false;
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
DEBUG_PRINT(F("Sending WS data "));
|
DEBUG_PRINT(F("Sending WS data "));
|
||||||
if (client) {
|
if (client) {
|
||||||
|
@ -254,17 +254,19 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
oappend(SET_F("d.um_p=[6,7,8,9,10,11"));
|
oappend(SET_F("d.um_p=[6,7,8,9,10,11"));
|
||||||
|
|
||||||
#ifdef WLED_USE_DYNAMIC_JSON
|
#ifdef WLED_USE_DYNAMIC_JSON
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(2048); // 2k is enough for usermods
|
||||||
#else
|
#else
|
||||||
while (jsonBufferLock) delay(1);
|
if (!requestJSONBufferLock()) {
|
||||||
jsonBufferLock = true;
|
DEBUG_PRINTLN(F("ERROR: Locking JSON buffer failed!"));
|
||||||
doc.clear();
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject mods = doc.createNestedObject(F("um"));
|
JsonObject mods = doc.createNestedObject(F("um"));
|
||||||
usermods.addToConfig(mods);
|
usermods.addToConfig(mods);
|
||||||
if (!mods.isNull()) fillUMPins(mods);
|
if (!mods.isNull()) fillUMPins(mods);
|
||||||
jsonBufferLock = false;
|
|
||||||
|
releaseJSONBufferLock();
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_DMX
|
#ifdef WLED_ENABLE_DMX
|
||||||
oappend(SET_F(",2")); // DMX hardcoded pin
|
oappend(SET_F(",2")); // DMX hardcoded pin
|
||||||
|
Loading…
Reference in New Issue
Block a user