AlteriomPainlessMesh v2.1.1
Easy ESP32/ESP8266 mesh networking with Alteriom IoT extensions
Loading...
Searching...
No Matches
protocol.hpp
Go to the documentation of this file.
1#ifndef _PAINLESS_MESH_PROTOCOL_HPP_
2#define _PAINLESS_MESH_PROTOCOL_HPP_
3
4#include <cmath>
5#include <list>
6
7#include "Arduino.h"
8
9#if ARDUINOJSON_VERSION_MAJOR == 7
10#include "ArduinoJson/Deserialization/DeserializationError.hpp"
11#include "ArduinoJson/Document/JsonDocument.hpp"
12#endif
14
15namespace painlessmesh {
16
17namespace router {
18
31} // namespace router
32
33namespace protocol {
34
35enum Type {
40 CONTROL = 7, // deprecated
41 BROADCAST = 8, // application data for everyone
42 SINGLE = 9 // application data for a single node
43};
44
51
52// Bridge protocol package types
53// These are used for bridge discovery, election, and coordination
54constexpr int BRIDGE_STATUS = 610; // Bridge status broadcast (internet, RSSI, etc.)
55constexpr int BRIDGE_ELECTION = 611; // Bridge election candidacy announcement
56constexpr int BRIDGE_TAKEOVER = 612; // Bridge takeover notification
57constexpr int BRIDGE_COORDINATION = 613; // Multi-bridge coordination (defined in plugin.hpp)
58
59// Gateway data protocol types
60// Used for routing Internet requests through the mesh network
61constexpr int GATEWAY_DATA = 620; // Gateway data package for Internet routing
62constexpr int GATEWAY_ACK = 621; // Gateway acknowledgment package
63constexpr int GATEWAY_HEARTBEAT = 622; // Gateway heartbeat for health monitoring
64
65// Message delivery confirmation types
66constexpr int MESSAGE_ACK = 630; // Per-message delivery acknowledgment (issue #379)
67
68// Outbound queue priority levels, in SentBuffer scheduling order (lower value
69// drains first). PRIORITY_NORMAL is the wire default: a package whose priority
70// equals it omits the "prio" key entirely.
71constexpr uint8_t PRIORITY_CRITICAL = 0;
72constexpr uint8_t PRIORITY_HIGH = 1;
73constexpr uint8_t PRIORITY_NORMAL = 2;
74constexpr uint8_t PRIORITY_LOW = 3;
75
77 public:
78 // A base with virtual functions destroyed through a derived pointer needs
79 // this, and a package held in a shared_ptr is exactly that case (#469);
80 // clang refuses the build without it under -Werror.
81 virtual ~PackageInterface() = default;
82 virtual JsonObject addTo(JsonObject&& jsonObj) const = 0;
83#if ARDUINOJSON_VERSION_MAJOR < 7
84 virtual size_t jsonObjectSize() const = 0;
85#endif
86};
87
93class Single : public PackageInterface {
94 public:
95 int type = SINGLE;
96 uint32_t from = 0;
97 uint32_t dest = 0;
99 // Non-zero when the sender requested a delivery acknowledgment. Only
100 // serialized when set, so plain sends carry zero overhead.
101 uint32_t msgId = 0;
102 // Outbound queue priority: 0=CRITICAL, 1=HIGH, 2=NORMAL, 3=LOW. Carried on
103 // the wire (as "prio") so intermediate hops re-enqueue a forwarded package
104 // at the sender's priority instead of silently dropping it to NORMAL after
105 // the first hop (issue #384). Only serialized when it deviates from NORMAL,
106 // so default sends carry zero overhead. Pre-2.0 receivers ignore the key.
108
110 Single(uint32_t fromID, uint32_t destID, TSTRING& message) {
111 from = fromID;
112 dest = destID;
113 msg = message;
114 }
115
116 Single(JsonObject jsonObj) {
117 dest = jsonObj["dest"].as<uint32_t>();
118 from = jsonObj["from"].as<uint32_t>();
119 msg = jsonObj["msg"].as<TSTRING>();
120 msgId = jsonObj["msgId"] | (uint32_t)0;
121 priority = jsonObj["prio"] | PRIORITY_NORMAL;
122 }
123
124 JsonObject addTo(JsonObject&& jsonObj) const {
125 jsonObj["type"] = type;
126 jsonObj["dest"] = dest;
127 jsonObj["from"] = from;
128 jsonObj["msg"] = msg;
129 if (msgId != 0) jsonObj["msgId"] = msgId;
130 if (priority != PRIORITY_NORMAL) jsonObj["prio"] = priority;
131 return jsonObj;
132 }
133
134#if ARDUINOJSON_VERSION_MAJOR < 7
135 size_t jsonObjectSize() const {
136 return JSON_OBJECT_SIZE((msgId != 0 ? 5 : 4) +
137 (priority != PRIORITY_NORMAL ? 1 : 0)) +
138 ceil(1.1 * msg.length());
139 }
140#endif
141};
142
146class Broadcast : public Single {
147 public:
149
150 using Single::Single;
151
152 JsonObject addTo(JsonObject&& jsonObj) const {
153 jsonObj = Single::addTo(std::move(jsonObj));
154 jsonObj["type"] = type;
155 return jsonObj;
156 }
157
158#if ARDUINOJSON_VERSION_MAJOR < 7
159 size_t jsonObjectSize() const {
160 return JSON_OBJECT_SIZE((msgId != 0 ? 5 : 4) +
161 (priority != PRIORITY_NORMAL ? 1 : 0)) +
162 ceil(1.1 * msg.length());
163 }
164#endif
165};
166
168 public:
169 uint32_t nodeId = 0;
170 bool root = false;
171 bool hasTimeAuthority = false; // True if node has RTC or Internet time source
172 std::list<NodeTree> subs;
173
175 virtual ~NodeTree() = default; // Add virtual destructor
176
177 NodeTree(uint32_t nodeID, bool iAmRoot, bool timeAuthority = false) {
178 nodeId = nodeID;
179 root = iAmRoot;
180 hasTimeAuthority = timeAuthority;
181 }
182
183 NodeTree(JsonObject jsonObj) {
184#if ARDUINOJSON_VERSION_MAJOR < 7
185 if (jsonObj.containsKey("root")) root = jsonObj["root"].as<bool>();
186 if (jsonObj.containsKey("hasTimeAuthority")) hasTimeAuthority = jsonObj["hasTimeAuthority"].as<bool>();
187 if (jsonObj.containsKey("nodeId"))
188#else
189
190 if (jsonObj["root"].is<bool>()) root = jsonObj["root"].as<bool>();
191 if (jsonObj["hasTimeAuthority"].is<bool>()) hasTimeAuthority = jsonObj["hasTimeAuthority"].as<bool>();
192 if (jsonObj["nodeId"].is<uint32_t>())
193#endif
194 nodeId = jsonObj["nodeId"].as<uint32_t>();
195 else
196 nodeId = jsonObj["from"].as<uint32_t>();
197
198#if ARDUINOJSON_VERSION_MAJOR < 7
199 if (jsonObj.containsKey("subs")) {
200#else
201 if (jsonObj["subs"].is<JsonArray>()) {
202#endif
203 auto jsonArr = jsonObj["subs"].as<JsonArray>();
204 for (size_t i = 0; i < jsonArr.size(); ++i) {
205 subs.push_back(NodeTree(jsonArr[i].as<JsonObject>()));
206 }
207 }
208 }
209
210 JsonObject addTo(JsonObject&& jsonObj) const {
211 jsonObj["nodeId"] = nodeId;
212 if (root) jsonObj["root"] = root;
213 if (hasTimeAuthority) jsonObj["hasTimeAuthority"] = hasTimeAuthority;
214 if (subs.size() > 0) {
215#if ARDUINOJSON_VERSION_MAJOR == 7
216 JsonArray subsArr = jsonObj["subs"].to<JsonArray>();
217#else
218 JsonArray subsArr = jsonObj.createNestedArray("subs");
219#endif
220 for (auto&& s : subs) {
221#if ARDUINOJSON_VERSION_MAJOR == 7
222 JsonObject subObj = subsArr.add<JsonObject>();
223#else
224 JsonObject subObj = subsArr.createNestedObject();
225#endif
226 subObj = s.addTo(std::move(subObj));
227 }
228 }
229 return jsonObj;
230 }
231
232 bool operator==(const NodeTree& b) const {
233 if (!(this->nodeId == b.nodeId && this->root == b.root &&
234 this->hasTimeAuthority == b.hasTimeAuthority &&
235 this->subs.size() == b.subs.size()))
236 return false;
237 auto itA = this->subs.begin();
238 auto itB = b.subs.begin();
239 for (size_t i = 0; i < this->subs.size(); ++i) {
240 if ((*itA) != (*itB)) {
241 return false;
242 }
243 ++itA;
244 ++itB;
245 }
246 return true;
247 }
248
249 bool operator!=(const NodeTree& b) const { return !this->operator==(b); }
250
251 TSTRING toString(bool pretty = false);
252
253#if ARDUINOJSON_VERSION_MAJOR < 7
254 size_t jsonObjectSize() const {
255 size_t base = 1;
256 if (root) ++base;
257 if (hasTimeAuthority) ++base;
258 if (subs.size() > 0) ++base;
259 size_t size = JSON_OBJECT_SIZE(base);
260 if (subs.size() > 0) size += JSON_ARRAY_SIZE(subs.size());
261 for (auto&& s : subs) size += s.jsonObjectSize();
262 return size;
263 }
264#endif
265
266 void clear() {
267 nodeId = 0;
268 subs.clear();
269 root = false;
270 hasTimeAuthority = false;
271 }
272};
273
277class NodeSyncRequest : public NodeTree {
278 public:
280 uint32_t from = 0;
281 uint32_t dest = 0;
282
284 NodeSyncRequest(uint32_t fromID, uint32_t destID, std::list<NodeTree> subTree,
285 bool iAmRoot = false) {
286 from = fromID;
287 dest = destID;
288 subs = subTree;
289 nodeId = fromID;
290 root = iAmRoot;
291 }
292
293 NodeSyncRequest(JsonObject jsonObj) : NodeTree(jsonObj) {
294 dest = jsonObj["dest"].as<uint32_t>();
295 from = jsonObj["from"].as<uint32_t>();
296 }
297
298 JsonObject addTo(JsonObject&& jsonObj) const {
299 jsonObj = NodeTree::addTo(std::move(jsonObj));
300 jsonObj["type"] = type;
301 jsonObj["dest"] = dest;
302 jsonObj["from"] = from;
303 return jsonObj;
304 }
305
306 bool operator==(const NodeSyncRequest& b) const {
307 if (!(this->from == b.from && this->dest == b.dest)) return false;
308 return NodeTree::operator==(b);
309 }
310
311 bool operator!=(const NodeSyncRequest& b) const {
312 return !this->operator==(b);
313 }
314
315#if ARDUINOJSON_VERSION_MAJOR < 7
316 size_t jsonObjectSize() const {
317 size_t base = 4;
318 if (root) ++base;
319 if (hasTimeAuthority) ++base;
320 if (subs.size() > 0) ++base;
321 size_t size = JSON_OBJECT_SIZE(base);
322 if (subs.size() > 0) size += JSON_ARRAY_SIZE(subs.size());
323 for (auto&& s : subs) size += s.jsonObjectSize();
324 return size;
325 }
326#endif
327};
328
333 public:
334 int type = NODE_SYNC_REPLY;
335
336 using NodeSyncRequest::NodeSyncRequest;
337
338 JsonObject addTo(JsonObject&& jsonObj) const {
339 jsonObj = NodeSyncRequest::addTo(std::move(jsonObj));
340 jsonObj["type"] = type;
341 return jsonObj;
342 }
343};
344
346 int type = TIME_SYNC_ERROR;
347 uint32_t t0 = 0;
348 uint32_t t1 = 0;
349 uint32_t t2 = 0;
350};
351
356 public:
357 int type = TIME_SYNC;
358 uint32_t dest = 0;
359 uint32_t from = 0;
361
363
364 TimeSync(uint32_t fromID, uint32_t destID) {
365 from = fromID;
366 dest = destID;
368 }
369
370 TimeSync(uint32_t fromID, uint32_t destID, uint32_t t0) {
371 from = fromID;
372 dest = destID;
373 msg.type = TIME_REQUEST;
374 msg.t0 = t0;
375 }
376
377 TimeSync(uint32_t fromID, uint32_t destID, uint32_t t0, uint32_t t1) {
378 from = fromID;
379 dest = destID;
380 msg.type = TIME_REPLY;
381 msg.t0 = t0;
382 msg.t1 = t1;
383 }
384
385 TimeSync(uint32_t fromID, uint32_t destID, uint32_t t0, uint32_t t1,
386 uint32_t t2) {
387 from = fromID;
388 dest = destID;
389 msg.type = TIME_REPLY;
390 msg.t0 = t0;
391 msg.t1 = t1;
392 msg.t2 = t2;
393 }
394
395 TimeSync(JsonObject jsonObj) {
396 dest = jsonObj["dest"].as<uint32_t>();
397 from = jsonObj["from"].as<uint32_t>();
398 msg.type = jsonObj["msg"]["type"].as<int>();
399#if ARDUINOJSON_VERSION_MAJOR < 7
400 if (jsonObj["msg"].containsKey("t0"))
401 msg.t0 = jsonObj["msg"]["t0"].as<uint32_t>();
402 if (jsonObj["msg"].containsKey("t1"))
403 msg.t1 = jsonObj["msg"]["t1"].as<uint32_t>();
404 if (jsonObj["msg"].containsKey("t2"))
405 msg.t2 = jsonObj["msg"]["t2"].as<uint32_t>();
406#else
407 if (jsonObj["msg"]["t0"].is<uint32_t>())
408 msg.t0 = jsonObj["msg"]["t0"].as<uint32_t>();
409 if (jsonObj["msg"]["t1"].is<uint32_t>())
410 msg.t1 = jsonObj["msg"]["t1"].as<uint32_t>();
411 if (jsonObj["msg"]["t2"].is<uint32_t>())
412 msg.t2 = jsonObj["msg"]["t2"].as<uint32_t>();
413#endif
414 }
415
416 JsonObject addTo(JsonObject&& jsonObj) const {
417 jsonObj["type"] = type;
418 jsonObj["dest"] = dest;
419 jsonObj["from"] = from;
420#if ARDUINOJSON_VERSION_MAJOR == 7
421 auto msgObj = jsonObj["msg"].to<JsonObject>();
422#else
423 auto msgObj = jsonObj.createNestedObject("msg");
424#endif
425 msgObj["type"] = msg.type;
426 if (msg.type >= 1) msgObj["t0"] = msg.t0;
427 if (msg.type >= 2) {
428 msgObj["t1"] = msg.t1;
429 msgObj["t2"] = msg.t2;
430 }
431 return jsonObj;
432 }
433
437 void reply(uint32_t newT0) {
438 msg.t0 = newT0;
439 ++msg.type;
440 std::swap(from, dest);
441 }
442
446 void reply(uint32_t newT1, uint32_t newT2) {
447 msg.t1 = newT1;
448 msg.t2 = newT2;
449 ++msg.type;
450 std::swap(from, dest);
451 }
452
453#if ARDUINOJSON_VERSION_MAJOR < 7
454 size_t jsonObjectSize() const {
455 return JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(4);
456 }
457#endif
458};
459
463class TimeDelay : public TimeSync {
464 public:
465 int type = TIME_DELAY;
466 using TimeSync::TimeSync;
467
468 JsonObject addTo(JsonObject&& jsonObj) const {
469 jsonObj = TimeSync::addTo(std::move(jsonObj));
470 jsonObj["type"] = type;
471 return jsonObj;
472 }
473};
474
481class Variant {
482 // Copy operations implemented safely to address issue #521
483 // Move semantics preferred for performance
484 public:
485 // Copy constructor - implemented safely
486 Variant(const Variant& other) : error(other.error) {
487 // Deep copy the JSON buffer to avoid shared references
488 if (error == DeserializationError::Ok) {
489#if ARDUINOJSON_VERSION_MAJOR == 7
490 jsonBuffer = JsonDocument();
491#else
492 jsonBuffer = DynamicJsonDocument(other.jsonBuffer.capacity());
493#endif
494 jsonBuffer.set(other.jsonBuffer);
495 jsonObj = jsonBuffer.as<JsonObject>();
496 }
497 }
498
499 // Copy assignment operator - implemented safely
500 Variant& operator=(const Variant& other) {
501 if (this != &other) {
502 error = other.error;
503 if (error == DeserializationError::Ok) {
504#if ARDUINOJSON_VERSION_MAJOR == 7
505 jsonBuffer = JsonDocument();
506#else
507 jsonBuffer = DynamicJsonDocument(other.jsonBuffer.capacity());
508#endif
509 jsonBuffer.set(other.jsonBuffer);
510 jsonObj = jsonBuffer.as<JsonObject>();
511 }
512 }
513 return *this;
514 }
515
516 // Move constructor - preferred for performance
517 Variant(Variant&& other) noexcept
518 : error(std::move(other.error)),
519 jsonBuffer(std::move(other.jsonBuffer)) {
520 if (error == DeserializationError::Ok) {
521 jsonObj = jsonBuffer.as<JsonObject>();
522 }
523 other.error = DeserializationError::EmptyInput;
524 }
525
526 // Move assignment operator - preferred for performance
527 Variant& operator=(Variant&& other) noexcept {
528 if (this != &other) {
529 error = std::move(other.error);
530 jsonBuffer = std::move(other.jsonBuffer);
531 if (error == DeserializationError::Ok) {
532 jsonObj = jsonBuffer.as<JsonObject>();
533 }
534 other.error = DeserializationError::EmptyInput;
535 }
536 return *this;
537 }
538#ifdef ARDUINOJSON_ENABLE_STD_STRING
544 Variant(const std::string& json)
545#if ARDUINOJSON_VERSION_MAJOR == 7
546 : jsonBuffer() {
547#else
548 : jsonBuffer(JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(4) +
549 2 * json.length()) {
550#endif
551 error = deserializeJson(jsonBuffer, json,
552 DeserializationOption::NestingLimit(255));
553 if (error == DeserializationError::Ok)
554 jsonObj = jsonBuffer.as<JsonObject>();
555 }
556
563 Variant(const std::string& json, size_t capacity)
564#if ARDUINOJSON_VERSION_MAJOR == 7
565 : jsonBuffer() {
566#else
567 : jsonBuffer(capacity) {
568#endif
569 error = deserializeJson(jsonBuffer, json,
570 DeserializationOption::NestingLimit(255));
571 if (error == DeserializationError::Ok)
572 jsonObj = jsonBuffer.as<JsonObject>();
573 }
574#endif
575
576#ifdef ARDUINOJSON_ENABLE_ARDUINO_STRING
582 Variant(String json)
583#if ARDUINOJSON_VERSION_MAJOR == 7
584 : jsonBuffer() {
585#else
586 : jsonBuffer(JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(4) +
587 2 * json.length()) {
588#endif
589 error = deserializeJson(jsonBuffer, json,
590 DeserializationOption::NestingLimit(255));
591
592 if (error == DeserializationError::Ok)
593 jsonObj = jsonBuffer.as<JsonObject>();
594 }
595
602 Variant(String json, size_t capacity)
603#if ARDUINOJSON_VERSION_MAJOR == 7
604 : jsonBuffer() {
605#else
606 : jsonBuffer(capacity) {
607#endif
608 error = deserializeJson(jsonBuffer, json,
609 DeserializationOption::NestingLimit(255));
610 if (!error) jsonObj = jsonBuffer.as<JsonObject>();
611 }
612#endif
617#if ARDUINOJSON_VERSION_MAJOR == 7
618 : jsonBuffer() {
619#else
620 : jsonBuffer(pkg->jsonObjectSize()) {
621#endif
622 jsonObj = jsonBuffer.to<JsonObject>();
623 jsonObj = pkg->addTo(std::move(jsonObj));
624 }
625
632#if ARDUINOJSON_VERSION_MAJOR == 7
633 : jsonBuffer() {
634#else
635 : jsonBuffer(single.jsonObjectSize()) {
636#endif
637 jsonObj = jsonBuffer.to<JsonObject>();
638 jsonObj = single.addTo(std::move(jsonObj));
639 }
640
647#if ARDUINOJSON_VERSION_MAJOR == 7
648 : jsonBuffer() {
649#else
650 : jsonBuffer(broadcast.jsonObjectSize()) {
651#endif
652 jsonObj = jsonBuffer.to<JsonObject>();
653 jsonObj = broadcast.addTo(std::move(jsonObj));
654 }
655
662#if ARDUINOJSON_VERSION_MAJOR == 7
663 : jsonBuffer() {
664#else
665 : jsonBuffer(nodeTree.jsonObjectSize()) {
666#endif
667 jsonObj = jsonBuffer.to<JsonObject>();
668 jsonObj = nodeTree.addTo(std::move(jsonObj));
669 }
670
676 Variant(NodeSyncReply nodeSyncReply)
677#if ARDUINOJSON_VERSION_MAJOR == 7
678 : jsonBuffer() {
679#else
680 : jsonBuffer(nodeSyncReply.jsonObjectSize()) {
681#endif
682 jsonObj = jsonBuffer.to<JsonObject>();
683 jsonObj = nodeSyncReply.addTo(std::move(jsonObj));
684 }
685
691 Variant(NodeSyncRequest nodeSyncRequest)
692#if ARDUINOJSON_VERSION_MAJOR == 7
693 : jsonBuffer() {
694#else
695 : jsonBuffer(nodeSyncRequest.jsonObjectSize()) {
696#endif
697 jsonObj = jsonBuffer.to<JsonObject>();
698 jsonObj = nodeSyncRequest.addTo(std::move(jsonObj));
699 }
700
707#if ARDUINOJSON_VERSION_MAJOR == 7
708 : jsonBuffer() {
709#else
710 : jsonBuffer(timeSync.jsonObjectSize()) {
711#endif
712 jsonObj = jsonBuffer.to<JsonObject>();
713 jsonObj = timeSync.addTo(std::move(jsonObj));
714 }
715
722#if ARDUINOJSON_VERSION_MAJOR == 7
723 : jsonBuffer() {
724#else
725 : jsonBuffer(timeDelay.jsonObjectSize()) {
726#endif
727 jsonObj = jsonBuffer.to<JsonObject>();
728 jsonObj = timeDelay.addTo(std::move(jsonObj));
729 }
730
734 template <typename T>
735 inline bool is() {
736 return false;
737 }
738
742 template <typename T>
743 inline T to() {
744 return T(jsonObj);
745 }
746
750 int type() { return jsonObj["type"].as<int>(); }
751
758 uint32_t from() { return jsonObj["from"] | (uint32_t)0; }
759
766 uint32_t msgId() { return jsonObj["msgId"] | (uint32_t)0; }
767
775 uint8_t priority() { return jsonObj["prio"] | PRIORITY_NORMAL; }
776
781#if ARDUINOJSON_VERSION_MAJOR < 7
782 if (jsonObj.containsKey("routing"))
783#else
784 if (jsonObj["routing"].is<int>())
785#endif
786 return (router::Type)jsonObj["routing"].as<int>();
787
788 auto type = this->type();
789 if (type == SINGLE || type == TIME_DELAY) return router::SINGLE;
790 if (type == BROADCAST) return router::BROADCAST;
791 if (type == NODE_SYNC_REQUEST || type == NODE_SYNC_REPLY ||
792 type == TIME_SYNC)
793 return router::NEIGHBOUR;
794 return router::ROUTING_ERROR;
795 }
796
800 uint32_t dest() {
801#if ARDUINOJSON_VERSION_MAJOR < 7
802 if (jsonObj.containsKey("dest")) return jsonObj["dest"].as<uint32_t>();
803#else
804 if (jsonObj["dest"].is<uint32_t>()) return jsonObj["dest"].as<uint32_t>();
805#endif
806 return 0;
807 }
808
809#ifdef ARDUINOJSON_ENABLE_STD_STRING
815 void printTo(std::string& str, bool pretty = false) {
816 if (pretty)
817 serializeJsonPretty(jsonObj, str);
818 else
819 serializeJson(jsonObj, str);
820 }
821#endif
822
823#ifdef ARDUINOJSON_ENABLE_ARDUINO_STRING
829 void printTo(String& str, bool pretty = false) {
830 if (pretty)
831 serializeJsonPretty(jsonObj, str);
832 else
833 serializeJson(jsonObj, str);
834 }
835#endif
836
837 DeserializationError error = DeserializationError::Ok;
838
839 private:
840#if ARDUINOJSON_VERSION_MAJOR == 7
841 JsonDocument jsonBuffer;
842#else
843 DynamicJsonDocument jsonBuffer;
844#endif
845 JsonObject jsonObj;
846};
847
848template <>
849inline bool Variant::is<Single>() {
850 return jsonObj["type"].as<int>() == SINGLE;
851}
852
853template <>
854inline bool Variant::is<Broadcast>() {
855 return jsonObj["type"].as<int>() == BROADCAST;
856}
857
858template <>
859inline bool Variant::is<NodeSyncReply>() {
860 return jsonObj["type"].as<int>() == NODE_SYNC_REPLY;
861}
862
863template <>
864inline bool Variant::is<NodeSyncRequest>() {
865 return jsonObj["type"].as<int>() == NODE_SYNC_REQUEST;
866}
867
868template <>
869inline bool Variant::is<TimeSync>() {
870 return jsonObj["type"].as<int>() == TIME_SYNC;
871}
872
873template <>
874inline bool Variant::is<TimeDelay>() {
875 return jsonObj["type"].as<int>() == TIME_DELAY;
876}
877
878template <>
879inline JsonObject Variant::to<JsonObject>() {
880 return jsonObj;
881}
882
883inline TSTRING NodeTree::toString(bool pretty) {
884 TSTRING str;
885 auto variant = Variant(*this);
886 variant.printTo(str, pretty);
887 return str;
888}
889
890} // namespace protocol
891} // namespace painlessmesh
892#endif
Definition protocol.hpp:146
size_t jsonObjectSize() const
Definition protocol.hpp:159
JsonObject addTo(JsonObject &&jsonObj) const
Definition protocol.hpp:152
int type
Definition protocol.hpp:148
Definition protocol.hpp:332
JsonObject addTo(JsonObject &&jsonObj) const
Definition protocol.hpp:338
Definition protocol.hpp:277
bool operator==(const NodeSyncRequest &b) const
Definition protocol.hpp:306
uint32_t dest
Definition protocol.hpp:281
NodeSyncRequest()
Definition protocol.hpp:283
NodeSyncRequest(uint32_t fromID, uint32_t destID, std::list< NodeTree > subTree, bool iAmRoot=false)
Definition protocol.hpp:284
JsonObject addTo(JsonObject &&jsonObj) const
Definition protocol.hpp:298
NodeSyncRequest(JsonObject jsonObj)
Definition protocol.hpp:293
bool operator!=(const NodeSyncRequest &b) const
Definition protocol.hpp:311
uint32_t from
Definition protocol.hpp:280
size_t jsonObjectSize() const
Definition protocol.hpp:316
Definition protocol.hpp:167
JsonObject addTo(JsonObject &&jsonObj) const
Definition protocol.hpp:210
TSTRING toString(bool pretty=false)
Definition protocol.hpp:883
std::list< NodeTree > subs
Definition protocol.hpp:172
NodeTree()
Definition protocol.hpp:174
NodeTree(uint32_t nodeID, bool iAmRoot, bool timeAuthority=false)
Definition protocol.hpp:177
bool operator!=(const NodeTree &b) const
Definition protocol.hpp:249
bool hasTimeAuthority
Definition protocol.hpp:171
uint32_t nodeId
Definition protocol.hpp:169
NodeTree(JsonObject jsonObj)
Definition protocol.hpp:183
bool root
Definition protocol.hpp:170
bool operator==(const NodeTree &b) const
Definition protocol.hpp:232
void clear()
Definition protocol.hpp:266
size_t jsonObjectSize() const
Definition protocol.hpp:254
virtual JsonObject addTo(JsonObject &&jsonObj) const =0
virtual size_t jsonObjectSize() const =0
Definition protocol.hpp:93
Single(JsonObject jsonObj)
Definition protocol.hpp:116
Single()
Definition protocol.hpp:109
JsonObject addTo(JsonObject &&jsonObj) const
Definition protocol.hpp:124
uint8_t priority
Definition protocol.hpp:107
uint32_t msgId
Definition protocol.hpp:101
size_t jsonObjectSize() const
Definition protocol.hpp:135
TSTRING msg
Definition protocol.hpp:98
int type
Definition protocol.hpp:95
uint32_t dest
Definition protocol.hpp:97
Single(uint32_t fromID, uint32_t destID, TSTRING &message)
Definition protocol.hpp:110
uint32_t from
Definition protocol.hpp:96
Definition protocol.hpp:463
JsonObject addTo(JsonObject &&jsonObj) const
Definition protocol.hpp:468
Definition protocol.hpp:355
JsonObject addTo(JsonObject &&jsonObj) const
Definition protocol.hpp:416
TimeSync(uint32_t fromID, uint32_t destID)
Definition protocol.hpp:364
void reply(uint32_t newT1, uint32_t newT2)
Definition protocol.hpp:446
void reply(uint32_t newT0)
Definition protocol.hpp:437
size_t jsonObjectSize() const
Definition protocol.hpp:454
TimeSync(JsonObject jsonObj)
Definition protocol.hpp:395
TimeSync(uint32_t fromID, uint32_t destID, uint32_t t0)
Definition protocol.hpp:370
TimeSync()
Definition protocol.hpp:362
time_sync_msg_t msg
Definition protocol.hpp:360
TimeSync(uint32_t fromID, uint32_t destID, uint32_t t0, uint32_t t1, uint32_t t2)
Definition protocol.hpp:385
TimeSync(uint32_t fromID, uint32_t destID, uint32_t t0, uint32_t t1)
Definition protocol.hpp:377
Definition protocol.hpp:481
Variant(const Variant &other)
Definition protocol.hpp:486
Variant(Broadcast broadcast)
Definition protocol.hpp:646
Variant & operator=(const Variant &other)
Definition protocol.hpp:500
bool is()
Definition protocol.hpp:735
Variant(NodeSyncRequest nodeSyncRequest)
Definition protocol.hpp:691
Variant(NodeTree nodeTree)
Definition protocol.hpp:661
int type()
Definition protocol.hpp:750
uint32_t from()
Definition protocol.hpp:758
Variant(NodeSyncReply nodeSyncReply)
Definition protocol.hpp:676
Variant(const PackageInterface *pkg)
Definition protocol.hpp:616
Variant(Variant &&other) noexcept
Definition protocol.hpp:517
Variant(Single single)
Definition protocol.hpp:631
router::Type routing()
Definition protocol.hpp:780
uint32_t msgId()
Definition protocol.hpp:766
Variant(TimeSync timeSync)
Definition protocol.hpp:706
uint32_t dest()
Definition protocol.hpp:800
DeserializationError error
Definition protocol.hpp:837
T to()
Definition protocol.hpp:743
Variant(TimeDelay timeDelay)
Definition protocol.hpp:721
Variant & operator=(Variant &&other) noexcept
Definition protocol.hpp:527
uint8_t priority()
Definition protocol.hpp:775
String TSTRING
Definition configuration.hpp:132
constexpr uint8_t PRIORITY_CRITICAL
Definition protocol.hpp:71
constexpr int GATEWAY_ACK
Definition protocol.hpp:62
constexpr int BRIDGE_COORDINATION
Definition protocol.hpp:57
constexpr int BRIDGE_ELECTION
Definition protocol.hpp:55
constexpr uint8_t PRIORITY_HIGH
Definition protocol.hpp:72
constexpr uint8_t PRIORITY_NORMAL
Definition protocol.hpp:73
constexpr int MESSAGE_ACK
Definition protocol.hpp:66
constexpr uint8_t PRIORITY_LOW
Definition protocol.hpp:74
TimeType
Definition protocol.hpp:45
@ TIME_REPLY
Definition protocol.hpp:49
@ TIME_SYNC_ERROR
Definition protocol.hpp:46
@ TIME_REQUEST
Definition protocol.hpp:48
@ TIME_SYNC_REQUEST
Definition protocol.hpp:47
constexpr int BRIDGE_TAKEOVER
Definition protocol.hpp:56
Type
Definition protocol.hpp:35
@ SINGLE
Definition protocol.hpp:42
@ NODE_SYNC_REPLY
Definition protocol.hpp:39
@ NODE_SYNC_REQUEST
Definition protocol.hpp:38
@ CONTROL
Definition protocol.hpp:40
@ TIME_SYNC
Definition protocol.hpp:37
@ TIME_DELAY
Definition protocol.hpp:36
@ BROADCAST
Definition protocol.hpp:41
constexpr int GATEWAY_HEARTBEAT
Definition protocol.hpp:63
constexpr int GATEWAY_DATA
Definition protocol.hpp:61
constexpr int BRIDGE_STATUS
Definition protocol.hpp:54
Type
Definition protocol.hpp:30
@ ROUTING_ERROR
Definition protocol.hpp:30
@ NEIGHBOUR
Definition protocol.hpp:30
@ SINGLE
Definition protocol.hpp:30
@ BROADCAST
Definition protocol.hpp:30
Definition wifi.hpp:34
@ PRIORITY_NORMAL
Definition message_queue.hpp:21
Definition protocol.hpp:345
uint32_t t0
Definition protocol.hpp:347
uint32_t t1
Definition protocol.hpp:348
int type
Definition protocol.hpp:346
uint32_t t2
Definition protocol.hpp:349