diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml index 15c5e85..64623e5 100644 --- a/.github/workflows/cppcheck.yml +++ b/.github/workflows/cppcheck.yml @@ -19,4 +19,4 @@ jobs: pip install platformio - name: Cppcheck run: | - pio check --fail-on-defect=low --flags "--enable=warning --enable=style --enable=performance --suppress=unusedFunction --suppress=preprocessorErrorDirective" --skip-packages \ No newline at end of file + pio check --fail-on-defect=low --flags "--enable=warning --enable=style --enable=performance --suppress=unusedFunction --suppress=preprocessorErrorDirective --inline-suppr" --skip-packages \ No newline at end of file diff --git a/examples/simple-esp32/simple-esp32.ino b/examples/simple-esp32/simple-esp32.ino index 4dc6516..b6ddb64 100644 --- a/examples/simple-esp32/simple-esp32.ino +++ b/examples/simple-esp32/simple-esp32.ino @@ -13,10 +13,10 @@ void loop() { static uint32_t lastMillis = 0; if (millis() - lastMillis > 10000) { lastMillis = millis(); - uint8_t signalQuality = espMqttManagerHelpers::signalQuality(); - char sqStr[4]; - snprintf(sqStr, sizeof(sqStr), "%d", signalQuality); - espMqttManager::mqttClient.publish("test/topic", 0, false, sqStr); + int8_t signalQuality = WiFi.RSSI(); + char buf[5]; + snprintf(buf, sizeof(buf), "%d", signalQuality); + espMqttManager::mqttClient.publish("test/topic", 0, false, buf); } espMqttManager::loop(); } diff --git a/examples/simple-esp8266/simple-esp8266.ino b/examples/simple-esp8266/simple-esp8266.ino index 85480d1..24840f4 100644 --- a/examples/simple-esp8266/simple-esp8266.ino +++ b/examples/simple-esp8266/simple-esp8266.ino @@ -13,10 +13,10 @@ void loop() { static uint32_t lastMillis = 0; if (millis() - lastMillis > 10000) { lastMillis = millis(); - uint8_t signalQuality = espMqttManagerHelpers::signalQuality(); - char sqStr[4]; - snprintf(sqStr, sizeof(sqStr), "%d", signalQuality); - espMqttManager::mqttClient.publish("test/topic", 0, false, sqStr); + int8_t signalQuality = WiFi.RSSI(); + char buf[5]; + snprintf(buf, sizeof(buf), "%d", signalQuality); + espMqttManager::mqttClient.publish("test/topic", 0, false, buf); } espMqttManager::loop(); } diff --git a/examples/tls-esp32/tls-esp32.ino b/examples/tls-esp32/tls-esp32.ino index 83ae7bf..4c3d99a 100644 --- a/examples/tls-esp32/tls-esp32.ino +++ b/examples/tls-esp32/tls-esp32.ino @@ -21,10 +21,10 @@ void loop() { static uint32_t lastMillis = 0; if (millis() - lastMillis > 10000) { lastMillis = millis(); - uint8_t signalQuality = espMqttManagerHelpers::signalQuality(); - char sqStr[4]; - snprintf(sqStr, sizeof(sqStr), "%d", signalQuality); - espMqttManager::mqttClient.publish("test/topic", 0, false, sqStr); + int8_t signalQuality = WiFi.RSSI(); + char buf[5]; + snprintf(buf, sizeof(buf), "%d", signalQuality); + espMqttManager::mqttClient.publish("test/topic", 0, false, buf); } espMqttManager::loop(); } diff --git a/src/Helpers/Config.cpp b/src/Helpers/Config.cpp index 967e38b..629c22e 100644 --- a/src/Helpers/Config.cpp +++ b/src/Helpers/Config.cpp @@ -39,10 +39,10 @@ bool Config::getConfig() { doc["PSK"] | "", sizeof(PSK)); JsonArray hostIPArray = doc["IPAddress"]; - uint8_t IPAddress_0 = hostIPArray[0] | 0; - uint8_t IPAddress_1 = hostIPArray[1] | 0; - uint8_t IPAddress_2 = hostIPArray[2] | 0; - uint8_t IPAddress_3 = hostIPArray[3] | 0; + uint8_t IPAddress_0 = hostIPArray[0] | 0; // cppcheck-suppress badBitmaskCheck + uint8_t IPAddress_1 = hostIPArray[1] | 0; // cppcheck-suppress badBitmaskCheck + uint8_t IPAddress_2 = hostIPArray[2] | 0; // cppcheck-suppress badBitmaskCheck + uint8_t IPAddress_3 = hostIPArray[3] | 0; // cppcheck-suppress badBitmaskCheck hostIP = IPAddress(IPAddress_0, IPAddress_1, IPAddress_2, IPAddress_3); strlcpy(hostname, doc["hostname"] | "", diff --git a/src/Helpers/Helpers.cpp b/src/Helpers/Helpers.cpp index 491225e..df69de2 100644 --- a/src/Helpers/Helpers.cpp +++ b/src/Helpers/Helpers.cpp @@ -10,19 +10,6 @@ the LICENSE file. namespace espMqttManagerHelpers { -uint8_t signalQuality() { - uint8_t signal = 0; - int32_t rssi = WiFi.RSSI(); - if (rssi <= -100) { - signal = 0; - } else if (rssi >= -50) { - signal = 100; - } else { - signal = 2 * (rssi + 100); - } - return signal; -} - bool updated = false; void handleUpdate(const uint8_t* payload, size_t length, size_t index, size_t total) { @@ -44,6 +31,7 @@ void handleUpdate(const uint8_t* payload, size_t length, size_t index, size_t to if (!Update.isRunning()) return; written += Update.write(data, length); } + espMqttManagerHelpers::updated = false; if (Update.isFinished()) { if (Update.end()) { espMqttManagerHelpers::updated = true; diff --git a/src/Helpers/Helpers.h b/src/Helpers/Helpers.h index a32693a..de44626 100644 --- a/src/Helpers/Helpers.h +++ b/src/Helpers/Helpers.h @@ -13,10 +13,8 @@ the LICENSE file. #include // millis() #if defined(ARDUINO_ARCH_ESP8266) -#include // WiFi.RSSI() #include #elif defined(ARDUINO_ARCH_ESP32) -#include #include #else #error Platform not supported @@ -24,7 +22,6 @@ the LICENSE file. namespace espMqttManagerHelpers { -uint8_t signalQuality(); void handleUpdate(const uint8_t* payload, size_t length, size_t index, size_t total); extern bool updated; diff --git a/src/espMqttManager.cpp b/src/espMqttManager.cpp index 276d636..2bcc2ee 100644 --- a/src/espMqttManager.cpp +++ b/src/espMqttManager.cpp @@ -29,12 +29,12 @@ void onMqttConnected() { } void onMqttDisconnected(espMqttClientTypes::DisconnectReason reason) { - (void) reason; + (void)reason; (void)0; } -void onReset() { - ESP.restart(); +void onDisconnected() { + (void)0; } #if ESP_MQTT_MANAGER_SECURE @@ -43,41 +43,43 @@ espMqttClientSecure espMqttManager::mqttClient; espMqttClient espMqttManager::mqttClient; #endif -void idle(); -void startWiFi(); -void waitForWiFi(); -void reconnectWaitMqtt(); -void waitForMqtt(); -void setupSession(); -void connected(); -void waitForDisconnect(); -void waitForDisconnectCleanSession(); -void reconnectWaitCleanSession(); -void waitForMqttCleanSession(); -void connectedCleanSession(); -void waitForDisconnectFinal(); - void onMqttClientConnected(bool sessionPresent); void onMqttClientDisconnected(espMqttClientTypes::DisconnectReason reason); namespace espMqttManagerInternals { -typedef void (*stateFunction)(); -stateFunction state = idle; +void idle(); +void connectWiFi(); +void waitWiFi(); +void connectMqtt(); +void setupSession(); +void waitDisconnect(); + +enum class espMqttManagerState { + OFFLINE, + CONNECTWIFI, + WAITWIFI, + CONNECTMQTT, + WAITMQTT, + SETUPSESSION, + CONNECTED, + WAITDISCONNECT, + DISCONNECTED +}; +espMqttManagerState state; uint32_t mqttReconnectTimer = 0; uint32_t wifiReconnectTimer = 0; uint32_t interval = 0; -bool disconnectCalled = false; espMqttManagerHelpers::Config config; +void setState(espMqttManagerState newState) { + emm_log_i("new espMqttManagerInternals::state: %u", newState); + state = newState; +} + } // end namespace espMqttManagerInternals -using espMqttManagerInternals::state; -using espMqttManagerInternals::mqttReconnectTimer; -using espMqttManagerInternals::wifiReconnectTimer; -using espMqttManagerInternals::interval; -using espMqttManagerInternals::disconnectCalled; -using espMqttManagerInternals::config; +using espMqttManagerInternals::espMqttManagerState; uint32_t getBackoffTimerVal(uint32_t currentInterval) { if (currentInterval == 0) currentInterval = 2000; @@ -90,212 +92,176 @@ uint32_t getBackoffTimerVal(uint32_t currentInterval) { void espMqttManager::setup() { WiFi.setAutoReconnect(false); - WiFi.setAutoConnect(false); + // WiFi.setAutoConnect(false); // deprecated WiFi.persistent(false); - if (!config.getConfig()) { + if (!espMqttManagerInternals::config.getConfig()) { emm_log_e("Error getting config"); return; } - mqttClient.setCleanSession(false); + mqttClient.setCleanSession(true); mqttClient.setKeepAlive(65); mqttClient.onConnect(onMqttClientConnected); mqttClient.onDisconnect(onMqttClientDisconnected); - if (strlen(config.hostname) > 0) { - mqttClient.setServer(config.hostname, config.port); + if (strlen(espMqttManagerInternals::config.hostname) > 0) { + mqttClient.setServer(espMqttManagerInternals::config.hostname, espMqttManagerInternals::config.port); } else { - mqttClient.setServer(config.hostIP, config.port); + mqttClient.setServer(espMqttManagerInternals::config.hostIP, espMqttManagerInternals::config.port); } - if (strlen(config.devicename) > 0) { - mqttClient.setClientId(config.devicename); + if (strlen(espMqttManagerInternals::config.devicename) > 0) { + mqttClient.setClientId(espMqttManagerInternals::config.devicename); } - if (strlen(config.username) > 0) { - mqttClient.setCredentials(config.username, config.password); + if (strlen(espMqttManagerInternals::config.username) > 0) { + mqttClient.setCredentials(espMqttManagerInternals::config.username, espMqttManagerInternals::config.password); } } void espMqttManager::start() { - state = startWiFi; - wifiReconnectTimer = millis(); - interval = 0; + espMqttManagerInternals::setState(espMqttManagerState::CONNECTWIFI); + espMqttManagerInternals::wifiReconnectTimer = millis(); + espMqttManagerInternals::interval = 0; } void espMqttManager::loop() { // espMqttManager doesn't use WiFi events so we have to monitor WiFi here - if (WiFi.status() != WL_CONNECTED && state != startWiFi && state != waitForWiFi) { - state = startWiFi; - wifiReconnectTimer = millis(); - interval = 0; + if (WiFi.status() != WL_CONNECTED && espMqttManagerInternals::state != espMqttManagerState::CONNECTWIFI && espMqttManagerInternals::state != espMqttManagerState::WAITWIFI) { + emm_log_i("WiFi disconnected"); + espMqttManagerInternals::setState(espMqttManagerState::CONNECTWIFI); + espMqttManagerInternals::wifiReconnectTimer = millis(); + espMqttManagerInternals::interval = 0; + WiFi.disconnect(false); onWiFiDisconnected(); } + switch (espMqttManagerInternals::state) { + case espMqttManagerState::OFFLINE: + espMqttManagerInternals::idle(); + break; + case espMqttManagerState::CONNECTWIFI: + espMqttManagerInternals::connectWiFi(); + break; + case espMqttManagerState::WAITWIFI: + espMqttManagerInternals::waitWiFi(); + break; + case espMqttManagerState::CONNECTMQTT: + espMqttManagerInternals::connectMqtt(); + break; + case espMqttManagerState::WAITMQTT: + espMqttManagerInternals::idle(); + break; + case espMqttManagerState::SETUPSESSION: + espMqttManagerInternals::setupSession(); + break; + case espMqttManagerState::CONNECTED: + espMqttManagerInternals::idle(); + break; + case espMqttManagerState::WAITDISCONNECT: + espMqttManagerInternals::waitDisconnect(); + break; + case espMqttManagerState::DISCONNECTED: + espMqttManagerInternals::idle(); + break; + } #if defined(ARDUINO_ARCH_ESP8266) espMqttManager::mqttClient.loop(); #endif - state(); } void espMqttManager::sessionReady() { - if (state == setupSession) { + if (espMqttManagerInternals::state == espMqttManagerState::SETUPSESSION) { emm_log_i("Session ready"); - state = connected; + espMqttManager::mqttClient.setCleanSession(false); + espMqttManagerInternals::setState(espMqttManagerState::CONNECTED); onMqttConnected(); } } -bool espMqttManager::disconnect(bool clearSession) { - if (state != connected) { +bool espMqttManager::disconnect() { + if (espMqttManagerInternals::state != espMqttManagerState::CONNECTED) { return false; } - // set state first to be in proper state when handling onMqttClientDisconnected - if (clearSession) { - state = waitForDisconnectCleanSession; - mqttClient.setCleanSession(true); - } else { - state = waitForDisconnect; - } - mqttReconnectTimer = millis(); + // set espMqttManagerInternals::state first to be in proper espMqttManagerInternals::state when handling onMqttClientDisconnected + espMqttManagerInternals::state = espMqttManagerState::WAITDISCONNECT; + espMqttManagerInternals::mqttReconnectTimer = millis(); mqttClient.disconnect(); return true; } bool espMqttManager::isConnected() { - return (state == connected) ? true : false; + return (espMqttManagerInternals::state == espMqttManagerState::CONNECTED) ? true : false; } -void idle() { +void espMqttManagerInternals::idle() { (void)0; } -void startWiFi() { - if (millis() - wifiReconnectTimer > interval) { - if (WiFi.begin(config.SSID, config.PSK) != WL_CONNECT_FAILED) { +void espMqttManagerInternals::connectWiFi() { + if (millis() - espMqttManagerInternals::wifiReconnectTimer > espMqttManagerInternals::interval) { + if (WiFi.begin(config.SSID, espMqttManagerInternals::config.PSK) != WL_CONNECT_FAILED) { #if defined(EMM_LOWER_WIFIPOWER) WiFi.setTxPower(EMM_LOWER_WIFIPOWER); #endif - state = waitForWiFi; + espMqttManagerInternals::setState(espMqttManagerState::WAITWIFI); } - wifiReconnectTimer = millis(); - interval = getBackoffTimerVal(interval); + espMqttManagerInternals::wifiReconnectTimer = millis(); + espMqttManagerInternals::interval = getBackoffTimerVal(interval); } } -void waitForWiFi() { +void espMqttManagerInternals::waitWiFi() { if (WiFi.status() == WL_CONNECTED) { emm_log_i("WiFi connected"); - state = reconnectWaitMqtt; - mqttReconnectTimer = millis(); - interval = 0; + espMqttManagerInternals::setState(espMqttManagerState::CONNECTMQTT); + espMqttManagerInternals::mqttReconnectTimer = millis(); + espMqttManagerInternals::interval = 0; onWiFiConnected(); + } else if (millis() - espMqttManagerInternals::wifiReconnectTimer > espMqttManagerInternals::interval) { + espMqttManagerInternals::setState(espMqttManagerState::CONNECTWIFI); } } -void reconnectWaitMqtt() { - if (WiFi.status() == WL_CONNECTED && millis() - mqttReconnectTimer > interval) { - if (espMqttManager::mqttClient.connect()) { - emm_log_i("Connecting to MQTT"); - state = waitForMqtt; - } +void espMqttManagerInternals::connectMqtt() { + if (millis() - espMqttManagerInternals::mqttReconnectTimer > espMqttManagerInternals::interval && espMqttManager::mqttClient.connect()) { + emm_log_i("Connecting to MQTT"); + espMqttManagerInternals::setState(espMqttManagerState::WAITMQTT); } } -void waitForMqtt() { - (void)0; - // state released by espMqttClient onConnect callback -} - -void setupSession() { - (void)0; - // state released by user action using espMqttManager::sessionSetup() -} - -void connected() { - // send stats - (void)0; +void espMqttManagerInternals::setupSession() { + onSetupSession(); + // espMqttManagerInternals::state released by user action using espMqttManager::sessionSetup() } -void waitForDisconnect() { - // state released by espMqttClient onDisconnect callback or force close connection - if (millis() - mqttReconnectTimer > ESP_MQTT_MANAGER_DISCONNECT_TIMEOUT) { +void espMqttManagerInternals::waitDisconnect() { + // espMqttManagerInternals::state released by espMqttClient onDisconnect callback or force close connection + if (millis() - espMqttManagerInternals::mqttReconnectTimer > ESP_MQTT_MANAGER_DISCONNECT_TIMEOUT) { emm_log_i("Disconnecting from MQTT"); espMqttManager::mqttClient.disconnect(true); } } -void waitForDisconnectCleanSession() { - // state released by espMqttClient onDisconnect callback or force close connection - if (millis() - mqttReconnectTimer > ESP_MQTT_MANAGER_DISCONNECT_TIMEOUT) { - emm_log_i("Disconnecting from MQTT (CS)"); - espMqttManager::mqttClient.disconnect(true); - } -} - -void reconnectWaitCleanSession() { - if (WiFi.status() == WL_CONNECTED && millis() - mqttReconnectTimer > interval) { - if (espMqttManager::mqttClient.connect()) { - emm_log_i("Reconnecting to MQTT (CS)"); - state = waitForMqttCleanSession; - } - } -} - -void waitForMqttCleanSession() { - (void)0; - // state released by espMqttClient onConnect callback -} - -void connectedCleanSession() { - espMqttManager::mqttClient.disconnect(); - emm_log_i("Disconnecting to MQTT (Final)"); - state = waitForDisconnectFinal; -} - -void waitForDisconnectFinal() { - (void)0; - // state released by espMqttClient onDisconnect callback -} - void onMqttClientConnected(bool sessionPresent) { - interval = 0; - if (state == waitForMqtt) { + espMqttManagerInternals::interval = 0; + if (espMqttManagerInternals::state == espMqttManagerState::WAITMQTT) { emm_log_i("Connected to MQTT (session: %s)", sessionPresent ? "y" : "n"); if (sessionPresent) { - state = connected; + espMqttManagerInternals::setState(espMqttManagerState::CONNECTED); onMqttConnected(); } else { - state = setupSession; - onSetupSession(); + espMqttManagerInternals::setState(espMqttManagerState::SETUPSESSION); } - } else if (state == waitForMqttCleanSession) { - emm_log_i("Connected to MQTT (CS)"); - state = connectedCleanSession; } } void onMqttClientDisconnected(espMqttClientTypes::DisconnectReason reason) { - mqttReconnectTimer = millis(); - if (state == waitForWiFi || - state == reconnectWaitMqtt || - state == waitForMqtt || - state == setupSession || - state == connected) { - interval = getBackoffTimerVal(interval); + espMqttManagerInternals::mqttReconnectTimer = millis(); + if (espMqttManagerInternals::state == espMqttManagerState::WAITDISCONNECT) { emm_log_i("Disconnected from MQTT"); - state = reconnectWaitMqtt; - onMqttDisconnected(reason); - } else if (state == waitForDisconnect) { + espMqttManagerInternals::setState(espMqttManagerState::DISCONNECTED); + onDisconnected(); + } else { + espMqttManagerInternals::interval = getBackoffTimerVal(espMqttManagerInternals::interval); emm_log_i("Disconnected from MQTT"); - state = idle; onMqttDisconnected(reason); - } else if (state == waitForDisconnectCleanSession) { - emm_log_i("Disconnected from MQTT (CS-1)"); - interval = 0; - state = reconnectWaitCleanSession; - } else if (state == waitForMqttCleanSession) { - emm_log_i("Disconnected from MQTT (CS-2)"); - interval = getBackoffTimerVal(interval); - state = reconnectWaitCleanSession; - } else if (state == waitForDisconnectFinal) { - emm_log_i("Disconnected from to MQTT (Final)"); - onReset(); + espMqttManagerInternals::setState(espMqttManagerState::CONNECTMQTT); } } diff --git a/src/espMqttManager.h b/src/espMqttManager.h index c5fd437..0561dba 100644 --- a/src/espMqttManager.h +++ b/src/espMqttManager.h @@ -39,7 +39,7 @@ void onWiFiConnected() __attribute__((weak)); void onWiFiDisconnected() __attribute__((weak)); void onMqttConnected() __attribute__((weak)); void onMqttDisconnected(espMqttClientTypes::DisconnectReason reason) __attribute__((weak)); -void onReset() __attribute__((weak)); +void onDisconnected() __attribute__((weak)); namespace espMqttManager { @@ -47,7 +47,7 @@ void setup(); void start(); void loop(); void sessionReady(); -bool disconnect(bool clearSession = false); +bool disconnect(); bool isConnected(); #if ESP_MQTT_MANAGER_SECURE extern espMqttClientSecure mqttClient;