@alteriom/painlessmesh 1.6.1 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +380 -143
- package/LICENSE +674 -674
- package/README.md +477 -434
- package/RELEASE_GUIDE.md +504 -418
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
- package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
- package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
- package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
- package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
- package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
- package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
- package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
- package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
- package/docs/PHASE1_GUIDE.md +349 -0
- package/docs/PHASE2_GUIDE.md +543 -0
- package/docs/README.md +77 -70
- package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
- package/docs/alteriom/overview.md +507 -507
- package/docs/api/core-api.md +606 -606
- package/docs/architecture/mesh-architecture.md +378 -378
- package/docs/architecture/plugin-system.md +516 -516
- package/docs/getting-started/first-mesh.md +409 -409
- package/docs/getting-started/installation.md +274 -274
- package/docs/getting-started/quickstart.md +157 -157
- package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
- package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
- package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
- package/docs/improvements/README.md +86 -68
- package/docs/improvements/ota-and-status-enhancements.md +911 -0
- package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
- package/docs/improvements/ota-status-quick-reference.md +284 -0
- package/docs/platformio-publishing.md +255 -0
- package/docs/platformio-setup-summary.md +121 -0
- package/docs/troubleshooting/common-issues.md +520 -520
- package/docs/troubleshooting/faq.md +472 -472
- package/docs/tutorials/basic-examples.md +717 -717
- package/docs/wiki/API-Reference.md +245 -245
- package/docs/wiki/Complete-Documentation.md +122 -122
- package/examples/alteriom/README.md +139 -81
- package/examples/alteriom/alteriom.ino +186 -185
- package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
- package/examples/alteriom/platformio.ini +24 -24
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
- package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
- package/examples/alteriomImproved/platformio.ini +25 -0
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase1/phase1_features.ino +242 -0
- package/examples/alteriomPhase1/platformio.ini +25 -0
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase2/phase2_features.ino +186 -0
- package/examples/alteriomPhase2/platformio.ini +25 -0
- package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomSensorNode/platformio.ini +25 -0
- package/examples/basic/basic.ino +66 -66
- package/examples/basic/platformio.ini +25 -25
- package/examples/bridge/bridge.ino +51 -51
- package/examples/bridge/mesh_event_publisher.hpp +253 -0
- package/examples/bridge/mesh_topology_reporter.hpp +303 -0
- package/examples/bridge/mqtt_command_bridge.hpp +459 -0
- package/examples/bridge/mqtt_status_bridge.hpp +519 -0
- package/examples/bridge/platformio.ini +25 -25
- package/examples/echoNode/echoNode.ino +33 -33
- package/examples/echoNode/platformio.ini +25 -25
- package/examples/logClient/logClient.ino +109 -109
- package/examples/logClient/platformio.ini +25 -25
- package/examples/logServer/logServer.ino +81 -81
- package/examples/logServer/platformio.ini +25 -25
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
- package/examples/meshCommandNode/meshCommandNode.ino +263 -0
- package/examples/meshCommandNode/platformio.ini +25 -0
- package/examples/mqttBridge/mqttBridge.ino +118 -118
- package/examples/mqttBridge/platformio.ini +26 -26
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
- package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
- package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
- package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
- package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
- package/examples/mqttCommandBridge/platformio.ini +26 -0
- package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
- package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
- package/examples/mqttStatusBridge/platformio.ini +26 -0
- package/examples/mqttTopologyTest/README.md +467 -0
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
- package/examples/mqttTopologyTest/platformio.ini +26 -0
- package/examples/namedMesh/namedMesh.ino +97 -97
- package/examples/namedMesh/platformio.ini +25 -25
- package/examples/otaReceiver/otaReceiver.ino +79 -79
- package/examples/otaReceiver/platformio.ini +25 -25
- package/examples/otaSender/otaSender.ino +160 -151
- package/examples/otaSender/platformio.ini +25 -25
- package/examples/startHere/platformio.ini +25 -25
- package/examples/startHere/startHere.ino +159 -159
- package/examples/webServer/platformio.ini +27 -27
- package/examples/webServer/webServer.ino +89 -89
- package/keywords.txt +48 -48
- package/library.json +55 -34
- package/library.properties +10 -10
- package/package.json +86 -78
- package/src/AlteriomPainlessMesh.h +97 -97
- package/src/arduino/wifi.hpp +365 -365
- package/src/boost/asynctcp.hpp +279 -279
- package/src/painlessMesh.h +70 -70
- package/src/painlessMeshSTA.cpp +236 -236
- package/src/painlessMeshSTA.h +58 -58
- package/src/painlessTaskOptions.h +4 -4
- package/src/painlessmesh/base64.hpp +111 -111
- package/src/painlessmesh/buffer.hpp +229 -229
- package/src/painlessmesh/callback.hpp +91 -91
- package/src/painlessmesh/configuration.hpp +77 -77
- package/src/painlessmesh/connection.hpp +192 -192
- package/src/painlessmesh/layout.hpp +188 -188
- package/src/painlessmesh/logger.hpp +158 -158
- package/src/painlessmesh/memory.hpp +119 -119
- package/src/painlessmesh/mesh.hpp +761 -560
- package/src/painlessmesh/metrics.hpp +322 -322
- package/src/painlessmesh/ntp.hpp +263 -263
- package/src/painlessmesh/ota.hpp +582 -553
- package/src/painlessmesh/plugin.hpp +188 -188
- package/src/painlessmesh/protocol.hpp +813 -813
- package/src/painlessmesh/router.hpp +322 -322
- package/src/painlessmesh/tcp.hpp +71 -71
- package/src/painlessmesh/validation.hpp +238 -238
- package/src/plugin/performance.hpp +214 -214
- package/src/plugin/remote.hpp +64 -64
- package/src/scheduler.cpp +10 -10
- package/src/wifi.cpp +2 -2
|
@@ -1,229 +1,229 @@
|
|
|
1
|
-
#ifndef _PAINLESS_MESH_BUFFER_HPP_
|
|
2
|
-
#define _PAINLESS_MESH_BUFFER_HPP_
|
|
3
|
-
|
|
4
|
-
#include <list>
|
|
5
|
-
|
|
6
|
-
#include "Arduino.h"
|
|
7
|
-
#include "painlessmesh/configuration.hpp"
|
|
8
|
-
|
|
9
|
-
#ifndef TCP_MSS
|
|
10
|
-
#define TCP_MSS 1024
|
|
11
|
-
#endif
|
|
12
|
-
|
|
13
|
-
namespace painlessmesh {
|
|
14
|
-
namespace buffer {
|
|
15
|
-
|
|
16
|
-
// Temporary buffer used by ReceiveBuffer and SentBuffer
|
|
17
|
-
struct temp_buffer_t {
|
|
18
|
-
size_t length = TCP_MSS;
|
|
19
|
-
char buffer[TCP_MSS];
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* \brief ReceivedBuffer handles cstrings and stores them as strings
|
|
24
|
-
*/
|
|
25
|
-
template <class T>
|
|
26
|
-
class ReceiveBuffer {
|
|
27
|
-
public:
|
|
28
|
-
ReceiveBuffer() { buffer = T(); }
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Push a message into the buffer
|
|
32
|
-
*/
|
|
33
|
-
void push(const char *cstr, size_t length, temp_buffer_t &buf) {
|
|
34
|
-
auto data_ptr = cstr;
|
|
35
|
-
do {
|
|
36
|
-
auto len = strnlen(data_ptr, length);
|
|
37
|
-
do {
|
|
38
|
-
auto read_len = std::min(len, buf.length);
|
|
39
|
-
memcpy(buf.buffer, data_ptr, read_len);
|
|
40
|
-
buf.buffer[read_len] = '\0';
|
|
41
|
-
auto newBuffer = T(buf.buffer);
|
|
42
|
-
stringAppend(buffer, newBuffer);
|
|
43
|
-
len -= newBuffer.length();
|
|
44
|
-
length -= newBuffer.length();
|
|
45
|
-
data_ptr += newBuffer.length() * sizeof(char);
|
|
46
|
-
} while (len > 0);
|
|
47
|
-
if (length > 0) {
|
|
48
|
-
// Skip/remove the '\0' between the messages
|
|
49
|
-
length -= 1;
|
|
50
|
-
data_ptr += 1 * sizeof(char);
|
|
51
|
-
if (buffer.length() > 0) { // skip empty buffers
|
|
52
|
-
jsonStrings.push_back(buffer);
|
|
53
|
-
buffer = T();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
} while (length > 0);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get the oldest message from the buffer
|
|
61
|
-
*/
|
|
62
|
-
T front() {
|
|
63
|
-
if (!empty()) return jsonStrings.front();
|
|
64
|
-
return T();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Remove the oldest message from the buffer
|
|
69
|
-
*/
|
|
70
|
-
void pop_front() { jsonStrings.pop_front(); }
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Is the buffer empty
|
|
74
|
-
*/
|
|
75
|
-
bool empty() { return jsonStrings.empty(); }
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Clear the buffer
|
|
79
|
-
*/
|
|
80
|
-
void clear() {
|
|
81
|
-
jsonStrings.clear();
|
|
82
|
-
buffer = T();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private:
|
|
86
|
-
T buffer;
|
|
87
|
-
std::list<T> jsonStrings;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Helper function to deal with difference Arduino String
|
|
91
|
-
* and std::string
|
|
92
|
-
*/
|
|
93
|
-
inline void stringAppend(T &buffer, T &newBuffer) {
|
|
94
|
-
buffer.concat(newBuffer);
|
|
95
|
-
};
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
#ifdef PAINLESSMESH_ENABLE_STD_STRING
|
|
99
|
-
template <>
|
|
100
|
-
inline void ReceiveBuffer<std::string>::stringAppend(std::string &buffer,
|
|
101
|
-
std::string &newBuffer) {
|
|
102
|
-
buffer.append(newBuffer);
|
|
103
|
-
}
|
|
104
|
-
#endif
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* \brief SentBuffer stores messages (strings) and allows them to be read in any
|
|
108
|
-
* length
|
|
109
|
-
*/
|
|
110
|
-
template <class T>
|
|
111
|
-
class SentBuffer {
|
|
112
|
-
public:
|
|
113
|
-
SentBuffer() {};
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* push a message into the buffer.
|
|
117
|
-
*
|
|
118
|
-
* \param priority Whether this is a high priority message.
|
|
119
|
-
*
|
|
120
|
-
* High priority messages will be sent to the front of the buffer
|
|
121
|
-
*/
|
|
122
|
-
void push(const T &message, bool priority = false) {
|
|
123
|
-
if (priority) {
|
|
124
|
-
if (clean)
|
|
125
|
-
jsonStrings.push_front(message);
|
|
126
|
-
else
|
|
127
|
-
jsonStrings.insert((++jsonStrings.begin()), message);
|
|
128
|
-
} else
|
|
129
|
-
jsonStrings.push_back(message);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Request whether the passed length is readable
|
|
134
|
-
*
|
|
135
|
-
* Returns the actual length available (<= the requested length
|
|
136
|
-
*/
|
|
137
|
-
size_t requestLength(size_t buffer_length) {
|
|
138
|
-
if (jsonStrings.empty())
|
|
139
|
-
return 0;
|
|
140
|
-
else
|
|
141
|
-
// String.toCharArray automatically turns the last character into
|
|
142
|
-
// a \0, we need the extra space to deal with that annoyance
|
|
143
|
-
return std::min(buffer_length - 1, jsonStrings.begin()->length() + 1);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Read the given length into the passed buffer (copy mode)
|
|
148
|
-
*
|
|
149
|
-
* Note the user should first make sure the requested length is available
|
|
150
|
-
* using `SentBuffer.requestLength()`, otherwise this function might fail.
|
|
151
|
-
* Note that if multiple messages are read then they are separated using '\0'.
|
|
152
|
-
*
|
|
153
|
-
* Performance note: Consider using readPtr() for zero-copy access when possible.
|
|
154
|
-
*/
|
|
155
|
-
void read(size_t length, temp_buffer_t &buf) {
|
|
156
|
-
// Note that toCharrArray always null terminates
|
|
157
|
-
// independent of whether the whole string was read so we use one extra
|
|
158
|
-
// space
|
|
159
|
-
jsonStrings.front().toCharArray(buf.buffer, length + 1);
|
|
160
|
-
last_read_size = length;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Returns a pointer directly to the oldest message
|
|
165
|
-
*
|
|
166
|
-
* Note the user should first make sure the requested length is available
|
|
167
|
-
* using `SentBuffer.requestLength()`, otherwise this function might fail.
|
|
168
|
-
* Note that if multiple messages are read then they are separated using '\0'.
|
|
169
|
-
*/
|
|
170
|
-
const char *readPtr(size_t length) {
|
|
171
|
-
last_read_size = length;
|
|
172
|
-
return jsonStrings.front().c_str();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Clear the previously read messages from the buffer.
|
|
177
|
-
*
|
|
178
|
-
* Should be called after a call of read() to clear the buffer.
|
|
179
|
-
*/
|
|
180
|
-
void freeRead() {
|
|
181
|
-
if (last_read_size == jsonStrings.begin()->length() + 1) {
|
|
182
|
-
jsonStrings.pop_front();
|
|
183
|
-
clean = true;
|
|
184
|
-
} else {
|
|
185
|
-
// jsonStrings.begin()->remove(0, last_read_size);
|
|
186
|
-
stringEraseFront((*jsonStrings.begin()), last_read_size);
|
|
187
|
-
clean = false;
|
|
188
|
-
}
|
|
189
|
-
last_read_size = 0;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
bool empty() { return jsonStrings.empty(); }
|
|
193
|
-
|
|
194
|
-
void clear() { jsonStrings.clear(); }
|
|
195
|
-
|
|
196
|
-
size_t size() { return jsonStrings.size(); }
|
|
197
|
-
|
|
198
|
-
private:
|
|
199
|
-
size_t last_read_size = 0;
|
|
200
|
-
bool clean = true;
|
|
201
|
-
std::list<T> jsonStrings;
|
|
202
|
-
|
|
203
|
-
inline void stringEraseFront(T &string, size_t length) {
|
|
204
|
-
string.remove(0, length);
|
|
205
|
-
};
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
#ifdef PAINLESSMESH_ENABLE_STD_STRING
|
|
209
|
-
template <>
|
|
210
|
-
inline void SentBuffer<std::string>::read(size_t length, temp_buffer_t &buf) {
|
|
211
|
-
jsonStrings.front().copy(buf.buffer, length);
|
|
212
|
-
// Mimic String.toCharArray behaviour, which will insert
|
|
213
|
-
// null termination at the end of original string and the last
|
|
214
|
-
// character
|
|
215
|
-
if (length == jsonStrings.front().length() + 1) buf.buffer[length - 1] = '\0';
|
|
216
|
-
buf.buffer[length] = '\0';
|
|
217
|
-
last_read_size = length;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
template <>
|
|
221
|
-
inline void SentBuffer<std::string>::stringEraseFront(std::string &string,
|
|
222
|
-
size_t length) {
|
|
223
|
-
string.erase(0, length);
|
|
224
|
-
};
|
|
225
|
-
#endif
|
|
226
|
-
|
|
227
|
-
} // namespace buffer
|
|
228
|
-
} // namespace painlessmesh
|
|
229
|
-
#endif
|
|
1
|
+
#ifndef _PAINLESS_MESH_BUFFER_HPP_
|
|
2
|
+
#define _PAINLESS_MESH_BUFFER_HPP_
|
|
3
|
+
|
|
4
|
+
#include <list>
|
|
5
|
+
|
|
6
|
+
#include "Arduino.h"
|
|
7
|
+
#include "painlessmesh/configuration.hpp"
|
|
8
|
+
|
|
9
|
+
#ifndef TCP_MSS
|
|
10
|
+
#define TCP_MSS 1024
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
namespace painlessmesh {
|
|
14
|
+
namespace buffer {
|
|
15
|
+
|
|
16
|
+
// Temporary buffer used by ReceiveBuffer and SentBuffer
|
|
17
|
+
struct temp_buffer_t {
|
|
18
|
+
size_t length = TCP_MSS;
|
|
19
|
+
char buffer[TCP_MSS];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* \brief ReceivedBuffer handles cstrings and stores them as strings
|
|
24
|
+
*/
|
|
25
|
+
template <class T>
|
|
26
|
+
class ReceiveBuffer {
|
|
27
|
+
public:
|
|
28
|
+
ReceiveBuffer() { buffer = T(); }
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Push a message into the buffer
|
|
32
|
+
*/
|
|
33
|
+
void push(const char *cstr, size_t length, temp_buffer_t &buf) {
|
|
34
|
+
auto data_ptr = cstr;
|
|
35
|
+
do {
|
|
36
|
+
auto len = strnlen(data_ptr, length);
|
|
37
|
+
do {
|
|
38
|
+
auto read_len = std::min(len, buf.length);
|
|
39
|
+
memcpy(buf.buffer, data_ptr, read_len);
|
|
40
|
+
buf.buffer[read_len] = '\0';
|
|
41
|
+
auto newBuffer = T(buf.buffer);
|
|
42
|
+
stringAppend(buffer, newBuffer);
|
|
43
|
+
len -= newBuffer.length();
|
|
44
|
+
length -= newBuffer.length();
|
|
45
|
+
data_ptr += newBuffer.length() * sizeof(char);
|
|
46
|
+
} while (len > 0);
|
|
47
|
+
if (length > 0) {
|
|
48
|
+
// Skip/remove the '\0' between the messages
|
|
49
|
+
length -= 1;
|
|
50
|
+
data_ptr += 1 * sizeof(char);
|
|
51
|
+
if (buffer.length() > 0) { // skip empty buffers
|
|
52
|
+
jsonStrings.push_back(buffer);
|
|
53
|
+
buffer = T();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} while (length > 0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get the oldest message from the buffer
|
|
61
|
+
*/
|
|
62
|
+
T front() {
|
|
63
|
+
if (!empty()) return jsonStrings.front();
|
|
64
|
+
return T();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Remove the oldest message from the buffer
|
|
69
|
+
*/
|
|
70
|
+
void pop_front() { jsonStrings.pop_front(); }
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Is the buffer empty
|
|
74
|
+
*/
|
|
75
|
+
bool empty() { return jsonStrings.empty(); }
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Clear the buffer
|
|
79
|
+
*/
|
|
80
|
+
void clear() {
|
|
81
|
+
jsonStrings.clear();
|
|
82
|
+
buffer = T();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private:
|
|
86
|
+
T buffer;
|
|
87
|
+
std::list<T> jsonStrings;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Helper function to deal with difference Arduino String
|
|
91
|
+
* and std::string
|
|
92
|
+
*/
|
|
93
|
+
inline void stringAppend(T &buffer, T &newBuffer) {
|
|
94
|
+
buffer.concat(newBuffer);
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
#ifdef PAINLESSMESH_ENABLE_STD_STRING
|
|
99
|
+
template <>
|
|
100
|
+
inline void ReceiveBuffer<std::string>::stringAppend(std::string &buffer,
|
|
101
|
+
std::string &newBuffer) {
|
|
102
|
+
buffer.append(newBuffer);
|
|
103
|
+
}
|
|
104
|
+
#endif
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* \brief SentBuffer stores messages (strings) and allows them to be read in any
|
|
108
|
+
* length
|
|
109
|
+
*/
|
|
110
|
+
template <class T>
|
|
111
|
+
class SentBuffer {
|
|
112
|
+
public:
|
|
113
|
+
SentBuffer() {};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* push a message into the buffer.
|
|
117
|
+
*
|
|
118
|
+
* \param priority Whether this is a high priority message.
|
|
119
|
+
*
|
|
120
|
+
* High priority messages will be sent to the front of the buffer
|
|
121
|
+
*/
|
|
122
|
+
void push(const T &message, bool priority = false) {
|
|
123
|
+
if (priority) {
|
|
124
|
+
if (clean)
|
|
125
|
+
jsonStrings.push_front(message);
|
|
126
|
+
else
|
|
127
|
+
jsonStrings.insert((++jsonStrings.begin()), message);
|
|
128
|
+
} else
|
|
129
|
+
jsonStrings.push_back(message);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Request whether the passed length is readable
|
|
134
|
+
*
|
|
135
|
+
* Returns the actual length available (<= the requested length
|
|
136
|
+
*/
|
|
137
|
+
size_t requestLength(size_t buffer_length) {
|
|
138
|
+
if (jsonStrings.empty())
|
|
139
|
+
return 0;
|
|
140
|
+
else
|
|
141
|
+
// String.toCharArray automatically turns the last character into
|
|
142
|
+
// a \0, we need the extra space to deal with that annoyance
|
|
143
|
+
return std::min(buffer_length - 1, jsonStrings.begin()->length() + 1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Read the given length into the passed buffer (copy mode)
|
|
148
|
+
*
|
|
149
|
+
* Note the user should first make sure the requested length is available
|
|
150
|
+
* using `SentBuffer.requestLength()`, otherwise this function might fail.
|
|
151
|
+
* Note that if multiple messages are read then they are separated using '\0'.
|
|
152
|
+
*
|
|
153
|
+
* Performance note: Consider using readPtr() for zero-copy access when possible.
|
|
154
|
+
*/
|
|
155
|
+
void read(size_t length, temp_buffer_t &buf) {
|
|
156
|
+
// Note that toCharrArray always null terminates
|
|
157
|
+
// independent of whether the whole string was read so we use one extra
|
|
158
|
+
// space
|
|
159
|
+
jsonStrings.front().toCharArray(buf.buffer, length + 1);
|
|
160
|
+
last_read_size = length;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Returns a pointer directly to the oldest message
|
|
165
|
+
*
|
|
166
|
+
* Note the user should first make sure the requested length is available
|
|
167
|
+
* using `SentBuffer.requestLength()`, otherwise this function might fail.
|
|
168
|
+
* Note that if multiple messages are read then they are separated using '\0'.
|
|
169
|
+
*/
|
|
170
|
+
const char *readPtr(size_t length) {
|
|
171
|
+
last_read_size = length;
|
|
172
|
+
return jsonStrings.front().c_str();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Clear the previously read messages from the buffer.
|
|
177
|
+
*
|
|
178
|
+
* Should be called after a call of read() to clear the buffer.
|
|
179
|
+
*/
|
|
180
|
+
void freeRead() {
|
|
181
|
+
if (last_read_size == jsonStrings.begin()->length() + 1) {
|
|
182
|
+
jsonStrings.pop_front();
|
|
183
|
+
clean = true;
|
|
184
|
+
} else {
|
|
185
|
+
// jsonStrings.begin()->remove(0, last_read_size);
|
|
186
|
+
stringEraseFront((*jsonStrings.begin()), last_read_size);
|
|
187
|
+
clean = false;
|
|
188
|
+
}
|
|
189
|
+
last_read_size = 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
bool empty() { return jsonStrings.empty(); }
|
|
193
|
+
|
|
194
|
+
void clear() { jsonStrings.clear(); }
|
|
195
|
+
|
|
196
|
+
size_t size() { return jsonStrings.size(); }
|
|
197
|
+
|
|
198
|
+
private:
|
|
199
|
+
size_t last_read_size = 0;
|
|
200
|
+
bool clean = true;
|
|
201
|
+
std::list<T> jsonStrings;
|
|
202
|
+
|
|
203
|
+
inline void stringEraseFront(T &string, size_t length) {
|
|
204
|
+
string.remove(0, length);
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
#ifdef PAINLESSMESH_ENABLE_STD_STRING
|
|
209
|
+
template <>
|
|
210
|
+
inline void SentBuffer<std::string>::read(size_t length, temp_buffer_t &buf) {
|
|
211
|
+
jsonStrings.front().copy(buf.buffer, length);
|
|
212
|
+
// Mimic String.toCharArray behaviour, which will insert
|
|
213
|
+
// null termination at the end of original string and the last
|
|
214
|
+
// character
|
|
215
|
+
if (length == jsonStrings.front().length() + 1) buf.buffer[length - 1] = '\0';
|
|
216
|
+
buf.buffer[length] = '\0';
|
|
217
|
+
last_read_size = length;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
template <>
|
|
221
|
+
inline void SentBuffer<std::string>::stringEraseFront(std::string &string,
|
|
222
|
+
size_t length) {
|
|
223
|
+
string.erase(0, length);
|
|
224
|
+
};
|
|
225
|
+
#endif
|
|
226
|
+
|
|
227
|
+
} // namespace buffer
|
|
228
|
+
} // namespace painlessmesh
|
|
229
|
+
#endif
|
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
#ifndef _PAINLESS_MESH_CALLBACK_HPP_
|
|
2
|
-
#define _PAINLESS_MESH_CALLBACK_HPP_
|
|
3
|
-
|
|
4
|
-
#include <map>
|
|
5
|
-
#include <memory>
|
|
6
|
-
|
|
7
|
-
#include "painlessmesh/configuration.hpp"
|
|
8
|
-
|
|
9
|
-
#include "painlessmesh/protocol.hpp"
|
|
10
|
-
|
|
11
|
-
namespace painlessmesh {
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Helper functions to work with multiple callbacks
|
|
15
|
-
*/
|
|
16
|
-
namespace callback {
|
|
17
|
-
template <typename... Args>
|
|
18
|
-
class List {
|
|
19
|
-
public:
|
|
20
|
-
int execute(Args... args) {
|
|
21
|
-
for (auto&& f : callbacks) {
|
|
22
|
-
f(args...);
|
|
23
|
-
}
|
|
24
|
-
return callbacks.size();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
size_t size() { return callbacks.size(); }
|
|
28
|
-
|
|
29
|
-
void clear() { return callbacks.clear(); }
|
|
30
|
-
|
|
31
|
-
/*
|
|
32
|
-
* Needs to be wrapped into semaphore
|
|
33
|
-
*
|
|
34
|
-
int executeWithScheduler(Scheduler& scheduler, Args... args) {
|
|
35
|
-
scheduler.execute();
|
|
36
|
-
for (auto&& f : callbacks) {
|
|
37
|
-
f(args...);
|
|
38
|
-
scheduler.execute();
|
|
39
|
-
}
|
|
40
|
-
return callbacks.size();
|
|
41
|
-
}*/
|
|
42
|
-
|
|
43
|
-
/** Add callbacks to the end of the list.
|
|
44
|
-
*/
|
|
45
|
-
void push_back(std::function<void(Args...)> func) {
|
|
46
|
-
callbacks.push_back(func);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
protected:
|
|
50
|
-
std::list<std::function<void(Args...)>> callbacks;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Manage callbacks for receiving packages
|
|
55
|
-
*/
|
|
56
|
-
template <typename... Args>
|
|
57
|
-
class PackageCallbackList {
|
|
58
|
-
public:
|
|
59
|
-
/**
|
|
60
|
-
* Add a callback for specific package id
|
|
61
|
-
*/
|
|
62
|
-
void onPackage(int id, std::function<void(Args...)> func) {
|
|
63
|
-
callbackMap[id].push_back(func);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
size_t size() {
|
|
67
|
-
size_t size = 0;
|
|
68
|
-
for (auto&& key_value : callbackMap) {
|
|
69
|
-
size += key_value.second.size();
|
|
70
|
-
}
|
|
71
|
-
return size;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
void clear() { callbackMap.clear(); }
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Execute all the callbacks associated with a certain package
|
|
78
|
-
*/
|
|
79
|
-
int execute(int id, Args... args) { return callbackMap[id].execute(args...); }
|
|
80
|
-
|
|
81
|
-
protected:
|
|
82
|
-
std::map<int, List<Args...>> callbackMap;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
template <typename T>
|
|
86
|
-
using MeshPackageCallbackList =
|
|
87
|
-
PackageCallbackList<protocol::Variant&, std::shared_ptr<T>, uint32_t>;
|
|
88
|
-
} // namespace callback
|
|
89
|
-
} // namespace painlessmesh
|
|
90
|
-
|
|
91
|
-
#endif
|
|
1
|
+
#ifndef _PAINLESS_MESH_CALLBACK_HPP_
|
|
2
|
+
#define _PAINLESS_MESH_CALLBACK_HPP_
|
|
3
|
+
|
|
4
|
+
#include <map>
|
|
5
|
+
#include <memory>
|
|
6
|
+
|
|
7
|
+
#include "painlessmesh/configuration.hpp"
|
|
8
|
+
|
|
9
|
+
#include "painlessmesh/protocol.hpp"
|
|
10
|
+
|
|
11
|
+
namespace painlessmesh {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Helper functions to work with multiple callbacks
|
|
15
|
+
*/
|
|
16
|
+
namespace callback {
|
|
17
|
+
template <typename... Args>
|
|
18
|
+
class List {
|
|
19
|
+
public:
|
|
20
|
+
int execute(Args... args) {
|
|
21
|
+
for (auto&& f : callbacks) {
|
|
22
|
+
f(args...);
|
|
23
|
+
}
|
|
24
|
+
return callbacks.size();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
size_t size() { return callbacks.size(); }
|
|
28
|
+
|
|
29
|
+
void clear() { return callbacks.clear(); }
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* Needs to be wrapped into semaphore
|
|
33
|
+
*
|
|
34
|
+
int executeWithScheduler(Scheduler& scheduler, Args... args) {
|
|
35
|
+
scheduler.execute();
|
|
36
|
+
for (auto&& f : callbacks) {
|
|
37
|
+
f(args...);
|
|
38
|
+
scheduler.execute();
|
|
39
|
+
}
|
|
40
|
+
return callbacks.size();
|
|
41
|
+
}*/
|
|
42
|
+
|
|
43
|
+
/** Add callbacks to the end of the list.
|
|
44
|
+
*/
|
|
45
|
+
void push_back(std::function<void(Args...)> func) {
|
|
46
|
+
callbacks.push_back(func);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
protected:
|
|
50
|
+
std::list<std::function<void(Args...)>> callbacks;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Manage callbacks for receiving packages
|
|
55
|
+
*/
|
|
56
|
+
template <typename... Args>
|
|
57
|
+
class PackageCallbackList {
|
|
58
|
+
public:
|
|
59
|
+
/**
|
|
60
|
+
* Add a callback for specific package id
|
|
61
|
+
*/
|
|
62
|
+
void onPackage(int id, std::function<void(Args...)> func) {
|
|
63
|
+
callbackMap[id].push_back(func);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
size_t size() {
|
|
67
|
+
size_t size = 0;
|
|
68
|
+
for (auto&& key_value : callbackMap) {
|
|
69
|
+
size += key_value.second.size();
|
|
70
|
+
}
|
|
71
|
+
return size;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void clear() { callbackMap.clear(); }
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Execute all the callbacks associated with a certain package
|
|
78
|
+
*/
|
|
79
|
+
int execute(int id, Args... args) { return callbackMap[id].execute(args...); }
|
|
80
|
+
|
|
81
|
+
protected:
|
|
82
|
+
std::map<int, List<Args...>> callbackMap;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
template <typename T>
|
|
86
|
+
using MeshPackageCallbackList =
|
|
87
|
+
PackageCallbackList<protocol::Variant&, std::shared_ptr<T>, uint32_t>;
|
|
88
|
+
} // namespace callback
|
|
89
|
+
} // namespace painlessmesh
|
|
90
|
+
|
|
91
|
+
#endif
|