1#ifndef _PAINLESS_MESH_GATEWAY_HPP_
2#define _PAINLESS_MESH_GATEWAY_HPP_
37#if defined(ESP32) || defined(ESP8266)
38#include <WiFiClient.h>
53 return channel >= 1 && channel <= 13;
58 uint32_t electedBridgeId,
59 uint8_t currentChannel,
60 uint8_t announcedChannel) {
61 return electedBridgeId != localNodeId &&
63 announcedChannel != currentChannel;
107 uint8_t avoidChannel, uint8_t routerChannel = 0) {
110 for (
const auto& c : candidates) {
112 if (c.channel == routerChannel)
return c.
channel;
114 if (slot ==
nullptr || c.
rssi > slot->
rssi) slot = &c;
116 if (elsewhere !=
nullptr)
return elsewhere->
channel;
117 if (here !=
nullptr)
return here->
channel;
133 explicit operator bool()
const {
return valid; }
345 "routerSSID exceeds maximum length of 32 characters");
351 false,
"routerPassword exceeds maximum length of 63 characters");
362 false,
"internetCheckInterval must be at least 1000ms");
367 "internetCheckTimeout must be at least 100ms");
373 "internetCheckTimeout must be less than internetCheckInterval");
378 false,
"gatewayHeartbeatInterval must be at least 1000ms");
384 "gatewayFailureTimeout should be at least 2x gatewayHeartbeatInterval");
389 false,
"duplicateTrackingTimeout must be at least 1000ms");
466 bool isStale(uint32_t maxAgeMs = 60000)
const {
532 checkInterval_ = intervalMs;
540 checkTimeout_ = timeoutMs;
548 connectivityChangedCallback_ = callback;
578 onDemandSpent_ =
false;
582 bool connected = performTcpCheck();
595 if (connectivityChangedCallback_) {
596 connectivityChangedCallback_(connected);
618 if (onDemandSpent_)
return false;
620 onDemandSpent_ =
true;
629 return checkInterval_;
637 return checkTimeout_;
669#ifdef PAINLESSMESH_BOOST
674 void setMockConnected(
bool connected) {
675 mockConnected_ = connected;
689 bool performTcpCheck() {
690#ifdef PAINLESSMESH_BOOST
692 if (mockConnected_) {
696 status_.
lastError =
"Mock: No Internet in test environment";
698#elif defined(ESP32) || defined(ESP8266)
702 if (WiFi.status() != WL_CONNECTED) {
703 status_.
lastError =
"Station not connected";
707 uint32_t started = millis();
709 bool connected = client.connect(checkHost_.c_str(), checkPort_, checkTimeout_);
718 client.setTimeout(checkTimeout_);
719 bool connected = client.connect(checkHost_.c_str(), checkPort_);
723 status_.
lastError =
"TCP connectivity check failed";
729 status_.
lastError =
"Internet health checks are unsupported on this platform";
735 TSTRING checkHost_ =
"8.8.8.8";
736 uint16_t checkPort_ = 53;
737 uint32_t checkInterval_ = 30000;
738 uint32_t checkTimeout_ = 5000;
741 InternetStatus status_;
743 bool onDemandSpent_ =
false;
745#ifdef PAINLESSMESH_BOOST
746 bool mockConnected_ =
false;
938#if ARDUINOJSON_VERSION_MAJOR < 7
939 if (jsonObj.containsKey(
"dest_url"))
941 if (jsonObj.containsKey(
"payload"))
942 payload = jsonObj[
"payload"].as<TSTRING>();
943 if (jsonObj.containsKey(
"content"))
946 if (jsonObj[
"dest_url"].is<TSTRING>())
948 if (jsonObj[
"payload"].is<TSTRING>())
949 payload = jsonObj[
"payload"].as<TSTRING>();
950 if (jsonObj[
"content"].is<TSTRING>())
963 JsonObject
addTo(JsonObject&& jsonObj)
const {
964 jsonObj = SinglePackage::addTo(std::move(jsonObj));
978#if ARDUINOJSON_VERSION_MAJOR < 7
1016 static uint16_t counter =
1019 if (counter == 0) ++counter;
1021 return ((nodeId & 0xFFFF) << 16) | counter;
1134static const size_t GATEWAY_RESPONSE_REASON_MAX = 240;
1142static const size_t GATEWAY_RESPONSE_HEAD_BYTES = 512;
1143static const size_t GATEWAY_RESPONSE_TAIL_BYTES = 256;
1150static const size_t GATEWAY_RESPONSE_SCAN_BYTES = 8192;
1153static const uint32_t GATEWAY_RESPONSE_HEAD_TIMEOUT_MS = 250;
1160static const uint32_t GATEWAY_RETRY_AFTER_MAX_MS = 60000;
1163#if defined(PAINLESSMESH_BOOST)
1164 return haystack.find(needle) != std::string::npos;
1166 return haystack.indexOf(needle) >= 0;
1180 const TSTRING& body,
size_t maxLen = GATEWAY_RESPONSE_REASON_MAX) {
1183 bool pendingSpace =
false;
1184 for (
size_t i = 0; i < body.length(); ++i) {
1185 const char c = body[i];
1192 pendingSpace =
true;
1195 if (inTag)
continue;
1196 if (c ==
' ' || c ==
'\t' || c ==
'\r' || c ==
'\n') {
1197 pendingSpace =
true;
1200 if (pendingSpace && text.length() > 0) text +=
' ';
1201 pendingSpace =
false;
1204 if (text.length() <= maxLen)
return text;
1206 static const char JOIN[] =
" ... ";
1207 const size_t joinLength =
sizeof(JOIN) - 1;
1208 const size_t room = maxLen > joinLength ? maxLen - joinLength : 0;
1209 const size_t head = room / 2;
1210 const size_t tail = room - head;
1212 for (
size_t i = 0; i < head; ++i) out += text[i];
1214 for (
size_t i = text.length() - tail; i < text.length(); ++i) out += text[i];
1233 if (head_.length() < GATEWAY_RESPONSE_HEAD_BYTES) {
1236 tail_[(tailStart_ + tailLength_) % GATEWAY_RESPONSE_TAIL_BYTES] = c;
1237 if (tailLength_ < GATEWAY_RESPONSE_TAIL_BYTES) {
1240 tailStart_ = (tailStart_ + 1) % GATEWAY_RESPONSE_TAIL_BYTES;
1243 return seen_ < GATEWAY_RESPONSE_SCAN_BYTES;
1247 for (
size_t i = 0; i <
text.length(); ++i) {
1254 if (seen_ > head_.length() + tailLength_) out +=
" ... ";
1255 for (
size_t i = 0; i < tailLength_; ++i) {
1256 out += tail_[(tailStart_ + i) % GATEWAY_RESPONSE_TAIL_BYTES];
1263 char tail_[GATEWAY_RESPONSE_TAIL_BYTES] = {};
1264 size_t tailStart_ = 0;
1265 size_t tailLength_ = 0;
1292 state_ = State::SizeLf;
1293 }
else if (c ==
';') {
1294 state_ = State::Extension;
1295 }
else if (c ==
' ' || c ==
'\t') {
1298 const int digit = hexValue(c);
1299 if (digit < 0 || sizeDigits_ >= 8)
return stop();
1300 remaining_ = (remaining_ << 4) | static_cast<uint32_t>(digit);
1304 case State::Extension:
1305 if (c ==
'\r') state_ = State::SizeLf;
1308 if (c !=
'\n' || sizeDigits_ == 0)
return stop();
1310 if (remaining_ == 0) {
1311 state_ = State::Done;
1314 state_ = State::Data;
1318 if (remaining_ == 0) state_ = State::DataCr;
1319 if (!excerpt_.
add(c)) {
1320 state_ = State::Done;
1325 if (c !=
'\r')
return stop();
1326 state_ = State::DataLf;
1329 if (c !=
'\n')
return stop();
1330 state_ = State::Size;
1339 for (
size_t i = 0; i < raw.length(); ++i) {
1340 if (!
add(raw[i]))
return;
1345 bool complete()
const {
return state_ == State::Done && !malformed_; }
1348 enum class State { Size, Extension, SizeLf, Data, DataCr, DataLf, Done };
1350 static int hexValue(
char c) {
1351 if (c >=
'0' && c <=
'9')
return c -
'0';
1352 if (c >=
'a' && c <=
'f')
return c -
'a' + 10;
1353 if (c >=
'A' && c <=
'F')
return c -
'A' + 10;
1359 state_ = State::Done;
1363 ResponseExcerpt& excerpt_;
1364 State state_ = State::Size;
1365 uint32_t remaining_ = 0;
1366 uint8_t sizeDigits_ = 0;
1367 bool malformed_ =
false;
1373 for (
size_t i = 0; i < value.length(); ++i) {
1374 const char c = value[i];
1375 lower += (c >=
'A' && c <= 'Z') ? static_cast<char>(c -
'A' +
'a') : c;
1389 uint64_t seconds = 0;
1391 for (
size_t i = 0; i < value.length(); ++i) {
1392 const char c = value[i];
1393 if (c ==
' ' || c ==
'\t') {
1394 if (digits == 0)
continue;
1397 if (c <
'0' || c >
'9')
return 0;
1398 seconds = seconds * 10 +
static_cast<uint64_t
>(c -
'0');
1399 if (seconds > 0xFFFFFFFFULL / 1000ULL)
return 0xFFFFFFFFUL;
1402 return digits == 0 ? 0 :
static_cast<uint32_t
>(seconds * 1000ULL);
1418 uint32_t requestNonce = 0) {
1420 if (requestNonce == 0) {
1421 snprintf(buffer,
sizeof(buffer),
"pm-%08x-%08x",
1422 static_cast<unsigned>(originNode),
static_cast<unsigned>(messageId));
1424 snprintf(buffer,
sizeof(buffer),
"pm-%08x-%08x-%08x",
1425 static_cast<unsigned>(originNode),
static_cast<unsigned>(messageId),
1426 static_cast<unsigned>(requestNonce));
1434 return nonce != 0 ? nonce : 1;
1460 static_cast<uint16_t
>(rawCode > 0xFFFF ? 0xFFFF : rawCode);
1462 rawCode == 200 || rawCode == 201 || rawCode == 202 || rawCode == 204;
1464 outcome.
retryable = rawCode == 429 || rawCode == 503;
1477static const char GATEWAY_NOT_A_GATEWAY_PHRASE[] =
"is not an Internet gateway";
1489static const uint32_t GATEWAY_DNS_NEGATIVE_TTL_MS = 60000;
1498 const char* s = url.c_str();
1499 const size_t n = url.length();
1501 for (
size_t k = 0; k + 2 < n; ++k) {
1502 if (s[k] ==
':' && s[k + 1] ==
'/' && s[k + 2] ==
'/') {
1508 while (j < n && s[j] !=
'/' && s[j] !=
'?' && s[j] !=
'#' && s[j] !=
':') ++j;
1510 for (
size_t k = i; k < j; ++k) host += s[k];
1516 if (host.length() == 0)
return false;
1517 for (
size_t i = 0; i < host.length(); ++i) {
1518 const char c = host[i];
1519 if (!(c >=
'0' && c <=
'9') && c !=
'.')
return false;
1539 uint32_t ttlMs = GATEWAY_DNS_NEGATIVE_TTL_MS) {
1540 Entry* slot = find(host);
1541 if (slot ==
nullptr) {
1542 slot = &entries_[0];
1543 for (
size_t i = 0; i <
SLOTS; ++i) {
1544 if (!entries_[i].used) {
1545 slot = &entries_[i];
1548 if (
static_cast<int32_t
>(entries_[i].at - slot->at) < 0) slot = &entries_[i];
1559 Entry* slot = find(host);
1560 if (slot ==
nullptr)
return false;
1561 const uint32_t age = nowMs - slot->at;
1562 if (age >= slot->ttl) {
1566 if (ageMs !=
nullptr) *ageMs = age;
1571 Entry* slot = find(host);
1572 if (slot !=
nullptr) slot->used =
false;
1577 for (
size_t i = 0; i <
SLOTS; ++i) n += entries_[i].used ? 1 : 0;
1589 Entry* find(
const TSTRING& host) {
1590 for (
size_t i = 0; i <
SLOTS; ++i) {
1591 if (entries_[i].used && entries_[i].host == host)
return &entries_[i];
1596 Entry entries_[
SLOTS];
1755 success = jsonObj[
"success"] |
false;
1759#if ARDUINOJSON_VERSION_MAJOR < 7
1760 if (jsonObj.containsKey(
"err"))
1762 if (jsonObj.containsKey(
"resp"))
1763 response = jsonObj[
"resp"].as<TSTRING>();
1764 if (jsonObj.containsKey(
"retry"))
1765 retryable = jsonObj[
"retry"].as<bool>() ? 1 : 0;
1767 if (jsonObj[
"err"].is<TSTRING>())
1768 error = jsonObj[
"err"].as<TSTRING>();
1769 if (jsonObj[
"resp"].is<TSTRING>())
1770 response = jsonObj[
"resp"].as<TSTRING>();
1771 if (jsonObj[
"retry"].is<bool>())
1772 retryable = jsonObj[
"retry"].as<bool>() ? 1 : 0;
1785 JsonObject
addTo(JsonObject&& jsonObj)
const {
1786 jsonObj = SinglePackage::addTo(std::move(jsonObj));
1791 jsonObj[
"err"] =
error;
1801#if ARDUINOJSON_VERSION_MAJOR < 7
1846#ifndef GATEWAY_HTTP_TIMEOUT_MS
1847#define GATEWAY_HTTP_TIMEOUT_MS ((NODE_TIMEOUT) / TASK_MILLISECOND / 5)
1852#ifndef GATEWAY_CAPTIVE_PORTAL_TIMEOUT_MS
1853#define GATEWAY_CAPTIVE_PORTAL_TIMEOUT_MS ((NODE_TIMEOUT) / TASK_MILLISECOND / 10)
1864#ifndef GATEWAY_DNS_TIMEOUT_MS
1865#define GATEWAY_DNS_TIMEOUT_MS ((NODE_TIMEOUT) / TASK_MILLISECOND / 10)
1874#ifndef GATEWAY_CONNECTIVITY_CACHE_MS
1875#define GATEWAY_CONNECTIVITY_CACHE_MS 60000UL
1913 "Gateway blocking budget (2x GATEWAY_HTTP_TIMEOUT_MS + 2x "
1914 "GATEWAY_CAPTIVE_PORTAL_TIMEOUT_MS + GATEWAY_DNS_TIMEOUT_MS) "
1915 "must stay below NODE_TIMEOUT, or a gateway request stalls the "
1916 "scheduler for longer than its peers are willing to wait and "
1917 "the mesh partitions around the gateway. Raise NODE_TIMEOUT if "
1918 "you need a longer HTTP timeout.");
1928template <
typename T>
1930 if (!connection.timeOutTask.isEnabled())
return false;
1931 connection.timeOutTask.adjust(
static_cast<long>(
1982template <
typename T>
1984 if (stalledMs == 0)
return 0;
1985 size_t refreshed = 0;
1986 for (
auto&& connection : mesh.subs) {
1987 if (!connection)
continue;
1988 if (!connection->timeOutTask.isEnabled())
continue;
1989 connection->timeOutTask.adjust(
1990 static_cast<long>(stalledMs * TASK_MILLISECOND));
Removes HTTP/1.1 chunked transfer framing from a body read a byte at a time, and passes the content o...
Definition gateway.hpp:1282
bool add(char c)
Definition gateway.hpp:1288
void add(const TSTRING &raw)
Definition gateway.hpp:1338
ChunkedBodyDecoder(ResponseExcerpt &excerpt)
Definition gateway.hpp:1284
bool complete() const
Definition gateway.hpp:1345
Gateway Acknowledgment Package for delivery confirmations.
Definition gateway.hpp:1651
JsonObject addTo(JsonObject &&jsonObj) const
Serialize to JSON object.
Definition gateway.hpp:1785
TSTRING response
The start of the response body, summarized to one line.
Definition gateway.hpp:1709
size_t jsonObjectSize() const
Calculate JSON object size for ArduinoJson v6.
Definition gateway.hpp:1809
bool success
Delivery success status.
Definition gateway.hpp:1675
uint32_t messageId
Original message ID being acknowledged.
Definition gateway.hpp:1659
GatewayAckPackage()
Default constructor.
Definition gateway.hpp:1742
static constexpr int numPackageFields
Number of additional JSON fields in this package.
Definition gateway.hpp:1735
int8_t retryable
Whether the origin node may resend the identical request.
Definition gateway.hpp:1719
uint32_t timestamp
Acknowledgment timestamp.
Definition gateway.hpp:1700
uint32_t retryAfterMs
How long the server asked to wait before a retry, in milliseconds.
Definition gateway.hpp:1727
GatewayAckPackage(JsonObject jsonObj)
Construct from JSON object.
Definition gateway.hpp:1752
uint16_t httpStatus
HTTP response code (if applicable)
Definition gateway.hpp:1684
uint32_t originNode
Original sender node ID.
Definition gateway.hpp:1667
TSTRING error
Error message (if failed)
Definition gateway.hpp:1692
Gateway Data Package for routing Internet requests through mesh.
Definition gateway.hpp:815
uint32_t timestamp
Creation timestamp.
Definition gateway.hpp:839
uint8_t priority
Message priority (0=CRITICAL, 1=HIGH, 2=NORMAL, 3=LOW)
Definition gateway.hpp:847
TSTRING destination
Destination URL or endpoint.
Definition gateway.hpp:857
TSTRING payload
Application payload data.
Definition gateway.hpp:865
GatewayDataPackage(JsonObject jsonObj)
Construct from JSON object.
Definition gateway.hpp:929
JsonObject addTo(JsonObject &&jsonObj) const
Serialize to JSON object.
Definition gateway.hpp:963
TSTRING contentType
MIME content type.
Definition gateway.hpp:875
uint32_t messageId
Unique message identifier.
Definition gateway.hpp:823
bool requiresAck
Whether acknowledgment is required.
Definition gateway.hpp:891
uint32_t requestNonce
Random value drawn once per sendToInternet() call.
Definition gateway.hpp:903
size_t jsonObjectSize() const
Calculate JSON object size for ArduinoJson v6.
Definition gateway.hpp:986
uint32_t originNode
Node ID that originated this message.
Definition gateway.hpp:831
uint8_t retryCount
Number of relay attempts.
Definition gateway.hpp:883
static constexpr int numPackageFields
Number of additional JSON fields in this package.
Definition gateway.hpp:912
GatewayDataPackage()
Default constructor.
Definition gateway.hpp:919
static uint32_t generateMessageId(uint32_t nodeId)
Generate a unique message ID.
Definition gateway.hpp:1011
Internet Health Checker class for periodic connectivity monitoring.
Definition gateway.hpp:498
void onConnectivityChanged(InternetChangedCallback_t callback)
Register callback for connectivity changes.
Definition gateway.hpp:547
void setCheckTimeout(uint32_t timeoutMs)
Set check timeout.
Definition gateway.hpp:539
void setCheckInterval(uint32_t intervalMs)
Set check interval.
Definition gateway.hpp:531
InternetStatus getStatus() const
Get detailed Internet status.
Definition gateway.hpp:563
bool checkNow()
Perform an immediate Internet connectivity check.
Definition gateway.hpp:576
uint32_t getCheckTimeout() const
Get check timeout.
Definition gateway.hpp:636
bool checkOnDemand()
Probe once outside the schedule, for a caller that needs the answer now (issue #450)
Definition gateway.hpp:616
uint16_t getCheckPort() const
Get check port.
Definition gateway.hpp:652
InternetHealthChecker()=default
bool hasLocalInternet() const
Check if local Internet is currently available.
Definition gateway.hpp:555
uint32_t getCheckInterval() const
Get check interval.
Definition gateway.hpp:628
TSTRING getCheckHost() const
Get check host.
Definition gateway.hpp:644
void setConfig(const SharedGatewayConfig &config)
Configure the health checker with gateway settings.
Definition gateway.hpp:506
void setCheckTarget(const TSTRING &host, uint16_t port=53)
Set custom check host and port.
Definition gateway.hpp:520
void resetStats()
Reset all statistics.
Definition gateway.hpp:659
A few hosts that recently failed to resolve, and when.
Definition gateway.hpp:1531
@ SLOTS
Definition gateway.hpp:1536
void forget(const TSTRING &host)
Definition gateway.hpp:1570
size_t size() const
Definition gateway.hpp:1575
bool isFailing(const TSTRING &host, uint32_t nowMs, uint32_t *ageMs=nullptr)
Definition gateway.hpp:1558
void remember(const TSTRING &host, uint32_t nowMs, uint32_t ttlMs=GATEWAY_DNS_NEGATIVE_TTL_MS)
Definition gateway.hpp:1538
The start and the end of a response body, read a byte at a time.
Definition gateway.hpp:1228
bool add(char c)
Definition gateway.hpp:1231
TSTRING text() const
Definition gateway.hpp:1252
void add(const TSTRING &text)
Definition gateway.hpp:1246
int noJsonFields
Definition plugin.hpp:49
SinglePackage(int type)
Definition plugin.hpp:51
static uint32_t generate()
Definition validation.hpp:54
#define NODE_TIMEOUT
Definition configuration.hpp:105
String TSTRING
Definition configuration.hpp:132
#define GATEWAY_HTTP_TIMEOUT_MS
Definition gateway.hpp:1847
#define GATEWAY_CAPTIVE_PORTAL_TIMEOUT_MS
Definition gateway.hpp:1853
#define GATEWAY_DNS_TIMEOUT_MS
Definition gateway.hpp:1865
uint32_t parseRetryAfterMs(const TSTRING &value)
The delay a Retry-After header asks for, in milliseconds.
Definition gateway.hpp:1388
HttpTransportError
HTTPClient transport errors, by what they say about the request.
Definition gateway.hpp:1043
@ HTTP_TRANSPORT_READ_TIMEOUT
sent, and no reply in time
Definition gateway.hpp:1054
@ HTTP_TRANSPORT_ENCODING
the reply arrived malformed; sent
Definition gateway.hpp:1052
@ HTTP_TRANSPORT_CONNECTION_REFUSED
no connection was made
Definition gateway.hpp:1044
@ HTTP_TRANSPORT_NOT_CONNECTED
closed before the reply began; sent
Definition gateway.hpp:1047
@ HTTP_TRANSPORT_NO_HTTP_SERVER
the reply was not HTTP; sent
Definition gateway.hpp:1050
@ HTTP_TRANSPORT_SEND_PAYLOAD_FAILED
the body never completed
Definition gateway.hpp:1046
@ HTTP_TRANSPORT_STREAM_WRITE
the reply could not be stored; sent
Definition gateway.hpp:1053
@ HTTP_TRANSPORT_TOO_LESS_RAM
out of memory sending or reading
Definition gateway.hpp:1051
@ HTTP_TRANSPORT_CONNECTION_LOST
dropped while reading the reply; sent
Definition gateway.hpp:1048
@ HTTP_TRANSPORT_NO_STREAM
no stream to send or read with
Definition gateway.hpp:1049
@ HTTP_TRANSPORT_SEND_HEADER_FAILED
the request line never completed
Definition gateway.hpp:1045
TSTRING summarizeResponseBody(const TSTRING &body, size_t maxLen=GATEWAY_RESPONSE_REASON_MAX)
Reduce a response body to one line fit for a log or an error string.
Definition gateway.hpp:1179
GatewayPriority
Priority levels for GatewayDataPackage messages.
Definition gateway.hpp:759
@ PRIORITY_HIGH
High priority - processed before normal.
@ PRIORITY_LOW
Low priority - processed when idle.
@ PRIORITY_CRITICAL
Critical messages - immediate processing.
@ PRIORITY_NORMAL
Normal priority - standard processing.
constexpr bool isValidMeshChannel(uint8_t channel)
Definition gateway.hpp:52
HttpRequestOutcome classifyHttpResult(int rawCode, const TSTRING &body=TSTRING())
Classify an HTTPClient result for the gateway acknowledgment.
Definition gateway.hpp:1451
bool reserveGatewayBlockingBudget(T &connection)
Definition gateway.hpp:1929
constexpr bool shouldFollowBridgeChannel(uint32_t localNodeId, uint32_t electedBridgeId, uint8_t currentChannel, uint8_t announcedChannel)
Definition gateway.hpp:57
bool looksLikeIpLiteral(const TSTRING &host)
Definition gateway.hpp:1515
constexpr unsigned long gatewayBlockingBudgetMs()
Wall-clock ceiling of the gateway's blocking calls on the GATEWAY_DATA path, in milliseconds (issue #...
Definition gateway.hpp:1900
TSTRING requestIdFor(uint32_t originNode, uint32_t messageId, uint32_t requestNonce=0)
The identifier the gateway sends with a request, as both X-Request-Id and Idempotency-Key.
Definition gateway.hpp:1417
bool transportErrorMayHaveReachedServer(int rawCode)
Can a request that failed with this transport error have reached the server?
Definition gateway.hpp:1064
bool transferEncodingIsChunked(const TSTRING &value)
Definition gateway.hpp:1371
uint8_t pickMeshChannel(const std::vector< MeshChannelCandidate > &candidates, uint8_t avoidChannel, uint8_t routerChannel=0)
Where a node that has lost the mesh should go.
Definition gateway.hpp:106
bool responseContains(const TSTRING &haystack, const char *needle)
Definition gateway.hpp:1162
std::function< void(bool available)> InternetChangedCallback_t
Callback type for Internet connectivity change events.
Definition gateway.hpp:475
TSTRING hostFromUrl(const TSTRING &url)
The host of an http(s) URL, without scheme, port, path or query.
Definition gateway.hpp:1497
uint32_t newRequestNonce()
Definition gateway.hpp:1432
size_t refreshPeerWatchdogs(T &mesh, unsigned long stalledMs)
Give every peer's running watchdog back the time a blocking call hid.
Definition gateway.hpp:1983
The outcome of a gateway HTTP request, classified for the ack.
Definition gateway.hpp:1093
bool unverifiedStatus
Definition gateway.hpp:1109
TSTRING reason
Definition gateway.hpp:1125
uint16_t ackStatus
Definition gateway.hpp:1098
bool retryable
Definition gateway.hpp:1119
bool success
Definition gateway.hpp:1095
bool transportError
Definition gateway.hpp:1101
Structure to hold Internet connectivity check results.
Definition gateway.hpp:431
uint32_t checkCount
Total number of checks performed.
Definition gateway.hpp:435
uint32_t failureCount
Number of failed checks.
Definition gateway.hpp:437
bool available
Whether Internet is currently available.
Definition gateway.hpp:432
uint32_t getTimeSinceLastSuccess() const
Get time since last successful Internet check.
Definition gateway.hpp:456
bool isStale(uint32_t maxAgeMs=60000) const
Check if Internet status is stale (no recent check)
Definition gateway.hpp:466
uint32_t lastCheckTime
Timestamp of last check (millis)
Definition gateway.hpp:433
uint8_t getUptimePercent() const
Get the uptime percentage of Internet connectivity.
Definition gateway.hpp:447
TSTRING lastError
Error message from last failed check.
Definition gateway.hpp:439
uint32_t lastLatencyMs
Latency of last successful check in ms.
Definition gateway.hpp:438
uint32_t lastSuccessTime
Timestamp of last successful check (millis)
Definition gateway.hpp:434
uint32_t successCount
Number of successful checks.
Definition gateway.hpp:436
uint16_t checkPort
Port used for connectivity check.
Definition gateway.hpp:441
TSTRING checkHost
Host used for connectivity check.
Definition gateway.hpp:440
One occurrence of the mesh SSID seen by an all-channel scan.
Definition gateway.hpp:69
MeshChannelCandidate()
Definition gateway.hpp:75
MeshChannelCandidate(uint8_t channel_, int32_t rssi_)
Definition gateway.hpp:76
uint8_t channel
Definition gateway.hpp:70
int32_t rssi
Definition gateway.hpp:71
Configuration structure for Shared Gateway Mode.
Definition gateway.hpp:162
uint32_t duplicateTrackingTimeout
Timeout for tracking duplicate messages in milliseconds.
Definition gateway.hpp:254
uint8_t messageRetryCount
Number of retry attempts for message delivery.
Definition gateway.hpp:237
uint32_t internetCheckInterval
Interval between Internet connectivity checks in milliseconds.
Definition gateway.hpp:201
uint16_t internetCheckPort
Port for Internet connectivity check.
Definition gateway.hpp:217
bool maintainPermanentConnection
Whether to maintain a permanent connection to the router.
Definition gateway.hpp:317
bool hasRouterCredentials() const
Check if the configuration has valid router credentials.
Definition gateway.hpp:421
uint32_t gatewayHeartbeatInterval
Interval for broadcasting gateway heartbeat in milliseconds.
Definition gateway.hpp:276
TSTRING routerSSID
Router SSID to connect for Internet access.
Definition gateway.hpp:180
TSTRING internetCheckHost
Host to ping for Internet connectivity verification.
Definition gateway.hpp:209
bool canParticipateInElection() const
Check if this node can participate in gateway elections.
Definition gateway.hpp:412
bool enabled
Enable or disable shared gateway functionality.
Definition gateway.hpp:172
bool participateInElection
Whether this node should participate in gateway elections.
Definition gateway.hpp:295
uint16_t maxTrackedMessages
Maximum number of messages to track for deduplication.
Definition gateway.hpp:263
uint8_t relayedMessagePriority
Priority for relayed messages (0 = highest/CRITICAL)
Definition gateway.hpp:308
ValidationResult validate() const
Validate the configuration.
Definition gateway.hpp:331
uint32_t retryInterval
Interval between retry attempts in milliseconds.
Definition gateway.hpp:246
uint32_t gatewayFailureTimeout
Timeout for detecting gateway failure in milliseconds.
Definition gateway.hpp:286
TSTRING routerPassword
Router password for authentication.
Definition gateway.hpp:188
uint32_t internetCheckTimeout
Timeout for Internet connectivity check in milliseconds.
Definition gateway.hpp:225
Validation result structure for SharedGatewayConfig.
Definition gateway.hpp:126
ValidationResult()=default
bool valid
Definition gateway.hpp:127
ValidationResult(bool v, const TSTRING &msg)
Definition gateway.hpp:131
TSTRING errorMessage
Definition gateway.hpp:128