Handle chunked MQTT messages missing topic on non-first chunks

See https://github.com/esphome/issues/issues/5125
This commit is contained in:
Adam Liddell 2023-11-17 19:31:24 +00:00
parent 32e3f26239
commit d1cd1c240b
2 changed files with 9 additions and 5 deletions

View file

@ -138,13 +138,16 @@ void MQTTBackendESP32::mqtt_event_handler_(const Event &event) {
this->on_publish_.call((int) event.msg_id);
break;
case MQTT_EVENT_DATA: {
static std::string topic;
if (event.topic.length() > 0) {
topic = event.topic;
// When a single message arrives as multiple chunks, the topic will be nullptr
// on any but the first message, leading to event.topic being an empty string.
// To ensure handlers get the correct topic, cache the last seen topic to
// simulate always receiving the topic from underlying library
topic_cache_ = event.topic;
}
ESP_LOGV(TAG, "MQTT_EVENT_DATA %s", topic.c_str());
this->on_message_.call(event.topic.length() > 0 ? topic.c_str() : nullptr, event.data.data(), event.data.size(),
event.current_data_offset, event.total_data_len);
ESP_LOGV(TAG, "MQTT_EVENT_DATA %s", topic_cache_.c_str());
this->on_message_.call(topic_cache_.c_str(), event.data.data(), event.data.size(), event.current_data_offset,
event.total_data_len);
} break;
case MQTT_EVENT_ERROR:
ESP_LOGE(TAG, "MQTT_EVENT_ERROR");

View file

@ -155,6 +155,7 @@ class MQTTBackendESP32 final : public MQTTBackend {
bool clean_session_;
optional<std::string> ca_certificate_;
bool skip_cert_cn_check_{false};
std::string topic_cache_;
// callbacks
CallbackManager<on_connect_callback_t> on_connect_;