7#ifdef USE_OPENTHREAD_BORDER_ROUTER
13#include <openthread/srp_client.h>
14#include <openthread/srp_client_buffers.h>
15#include <openthread/instance.h>
16#include <openthread/thread.h>
26enum class TeardownStage : uint8_t {
27 TEARDOWN_STAGE_NOT_STARTED = 0,
28 TEARDOWN_STAGE_STOP_IN_PROCESS,
29 TEARDOWN_STAGE_COMPLETED,
32#ifdef USE_OPENTHREAD_BORDER_ROUTER
33class OpenThreadComponent final :
public Component,
public wifi::WiFiConnectStateListener {
35class OpenThreadComponent final :
public Component {
38 OpenThreadComponent();
39#ifdef USE_OPENTHREAD_RCP_UART
40 OpenThreadComponent(
uint32_t rcp_baud_rate, uint8_t rcp_rx_pin, uint8_t rcp_tx_pin, GPIOPin *rcp_reset_pin);
42 ~OpenThreadComponent();
43 void dump_config()
override;
44 void setup()
override;
45#ifdef USE_OPENTHREAD_BORDER_ROUTER
48 void on_wifi_connect_state(StringRef ssid, std::span<const uint8_t, 6> bssid)
override { this->enable_loop(); }
50 bool teardown()
override;
51 float get_setup_priority()
const override {
52#ifdef USE_OPENTHREAD_BORDER_ROUTER
54 return setup_priority::BEFORE_CONNECTION;
56 return setup_priority::WIFI;
62 bool is_lock_initialized()
const {
return this->lock_initialized_; }
65 bool is_task_exited()
const {
return this->task_exited_; }
68 std::optional<otIp6Address> get_omr_address();
69 void on_factory_reset(
const std::function<
void()> &callback);
70#ifdef USE_OPENTHREAD_SRP
71 void defer_factory_reset_external_callback();
76 const char *get_use_address()
const {
return this->use_address_; }
77 void set_use_address(
const char *use_address) { this->use_address_ = use_address; }
78#if CONFIG_OPENTHREAD_MTD
79 void set_poll_period(
uint32_t poll_period) { this->poll_period_ = poll_period; }
80 uint32_t get_poll_period()
const {
return this->poll_period_; }
83 void apply_poll_period(
uint32_t poll_period);
84 void set_output_power(int8_t output_power) { this->output_power_ = output_power; }
85 void set_connected(
bool connected) { this->connected_ = connected; }
86 static void on_state_changed(otChangedFlags
flags,
void *context);
87#ifdef USE_OPENTHREAD_RCP_UART
88 static void rcp_failure_handler();
95 void apply_linkmode_(otInstance *instance);
98 void mark_task_failed_(
const LogString *reason);
100#ifdef USE_OPENTHREAD_RCP_UART
101 void reset_rcp_(
bool recovery_attempt);
104 std::optional<otIp6Address> get_omr_address_(InstanceLock &
lock);
105 otInstance *get_openthread_instance_();
106 int openthread_stop_();
107#ifdef USE_OPENTHREAD_SRP
108 std::function<void()> factory_reset_external_callback_;
110#if CONFIG_OPENTHREAD_MTD
113 std::optional<int8_t> output_power_{};
114 std::atomic<bool> lock_initialized_{
false};
115 std::atomic<TeardownStage> teardown_stage_{TeardownStage::TEARDOWN_STAGE_NOT_STARTED};
116 std::atomic<bool> connected_{
false};
118 std::atomic<bool> task_exited_{
false};
120#ifdef USE_OPENTHREAD_RCP_UART
122 uint8_t rcp_rx_pin_{0};
123 uint8_t rcp_tx_pin_{0};
124 GPIOPin *rcp_reset_pin_{
nullptr};
126 uint8_t rcp_reset_attempts_{0};
128 static constexpr uint32_t RCP_RESET_FORGET_MS = 10 * 60 * 1000;
130#ifdef USE_OPENTHREAD_BORDER_ROUTER
131 std::atomic<bool> mainloop_running_{
false};
132 bool border_router_started_{
false};
133 bool backbone_up_{
false};
139 const char *use_address_{
nullptr};
144#ifdef USE_OPENTHREAD_SRP
145class OpenThreadSrpComponent final :
public Component {
149 float get_setup_priority()
const override {
return this->mdns_->
get_setup_priority() - 1.0f; }
150 void setup()
override;
151 static void srp_callback(otError err,
const otSrpClientHostInfo *host_info,
const otSrpClientService *services,
152 const otSrpClientService *removed_services,
void *context);
153 static void srp_start_callback(
const otSockAddr *server_socket_address,
void *context);
154 static void srp_factory_reset_callback(otError err,
const otSrpClientHostInfo *host_info,
155 const otSrpClientService *services,
const otSrpClientService *removed_services,
160 std::vector<std::unique_ptr<uint8_t[]>> memory_pool_;
161 void *pool_alloc_(
size_t size);
173 static InstanceLock try_acquire(
int delay);
175 static InstanceLock acquire();
176 InstanceLock(
const InstanceLock &) =
delete;
177 InstanceLock(InstanceLock &&) =
delete;
178 InstanceLock &operator=(
const InstanceLock &) =
delete;
179 InstanceLock &operator=(InstanceLock &&) =
delete;
182 explicit operator bool()
const {
return this->owns_; }
186 otInstance *get_instance();
189 explicit InstanceLock(
bool owns) : owns_(owns) {}
float get_setup_priority() const override
void delay(unsigned long ms)
ESPHOME_ALWAYS_INLINE bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
network::IPAddresses get_ip_addresses()
OpenThreadComponent * global_openthread_component