@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,279 +1,279 @@
1
- #ifndef _BOOST_ASYNCTCP_HPP_
2
- #define _BOOST_ASYNCTCP_HPP_
3
-
4
- #include <boost/array.hpp>
5
- #include <boost/asio.hpp>
6
- #include <iostream>
7
-
8
- #ifndef TCP_MSS
9
- #define TCP_MSS 1024
10
- #endif
11
-
12
- using boost::asio::ip::tcp;
13
-
14
- #define ASYNC_WRITE_FLAG_COPY 0x01
15
-
16
- class AsyncClient;
17
-
18
- typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
19
- typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)>
20
- AcAckHandler;
21
- typedef std::function<void(void*, AsyncClient*, int8_t error)> AcErrorHandler;
22
- typedef std::function<void(void*, AsyncClient*, void* data, size_t len)>
23
- AcDataHandler;
24
- // typedef std::function<void(void*, AsyncClient*, struct pbuf* pb)>
25
- // AcPacketHandler;
26
- typedef std::function<void(void*, AsyncClient*, uint32_t time)>
27
- AcTimeoutHandler;
28
-
29
- typedef boost::asio::ip::address IPAddress;
30
-
31
- class AsyncClient {
32
- public:
33
- AsyncClient(boost::asio::io_context& io_service)
34
- : _io_service(io_service), mSocket(_io_service) {}
35
-
36
- bool connect(IPAddress ipaddress, uint16_t port) {
37
- namespace ip = boost::asio::ip;
38
- auto endpoint = ip::tcp::endpoint(ipaddress, port);
39
-
40
- mSocket.async_connect(endpoint, [&](auto& ec) { this->handleConnect(ec); });
41
- return true;
42
- }
43
-
44
- void initRead() {
45
- mSocket.async_read_some(
46
- boost::asio::buffer(mInputBuffer, TCP_MSS),
47
- [&](auto& ec, auto len) { this->handleData(ec, len); });
48
- }
49
-
50
- size_t write(const void* data, size_t len,
51
- size_t copy = ASYNC_WRITE_FLAG_COPY) {
52
- if (writing) return 0;
53
- writing = true;
54
- if (copy == ASYNC_WRITE_FLAG_COPY) {
55
- memcpy(mWriteBuffer, data, len);
56
- mSocket.async_send(
57
- boost::asio::buffer(mWriteBuffer, len),
58
- [&](auto& ec, auto len) { this->handleWrite(ec, len); });
59
- } else {
60
- mSocket.async_send(
61
- boost::asio::buffer(data, len),
62
- [&](auto& ec, auto len) { this->handleWrite(ec, len); });
63
- }
64
- return len;
65
- }
66
-
67
- // Dummy functions for compatibility with ESPAsycnTCP
68
- void send() {}
69
- void setNoDelay(bool value = true) {}
70
- void setRxTimeout(uint32_t timeout) {}
71
- const char* errorToString(int8_t error) { return ""; }
72
-
73
- // TODO: check if there is a better one
74
- void abort() { this->close(true); }
75
-
76
- void onConnect(AcConnectHandler cb, void* arg = 0) {
77
- _connect_cb = cb;
78
- _connect_cb_arg = arg;
79
- }
80
-
81
- void onDisconnect(AcConnectHandler cb, void* arg = 0) {
82
- _discard_cb = cb;
83
- _discard_cb_arg = arg;
84
- }
85
-
86
- void onAck(AcAckHandler cb, void* arg = 0) {
87
- _sent_cb = cb;
88
- _sent_cb_arg = arg;
89
- }
90
-
91
- void onError(AcErrorHandler cb, void* arg = 0) {
92
- _error_cb = cb;
93
- _error_cb_arg = arg;
94
- }
95
-
96
- void onData(AcDataHandler cb, void* arg = 0) {
97
- _recv_cb = cb;
98
- _recv_cb_arg = arg;
99
- }
100
-
101
- void onTimeout(AcTimeoutHandler cb, void* arg = 0) {
102
- _timeout_cb = cb;
103
- _timeout_cb_arg = arg;
104
- }
105
-
106
- void onPoll(AcConnectHandler cb, void* arg = 0) {
107
- _poll_cb = cb;
108
- _poll_cb_arg = arg;
109
- }
110
-
111
- bool connected() { return mSocket.is_open(); }
112
-
113
- bool freeable() { return !this->connected(); }
114
-
115
- void close(bool now = true) {
116
- if (this->connected()) {
117
- mSocket.close();
118
- }
119
- if (!disconnectCalled) {
120
- disconnectCalled = true;
121
- if (_discard_cb) {
122
- _discard_cb(_discard_cb_arg, this);
123
- }
124
- }
125
- }
126
-
127
- ~AsyncClient() { close(true); }
128
-
129
- size_t space() {
130
- // This could be more intelligent, but simple and safe for now
131
- if (writing) return 0;
132
- return TCP_MSS;
133
- }
134
-
135
- bool canSend() { return this->space() > 0; }
136
-
137
- size_t ack(size_t len) {
138
- // Currently assumes that len is actually the size of the data that was sent
139
- // Otherwise it will break
140
- initRead();
141
- return len;
142
- }
143
-
144
- tcp::socket& socket() { return mSocket; }
145
-
146
- protected:
147
- boost::asio::io_context& _io_service;
148
- tcp::socket mSocket;
149
-
150
- char mInputBuffer[TCP_MSS];
151
- char mWriteBuffer[TCP_MSS];
152
- bool writing = false;
153
-
154
- bool disconnectCalled = false;
155
-
156
- AcConnectHandler _connect_cb = 0;
157
- void* _connect_cb_arg = 0;
158
- AcConnectHandler _discard_cb = 0;
159
- void* _discard_cb_arg = 0;
160
- AcAckHandler _sent_cb = 0;
161
- void* _sent_cb_arg = 0;
162
- AcErrorHandler _error_cb = 0;
163
- void* _error_cb_arg = 0;
164
- AcDataHandler _recv_cb = 0;
165
- void* _recv_cb_arg = 0;
166
- AcTimeoutHandler _timeout_cb = 0;
167
- void* _timeout_cb_arg = 0;
168
- AcConnectHandler _poll_cb = 0;
169
- void* _poll_cb_arg = 0;
170
-
171
- void handleConnect(const boost::system::error_code& ec) {
172
- if (!ec) {
173
- if (_connect_cb) _connect_cb(_connect_cb_arg, this);
174
-
175
- initRead();
176
- } else {
177
- handleError(ec);
178
- if (this->connected()) close(true);
179
- }
180
- }
181
-
182
- void handleData(const boost::system::error_code& ec, size_t len) {
183
- if (disconnectCalled) return;
184
-
185
- if (!ec) {
186
- if (_recv_cb) {
187
- _recv_cb(_recv_cb_arg, this, (void*)mInputBuffer, len);
188
- }
189
- } else {
190
- handleError(ec);
191
- close(true);
192
- }
193
- }
194
-
195
- void handleWrite(const boost::system::error_code& ec, size_t len) {
196
- if (disconnectCalled) return;
197
-
198
- if (!ec) {
199
- if (_sent_cb) {
200
- // TODO send actual time
201
- _sent_cb(_sent_cb_arg, this, len, 0);
202
- }
203
- writing = false;
204
- } else {
205
- handleError(ec);
206
- close(true);
207
- }
208
- }
209
-
210
- void handleError(const boost::system::error_code& ec) {
211
- if (ec != boost::asio::error::eof && _error_cb) {
212
- _error_cb(_error_cb_arg, this, ec.value());
213
- }
214
- }
215
- };
216
-
217
- class AsyncServer {
218
- public:
219
- AsyncServer(boost::asio::io_context& io_service, uint16_t port)
220
- : _io_service(io_service),
221
- // mSocket(io_service),
222
- _port(port),
223
- mAcceptor(io_service) {}
224
-
225
- ~AsyncServer() { this->end(); }
226
-
227
- void onClient(AcConnectHandler cb, void* arg = 0) {
228
- _connect_cb = cb;
229
- _connect_cb_arg = arg;
230
- }
231
-
232
- // begin() should do start_accept (see server2):w
233
- void begin() {
234
- mAcceptor.open(tcp::v4());
235
- int one = 1;
236
- setsockopt(mAcceptor.native_handle(), SOL_SOCKET,
237
- SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one));
238
- boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), _port);
239
- mAcceptor.set_option(boost::asio::socket_base::reuse_address(true));
240
- mAcceptor.set_option(boost::asio::ip::tcp::no_delay(true));
241
- mAcceptor.set_option(boost::asio::socket_base::send_buffer_size(65536));
242
- mAcceptor.set_option(boost::asio::socket_base::receive_buffer_size(65536));
243
- mAcceptor.bind(endpoint);
244
- mAcceptor.listen();
245
- initAccept();
246
- }
247
-
248
- // Acceptor stop?
249
- void end() { mAcceptor.close(); }
250
-
251
- // Dummy function for compatibility with ESPAsycnTCP
252
- void setNoDelay(bool value = true) {}
253
-
254
- protected:
255
- boost::asio::io_context& _io_service;
256
- uint16_t _port;
257
- tcp::acceptor mAcceptor;
258
- AcConnectHandler _connect_cb = 0;
259
- void* _connect_cb_arg = 0;
260
-
261
- void initAccept() {
262
- #if BOOST_VERSION >= 107000
263
- AsyncClient* client = new AsyncClient(_io_service);
264
- #else
265
- AsyncClient* client = new AsyncClient(mAcceptor.get_io_service());
266
- #endif
267
- mAcceptor.async_accept(
268
- client->socket(), [this, client](const boost::system::error_code& e) {
269
- if (!e && this->_connect_cb) {
270
- this->_connect_cb(this->_connect_cb_arg, client);
271
- this->initAccept();
272
- client->initRead();
273
- } else
274
- std::cout << "Error: " << e.message() << std::endl;
275
- });
276
- }
277
- };
278
-
279
- #endif
1
+ #ifndef _BOOST_ASYNCTCP_HPP_
2
+ #define _BOOST_ASYNCTCP_HPP_
3
+
4
+ #include <boost/array.hpp>
5
+ #include <boost/asio.hpp>
6
+ #include <iostream>
7
+
8
+ #ifndef TCP_MSS
9
+ #define TCP_MSS 1024
10
+ #endif
11
+
12
+ using boost::asio::ip::tcp;
13
+
14
+ #define ASYNC_WRITE_FLAG_COPY 0x01
15
+
16
+ class AsyncClient;
17
+
18
+ typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
19
+ typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)>
20
+ AcAckHandler;
21
+ typedef std::function<void(void*, AsyncClient*, int8_t error)> AcErrorHandler;
22
+ typedef std::function<void(void*, AsyncClient*, void* data, size_t len)>
23
+ AcDataHandler;
24
+ // typedef std::function<void(void*, AsyncClient*, struct pbuf* pb)>
25
+ // AcPacketHandler;
26
+ typedef std::function<void(void*, AsyncClient*, uint32_t time)>
27
+ AcTimeoutHandler;
28
+
29
+ typedef boost::asio::ip::address IPAddress;
30
+
31
+ class AsyncClient {
32
+ public:
33
+ AsyncClient(boost::asio::io_context& io_service)
34
+ : _io_service(io_service), mSocket(_io_service) {}
35
+
36
+ bool connect(IPAddress ipaddress, uint16_t port) {
37
+ namespace ip = boost::asio::ip;
38
+ auto endpoint = ip::tcp::endpoint(ipaddress, port);
39
+
40
+ mSocket.async_connect(endpoint, [&](auto& ec) { this->handleConnect(ec); });
41
+ return true;
42
+ }
43
+
44
+ void initRead() {
45
+ mSocket.async_read_some(
46
+ boost::asio::buffer(mInputBuffer, TCP_MSS),
47
+ [&](auto& ec, auto len) { this->handleData(ec, len); });
48
+ }
49
+
50
+ size_t write(const void* data, size_t len,
51
+ size_t copy = ASYNC_WRITE_FLAG_COPY) {
52
+ if (writing) return 0;
53
+ writing = true;
54
+ if (copy == ASYNC_WRITE_FLAG_COPY) {
55
+ memcpy(mWriteBuffer, data, len);
56
+ mSocket.async_send(
57
+ boost::asio::buffer(mWriteBuffer, len),
58
+ [&](auto& ec, auto len) { this->handleWrite(ec, len); });
59
+ } else {
60
+ mSocket.async_send(
61
+ boost::asio::buffer(data, len),
62
+ [&](auto& ec, auto len) { this->handleWrite(ec, len); });
63
+ }
64
+ return len;
65
+ }
66
+
67
+ // Dummy functions for compatibility with ESPAsycnTCP
68
+ void send() {}
69
+ void setNoDelay(bool value = true) {}
70
+ void setRxTimeout(uint32_t timeout) {}
71
+ const char* errorToString(int8_t error) { return ""; }
72
+
73
+ // TODO: check if there is a better one
74
+ void abort() { this->close(true); }
75
+
76
+ void onConnect(AcConnectHandler cb, void* arg = 0) {
77
+ _connect_cb = cb;
78
+ _connect_cb_arg = arg;
79
+ }
80
+
81
+ void onDisconnect(AcConnectHandler cb, void* arg = 0) {
82
+ _discard_cb = cb;
83
+ _discard_cb_arg = arg;
84
+ }
85
+
86
+ void onAck(AcAckHandler cb, void* arg = 0) {
87
+ _sent_cb = cb;
88
+ _sent_cb_arg = arg;
89
+ }
90
+
91
+ void onError(AcErrorHandler cb, void* arg = 0) {
92
+ _error_cb = cb;
93
+ _error_cb_arg = arg;
94
+ }
95
+
96
+ void onData(AcDataHandler cb, void* arg = 0) {
97
+ _recv_cb = cb;
98
+ _recv_cb_arg = arg;
99
+ }
100
+
101
+ void onTimeout(AcTimeoutHandler cb, void* arg = 0) {
102
+ _timeout_cb = cb;
103
+ _timeout_cb_arg = arg;
104
+ }
105
+
106
+ void onPoll(AcConnectHandler cb, void* arg = 0) {
107
+ _poll_cb = cb;
108
+ _poll_cb_arg = arg;
109
+ }
110
+
111
+ bool connected() { return mSocket.is_open(); }
112
+
113
+ bool freeable() { return !this->connected(); }
114
+
115
+ void close(bool now = true) {
116
+ if (this->connected()) {
117
+ mSocket.close();
118
+ }
119
+ if (!disconnectCalled) {
120
+ disconnectCalled = true;
121
+ if (_discard_cb) {
122
+ _discard_cb(_discard_cb_arg, this);
123
+ }
124
+ }
125
+ }
126
+
127
+ ~AsyncClient() { close(true); }
128
+
129
+ size_t space() {
130
+ // This could be more intelligent, but simple and safe for now
131
+ if (writing) return 0;
132
+ return TCP_MSS;
133
+ }
134
+
135
+ bool canSend() { return this->space() > 0; }
136
+
137
+ size_t ack(size_t len) {
138
+ // Currently assumes that len is actually the size of the data that was sent
139
+ // Otherwise it will break
140
+ initRead();
141
+ return len;
142
+ }
143
+
144
+ tcp::socket& socket() { return mSocket; }
145
+
146
+ protected:
147
+ boost::asio::io_context& _io_service;
148
+ tcp::socket mSocket;
149
+
150
+ char mInputBuffer[TCP_MSS];
151
+ char mWriteBuffer[TCP_MSS];
152
+ bool writing = false;
153
+
154
+ bool disconnectCalled = false;
155
+
156
+ AcConnectHandler _connect_cb = 0;
157
+ void* _connect_cb_arg = 0;
158
+ AcConnectHandler _discard_cb = 0;
159
+ void* _discard_cb_arg = 0;
160
+ AcAckHandler _sent_cb = 0;
161
+ void* _sent_cb_arg = 0;
162
+ AcErrorHandler _error_cb = 0;
163
+ void* _error_cb_arg = 0;
164
+ AcDataHandler _recv_cb = 0;
165
+ void* _recv_cb_arg = 0;
166
+ AcTimeoutHandler _timeout_cb = 0;
167
+ void* _timeout_cb_arg = 0;
168
+ AcConnectHandler _poll_cb = 0;
169
+ void* _poll_cb_arg = 0;
170
+
171
+ void handleConnect(const boost::system::error_code& ec) {
172
+ if (!ec) {
173
+ if (_connect_cb) _connect_cb(_connect_cb_arg, this);
174
+
175
+ initRead();
176
+ } else {
177
+ handleError(ec);
178
+ if (this->connected()) close(true);
179
+ }
180
+ }
181
+
182
+ void handleData(const boost::system::error_code& ec, size_t len) {
183
+ if (disconnectCalled) return;
184
+
185
+ if (!ec) {
186
+ if (_recv_cb) {
187
+ _recv_cb(_recv_cb_arg, this, (void*)mInputBuffer, len);
188
+ }
189
+ } else {
190
+ handleError(ec);
191
+ close(true);
192
+ }
193
+ }
194
+
195
+ void handleWrite(const boost::system::error_code& ec, size_t len) {
196
+ if (disconnectCalled) return;
197
+
198
+ if (!ec) {
199
+ if (_sent_cb) {
200
+ // TODO send actual time
201
+ _sent_cb(_sent_cb_arg, this, len, 0);
202
+ }
203
+ writing = false;
204
+ } else {
205
+ handleError(ec);
206
+ close(true);
207
+ }
208
+ }
209
+
210
+ void handleError(const boost::system::error_code& ec) {
211
+ if (ec != boost::asio::error::eof && _error_cb) {
212
+ _error_cb(_error_cb_arg, this, ec.value());
213
+ }
214
+ }
215
+ };
216
+
217
+ class AsyncServer {
218
+ public:
219
+ AsyncServer(boost::asio::io_context& io_service, uint16_t port)
220
+ : _io_service(io_service),
221
+ // mSocket(io_service),
222
+ _port(port),
223
+ mAcceptor(io_service) {}
224
+
225
+ ~AsyncServer() { this->end(); }
226
+
227
+ void onClient(AcConnectHandler cb, void* arg = 0) {
228
+ _connect_cb = cb;
229
+ _connect_cb_arg = arg;
230
+ }
231
+
232
+ // begin() should do start_accept (see server2):w
233
+ void begin() {
234
+ mAcceptor.open(tcp::v4());
235
+ int one = 1;
236
+ setsockopt(mAcceptor.native_handle(), SOL_SOCKET,
237
+ SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one));
238
+ boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), _port);
239
+ mAcceptor.set_option(boost::asio::socket_base::reuse_address(true));
240
+ mAcceptor.set_option(boost::asio::ip::tcp::no_delay(true));
241
+ mAcceptor.set_option(boost::asio::socket_base::send_buffer_size(65536));
242
+ mAcceptor.set_option(boost::asio::socket_base::receive_buffer_size(65536));
243
+ mAcceptor.bind(endpoint);
244
+ mAcceptor.listen();
245
+ initAccept();
246
+ }
247
+
248
+ // Acceptor stop?
249
+ void end() { mAcceptor.close(); }
250
+
251
+ // Dummy function for compatibility with ESPAsycnTCP
252
+ void setNoDelay(bool value = true) {}
253
+
254
+ protected:
255
+ boost::asio::io_context& _io_service;
256
+ uint16_t _port;
257
+ tcp::acceptor mAcceptor;
258
+ AcConnectHandler _connect_cb = 0;
259
+ void* _connect_cb_arg = 0;
260
+
261
+ void initAccept() {
262
+ #if BOOST_VERSION >= 107000
263
+ AsyncClient* client = new AsyncClient(_io_service);
264
+ #else
265
+ AsyncClient* client = new AsyncClient(mAcceptor.get_io_service());
266
+ #endif
267
+ mAcceptor.async_accept(
268
+ client->socket(), [this, client](const boost::system::error_code& e) {
269
+ if (!e && this->_connect_cb) {
270
+ this->_connect_cb(this->_connect_cb_arg, client);
271
+ this->initAccept();
272
+ client->initRead();
273
+ } else
274
+ std::cout << "Error: " << e.message() << std::endl;
275
+ });
276
+ }
277
+ };
278
+
279
+ #endif