ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
ipv4_resolve.h
Go to the documentation of this file.
1#pragma once
2
3#include "headers.h"
4
5#if defined(USE_SOCKET_IMPL_LWIP_TCP) || defined(USE_SOCKET_IMPL_LWIP_SOCKETS) || defined(USE_SOCKET_IMPL_BSD_SOCKETS)
6
7#include <cstdint>
8
9// MULTI_ATOMICS: one atomic state word, races closed by compare_exchange.
10// SINGLE: volatile state, the callback never runs beside loop().
11// MULTI_NO_ATOMICS: volatile state plus a generation; BK72xx has no
12// compare_exchange and the DNS callback runs on the tcpip thread.
13#if defined(ESPHOME_THREAD_MULTI_NO_ATOMICS)
14#define IPV4_RESOLVE_VOLATILE_EPOCH
15#elif defined(ESPHOME_THREAD_SINGLE)
16#define IPV4_RESOLVE_VOLATILE
17#else
18#define IPV4_RESOLVE_ATOMIC_STATE
19#include <atomic>
20#endif
21
22#if !defined(USE_HOST) && !defined(USE_ZEPHYR)
23#include "lwip/ip_addr.h"
24#endif
25
26namespace esphome::socket {
27
30 public:
31 static constexpr uint8_t STATE_IDLE = 0;
32 static constexpr uint8_t STATE_RESOLVING = 1;
33 static constexpr uint8_t STATE_RESOLVED = 2;
34 static constexpr uint8_t STATE_FAILED = 3;
35 // The callback holds this between winning the lookup and storing the address.
36 static constexpr uint8_t STATE_PUBLISHING = 4;
37
41 void forget();
43 bool consume_failure();
44 bool ready() const { return this->state_() == STATE_RESOLVED; }
46 socklen_t to_sockaddr(struct sockaddr *dest, socklen_t destlen, uint16_t port) const;
49 void start(const char *host, uint16_t port, const char *tag);
50
51 private:
52#if !defined(USE_HOST) && !defined(USE_ZEPHYR)
53 static void dns_found(const char *name, const ip_addr_t *addr, void *arg);
54#if defined(IPV4_RESOLVE_VOLATILE_EPOCH)
55 bool drop_stale_(uint32_t expected);
56#endif
57#endif
58 uint8_t state_() const {
59#if defined(IPV4_RESOLVE_ATOMIC_STATE)
60 return this->state_word_.load();
61#else
62 return this->state_word_;
63#endif
64 }
65 uint32_t addr_() const {
66#if defined(IPV4_RESOLVE_ATOMIC_STATE)
67 return this->addr_word_.load();
68#else
69 return this->addr_word_;
70#endif
71 }
72 void set_state_(uint8_t state) {
73#if defined(IPV4_RESOLVE_ATOMIC_STATE)
74 this->state_word_.store(state);
75#else
76 this->state_word_ = state;
77#endif
78 }
79 void set_addr_(uint32_t addr) {
80#if defined(IPV4_RESOLVE_ATOMIC_STATE)
81 this->addr_word_.store(addr);
82#else
83 this->addr_word_ = addr;
84#endif
85 }
86 const char *tag_{nullptr};
87#if defined(IPV4_RESOLVE_ATOMIC_STATE)
88 std::atomic<uint32_t> addr_word_{0};
89 std::atomic<uint8_t> state_word_{STATE_IDLE};
90#elif defined(IPV4_RESOLVE_VOLATILE_EPOCH)
91 volatile uint32_t addr_word_{0};
92 volatile uint32_t epoch_{0};
93 volatile uint32_t pending_epoch_{0};
94 volatile uint8_t state_word_{STATE_IDLE};
95#else
96 volatile uint32_t addr_word_{0};
97 volatile uint8_t state_word_{STATE_IDLE};
98#endif
99};
100
101} // namespace esphome::socket
102
103#endif
One IPv4 literal or hostname. Must outlive a pending lookup.
void start(const char *host, uint16_t port, const char *tag)
Resolve host; tag names the failure log.
bool consume_failure()
Drop a failed lookup so the next start() tries again.
static constexpr uint8_t STATE_RESOLVED
static constexpr uint8_t STATE_RESOLVING
socklen_t to_sockaddr(struct sockaddr *dest, socklen_t destlen, uint16_t port) const
Write the stored address into dest. Returns 0 until ready() is true.
static constexpr uint8_t STATE_IDLE
static constexpr uint8_t STATE_FAILED
static constexpr uint8_t STATE_PUBLISHING
void forget()
Drop the stored address so the next start() resolves again.
bool state
Definition fan.h:2
uint32_t socklen_t
Definition headers.h:109
static void uint32_t