diff --git a/esphome/components/mdns/mdns_component.cpp b/esphome/components/mdns/mdns_component.cpp index 8b93c486a7..47db92610a 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 from caller (either member buffer or stack buffer depending on USE_MDNS_STORE_SERVICES) + 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 198d1f23ae..d0659abdbf 100644 --- a/esphome/components/mdns/mdns_component.h +++ b/esphome/components/mdns/mdns_component.h @@ -70,14 +70,15 @@ 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_)); -#endif - + void on_setup_(char *mac_address_buf) { #ifdef USE_MDNS_STORE_SERVICES - this->compile_records_(this->services_); +#ifdef USE_API + // Copy to member buffer for storage + std::memcpy(this->mac_address_, mac_address_buf, MAC_ADDRESS_BUFFER_SIZE); + this->compile_records_(this->services_, this->mac_address_); +#else + this->compile_records_(this->services_, mac_address_buf); +#endif #endif } @@ -88,14 +89,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 1090ef53b5..4dfb416249 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 14ba355f4a..e70028d075 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 c154b44049..1be0b721c5 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 2ee162ac2e..04c6f8f89d 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 102e9eb3c2..10677b49ed 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 38efce1187..5e6e637a1d 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -640,17 +640,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 d3bec31efa..79e537153e 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -1123,6 +1123,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(); @@ -1130,13 +1136,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).