diff --git a/README.md b/README.md index 3585b72..7ed7a74 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ ## Supported types -- :heavy_check_mark: Binary sensors -- :heavy_check_mark: Device triggers -- :heavy_check_mark: Switches -- :heavy_check_mark: Sensors -- :heavy_check_mark: Tag scanners +- Binary sensors +- Device triggers +- Switches +- Sensors +- Tag scanners If you need support for non-listed device's type please open a new issue in the Github repository. diff --git a/src/HAMqtt.cpp b/src/HAMqtt.cpp index d9ee8be..4bb2f22 100644 --- a/src/HAMqtt.cpp +++ b/src/HAMqtt.cpp @@ -91,7 +91,11 @@ bool HAMqtt::isConnected() void HAMqtt::addDeviceType(BaseDeviceType* deviceType) { - BaseDeviceType** data = realloc(_devicesTypes, sizeof(BaseDeviceType*) * (_devicesTypesNb + 1)); + BaseDeviceType** data = realloc( + _devicesTypes, + sizeof(BaseDeviceType*) * (_devicesTypesNb + 1) + ); + if (data != nullptr) { _devicesTypes = data; _devicesTypes[_devicesTypesNb] = deviceType; diff --git a/src/device-types/BaseDeviceType.cpp b/src/device-types/BaseDeviceType.cpp index a45464a..9aff833 100644 --- a/src/device-types/BaseDeviceType.cpp +++ b/src/device-types/BaseDeviceType.cpp @@ -25,6 +25,10 @@ uint16_t BaseDeviceType::calculateTopicLength( { // [discovery prefix]/[namespace]/[device id - optional]/subtype_type/[suffix] const char* prefix = _mqtt.getDiscoveryPrefix(); + if (prefix == nullptr) { + return 0; + } + uint16_t size = strlen(prefix) + 1 + // with slash strlen(component) + 1 + // with slash diff --git a/src/device-types/HASwitch.cpp b/src/device-types/HASwitch.cpp index 993a5d8..7f369c8 100644 --- a/src/device-types/HASwitch.cpp +++ b/src/device-types/HASwitch.cpp @@ -105,19 +105,34 @@ void HASwitch::triggerCallback(bool state) void HASwitch::publishConfig() { const HADevice* device = mqtt()->getDevice(); - uint16_t deviceLength = (device == nullptr ? 0 : device->calculateSerializedLength()); - char serializedDevice[deviceLength]; + if (device == nullptr) { + return; + } - if (device != nullptr) { - device->serialize(serializedDevice); + const uint16_t& deviceLength = device->calculateSerializedLength(); + if (deviceLength == 0) { + return; + } + + char serializedDevice[deviceLength]; + if (device->serialize(serializedDevice) == 0) { + return; } const uint16_t& topicLength = calculateTopicLength(HAComponentName, _name, ConfigTopic); const uint16_t& dataLength = calculateSerializedLength(serializedDevice); + if (topicLength == 0 || dataLength == 0) { + return; + } + char topic[topicLength]; generateTopic(topic, HAComponentName, _name, ConfigTopic); + if (strlen(topic) == 0) { + return; + } + if (mqtt()->beginPublish(topic, dataLength, true)) { writeSerializedTrigger(serializedDevice); mqtt()->endPublish(); @@ -135,6 +150,10 @@ void HASwitch::publishCurrentState() _name, StateTopic ); + if (topicSize == 0) { + return; + } + char topic[topicSize]; generateTopic( topic, @@ -143,6 +162,10 @@ void HASwitch::publishCurrentState() StateTopic ); + if (strlen(topic) == 0) { + return; + } + mqtt()->publish(topic, (_currentState ? StateOn : StateOff)); } @@ -153,6 +176,10 @@ void HASwitch::subscribeCommandTopic() _name, CommandTopic ); + if (topicSize == 0) { + return; + } + char topic[topicSize]; generateTopic( topic, @@ -161,11 +188,19 @@ void HASwitch::subscribeCommandTopic() CommandTopic ); + if (strlen(topic) == 0) { + return; + } + mqtt()->subscribe(topic); } uint16_t HASwitch::calculateSerializedLength(const char* serializedDevice) const { + if (serializedDevice == nullptr) { + return 0; + } + const uint16_t& cmdTopicLength = calculateTopicLength( HAComponentName, _name, @@ -179,6 +214,10 @@ uint16_t HASwitch::calculateSerializedLength(const char* serializedDevice) const false ); + if (cmdTopicLength == 0 || stateTopicLength == 0) { + return 0; + } + uint16_t size = 2 + // opening and closing bracket (without null terminator) cmdTopicLength + 10 + // 10 - length of the JSON data for this field @@ -210,6 +249,10 @@ bool HASwitch::writeSerializedTrigger(const char* serializedDevice) const _name, CommandTopic ); + if (topicSize == 0) { + return false; + } + char cmdTopic[topicSize]; generateTopic( cmdTopic, @@ -218,6 +261,10 @@ bool HASwitch::writeSerializedTrigger(const char* serializedDevice) const CommandTopic ); + if (strlen(cmdTopic) == 0) { + return false; + } + static const char DataBefore[] PROGMEM = {"{\"cmd_t\":\""}; mqtt()->writePayload_P(DataBefore); @@ -232,6 +279,10 @@ bool HASwitch::writeSerializedTrigger(const char* serializedDevice) const _name, StateTopic ); + if (topicSize == 0) { + return false; + } + char stateTopic[topicSize]; generateTopic( stateTopic, @@ -240,6 +291,10 @@ bool HASwitch::writeSerializedTrigger(const char* serializedDevice) const StateTopic ); + if (strlen(stateTopic) == 0) { + return false; + } + static const char DataBefore[] PROGMEM = {",\"stat_t\":\""}; mqtt()->writePayload_P(DataBefore); diff --git a/src/device-types/HATagScanner.cpp b/src/device-types/HATagScanner.cpp index f2194d9..b8ef9c1 100644 --- a/src/device-types/HATagScanner.cpp +++ b/src/device-types/HATagScanner.cpp @@ -37,6 +37,10 @@ bool HATagScanner::tagScanned(const char* tag) _name, EventTopic ); + if (topicSize == 0) { + return false; + } + char topic[topicSize]; generateTopic( topic, @@ -45,22 +49,44 @@ bool HATagScanner::tagScanned(const char* tag) EventTopic ); + if (strlen(topic) == 0) { + return false; + } + return mqtt()->publish(topic, tag); } void HATagScanner::publishConfig() { const HADevice* device = mqtt()->getDevice(); + if (device == nullptr) { + return; + } + const uint16_t& deviceLength = device->calculateSerializedLength(); + if (deviceLength == 0) { + return; + } + char serializedDevice[deviceLength]; - device->serialize(serializedDevice); + if (device->serialize(serializedDevice) == 0) { + return; + } const uint16_t& topicLength = calculateTopicLength(HAComponentName, _name, ConfigTopic); const uint16_t& dataLength = calculateSerializedLength(serializedDevice); + if (topicLength == 0 || dataLength == 0) { + return; + } + char topic[topicLength]; generateTopic(topic, HAComponentName, _name, ConfigTopic); + if (strlen(topic) == 0) { + return; + } + if (mqtt()->beginPublish(topic, dataLength, true)) { writeSerializedTrigger(serializedDevice); mqtt()->endPublish(); diff --git a/src/device-types/HATriggers.cpp b/src/device-types/HATriggers.cpp index 001b16b..2c9c193 100644 --- a/src/device-types/HATriggers.cpp +++ b/src/device-types/HATriggers.cpp @@ -69,15 +69,24 @@ bool HATriggers::trigger(const char* type, const char* subtype) return false; } - const uint16_t& size = calculateTopicLength( + const uint16_t& topicSize = calculateTopicLength( HAComponentName, trigger, EventTopic ); - char topic[size]; + if (topicSize == 0) { + return false; + } + + char topic[topicSize]; generateTopic(topic, HAComponentName, trigger, EventTopic); - mqtt()->publish(topic, ""); + + if (strlen(topic) == 0) { + return false; + } + + return mqtt()->publish(topic, ""); } void HATriggers::publishConfig() @@ -87,18 +96,36 @@ void HATriggers::publishConfig() return; // device is required for triggers } - uint16_t deviceLength = device->calculateSerializedLength(); + const uint16_t& deviceLength = device->calculateSerializedLength(); + if (deviceLength == 0) { + return; + } + char serializedDevice[deviceLength]; - device->serialize(serializedDevice); + if (device->serialize(serializedDevice) == 0) { + return; + } for (uint8_t i = 0; i < _triggersNb; i++) { const HATrigger* trigger = &_triggers[i]; + if (trigger == nullptr) { + continue; + } + const uint16_t& topicLength = calculateTopicLength(HAComponentName, trigger, ConfigTopic); const uint16_t& dataLength = calculateSerializedLength(trigger, serializedDevice); + if (topicLength == 0 || dataLength == 0) { + continue; + } + char topic[topicLength]; generateTopic(topic, HAComponentName, trigger, ConfigTopic); + if (strlen(topic) == 0) { + continue; + } + if (mqtt()->beginPublish(topic, dataLength, true)) { writeSerializedTrigger(trigger, serializedDevice); mqtt()->endPublish(); @@ -150,12 +177,20 @@ uint16_t HATriggers::calculateSerializedLength( const char* serializedDevice ) const { + if (serializedDevice == nullptr) { + return 0; + } + const uint16_t& topicLength = calculateTopicLength( HAComponentName, trigger, EventTopic, false ); + if (topicLength == 0) { + return 0; + } + uint16_t size = 2 + // opening and closing bracket (without null terminator) 17 + // automation type @@ -175,6 +210,10 @@ bool HATriggers::writeSerializedTrigger( const char* serializedDevice ) const { + if (serializedDevice == nullptr) { + return false; + } + static const char QuotationSign[] PROGMEM = {"\""}; // automation type @@ -190,6 +229,10 @@ bool HATriggers::writeSerializedTrigger( trigger, EventTopic ); + if (topicSize == 0) { + return false; + } + char eventTopic[topicSize]; generateTopic( eventTopic, @@ -198,6 +241,10 @@ bool HATriggers::writeSerializedTrigger( EventTopic ); + if (strlen(eventTopic) == 0) { + return false; + } + static const char DataBefore[] PROGMEM = {",\"t\":\""}; mqtt()->writePayload_P(DataBefore); @@ -224,7 +271,7 @@ bool HATriggers::writeSerializedTrigger( } // device - if (serializedDevice != nullptr) { + { static const char Data[] PROGMEM = {",\"dev\":"}; mqtt()->writePayload_P(Data);