diff --git a/CHANGES.md b/CHANGES.md index 7a7aeb095..8192b4d79 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,7 @@ static esp_matter_node_config_t node_config = NODE_CONFIG_DEFAULT(); static esp_matter_endpoint_color_dimmable_light_config_t light_config = ENDPOINT_CONFIG_COLOR_DIMMABLE_LIGHT_DEFAULT(); esp_matter_node_t *node = esp_matter_node_create(&node_config, app_attribute_update_cb, NULL); -esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_color_dimmable_light(node, &light_config); +esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_color_dimmable_light(node, &light_config, ENDPOINT_MASK_NONE); ``` The examples have also been restructured and the matter submodule specific initialisations have @@ -53,7 +53,7 @@ low level APIs. New device types (endpoints) and supporting clusters can be adde by looking at the existing APIs for reference. ``` esp_matter_node_t *esp_matter_node_create_raw(); -esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, int endpoint_id); +esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, int endpoint_id, uint8_t flags); esp_matter_cluster_t *esp_matter_cluster_create(esp_matter_endpoint_t *endpoint, int cluster_id, uint8_t flags); esp_matter_attribute_t *esp_matter_attribute_create(esp_matter_cluster_t *cluster, int attribute_id, uint8_t flags, esp_matter_attr_val_t val); esp_matter_command_t *esp_matter_command_create(esp_matter_cluster_t *cluster, int command_id, uint8_t flags, esp_matter_command_callback_t callback); diff --git a/components/esp_matter/esp_matter.h b/components/esp_matter/esp_matter.h index ab368ee34..794a6b312 100644 --- a/components/esp_matter/esp_matter.h +++ b/components/esp_matter/esp_matter.h @@ -32,3 +32,12 @@ application. #include #include + +#define ATTRIBUTE_MASK_NONE 0x0 +#define COMMAND_MASK_NONE 0x0 +#define CLUSTER_MASK_NONE 0x0 +#define ENDPOINT_MASK_NONE 0x0 + +#define ENDPOINT_MASK_DELETABLE 0x1 + +#define COMMAND_MASK_CUSTOM 0x80 diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 10713c739..d4c7b7c23 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -56,6 +56,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_descriptor(esp_matter_endpoint_t uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_DESCRIPTOR_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterDescriptorPluginServerInitCallback); } @@ -84,6 +89,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_access_control(esp_matter_endpoi /* Not implemented esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_ACCESS_CONTROL_CLUSTER_ID, CLUSTER_MASK_SERVER); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterAcccessControlPluginServerInitCallback); } @@ -107,6 +117,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_basic(esp_matter_endpoint_t *end esp_matter_cluster_basic_config_t *config, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_BASIC_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterBasicPluginServerInitCallback); } @@ -151,6 +166,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_ota_provider(esp_matter_endpoint uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_OTA_PROVIDER_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterOtaSoftwareUpdateProviderPluginServerInitCallback); @@ -182,6 +202,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_ota_requestor(esp_matter_endpoin uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_OTA_REQUESTOR_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterOtaSoftwareUpdateRequestorPluginServerInitCallback); @@ -214,6 +239,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_general_commissioning(esp_matter uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_GENERAL_COMMISSIONING_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterGeneralCommissioningPluginServerInitCallback); } @@ -254,6 +284,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_network_commissioning(esp_matter uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_NETWORK_COMMISSIONING_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterNetworkCommissioningPluginServerInitCallback); } @@ -309,6 +344,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_general_diagnostics(esp_matter_e uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_GENERAL_DIAGNOSTICS_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterGeneralDiagnosticsPluginServerInitCallback); } @@ -332,6 +372,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_administrator_commissioning(esp_ { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterAdministratorCommissioningPluginServerInitCallback); @@ -365,6 +410,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_operational_credentials(esp_matt uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_OPERATIONAL_CREDENTIALS_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterOperationalCredentialsPluginServerInitCallback); @@ -426,6 +476,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_group_key_management(esp_matter_ uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_GROUP_KEY_MANAGEMENT_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterGroupKeyManagementPluginServerInitCallback); } @@ -466,6 +521,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_identify(esp_matter_endpoint_t * esp_matter_cluster_identify_config_t *config, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_IDENTIFY_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterIdentifyPluginServerInitCallback); } @@ -494,6 +554,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_groups(esp_matter_endpoint_t *en esp_matter_cluster_groups_config_t *config, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_GROUPS_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterGroupsPluginServerInitCallback); } @@ -534,6 +599,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_scenes(esp_matter_endpoint_t *en esp_matter_cluster_scenes_config_t *config, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_SCENES_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterScenesPluginServerInitCallback); } @@ -588,6 +658,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_on_off(esp_matter_endpoint_t *en esp_matter_cluster_on_off_config_t *config, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_ON_OFF_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterOnOffPluginServerInitCallback); } @@ -611,6 +686,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_level_control(esp_matter_endpoin uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterLevelControlPluginServerInitCallback); } @@ -649,6 +729,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_color_control(esp_matter_endpoin uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_MASK_SERVER) { esp_matter_cluster_set_plugin_server_init_callback(cluster, MatterColorControlPluginServerInitCallback); } diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 533009e66..278f3cde5 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -17,10 +17,6 @@ #include #include -#define ATTRIBUTE_MASK_NONE 0 -#define COMMAND_MASK_NONE 0 -#define CLUSTER_MASK_NONE 0 - #define CLUSTER_CONFIG_DESCRIPTOR_DEFAULT() \ { \ .cluster_revision = 1, \ diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index 9bf84d558..d123a3ecf 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 0436599f2..53ba60ce2 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -19,8 +19,6 @@ using chip::app::ConcreteCommandPath; using chip::TLV::TLVReader; -#define COMMAND_MASK_CUSTOM 0x80 - typedef esp_err_t (*esp_matter_command_custom_callback_t)(int endpoint_id, int cluster_id, int command_id, TLVReader &tlv_data, void *priv_data); diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index 2dba6c7e8..f3debfad7 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include @@ -25,6 +26,7 @@ #include #endif +using chip::kInvalidEndpointId; using chip::Credentials::SetDeviceAttestationCredentialsProvider; using chip::Credentials::Examples::GetExampleDACProvider; using chip::DeviceLayer::ChipDeviceEvent; @@ -35,7 +37,7 @@ using chip::DeviceLayer::PlatformMgr; using chip::DeviceLayer::ThreadStackMgr; #endif -static const char *TAG = "esp_matter_device"; +static const char *TAG = "esp_matter_core"; typedef struct esp_matter_attribute { int attribute_id; @@ -64,7 +66,9 @@ typedef struct esp_matter_cluster { typedef struct esp_matter_endpoint { int endpoint_id; + uint8_t flags; _esp_matter_cluster_t *cluster_list; + EmberAfEndpointType *endpoint_type; struct esp_matter_endpoint *next; } _esp_matter_endpoint_t; @@ -94,6 +98,49 @@ static int esp_matter_attribute_get_count(_esp_matter_attribute_t *current) return count; } +static int esp_matter_endpoint_get_next_index() +{ + int endpoint_id = 0; + for (int index = 0; index < MAX_ENDPOINT_COUNT; index++) { + endpoint_id = emberAfEndpointFromIndex(index); + if (endpoint_id == kInvalidEndpointId) { + return index; + } + } + return 0xFFFF; +} + +static esp_err_t esp_matter_endpoint_disable(esp_matter_endpoint_t *endpoint) +{ + if (!endpoint) { + ESP_LOGE(TAG, "Endpoint cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + + /* Remove endpoint */ + _esp_matter_endpoint_t *current_endpoint = (_esp_matter_endpoint_t *)endpoint; + int endpoint_index = emberAfGetDynamicIndexFromEndpoint(current_endpoint->endpoint_id); + if (endpoint_index == 0xFFFF) { + ESP_LOGE(TAG, "Could not find endpoint index"); + return ESP_FAIL; + } + emberAfClearDynamicEndpoint(endpoint_index); + + /* Free all clusters */ + EmberAfEndpointType *endpoint_type = current_endpoint->endpoint_type; + int cluster_count = endpoint_type->clusterCount; + for (int cluster_index = 0; cluster_index < cluster_count; cluster_index++) { + /* Free attributes */ + free(endpoint_type->cluster[cluster_index].attributes); + } + free(endpoint_type->cluster); + + /* Free endpoint type */ + free(endpoint_type); + current_endpoint->endpoint_type = NULL; + return ESP_OK; +} + extern esp_err_t esp_matter_attribute_get_type_and_val_default(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, uint16_t *attribute_size, @@ -106,7 +153,6 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) return ESP_ERR_INVALID_ARG; } _esp_matter_endpoint_t *current_endpoint = (_esp_matter_endpoint_t *)endpoint; - static int endpoint_index = 0; /* Endpoint Type */ EmberAfEndpointType *endpoint_type = (EmberAfEndpointType *)calloc(1, sizeof(EmberAfEndpointType)); @@ -114,6 +160,7 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) ESP_LOGE(TAG, "Couldn't allocate endpoint_type"); return ESP_ERR_NO_MEM; } + current_endpoint->endpoint_type = endpoint_type; /* Clusters */ _esp_matter_cluster_t *cluster = current_endpoint->cluster_list; @@ -130,7 +177,7 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) _esp_matter_attribute_t *attribute = cluster->attribute_list; int attribute_count = esp_matter_attribute_get_count(attribute); int attribute_index = 0; - EmberAfAttributeMetadata *matter_attributes = (EmberAfAttributeMetadata *)calloc(1, + EmberAfAttributeMetadata *matter_attributes = (EmberAfAttributeMetadata *)calloc(1, attribute_count * sizeof(EmberAfAttributeMetadata)); if (!matter_attributes) { ESP_LOGE(TAG, "Couldn't allocate matter_attributes"); @@ -165,11 +212,11 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) endpoint_type->clusterCount = cluster_count; /* Add Endpoint */ + int endpoint_index = esp_matter_endpoint_get_next_index(); EmberAfStatus err = emberAfSetDynamicEndpoint(endpoint_index, current_endpoint->endpoint_id, endpoint_type, 0, 1); if (err != EMBER_ZCL_STATUS_SUCCESS) { ESP_LOGE(TAG, "Error adding dynamic endpoint %d: %d", current_endpoint->endpoint_id, err); } - endpoint_index++; return ESP_OK; } @@ -532,6 +579,21 @@ int esp_matter_command_get_flags(esp_matter_command_t *command) return current_command->flags; } +static esp_err_t esp_matter_attribute_delete(esp_matter_attribute_t *attribute) +{ + if (!attribute) { + ESP_LOGE(TAG, "Attribute cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)attribute; + + /* Delete val here, if required */ + + /* Free */ + free(current_attribute); + return ESP_OK; +} + esp_matter_attribute_t *esp_matter_attribute_create(esp_matter_cluster_t *cluster, int attribute_id, uint8_t flags, esp_matter_attr_val_t val) { @@ -571,6 +633,19 @@ esp_matter_attribute_t *esp_matter_attribute_create(esp_matter_cluster_t *cluste return (esp_matter_attribute_t *)attribute; } +static esp_err_t esp_matter_command_delete(esp_matter_command_t *command) +{ + if (!command) { + ESP_LOGE(TAG, "Command cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + _esp_matter_command_t *current_command = (_esp_matter_command_t *)command; + + /* Free */ + free(current_command); + return ESP_OK; +} + esp_matter_command_t *esp_matter_command_create(esp_matter_cluster_t *cluster, int command_id, uint8_t flags, esp_matter_command_callback_t callback) { @@ -609,6 +684,35 @@ esp_matter_command_t *esp_matter_command_create(esp_matter_cluster_t *cluster, i return (esp_matter_command_t *)command; } +static esp_err_t esp_matter_cluster_delete(esp_matter_cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + _esp_matter_cluster_t *current_cluster = (_esp_matter_cluster_t *)cluster; + + /* Parse and delete all commands */ + _esp_matter_command_t *command = current_cluster->command_list; + while (command) { + _esp_matter_command_t *next_command = command->next; + esp_matter_command_delete((esp_matter_command_t *)command); + command = next_command; + } + + /* Parse and delete all attributes */ + _esp_matter_attribute_t *attribute = current_cluster->attribute_list; + while (attribute) { + _esp_matter_attribute_t *next_attribute = attribute->next; + esp_matter_attribute_delete((esp_matter_attribute_t *)attribute); + attribute = next_attribute; + } + + /* Free */ + free(current_cluster); + return ESP_OK; +} + esp_matter_cluster_t *esp_matter_cluster_create(esp_matter_endpoint_t *endpoint, int cluster_id, uint8_t flags) { /* Find */ @@ -645,7 +749,57 @@ esp_matter_cluster_t *esp_matter_cluster_create(esp_matter_endpoint_t *endpoint, return (esp_matter_cluster_t *)cluster; } -esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, int endpoint_id) +esp_err_t esp_matter_endpoint_delete(esp_matter_node_t *node, esp_matter_endpoint_t *endpoint) +{ + if (!node || !endpoint) { + ESP_LOGE(TAG, "Node or endpoint cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + _esp_matter_node_t *current_node = (_esp_matter_node_t *)node; + _esp_matter_endpoint_t *_endpoint = (_esp_matter_endpoint_t *)endpoint; + + if (!(_endpoint->flags & ENDPOINT_MASK_DELETABLE)) { + ESP_LOGE(TAG, "This endpoint cannot be deleted since the ENDPOINT_MASK_DELETABLE is not set"); + return ESP_FAIL; + } + + /* Find current endpoint and remove from list */ + _esp_matter_endpoint_t *current_endpoint = current_node->endpoint_list; + _esp_matter_endpoint_t *previous_endpoint = NULL; + while (current_endpoint) { + if (current_endpoint == _endpoint) { + break; + } + previous_endpoint = current_endpoint; + current_endpoint = current_endpoint->next; + } + if (current_endpoint == NULL) { + ESP_LOGE(TAG, "Could not find the endpoint to delete"); + return ESP_FAIL; + } + if (previous_endpoint == NULL) { + current_node->endpoint_list = current_endpoint->next; + } else { + previous_endpoint->next = current_endpoint->next; + } + + /* Disable */ + esp_matter_endpoint_disable(endpoint); + + /* Parse and delete all clusters */ + _esp_matter_cluster_t *cluster = current_endpoint->cluster_list; + while (cluster) { + _esp_matter_cluster_t *next_cluster = cluster->next; + esp_matter_cluster_delete((esp_matter_cluster_t *)cluster); + cluster = next_cluster; + } + + /* Free */ + free(current_endpoint); + return ESP_OK; +} + +esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, int endpoint_id, uint8_t flags) { /* Find */ if (!node) { @@ -653,6 +807,15 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, i return NULL; } _esp_matter_node_t *current_node = (_esp_matter_node_t *)node; + if (endpoint_id == kInvalidEndpointId) { + ESP_LOGE(TAG, "Invalid endpoint_id: 0x%04X", endpoint_id); + return NULL; + } + esp_matter_endpoint_t *existing_endpoint = esp_matter_endpoint_get(node, endpoint_id); + if (existing_endpoint) { + ESP_LOGE(TAG, "Endpoint with id 0x%04X already exists", endpoint_id); + return NULL; + } /* Allocate */ _esp_matter_endpoint_t *endpoint = (_esp_matter_endpoint_t *)calloc(1, sizeof(_esp_matter_endpoint_t)); @@ -663,6 +826,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, i /* Set */ endpoint->endpoint_id = endpoint_id; + endpoint->flags = flags; /* Add */ _esp_matter_endpoint_t *previous_endpoint = NULL; diff --git a/components/esp_matter/esp_matter_core.h b/components/esp_matter/esp_matter_core.h index 900a21f57..bb2022868 100644 --- a/components/esp_matter/esp_matter_core.h +++ b/components/esp_matter/esp_matter_core.h @@ -55,7 +55,8 @@ esp_matter_node_t *esp_matter_node_create_raw(); esp_matter_node_t *esp_matter_node_get(); /** Endpoint APIs */ -esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, int endpoint_id); +esp_matter_endpoint_t *esp_matter_endpoint_create_raw(esp_matter_node_t *node, int endpoint_id, uint8_t flags); +esp_err_t esp_matter_endpoint_delete(esp_matter_node_t *node, esp_matter_endpoint_t *endpoint); esp_matter_endpoint_t *esp_matter_endpoint_get(esp_matter_node_t *node, int endpoint_id); esp_matter_endpoint_t *esp_matter_endpoint_get_first(esp_matter_node_t *node); esp_matter_endpoint_t *esp_matter_endpoint_get_next(esp_matter_endpoint_t *endpoint); diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 6e536ead5..1870c15f5 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -12,13 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include +static const char *TAG = "esp_matter_endpoint"; + esp_matter_endpoint_t *esp_matter_endpoint_create_root_node(esp_matter_node_t *node, - esp_matter_endpoint_root_node_config_t *config) + esp_matter_endpoint_root_node_config_t *config, + uint8_t flags) { - esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_raw(node, ESP_MATTER_ROOT_NODE_ENDPOINT_ID); + esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_raw(node, ESP_MATTER_ROOT_NODE_ENDPOINT_ID, + flags); + if (!endpoint) { + ESP_LOGE(TAG, "Could not create endpoint"); + return NULL; + } esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), CLUSTER_MASK_SERVER); esp_matter_cluster_create_access_control(endpoint, &(config->access_control), CLUSTER_MASK_SERVER); @@ -38,9 +47,15 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_root_node(esp_matter_node_t *n } esp_matter_endpoint_t *esp_matter_endpoint_create_color_dimmable_light(esp_matter_node_t *node, - esp_matter_endpoint_color_dimmable_light_config_t *config) + esp_matter_endpoint_color_dimmable_light_config_t *config, + uint8_t flags) { - esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_raw(node, ESP_MATTER_COLOR_DIMMABLE_LIGHT_ENDPOINT_ID); + esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_raw(node, ESP_MATTER_COLOR_DIMMABLE_LIGHT_ENDPOINT_ID, + flags); + if (!endpoint) { + ESP_LOGE(TAG, "Could not create endpoint"); + return NULL; + } esp_matter_cluster_create_identify(endpoint, &(config->identify), CLUSTER_MASK_SERVER); esp_matter_cluster_create_groups(endpoint, &(config->groups), CLUSTER_MASK_SERVER); @@ -56,11 +71,15 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_color_dimmable_light(esp_matte esp_matter_node_t *esp_matter_node_create(esp_matter_node_config_t *config, esp_matter_attribute_callback_t callback, void *priv_data) { - esp_matter_node_t *node = esp_matter_node_create_raw(); - esp_matter_attribute_callback_set(callback, priv_data); - esp_matter_endpoint_create_root_node(node, &(config->root_node)); + esp_matter_node_t *node = esp_matter_node_create_raw(); + if (!node) { + ESP_LOGE(TAG, "Could not create node"); + return NULL; + } + + esp_matter_endpoint_create_root_node(node, &(config->root_node), ENDPOINT_MASK_NONE); return node; } diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index 7610580dc..135f0283b 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -80,9 +80,11 @@ typedef struct esp_matter_node_config { } esp_matter_node_config_t; esp_matter_endpoint_t *esp_matter_endpoint_create_root_node(esp_matter_node_t *node, - esp_matter_endpoint_root_node_config_t *config); + esp_matter_endpoint_root_node_config_t *config, + uint8_t flags); esp_matter_endpoint_t *esp_matter_endpoint_create_color_dimmable_light(esp_matter_node_t *node, - esp_matter_endpoint_color_dimmable_light_config_t *config); + esp_matter_endpoint_color_dimmable_light_config_t *config, + uint8_t flags); esp_matter_node_t *esp_matter_node_create(esp_matter_node_config_t *config, esp_matter_attribute_callback_t callback, void *priv_data); diff --git a/examples/light/main/app_main.cpp b/examples/light/main/app_main.cpp index 2d4d9c229..34d119b47 100644 --- a/examples/light/main/app_main.cpp +++ b/examples/light/main/app_main.cpp @@ -58,7 +58,8 @@ extern "C" void app_main() /* Create matter device */ esp_matter_node_t *node = esp_matter_node_create(&node_config, app_attribute_update_cb, NULL); - esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_color_dimmable_light(node, &light_config); + esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_color_dimmable_light(node, &light_config, + ENDPOINT_MASK_NONE); /** These node and endpoint handles can be used to create and add other endpoints and other clusters to the endpoints. */ diff --git a/examples/rainmaker_light/main/app_main.cpp b/examples/rainmaker_light/main/app_main.cpp index 47ed2b650..d85396676 100644 --- a/examples/rainmaker_light/main/app_main.cpp +++ b/examples/rainmaker_light/main/app_main.cpp @@ -59,7 +59,8 @@ extern "C" void app_main() /* Create matter device */ esp_matter_node_t *node = esp_matter_node_create(&node_config, app_attribute_update_cb, NULL); - esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_color_dimmable_light(node, &light_config); + esp_matter_endpoint_t *endpoint = esp_matter_endpoint_create_color_dimmable_light(node, &light_config, + ENDPOINT_MASK_NONE); /** These node and endpoint handles can be used to create and add other endpoints and other clusters to the endpoints. */