1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-14 17:22:20 +01:00

Openthread Fix Factory Reset (#9281)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
rwrozelle
2025-09-11 01:23:58 -04:00
committed by GitHub
parent c45efe8f40
commit 625f108183
6 changed files with 99 additions and 11 deletions

View File

@@ -1,7 +1,13 @@
#include "factory_reset_button.h"
#include "esphome/core/defines.h"
#ifdef USE_OPENTHREAD
#include "esphome/components/openthread/openthread.h"
#endif
#include "esphome/core/application.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
#include "esphome/core/application.h"
namespace esphome {
namespace factory_reset {
@@ -13,9 +19,20 @@ void FactoryResetButton::press_action() {
ESP_LOGI(TAG, "Resetting");
// Let MQTT settle a bit
delay(100); // NOLINT
#ifdef USE_OPENTHREAD
openthread::global_openthread_component->on_factory_reset(FactoryResetButton::factory_reset_callback);
#else
global_preferences->reset();
App.safe_reboot();
#endif
}
#ifdef USE_OPENTHREAD
void FactoryResetButton::factory_reset_callback() {
global_preferences->reset();
App.safe_reboot();
}
#endif
} // namespace factory_reset
} // namespace esphome

View File

@@ -1,7 +1,9 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#include "esphome/components/button/button.h"
#include "esphome/core/component.h"
namespace esphome {
namespace factory_reset {
@@ -9,6 +11,9 @@ namespace factory_reset {
class FactoryResetButton : public button::Button, public Component {
public:
void dump_config() override;
#ifdef USE_OPENTHREAD
static void factory_reset_callback();
#endif
protected:
void press_action() override;

View File

@@ -1,7 +1,13 @@
#include "factory_reset_switch.h"
#include "esphome/core/defines.h"
#ifdef USE_OPENTHREAD
#include "esphome/components/openthread/openthread.h"
#endif
#include "esphome/core/application.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
#include "esphome/core/application.h"
namespace esphome {
namespace factory_reset {
@@ -17,10 +23,21 @@ void FactoryResetSwitch::write_state(bool state) {
ESP_LOGI(TAG, "Resetting");
// Let MQTT settle a bit
delay(100); // NOLINT
#ifdef USE_OPENTHREAD
openthread::global_openthread_component->on_factory_reset(FactoryResetSwitch::factory_reset_callback);
#else
global_preferences->reset();
App.safe_reboot();
#endif
}
}
#ifdef USE_OPENTHREAD
void FactoryResetSwitch::factory_reset_callback() {
global_preferences->reset();
App.safe_reboot();
}
#endif
} // namespace factory_reset
} // namespace esphome

View File

@@ -1,7 +1,8 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/switch/switch.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
namespace esphome {
namespace factory_reset {
@@ -9,6 +10,9 @@ namespace factory_reset {
class FactoryResetSwitch : public switch_::Switch, public Component {
public:
void dump_config() override;
#ifdef USE_OPENTHREAD
static void factory_reset_callback();
#endif
protected:
void write_state(bool state) override;

View File

@@ -11,8 +11,6 @@
#include <openthread/instance.h>
#include <openthread/logging.h>
#include <openthread/netdata.h>
#include <openthread/srp_client.h>
#include <openthread/srp_client_buffers.h>
#include <openthread/tasklet.h>
#include <cstring>
@@ -77,7 +75,13 @@ std::optional<otIp6Address> OpenThreadComponent::get_omr_address_(InstanceLock &
return {};
}
void srp_callback(otError err, const otSrpClientHostInfo *host_info, const otSrpClientService *services,
void OpenThreadComponent::defer_factory_reset_external_callback() {
ESP_LOGD(TAG, "Defer factory_reset_external_callback_");
this->defer([this]() { this->factory_reset_external_callback_(); });
}
void OpenThreadSrpComponent::srp_callback(otError err, const otSrpClientHostInfo *host_info,
const otSrpClientService *services,
const otSrpClientService *removed_services, void *context) {
if (err != 0) {
ESP_LOGW(TAG, "SRP client reported an error: %s", otThreadErrorToString(err));
@@ -90,16 +94,30 @@ void srp_callback(otError err, const otSrpClientHostInfo *host_info, const otSrp
}
}
void srp_start_callback(const otSockAddr *server_socket_address, void *context) {
void OpenThreadSrpComponent::srp_start_callback(const otSockAddr *server_socket_address, void *context) {
ESP_LOGI(TAG, "SRP client has started");
}
void OpenThreadSrpComponent::srp_factory_reset_callback(otError err, const otSrpClientHostInfo *host_info,
const otSrpClientService *services,
const otSrpClientService *removed_services, void *context) {
OpenThreadComponent *obj = (OpenThreadComponent *) context;
if (err == OT_ERROR_NONE && removed_services != NULL && host_info != NULL &&
host_info->mState == OT_SRP_CLIENT_ITEM_STATE_REMOVED) {
ESP_LOGD(TAG, "Successful Removal SRP Host and Services");
} else if (err != OT_ERROR_NONE) {
// Handle other SRP client events or errors
ESP_LOGW(TAG, "SRP client event/error: %s", otThreadErrorToString(err));
}
obj->defer_factory_reset_external_callback();
}
void OpenThreadSrpComponent::setup() {
otError error;
InstanceLock lock = InstanceLock::acquire();
otInstance *instance = lock.get_instance();
otSrpClientSetCallback(instance, srp_callback, nullptr);
otSrpClientSetCallback(instance, OpenThreadSrpComponent::srp_callback, nullptr);
// set the host name
uint16_t size;
@@ -179,7 +197,8 @@ void OpenThreadSrpComponent::setup() {
ESP_LOGD(TAG, "Added service: %s", full_service.c_str());
}
otSrpClientEnableAutoStartMode(instance, srp_start_callback, nullptr);
otSrpClientEnableAutoStartMode(instance, OpenThreadSrpComponent::srp_start_callback, nullptr);
ESP_LOGD(TAG, "Finished SRP setup");
}
void *OpenThreadSrpComponent::pool_alloc_(size_t size) {
@@ -217,6 +236,21 @@ bool OpenThreadComponent::teardown() {
return this->teardown_complete_;
}
void OpenThreadComponent::on_factory_reset(std::function<void()> callback) {
factory_reset_external_callback_ = callback;
ESP_LOGD(TAG, "Start Removal SRP Host and Services");
otError error;
InstanceLock lock = InstanceLock::acquire();
otInstance *instance = lock.get_instance();
otSrpClientSetCallback(instance, OpenThreadSrpComponent::srp_factory_reset_callback, this);
error = otSrpClientRemoveHostAndServices(instance, true, true);
if (error != OT_ERROR_NONE) {
ESP_LOGW(TAG, "Failed to Remove SRP Host and Services");
return;
}
ESP_LOGD(TAG, "Waiting on Confirmation Removal SRP Host and Services");
}
} // namespace openthread
} // namespace esphome

View File

@@ -6,6 +6,8 @@
#include "esphome/components/network/ip_address.h"
#include "esphome/core/component.h"
#include <openthread/srp_client.h>
#include <openthread/srp_client_buffers.h>
#include <openthread/thread.h>
#include <optional>
@@ -28,11 +30,14 @@ class OpenThreadComponent : public Component {
network::IPAddresses get_ip_addresses();
std::optional<otIp6Address> get_omr_address();
void ot_main();
void on_factory_reset(std::function<void()> callback);
void defer_factory_reset_external_callback();
protected:
std::optional<otIp6Address> get_omr_address_(InstanceLock &lock);
bool teardown_started_{false};
bool teardown_complete_{false};
std::function<void()> factory_reset_external_callback_;
};
extern OpenThreadComponent *global_openthread_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
@@ -43,6 +48,12 @@ class OpenThreadSrpComponent : public Component {
// This has to run after the mdns component or else no services are available to advertise
float get_setup_priority() const override { return this->mdns_->get_setup_priority() - 1.0; }
void setup() override;
static void srp_callback(otError err, const otSrpClientHostInfo *host_info, const otSrpClientService *services,
const otSrpClientService *removed_services, void *context);
static void srp_start_callback(const otSockAddr *server_socket_address, void *context);
static void srp_factory_reset_callback(otError err, const otSrpClientHostInfo *host_info,
const otSrpClientService *services, const otSrpClientService *removed_services,
void *context);
protected:
esphome::mdns::MDNSComponent *mdns_{nullptr};