diff --git a/esphome/components/debug/debug_zephyr.cpp b/esphome/components/debug/debug_zephyr.cpp index 85880595b6..3f9af03b2b 100644 --- a/esphome/components/debug/debug_zephyr.cpp +++ b/esphome/components/debug/debug_zephyr.cpp @@ -322,6 +322,8 @@ size_t DebugComponent::get_device_info_(std::span return "Unspecified"; }; + char mac_pretty[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + get_mac_address_pretty_into_buffer(mac_pretty); ESP_LOGD(TAG, "Code page size: %u, code size: %u, device id: 0x%08x%08x\n" "Encryption root: 0x%08x%08x%08x%08x, Identity Root: 0x%08x%08x%08x%08x\n" @@ -330,10 +332,10 @@ size_t DebugComponent::get_device_info_(std::span "RAM: %ukB, Flash: %ukB, production test: %sdone", NRF_FICR->CODEPAGESIZE, NRF_FICR->CODESIZE, NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0], NRF_FICR->ER[0], NRF_FICR->ER[1], NRF_FICR->ER[2], NRF_FICR->ER[3], NRF_FICR->IR[0], NRF_FICR->IR[1], NRF_FICR->IR[2], - NRF_FICR->IR[3], (NRF_FICR->DEVICEADDRTYPE & 0x1 ? "Random" : "Public"), get_mac_address_pretty().c_str(), - NRF_FICR->INFO.PART, NRF_FICR->INFO.VARIANT >> 24 & 0xFF, NRF_FICR->INFO.VARIANT >> 16 & 0xFF, - NRF_FICR->INFO.VARIANT >> 8 & 0xFF, NRF_FICR->INFO.VARIANT & 0xFF, package(NRF_FICR->INFO.PACKAGE), - NRF_FICR->INFO.RAM, NRF_FICR->INFO.FLASH, (NRF_FICR->PRODTEST[0] == 0xBB42319F ? "" : "not ")); + NRF_FICR->IR[3], (NRF_FICR->DEVICEADDRTYPE & 0x1 ? "Random" : "Public"), mac_pretty, NRF_FICR->INFO.PART, + NRF_FICR->INFO.VARIANT >> 24 & 0xFF, NRF_FICR->INFO.VARIANT >> 16 & 0xFF, NRF_FICR->INFO.VARIANT >> 8 & 0xFF, + NRF_FICR->INFO.VARIANT & 0xFF, package(NRF_FICR->INFO.PACKAGE), NRF_FICR->INFO.RAM, NRF_FICR->INFO.FLASH, + (NRF_FICR->PRODTEST[0] == 0xBB42319F ? "" : "not ")); bool n_reset_enabled = NRF_UICR->PSELRESET[0] == NRF_UICR->PSELRESET[1] && (NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) == UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos; diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index 652f55734b..0ab5b238b5 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -28,8 +28,9 @@ static const char *const TAG = "mqtt"; MQTTClientComponent::MQTTClientComponent() { global_mqtt_client = this; - const std::string mac_addr = get_mac_address(); - this->credentials_.client_id = make_name_with_suffix(App.get_name(), '-', mac_addr.c_str(), mac_addr.size()); + char mac_addr[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(mac_addr); + this->credentials_.client_id = make_name_with_suffix(App.get_name(), '-', mac_addr, MAC_ADDRESS_BUFFER_SIZE - 1); } // Connection @@ -102,7 +103,9 @@ void MQTTClientComponent::send_device_info_() { root[ESPHOME_F("port")] = api::global_api_server->get_port(); #endif root[ESPHOME_F("version")] = ESPHOME_VERSION; - root[ESPHOME_F("mac")] = get_mac_address(); + char mac_buf[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(mac_buf); + root[ESPHOME_F("mac")] = mac_buf; #ifdef USE_ESP8266 root[ESPHOME_F("platform")] = ESPHOME_F("ESP8266"); diff --git a/esphome/components/mqtt/mqtt_component.cpp b/esphome/components/mqtt/mqtt_component.cpp index d838d1789f..40eb15acdd 100644 --- a/esphome/components/mqtt/mqtt_component.cpp +++ b/esphome/components/mqtt/mqtt_component.cpp @@ -187,7 +187,13 @@ bool MQTTComponent::send_discovery_() { char friendly_name_hash[9]; sprintf(friendly_name_hash, "%08" PRIx32, fnv1_hash(this->friendly_name_())); friendly_name_hash[8] = 0; // ensure the hash-string ends with null - root[MQTT_UNIQUE_ID] = get_mac_address() + "-" + this->component_type() + "-" + friendly_name_hash; + // Format: mac-component_type-hash (e.g. "aabbccddeeff-sensor-12345678") + // MAC (12) + "-" (1) + domain (max 20) + "-" (1) + hash (8) + null (1) = 43 + char unique_id[MAC_ADDRESS_BUFFER_SIZE + ESPHOME_DOMAIN_MAX_LEN + 11]; + char mac_buf[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(mac_buf); + snprintf(unique_id, sizeof(unique_id), "%s-%s-%s", mac_buf, this->component_type(), friendly_name_hash); + root[MQTT_UNIQUE_ID] = unique_id; } else { // default to almost-unique ID. It's a hack but the only way to get that // gorgeous device registry view. @@ -203,7 +209,8 @@ bool MQTTComponent::send_discovery_() { std::string node_area = App.get_area(); JsonObject device_info = root[MQTT_DEVICE].to(); - const auto mac = get_mac_address(); + char mac[MAC_ADDRESS_BUFFER_SIZE]; + get_mac_address_into_buffer(mac); device_info[MQTT_DEVICE_IDENTIFIERS] = mac; device_info[MQTT_DEVICE_NAME] = node_friendly_name; #ifdef ESPHOME_PROJECT_NAME diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 396a58464f..8847586f0a 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -1306,9 +1306,13 @@ class HighFrequencyLoopRequester { void get_mac_address_raw(uint8_t *mac); // NOLINT(readability-non-const-parameter) /// Get the device MAC address as a string, in lowercase hex notation. +/// @warning Allocates heap memory. Avoid in new code - causes heap fragmentation on long-running devices. +/// Use get_mac_address_into_buffer() instead. std::string get_mac_address(); /// Get the device MAC address as a string, in colon-separated uppercase hex notation. +/// @warning Allocates heap memory. Avoid in new code - causes heap fragmentation on long-running devices. +/// Use get_mac_address_pretty_into_buffer() instead. std::string get_mac_address_pretty(); /// Get the device MAC address into the given buffer, in lowercase hex notation.