diff --git a/protobufs b/protobufs index 384b664a7..2b391ff8a 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 384b664a759592d9393642ba98835f69bb8f2fb2 +Subproject commit 2b391ff8a76bfc07662faa007bb4fd6e01691ba8 diff --git a/src/DebugConfiguration.cpp b/src/DebugConfiguration.cpp new file mode 100644 index 000000000..9df402e77 --- /dev/null +++ b/src/DebugConfiguration.cpp @@ -0,0 +1,172 @@ +/* based on https://github.com/arcao/Syslog + +MIT License + +Copyright (c) 2016 Martin Sloup + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.*/ + +#include "configuration.h" + +#include "DebugConfiguration.h" + +#if HAS_WIFI || HAS_ETHERNET + +Syslog::Syslog(UDP &client) +{ + this->_client = &client; + this->_server = NULL; + this->_port = 0; + this->_deviceHostname = SYSLOG_NILVALUE; + this->_appName = SYSLOG_NILVALUE; + this->_priDefault = LOGLEVEL_KERN; +} + +Syslog &Syslog::server(const char *server, uint16_t port) +{ + if (this->_ip.fromString(server)) { + this->_server = NULL; + } else { + this->_server = server; + } + this->_port = port; + return *this; +} + +Syslog &Syslog::server(IPAddress ip, uint16_t port) +{ + this->_ip = ip; + this->_server = NULL; + this->_port = port; + return *this; +} + +Syslog &Syslog::deviceHostname(const char *deviceHostname) +{ + this->_deviceHostname = (deviceHostname == NULL) ? SYSLOG_NILVALUE : deviceHostname; + return *this; +} + +Syslog &Syslog::appName(const char *appName) +{ + this->_appName = (appName == NULL) ? SYSLOG_NILVALUE : appName; + return *this; +} + +Syslog &Syslog::defaultPriority(uint16_t pri) +{ + this->_priDefault = pri; + return *this; +} + +Syslog &Syslog::logMask(uint8_t priMask) +{ + this->_priMask = priMask; + return *this; +} + +void Syslog::enable() +{ + this->_enabled = true; +} + +void Syslog::disable() +{ + this->_enabled = false; +} + +bool Syslog::isEnabled() +{ + return this->_enabled; +} + +bool Syslog::vlogf(uint16_t pri, const char *fmt, va_list args) +{ + return this->vlogf(pri, this->_appName, fmt, args); +} + +bool Syslog::vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) +{ + char *message; + size_t initialLen; + size_t len; + bool result; + + initialLen = strlen(fmt); + + message = new char[initialLen + 1]; + + len = vsnprintf(message, initialLen + 1, fmt, args); + if (len > initialLen) { + delete[] message; + message = new char[len + 1]; + + vsnprintf(message, len + 1, fmt, args); + } + + result = this->_sendLog(pri, appName, message); + + delete[] message; + return result; +} + +inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *message) +{ + int result; + + if (!this->_enabled) + return false; + + if ((this->_server == NULL && this->_ip == INADDR_NONE) || this->_port == 0) + return false; + + // Check priority against priMask values. + if ((LOG_MASK(LOG_PRI(pri)) & this->_priMask) == 0) + return true; + + // Set default facility if none specified. + if ((pri & LOG_FACMASK) == 0) + pri = LOG_MAKEPRI(LOG_FAC(this->_priDefault), pri); + + if (this->_server != NULL) { + result = this->_client->beginPacket(this->_server, this->_port); + } else { + result = this->_client->beginPacket(this->_ip, this->_port); + } + + if (result != 1) + return false; + + this->_client->print('<'); + this->_client->print(pri); + this->_client->print(F(">1 - ")); + this->_client->print(this->_deviceHostname); + this->_client->print(' '); + this->_client->print(appName); + this->_client->print(F(" - - - \xEF\xBB\xBF")); + this->_client->print(F("[")); + this->_client->print(int(millis() / 1000)); + this->_client->print(F("]: ")); + this->_client->print(message); + this->_client->endPacket(); + + return true; +} + +#endif diff --git a/src/DebugConfiguration.h b/src/DebugConfiguration.h index 389a35d81..36b009ff2 100644 --- a/src/DebugConfiguration.h +++ b/src/DebugConfiguration.h @@ -1,3 +1,6 @@ +#ifndef SYSLOG_H +#define SYSLOG_H + // DEBUG LED #ifndef LED_INVERTED #define LED_INVERTED 0 // define as 1 if LED is active low (on) @@ -17,6 +20,7 @@ #define MESHTASTIC_LOG_LEVEL_INFO "INFO " #define MESHTASTIC_LOG_LEVEL_WARN "WARN " #define MESHTASTIC_LOG_LEVEL_ERROR "ERROR" +#define MESHTASTIC_LOG_LEVEL_CRIT "CRIT " #define MESHTASTIC_LOG_LEVEL_TRACE "TRACE" #include "SerialConsole.h" @@ -28,21 +32,72 @@ #define LOG_INFO(...) SEGGER_RTT_printf(0, __VA_ARGS__) #define LOG_WARN(...) SEGGER_RTT_printf(0, __VA_ARGS__) #define LOG_ERROR(...) SEGGER_RTT_printf(0, __VA_ARGS__) +#define LOG_CRIT(...) SEGGER_RTT_printf(0, __VA_ARGS__) +#define LOG_TRACE(...) SEGGER_RTT_printf(0, __VA_ARGS__) #else #ifdef DEBUG_PORT #define LOG_DEBUG(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_DEBUG, __VA_ARGS__) #define LOG_INFO(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_INFO, __VA_ARGS__) #define LOG_WARN(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_WARN, __VA_ARGS__) #define LOG_ERROR(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_ERROR, __VA_ARGS__) -#define LOG_TRACE(...) DEBUG_PORT.log(MESHTASTIC_LOG_TRACE, __VA_ARGS__) +#define LOG_CRIT(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_CRIT, __VA_ARGS__) +#define LOG_TRACE(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_TRACE, __VA_ARGS__) #else #define LOG_DEBUG(...) #define LOG_INFO(...) #define LOG_WARN(...) #define LOG_ERROR(...) +#define LOG_CRIT(...) +#define LOG_TRACE(...) #endif #endif +#define SYSLOG_NILVALUE "-" + +#define SYSLOG_CRIT 2 /* critical conditions */ +#define SYSLOG_ERR 3 /* error conditions */ +#define SYSLOG_WARN 4 /* warning conditions */ +#define SYSLOG_INFO 6 /* informational */ +#define SYSLOG_DEBUG 7 /* debug-level messages */ +// trace does not go out to syslog (yet?) + +#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */ + /* extract priority */ +#define LOG_PRI(p) ((p)&LOG_PRIMASK) +#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri)) + +/* facility codes */ +#define LOGLEVEL_KERN (0 << 3) /* kernel messages */ +#define LOGLEVEL_USER (1 << 3) /* random user-level messages */ +#define LOGLEVEL_MAIL (2 << 3) /* mail system */ +#define LOGLEVEL_DAEMON (3 << 3) /* system daemons */ +#define LOGLEVEL_AUTH (4 << 3) /* security/authorization messages */ +#define LOGLEVEL_SYSLOG (5 << 3) /* messages generated internally by syslogd */ +#define LOGLEVEL_LPR (6 << 3) /* line printer subsystem */ +#define LOGLEVEL_NEWS (7 << 3) /* network news subsystem */ +#define LOGLEVEL_UUCP (8 << 3) /* UUCP subsystem */ +#define LOGLEVEL_CRON (9 << 3) /* clock daemon */ +#define LOGLEVEL_AUTHPRIV (10 << 3) /* security/authorization messages (private) */ +#define LOGLEVEL_FTP (11 << 3) /* ftp daemon */ + +/* other codes through 15 reserved for system use */ +#define LOGLEVEL_LOCAL0 (16 << 3) /* reserved for local use */ +#define LOGLEVEL_LOCAL1 (17 << 3) /* reserved for local use */ +#define LOGLEVEL_LOCAL2 (18 << 3) /* reserved for local use */ +#define LOGLEVEL_LOCAL3 (19 << 3) /* reserved for local use */ +#define LOGLEVEL_LOCAL4 (20 << 3) /* reserved for local use */ +#define LOGLEVEL_LOCAL5 (21 << 3) /* reserved for local use */ +#define LOGLEVEL_LOCAL6 (22 << 3) /* reserved for local use */ +#define LOGLEVEL_LOCAL7 (23 << 3) /* reserved for local use */ + +#define LOG_NFACILITIES 24 /* current number of facilities */ +#define LOG_FACMASK 0x03f8 /* mask to extract facility part */ + /* facility of pri */ +#define LOG_FAC(p) (((p)&LOG_FACMASK) >> 3) + +#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ +#define LOG_UPTO(pri) ((1 << ((pri) + 1)) - 1) /* all priorities through pri */ + // ----------------------------------------------------------------------------- // AXP192 (Rev1-specific options) // ----------------------------------------------------------------------------- @@ -52,3 +107,50 @@ // Default Bluetooth PIN #define defaultBLEPin 123456 + +#if HAS_ETHERNET +#include +#endif // HAS_ETHERNET + +#if HAS_WIFI +#include +#endif // HAS_WIFI + +#if HAS_WIFI || HAS_ETHERNET + +class Syslog +{ + private: + UDP *_client; + IPAddress _ip; + const char *_server; + uint16_t _port; + const char *_deviceHostname; + const char *_appName; + uint16_t _priDefault; + uint8_t _priMask = 0xff; + bool _enabled = false; + + bool _sendLog(uint16_t pri, const char *appName, const char *message); + + public: + explicit Syslog(UDP &client); + + Syslog &server(const char *server, uint16_t port); + Syslog &server(IPAddress ip, uint16_t port); + Syslog &deviceHostname(const char *deviceHostname); + Syslog &appName(const char *appName); + Syslog &defaultPriority(uint16_t pri = LOGLEVEL_KERN); + Syslog &logMask(uint8_t priMask); + + void enable(); + void disable(); + bool isEnabled(); + + bool vlogf(uint16_t pri, const char *fmt, va_list args) __attribute__((format(printf, 3, 0))); + bool vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) __attribute__((format(printf, 3, 0))); +}; + +#endif // HAS_ETHERNET || HAS_WIFI + +#endif // SYSLOG_H \ No newline at end of file diff --git a/src/Power.cpp b/src/Power.cpp index 082c05181..f84c7b71d 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -7,6 +7,12 @@ #include "sleep.h" #include "utils.h" +#ifdef DEBUG_HEAP_MQTT +#include "mqtt/MQTT.h" +#include "target_specific.h" +#include +#endif + #ifdef HAS_PMU #include "XPowersAXP192.tpp" #include "XPowersAXP2101.tpp" @@ -311,6 +317,25 @@ void Power::readPowerStatus() ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false)); lastheap = ESP.getFreeHeap(); } +#ifdef DEBUG_HEAP_MQTT + if (mqtt) { + // send MQTT-Packet with Heap-Size + uint8_t dmac[6]; + getMacAddr(dmac); // Get our hardware ID + char mac[18]; + sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]); + auto newHeap = ESP.getFreeHeap(); + std::string heapTopic = "msh/2/heap/" + std::string(mac); + std::string heapString = std::to_string(newHeap); + mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false); + // auto fragHeap = ESP.getHeapFragmentation(); + auto wifiRSSI = WiFi.RSSI(); + heapTopic = "msh/2/wifi/" + std::string(mac); + std::string wifiString = std::to_string(wifiRSSI); + mqtt->pubSub.publish(heapTopic.c_str(), wifiString.c_str(), false); + } +#endif + #endif // If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index f316785f0..04dbcdd49 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -5,6 +5,8 @@ #include "configuration.h" #include #include +#include +#include #include #include @@ -13,6 +15,10 @@ */ NoopPrint noopPrint; +#if HAS_WIFI || HAS_ETHERNET +extern Syslog syslog; +#endif + void RedirectablePrint::setDestination(Print *_dest) { assert(_dest); @@ -96,6 +102,39 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) } } r += vprintf(format, arg); + +#if HAS_WIFI || HAS_ETHERNET + // if syslog is in use, collect the log messages and send them to syslog + if (syslog.isEnabled()) { + int ll = 0; + switch (logLevel[0]) { + case 'D': + ll = SYSLOG_DEBUG; + break; + case 'I': + ll = SYSLOG_INFO; + break; + case 'W': + ll = SYSLOG_WARN; + break; + case 'E': + ll = SYSLOG_ERR; + break; + case 'C': + ll = SYSLOG_CRIT; + break; + default: + ll = 0; + } + auto thread = concurrency::OSThread::currentThread; + if (thread) { + syslog.vlogf(ll, thread->ThreadName.c_str(), format, arg); + } else { + syslog.vlogf(ll, format, arg); + } + } +#endif + va_end(arg); isContinuationMessage = !hasNewline; @@ -136,3 +175,22 @@ void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16 } log(logLevel, " +------------------------------------------------+ +----------------+\n"); } + +std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...) +{ + int n = ((int)fmt_str.size()) * 2; /* Reserve two times as much as the length of the fmt_str */ + std::unique_ptr formatted; + va_list ap; + while (1) { + formatted.reset(new char[n]); /* Wrap the plain char array into the unique_ptr */ + strcpy(&formatted[0], fmt_str.c_str()); + va_start(ap, fmt_str); + int final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap); + va_end(ap); + if (final_n < 0 || final_n >= n) + n += abs(final_n - n + 1); + else + break; + } + return std::string(formatted.get()); +} \ No newline at end of file diff --git a/src/RedirectablePrint.h b/src/RedirectablePrint.h index 659b6e10d..560021972 100644 --- a/src/RedirectablePrint.h +++ b/src/RedirectablePrint.h @@ -2,6 +2,7 @@ #include #include +#include /** * A Printable that can be switched to squirt its bytes to a different sink. @@ -40,6 +41,8 @@ class RedirectablePrint : public Print size_t vprintf(const char *format, va_list arg); void hexDump(const char *logLevel, unsigned char *buf, uint16_t len); + + std::string mt_sprintf(const std::string fmt_str, ...); }; class NoopPrint : public Print diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 61c864394..94dab0bcd 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -241,47 +241,48 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) void printPacket(const char *prefix, const meshtastic_MeshPacket *p) { - LOG_DEBUG("%s (id=0x%08x fr=0x%02x to=0x%02x, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id, p->from & 0xff, p->to & 0xff, - p->want_ack, p->hop_limit, p->channel); + std::string out = DEBUG_PORT.mt_sprintf("%s (id=0x%08x fr=0x%02x to=0x%02x, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id, + p->from & 0xff, p->to & 0xff, p->want_ack, p->hop_limit, p->channel); if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { auto &s = p->decoded; - LOG_DEBUG(" Portnum=%d", s.portnum); + out += DEBUG_PORT.mt_sprintf(" Portnum=%d", s.portnum); if (s.want_response) - LOG_DEBUG(" WANTRESP"); + out += DEBUG_PORT.mt_sprintf(" WANTRESP"); if (s.source != 0) - LOG_DEBUG(" source=%08x", s.source); + out += DEBUG_PORT.mt_sprintf(" source=%08x", s.source); if (s.dest != 0) - LOG_DEBUG(" dest=%08x", s.dest); + out += DEBUG_PORT.mt_sprintf(" dest=%08x", s.dest); if (s.request_id) - LOG_DEBUG(" requestId=%0x", s.request_id); + out += DEBUG_PORT.mt_sprintf(" requestId=%0x", s.request_id); /* now inside Data and therefore kinda opaque if (s.which_ackVariant == SubPacket_success_id_tag) - LOG_DEBUG(" successId=%08x", s.ackVariant.success_id); + out += DEBUG_PORT.mt_sprintf(" successId=%08x", s.ackVariant.success_id); else if (s.which_ackVariant == SubPacket_fail_id_tag) - LOG_DEBUG(" failId=%08x", s.ackVariant.fail_id); */ + out += DEBUG_PORT.mt_sprintf(" failId=%08x", s.ackVariant.fail_id); */ } else { - LOG_DEBUG(" encrypted"); + out += " encrypted"; } if (p->rx_time != 0) { - LOG_DEBUG(" rxtime=%u", p->rx_time); + out += DEBUG_PORT.mt_sprintf(" rxtime=%u", p->rx_time); } if (p->rx_snr != 0.0) { - LOG_DEBUG(" rxSNR=%g", p->rx_snr); + out += DEBUG_PORT.mt_sprintf(" rxSNR=%g", p->rx_snr); } if (p->rx_rssi != 0) { - LOG_DEBUG(" rxRSSI=%i", p->rx_rssi); + out += DEBUG_PORT.mt_sprintf(" rxRSSI=%i", p->rx_rssi); } if (p->priority != 0) - LOG_DEBUG(" priority=%d", p->priority); + out += DEBUG_PORT.mt_sprintf(" priority=%d", p->priority); - LOG_DEBUG(")\n"); + out + ")\n"; + LOG_DEBUG("%s", out.c_str()); } RadioInterface::RadioInterface() diff --git a/src/mesh/eth/ethClient.cpp b/src/mesh/eth/ethClient.cpp index 80208825c..659de05f8 100644 --- a/src/mesh/eth/ethClient.cpp +++ b/src/mesh/eth/ethClient.cpp @@ -2,6 +2,7 @@ #include "NodeDB.h" #include "RTC.h" #include "concurrency/Periodic.h" +#include "main.h" #include "mesh/api/ethServerAPI.h" #include "mqtt/MQTT.h" #include "target_specific.h" @@ -17,6 +18,9 @@ NTPClient timeClient(ntpUDP, config.network.ntp_server); uint32_t ntp_renew = 0; #endif +EthernetUDP syslogClient; +Syslog syslog(syslogClient); + bool ethStartupComplete = 0; using namespace concurrency; @@ -36,6 +40,27 @@ static int32_t reconnectETH() timeClient.begin(); timeClient.setUpdateInterval(60 * 60); // Update once an hour #endif + + if (config.network.rsyslog_server[0]) { + LOG_INFO("Starting Syslog client\n"); + // Defaults + int serverPort = 514; + const char *serverAddr = config.network.rsyslog_server; + String server = String(serverAddr); + int delimIndex = server.indexOf(':'); + if (delimIndex > 0) { + String port = server.substring(delimIndex + 1, server.length()); + server[delimIndex] = 0; + serverPort = port.toInt(); + serverAddr = server.c_str(); + } + syslog.server(serverAddr, serverPort); + syslog.deviceHostname(getDeviceName()); + syslog.appName("Meshtastic"); + syslog.defaultPriority(LOGLEVEL_USER); + syslog.enable(); + } + // initWebServer(); initApiServer(); @@ -143,10 +168,13 @@ bool isEthernetAvailable() { if (!config.network.eth_enabled) { + syslog.disable(); return false; } else if (Ethernet.hardwareStatus() == EthernetNoHardware) { + syslog.disable(); return false; } else if (Ethernet.linkStatus() == LinkOFF) { + syslog.disable(); return false; } else { return true; diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index 4c062a148..cc8d4b168 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -39,6 +39,9 @@ unsigned long lastrun_ntp = 0; bool needReconnect = true; // If we create our reconnector, run it once at the beginning +WiFiUDP syslogClient; +Syslog syslog(syslogClient); + Periodic *wifiReconnect; static int32_t reconnectWiFi() @@ -135,6 +138,26 @@ static void onNetworkConnected() timeClient.setUpdateInterval(60 * 60); // Update once an hour #endif + if (config.network.rsyslog_server[0]) { + LOG_INFO("Starting Syslog client\n"); + // Defaults + int serverPort = 514; + const char *serverAddr = config.network.rsyslog_server; + String server = String(serverAddr); + int delimIndex = server.indexOf(':'); + if (delimIndex > 0) { + String port = server.substring(delimIndex + 1, server.length()); + server[delimIndex] = 0; + serverPort = port.toInt(); + serverAddr = server.c_str(); + } + syslog.server(serverAddr, serverPort); + syslog.deviceHostname(getDeviceName()); + syslog.appName("Meshtastic"); + syslog.defaultPriority(LOGLEVEL_USER); + syslog.enable(); + } + initWebServer(); initApiServer(); @@ -223,6 +246,7 @@ static void WiFiEvent(WiFiEvent_t event) break; case ARDUINO_EVENT_WIFI_STA_STOP: LOG_INFO("WiFi station stopped\n"); + syslog.disable(); break; case ARDUINO_EVENT_WIFI_STA_CONNECTED: LOG_INFO("Connected to access point\n"); @@ -230,6 +254,7 @@ static void WiFiEvent(WiFiEvent_t event) case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: LOG_INFO("Disconnected from WiFi access point\n"); WiFi.disconnect(false, true); + syslog.disable(); needReconnect = true; wifiReconnect->setIntervalFromNow(1000); break; @@ -246,6 +271,7 @@ static void WiFiEvent(WiFiEvent_t event) case ARDUINO_EVENT_WIFI_STA_LOST_IP: LOG_INFO("Lost IP address and IP address is reset to 0\n"); WiFi.disconnect(false, true); + syslog.disable(); needReconnect = true; wifiReconnect->setIntervalFromNow(1000); break; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index b03ae3579..56bdf300f 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -15,6 +15,8 @@ #include "mqtt/JSON.h" #include +const int reconnectMax = 5; + MQTT *mqtt; std::string statusTopic = "msh/2/stat/"; @@ -218,15 +220,13 @@ void MQTT::reconnect() sendSubscriptions(); } else { #if HAS_WIFI && !defined(ARCH_PORTDUINO) - LOG_ERROR("Failed to contact MQTT server (%d/5)...\n", reconnectCount + 1); - if (reconnectCount >= 4) { + reconnectCount++; + LOG_ERROR("Failed to contact MQTT server (%d/%d)...\n", reconnectCount, reconnectMax); + if (reconnectCount >= reconnectMax) { needReconnect = true; wifiReconnect->setIntervalFromNow(0); reconnectCount = 0; - } else { - reconnectCount++; } - #endif } } diff --git a/suppressions.txt b/suppressions.txt index 3db2d5b7d..0dd5198ec 100644 --- a/suppressions.txt +++ b/suppressions.txt @@ -43,3 +43,4 @@ postfixOperator:*/mqtt/* missingOverride virtualCallInConstructor +passedByValue:*/RedirectablePrint.h