diff --git a/esphome/components/mdns/mdns_component.cpp b/esphome/components/mdns/mdns_component.cpp index 208f4e9cd4a..109b1a75ad2 100644 --- a/esphome/components/mdns/mdns_component.cpp +++ b/esphome/components/mdns/mdns_component.cpp @@ -35,7 +35,7 @@ MDNS_STATIC_CONST_CHAR(SERVICE_TCP, "_tcp"); // Wrap build-time defines into flash storage MDNS_STATIC_CONST_CHAR(VALUE_VERSION, ESPHOME_VERSION); -void MDNSComponent::compile_records_(StaticVector &services) { +void MDNSComponent::compile_records_(StaticVector &services, char *mac_address_buf) { // IMPORTANT: The #ifdef blocks below must match COMPONENTS_WITH_MDNS_SERVICES // in mdns/__init__.py. If you add a new service here, update both locations. @@ -86,7 +86,9 @@ void MDNSComponent::compile_records_(StaticVectormac_address_)}); + + // MAC address: passed as parameter from setup(), lives in caller's stack frame + txt_records.push_back({MDNS_STR(TXT_MAC), MDNS_STR(mac_address_buf)}); #ifdef USE_ESP8266 MDNS_STATIC_CONST_CHAR(PLATFORM_ESP8266, "ESP8266"); diff --git a/esphome/components/mdns/mdns_component.h b/esphome/components/mdns/mdns_component.h index 198d1f23aed..6d48d6382ac 100644 --- a/esphome/components/mdns/mdns_component.h +++ b/esphome/components/mdns/mdns_component.h @@ -70,14 +70,14 @@ class MDNSComponent : public Component { protected: /// Common setup logic called by all platform-specific setup() implementations - void on_setup_() { -#ifdef USE_API - // Populate MAC address buffer once during setup - get_mac_address_into_buffer(std::span(this->mac_address_)); + void on_setup_(char *mac_address_buf) { +#if defined(USE_API) && defined(USE_MDNS_STORE_SERVICES) + // Populate MAC address buffer once during setup (only needed if storing services) + get_mac_address_into_buffer(std::span(this->mac_address_)); #endif #ifdef USE_MDNS_STORE_SERVICES - this->compile_records_(this->services_); + this->compile_records_(this->services_, this->mac_address_); #endif } @@ -88,14 +88,14 @@ class MDNSComponent : public Component { StaticVector dynamic_txt_values_; #endif -#ifdef USE_API - /// Fixed buffer for MAC address (populated once in setup()) - char mac_address_[13]; // 12 hex chars + null terminator +#if defined(USE_API) && defined(USE_MDNS_STORE_SERVICES) + /// Fixed buffer for MAC address (only needed when services are stored) + char mac_address_[MAC_ADDRESS_BUFFER_SIZE]; #endif #ifdef USE_MDNS_STORE_SERVICES StaticVector services_{}; #endif - void compile_records_(StaticVector &services); + void compile_records_(StaticVector &services, char *mac_address_buf); }; } // namespace esphome::mdns diff --git a/esphome/components/mdns/mdns_esp32.cpp b/esphome/components/mdns/mdns_esp32.cpp index 1090ef53b59..4dfb4162496 100644 --- a/esphome/components/mdns/mdns_esp32.cpp +++ b/esphome/components/mdns/mdns_esp32.cpp @@ -12,13 +12,20 @@ namespace esphome::mdns { static const char *const TAG = "mdns"; void MDNSComponent::setup() { - this->on_setup_(); +#ifdef USE_API + char mac_address[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(std::span(mac_address)); +#else + char *mac_address = nullptr; +#endif + + this->on_setup_(mac_address); #ifdef USE_MDNS_STORE_SERVICES const auto &services = this->services_; #else StaticVector services; - this->compile_records_(services); + this->compile_records_(services, mac_address); #endif esp_err_t err = mdns_init(); diff --git a/esphome/components/mdns/mdns_esp8266.cpp b/esphome/components/mdns/mdns_esp8266.cpp index 14ba355f4a9..e70028d0758 100644 --- a/esphome/components/mdns/mdns_esp8266.cpp +++ b/esphome/components/mdns/mdns_esp8266.cpp @@ -12,13 +12,20 @@ namespace esphome::mdns { void MDNSComponent::setup() { - this->on_setup_(); +#ifdef USE_API + char mac_address[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(std::span(mac_address)); +#else + char *mac_address = nullptr; +#endif + + this->on_setup_(mac_address); #ifdef USE_MDNS_STORE_SERVICES const auto &services = this->services_; #else StaticVector services; - this->compile_records_(services); + this->compile_records_(services, mac_address); #endif MDNS.begin(App.get_name().c_str()); diff --git a/esphome/components/mdns/mdns_host.cpp b/esphome/components/mdns/mdns_host.cpp index c154b440490..1be0b721c56 100644 --- a/esphome/components/mdns/mdns_host.cpp +++ b/esphome/components/mdns/mdns_host.cpp @@ -9,7 +9,14 @@ namespace esphome::mdns { void MDNSComponent::setup() { - this->on_setup_(); +#ifdef USE_API + char mac_address[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(std::span(mac_address)); +#else + char *mac_address = nullptr; +#endif + + this->on_setup_(mac_address); // Host platform doesn't have actual mDNS implementation } diff --git a/esphome/components/mdns/mdns_libretiny.cpp b/esphome/components/mdns/mdns_libretiny.cpp index 2ee162ac2e1..04c6f8f89d2 100644 --- a/esphome/components/mdns/mdns_libretiny.cpp +++ b/esphome/components/mdns/mdns_libretiny.cpp @@ -12,13 +12,20 @@ namespace esphome::mdns { void MDNSComponent::setup() { - this->on_setup_(); +#ifdef USE_API + char mac_address[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(std::span(mac_address)); +#else + char *mac_address = nullptr; +#endif + + this->on_setup_(mac_address); #ifdef USE_MDNS_STORE_SERVICES const auto &services = this->services_; #else StaticVector services; - this->compile_records_(services); + this->compile_records_(services, mac_address); #endif MDNS.begin(App.get_name().c_str()); diff --git a/esphome/components/mdns/mdns_rp2040.cpp b/esphome/components/mdns/mdns_rp2040.cpp index 102e9eb3c29..10677b49eda 100644 --- a/esphome/components/mdns/mdns_rp2040.cpp +++ b/esphome/components/mdns/mdns_rp2040.cpp @@ -12,13 +12,20 @@ namespace esphome::mdns { void MDNSComponent::setup() { - this->on_setup_(); +#ifdef USE_API + char mac_address[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(std::span(mac_address)); +#else + char *mac_address = nullptr; +#endif + + this->on_setup_(mac_address); #ifdef USE_MDNS_STORE_SERVICES const auto &services = this->services_; #else StaticVector services; - this->compile_records_(services); + this->compile_records_(services, mac_address); #endif MDNS.begin(App.get_name().c_str()); diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 50af71649c5..17bab6b041a 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -638,17 +638,17 @@ std::string get_mac_address() { } std::string get_mac_address_pretty() { - char buf[18]; + char buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; return std::string(get_mac_address_pretty_into_buffer(buf)); } -void get_mac_address_into_buffer(std::span buf) { +void get_mac_address_into_buffer(std::span buf) { uint8_t mac[6]; get_mac_address_raw(mac); format_mac_addr_lower_no_sep(mac, buf.data()); } -const char *get_mac_address_pretty_into_buffer(std::span buf) { +const char *get_mac_address_pretty_into_buffer(std::span buf) { uint8_t mac[6]; get_mac_address_raw(mac); format_mac_addr_upper(mac, buf.data()); diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index d8c1f4647e7..27e127b1dea 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -1042,6 +1042,12 @@ class HighFrequencyLoopRequester { /// Get the device MAC address as raw bytes, written into the provided byte array (6 bytes). void get_mac_address_raw(uint8_t *mac); // NOLINT(readability-non-const-parameter) +/// Buffer size for MAC address in lowercase hex notation (12 hex chars + null terminator) +constexpr size_t MAC_ADDRESS_BUFFER_SIZE = 13; + +/// Buffer size for MAC address in colon-separated uppercase hex notation (17 chars + null terminator) +constexpr size_t MAC_ADDRESS_PRETTY_BUFFER_SIZE = 18; + /// Get the device MAC address as a string, in lowercase hex notation. std::string get_mac_address(); @@ -1049,13 +1055,14 @@ std::string get_mac_address(); std::string get_mac_address_pretty(); /// Get the device MAC address into the given buffer, in lowercase hex notation. -/// Assumes buffer length is 13 (12 digits for hexadecimal representation followed by null terminator). -void get_mac_address_into_buffer(std::span buf); +/// Assumes buffer length is MAC_ADDRESS_BUFFER_SIZE (12 digits for hexadecimal representation followed by null +/// terminator). +void get_mac_address_into_buffer(std::span buf); /// Get the device MAC address into the given buffer, in colon-separated uppercase hex notation. -/// Buffer must be exactly 18 bytes (17 for "XX:XX:XX:XX:XX:XX" + null terminator). +/// Buffer must be exactly MAC_ADDRESS_PRETTY_BUFFER_SIZE bytes (17 for "XX:XX:XX:XX:XX:XX" + null terminator). /// Returns pointer to the buffer for convenience. -const char *get_mac_address_pretty_into_buffer(std::span buf); +const char *get_mac_address_pretty_into_buffer(std::span buf); #ifdef USE_ESP32 /// Set the MAC address to use from the provided byte array (6 bytes).