[openthread] Cache is_connected() for cheap inline access (#14484)

Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
rwrozelle
2026-03-04 17:34:13 -10:00
committed by GitHub
co-authored by J. Nick Koston
parent f5c37bf486
commit 0e2a10c5f0
3 changed files with 15 additions and 18 deletions
+8 -17
View File
@@ -1,9 +1,7 @@
#include "esphome/core/defines.h"
#ifdef USE_OPENTHREAD
#include "openthread.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
#include "esp_openthread.h"
#endif
#include <freertos/portmacro.h>
@@ -48,22 +46,15 @@ void OpenThreadComponent::dump_config() {
}
}
bool OpenThreadComponent::is_connected() {
auto lock = InstanceLock::try_acquire(100);
if (!lock) {
ESP_LOGW(TAG, "Failed to acquire OpenThread lock in is_connected");
return false;
void OpenThreadComponent::on_state_changed_(otChangedFlags flags, void *context) {
if (flags & OT_CHANGED_THREAD_ROLE) {
auto *self = static_cast<OpenThreadComponent *>(context);
// This runs on the OpenThread task thread with the OT lock held,
// so we can safely call otThreadGetDeviceRole directly.
otInstance *instance = esp_openthread_get_instance();
otDeviceRole role = otThreadGetDeviceRole(instance);
self->connected_ = role >= OT_DEVICE_ROLE_CHILD;
}
otInstance *instance = lock->get_instance();
if (instance == nullptr) {
return false;
}
otDeviceRole role = otThreadGetDeviceRole(instance);
// TODO: If we're a leader, check that there is at least 1 known peer
return role >= OT_DEVICE_ROLE_CHILD;
}
// Gets the off-mesh routable address
+4 -1
View File
@@ -8,6 +8,7 @@
#include <openthread/srp_client.h>
#include <openthread/srp_client_buffers.h>
#include <openthread/instance.h>
#include <openthread/thread.h>
#include <optional>
@@ -26,7 +27,7 @@ class OpenThreadComponent : public Component {
bool teardown() override;
float get_setup_priority() const override { return setup_priority::WIFI; }
bool is_connected();
bool is_connected() const { return this->connected_; }
network::IPAddresses get_ip_addresses();
std::optional<otIp6Address> get_omr_address();
void ot_main();
@@ -42,6 +43,7 @@ class OpenThreadComponent : public Component {
protected:
std::optional<otIp6Address> get_omr_address_(InstanceLock &lock);
static void on_state_changed_(otChangedFlags flags, void *context);
std::function<void()> factory_reset_external_callback_;
#if CONFIG_OPENTHREAD_MTD
uint32_t poll_period_{0};
@@ -49,6 +51,7 @@ class OpenThreadComponent : public Component {
std::optional<int8_t> output_power_{};
bool teardown_started_{false};
bool teardown_complete_{false};
bool connected_{false};
private:
// Stores a pointer to a string literal (static storage duration).
@@ -175,6 +175,9 @@ void OpenThreadComponent::ot_main() {
// Pass the existing dataset, or NULL which will use the preprocessor definitions
ESP_ERROR_CHECK(esp_openthread_auto_start(dataset.mLength > 0 ? &dataset : nullptr));
// Register state change callback to update connected_ reactively instead of polling
otSetStateChangedCallback(instance, OpenThreadComponent::on_state_changed_, this);
esp_openthread_launch_mainloop();
// Clean up