From eb4185902b11bd0d152256917c34daf29c4f7351 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Wed, 24 Apr 2024 15:02:47 +0530 Subject: [PATCH] Support to add delegate callbacks in cluster. --- components/esp_matter/esp_matter_cluster.cpp | 23 ++++++++++++ components/esp_matter/esp_matter_cluster.h | 6 ++++ components/esp_matter/esp_matter_core.cpp | 36 +++++++++++++++++++ components/esp_matter/esp_matter_core.h | 37 ++++++++++++++++++++ 4 files changed, 102 insertions(+) diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index aaf703b11..1c870ea3c 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -60,6 +60,29 @@ void plugin_init_callback_common() } } +void delegate_init_callback_common() +{ + node_t *node = node::get(); + if (!node) { + /* Skip delegate_init_callback_common when ESP Matter data model is not used */ + return; + } + endpoint_t *endpoint = endpoint::get_first(node); + while (endpoint) { + uint16_t endpoint_id = endpoint::get_id(endpoint); + cluster_t *cluster = get_first(endpoint); + while (cluster) { + /* Delegate server init callback */ + delegate_init_callback_t delegate_init_callback = get_delegate_init_callback(cluster); + if (delegate_init_callback) { + delegate_init_callback(get_delegate_impl(cluster), endpoint_id); + } + cluster = get_next(cluster); + } + endpoint = endpoint::get_next(endpoint); + } +} + cluster_t *create_default_binding_cluster(endpoint_t *endpoint) { /* Don't create binding cluster if it already exists on the endpoint */ diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 389e32543..d7d85ca47 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -31,6 +31,12 @@ namespace cluster { */ void plugin_init_callback_common(); +/** Common cluster delegate init callback + * + * This is the common delegate init callback which calls the delegate init callbacks in the clusters. + */ +void delegate_init_callback_common(); + /** Specific cluster create APIs * * These APIs also create the mandatory attributes and commands for the cluster. If the mandatory attribute is not diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index 677919092..8c08e352e 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -194,6 +194,8 @@ typedef struct _cluster { uint16_t flags; const cluster::function_generic_t *function_list; cluster::plugin_server_init_callback_t plugin_server_init_callback; + cluster::delegate_init_callback_t delegate_init_callback; + void * delegate_pointer; _attribute_t *attribute_list; _command_t *command_list; _event_t *event_list; @@ -1052,6 +1054,8 @@ static esp_err_t chip_init(event_callback_t callback, intptr_t callback_arg) PlatformMgr().ScheduleWork(esp_matter_chip_init_task, reinterpret_cast(xTaskGetCurrentTaskHandle())); // Wait for the matter stack to be initialized xTaskNotifyWait(0, 0, NULL, portMAX_DELAY); + // Initialise clusters which have delegate implemented + esp_matter::cluster::delegate_init_callback_common(); #endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER return ESP_OK; @@ -1866,6 +1870,16 @@ uint32_t get_id(cluster_t *cluster) return current_cluster->cluster_id; } +void *get_delegate_impl(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return NULL; + } + _cluster_t *current_cluster = (_cluster_t *)cluster; + return current_cluster->delegate_pointer; +} + esp_err_t set_plugin_server_init_callback(cluster_t *cluster, plugin_server_init_callback_t callback) { if (!cluster) { @@ -1887,6 +1901,28 @@ plugin_server_init_callback_t get_plugin_server_init_callback(cluster_t *cluster return current_cluster->plugin_server_init_callback; } +esp_err_t set_delegate_and_init_callback(cluster_t *cluster, delegate_init_callback_t callback, void *delegate) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + _cluster_t *current_cluster = (_cluster_t *)cluster; + current_cluster->delegate_init_callback = callback; + current_cluster->delegate_pointer = delegate; + return ESP_OK; +} + +delegate_init_callback_t get_delegate_init_callback(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return NULL; + } + _cluster_t *current_cluster = (_cluster_t *)cluster; + return current_cluster->delegate_init_callback; +} + esp_err_t add_function_list(cluster_t *cluster, const function_generic_t *function_list, int function_flags) { if (!cluster) { diff --git a/components/esp_matter/esp_matter_core.h b/components/esp_matter/esp_matter_core.h index feb598da1..7adf13d28 100644 --- a/components/esp_matter/esp_matter_core.h +++ b/components/esp_matter/esp_matter_core.h @@ -312,6 +312,12 @@ namespace cluster { */ typedef void (*plugin_server_init_callback_t)(); +/** Cluster delegate server init callback + * + * This callback will be called when the endpoints are initialised. + */ +typedef void (*delegate_init_callback_t)(void *ptr, uint16_t endpoint_id); + /** Generic function * * This can be used to add additional functions based on `cluster_flags_t`. @@ -376,6 +382,17 @@ cluster_t *get_next(cluster_t *cluster); */ uint32_t get_id(cluster_t *cluster); +/** Get delegate pointer + * + * Get the delegate pointer for the cluster. + * + * @param[in] cluster Cluster handle. + * + * @return pointer of delegate class on success. + * @return nullptr in case of failure. + */ +void *get_delegate_impl(cluster_t *cluster); + /** Set cluster plugin server init callback * * Set the cluster plugin server init callback. This callback will be called when the endpoints are initialised. The @@ -390,6 +407,17 @@ uint32_t get_id(cluster_t *cluster); */ esp_err_t set_plugin_server_init_callback(cluster_t *cluster, plugin_server_init_callback_t callback); +/** Set server cluster delegate init callback + * + * @param[in] cluster Cluster handle. + * @param[in] callback Delegate server init callback. + * @param[in] delegate Pointer to delegate impl.. + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t set_delegate_and_init_callback(cluster_t *cluster, delegate_init_callback_t callback, void *delegate); + /** Get cluster plugin server init callback * * Get the cluster plugin server init callback which has previously been set. @@ -401,6 +429,15 @@ esp_err_t set_plugin_server_init_callback(cluster_t *cluster, plugin_server_init */ plugin_server_init_callback_t get_plugin_server_init_callback(cluster_t *cluster); +/** Get server cluster delegate init callback + * + * @param[in] cluster Cluster handle. + * + * @return Delegate init callback. + * @return NULL in case of failure or if it has not been set. + */ +delegate_init_callback_t get_delegate_init_callback(cluster_t *cluster); + /** Add cluster function list * * This API can be used to add additional cluster functions based on `cluster_flags_t`. This should be set