1#ifndef _PAINLESS_MESH_TCP_HPP_
2#define _PAINLESS_MESH_TCP_HPP_
20static const uint8_t TCP_CONNECT_MAX_RETRIES = 5;
21static const uint32_t TCP_CONNECT_RETRY_DELAY_MS = 1000;
22static const uint32_t TCP_CONNECT_STABILIZATION_DELAY_MS = 500;
27static const uint32_t TCP_EXHAUSTION_RECONNECT_DELAY_MS = 10000;
31static const uint32_t TCP_FAILURE_BLOCK_DURATION_MS = 60000;
38static const uint8_t TCP_RETRY_MAX_RETRIES_LIMIT = 10;
39static const uint32_t TCP_RETRY_MIN_DELAY_MS = 50;
40static const uint32_t TCP_RETRY_MAX_DELAY_MS = 60000;
83 uint8_t backoffMultiplier = (retryCount < 3) ? (1U << retryCount) : 8;
102 if (cfg.
maxRetries > TCP_RETRY_MAX_RETRIES_LIMIT)
113 Log(GENERAL,
"encodeNodeId():\n");
118 value |= hwaddr[2] << 24;
119 value |= hwaddr[3] << 16;
120 value |= hwaddr[4] << 8;
128#if defined(PAINLESSMESH_BOOST)
136 const uint8_t MESH_IP_FIRST_OCTET = 10;
137 const uint8_t MESH_IP_LAST_OCTET = 1;
138 if (ip[0] != MESH_IP_FIRST_OCTET || ip[3] != MESH_IP_LAST_OCTET) {
144 const uint8_t BYTE_SHIFT = 8;
145 uint32_t nodeId = ((uint32_t)ip[1] << BYTE_SHIFT) | (uint32_t)ip[2];
150template <
class T,
class M>
152 using namespace logger;
157 if (mesh.semaphoreTake()) {
158 Log(CONNECTION,
"New AP connection incoming\n");
159 auto conn = std::make_shared<T>(client, &mesh, false);
161 mesh.subs.push_back(conn);
162 mesh.semaphoreGive();
171 "New AP connection refused: mesh busy, closing it so the peer "
205template <
class T,
class M>
207 uint8_t retryCount = 0) {
208 using namespace logger;
219 Log(CONNECTION,
"tcp::connect(): Attempting connection to port %d (attempt %d/%d)\n",
234 auto claimed = std::make_shared<bool>(
false);
238 client.
onError([&mesh, ip, port, retryCount, claimed, cfg](
void *,
AsyncClient *client, int8_t err) {
244 "tcp_err(): onError fired after onConnect had already claimed "
245 "the client - ignored to avoid double handling\n");
249 if (mesh.semaphoreTake()) {
250 Log(CONNECTION,
"tcp_err(): error trying to connect %d (attempt %d/%d)\n",
258#if !defined(PAINLESSMESH_BOOST) && (defined(ESP32) || defined(ESP8266))
264 Log(CONNECTION,
"tcp_err(): Scheduling retry in %u ms\n", retryDelay);
274 mesh.addTask([&mesh, ip, port, retryCount]() {
275 Log(CONNECTION,
"tcp_err(): Retrying TCP connection...\n");
281 connect<T, M>((*pRetryConn), ip, port, mesh, retryCount + 1);
289 mesh.semaphoreGive();
296 Log(CONNECTION,
"tcp_err(): All %d retries exhausted for IP %s\n",
302 #if !defined(PAINLESSMESH_BOOST)
316 Log(CONNECTION,
"tcp_err(): Scheduling WiFi reconnection in %u ms\n",
328 mesh.addTask([&mesh]() {
329 Log(CONNECTION,
"tcp_err(): Executing delayed WiFi reconnection after retry exhaustion\n");
330 mesh.droppedConnectionCallbacks.execute(0,
true);
332 mesh.semaphoreGive();
350 "tcp::connect(): onConnect fired after onError had already "
351 "claimed the client - closing the connection and discarding "
357 if (mesh.semaphoreTake()) {
358 Log(CONNECTION,
"New STA connection incoming\n");
359 auto conn = std::make_shared<T>(client, &mesh,
true);
361 mesh.subs.push_back(conn);
362 mesh.semaphoreGive();
boost::asio::ip::address IPAddress
Definition asynctcp.hpp:29
Definition asynctcp.hpp:31
void onConnect(AcConnectHandler cb, void *arg=0)
Definition asynctcp.hpp:76
bool connect(IPAddress ipaddress, uint16_t port)
Definition asynctcp.hpp:36
void close(bool now=true)
Definition asynctcp.hpp:115
void onError(AcErrorHandler cb, void *arg=0)
Definition asynctcp.hpp:91
Definition asynctcp.hpp:217
void setNoDelay(bool value=true)
Definition asynctcp.hpp:257
void begin()
Definition asynctcp.hpp:233
void onClient(AcConnectHandler cb, void *arg=0)
Definition asynctcp.hpp:227
uint32_t decodeNodeIdFromIP(IPAddress ip)
Definition tcp.hpp:127
void initServer(AsyncServer &server, M &mesh)
Definition tcp.hpp:151
TcpRetryConfig clampTcpRetryConfig(TcpRetryConfig cfg)
Definition tcp.hpp:101
void scheduleAsyncClientDeletion(Scheduler *scheduler, AsyncClient *client, const char *logPrefix)
Definition connection.hpp:67
void connect(AsyncClient &client, IPAddress ip, uint16_t port, M &mesh, uint8_t retryCount=0)
Definition tcp.hpp:206
uint32_t encodeNodeId(const uint8_t *hwaddr)
Definition tcp.hpp:111
uint32_t retryBackoffDelay(const TcpRetryConfig &cfg, uint8_t retryCount)
Definition tcp.hpp:81
uint32_t stabilizationDelayMs
Delay after IP acquisition before the TCP connect is attempted (ms)
Definition tcp.hpp:63
uint8_t maxRetries
Max TCP connect retry attempts before falling back to a WiFi reconnect.
Definition tcp.hpp:59
uint32_t failureBlockDurationMs
Duration a node is blocklisted after retry exhaustion (ms, 0 = never)
Definition tcp.hpp:67
uint32_t retryDelayMs
Base delay between retry attempts (ms), scaled by exponential backoff.
Definition tcp.hpp:61
uint32_t exhaustionReconnectDelayMs
Delay before the WiFi reconnect that follows retry exhaustion (ms)
Definition tcp.hpp:65
painlessmesh::logger::LogClass Log
Definition wifi.cpp:2