mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-31 09:18:12 +00:00
fix(screenshot): widen header to uint16, sanity-check buffer, fix ERR path
Protocol header grows from 7 to 11 bytes: display_type, rotation, then uint16 LE width / height / chunk_idx / total_chunks. Removes silent truncation on panels >255 px (e.g. future 4.2" 400x300 e-ink). Decoder now: - checks RESP_CODE_ERR before length so error frames don't surface as "Frame too short"; logs the error code byte - validates received buffer size against expected (OLED: w*h/8; e-ink: ceil(min(w,h)/8) * max(w,h)) so truncated transfers fail loudly - initializes disp_rotation in outer scope and detects missed chunk 0 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -2098,23 +2098,30 @@ void MyMesh::handleScreenshotRequest() {
|
||||
}
|
||||
|
||||
void MyMesh::sendScreenshotResponse(DisplayDriver* display, const uint8_t* buffer, uint16_t bufferSize) {
|
||||
// Frame format: RESP_CODE_SCREENSHOT, width, height, chunk_idx, total_chunks,
|
||||
// display_type, rotation, [data]
|
||||
// display_type: 0=OLED (page-based), 1=e-ink (row-major, MSB-first, 1=white/0=black)
|
||||
// rotation: 0-3, Adafruit_GFX/GxEPD2 rotation value (only meaningful for e-ink)
|
||||
const int HEADER_SIZE = 7;
|
||||
// Frame format (11-byte header, little-endian multi-byte fields):
|
||||
// [0] resp_code = RESP_CODE_SCREENSHOT
|
||||
// [1] display_type (0=OLED page-based, 1=e-ink row-major MSB-first 1=white)
|
||||
// [2] rotation (0-3, GxEPD2/Adafruit_GFX value; only meaningful for e-ink)
|
||||
// [3..4] width (uint16 LE — GxEPD2-reported visible width)
|
||||
// [5..6] height (uint16 LE — GxEPD2-reported visible height)
|
||||
// [7..8] chunk_idx (uint16 LE)
|
||||
// [9..10] total_chunks (uint16 LE)
|
||||
// [11..] chunk data
|
||||
const int HEADER_SIZE = 11;
|
||||
const int MAX_DATA_PER_FRAME = MAX_FRAME_SIZE - HEADER_SIZE;
|
||||
int totalChunks = (bufferSize + MAX_DATA_PER_FRAME - 1) / MAX_DATA_PER_FRAME;
|
||||
const uint16_t width = (uint16_t)display->screenshotWidth();
|
||||
const uint16_t height = (uint16_t)display->screenshotHeight();
|
||||
const uint16_t totalChunks = (bufferSize + MAX_DATA_PER_FRAME - 1) / MAX_DATA_PER_FRAME;
|
||||
|
||||
for (int chunkIdx = 0; chunkIdx < totalChunks; chunkIdx++) {
|
||||
for (uint16_t chunkIdx = 0; chunkIdx < totalChunks; chunkIdx++) {
|
||||
int i = 0;
|
||||
out_frame[i++] = RESP_CODE_SCREENSHOT;
|
||||
out_frame[i++] = (uint8_t)display->screenshotWidth();
|
||||
out_frame[i++] = (uint8_t)display->screenshotHeight();
|
||||
out_frame[i++] = (uint8_t)chunkIdx;
|
||||
out_frame[i++] = (uint8_t)totalChunks;
|
||||
out_frame[i++] = display->getDisplayType();
|
||||
out_frame[i++] = display->screenshotRotation();
|
||||
out_frame[i++] = width & 0xFF; out_frame[i++] = width >> 8;
|
||||
out_frame[i++] = height & 0xFF; out_frame[i++] = height >> 8;
|
||||
out_frame[i++] = chunkIdx & 0xFF; out_frame[i++] = chunkIdx >> 8;
|
||||
out_frame[i++] = totalChunks & 0xFF; out_frame[i++] = totalChunks >> 8;
|
||||
|
||||
int chunkSize = min(MAX_DATA_PER_FRAME, (int)bufferSize - chunkIdx * MAX_DATA_PER_FRAME);
|
||||
memcpy(&out_frame[i], buffer + chunkIdx * MAX_DATA_PER_FRAME, chunkSize);
|
||||
|
||||
Reference in New Issue
Block a user