mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
fix: protocol 2 core review findings
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>
This commit is contained in:
parent
d869bb53d5
commit
dc2f1478b6
29 changed files with 1087 additions and 670 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#define PROTO_SOCKET_H
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include "ProtoSchema.h"
|
||||
#include "ModelEditor.h"
|
||||
|
||||
class SomfyShade;
|
||||
class SomfyGroup;
|
||||
|
|
@ -13,11 +14,8 @@ class SomfyRoom;
|
|||
//
|
||||
// async_tcp only reads what clients send and answers with fixed frames that
|
||||
// hold nothing of the shade model (hello, errors, ok). Everything formatted
|
||||
// from the model goes out from loop(), in the socket event buffer.
|
||||
#define PROTO_MAX_CLIENTS 5
|
||||
// How long a client may take to ask for the next sync frame.
|
||||
#define PROTO_SYNC_TIMEOUT_MS 30000
|
||||
|
||||
// from the model goes out from loop(), in the socket event buffer. The
|
||||
// clients' slots and syncs are in ProtoSlots.
|
||||
class ProtoSocket {
|
||||
public:
|
||||
// Adds /ws to the server. From setup(), on loop()'s task.
|
||||
|
|
@ -34,24 +32,23 @@ class ProtoSocket {
|
|||
void groupRemoved(uint8_t groupId);
|
||||
void room(SomfyRoom &room);
|
||||
void roomRemoved(uint8_t roomId);
|
||||
// roomOrder, shadeOrder or groupOrder: the ids, in sort order.
|
||||
void order(proto_type_t type);
|
||||
// roomOrder, shadeOrder or groupOrder: the list's ids, in sort order.
|
||||
void order(sort_list_t list);
|
||||
void repeaters();
|
||||
void shadeCommand(SomfyShade &shade, const char *command, const char *source, uint32_t sourceAddress);
|
||||
void memory();
|
||||
void wifi();
|
||||
void ethernet();
|
||||
// A feed event: write its fields into the writer between the two. Only
|
||||
// when someone subscribed, so check subscribed() first.
|
||||
// when subscribed() says someone is, which is also only on loop().
|
||||
bool subscribed(proto_feed_t feed) const;
|
||||
ProtoWriter beginFeed(proto_type_t type);
|
||||
void endFeed(proto_feed_t feed);
|
||||
static void wsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
|
||||
private:
|
||||
TaskHandle_t _owner = nullptr;
|
||||
bool onLoopTask() const;
|
||||
JsonFormatter &beginEvent(proto_type_t type);
|
||||
void endEvent();
|
||||
// On loop()'s task, with a client to send to: nothing is formatted for
|
||||
// nobody, or off the task that owns the event buffer.
|
||||
bool sending() const;
|
||||
};
|
||||
extern ProtoSocket protoSocket;
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue