ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
mdns_rp2.cpp
Go to the documentation of this file.
2#if defined(USE_RP2) && defined(USE_MDNS)
3
7#include "esphome/core/log.h"
8#include "mdns_component.h"
9// wifi_component.h / ethernet_component.h are pulled in transitively by
10// mdns_component.h when their respective listener defines are active.
11
12// Arduino-Pico's PolledTimeout.h (pulled in by ESP8266mDNS.h) redefines IRAM_ATTR to empty.
13#pragma push_macro("IRAM_ATTR")
14#undef IRAM_ATTR
15#include <ESP8266mDNS.h>
16#pragma pop_macro("IRAM_ATTR")
17
18namespace esphome::mdns {
19
20static void register_rp2(MDNSComponent *, StaticVector<MDNSService, MDNS_SERVICE_COUNT> &services) {
21 MDNS.begin(App.get_name().c_str());
22
23 for (const auto &service : services) {
24 // ESP8266mDNS always adds the leading underscore itself, so strip it here.
25 auto *proto = MDNS_STR_ARG(service.proto);
26 while (*proto == '_') {
27 proto++;
28 }
29 auto *service_type = MDNS_STR_ARG(service.service_type);
30 while (*service_type == '_') {
31 service_type++;
32 }
33 uint16_t port = service.port.value();
34 MDNS.addService(service_type, proto, port);
35 for (const auto &record : service.txt_records) {
36 MDNS.addServiceTxt(service_type, proto, MDNS_STR_ARG(record.key), MDNS_STR_ARG(record.value));
37 }
38 }
39}
40
41#ifdef USE_MDNS_EVENT_DRIVEN_POLLING
43 // uint32_t-ID set_interval/set_timeout already does atomic cancel-and-add.
44 this->set_interval(MDNS_POLL_ID, MDNS_UPDATE_INTERVAL_MS, []() { MDNS.update(); });
46}
47#endif
48
49#ifdef USE_MDNS_DYNAMIC_NETWORK_TXT
50ESPHOME_LOG_TAG(TAG, "mdns");
51
52bool MDNSComponent::publish_network_txt_(const char *network) {
53 // LEAmDNS replaces the value of an existing key; announce() sends the change
54 if (!MDNS.addServiceTxt("esphomelib", "tcp", "network", network)) {
55 ESP_LOGW(TAG, "Failed to update network TXT");
56 return false;
57 }
58 MDNS.announce();
60 return true;
61}
62#endif
63
65#ifdef USE_MDNS_DYNAMIC_NETWORK_TXT
66 // No-op until the first IP-up event registers the services
68 [this]() { this->update_network_txt_(this->connected_network_()); });
69#endif
70 // arduino-pico stubs out LwipIntf::stateUpCB (the netif status callback LEAmDNS uses
71 // on ESP8266 for auto-restart), so we must drive begin()/notifyAPChange() from our
72 // own IP state listener. Both WiFi and Ethernet have the same listener signature —
73 // one on_ip_state() override serves both.
74#ifdef USE_MDNS_WIFI_LISTENER
76 // AFTER_CONNECTION priority means the network may already be up; the listener only
77 // fires on subsequent changes, so seed the current state.
78 {
80 if (ips[0].is_set()) {
81 this->on_ip_state(ips, wifi::global_wifi_component->get_dns_address(0),
82 wifi::global_wifi_component->get_dns_address(1));
83 }
84 }
85#endif
86#ifdef USE_MDNS_ETHERNET_LISTENER
90 if (ips[0].is_set()) {
91 this->on_ip_state(ips, network::IPAddress{}, network::IPAddress{});
92 }
93 }
94#endif
95}
96
97#ifdef USE_MDNS_EVENT_DRIVEN_POLLING
98void MDNSComponent::on_ip_state(const network::IPAddresses &ips, const network::IPAddress &,
99 const network::IPAddress &) {
100 // Listener only fires on IP acquisition (not loss); every event is a fresh IP.
101 if (!ips[0].is_set()) {
102 return;
103 }
104 if (!this->initialized_) {
105 this->setup_buffers_and_register_(register_rp2);
106 this->initialized_ = true;
107 } else {
108 MDNS.notifyAPChange();
109 }
110 this->start_polling_window_();
111}
112#endif
113
115 MDNS.close();
116 delay(40);
117}
118
119} // namespace esphome::mdns
120
121#endif
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
bool cancel_interval(const char *name)
Cancel an interval function.
Definition component.cpp:92
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
Definition component.cpp:96
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
Definition component.cpp:88
constexpr const char * c_str() const
Definition string_ref.h:78
void add_ip_state_listener(EthernetIPStateListener *listener)
const char * connected_network_() const
The first connected interface in network: priority order ("ethernet" or "wifi"), else nullptr.
static constexpr uint32_t MDNS_POLL_STOP_ID
void start_polling_window_()
Arm a fresh MDNS_POLL_WINDOW_MS polling window.
void on_ip_state(const network::IPAddresses &ips, const network::IPAddress &dns1, const network::IPAddress &dns2) override
static constexpr uint32_t MDNS_POLL_WINDOW_MS
void setup_buffers_and_register_(PlatformRegisterFn platform_register)
void update_network_txt_(const char *network)
Publish network as the "network" TXT value if it changed; nullptr keeps the current value.
static constexpr uint32_t MDNS_POLL_ID
static constexpr uint32_t MDNS_UPDATE_INTERVAL_MS
static constexpr uint32_t NETWORK_TXT_CHECK_INTERVAL_MS
bool publish_network_txt_(const char *network)
Platform-specific: replace the "network" TXT value of the registered _esphomelib service.
void add_ip_state_listener(WiFiIPStateListener *listener)
Add a listener for IP state changes.
network::IPAddresses wifi_sta_ip_addresses()
EthernetComponent * global_eth_component
ESPHOME_LOG_TAG(TAG, "mdns")
std::array< IPAddress, 5 > IPAddresses
Definition ip_address.h:292
ESPHOME_ALWAYS_INLINE bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
Definition util.h:36
WiFiComponent * global_wifi_component
void HOT delay(uint32_t ms)
Definition hal.cpp:85
Application App
Global storage of Application pointer - only one Application can exist.