@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.
Files changed (129) hide show
  1. package/CHANGELOG.md +380 -143
  2. package/LICENSE +674 -674
  3. package/README.md +477 -434
  4. package/RELEASE_GUIDE.md +504 -418
  5. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
  6. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
  7. package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
  8. package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
  9. package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
  10. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
  11. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
  12. package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
  13. package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
  14. package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
  15. package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
  16. package/docs/PHASE1_GUIDE.md +349 -0
  17. package/docs/PHASE2_GUIDE.md +543 -0
  18. package/docs/README.md +77 -70
  19. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
  20. package/docs/alteriom/overview.md +507 -507
  21. package/docs/api/core-api.md +606 -606
  22. package/docs/architecture/mesh-architecture.md +378 -378
  23. package/docs/architecture/plugin-system.md +516 -516
  24. package/docs/getting-started/first-mesh.md +409 -409
  25. package/docs/getting-started/installation.md +274 -274
  26. package/docs/getting-started/quickstart.md +157 -157
  27. package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
  28. package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
  29. package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
  30. package/docs/improvements/README.md +86 -68
  31. package/docs/improvements/ota-and-status-enhancements.md +911 -0
  32. package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
  33. package/docs/improvements/ota-status-quick-reference.md +284 -0
  34. package/docs/platformio-publishing.md +255 -0
  35. package/docs/platformio-setup-summary.md +121 -0
  36. package/docs/troubleshooting/common-issues.md +520 -520
  37. package/docs/troubleshooting/faq.md +472 -472
  38. package/docs/tutorials/basic-examples.md +717 -717
  39. package/docs/wiki/API-Reference.md +245 -245
  40. package/docs/wiki/Complete-Documentation.md +122 -122
  41. package/examples/alteriom/README.md +139 -81
  42. package/examples/alteriom/alteriom.ino +186 -185
  43. package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
  44. package/examples/alteriom/platformio.ini +24 -24
  45. package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
  46. package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
  47. package/examples/alteriomImproved/platformio.ini +25 -0
  48. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
  49. package/examples/alteriomPhase1/phase1_features.ino +242 -0
  50. package/examples/alteriomPhase1/platformio.ini +25 -0
  51. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
  52. package/examples/alteriomPhase2/phase2_features.ino +186 -0
  53. package/examples/alteriomPhase2/platformio.ini +25 -0
  54. package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
  55. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
  56. package/examples/alteriomSensorNode/platformio.ini +25 -0
  57. package/examples/basic/basic.ino +66 -66
  58. package/examples/basic/platformio.ini +25 -25
  59. package/examples/bridge/bridge.ino +51 -51
  60. package/examples/bridge/mesh_event_publisher.hpp +253 -0
  61. package/examples/bridge/mesh_topology_reporter.hpp +303 -0
  62. package/examples/bridge/mqtt_command_bridge.hpp +459 -0
  63. package/examples/bridge/mqtt_status_bridge.hpp +519 -0
  64. package/examples/bridge/platformio.ini +25 -25
  65. package/examples/echoNode/echoNode.ino +33 -33
  66. package/examples/echoNode/platformio.ini +25 -25
  67. package/examples/logClient/logClient.ino +109 -109
  68. package/examples/logClient/platformio.ini +25 -25
  69. package/examples/logServer/logServer.ino +81 -81
  70. package/examples/logServer/platformio.ini +25 -25
  71. package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
  72. package/examples/meshCommandNode/meshCommandNode.ino +263 -0
  73. package/examples/meshCommandNode/platformio.ini +25 -0
  74. package/examples/mqttBridge/mqttBridge.ino +118 -118
  75. package/examples/mqttBridge/platformio.ini +26 -26
  76. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
  77. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
  78. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
  79. package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
  80. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
  81. package/examples/mqttCommandBridge/platformio.ini +26 -0
  82. package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
  83. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
  84. package/examples/mqttStatusBridge/platformio.ini +26 -0
  85. package/examples/mqttTopologyTest/README.md +467 -0
  86. package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
  87. package/examples/mqttTopologyTest/platformio.ini +26 -0
  88. package/examples/namedMesh/namedMesh.ino +97 -97
  89. package/examples/namedMesh/platformio.ini +25 -25
  90. package/examples/otaReceiver/otaReceiver.ino +79 -79
  91. package/examples/otaReceiver/platformio.ini +25 -25
  92. package/examples/otaSender/otaSender.ino +160 -151
  93. package/examples/otaSender/platformio.ini +25 -25
  94. package/examples/startHere/platformio.ini +25 -25
  95. package/examples/startHere/startHere.ino +159 -159
  96. package/examples/webServer/platformio.ini +27 -27
  97. package/examples/webServer/webServer.ino +89 -89
  98. package/keywords.txt +48 -48
  99. package/library.json +55 -34
  100. package/library.properties +10 -10
  101. package/package.json +86 -78
  102. package/src/AlteriomPainlessMesh.h +97 -97
  103. package/src/arduino/wifi.hpp +365 -365
  104. package/src/boost/asynctcp.hpp +279 -279
  105. package/src/painlessMesh.h +70 -70
  106. package/src/painlessMeshSTA.cpp +236 -236
  107. package/src/painlessMeshSTA.h +58 -58
  108. package/src/painlessTaskOptions.h +4 -4
  109. package/src/painlessmesh/base64.hpp +111 -111
  110. package/src/painlessmesh/buffer.hpp +229 -229
  111. package/src/painlessmesh/callback.hpp +91 -91
  112. package/src/painlessmesh/configuration.hpp +77 -77
  113. package/src/painlessmesh/connection.hpp +192 -192
  114. package/src/painlessmesh/layout.hpp +188 -188
  115. package/src/painlessmesh/logger.hpp +158 -158
  116. package/src/painlessmesh/memory.hpp +119 -119
  117. package/src/painlessmesh/mesh.hpp +761 -560
  118. package/src/painlessmesh/metrics.hpp +322 -322
  119. package/src/painlessmesh/ntp.hpp +263 -263
  120. package/src/painlessmesh/ota.hpp +582 -553
  121. package/src/painlessmesh/plugin.hpp +188 -188
  122. package/src/painlessmesh/protocol.hpp +813 -813
  123. package/src/painlessmesh/router.hpp +322 -322
  124. package/src/painlessmesh/tcp.hpp +71 -71
  125. package/src/painlessmesh/validation.hpp +238 -238
  126. package/src/plugin/performance.hpp +214 -214
  127. package/src/plugin/remote.hpp +64 -64
  128. package/src/scheduler.cpp +10 -10
  129. package/src/wifi.cpp +2 -2
@@ -1,77 +1,77 @@
1
- #ifndef _PAINLESS_MESH_CONFIGURATION_HPP_
2
- #define _PAINLESS_MESH_CONFIGURATION_HPP_
3
-
4
- // Include Arduino.h in test environment to ensure TSTRING is defined
5
- #if defined(PAINLESSMESH_BOOST) || defined(ARDUINO_ARCH_ESP8266) || \
6
- defined(ARDUINO_ARCH_ESP32)
7
- #ifndef ARDUINO
8
- #include "Arduino.h"
9
- #endif
10
- #endif
11
-
12
- #include <list>
13
-
14
- #include "painlessTaskOptions.h"
15
-
16
- #include <TaskSchedulerDeclarations.h>
17
-
18
- #define ARDUINOJSON_USE_LONG_LONG 1
19
- #undef ARDUINOJSON_ENABLE_STD_STRING
20
- #include <ArduinoJson.h>
21
- #undef ARDUINOJSON_ENABLE_STD_STRING
22
-
23
- // Enable (arduino) wifi support
24
- #define PAINLESSMESH_ENABLE_ARDUINO_WIFI
25
-
26
- // Enable OTA support
27
- #define PAINLESSMESH_ENABLE_OTA
28
-
29
- // Minimum free memory, besides here all packets in queue are discarded.
30
- #define MIN_FREE_MEMORY 4000
31
- // MAX number of unsent messages in queue. Newer messages are discarded
32
- #define MAX_MESSAGE_QUEUE 50
33
-
34
- #define NODE_TIMEOUT 10 * TASK_SECOND
35
- #define SCAN_INTERVAL 30 * TASK_SECOND // AP scan period in ms
36
-
37
- #ifdef ESP32
38
- #include <AsyncTCP.h>
39
- #include <WiFi.h>
40
- #if ESP_ARDUINO_VERSION_MAJOR >= 3
41
- #include "esp_mac.h" // required for core 3.x - exposes esp_mac_type_t values
42
- #endif
43
- #elif defined(ESP8266)
44
- #include <ESP8266WiFi.h>
45
- #include <ESPAsyncTCP.h>
46
- #endif // ESP32
47
-
48
- // Define TSTRING - use std::string in test environment, Arduino String
49
- // otherwise
50
- #if defined(PAINLESSMESH_BOOST)
51
- // Test environment - TSTRING already defined in test Arduino.h as std::string
52
- #else
53
- typedef String TSTRING;
54
- #endif
55
-
56
- // backward compatibility
57
- template <typename T>
58
- using SimpleList = std::list<T>;
59
-
60
- namespace painlessmesh {
61
- namespace wifi {
62
- class Mesh;
63
- };
64
- }; // namespace painlessmesh
65
-
66
- /** A convenience typedef to access the mesh class*/
67
- #ifdef PAINLESSMESH_ENABLE_ARDUINO_WIFI
68
- using painlessMesh = painlessmesh::wifi::Mesh;
69
- #endif
70
-
71
- #ifdef ESP32
72
- #define MAX_CONN 10
73
- #else
74
- #define MAX_CONN 4
75
- #endif // DEBUG
76
-
77
- #endif
1
+ #ifndef _PAINLESS_MESH_CONFIGURATION_HPP_
2
+ #define _PAINLESS_MESH_CONFIGURATION_HPP_
3
+
4
+ // Include Arduino.h in test environment to ensure TSTRING is defined
5
+ #if defined(PAINLESSMESH_BOOST) || defined(ARDUINO_ARCH_ESP8266) || \
6
+ defined(ARDUINO_ARCH_ESP32)
7
+ #ifndef ARDUINO
8
+ #include "Arduino.h"
9
+ #endif
10
+ #endif
11
+
12
+ #include <list>
13
+
14
+ #include "painlessTaskOptions.h"
15
+
16
+ #include <TaskSchedulerDeclarations.h>
17
+
18
+ #define ARDUINOJSON_USE_LONG_LONG 1
19
+ #undef ARDUINOJSON_ENABLE_STD_STRING
20
+ #include <ArduinoJson.h>
21
+ #undef ARDUINOJSON_ENABLE_STD_STRING
22
+
23
+ // Enable (arduino) wifi support
24
+ #define PAINLESSMESH_ENABLE_ARDUINO_WIFI
25
+
26
+ // Enable OTA support
27
+ #define PAINLESSMESH_ENABLE_OTA
28
+
29
+ // Minimum free memory, besides here all packets in queue are discarded.
30
+ #define MIN_FREE_MEMORY 4000
31
+ // MAX number of unsent messages in queue. Newer messages are discarded
32
+ #define MAX_MESSAGE_QUEUE 50
33
+
34
+ #define NODE_TIMEOUT 10 * TASK_SECOND
35
+ #define SCAN_INTERVAL 30 * TASK_SECOND // AP scan period in ms
36
+
37
+ #ifdef ESP32
38
+ #include <AsyncTCP.h>
39
+ #include <WiFi.h>
40
+ #if ESP_ARDUINO_VERSION_MAJOR >= 3
41
+ #include "esp_mac.h" // required for core 3.x - exposes esp_mac_type_t values
42
+ #endif
43
+ #elif defined(ESP8266)
44
+ #include <ESP8266WiFi.h>
45
+ #include <ESPAsyncTCP.h>
46
+ #endif // ESP32
47
+
48
+ // Define TSTRING - use std::string in test environment, Arduino String
49
+ // otherwise
50
+ #if defined(PAINLESSMESH_BOOST)
51
+ // Test environment - TSTRING already defined in test Arduino.h as std::string
52
+ #else
53
+ typedef String TSTRING;
54
+ #endif
55
+
56
+ // backward compatibility
57
+ template <typename T>
58
+ using SimpleList = std::list<T>;
59
+
60
+ namespace painlessmesh {
61
+ namespace wifi {
62
+ class Mesh;
63
+ };
64
+ }; // namespace painlessmesh
65
+
66
+ /** A convenience typedef to access the mesh class*/
67
+ #ifdef PAINLESSMESH_ENABLE_ARDUINO_WIFI
68
+ using painlessMesh = painlessmesh::wifi::Mesh;
69
+ #endif
70
+
71
+ #ifdef ESP32
72
+ #define MAX_CONN 10
73
+ #else
74
+ #define MAX_CONN 4
75
+ #endif // DEBUG
76
+
77
+ #endif
@@ -1,192 +1,192 @@
1
- #ifndef _PAINLESS_MESH_CONNECTION_HPP_
2
- #define _PAINLESS_MESH_CONNECTION_HPP_
3
-
4
- #include <memory>
5
-
6
- #include "Arduino.h"
7
- #include "painlessmesh/configuration.hpp"
8
-
9
- #include "painlessmesh/buffer.hpp"
10
- #include "painlessmesh/logger.hpp"
11
-
12
- extern painlessmesh::logger::LogClass Log;
13
-
14
- namespace painlessmesh {
15
- namespace tcp {
16
-
17
- // Shared buffer for reading/writing to the buffer
18
- static painlessmesh::buffer::temp_buffer_t shared_buffer;
19
-
20
- /**
21
- * Class that performs buffered read and write to the tcp connection
22
- * (asyncclient)
23
- *
24
- * Note that the class expects to be wrapped in a shared_ptr to ensure proper
25
- * lifetime management. Objects generally will only be destroyed after close is
26
- * called (and the reading and writing tasks are stopped).
27
- */
28
- class BufferedConnection
29
- : public std::enable_shared_from_this<BufferedConnection> {
30
- public:
31
- /**
32
- * Create a buffered connection around the client
33
- *
34
- *
35
- * BufferedConnection takes ownership of the client and will delete the
36
- * pointer at the end.
37
- *
38
- * One should always call initialize after construction
39
- */
40
- BufferedConnection(AsyncClient *client) : client(client) {}
41
-
42
- ~BufferedConnection() {
43
- Log.remote("~BufferedConnection");
44
- this->close();
45
- if (!client->freeable()) {
46
- client->close(true);
47
- }
48
- client->abort();
49
- delete client;
50
- }
51
-
52
- void initialize(Scheduler *scheduler) {
53
- auto self = this->shared_from_this();
54
- sentBufferTask.set(TASK_SECOND, TASK_FOREVER, [self]() {
55
- if (!self->sentBuffer.empty() && self->client->canSend()) {
56
- auto ret = self->writeNext();
57
- if (ret)
58
- self->sentBufferTask.forceNextIteration();
59
- else
60
- self->sentBufferTask.delay(100 * TASK_MILLISECOND);
61
- }
62
- });
63
- scheduler->addTask(sentBufferTask);
64
- sentBufferTask.enableDelayed();
65
-
66
- readBufferTask.set(TASK_SECOND, TASK_FOREVER, [self]() {
67
- if (!self->receiveBuffer.empty()) {
68
- TSTRING frnt = self->receiveBuffer.front();
69
- self->receiveBuffer.pop_front();
70
- if (!self->receiveBuffer.empty())
71
- self->readBufferTask.forceNextIteration();
72
- if (self->receiveCallback) self->receiveCallback(frnt);
73
- }
74
- });
75
- scheduler->addTask(readBufferTask);
76
- readBufferTask.enableDelayed();
77
-
78
- client->onAck(
79
- [self](void *arg, AsyncClient *client, size_t len, uint32_t time) {
80
- self->sentBufferTask.forceNextIteration();
81
- },
82
- NULL);
83
-
84
- client->onData(
85
- [self](void *arg, AsyncClient *client, void *data, size_t len) {
86
- self->receiveBuffer.push(static_cast<const char *>(data), len,
87
- shared_buffer);
88
- // Signal that we are done
89
- self->client->ack(len);
90
- self->readBufferTask.forceNextIteration();
91
- },
92
- NULL);
93
-
94
- client->onDisconnect(
95
- [self](void *arg, AsyncClient *client) { self->close(); }, NULL);
96
- }
97
-
98
- void close() {
99
- if (!mConnected) return;
100
-
101
- // Disable tasks and callbacks
102
- this->sentBufferTask.setCallback(NULL);
103
- this->sentBufferTask.disable();
104
- this->readBufferTask.setCallback(NULL);
105
- this->readBufferTask.disable();
106
-
107
- this->client->onData(NULL, NULL);
108
- this->client->onAck(NULL, NULL);
109
- this->client->onDisconnect(NULL, NULL);
110
- this->client->onError(NULL, NULL);
111
-
112
- if (client->connected()) {
113
- client->close();
114
- }
115
-
116
- receiveBuffer.clear();
117
- sentBuffer.clear();
118
-
119
- if (disconnectCallback) disconnectCallback();
120
-
121
- receiveCallback = NULL;
122
- disconnectCallback = NULL;
123
-
124
- mConnected = false;
125
- }
126
-
127
- bool write(const TSTRING &data, bool priority = false) {
128
- sentBuffer.push(data, priority);
129
- sentBufferTask.forceNextIteration();
130
- return true;
131
- }
132
-
133
- void onDisconnect(std::function<void()> callback) {
134
- disconnectCallback = callback;
135
- }
136
-
137
- void onReceive(std::function<void(TSTRING)> callback) {
138
- receiveCallback = callback;
139
- }
140
-
141
- bool connected() { return mConnected; }
142
-
143
- protected:
144
- bool mConnected = true;
145
-
146
- AsyncClient *client;
147
-
148
- std::function<void(TSTRING)> receiveCallback;
149
- std::function<void()> disconnectCallback;
150
-
151
- painlessmesh::buffer::ReceiveBuffer<TSTRING> receiveBuffer;
152
- painlessmesh::buffer::SentBuffer<TSTRING> sentBuffer;
153
-
154
- bool writeNext() {
155
- if (sentBuffer.empty()) {
156
- return false;
157
- }
158
- auto len = sentBuffer.requestLength(shared_buffer.length);
159
- auto snd_len = client->space();
160
- if (len > snd_len) len = snd_len;
161
- if (len > 0) {
162
- // sentBuffer.read(len, shared_buffer);
163
- // auto written = client->write(shared_buffer.buffer, len, 1);
164
- auto data_ptr = sentBuffer.readPtr(len);
165
- auto written = client->write(data_ptr, len, 1);
166
- if (written == len) {
167
- client->send(); // TODO only do this for priority messages
168
- sentBuffer.freeRead();
169
- sentBufferTask.forceNextIteration();
170
- return true;
171
- } else if (written == 0) {
172
- return false;
173
- } else {
174
- return false;
175
- }
176
- } else {
177
- return false;
178
- }
179
- }
180
-
181
- Task sentBufferTask;
182
- Task readBufferTask;
183
-
184
- template <typename T>
185
- std::shared_ptr<T> shared_from(T *derived) {
186
- return std::static_pointer_cast<T>(shared_from_this());
187
- }
188
- }; // namespace tcp
189
- }; // namespace tcp
190
- }; // namespace painlessmesh
191
-
192
- #endif
1
+ #ifndef _PAINLESS_MESH_CONNECTION_HPP_
2
+ #define _PAINLESS_MESH_CONNECTION_HPP_
3
+
4
+ #include <memory>
5
+
6
+ #include "Arduino.h"
7
+ #include "painlessmesh/configuration.hpp"
8
+
9
+ #include "painlessmesh/buffer.hpp"
10
+ #include "painlessmesh/logger.hpp"
11
+
12
+ extern painlessmesh::logger::LogClass Log;
13
+
14
+ namespace painlessmesh {
15
+ namespace tcp {
16
+
17
+ // Shared buffer for reading/writing to the buffer
18
+ static painlessmesh::buffer::temp_buffer_t shared_buffer;
19
+
20
+ /**
21
+ * Class that performs buffered read and write to the tcp connection
22
+ * (asyncclient)
23
+ *
24
+ * Note that the class expects to be wrapped in a shared_ptr to ensure proper
25
+ * lifetime management. Objects generally will only be destroyed after close is
26
+ * called (and the reading and writing tasks are stopped).
27
+ */
28
+ class BufferedConnection
29
+ : public std::enable_shared_from_this<BufferedConnection> {
30
+ public:
31
+ /**
32
+ * Create a buffered connection around the client
33
+ *
34
+ *
35
+ * BufferedConnection takes ownership of the client and will delete the
36
+ * pointer at the end.
37
+ *
38
+ * One should always call initialize after construction
39
+ */
40
+ BufferedConnection(AsyncClient *client) : client(client) {}
41
+
42
+ ~BufferedConnection() {
43
+ Log.remote("~BufferedConnection");
44
+ this->close();
45
+ if (!client->freeable()) {
46
+ client->close(true);
47
+ }
48
+ client->abort();
49
+ delete client;
50
+ }
51
+
52
+ void initialize(Scheduler *scheduler) {
53
+ auto self = this->shared_from_this();
54
+ sentBufferTask.set(TASK_SECOND, TASK_FOREVER, [self]() {
55
+ if (!self->sentBuffer.empty() && self->client->canSend()) {
56
+ auto ret = self->writeNext();
57
+ if (ret)
58
+ self->sentBufferTask.forceNextIteration();
59
+ else
60
+ self->sentBufferTask.delay(100 * TASK_MILLISECOND);
61
+ }
62
+ });
63
+ scheduler->addTask(sentBufferTask);
64
+ sentBufferTask.enableDelayed();
65
+
66
+ readBufferTask.set(TASK_SECOND, TASK_FOREVER, [self]() {
67
+ if (!self->receiveBuffer.empty()) {
68
+ TSTRING frnt = self->receiveBuffer.front();
69
+ self->receiveBuffer.pop_front();
70
+ if (!self->receiveBuffer.empty())
71
+ self->readBufferTask.forceNextIteration();
72
+ if (self->receiveCallback) self->receiveCallback(frnt);
73
+ }
74
+ });
75
+ scheduler->addTask(readBufferTask);
76
+ readBufferTask.enableDelayed();
77
+
78
+ client->onAck(
79
+ [self](void *arg, AsyncClient *client, size_t len, uint32_t time) {
80
+ self->sentBufferTask.forceNextIteration();
81
+ },
82
+ NULL);
83
+
84
+ client->onData(
85
+ [self](void *arg, AsyncClient *client, void *data, size_t len) {
86
+ self->receiveBuffer.push(static_cast<const char *>(data), len,
87
+ shared_buffer);
88
+ // Signal that we are done
89
+ self->client->ack(len);
90
+ self->readBufferTask.forceNextIteration();
91
+ },
92
+ NULL);
93
+
94
+ client->onDisconnect(
95
+ [self](void *arg, AsyncClient *client) { self->close(); }, NULL);
96
+ }
97
+
98
+ void close() {
99
+ if (!mConnected) return;
100
+
101
+ // Disable tasks and callbacks
102
+ this->sentBufferTask.setCallback(NULL);
103
+ this->sentBufferTask.disable();
104
+ this->readBufferTask.setCallback(NULL);
105
+ this->readBufferTask.disable();
106
+
107
+ this->client->onData(NULL, NULL);
108
+ this->client->onAck(NULL, NULL);
109
+ this->client->onDisconnect(NULL, NULL);
110
+ this->client->onError(NULL, NULL);
111
+
112
+ if (client->connected()) {
113
+ client->close();
114
+ }
115
+
116
+ receiveBuffer.clear();
117
+ sentBuffer.clear();
118
+
119
+ if (disconnectCallback) disconnectCallback();
120
+
121
+ receiveCallback = NULL;
122
+ disconnectCallback = NULL;
123
+
124
+ mConnected = false;
125
+ }
126
+
127
+ bool write(const TSTRING &data, bool priority = false) {
128
+ sentBuffer.push(data, priority);
129
+ sentBufferTask.forceNextIteration();
130
+ return true;
131
+ }
132
+
133
+ void onDisconnect(std::function<void()> callback) {
134
+ disconnectCallback = callback;
135
+ }
136
+
137
+ void onReceive(std::function<void(TSTRING)> callback) {
138
+ receiveCallback = callback;
139
+ }
140
+
141
+ bool connected() { return mConnected; }
142
+
143
+ protected:
144
+ bool mConnected = true;
145
+
146
+ AsyncClient *client;
147
+
148
+ std::function<void(TSTRING)> receiveCallback;
149
+ std::function<void()> disconnectCallback;
150
+
151
+ painlessmesh::buffer::ReceiveBuffer<TSTRING> receiveBuffer;
152
+ painlessmesh::buffer::SentBuffer<TSTRING> sentBuffer;
153
+
154
+ bool writeNext() {
155
+ if (sentBuffer.empty()) {
156
+ return false;
157
+ }
158
+ auto len = sentBuffer.requestLength(shared_buffer.length);
159
+ auto snd_len = client->space();
160
+ if (len > snd_len) len = snd_len;
161
+ if (len > 0) {
162
+ // sentBuffer.read(len, shared_buffer);
163
+ // auto written = client->write(shared_buffer.buffer, len, 1);
164
+ auto data_ptr = sentBuffer.readPtr(len);
165
+ auto written = client->write(data_ptr, len, 1);
166
+ if (written == len) {
167
+ client->send(); // TODO only do this for priority messages
168
+ sentBuffer.freeRead();
169
+ sentBufferTask.forceNextIteration();
170
+ return true;
171
+ } else if (written == 0) {
172
+ return false;
173
+ } else {
174
+ return false;
175
+ }
176
+ } else {
177
+ return false;
178
+ }
179
+ }
180
+
181
+ Task sentBufferTask;
182
+ Task readBufferTask;
183
+
184
+ template <typename T>
185
+ std::shared_ptr<T> shared_from(T *derived) {
186
+ return std::static_pointer_cast<T>(shared_from_this());
187
+ }
188
+ }; // namespace tcp
189
+ }; // namespace tcp
190
+ }; // namespace painlessmesh
191
+
192
+ #endif