mirror of
https://github.com/wled/WLED.git
synced 2025-04-24 14:57:18 +00:00
ESP-NOW packet modification
- include up to 5 segments in 1st packet - header contains total number of packets (instead of segments) web server code reorganise
This commit is contained in:
parent
2d30535b69
commit
95e2e574b8
@ -253,6 +253,7 @@ void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
|
||||
void refreshNodeList();
|
||||
void sendSysInfoUDP();
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
void espNowSentCB(uint8_t* address, uint8_t status);
|
||||
void espNowReceiveCB(uint8_t* address, uint8_t* data, uint8_t len, signed int rssi, bool broadcast);
|
||||
#endif
|
||||
|
||||
@ -428,15 +429,10 @@ void handleSerial();
|
||||
void updateBaudRate(uint32_t rate);
|
||||
|
||||
//wled_server.cpp
|
||||
bool isIp(String str);
|
||||
void createEditHandler(bool enable);
|
||||
bool captivePortal(AsyncWebServerRequest *request);
|
||||
void initServer();
|
||||
void serveIndex(AsyncWebServerRequest* request);
|
||||
String msgProcessor(const String& var);
|
||||
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255);
|
||||
void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t error);
|
||||
String dmxProcessor(const String& var);
|
||||
void serveSettings(AsyncWebServerRequest* request, bool post = false);
|
||||
void serveSettingsJS(AsyncWebServerRequest* request);
|
||||
|
||||
@ -447,7 +443,6 @@ void sendDataWs(AsyncWebSocketClient * client = nullptr);
|
||||
|
||||
//xml.cpp
|
||||
void XML_response(AsyncWebServerRequest *request, char* dest = nullptr);
|
||||
void URL_response(AsyncWebServerRequest *request);
|
||||
void getSettingsJS(byte subPage, char* dest);
|
||||
|
||||
#endif
|
||||
|
@ -13,7 +13,7 @@
|
||||
typedef struct PartialEspNowPacket {
|
||||
uint8_t magic;
|
||||
uint8_t packet;
|
||||
uint8_t segs;
|
||||
uint8_t noOfPackets;
|
||||
uint8_t data[247];
|
||||
} partial_packet_t;
|
||||
|
||||
@ -151,20 +151,32 @@ void notify(byte callMode, bool followUp)
|
||||
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
if (enableESPNow && useESPNowSync && statusESPNow == ESP_NOW_STATE_ON) {
|
||||
partial_packet_t buffer = {'W', 0, (uint8_t)s, {0}};
|
||||
partial_packet_t buffer = {'W', 0, 1, {0}};
|
||||
// send global data
|
||||
DEBUG_PRINTLN(F("ESP-NOW sending first packet."));
|
||||
memcpy(buffer.data, udpOut, 41);
|
||||
auto err = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, reinterpret_cast<const uint8_t*>(&buffer), 41+3);
|
||||
if (!err) {
|
||||
// send segment data
|
||||
DEBUG_PRINTLN(F("ESP-NOW sending first packet."));
|
||||
const size_t bufferSize = sizeof(buffer.data)/sizeof(uint8_t);
|
||||
size_t packetSize = 41;
|
||||
size_t s0 = 0;
|
||||
memcpy(buffer.data, udpOut, packetSize);
|
||||
// stuff as many segments in first packet as possible (normally up to 5)
|
||||
for (size_t i = 0; packetSize < bufferSize && i < s; i++) {
|
||||
memcpy(buffer.data + packetSize, &udpOut[41+i*UDP_SEG_SIZE], UDP_SEG_SIZE);
|
||||
packetSize += UDP_SEG_SIZE;
|
||||
s0++;
|
||||
}
|
||||
if (s > s0) buffer.noOfPackets += 1 + ((s - s0) * UDP_SEG_SIZE) / bufferSize; // set number of packets
|
||||
auto err = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, reinterpret_cast<const uint8_t*>(&buffer), packetSize+3);
|
||||
if (!err && s0 < s) {
|
||||
// send rest of the segments
|
||||
buffer.packet++;
|
||||
size_t packetSize = 0;
|
||||
int32_t err = 0;
|
||||
for (size_t i = 0; i < s; i++) {
|
||||
packetSize = 0;
|
||||
// WARNING: this will only work for up to 3 messages (~17 segments) as QuickESPNOW only has a ring buffer capable of holding 3 queued messages
|
||||
// to work around that limitation it is mandatory to utilize onDataSent() callback which should reduce number queued messages
|
||||
// and wait until at least one space is available in the buffer
|
||||
for (size_t i = s0; i < s; i++) {
|
||||
memcpy(buffer.data + packetSize, &udpOut[41+i*UDP_SEG_SIZE], UDP_SEG_SIZE);
|
||||
packetSize += UDP_SEG_SIZE;
|
||||
if (packetSize + UDP_SEG_SIZE < sizeof(buffer.data)/sizeof(uint8_t)) continue;
|
||||
if (packetSize + UDP_SEG_SIZE < bufferSize) continue;
|
||||
DEBUG_PRINTF("ESP-NOW sending packet: %d (%d)\n", (int)buffer.packet, packetSize+3);
|
||||
err = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, reinterpret_cast<const uint8_t*>(&buffer), packetSize+3);
|
||||
buffer.packet++;
|
||||
@ -175,9 +187,9 @@ void notify(byte callMode, bool followUp)
|
||||
DEBUG_PRINTF("ESP-NOW sending last packet: %d (%d)\n", (int)buffer.packet, packetSize+3);
|
||||
err = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, reinterpret_cast<const uint8_t*>(&buffer), packetSize+3);
|
||||
}
|
||||
if (err) {
|
||||
DEBUG_PRINTLN(F("ESP-NOW sending packet failed."));
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
DEBUG_PRINTLN(F("ESP-NOW sending packet failed."));
|
||||
}
|
||||
}
|
||||
if (udpConnected)
|
||||
@ -942,6 +954,11 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8
|
||||
}
|
||||
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
// ESP-NOW message sent callback function
|
||||
void espNowSentCB(uint8_t* address, uint8_t status) {
|
||||
DEBUG_PRINTF("Message sent to " MACSTR ", status: %d\n", MAC2STR(address), status);
|
||||
}
|
||||
|
||||
// ESP-NOW message receive callback function
|
||||
void espNowReceiveCB(uint8_t* address, uint8_t* data, uint8_t len, signed int rssi, bool broadcast) {
|
||||
sprintf_P(last_signal_src, PSTR("%02x%02x%02x%02x%02x%02x"), address[0], address[1], address[2], address[3], address[4], address[5]);
|
||||
@ -970,19 +987,35 @@ void espNowReceiveCB(uint8_t* address, uint8_t* data, uint8_t len, signed int rs
|
||||
}
|
||||
|
||||
static uint8_t *udpIn = nullptr;
|
||||
static uint8_t packetsReceived = 0; // bitfield (max 5 packets ATM)
|
||||
static uint8_t packetsReceived = 0;
|
||||
static uint8_t segsReceived = 0;
|
||||
static unsigned long lastProcessed = 0;
|
||||
|
||||
if (buffer->packet == 0) {
|
||||
if (udpIn == nullptr) udpIn = (uint8_t *)malloc(WLEDPACKETSIZE); // we cannot use stack as we are in callback
|
||||
DEBUG_PRINTLN(F("ESP-NOW inited UDP buffer."));
|
||||
memcpy(udpIn, buffer->data, len-3); // global data (41 bytes)
|
||||
packetsReceived |= 0x01 << buffer->packet;
|
||||
segsReceived = 0;
|
||||
return;
|
||||
} else if (((len-3)/UDP_SEG_SIZE)*UDP_SEG_SIZE != (len-3)) {
|
||||
DEBUG_PRINTF("ESP-NOW incorrect packet size: %d (%d) [%d]\n", (int)buffer->packet, (int)len-3, (int)UDP_SEG_SIZE);
|
||||
packetsReceived = 0; // it will increment later (this is to make sure we start counting packets correctly)
|
||||
if (udpIn == nullptr) {
|
||||
udpIn = (uint8_t *)malloc(WLEDPACKETSIZE); // we cannot use stack as we are in callback
|
||||
if (!udpIn) return; // memory alocation failed
|
||||
DEBUG_PRINTLN(F("ESP-NOW inited UDP buffer."));
|
||||
}
|
||||
memcpy(udpIn, buffer->data, len-3); // global data (41 bytes + up to 5 segments)
|
||||
segsReceived = (len - 3 - 41) / UDP_SEG_SIZE;
|
||||
} else if (buffer->packet == packetsReceived && udpIn && ((len - 3) / UDP_SEG_SIZE) * UDP_SEG_SIZE == (len-3)) {
|
||||
// we received a packet full of segments
|
||||
if (segsReceived >= MAX_NUM_SEGMENTS) {
|
||||
// we are already past max segments, just ignore
|
||||
DEBUG_PRINTLN(F("ESP-NOW received segments past maximum."));
|
||||
len = 3;
|
||||
} else if ((segsReceived + ((len - 3) / UDP_SEG_SIZE)) >= MAX_NUM_SEGMENTS) {
|
||||
len = ((MAX_NUM_SEGMENTS - segsReceived) * UDP_SEG_SIZE) + 3; // we have reached max number of segments
|
||||
}
|
||||
if (len > 3) {
|
||||
memcpy(udpIn + 41 + (segsReceived * UDP_SEG_SIZE), buffer->data, len-3);
|
||||
segsReceived += (len - 3) / UDP_SEG_SIZE;
|
||||
}
|
||||
} else {
|
||||
// any out of order packet or incorrectly sized packet or if we have no UDP buffer will abort
|
||||
DEBUG_PRINTF("ESP-NOW incorrect packet: %d (%d) [%d]\n", (int)buffer->packet, (int)len-3, (int)UDP_SEG_SIZE);
|
||||
if (udpIn) free(udpIn);
|
||||
udpIn = nullptr;
|
||||
packetsReceived = 0;
|
||||
@ -991,15 +1024,9 @@ void espNowReceiveCB(uint8_t* address, uint8_t* data, uint8_t len, signed int rs
|
||||
}
|
||||
if (!udpIn) return;
|
||||
|
||||
// TODO add verification if segsReceived > MAX_NUM_SEGMENTS or WLEDPACKETSIZE
|
||||
|
||||
memcpy(udpIn+41+segsReceived, buffer->data, len-3);
|
||||
packetsReceived |= 0x01 << buffer->packet;
|
||||
segsReceived += (len-3)/UDP_SEG_SIZE;
|
||||
|
||||
DEBUG_PRINTF("ESP-NOW packet received: %d (%d) [%d]\n", (int)buffer->packet, (int)len-3, (int)segsReceived);
|
||||
|
||||
if (segsReceived == buffer->segs) {
|
||||
packetsReceived++;
|
||||
DEBUG_PRINTF("ESP-NOW packet received: %d (%d/%d) s:[%d/%d]\n", (int)buffer->packet, (int)packetsReceived, (int)buffer->noOfPackets, (int)segsReceived, MAX_NUM_SEGMENTS);
|
||||
if (packetsReceived >= buffer->noOfPackets) {
|
||||
// last packet received
|
||||
if (millis() - lastProcessed > 250) {
|
||||
DEBUG_PRINTLN(F("ESP-NOW processing complete message."));
|
||||
|
@ -247,6 +247,9 @@ void WLED::loop()
|
||||
}
|
||||
#endif
|
||||
DEBUG_PRINT(F("Wifi state: ")); DEBUG_PRINTLN(WiFi.status());
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
DEBUG_PRINT(F("ESP-NOW state: ")); DEBUG_PRINTLN(statusESPNow);
|
||||
#endif
|
||||
|
||||
if (WiFi.status() != lastWifiState) {
|
||||
wifiStateChangedTime = millis();
|
||||
@ -834,7 +837,8 @@ void WLED::initConnection()
|
||||
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
if (enableESPNow) {
|
||||
quickEspNow.onDataRcvd(espNowReceiveCB);
|
||||
quickEspNow.onDataSent(espNowSentCB); // see udp.cpp
|
||||
quickEspNow.onDataRcvd(espNowReceiveCB); // see udp.cpp
|
||||
bool espNowOK;
|
||||
if (apActive) {
|
||||
DEBUG_PRINTLN(F("ESP-NOW initing in AP mode."));
|
||||
|
@ -11,14 +11,6 @@
|
||||
#endif
|
||||
#include "html_cpal.h"
|
||||
|
||||
/*
|
||||
* Integrated HTTP web server page declarations
|
||||
*/
|
||||
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request, int code, uint16_t eTagSuffix = 0);
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix = 0);
|
||||
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip = true, uint16_t eTagSuffix = 0);
|
||||
|
||||
// define flash strings once (saves flash memory)
|
||||
static const char s_redirecting[] PROGMEM = "Redirecting...";
|
||||
static const char s_content_enc[] PROGMEM = "Content-Encoding";
|
||||
@ -33,7 +25,7 @@ static const char s_plain[] PROGMEM = "text/plain";
|
||||
static const char s_css[] PROGMEM = "text/css";
|
||||
|
||||
//Is this an IP?
|
||||
bool isIp(String str) {
|
||||
static bool isIp(String str) {
|
||||
for (size_t i = 0; i < str.length(); i++) {
|
||||
int c = str.charAt(i);
|
||||
if (c != '.' && (c < '0' || c > '9')) {
|
||||
@ -43,7 +35,128 @@ bool isIp(String str) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
/*
|
||||
* Integrated HTTP web server page declarations
|
||||
*/
|
||||
|
||||
static void generateEtag(char *etag, uint16_t eTagSuffix) {
|
||||
sprintf_P(etag, PSTR("%7d-%02x-%04x"), VERSION, cacheInvalidate, eTagSuffix);
|
||||
}
|
||||
|
||||
static void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix = 0) {
|
||||
// Only send ETag for 200 (OK) responses
|
||||
if (code != 200) return;
|
||||
|
||||
// https://medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c
|
||||
#ifndef WLED_DEBUG
|
||||
// this header name is misleading, "no-cache" will not disable cache,
|
||||
// it just revalidates on every load using the "If-None-Match" header with the last ETag value
|
||||
response->addHeader(F("Cache-Control"), F("no-cache"));
|
||||
#else
|
||||
response->addHeader(F("Cache-Control"), F("no-store,max-age=0")); // prevent caching if debug build
|
||||
#endif
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
response->addHeader(F("ETag"), etag);
|
||||
}
|
||||
|
||||
static bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request, int code, uint16_t eTagSuffix = 0) {
|
||||
// Only send 304 (Not Modified) if response code is 200 (OK)
|
||||
if (code != 200) return false;
|
||||
|
||||
AsyncWebHeader *header = request->getHeader(F("If-None-Match"));
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
if (header && header->value() == etag) {
|
||||
AsyncWebServerResponse *response = request->beginResponse(304);
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the request for a static file.
|
||||
* If the file was found in the filesystem, it will be sent to the client.
|
||||
* Otherwise it will be checked if the browser cached the file and if so, a 304 response will be sent.
|
||||
* If the file was not found in the filesystem and not in the browser cache, the request will be handled as a 200 response with the content of the page.
|
||||
*
|
||||
* @param request The request object
|
||||
* @param path If a file with this path exists in the filesystem, it will be sent to the client. Set to "" to skip this check.
|
||||
* @param code The HTTP status code
|
||||
* @param contentType The content type of the web page
|
||||
* @param content Content of the web page
|
||||
* @param len Length of the content
|
||||
* @param gzip Optional. Defaults to true. If false, the gzip header will not be added.
|
||||
* @param eTagSuffix Optional. Defaults to 0. A suffix that will be added to the ETag header. This can be used to invalidate the cache for a specific page.
|
||||
*/
|
||||
static void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip = true, uint16_t eTagSuffix = 0) {
|
||||
if (path != "" && handleFileRead(request, path)) return;
|
||||
if (handleIfNoneMatchCacheHeader(request, code, eTagSuffix)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(code, contentType, content, len);
|
||||
if (gzip) response->addHeader(FPSTR(s_content_enc), F("gzip"));
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
static String dmxProcessor(const String& var)
|
||||
{
|
||||
String mapJS;
|
||||
if (var == F("DMXVARS")) {
|
||||
mapJS += F("\nCN=");
|
||||
mapJS += String(DMXChannels);
|
||||
mapJS += F(";\nCS=");
|
||||
mapJS += String(DMXStart);
|
||||
mapJS += F(";\nCG=");
|
||||
mapJS += String(DMXGap);
|
||||
mapJS += F(";\nLC=");
|
||||
mapJS += String(strip.getLengthTotal());
|
||||
mapJS += F(";\nvar CH=[");
|
||||
for (int i=0; i<15; i++) {
|
||||
mapJS += String(DMXFixtureMap[i]) + ',';
|
||||
}
|
||||
mapJS += F("0];");
|
||||
}
|
||||
return mapJS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static String msgProcessor(const String& var)
|
||||
{
|
||||
if (var == "MSG") {
|
||||
String messageBody = messageHead;
|
||||
messageBody += F("</h2>");
|
||||
messageBody += messageSub;
|
||||
uint32_t optt = optionType;
|
||||
|
||||
if (optt < 60) //redirect to settings after optionType seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RS,");
|
||||
messageBody +=String(optt*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt < 120) //redirect back after optionType-60 seconds, unused
|
||||
{
|
||||
//messageBody += "<script>setTimeout(B," + String((optt-60)*1000) + ")</script>";
|
||||
} else if (optt < 180) //reload parent after optionType-120 seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RP,");
|
||||
messageBody += String((optt-120)*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt == 253)
|
||||
{
|
||||
messageBody += F("<br><br><form action=/settings><button class=\"bt\" type=submit>Back</button></form>"); //button to settings
|
||||
} else if (optt == 254)
|
||||
{
|
||||
messageBody += F("<br><br><button type=\"button\" class=\"bt\" onclick=\"B()\">Back</button>");
|
||||
}
|
||||
return messageBody;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
static void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
if (!correctPIN) {
|
||||
if (final) request->send(401, FPSTR(s_plain), FPSTR(s_unlock_cfg));
|
||||
return;
|
||||
@ -96,7 +209,7 @@ void createEditHandler(bool enable) {
|
||||
}
|
||||
}
|
||||
|
||||
bool captivePortal(AsyncWebServerRequest *request)
|
||||
static bool captivePortal(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (!apActive) return false; //only serve captive in AP mode
|
||||
if (!request->hasHeader("Host")) return false;
|
||||
@ -368,102 +481,6 @@ void initServer()
|
||||
});
|
||||
}
|
||||
|
||||
void generateEtag(char *etag, uint16_t eTagSuffix) {
|
||||
sprintf_P(etag, PSTR("%7d-%02x-%04x"), VERSION, cacheInvalidate, eTagSuffix);
|
||||
}
|
||||
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request, int code, uint16_t eTagSuffix) {
|
||||
// Only send 304 (Not Modified) if response code is 200 (OK)
|
||||
if (code != 200) return false;
|
||||
|
||||
AsyncWebHeader *header = request->getHeader(F("If-None-Match"));
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
if (header && header->value() == etag) {
|
||||
AsyncWebServerResponse *response = request->beginResponse(304);
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix) {
|
||||
// Only send ETag for 200 (OK) responses
|
||||
if (code != 200) return;
|
||||
|
||||
// https://medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c
|
||||
#ifndef WLED_DEBUG
|
||||
// this header name is misleading, "no-cache" will not disable cache,
|
||||
// it just revalidates on every load using the "If-None-Match" header with the last ETag value
|
||||
response->addHeader(F("Cache-Control"), F("no-cache"));
|
||||
#else
|
||||
response->addHeader(F("Cache-Control"), F("no-store,max-age=0")); // prevent caching if debug build
|
||||
#endif
|
||||
char etag[32];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
response->addHeader(F("ETag"), etag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handels the request for a static file.
|
||||
* If the file was found in the filesystem, it will be sent to the client.
|
||||
* Otherwise it will be checked if the browser cached the file and if so, a 304 response will be sent.
|
||||
* If the file was not found in the filesystem and not in the browser cache, the request will be handled as a 200 response with the content of the page.
|
||||
*
|
||||
* @param request The request object
|
||||
* @param path If a file with this path exists in the filesystem, it will be sent to the client. Set to "" to skip this check.
|
||||
* @param code The HTTP status code
|
||||
* @param contentType The content type of the web page
|
||||
* @param content Content of the web page
|
||||
* @param len Length of the content
|
||||
* @param gzip Optional. Defaults to true. If false, the gzip header will not be added.
|
||||
* @param eTagSuffix Optional. Defaults to 0. A suffix that will be added to the ETag header. This can be used to invalidate the cache for a specific page.
|
||||
*/
|
||||
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip, uint16_t eTagSuffix) {
|
||||
if (path != "" && handleFileRead(request, path)) return;
|
||||
if (handleIfNoneMatchCacheHeader(request, code, eTagSuffix)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(code, contentType, content, len);
|
||||
if (gzip) response->addHeader(FPSTR(s_content_enc), F("gzip"));
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
String msgProcessor(const String& var)
|
||||
{
|
||||
if (var == "MSG") {
|
||||
String messageBody = messageHead;
|
||||
messageBody += F("</h2>");
|
||||
messageBody += messageSub;
|
||||
uint32_t optt = optionType;
|
||||
|
||||
if (optt < 60) //redirect to settings after optionType seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RS,");
|
||||
messageBody +=String(optt*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt < 120) //redirect back after optionType-60 seconds, unused
|
||||
{
|
||||
//messageBody += "<script>setTimeout(B," + String((optt-60)*1000) + ")</script>";
|
||||
} else if (optt < 180) //reload parent after optionType-120 seconds
|
||||
{
|
||||
messageBody += F("<script>setTimeout(RP,");
|
||||
messageBody += String((optt-120)*1000);
|
||||
messageBody += F(")</script>");
|
||||
} else if (optt == 253)
|
||||
{
|
||||
messageBody += F("<br><br><form action=/settings><button class=\"bt\" type=submit>Back</button></form>"); //button to settings
|
||||
} else if (optt == 254)
|
||||
{
|
||||
messageBody += F("<br><br><button type=\"button\" class=\"bt\" onclick=\"B()\">Back</button>");
|
||||
}
|
||||
return messageBody;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl, byte optionT)
|
||||
{
|
||||
@ -487,29 +504,6 @@ void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t erro
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
String dmxProcessor(const String& var)
|
||||
{
|
||||
String mapJS;
|
||||
if (var == F("DMXVARS")) {
|
||||
mapJS += F("\nCN=");
|
||||
mapJS += String(DMXChannels);
|
||||
mapJS += F(";\nCS=");
|
||||
mapJS += String(DMXStart);
|
||||
mapJS += F(";\nCG=");
|
||||
mapJS += String(DMXGap);
|
||||
mapJS += F(";\nLC=");
|
||||
mapJS += String(strip.getLengthTotal());
|
||||
mapJS += F(";\nvar CH=[");
|
||||
for (int i=0; i<15; i++) {
|
||||
mapJS += String(DMXFixtureMap[i]) + ',';
|
||||
}
|
||||
mapJS += F("0];");
|
||||
}
|
||||
return mapJS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void serveSettingsJS(AsyncWebServerRequest* request)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user