ProtoSync.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef PROTO_SYNC_H | ||
| 2 | #define PROTO_SYNC_H | ||
| 3 | #include <stddef.h> | ||
| 4 | #include <stdint.h> | ||
| 5 | #include "ItemSnapshot.h" | ||
| 6 | #include "ProtoSchema.h" | ||
| 7 | |||
| 8 | // The shade model in socket protocol 2: how each room, shade and group is | ||
| 9 | // written, and the sync that sends a client all of them (docs/PROTOCOL.md). | ||
| 10 | // Kept free of the shade model and the web server so it can be unit tested on | ||
| 11 | // the PC (pio test -e native). | ||
| 12 | |||
| 13 | // The largest frame: what a sync message, or any event, is formatted into. | ||
| 14 | #define PROTO_MAX_FRAME 4096 | ||
| 15 | |||
| 16 | // The fields of one item, into the object the caller opened. | ||
| 17 | void protoRoom(ProtoWriter &w, const room_snapshot_t &room); | ||
| 18 | // Everything about a shade: its settings and its state. | ||
| 19 | void protoShade(ProtoWriter &w, const shade_snapshot_t &shade); | ||
| 20 | // Only what changes while a shade moves or is commanded. | ||
| 21 | void protoShadeState(ProtoWriter &w, const shade_snapshot_t &shade); | ||
| 22 | // A group, with the ids of its shades. | ||
| 23 | void protoGroup(ProtoWriter &w, const group_snapshot_t &group); | ||
| 24 | void protoGroupState(ProtoWriter &w, uint8_t groupId, uint8_t flags, int8_t direction); | ||
| 25 | |||
| 26 | // Where a sync gets the shade model from: the live model on the device, a | ||
| 27 | // filled snapshot in the tests. Slots run from 0 to the SOMFY_MAX_* of their | ||
| 28 | // kind; an empty slot returns false. | ||
| 29 | class SyncSource { | ||
| 30 | public: | ||
| 31 | 8 | virtual ~SyncSource() {} | |
| 32 | virtual bool room(uint8_t slot, room_snapshot_t &out) = 0; | ||
| 33 | virtual bool shade(uint8_t slot, shade_snapshot_t &out) = 0; | ||
| 34 | virtual bool group(uint8_t slot, group_snapshot_t &out) = 0; | ||
| 35 | virtual bool repeater(uint8_t slot, uint32_t &address) = 0; | ||
| 36 | // The fields of the header and status objects. | ||
| 37 | virtual void header(ProtoWriter &w) = 0; | ||
| 38 | virtual void status(ProtoWriter &w) = 0; | ||
| 39 | }; | ||
| 40 | |||
| 41 | // The parts of a sync, in the order they are sent. | ||
| 42 | enum class sync_section_t : uint8_t { | ||
| 43 | types, fields, errors, feeds, // the schema | ||
| 44 | header, rooms, shades, groups, repeaters, status, // the device | ||
| 45 | done | ||
| 46 | }; | ||
| 47 | struct sync_cursor_t { | ||
| 48 | sync_section_t section = sync_section_t::done; | ||
| 49 | uint8_t index = 0; | ||
| 50 | 139 | bool active() const { return this->section != sync_section_t::done; } | |
| 51 | }; | ||
| 52 | // A sync from the start: with the schema, or from the header when the client | ||
| 53 | // already has it. | ||
| 54 | sync_cursor_t beginSync(bool withSchema); | ||
| 55 | // Writes the next sync frame into buff: as many whole items as fit in size | ||
| 56 | // bytes, never one split in two. An item too big for an empty frame is left | ||
| 57 | // out. Returns the frame's length, or 0 once the sync is done and syncEnd is | ||
| 58 | // due. Each call reads the source afresh, so a sync shows each item as it is | ||
| 59 | // when it goes out, not one moment. | ||
| 60 | size_t writeSyncFrame(SyncSource &src, sync_cursor_t &cur, char *buff, size_t size); | ||
| 61 | #endif | ||
| 62 |