1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-12 06:43:48 +01:00

[mdns][openthread] Use std::array for mdns services and remove unnecessary copy

This commit is contained in:
J. Nick Koston
2025-10-01 22:21:58 +02:00
parent 08afc3030a
commit a9dc0628c4
5 changed files with 58 additions and 50 deletions

View File

@@ -91,12 +91,36 @@ async def to_code(config):
cg.add_define("USE_MDNS") cg.add_define("USE_MDNS")
# Calculate compile-time service count
service_count = 0
# Check if API component is enabled (it may create a service at runtime)
if cg.is_defined("USE_API"):
service_count += 1
# Check for prometheus
if cg.is_defined("USE_PROMETHEUS"):
service_count += 1
# Check for web_server
if cg.is_defined("USE_WEBSERVER"):
service_count += 1
# Count extra services from config
extra_services_count = len(config[CONF_SERVICES])
if extra_services_count > 0:
service_count += extra_services_count
cg.add_define("USE_MDNS_EXTRA_SERVICES")
# Ensure at least 1 service (fallback service)
if service_count == 0:
service_count = 1
cg.add_define("MDNS_SERVICE_COUNT", service_count)
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config) await cg.register_component(var, config)
if config[CONF_SERVICES]:
cg.add_define("USE_MDNS_EXTRA_SERVICES")
for service in config[CONF_SERVICES]: for service in config[CONF_SERVICES]:
txt = [ txt = [
cg.StructInitializer( cg.StructInitializer(

View File

@@ -73,33 +73,11 @@ MDNS_STATIC_CONST_CHAR(NETWORK_THREAD, "thread");
void MDNSComponent::compile_records_() { void MDNSComponent::compile_records_() {
this->hostname_ = App.get_name(); this->hostname_ = App.get_name();
this->services_count_ = 0;
// Calculate exact capacity needed for services vector
size_t services_count = 0;
#ifdef USE_API
if (api::global_api_server != nullptr) {
services_count++;
}
#endif
#ifdef USE_PROMETHEUS
services_count++;
#endif
#ifdef USE_WEBSERVER
services_count++;
#endif
#ifdef USE_MDNS_EXTRA_SERVICES
services_count += this->services_extra_.size();
#endif
// Reserve for fallback service if needed
if (services_count == 0) {
services_count = 1;
}
this->services_.reserve(services_count);
#ifdef USE_API #ifdef USE_API
if (api::global_api_server != nullptr) { if (api::global_api_server != nullptr) {
this->services_.emplace_back(); auto &service = this->services_[this->services_count_++];
auto &service = this->services_.back();
service.service_type = MDNS_STR(SERVICE_ESPHOMELIB); service.service_type = MDNS_STR(SERVICE_ESPHOMELIB);
service.proto = MDNS_STR(SERVICE_TCP); service.proto = MDNS_STR(SERVICE_TCP);
service.port = api::global_api_server->get_port(); service.port = api::global_api_server->get_port();
@@ -178,30 +156,29 @@ void MDNSComponent::compile_records_() {
#endif // USE_API #endif // USE_API
#ifdef USE_PROMETHEUS #ifdef USE_PROMETHEUS
this->services_.emplace_back(); auto &prom_service = this->services_[this->services_count_++];
auto &prom_service = this->services_.back();
prom_service.service_type = MDNS_STR(SERVICE_PROMETHEUS); prom_service.service_type = MDNS_STR(SERVICE_PROMETHEUS);
prom_service.proto = MDNS_STR(SERVICE_TCP); prom_service.proto = MDNS_STR(SERVICE_TCP);
prom_service.port = USE_WEBSERVER_PORT; prom_service.port = USE_WEBSERVER_PORT;
#endif #endif
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
this->services_.emplace_back(); auto &web_service = this->services_[this->services_count_++];
auto &web_service = this->services_.back();
web_service.service_type = MDNS_STR(SERVICE_HTTP); web_service.service_type = MDNS_STR(SERVICE_HTTP);
web_service.proto = MDNS_STR(SERVICE_TCP); web_service.proto = MDNS_STR(SERVICE_TCP);
web_service.port = USE_WEBSERVER_PORT; web_service.port = USE_WEBSERVER_PORT;
#endif #endif
#ifdef USE_MDNS_EXTRA_SERVICES #ifdef USE_MDNS_EXTRA_SERVICES
this->services_.insert(this->services_.end(), this->services_extra_.begin(), this->services_extra_.end()); for (const auto &extra_service : this->services_extra_) {
this->services_[this->services_count_++] = extra_service;
}
#endif #endif
#if !defined(USE_API) && !defined(USE_PROMETHEUS) && !defined(USE_WEBSERVER) && !defined(USE_MDNS_EXTRA_SERVICES) #if !defined(USE_API) && !defined(USE_PROMETHEUS) && !defined(USE_WEBSERVER) && !defined(USE_MDNS_EXTRA_SERVICES)
// Publish "http" service if not using native API or any other services // Publish "http" service if not using native API or any other services
// This is just to have *some* mDNS service so that .local resolution works // This is just to have *some* mDNS service so that .local resolution works
this->services_.emplace_back(); auto &fallback_service = this->services_[this->services_count_++];
auto &fallback_service = this->services_.back();
fallback_service.service_type = "_http"; fallback_service.service_type = "_http";
fallback_service.proto = "_tcp"; fallback_service.proto = "_tcp";
fallback_service.port = USE_WEBSERVER_PORT; fallback_service.port = USE_WEBSERVER_PORT;
@@ -209,6 +186,12 @@ void MDNSComponent::compile_records_() {
#endif #endif
} }
#ifdef USE_MDNS_EXTRA_SERVICES
void MDNSComponent::add_extra_service(MDNSService service) {
this->services_[this->services_count_++] = std::move(service);
}
#endif
void MDNSComponent::dump_config() { void MDNSComponent::dump_config() {
ESP_LOGCONFIG(TAG, ESP_LOGCONFIG(TAG,
"mDNS:\n" "mDNS:\n"
@@ -216,7 +199,8 @@ void MDNSComponent::dump_config() {
this->hostname_.c_str()); this->hostname_.c_str());
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
ESP_LOGV(TAG, " Services:"); ESP_LOGV(TAG, " Services:");
for (const auto &service : this->services_) { for (uint8_t i = 0; i < this->services_count_; i++) {
const auto &service = this->services_[i];
ESP_LOGV(TAG, " - %s, %s, %d", service.service_type.c_str(), service.proto.c_str(), ESP_LOGV(TAG, " - %s, %s, %d", service.service_type.c_str(), service.proto.c_str(),
const_cast<TemplatableValue<uint16_t> &>(service.port).value()); const_cast<TemplatableValue<uint16_t> &>(service.port).value());
for (const auto &record : service.txt_records) { for (const auto &record : service.txt_records) {
@@ -227,8 +211,6 @@ void MDNSComponent::dump_config() {
#endif #endif
} }
std::vector<MDNSService> MDNSComponent::get_services() { return this->services_; }
} // namespace mdns } // namespace mdns
} // namespace esphome } // namespace esphome
#endif #endif

View File

@@ -1,14 +1,17 @@
#pragma once #pragma once
#include "esphome/core/defines.h" #include "esphome/core/defines.h"
#ifdef USE_MDNS #ifdef USE_MDNS
#include <array>
#include <string> #include <string>
#include <vector>
#include "esphome/core/automation.h" #include "esphome/core/automation.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
namespace esphome { namespace esphome {
namespace mdns { namespace mdns {
// Service count is calculated at compile time by Python codegen
// MDNS_SERVICE_COUNT will always be defined
struct MDNSTXTRecord { struct MDNSTXTRecord {
std::string key; std::string key;
TemplatableValue<std::string> value; TemplatableValue<std::string> value;
@@ -36,18 +39,17 @@ class MDNSComponent : public Component {
float get_setup_priority() const override { return setup_priority::AFTER_CONNECTION; } float get_setup_priority() const override { return setup_priority::AFTER_CONNECTION; }
#ifdef USE_MDNS_EXTRA_SERVICES #ifdef USE_MDNS_EXTRA_SERVICES
void add_extra_service(MDNSService service) { services_extra_.push_back(std::move(service)); } void add_extra_service(MDNSService service);
#endif #endif
std::vector<MDNSService> get_services(); const std::array<MDNSService, MDNS_SERVICE_COUNT> &get_services() const { return services_; }
uint8_t get_services_count() const { return services_count_; }
void on_shutdown() override; void on_shutdown() override;
protected: protected:
#ifdef USE_MDNS_EXTRA_SERVICES std::array<MDNSService, MDNS_SERVICE_COUNT> services_{};
std::vector<MDNSService> services_extra_{}; uint8_t services_count_{0};
#endif
std::vector<MDNSService> services_{};
std::string hostname_; std::string hostname_;
void compile_records_(); void compile_records_();
}; };

View File

@@ -143,11 +143,12 @@ void OpenThreadSrpComponent::setup() {
return; return;
} }
// Copy the mdns services to our local instance so that the c_str pointers remain valid for the lifetime of this // Use mdns services directly - they remain valid for the lifetime of the mdns component
// component const auto &mdns_services = this->mdns_->get_services();
this->mdns_services_ = this->mdns_->get_services(); uint8_t mdns_count = this->mdns_->get_services_count();
ESP_LOGD(TAG, "Setting up SRP services. count = %d\n", this->mdns_services_.size()); ESP_LOGD(TAG, "Setting up SRP services. count = %d\n", mdns_count);
for (const auto &service : this->mdns_services_) { for (uint8_t i = 0; i < mdns_count; i++) {
const auto &service = mdns_services[i];
otSrpClientBuffersServiceEntry *entry = otSrpClientBuffersAllocateService(instance); otSrpClientBuffersServiceEntry *entry = otSrpClientBuffersAllocateService(instance);
if (!entry) { if (!entry) {
ESP_LOGW(TAG, "Failed to allocate service entry"); ESP_LOGW(TAG, "Failed to allocate service entry");

View File

@@ -57,7 +57,6 @@ class OpenThreadSrpComponent : public Component {
protected: protected:
esphome::mdns::MDNSComponent *mdns_{nullptr}; esphome::mdns::MDNSComponent *mdns_{nullptr};
std::vector<esphome::mdns::MDNSService> mdns_services_;
std::vector<std::unique_ptr<uint8_t[]>> memory_pool_; std::vector<std::unique_ptr<uint8_t[]>> memory_pool_;
void *pool_alloc_(size_t size); void *pool_alloc_(size_t size);
}; };