@alteriom/painlessmesh 1.6.1 → 1.7.3

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 (152) hide show
  1. package/CHANGELOG.md +435 -144
  2. package/LICENSE +674 -674
  3. package/README.md +491 -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 +130 -71
  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/archive/DOCUSAURUS_DEPLOYMENT.md +166 -0
  25. package/docs/archive/FEATURE_PROPOSALS.md +337 -0
  26. package/docs/archive/LIBRARY_JSON_FIX.md +98 -0
  27. package/docs/archive/LIBRARY_STRUCTURE_FIX.md +215 -0
  28. package/docs/archive/PHASE1_IMPLEMENTATION.md +325 -0
  29. package/docs/archive/PHASE2_IMPLEMENTATION.md +567 -0
  30. package/docs/archive/RELEASE_SUMMARY.md +173 -0
  31. package/docs/archive/SCONS_BUILD_FIX.md +313 -0
  32. package/docs/archive/TRIGGER_RELEASE.md +280 -0
  33. package/docs/archive/VECTOR_INCLUDE_FIX.md +129 -0
  34. package/docs/archive/ota-and-status-enhancements.md +911 -0
  35. package/docs/archive/ota-status-architecture-diagrams.md +658 -0
  36. package/docs/archive/ota-status-quick-reference.md +284 -0
  37. package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +71 -0
  38. package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +1011 -0
  39. package/docs/development/DOCKER_TESTING.md +196 -0
  40. package/docs/development/PLATFORMIO_USAGE.md +180 -0
  41. package/docs/development/TESTING_SUMMARY.md +126 -0
  42. package/docs/development/contributing.md +301 -0
  43. package/docs/development/documentation.md +583 -0
  44. package/docs/getting-started/first-mesh.md +409 -409
  45. package/docs/getting-started/installation.md +274 -274
  46. package/docs/getting-started/quickstart.md +157 -157
  47. package/docs/improvements/FUTURE_PROPOSALS.md +1016 -0
  48. package/docs/improvements/IMPLEMENTATION_HISTORY.md +1091 -0
  49. package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +709 -0
  50. package/docs/improvements/README.md +212 -69
  51. package/docs/platformio-publishing.md +255 -0
  52. package/docs/platformio-setup-summary.md +121 -0
  53. package/docs/releases/FEATURE_HISTORY.md +543 -0
  54. package/docs/releases/PATCH_v1.7.3.md +262 -0
  55. package/docs/releases/PHASE1_SUMMARY.md +246 -0
  56. package/docs/releases/PHASE2_SUMMARY.md +499 -0
  57. package/docs/releases/RELEASE_NOTES_1.7.0.md +539 -0
  58. package/docs/troubleshooting/common-issues.md +520 -520
  59. package/docs/troubleshooting/debugging.md +455 -0
  60. package/docs/troubleshooting/faq.md +472 -472
  61. package/docs/tutorials/basic-examples.md +717 -717
  62. package/docs/wiki/API-Reference.md +245 -245
  63. package/docs/wiki/Complete-Documentation.md +122 -122
  64. package/examples/alteriom/README.md +139 -81
  65. package/examples/alteriom/alteriom.ino +186 -185
  66. package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
  67. package/examples/alteriom/platformio.ini +24 -24
  68. package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
  69. package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
  70. package/examples/alteriomImproved/platformio.ini +25 -0
  71. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
  72. package/examples/alteriomPhase1/phase1_features.ino +242 -0
  73. package/examples/alteriomPhase1/platformio.ini +25 -0
  74. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
  75. package/examples/alteriomPhase2/phase2_features.ino +186 -0
  76. package/examples/alteriomPhase2/platformio.ini +25 -0
  77. package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
  78. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
  79. package/examples/alteriomSensorNode/platformio.ini +25 -0
  80. package/examples/basic/basic.ino +66 -66
  81. package/examples/basic/platformio.ini +25 -25
  82. package/examples/bridge/bridge.ino +51 -51
  83. package/examples/bridge/mesh_event_publisher.hpp +253 -0
  84. package/examples/bridge/mesh_topology_reporter.hpp +303 -0
  85. package/examples/bridge/mqtt_command_bridge.hpp +459 -0
  86. package/examples/bridge/mqtt_status_bridge.hpp +519 -0
  87. package/examples/bridge/platformio.ini +25 -25
  88. package/examples/echoNode/echoNode.ino +33 -33
  89. package/examples/echoNode/platformio.ini +25 -25
  90. package/examples/logClient/logClient.ino +109 -109
  91. package/examples/logClient/platformio.ini +25 -25
  92. package/examples/logServer/logServer.ino +81 -81
  93. package/examples/logServer/platformio.ini +25 -25
  94. package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
  95. package/examples/meshCommandNode/meshCommandNode.ino +263 -0
  96. package/examples/meshCommandNode/platformio.ini +25 -0
  97. package/examples/mqttBridge/mqttBridge.ino +118 -118
  98. package/examples/mqttBridge/platformio.ini +26 -26
  99. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
  100. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
  101. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
  102. package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
  103. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
  104. package/examples/mqttCommandBridge/platformio.ini +26 -0
  105. package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
  106. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
  107. package/examples/mqttStatusBridge/platformio.ini +26 -0
  108. package/examples/mqttTopologyTest/README.md +467 -0
  109. package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
  110. package/examples/mqttTopologyTest/platformio.ini +26 -0
  111. package/examples/namedMesh/namedMesh.ino +97 -97
  112. package/examples/namedMesh/platformio.ini +25 -25
  113. package/examples/otaReceiver/otaReceiver.ino +79 -79
  114. package/examples/otaReceiver/platformio.ini +25 -25
  115. package/examples/otaSender/otaSender.ino +160 -151
  116. package/examples/otaSender/platformio.ini +25 -25
  117. package/examples/startHere/platformio.ini +25 -25
  118. package/examples/startHere/startHere.ino +159 -159
  119. package/examples/webServer/platformio.ini +27 -27
  120. package/examples/webServer/webServer.ino +89 -89
  121. package/keywords.txt +48 -48
  122. package/library.json +55 -34
  123. package/library.properties +10 -10
  124. package/package.json +86 -78
  125. package/src/AlteriomPainlessMesh.h +97 -97
  126. package/src/arduino/wifi.hpp +365 -365
  127. package/src/boost/asynctcp.hpp +279 -279
  128. package/src/painlessMesh.h +70 -70
  129. package/src/painlessMeshSTA.cpp +236 -236
  130. package/src/painlessMeshSTA.h +58 -58
  131. package/src/painlessTaskOptions.h +4 -4
  132. package/src/painlessmesh/base64.hpp +111 -111
  133. package/src/painlessmesh/buffer.hpp +229 -229
  134. package/src/painlessmesh/callback.hpp +91 -91
  135. package/src/painlessmesh/configuration.hpp +77 -77
  136. package/src/painlessmesh/connection.hpp +192 -192
  137. package/src/painlessmesh/layout.hpp +188 -188
  138. package/src/painlessmesh/logger.hpp +158 -158
  139. package/src/painlessmesh/memory.hpp +119 -119
  140. package/src/painlessmesh/mesh.hpp +761 -560
  141. package/src/painlessmesh/metrics.hpp +322 -322
  142. package/src/painlessmesh/ntp.hpp +263 -263
  143. package/src/painlessmesh/ota.hpp +582 -553
  144. package/src/painlessmesh/plugin.hpp +188 -188
  145. package/src/painlessmesh/protocol.hpp +813 -813
  146. package/src/painlessmesh/router.hpp +338 -322
  147. package/src/painlessmesh/tcp.hpp +71 -71
  148. package/src/painlessmesh/validation.hpp +238 -238
  149. package/src/plugin/performance.hpp +214 -214
  150. package/src/plugin/remote.hpp +64 -64
  151. package/src/scheduler.cpp +10 -10
  152. 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