serveLiveLeds: Use dynamic buffer
There were three problems here:
- AsyncWebServer is going to copy to a heap buffer anyways, so we might
as well just pass it one it can use
- The buffer size estimate was wrong -- we need 9 bytes per pixel
("RRGGBB",), so the buffer could overflow, and it was not
considering the extra 2D requirements
- On ESP8266, the stack allocation was overflowing the stack, causing
corruption and crashes.
This commit is contained in:
@@ -1554,10 +1554,20 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
||||
|
||||
uint16_t used = strip.getLengthTotal();
|
||||
uint16_t n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS
|
||||
char buffer[2000];
|
||||
strcpy_P(buffer, PSTR("{\"leds\":["));
|
||||
obuf = buffer;
|
||||
olen = 9;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (strip.isMatrix) {
|
||||
// ignore anything behid matrix (i.e. extra strip)
|
||||
used = Segment::maxWidth*Segment::maxHeight; // always the size of matrix (more or less than strip.getLengthTotal())
|
||||
n = 1;
|
||||
if (used > MAX_LIVE_LEDS) n = 2;
|
||||
if (used > MAX_LIVE_LEDS*4) n = 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
DynamicBuffer buffer(9 + (9*MAX_LIVE_LEDS) + 7 + 5 + 6 + 5 + 6 + 5 + 2);
|
||||
char* buf = buffer.data(); // assign buffer for oappnd() functions
|
||||
strncpy_P(buffer.data(), PSTR("{\"leds\":["), buffer.size());
|
||||
buf += 9; // sizeof(PSTR()) from last line
|
||||
|
||||
for (size_t i= 0; i < used; i += n)
|
||||
{
|
||||
@@ -1575,20 +1585,21 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
||||
g = qadd8(w, G(c));
|
||||
b = qadd8(w, B(c));
|
||||
}
|
||||
olen += sprintf(obuf + olen, "\"%06X\",", RGBW32(r,g,b,0));
|
||||
buf += sprintf_P(buf, PSTR("\"%06X\","), RGBW32(r,g,b,0));
|
||||
}
|
||||
olen -= 1;
|
||||
oappend((const char*)F("],\"n\":"));
|
||||
oappendi(n);
|
||||
oappend("}");
|
||||
buf--; // remove last comma
|
||||
buf += sprintf_P(buf, PSTR("],\"n\":%d"), n);
|
||||
(*buf++) = '}';
|
||||
(*buf++) = 0;
|
||||
|
||||
if (request) {
|
||||
request->send(200, "application/json", buffer);
|
||||
request->send(200, "application/json", toString(std::move(buffer)));
|
||||
}
|
||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||
else {
|
||||
wsc->text(obuf, olen);
|
||||
wsc->text(toString(std::move(buffer)));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user