feat: socket protocol 2 core on ws://host/ws

The /ws endpoint runs next to the old socket on port 8080.  The
handshake checks the token under security, the device sends hello,
then a sync of the schema (unless the client has it), header, rooms,
shades, groups, repeaters and status, paced by the client's next.
Events go out with the old ones: shadeState or the whole shade on a
config change, groups, rooms, removals, orders, repeaters,
shadeCommand, memory, wifi, ethernet, and the frames and
frequencyScan feeds.

The table of types, fields, errors and feeds is defined once and is
sent as the schema.  The writer, item writers, sync and client frame
parser are pure and natively tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-22 21:19:29 +02:00
parent a36888f8a1
commit 482e495678
24 changed files with 1839 additions and 5 deletions

View file

@ -228,6 +228,42 @@ static void test_setBuffer_after_discard_writes_again() {
TEST_ASSERT_EQUAL_STRING("{}", storage);
}
/*********************************************************************
* Mark and roll back
********************************************************************/
static void test_rollback_drops_what_was_written_since_the_mark() {
fmt.beginObject();
fmt.addElem("a", (uint8_t)1);
const json_mark_t m = fmt.mark();
fmt.addElem("b", (uint8_t)2);
fmt.beginArray("c");
fmt.rollback(m);
fmt.addElem("d", (uint8_t)3);
fmt.endObject();
TEST_ASSERT_EQUAL_STRING("{\"a\":1,\"d\":3}", storage);
}
static void test_rollback_clears_an_overflow() {
fmt.beginObject();
const json_mark_t m = fmt.mark();
char big[BUFF_SIZE + 1];
memset(big, 'z', BUFF_SIZE);
big[BUFF_SIZE] = '\0';
fmt.addElem("big", big);
TEST_ASSERT_TRUE(fmt.overflowed());
fmt.rollback(m);
TEST_ASSERT_FALSE(fmt.overflowed());
fmt.addElem("ok", true);
fmt.endObject();
TEST_ASSERT_EQUAL_STRING("{\"ok\":true}", storage);
}
static void test_rollback_at_the_start_leaves_an_empty_buffer() {
const json_mark_t m = fmt.mark();
fmt.beginObject();
fmt.rollback(m);
TEST_ASSERT_EQUAL_UINT32(0, fmt.length());
TEST_ASSERT_EQUAL_STRING("", storage);
}
int main(int argc, char **argv) {
(void)argc;
(void)argv;
@ -251,5 +287,8 @@ int main(int argc, char **argv) {
RUN_TEST(test_setBuffer_resets_length);
RUN_TEST(test_discard_writes_nothing);
RUN_TEST(test_setBuffer_after_discard_writes_again);
RUN_TEST(test_rollback_drops_what_was_written_since_the_mark);
RUN_TEST(test_rollback_clears_an_overflow);
RUN_TEST(test_rollback_at_the_start_leaves_an_empty_buffer);
return UNITY_END();
}