ESPHome 2025.7.1
Loading...
Searching...
No Matches
helpers.cpp
Go to the documentation of this file.
3
4#ifdef USE_ESP32
5
6#include "esp_efuse.h"
7#include "esp_efuse_table.h"
8#include "esp_mac.h"
9
10#include <freertos/FreeRTOS.h>
11#include <freertos/portmacro.h>
12#include "esp_random.h"
13#include "esp_system.h"
14
15namespace esphome {
16
17uint32_t random_uint32() { return esp_random(); }
18bool random_bytes(uint8_t *data, size_t len) {
19 esp_fill_random(data, len);
20 return true;
21}
22
23Mutex::Mutex() { handle_ = xSemaphoreCreateMutex(); }
25void Mutex::lock() { xSemaphoreTake(this->handle_, portMAX_DELAY); }
26bool Mutex::try_lock() { return xSemaphoreTake(this->handle_, 0) == pdTRUE; }
27void Mutex::unlock() { xSemaphoreGive(this->handle_); }
28
29// only affects the executing core
30// so should not be used as a mutex lock, only to get accurate timing
31IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); }
32IRAM_ATTR InterruptLock::~InterruptLock() { portENABLE_INTERRUPTS(); }
33
34#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING
35#include "lwip/priv/tcpip_priv.h"
36#endif
37
39#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING
40 // When CONFIG_LWIP_TCPIP_CORE_LOCKING is enabled, lwIP uses a global mutex to protect
41 // its internal state. Any thread can take this lock to safely access lwIP APIs.
42 //
43 // sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER) returns true if the current thread
44 // already holds the lwIP core lock. This prevents recursive locking attempts and
45 // allows nested LwIPLock instances to work correctly.
46 //
47 // If we don't already hold the lock, acquire it. This will block until the lock
48 // is available if another thread currently holds it.
49 if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) {
50 LOCK_TCPIP_CORE();
51 }
52#endif
53}
54
56#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING
57 // Only release the lwIP core lock if this thread currently holds it.
58 //
59 // sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER) queries lwIP's internal lock
60 // ownership tracking. It returns true only if the current thread is registered
61 // as the lock holder.
62 //
63 // This check is essential because:
64 // 1. We may not have acquired the lock in the constructor (if we already held it)
65 // 2. The lock might have been released by other means between constructor and destructor
66 // 3. Calling UNLOCK_TCPIP_CORE() without holding the lock causes undefined behavior
67 if (sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) {
68 UNLOCK_TCPIP_CORE();
69 }
70#endif
71}
72
73void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
74#if defined(CONFIG_SOC_IEEE802154_SUPPORTED)
75 // When CONFIG_SOC_IEEE802154_SUPPORTED is defined, esp_efuse_mac_get_default
76 // returns the 802.15.4 EUI-64 address, so we read directly from eFuse instead.
78 esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM, mac, 48);
79 } else {
80 esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, mac, 48);
81 }
82#else
84 esp_efuse_mac_get_custom(mac);
85 } else {
86 esp_efuse_mac_get_default(mac);
87 }
88#endif
89}
90
91void set_mac_address(uint8_t *mac) { esp_base_mac_addr_set(mac); }
92
94#if !defined(USE_ESP32_IGNORE_EFUSE_CUSTOM_MAC)
95 uint8_t mac[6];
96 // do not use 'esp_efuse_mac_get_custom(mac)' because it drops an error in the logs whenever it fails
97#ifndef USE_ESP32_VARIANT_ESP32
98 return (esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA_MAC_CUSTOM, mac, 48) == ESP_OK) && mac_address_is_valid(mac);
99#else
100 return (esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM, mac, 48) == ESP_OK) && mac_address_is_valid(mac);
101#endif
102#else
103 return false;
104#endif
105}
106
107} // namespace esphome
108
109#endif // USE_ESP32
void unlock()
Definition helpers.cpp:27
bool try_lock()
Definition helpers.cpp:26
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
bool random_bytes(uint8_t *data, size_t len)
Generate len number of random bytes.
Definition helpers.cpp:18
bool mac_address_is_valid(const uint8_t *mac)
Check if the MAC address is not all zeros or all ones.
Definition helpers.cpp:601
std::string size_t len
Definition helpers.h:229
bool has_custom_mac_address()
Check if a custom MAC address is set (ESP32 & variants)
Definition helpers.cpp:93
void set_mac_address(uint8_t *mac)
Set the MAC address to use from the provided byte array (6 bytes).
Definition helpers.cpp:91
uint32_t random_uint32()
Return a random 32-bit unsigned integer.
Definition helpers.cpp:17
void get_mac_address_raw(uint8_t *mac)
Get the device MAC address as raw bytes, written into the provided byte array (6 bytes).
Definition helpers.cpp:73