ESPHome 2026.3.0
Loading...
Searching...
No Matches
mdns_rp2040.cpp
Go to the documentation of this file.
2#if defined(USE_RP2040) && defined(USE_MDNS)
3
7#include "esphome/core/log.h"
8#include "mdns_component.h"
9
10// Arduino-Pico's PolledTimeout.h (pulled in by ESP8266mDNS.h) redefines IRAM_ATTR to empty.
11// Save and restore our definition around the include to avoid a redefinition warning.
12#pragma push_macro("IRAM_ATTR")
13#undef IRAM_ATTR
14#include <ESP8266mDNS.h>
15#pragma pop_macro("IRAM_ATTR")
16
17namespace esphome::mdns {
18
19static void register_rp2040(MDNSComponent *, StaticVector<MDNSService, MDNS_SERVICE_COUNT> &services) {
20 MDNS.begin(App.get_name().c_str());
21
22 for (const auto &service : services) {
23 // Strip the leading underscore from the proto and service_type. While it is
24 // part of the wire protocol to have an underscore, and for example ESP-IDF
25 // expects the underscore to be there, the ESP8266 implementation always adds
26 // the underscore itself.
27 auto *proto = MDNS_STR_ARG(service.proto);
28 while (*proto == '_') {
29 proto++;
30 }
31 auto *service_type = MDNS_STR_ARG(service.service_type);
32 while (*service_type == '_') {
33 service_type++;
34 }
35 uint16_t port = const_cast<TemplatableValue<uint16_t> &>(service.port).value();
36 MDNS.addService(service_type, proto, port);
37 for (const auto &record : service.txt_records) {
38 MDNS.addServiceTxt(service_type, proto, MDNS_STR_ARG(record.key), MDNS_STR_ARG(record.value));
39 }
40 }
41}
42
44 // RP2040's LEAmDNS library registers a LwipIntf::stateUpCB() callback to restart
45 // mDNS when the network interface reconnects. However, stateUpCB() is stubbed out
46 // in arduino-pico's LwipIntfCB.cpp because the original ESP8266 implementation used
47 // schedule_function() which doesn't exist in arduino-pico, and the callback can't
48 // safely run directly since netif status callbacks fire from IRQ context
49 // (PICO_CYW43_ARCH_THREADSAFE_BACKGROUND) while _restart() allocates UDP sockets.
50 //
51 // Workaround: defer MDNS.begin() and service registration until the network is
52 // connected (has an IP), then call notifyAPChange() on subsequent reconnects to
53 // restart mDNS probing and announcing — all from main loop context so it's
54 // thread-safe.
56 bool connected = network::is_connected();
57 if (connected && !this->was_connected_) {
58 if (!this->initialized_) {
59 this->setup_buffers_and_register_(register_rp2040);
60 this->initialized_ = true;
61 } else {
62 MDNS.notifyAPChange();
63 }
64 }
65 this->was_connected_ = connected;
66 if (this->initialized_) {
67 MDNS.update();
68 }
69 });
70}
71
73 MDNS.close();
74 delay(40);
75}
76
77} // namespace esphome::mdns
78
79#endif
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_interval(const std voi set_interval)(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
Definition component.h:358
constexpr const char * c_str() const
Definition string_ref.h:73
void setup_buffers_and_register_(PlatformRegisterFn platform_register)
static constexpr uint32_t MDNS_UPDATE_INTERVAL_MS
ESPHOME_ALWAYS_INLINE bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
Definition util.h:27
void HOT delay(uint32_t ms)
Definition core.cpp:28
Application App
Global storage of Application pointer - only one Application can exist.