From eac8e2fe7c10be42b6147c087926c863a7566297 Mon Sep 17 00:00:00 2001 From: Ian Hubbertz Date: Mon, 6 Mar 2017 23:50:17 +0100 Subject: [PATCH] Local develop (#3) * :memo: Add Gitter badge * :memo: Add link to the Gitter in the ISSUE_TEMPLATE * :bug: Fix loopFunction being called too early before MQTT connection is established - closes #260 (#290) * :shirt: Fix lint * :sparkles: Add destructor to HomieNode, that will abort() (#286) * Added destructor to HomieNode, that will abort() * :art: Log wifi client IP address upon connection. (#280) This removes the need to hunt the device IP when debugging connectivity issues. * :memo: Mention troubleshooting page in issue template * :shirt: Fix cpplint failure, causing travis CI to be red (#291) E.g. https://travis-ci.org/marvinroger/homie-esp8266/jobs/199213998 Ran the following command successfully: cpplint --repository=. --recursive \ --filter=-whitespace/line_length,-legal/copyright,-runtime/printf,-build/include,-build/namespace,-runtime/int \ ./src * :fire: Remove MQTT ack logging * :racehorse: Make tiny optimizations * :art: Add a comma to the wifi connected log * :art: Reorganize next boot mode feature * :racehorse: Check length on input fields (#292) * Fixing loopFunction being called too early before MQTT connection is established * Started cleanup of strcpy/sprintf to include length check. * Fixed warning under Interface.cpp * :shirt: Fix lint * :art: Print firmware name and version at boot * :bug: Fix DeviceId incomplete MAC address (#296) snprintf works with n-1 characters expected behaviour: DeviceId is 12 characters behaviour: only 11 characters are returned (resulting in a "incomplete" mac address) * :bug Fix millis() overflow in uptime - fix #299 (#302) Corrected type declaration for correct overflow handling of millis function in uptime calculation --- .github/ISSUE_TEMPLATE.md | 8 +++-- README.md | 2 +- src/Homie.cpp | 16 +++++----- src/Homie.hpp | 19 +++++------- src/Homie/Boot/Boot.cpp | 1 + src/Homie/Boot/BootConfig.cpp | 7 +++-- src/Homie/Boot/BootConfig.hpp | 2 +- src/Homie/Boot/BootNormal.cpp | 31 +++++++------------ src/Homie/Boot/BootStandalone.cpp | 2 +- src/Homie/Config.cpp | 50 ++++++++----------------------- src/Homie/Config.hpp | 2 +- src/Homie/Constants.hpp | 7 ----- src/Homie/Datatypes/Interface.cpp | 19 ++++++------ src/Homie/Datatypes/Interface.hpp | 1 + src/Homie/Limits.hpp | 4 +++ src/Homie/TimedRetry.cpp | 11 +++---- src/Homie/Timer.cpp | 2 +- src/Homie/Timer.hpp | 2 +- src/Homie/Uptime.cpp | 2 +- src/Homie/Uptime.hpp | 2 +- src/Homie/Utils/DeviceId.cpp | 4 +-- src/Homie/Utils/DeviceId.hpp | 4 ++- src/HomieBootMode.hpp | 8 +++++ src/HomieNode.cpp | 1 + 24 files changed, 92 insertions(+), 115 deletions(-) create mode 100644 src/HomieBootMode.hpp diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index e2021002..ffc87606 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,7 +1,9 @@ +The issue tracker is a great place to ask for enhancements and to report bugs. +If you have some questions or if you need help, some people might help you on the [Gitter room](https://gitter.im/homie-iot/ESP8266). + Before submitting your issue, make sure: -- [ ] You're using a [stable release](https://github.com/marvinroger/homie-esp8266/releases), not the Git development version which is, by definition, unstable -- [ ] You've read the documentation for *your* release, which is in the `docs/` folder of the `.zip` of the release you're using, especially the **Getting started** and **Troubleshooting** pages, which contain respectively the minimum required version of the dependencies, and some answsers to the most common problems -- [ ] You're using the examples bundled in *your* release, which are in the `examples/` folder of the `.zip` of the release you're using. Examples in the latest git revision might not be backward-compatible with your release +- [ ] You've read the documentation for *your* release (in the `docs/` folder for the v1, at https://homie-esp8266.readme.io) which contains some answsers to the most common problems (notably the `Limitations and know issues` and `Troubleshooting` pages) +- [ ] You're using the examples bundled in *your* release, which are in the `examples/` folder of the `.zip` of the release you're using. Examples might not be backward-compatible Thanks! diff --git a/README.md b/README.md index 0940f2a0..fa5bcb3d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Homie for ESP8266 ================= -[![Build Status](https://img.shields.io/travis/marvinroger/homie-esp8266/develop.svg?style=flat-square)](https://travis-ci.org/marvinroger/homie-esp8266) [![Latest Release](https://img.shields.io/badge/release-v2.0.0-yellow.svg?style=flat-square)](https://github.com/marvinroger/homie-esp8266/releases) +[![Build Status](https://img.shields.io/travis/marvinroger/homie-esp8266/develop.svg?style=flat-square)](https://travis-ci.org/marvinroger/homie-esp8266) [![Latest Release](https://img.shields.io/badge/release-v2.0.0-yellow.svg?style=flat-square)](https://github.com/marvinroger/homie-esp8266/releases) [![Gitter](https://img.shields.io/gitter/room/Homie/ESP8266.svg?style=flat-square)](https://gitter.im/homie-iot/ESP8266) An Arduino for ESP8266 implementation of [Homie](https://github.com/marvinroger/homie), an MQTT convention for the IoT. diff --git a/src/Homie.cpp b/src/Homie.cpp index 64651117..ceafba74 100644 --- a/src/Homie.cpp +++ b/src/Homie.cpp @@ -6,7 +6,7 @@ HomieClass::HomieClass() : _setupCalled(false) , _firmwareSet(false) , __HOMIE_SIGNATURE("\x25\x48\x4f\x4d\x49\x45\x5f\x45\x53\x50\x38\x32\x36\x36\x5f\x46\x57\x25") { - strcpy(Interface::get().brand, DEFAULT_BRAND); + strlcpy(Interface::get().brand, DEFAULT_BRAND, MAX_BRAND_LENGTH); Interface::get().bootMode = HomieBootMode::UNDEFINED; Interface::get().configurationAp.secured = false; Interface::get().led.enabled = true; @@ -63,7 +63,7 @@ void HomieClass::setup() { Interface::get().getConfig().setHomieBootModeOnNextBoot(HomieBootMode::UNDEFINED); } - HomieBootMode _selectedHomieBootMode = HomieBootMode::CONFIG; + HomieBootMode _selectedHomieBootMode = HomieBootMode::CONFIGURATION; // select boot mode source if (_applicationHomieBootMode != HomieBootMode::UNDEFINED) { @@ -77,7 +77,7 @@ void HomieClass::setup() { // validate selected mode and fallback as needed if (_selectedHomieBootMode == HomieBootMode::NORMAL && !Interface::get().getConfig().load()) { Interface::get().getLogger() << F("Configuration invalid. Using CONFIG MODE") << endl; - _selectedHomieBootMode = HomieBootMode::CONFIG; + _selectedHomieBootMode = HomieBootMode::CONFIGURATION; } // run selected mode @@ -86,7 +86,7 @@ void HomieClass::setup() { Interface::get().event.type = HomieEventType::NORMAL_MODE; Interface::get().eventHandler(Interface::get().event); - } else if (_selectedHomieBootMode == HomieBootMode::CONFIG) { + } else if (_selectedHomieBootMode == HomieBootMode::CONFIGURATION) { _boot = &_bootConfig; Interface::get().event.type = HomieEventType::CONFIGURATION_MODE; Interface::get().eventHandler(Interface::get().event); @@ -157,7 +157,7 @@ HomieClass& HomieClass::setConfigurationApPassword(const char* password) { _checkBeforeSetup(F("setConfigurationApPassword")); Interface::get().configurationAp.secured = true; - strcpy(Interface::get().configurationAp.password, password); + strlcpy(Interface::get().configurationAp.password, password, MAX_WIFI_PASSWORD_LENGTH); } void HomieClass::__setFirmware(const char* name, const char* version) { @@ -242,11 +242,11 @@ HomieClass& HomieClass::setHomieBootModeOnNextBoot(HomieBootMode bootMode) { return *this; } -bool HomieClass::isConfigured() const { +bool HomieClass::isConfigured() { return Interface::get().getConfig().load(); } -bool HomieClass::isConnected() const { +bool HomieClass::isConnected() { return Interface::get().connected; } @@ -277,7 +277,7 @@ HomieClass& HomieClass::disableResetTrigger() { return *this; } -const ConfigStruct& HomieClass::getConfiguration() const { +const ConfigStruct& HomieClass::getConfiguration() { return Interface::get().getConfig().get(); } diff --git a/src/Homie.hpp b/src/Homie.hpp index e5a1f010..a39dc4d9 100644 --- a/src/Homie.hpp +++ b/src/Homie.hpp @@ -16,6 +16,8 @@ #include "Homie/Blinker.hpp" #include "SendingPromise.hpp" +#include "HomieBootMode.hpp" +#include "HomieEvent.hpp" #include "HomieNode.hpp" #include "HomieSetting.hpp" #include "StreamingOperator.hpp" @@ -37,11 +39,6 @@ class HomieClass { void __setFirmware(const char* name, const char* version); void __setBrand(const char* brand) const; - static const HomieBootMode MODE_UNDEFINED = HomieBootMode::UNDEFINED; - static const HomieBootMode MODE_STANDALONE = HomieBootMode::STANDALONE; - static const HomieBootMode MODE_CONFIG = HomieBootMode::CONFIG; - static const HomieBootMode MODE_NORMAL = HomieBootMode::NORMAL; - HomieClass& disableLogging(); HomieClass& setLoggingPrinter(Print* printer); HomieClass& disableLedFeedback(); @@ -57,15 +54,15 @@ class HomieClass { HomieClass& setHomieBootMode(HomieBootMode bootMode); HomieClass& setHomieBootModeOnNextBoot(HomieBootMode bootMode); - void reset(); + static void reset(); void reboot(); - void setIdle(bool idle); - bool isConfigured() const; - bool isConnected() const; - const ConfigStruct& getConfiguration() const; + static void setIdle(bool idle); + static bool isConfigured(); + static bool isConnected(); + static const ConfigStruct& getConfiguration(); AsyncMqttClient& getMqttClient(); Logger& getLogger(); - void prepareToSleep(); + static void prepareToSleep(); private: bool _setupCalled; diff --git a/src/Homie/Boot/Boot.cpp b/src/Homie/Boot/Boot.cpp index b14f218a..22f81fc5 100644 --- a/src/Homie/Boot/Boot.cpp +++ b/src/Homie/Boot/Boot.cpp @@ -15,6 +15,7 @@ void Boot::setup() { WiFi.persistent(true); // Persist data on SDK as it seems Wi-Fi connection is faster + Interface::get().getLogger() << F("💡 Firmware ") << Interface::get().firmware.name << F(" (") << Interface::get().firmware.version << F(")") << endl; Interface::get().getLogger() << F("🔌 Booting into ") << _name << F(" mode 🔌") << endl; } diff --git a/src/Homie/Boot/BootConfig.cpp b/src/Homie/Boot/BootConfig.cpp index dbdd9db0..5eaf51c7 100644 --- a/src/Homie/Boot/BootConfig.cpp +++ b/src/Homie/Boot/BootConfig.cpp @@ -11,7 +11,8 @@ BootConfig::BootConfig() , _jsonWifiNetworks() , _flaggedForReboot(false) , _flaggedForRebootAt(0) -, _proxyEnabled(false) { +, _proxyEnabled(false) +, _apIpStr({'\0'}) { _wifiScanTimer.setInterval(CONFIG_SCAN_INTERVAL); } @@ -30,7 +31,7 @@ void BootConfig::setup() { WiFi.mode(WIFI_AP_STA); char apName[MAX_WIFI_SSID_LENGTH]; - strcpy(apName, Interface::get().brand); + strlcpy(apName, Interface::get().brand, MAX_WIFI_SSID_LENGTH - 1 - MAX_MAC_STRING_LENGTH); strcat_P(apName, PSTR("-")); strcat(apName, DeviceId::get()); @@ -41,7 +42,7 @@ void BootConfig::setup() { WiFi.softAP(apName); } - sprintf(_apIpStr, "%d.%d.%d.%d", ACCESS_POINT_IP[0], ACCESS_POINT_IP[1], ACCESS_POINT_IP[2], ACCESS_POINT_IP[3]); + snprintf(_apIpStr, MAX_IP_STRING_LENGTH, "%d.%d.%d.%d", ACCESS_POINT_IP[0], ACCESS_POINT_IP[1], ACCESS_POINT_IP[2], ACCESS_POINT_IP[3]); Interface::get().getLogger() << F("AP started as ") << apName << F(" with IP ") << _apIpStr << endl; _dns.setTTL(30); diff --git a/src/Homie/Boot/BootConfig.hpp b/src/Homie/Boot/BootConfig.hpp index 9fb33868..cbff972e 100644 --- a/src/Homie/Boot/BootConfig.hpp +++ b/src/Homie/Boot/BootConfig.hpp @@ -41,7 +41,7 @@ class BootConfig : public Boot { bool _flaggedForReboot; uint32_t _flaggedForRebootAt; bool _proxyEnabled; - char _apIpStr[15 + 1]; + char _apIpStr[MAX_IP_STRING_LENGTH]; void _onCaptivePortal(); void _onDeviceInfoRequest(); diff --git a/src/Homie/Boot/BootNormal.cpp b/src/Homie/Boot/BootNormal.cpp index 96a9ff8b..565a2df4 100644 --- a/src/Homie/Boot/BootNormal.cpp +++ b/src/Homie/Boot/BootNormal.cpp @@ -4,9 +4,9 @@ using namespace HomieInternals; BootNormal::BootNormal() : Boot("normal") +, _mqttTimedRetry(MQTT_RECONNECT_STEP_INTERVAL, MQTT_RECONNECT_MAX_INTERVAL) , _setupFunctionCalled(false) , _mqttDisconnectNotified(true) -, _mqttTimedRetry(MQTT_RECONNECT_STEP_INTERVAL, MQTT_RECONNECT_MAX_INTERVAL) , _flaggedForOta(false) , _flaggedForReset(false) , _flaggedForReboot(false) @@ -20,7 +20,7 @@ BootNormal::BootNormal() , _mqttWillTopic(nullptr) , _mqttPayloadBuffer(nullptr) { _statsTimer.setInterval(STATS_SEND_INTERVAL); - strncpy(_fwChecksum, ESP.getSketchMD5().c_str(), sizeof(_fwChecksum) - 1); + strlcpy(_fwChecksum, ESP.getSketchMD5().c_str(), sizeof(_fwChecksum)); _fwChecksum[sizeof(_fwChecksum) - 1] = '\0'; } @@ -118,7 +118,7 @@ void BootNormal::_wifiConnect() { void BootNormal::_onWifiGotIp(const WiFiEventStationModeGotIP& event) { if (Interface::get().led.enabled) Interface::get().getBlinker().stop(); - Interface::get().getLogger() << F("✔ Wi-Fi connected") << endl; + Interface::get().getLogger() << F("✔ Wi-Fi connected, IP: ") << event.ip << endl; Interface::get().getLogger() << F("Triggering WIFI_CONNECTED event...") << endl; Interface::get().event.type = HomieEventType::WIFI_CONNECTED; Interface::get().event.ip = event.ip; @@ -189,19 +189,9 @@ void BootNormal::_onMqttConnected() { Interface::get().getMqttClient().publish(_prefixMqttTopic(PSTR("/$name")), 1, true, Interface::get().getConfig().get().name); IPAddress localIp = WiFi.localIP(); - char localIpStr[15 + 1]; - char localIpPartStr[3 + 1]; - itoa(localIp[0], localIpPartStr, 10); - strcpy(localIpStr, localIpPartStr); - strcat_P(localIpStr, PSTR(".")); - itoa(localIp[1], localIpPartStr, 10); - strcat(localIpStr, localIpPartStr); - strcat_P(localIpStr, PSTR(".")); - itoa(localIp[2], localIpPartStr, 10); - strcat(localIpStr, localIpPartStr); - strcat_P(localIpStr, PSTR(".")); - itoa(localIp[3], localIpPartStr, 10); - strcat(localIpStr, localIpPartStr); + char localIpStr[MAX_IP_STRING_LENGTH]; + snprintf(localIpStr, MAX_IP_STRING_LENGTH - 1, "%d.%d.%d.%d", localIp[0], localIp[1], localIp[2], localIp[3]); + Interface::get().getMqttClient().publish(_prefixMqttTopic(PSTR("/$localip")), 1, true, localIpStr); char statsIntervalStr[3 + 1]; @@ -614,7 +604,6 @@ void BootNormal::_onMqttMessage(char* topic, char* payload, AsyncMqttClientMessa } void BootNormal::_onMqttPublish(uint16_t id) { - Interface::get().getLogger() << F("Triggering MQTT_PACKET_ACKNOWLEDGED event (packetId ") << id << F(")...") << endl; Interface::get().event.type = HomieEventType::MQTT_PACKET_ACKNOWLEDGED; Interface::get().event.packetId = id; Interface::get().eventHandler(Interface::get().event); @@ -755,11 +744,11 @@ void BootNormal::loop() { Interface::get().getMqttClient().publish(_prefixMqttTopic(PSTR("/$stats/uptime")), 1, true, uptimeStr); _statsTimer.tick(); } - } - Interface::get().loopFunction(); + Interface::get().loopFunction(); - for (HomieNode* iNode : HomieNode::nodes) { - iNode->loop(); + for (HomieNode* iNode : HomieNode::nodes) { + iNode->loop(); + } } } diff --git a/src/Homie/Boot/BootStandalone.cpp b/src/Homie/Boot/BootStandalone.cpp index 4518e07a..9ac8f473 100644 --- a/src/Homie/Boot/BootStandalone.cpp +++ b/src/Homie/Boot/BootStandalone.cpp @@ -46,7 +46,7 @@ void BootStandalone::loop() { if (_flaggedForConfig && Interface::get().reset.idle) { Interface::get().getLogger() << F("Device is idle") << endl; - Interface::get().getConfig().setHomieBootModeOnNextBoot(HomieBootMode::CONFIG); + Interface::get().getConfig().setHomieBootModeOnNextBoot(HomieBootMode::CONFIGURATION); Interface::get().getLogger() << F("Triggering ABOUT_TO_RESET event...") << endl; Interface::get().event.type = HomieEventType::ABOUT_TO_RESET; diff --git a/src/Homie/Config.cpp b/src/Homie/Config.cpp index 0f927a8f..61f1e12e 100644 --- a/src/Homie/Config.cpp +++ b/src/Homie/Config.cpp @@ -3,9 +3,9 @@ using namespace HomieInternals; Config::Config() -: _valid(false) -, _configStruct() -, _spiffsBegan(false) { +: _configStruct() +, _spiffsBegan(false) +, _valid(false) { } bool Config::_spiffsBegin() { @@ -93,16 +93,16 @@ bool Config::load() { reqOtaEnabled = parsedJson["ota"]["enabled"]; } - strcpy(_configStruct.name, reqName); - strcpy(_configStruct.wifi.ssid, reqWifiSsid); - if (reqWifiPassword) strcpy(_configStruct.wifi.password, reqWifiPassword); - strcpy(_configStruct.deviceId, reqDeviceId); - strcpy(_configStruct.mqtt.server.host, reqMqttHost); + strlcpy(_configStruct.name, reqName, MAX_FRIENDLY_NAME_LENGTH); + strlcpy(_configStruct.wifi.ssid, reqWifiSsid, MAX_WIFI_SSID_LENGTH); + if (reqWifiPassword) strlcpy(_configStruct.wifi.password, reqWifiPassword, MAX_WIFI_PASSWORD_LENGTH); + strlcpy(_configStruct.deviceId, reqDeviceId, MAX_DEVICE_ID_LENGTH); + strlcpy(_configStruct.mqtt.server.host, reqMqttHost, MAX_HOSTNAME_LENGTH); _configStruct.mqtt.server.port = reqMqttPort; - strcpy(_configStruct.mqtt.baseTopic, reqMqttBaseTopic); + strlcpy(_configStruct.mqtt.baseTopic, reqMqttBaseTopic, MAX_MQTT_BASE_TOPIC_LENGTH); _configStruct.mqtt.auth = reqMqttAuth; - strcpy(_configStruct.mqtt.username, reqMqttUsername); - strcpy(_configStruct.mqtt.password, reqMqttPassword); + strlcpy(_configStruct.mqtt.username, reqMqttUsername, MAX_MQTT_CREDS_LENGTH); + strlcpy(_configStruct.mqtt.password, reqMqttPassword, MAX_MQTT_CREDS_LENGTH); _configStruct.ota.enabled = reqOtaEnabled; /* Parse the settings */ @@ -178,7 +178,7 @@ void Config::setHomieBootModeOnNextBoot(HomieBootMode bootMode) { } else { File bootModeFile = SPIFFS.open(CONFIG_NEXT_BOOT_MODE_FILE_PATH, "w"); if (!bootModeFile) { - Interface::get().getLogger() << F("✖ Cannot open BOOTMODE file") << endl; + Interface::get().getLogger() << F("✖ Cannot open NEXTMODE file") << endl; return; } @@ -195,15 +195,7 @@ HomieBootMode Config::getHomieBootModeOnNextBoot() { if (bootModeFile) { int v = bootModeFile.parseInt(); bootModeFile.close(); - if (v == 1) { - return HomieBootMode::STANDALONE; - } else if (v == 2) { - return HomieBootMode::CONFIG; - } else if (v == 3) { - return HomieBootMode::NORMAL; - } else { - return HomieBootMode::UNDEFINED; - } + return static_cast(v); } else { return HomieBootMode::UNDEFINED; } @@ -289,22 +281,6 @@ void Config::log() const { Interface::get().getLogger() << F("{} Stored configuration") << endl; Interface::get().getLogger() << F(" • Hardware device ID: ") << DeviceId::get() << endl; Interface::get().getLogger() << F(" • Device ID: ") << _configStruct.deviceId << endl; - Interface::get().getLogger() << F(" • Boot mode: "); - switch (_bootMode) { - case HomieBootMode::CONFIG: - Interface::get().getLogger() << F("configuration") << endl; - break; - case HomieBootMode::NORMAL: - Interface::get().getLogger() << F("normal") << endl; - break; - case HomieBootMode::STANDALONE: - Interface::get().getLogger() << F("standalone") << endl; - break; - default: - Interface::get().getLogger() << F("unknown") << endl; - break; - } - Interface::get().getLogger() << F(" • Name: ") << _configStruct.name << endl; Interface::get().getLogger() << F(" • Wi-Fi: ") << endl; diff --git a/src/Homie/Config.hpp b/src/Homie/Config.hpp index 0b0055ac..cfc95c6b 100644 --- a/src/Homie/Config.hpp +++ b/src/Homie/Config.hpp @@ -10,6 +10,7 @@ #include "Utils/Validation.hpp" #include "Constants.hpp" #include "Limits.hpp" +#include "../HomieBootMode.hpp" #include "../HomieSetting.hpp" #include "../StreamingOperator.hpp" @@ -29,7 +30,6 @@ class Config { bool isValid() const; private: - HomieBootMode _bootMode; ConfigStruct _configStruct; bool _spiffsBegan; bool _valid; diff --git a/src/Homie/Constants.hpp b/src/Homie/Constants.hpp index 4a1909f1..6fe2702b 100644 --- a/src/Homie/Constants.hpp +++ b/src/Homie/Constants.hpp @@ -28,11 +28,4 @@ namespace HomieInternals { const char CONFIG_UI_BUNDLE_PATH[] = "/homie/ui_bundle.gz"; const char CONFIG_NEXT_BOOT_MODE_FILE_PATH[] = "/homie/NEXTMODE"; const char CONFIG_FILE_PATH[] = "/homie/config.json"; - - enum class HomieBootMode : uint8_t { - UNDEFINED = 0, - STANDALONE = 1, - CONFIG = 2, - NORMAL = 3 - }; } // namespace HomieInternals diff --git a/src/Homie/Datatypes/Interface.cpp b/src/Homie/Datatypes/Interface.cpp index 2dde4a11..49d3f87a 100644 --- a/src/Homie/Datatypes/Interface.cpp +++ b/src/Homie/Datatypes/Interface.cpp @@ -5,18 +5,19 @@ using namespace HomieInternals; InterfaceData Interface::_interface; // need to define the static variable InterfaceData::InterfaceData() -: brand({'\0'}) -, bootMode(HomieBootMode::UNDEFINED) +: brand{'\0'} +, bootMode{HomieBootMode::UNDEFINED} +, configurationAp { .secured = false, .password = {'\0'} } , firmware { .name = {'\0'}, .version = {'\0'} } , led { .enabled = false, .pin = 0, .on = 0 } , reset { .enabled = false, .idle = false, .triggerPin = 0, .triggerState = 0, .triggerTime = 0, .flaggedBySketch = false } -, flaggedForSleep(false) -, connected(false) -, _logger(nullptr) -, _blinker(nullptr) -, _config(nullptr) -, _mqttClient(nullptr) -, _sendingPromise(nullptr) { +, flaggedForSleep{false} +, connected{false} +, _logger{nullptr} +, _blinker{nullptr} +, _config{nullptr} +, _mqttClient{nullptr} +, _sendingPromise{nullptr} { } InterfaceData& Interface::get() { diff --git a/src/Homie/Datatypes/Interface.hpp b/src/Homie/Datatypes/Interface.hpp index e68546a2..3570cd1e 100644 --- a/src/Homie/Datatypes/Interface.hpp +++ b/src/Homie/Datatypes/Interface.hpp @@ -7,6 +7,7 @@ #include "../Config.hpp" #include "../Limits.hpp" #include "./Callbacks.hpp" +#include "../../HomieBootMode.hpp" #include "../../HomieNode.hpp" #include "../../SendingPromise.hpp" #include "../../HomieEvent.hpp" diff --git a/src/Homie/Limits.hpp b/src/Homie/Limits.hpp index 95c8b6bc..0c0e1373 100644 --- a/src/Homie/Limits.hpp +++ b/src/Homie/Limits.hpp @@ -24,4 +24,8 @@ namespace HomieInternals { const uint8_t MAX_NODE_ID_LENGTH = sizeof("my-super-awesome-node-id"); const uint8_t MAX_NODE_TYPE_LENGTH = sizeof("my-super-awesome-type"); const uint8_t MAX_NODE_PROPERTY_LENGTH = sizeof("my-super-awesome-property"); + + const uint8_t MAX_IP_STRING_LENGTH = sizeof("123.123.123.123"); + + const uint8_t MAX_MAC_STRING_LENGTH = 12; } // namespace HomieInternals diff --git a/src/Homie/TimedRetry.cpp b/src/Homie/TimedRetry.cpp index bb6f8698..b11bebcf 100644 --- a/src/Homie/TimedRetry.cpp +++ b/src/Homie/TimedRetry.cpp @@ -3,11 +3,12 @@ using namespace HomieInternals; -TimedRetry::TimedRetry(uint32_t stepInterval, uint32_t maxInterval) : - _stepInterval(stepInterval), - _maxInterval(maxInterval), - _timer(Timer()) { - _timer.deactivate(); +TimedRetry::TimedRetry(uint32_t stepInterval, uint32_t maxInterval) +: _currentStep(0) +, _stepInterval(stepInterval) +, _maxInterval(maxInterval) +, _timer(Timer()) { + _timer.deactivate(); } void TimedRetry::activate() { diff --git a/src/Homie/Timer.cpp b/src/Homie/Timer.cpp index b37550f4..ce1b9c09 100644 --- a/src/Homie/Timer.cpp +++ b/src/Homie/Timer.cpp @@ -45,6 +45,6 @@ void Timer::deactivate() { reset(); } -bool Timer::isActive() { +bool Timer::isActive() const { return _active; } diff --git a/src/Homie/Timer.hpp b/src/Homie/Timer.hpp index 2216ca81..b7afa253 100644 --- a/src/Homie/Timer.hpp +++ b/src/Homie/Timer.hpp @@ -13,7 +13,7 @@ class Timer { void reset(); void activate(); void deactivate(); - bool isActive(); + bool isActive() const; private: uint32_t _initialTime; diff --git a/src/Homie/Uptime.cpp b/src/Homie/Uptime.cpp index 54fd9628..710578f2 100644 --- a/src/Homie/Uptime.cpp +++ b/src/Homie/Uptime.cpp @@ -8,7 +8,7 @@ Uptime::Uptime() } void Uptime::update() { - uint64_t now = millis(); + uint32_t now = millis(); _seconds += (now - _lastTick) / 1000UL; _lastTick = now; } diff --git a/src/Homie/Uptime.hpp b/src/Homie/Uptime.hpp index f685d292..3289153d 100644 --- a/src/Homie/Uptime.hpp +++ b/src/Homie/Uptime.hpp @@ -11,6 +11,6 @@ class Uptime { private: uint64_t _seconds; - uint64_t _lastTick; + uint32_t _lastTick; }; } // namespace HomieInternals diff --git a/src/Homie/Utils/DeviceId.cpp b/src/Homie/Utils/DeviceId.cpp index de0fd584..b3d8966b 100644 --- a/src/Homie/Utils/DeviceId.cpp +++ b/src/Homie/Utils/DeviceId.cpp @@ -2,12 +2,12 @@ using namespace HomieInternals; -char DeviceId::_deviceId[] = ""; // need to define the static variable +char DeviceId::_deviceId[]; // need to define the static variable void DeviceId::generate() { uint8_t mac[6]; WiFi.macAddress(mac); - sprintf(DeviceId::_deviceId, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + snprintf(DeviceId::_deviceId, MAX_MAC_STRING_LENGTH+1 , "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } const char* DeviceId::get() { diff --git a/src/Homie/Utils/DeviceId.hpp b/src/Homie/Utils/DeviceId.hpp index 4ca6744b..da5a42a5 100644 --- a/src/Homie/Utils/DeviceId.hpp +++ b/src/Homie/Utils/DeviceId.hpp @@ -4,6 +4,8 @@ #include +#include "../Limits.hpp" + namespace HomieInternals { class DeviceId { public: @@ -11,6 +13,6 @@ class DeviceId { static const char* get(); private: - static char _deviceId[12 + 1]; + static char _deviceId[MAX_MAC_STRING_LENGTH + 1]; }; } // namespace HomieInternals diff --git a/src/HomieBootMode.hpp b/src/HomieBootMode.hpp new file mode 100644 index 00000000..f2ea7664 --- /dev/null +++ b/src/HomieBootMode.hpp @@ -0,0 +1,8 @@ +#pragma once + +enum class HomieBootMode : uint8_t { + UNDEFINED = 0, + STANDALONE = 1, + CONFIGURATION = 2, + NORMAL = 3 +}; diff --git a/src/HomieNode.cpp b/src/HomieNode.cpp index 6f05b3cd..0cfba072 100644 --- a/src/HomieNode.cpp +++ b/src/HomieNode.cpp @@ -35,6 +35,7 @@ HomieNode::HomieNode(const char* id, const char* type, NodeInputHandler inputHan HomieNode::~HomieNode() { + Interface::get().getLogger() << F("✖ ~HomieNode(): Destruction of HomieNode object not possible") << endl; Interface::get().getLogger() << F(" Hint: Don't create HomieNode objects as a local variable (e.g. in setup())") << endl; Serial.flush();