#include "esphome/core/defines.h" #if defined(USE_ESP32) && defined(USE_MDNS) #include #include #include "esphome/core/hal.h" #include "esphome/core/log.h" #include "mdns_component.h" namespace esphome { namespace mdns { static const char *const TAG = "mdns"; void MDNSComponent::setup() { this->compile_records_(); esp_err_t err = mdns_init(); if (err != ESP_OK) { ESP_LOGW(TAG, "Init failed: %s", esp_err_to_name(err)); this->mark_failed(); return; } mdns_hostname_set(this->hostname_.c_str()); mdns_instance_name_set(this->hostname_.c_str()); for (const auto &service : this->services_) { std::vector txt_records; for (const auto &record : service.txt_records) { mdns_txt_item_t it{}; // dup strings to ensure the pointer is valid even after the record loop it.key = strdup(record.key.c_str()); it.value = strdup(const_cast &>(record.value).value().c_str()); txt_records.push_back(it); } uint16_t port = const_cast &>(service.port).value(); err = mdns_service_add(nullptr, service.service_type.c_str(), service.proto.c_str(), port, txt_records.data(), txt_records.size()); // free records for (const auto &it : txt_records) { delete it.key; // NOLINT(cppcoreguidelines-owning-memory) delete it.value; // NOLINT(cppcoreguidelines-owning-memory) } if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to register service %s: %s", service.service_type.c_str(), esp_err_to_name(err)); } } } void MDNSComponent::on_shutdown() { mdns_free(); delay(40); // Allow the mdns packets announcing service removal to be sent } } // namespace mdns } // namespace esphome #endif // USE_ESP32