mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
From the review of #99: - A sync could stall when a client took a slot the moment another left: loop() used up the new client's sync on the old one. The slots move to ProtoSlots, a pure module with native tests, and loop() takes a slot's wants only for the client it read (takeWants). - Deleting a group sends its shades, whose inGroup changed. Deleting a shade unlinks it from its groups and sends them, so a new shade given its id doesn't join them. - next and sync with an id get an ok reply, and a message in pieces gets one bad request, not one per piece. - Feeds check for loop() before they write the event buffer, and log an event too large, as events do. - editChanges() (ModelEditor, native tests) says what clients get after an edit; the edit result carries the shade a group gained or lost. order() takes a sort_list_t. - The frame writers move to ProtoFrame. Renames: pf to proto_field_t, the X-macro letters to TYPE/FIELD/ERR/FEED, proto_request_t to proto_message_t, REQ_* to WANTS_*, fmt to eventJson. The event bodies share sendItem(), the connection type name lives in ESPNetwork, and the loop() task check in SocketEmitter. - e2e: the heap floor check skips when the low since boot is already under it; tests for replies to next and sync and a long message. - SECURITY_PLAN.md splits step 1 into 1a-1d. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.3 KiB
C
32 lines
1.3 KiB
C
#ifndef PROTO_PARSE_H
|
|
#define PROTO_PARSE_H
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <ArduinoJson.h>
|
|
#include "ProtoSchema.h"
|
|
|
|
// Reading the frames a socket protocol 2 client sends (docs/PROTOCOL.md).
|
|
// Kept free of the web server so it can be unit tested on the PC
|
|
// (pio test -e native).
|
|
|
|
// The largest frame a client may send; a longer one is refused unread.
|
|
#define PROTO_MAX_CLIENT_FRAME 4096
|
|
|
|
struct proto_message_t {
|
|
uint8_t type = 0;
|
|
uint32_t id = 0; // 0 when the frame had none
|
|
};
|
|
// Reads one frame into doc and out. none when it is a message a client may
|
|
// send; otherwise the error to reply with. out.id is set whenever the frame
|
|
// had one, so the reply can name it. The payload is doc["d"].
|
|
proto_error_t parseClientFrame(const char *text, size_t len, JsonDocument &doc, proto_message_t &out);
|
|
// An op (16-127) as opposed to a control message.
|
|
inline bool protoIsOp(uint8_t type) { return type >= 16 && type <= 127; }
|
|
|
|
// A field of a payload, or its default when it was left out.
|
|
int32_t protoInt(JsonObjectConst d, proto_field_t field);
|
|
bool protoBool(JsonObjectConst d, proto_field_t field);
|
|
// nullptr when it was left out, as a string's default is "".
|
|
const char *protoString(JsonObjectConst d, proto_field_t field);
|
|
bool protoHas(JsonObjectConst d, proto_field_t field);
|
|
#endif
|