mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
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:
parent
a36888f8a1
commit
482e495678
24 changed files with 1839 additions and 5 deletions
36
src/ProtoParse.cpp
Normal file
36
src/ProtoParse.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include "ProtoParse.h"
|
||||
|
||||
proto_error_t parseClientFrame(const char *text, size_t len, JsonDocument &doc, proto_request_t &out) {
|
||||
out = proto_request_t();
|
||||
if(len > PROTO_MAX_CLIENT_FRAME) return proto_error_t::badRequest;
|
||||
if(deserializeJson(doc, text, len) != DeserializationError::Ok) return proto_error_t::badRequest;
|
||||
if(!doc.is<JsonObject>()) return proto_error_t::badRequest;
|
||||
JsonVariantConst id = doc["id"];
|
||||
if(id.is<uint32_t>()) out.id = id.as<uint32_t>();
|
||||
else if(!id.isNull()) return proto_error_t::badRequest;
|
||||
if(!doc["v"].is<int>() || doc["v"].as<int>() != PROTO_VERSION) return proto_error_t::badRequest;
|
||||
JsonVariantConst t = doc["t"];
|
||||
if(!t.is<int>() || t.as<int>() < 1 || t.as<int>() > 255) return proto_error_t::badRequest;
|
||||
out.type = static_cast<uint8_t>(t.as<int>());
|
||||
if(!protoClientMaySend(out.type)) return proto_error_t::unknownOp;
|
||||
if(protoIsOp(out.type) && out.id == 0) return proto_error_t::badRequest;
|
||||
JsonVariantConst d = doc["d"];
|
||||
if(!d.isNull() && !d.is<JsonObjectConst>()) return proto_error_t::badRequest;
|
||||
return proto_error_t::none;
|
||||
}
|
||||
|
||||
int32_t protoInt(JsonObjectConst d, pf field) {
|
||||
const proto_field_info_t &f = protoField(field);
|
||||
JsonVariantConst v = d[f.key];
|
||||
return v.is<int32_t>() ? v.as<int32_t>() : f.def;
|
||||
}
|
||||
bool protoBool(JsonObjectConst d, pf field) {
|
||||
const proto_field_info_t &f = protoField(field);
|
||||
JsonVariantConst v = d[f.key];
|
||||
return v.is<int>() ? v.as<int>() != 0 : f.def != 0;
|
||||
}
|
||||
const char *protoString(JsonObjectConst d, pf field) {
|
||||
JsonVariantConst v = d[protoField(field).key];
|
||||
return v.is<const char *>() ? v.as<const char *>() : nullptr;
|
||||
}
|
||||
bool protoHas(JsonObjectConst d, pf field) { return !d[protoField(field).key].isNull(); }
|
||||
Loading…
Add table
Add a link
Reference in a new issue