diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index fc493014a..3d2c2597a 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -2258,10 +2258,42 @@ node_t *create_raw() return (node_t *)node; } +esp_err_t destroy_raw() +{ + VerifyOrReturnError(node, ESP_ERR_INVALID_STATE, ESP_LOGE(TAG, "NULL node cannot be destroyed")); + _node_t *current_node = (_node_t *)node; + esp_matter_mem_free(current_node); + node = NULL; + return ESP_OK; +} + node_t *get() { return (node_t *)node; } +esp_err_t destroy() +{ + esp_err_t err = ESP_OK; + node_t *current_node = get(); + VerifyOrReturnError(current_node, ESP_ERR_INVALID_STATE, ESP_LOGE(TAG, "Node cannot be NULL")); + + attribute::set_callback(nullptr); + identification::set_callback(nullptr); + + endpoint_t *current_endpoint = endpoint::get_first(current_node); + endpoint_t *next_endpoint = nullptr; + while (current_endpoint != nullptr) { + next_endpoint = endpoint::get_next(current_endpoint); + // Endpoints should have destroyable flag set to true before destroying + ((_endpoint_t *)current_endpoint)->flags |= ENDPOINT_FLAG_DESTROYABLE; + err = endpoint::destroy((node_t *)current_node, current_endpoint); + VerifyOrDo(err == ESP_OK, ESP_LOGE(TAG, "Failed to destroy endpoint")); + current_endpoint = next_endpoint; + } + + return destroy_raw(); +} + } /* node */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_core.h b/components/esp_matter/esp_matter_core.h index 3163b71e8..41684aee6 100644 --- a/components/esp_matter/esp_matter_core.h +++ b/components/esp_matter/esp_matter_core.h @@ -120,6 +120,13 @@ namespace node { */ node_t *create_raw(); +/** Destroy raw node + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t destroy_raw(); + /** Get node * * @return Node handle on success. @@ -127,6 +134,17 @@ node_t *create_raw(); */ node_t *get(); +/** Destroy node + * + * This will destroy the node and all the endpoints, clusters, attributes, commands and events associated with it. + * + * @note: Call this function only if matter is not running. + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t destroy(); + } /* node */ namespace endpoint { diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index a0fa43cb6..f68691ae4 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -2080,17 +2080,15 @@ namespace node { node_t *create(config_t *config, attribute::callback_t attribute_callback, identification::callback_t identification_callback) { - attribute::set_callback(attribute_callback); - identification::set_callback(identification_callback); - node_t *node = create_raw(); - if (!node) { - ESP_LOGE(TAG, "Could not create node"); + VerifyOrReturnValue(node != nullptr, NULL, ESP_LOGE(TAG, "Could not create node")); + endpoint_t *endpoint = endpoint::root_node::create(node, &(config->root_node), ENDPOINT_FLAG_NONE, NULL); + if (endpoint == nullptr) { + destroy_raw(); return NULL; } - - endpoint::root_node::create(node, &(config->root_node), ENDPOINT_FLAG_NONE, NULL); - + attribute::set_callback(attribute_callback); + identification::set_callback(identification_callback); return node; }