mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
esp_matter: create a data_model directory and move data_model related codes to it
This commit is contained in:
@@ -1,14 +1,6 @@
|
|||||||
set(SRC_DIRS_LIST "."
|
set(SRC_DIRS_LIST "."
|
||||||
"private"
|
|
||||||
"utils"
|
"utils"
|
||||||
"${MATTER_SDK_PATH}/zzz_generated/app-common/app-common/zap-generated/attributes"
|
"${MATTER_SDK_PATH}/zzz_generated/app-common/app-common/zap-generated/attributes"
|
||||||
"${MATTER_SDK_PATH}/src/app/server"
|
|
||||||
"${MATTER_SDK_PATH}/src/app/util"
|
|
||||||
"${MATTER_SDK_PATH}/src/app/util/persistence"
|
|
||||||
"${MATTER_SDK_PATH}/src/app/reporting"
|
|
||||||
# TODO Use esp-matter data model and remove ember codes
|
|
||||||
"${MATTER_SDK_PATH}/src/data-model-providers/codegen"
|
|
||||||
"${MATTER_SDK_PATH}/src/app/server-cluster"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(INCLUDE_DIRS_LIST "."
|
set(INCLUDE_DIRS_LIST "."
|
||||||
@@ -20,7 +12,15 @@ set(INCLUDE_DIRS_LIST "."
|
|||||||
# TODO: This file has compilation errors
|
# TODO: This file has compilation errors
|
||||||
set(EXCLUDE_SRCS_LIST "${MATTER_SDK_PATH}/src/app/clusters/closure-control-server/closure-control-server.cpp")
|
set(EXCLUDE_SRCS_LIST "${MATTER_SDK_PATH}/src/app/clusters/closure-control-server/closure-control-server.cpp")
|
||||||
|
|
||||||
if (CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
if (CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER)
|
||||||
|
list(APPEND SRC_DIRS_LIST "${MATTER_SDK_PATH}/src/app/server"
|
||||||
|
"${MATTER_SDK_PATH}/src/app/reporting"
|
||||||
|
"${MATTER_SDK_PATH}/src/app/server-cluster"
|
||||||
|
# TODO Use esp-matter data model and remove ember codes
|
||||||
|
"${MATTER_SDK_PATH}/src/app/util"
|
||||||
|
"${MATTER_SDK_PATH}/src/app/util/persistence"
|
||||||
|
"${MATTER_SDK_PATH}/src/data-model-providers/codegen")
|
||||||
|
if (CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
||||||
include("utils/cluster_select/cluster_dir.cmake")
|
include("utils/cluster_select/cluster_dir.cmake")
|
||||||
get_supported_cluster_dirs(SUPPORTED_CLUSTER_DIRS)
|
get_supported_cluster_dirs(SUPPORTED_CLUSTER_DIRS)
|
||||||
foreach(CLUSTER_DIR ${SUPPORTED_CLUSTER_DIRS})
|
foreach(CLUSTER_DIR ${SUPPORTED_CLUSTER_DIRS})
|
||||||
@@ -31,20 +31,24 @@ if (CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
|||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
list(APPEND SRC_DIRS_LIST "zap_common/app")
|
list(APPEND SRC_DIRS_LIST "zap_common/app"
|
||||||
list(APPEND INCLUDE_DIRS_LIST "zap_common")
|
"data_model"
|
||||||
|
"private")
|
||||||
|
list(APPEND INCLUDE_DIRS_LIST "zap_common"
|
||||||
|
"data_model")
|
||||||
|
endif(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
||||||
else()
|
else()
|
||||||
# Do not add all the clusters srcs to esp_matter for examples that don't use ESP-Matter Data Model(such as zap light example)
|
list(APPEND EXCLUDE_SRCS_LIST "esp_matter_identify.cpp"
|
||||||
# For those examples, they should include the clusters srcs in their main component
|
"esp_matter_ota.cpp"
|
||||||
list(APPEND EXCLUDE_SRCS_LIST "esp_matter_delegate_callbacks.cpp")
|
"esp_matter_attribute_utils.cpp")
|
||||||
endif()
|
endif(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER)
|
||||||
|
|
||||||
set(REQUIRES_LIST chip bt esp_matter_console nvs_flash app_update esp_secure_cert_mgr mbedtls esp_system openthread json)
|
set(REQUIRES_LIST chip bt esp_matter_console nvs_flash app_update esp_secure_cert_mgr mbedtls esp_system openthread json)
|
||||||
|
|
||||||
idf_component_register( SRC_DIRS ${SRC_DIRS_LIST}
|
idf_component_register( SRC_DIRS ${SRC_DIRS_LIST}
|
||||||
INCLUDE_DIRS ${INCLUDE_DIRS_LIST}
|
INCLUDE_DIRS ${INCLUDE_DIRS_LIST}
|
||||||
EXCLUDE_SRCS ${EXCLUDE_SRCS_LIST}
|
EXCLUDE_SRCS ${EXCLUDE_SRCS_LIST}
|
||||||
PRIV_INCLUDE_DIRS "private"
|
PRIV_INCLUDE_DIRS "private" "data_model/private"
|
||||||
REQUIRES ${REQUIRES_LIST})
|
REQUIRES ${REQUIRES_LIST})
|
||||||
|
|
||||||
# This has been added to fix the error and should be removed once fixed:
|
# This has been added to fix the error and should be removed once fixed:
|
||||||
@@ -53,10 +57,14 @@ idf_component_register( SRC_DIRS ${SRC_DIRS_LIST}
|
|||||||
idf_build_set_property(COMPILE_OPTIONS "-Wno-error=uninitialized;-Wno-error=maybe-uninitialized;-Wno-missing-field-initializers;" APPEND)
|
idf_build_set_property(COMPILE_OPTIONS "-Wno-error=uninitialized;-Wno-error=maybe-uninitialized;-Wno-missing-field-initializers;" APPEND)
|
||||||
idf_build_set_property(COMPILE_OPTIONS "-Wno-error=array-bounds" APPEND)
|
idf_build_set_property(COMPILE_OPTIONS "-Wno-error=array-bounds" APPEND)
|
||||||
|
|
||||||
if (NOT CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
if (CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER)
|
||||||
|
if (CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
||||||
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u data_model_utils_impl")
|
||||||
|
else()
|
||||||
target_include_directories(${COMPONENT_LIB} PUBLIC "${CMAKE_BINARY_DIR}/gen/__idf_main-codegen/cpp-app"
|
target_include_directories(${COMPONENT_LIB} PUBLIC "${CMAKE_BINARY_DIR}/gen/__idf_main-codegen/cpp-app"
|
||||||
"${CMAKE_BINARY_DIR}/gen/__idf_main-zapgen/zapgen/app-templates")
|
"${CMAKE_BINARY_DIR}/gen/__idf_main-zapgen/zapgen/app-templates")
|
||||||
endif()
|
endif(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
||||||
|
endif(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER)
|
||||||
|
|
||||||
target_sources(${COMPONENT_LIB} PRIVATE ${MATTER_SDK_PATH}/src/app/StorageDelegateWrapper.cpp
|
target_sources(${COMPONENT_LIB} PRIVATE ${MATTER_SDK_PATH}/src/app/StorageDelegateWrapper.cpp
|
||||||
${MATTER_SDK_PATH}/src/app/SafeAttributePersistenceProvider.cpp)
|
${MATTER_SDK_PATH}/src/app/SafeAttributePersistenceProvider.cpp)
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ menu "ESP Matter"
|
|||||||
|
|
||||||
config ESP_MATTER_ENABLE_DATA_MODEL
|
config ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
bool "Use ESP-Matter data model"
|
bool "Use ESP-Matter data model"
|
||||||
|
depends on ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
This option should be disable for zap examples
|
This option should be disable for zap examples
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <esp_matter_core.h>
|
#include <esp_matter_data_model.h>
|
||||||
|
|
||||||
namespace esp_matter {
|
namespace esp_matter {
|
||||||
namespace cluster {
|
namespace cluster {
|
||||||
+2
@@ -15,6 +15,8 @@
|
|||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include <esp_matter_attribute_bounds.h>
|
#include <esp_matter_attribute_bounds.h>
|
||||||
|
|
||||||
|
#include <app-common/zap-generated/ids/Attributes.h>
|
||||||
|
|
||||||
static const char *TAG = "esp_matter_cluster";
|
static const char *TAG = "esp_matter_cluster";
|
||||||
|
|
||||||
using namespace chip::app::Clusters;
|
using namespace chip::app::Clusters;
|
||||||
+1
-1
@@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <esp_matter_core.h>
|
#include <esp_matter_data_model.h>
|
||||||
|
|
||||||
namespace esp_matter {
|
namespace esp_matter {
|
||||||
namespace cluster {
|
namespace cluster {
|
||||||
-3
@@ -114,7 +114,6 @@ cluster_t *create_default_binding_cluster(endpoint_t *endpoint)
|
|||||||
return binding::create(endpoint, &config, CLUSTER_FLAG_SERVER);
|
return binding::create(endpoint, &config, CLUSTER_FLAG_SERVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
|
||||||
namespace descriptor {
|
namespace descriptor {
|
||||||
const function_generic_t *function_list = NULL;
|
const function_generic_t *function_list = NULL;
|
||||||
const int function_flags = CLUSTER_FLAG_NONE;
|
const int function_flags = CLUSTER_FLAG_NONE;
|
||||||
@@ -3727,7 +3726,5 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags)
|
|||||||
// // ToDo
|
// // ToDo
|
||||||
// } /* audio_output */
|
// } /* audio_output */
|
||||||
|
|
||||||
#endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */
|
|
||||||
|
|
||||||
} /* cluster */
|
} /* cluster */
|
||||||
} /* esp_matter */
|
} /* esp_matter */
|
||||||
+2
-1
@@ -14,13 +14,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <esp_matter_core.h>
|
|
||||||
#include <esp_matter_attribute.h>
|
#include <esp_matter_attribute.h>
|
||||||
#include <esp_matter_feature.h>
|
#include <esp_matter_feature.h>
|
||||||
|
#include <esp_matter_data_model.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <app-common/zap-generated/cluster-enums.h>
|
#include <app-common/zap-generated/cluster-enums.h>
|
||||||
#include <lib/support/TypeTraits.h>
|
#include <lib/support/TypeTraits.h>
|
||||||
|
#include <platform/ESP32/CHIPDevicePlatformConfig.h>
|
||||||
|
|
||||||
namespace esp_matter {
|
namespace esp_matter {
|
||||||
namespace cluster {
|
namespace cluster {
|
||||||
-4
@@ -3225,7 +3225,6 @@ constexpr const cluster_command_t cluster_command_table[] = {
|
|||||||
{GroupKeyManagement::Id, GET_COMMAND_COUNT_LIST(cluster::group_key_management)},
|
{GroupKeyManagement::Id, GET_COMMAND_COUNT_LIST(cluster::group_key_management)},
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) && defined(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
|
||||||
const command_entry_t *get_cluster_accepted_command_list(uint32_t cluster_id)
|
const command_entry_t *get_cluster_accepted_command_list(uint32_t cluster_id)
|
||||||
{
|
{
|
||||||
for (auto const &cluster_command : cluster_command_table) {
|
for (auto const &cluster_command : cluster_command_table) {
|
||||||
@@ -3265,11 +3264,9 @@ size_t get_cluster_generated_command_count(uint32_t cluster_id)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif // defined(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) && defined(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
|
||||||
|
|
||||||
static callback_t get_cluster_accepted_command(uint32_t cluster_id, uint32_t command_id)
|
static callback_t get_cluster_accepted_command(uint32_t cluster_id, uint32_t command_id)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) && defined(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
|
||||||
for (auto const &cluster_command : cluster_command_table) {
|
for (auto const &cluster_command : cluster_command_table) {
|
||||||
if (cluster_command.cluster_id == cluster_id) {
|
if (cluster_command.cluster_id == cluster_id) {
|
||||||
for (size_t index = 0; index < cluster_command.accepted_command_count; ++index){
|
for (size_t index = 0; index < cluster_command.accepted_command_count; ++index){
|
||||||
@@ -3279,7 +3276,6 @@ static callback_t get_cluster_accepted_command(uint32_t cluster_id, uint32_t com
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,958 @@
|
|||||||
|
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_matter_attribute_utils.h>
|
||||||
|
#include "app/ConcreteCommandPath.h"
|
||||||
|
#include "app/util/af-types.h"
|
||||||
|
#include "lib/core/TLVReader.h"
|
||||||
|
|
||||||
|
#define ESP_MATTER_NVS_PART_NAME CONFIG_ESP_MATTER_NVS_PART_NAME
|
||||||
|
|
||||||
|
using chip::app::ConcreteCommandPath;
|
||||||
|
using chip::TLV::TLVReader;
|
||||||
|
using chip::DeviceLayer::ChipDeviceEvent;
|
||||||
|
|
||||||
|
namespace esp_matter {
|
||||||
|
|
||||||
|
/** Generic handle */
|
||||||
|
typedef size_t handle_t;
|
||||||
|
/** Node handle */
|
||||||
|
typedef handle_t node_t;
|
||||||
|
/** Endpoint handle */
|
||||||
|
typedef handle_t endpoint_t;
|
||||||
|
/** Cluster handle */
|
||||||
|
typedef handle_t cluster_t;
|
||||||
|
/** Attribute handle */
|
||||||
|
typedef handle_t attribute_t;
|
||||||
|
/** Command handle */
|
||||||
|
typedef handle_t command_t;
|
||||||
|
/** Event handle */
|
||||||
|
typedef handle_t event_t;
|
||||||
|
|
||||||
|
/** Endpoint flags */
|
||||||
|
typedef enum endpoint_flags {
|
||||||
|
/** No specific flags */
|
||||||
|
ENDPOINT_FLAG_NONE = 0x00,
|
||||||
|
/** The endpoint can be destroyed using `endpoint::destroy()` */
|
||||||
|
ENDPOINT_FLAG_DESTROYABLE = 0x01,
|
||||||
|
/** The endpoint is a bridged node */
|
||||||
|
ENDPOINT_FLAG_BRIDGE = 0x02,
|
||||||
|
} endpoint_flags_t;
|
||||||
|
|
||||||
|
/** Cluster flags */
|
||||||
|
typedef enum cluster_flags {
|
||||||
|
/** No specific flags */
|
||||||
|
CLUSTER_FLAG_NONE = 0x00,
|
||||||
|
/** The cluster has an init function (function_flag) */
|
||||||
|
CLUSTER_FLAG_INIT_FUNCTION = MATTER_CLUSTER_FLAG_INIT_FUNCTION, /* 0x01 */
|
||||||
|
/** The cluster has an attribute changed function (function_flag) */
|
||||||
|
CLUSTER_FLAG_ATTRIBUTE_CHANGED_FUNCTION = MATTER_CLUSTER_FLAG_ATTRIBUTE_CHANGED_FUNCTION, /* 0x02 */
|
||||||
|
/** The cluster has a shutdown function (function_flag) */
|
||||||
|
CLUSTER_FLAG_SHUTDOWN_FUNCTION = MATTER_CLUSTER_FLAG_SHUTDOWN_FUNCTION, /* 0x10 */
|
||||||
|
/** The cluster has a pre attribute changed function (function_flag) */
|
||||||
|
CLUSTER_FLAG_PRE_ATTRIBUTE_CHANGED_FUNCTION = MATTER_CLUSTER_FLAG_PRE_ATTRIBUTE_CHANGED_FUNCTION, /* 0x20 */
|
||||||
|
/** The cluster is a server cluster */
|
||||||
|
CLUSTER_FLAG_SERVER = MATTER_CLUSTER_FLAG_SERVER, /* 0x40 */
|
||||||
|
/** The cluster is a client cluster */
|
||||||
|
CLUSTER_FLAG_CLIENT = MATTER_CLUSTER_FLAG_CLIENT, /* 0x80 */
|
||||||
|
} cluster_flags_t;
|
||||||
|
|
||||||
|
/** Attribute flags */
|
||||||
|
typedef enum attribute_flags {
|
||||||
|
/** No specific flags */
|
||||||
|
ATTRIBUTE_FLAG_NONE = 0x00,
|
||||||
|
/** The attribute is writable and can be directly changed by clients */
|
||||||
|
ATTRIBUTE_FLAG_WRITABLE = MATTER_ATTRIBUTE_FLAG_WRITABLE, /* 0x01 */
|
||||||
|
/** The attribute is non volatile and its value will be stored in NVS */
|
||||||
|
ATTRIBUTE_FLAG_NONVOLATILE = MATTER_ATTRIBUTE_FLAG_NONVOLATILE, /* 0x02 */
|
||||||
|
/** The attribute has bounds */
|
||||||
|
ATTRIBUTE_FLAG_MIN_MAX = MATTER_ATTRIBUTE_FLAG_MIN_MAX, /* 0x04 */
|
||||||
|
ATTRIBUTE_FLAG_MUST_USE_TIMED_WRITE = MATTER_ATTRIBUTE_FLAG_MUST_USE_TIMED_WRITE, /* 0x08 */
|
||||||
|
/** The attribute uses external storage for its value. If attributes
|
||||||
|
have this flag enabled, as all of them are stored in the ESP Matter database. */
|
||||||
|
ATTRIBUTE_FLAG_EXTERNAL_STORAGE = MATTER_ATTRIBUTE_FLAG_EXTERNAL_STORAGE, /* 0x10 */
|
||||||
|
ATTRIBUTE_FLAG_SINGLETON = MATTER_ATTRIBUTE_FLAG_SINGLETON, /* 0x20 */
|
||||||
|
ATTRIBUTE_FLAG_NULLABLE = MATTER_ATTRIBUTE_FLAG_NULLABLE, /* 0x40 */
|
||||||
|
/** The attribute read and write are overridden. The attribute value will be fetched from and will be updated using
|
||||||
|
the override callback. The value of this attribute is not maintained internally. */
|
||||||
|
ATTRIBUTE_FLAG_OVERRIDE = ATTRIBUTE_FLAG_NULLABLE << 1, /* 0x80 */
|
||||||
|
/** The attribute is non-volatile but its value will be changed frequently. If an attribute has this flag, its value
|
||||||
|
will not be written to flash immediately. A timer will be started and the attribute value will be written after
|
||||||
|
timeout. */
|
||||||
|
ATTRIBUTE_FLAG_DEFERRED = ATTRIBUTE_FLAG_NULLABLE << 2, /* 0x100 */
|
||||||
|
/** The attribute is managed internally and is not stored in the ESP Matter database.
|
||||||
|
If not set, ATTRIBUTE_FLAG_EXTERNAL_STORAGE flag will be enabled. */
|
||||||
|
ATTRIBUTE_FLAG_MANAGED_INTERNALLY = ATTRIBUTE_FLAG_NULLABLE << 3, /* 0x200 */
|
||||||
|
} attribute_flags_t;
|
||||||
|
|
||||||
|
/** Command flags */
|
||||||
|
typedef enum command_flags {
|
||||||
|
/** No specific flags */
|
||||||
|
COMMAND_FLAG_NONE = 0x00,
|
||||||
|
/** The command is not a standard command */
|
||||||
|
COMMAND_FLAG_CUSTOM = 0x01,
|
||||||
|
/** The command is client generated */
|
||||||
|
COMMAND_FLAG_ACCEPTED = 0x02,
|
||||||
|
/** The command is server generated */
|
||||||
|
COMMAND_FLAG_GENERATED = 0x04,
|
||||||
|
} command_flags_t;
|
||||||
|
|
||||||
|
namespace node {
|
||||||
|
|
||||||
|
/** Create raw node
|
||||||
|
*
|
||||||
|
* @return Node handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
|
||||||
|
/** Get the endpoint count for a server cluster
|
||||||
|
*
|
||||||
|
* Get the number of endpoints that have the given cluster ID as a server cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster_id Cluster ID.
|
||||||
|
*
|
||||||
|
* @return Endpoint count on success.
|
||||||
|
* @return 0 in case of failure or if not found on any endpoint.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t get_server_cluster_endpoint_count(uint32_t cluster_id);
|
||||||
|
|
||||||
|
/** Get the endpoint count for a client cluster
|
||||||
|
*
|
||||||
|
* Get the number of endpoints that have the given cluster ID as a client cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster_id Cluster ID.
|
||||||
|
*
|
||||||
|
* @return Endpoint count on success.
|
||||||
|
* @return 0 in case of failure or if not found on any endpoint.
|
||||||
|
*/
|
||||||
|
uint32_t get_client_cluster_endpoint_count(uint32_t cluster_id);
|
||||||
|
|
||||||
|
} /* node */
|
||||||
|
|
||||||
|
namespace endpoint {
|
||||||
|
|
||||||
|
/** Create endpoint
|
||||||
|
*
|
||||||
|
* This will create a new endpoint with a unique endpoint_id and add the endpoint to the node.
|
||||||
|
*
|
||||||
|
* @param[in] node Node handle.
|
||||||
|
* @param[in] flags Bitmap of `endpoint_flags_t`.
|
||||||
|
* @param[in] priv_data (Optional) Private data associated with the endpoint. This will be passed to the
|
||||||
|
* attribute_update and identify callbacks. It should stay allocated throughout the lifetime of the device.
|
||||||
|
*
|
||||||
|
* @return Endpoint handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
endpoint_t *create(node_t *node, uint8_t flags, void *priv_data);
|
||||||
|
|
||||||
|
/** Resume endpoint
|
||||||
|
*
|
||||||
|
* This will resume an endpoint after reboot and add it to the node.
|
||||||
|
*
|
||||||
|
* @param[in] node Node handle.
|
||||||
|
* @param[in] flags Bitmap of `endpoint_flags_t`.
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the endpoint resumed.
|
||||||
|
* @param[in] priv_data (Optional) Private data associated with the endpoint. This will be passed to the
|
||||||
|
* attribute_update and identify callbacks. It should stay allocated throughout the lifetime of the device.
|
||||||
|
*
|
||||||
|
* @return Endpoint handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
endpoint_t *resume(node_t *node, uint8_t flags, uint16_t endpoint_id, void *priv_data);
|
||||||
|
|
||||||
|
/** Destroy endpoint
|
||||||
|
*
|
||||||
|
* This will destroy the endpoint which has been created and added to the node. It also destroys the associated
|
||||||
|
* clusters, attributes and commands.
|
||||||
|
*
|
||||||
|
* @param[in] node Node handle.
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t destroy(node_t *node, endpoint_t *endpoint);
|
||||||
|
|
||||||
|
/** Get endpoint
|
||||||
|
*
|
||||||
|
* Get the endpoint present on the node.
|
||||||
|
*
|
||||||
|
* @param[in] node Node handle.
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the endpoint.
|
||||||
|
*
|
||||||
|
* @return Endpoint handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
endpoint_t *get(node_t *node, uint16_t endpoint_id);
|
||||||
|
|
||||||
|
/** Get endpoint
|
||||||
|
*
|
||||||
|
* Get the endpoint present on the node.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the endpoint.
|
||||||
|
*
|
||||||
|
* @return Endpoint handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
endpoint_t *get(uint16_t endpoint_id);
|
||||||
|
|
||||||
|
/** Get first endpoint
|
||||||
|
*
|
||||||
|
* Get the first endpoint present on the node.
|
||||||
|
*
|
||||||
|
* @param[in] node Node handle.
|
||||||
|
*
|
||||||
|
* @return Endpoint handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
endpoint_t *get_first(node_t *node);
|
||||||
|
|
||||||
|
/** Get next endpoint
|
||||||
|
*
|
||||||
|
* Get the next endpoint present on the node.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
*
|
||||||
|
* @return Endpoint handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
endpoint_t *get_next(endpoint_t *endpoint);
|
||||||
|
|
||||||
|
/** Get endpoint count
|
||||||
|
*
|
||||||
|
* Get the endpoint count present on the node.
|
||||||
|
*
|
||||||
|
* @param[in] node Node handle.
|
||||||
|
*
|
||||||
|
* @return Endpoint count on success.
|
||||||
|
* @return 0 in case of failure.
|
||||||
|
*/
|
||||||
|
uint16_t get_count(node_t *node);
|
||||||
|
|
||||||
|
/** Get endpoint ID
|
||||||
|
*
|
||||||
|
* Get the endpoint ID for the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
*
|
||||||
|
* @return Endpoint ID on success.
|
||||||
|
* @return Invalid Endpoint ID (0xFFFF) in case of failure.
|
||||||
|
*/
|
||||||
|
uint16_t get_id(endpoint_t *endpoint);
|
||||||
|
|
||||||
|
/** Add device type ID and verision
|
||||||
|
*
|
||||||
|
* Add the device type ID and version for the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
* @param[in] device_type_id Device type ID.
|
||||||
|
* @param[in] device_type_version Device type version.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t add_device_type(endpoint_t *endpoint, uint32_t device_type_id, uint8_t device_type_version);
|
||||||
|
|
||||||
|
/** Get device type ID array
|
||||||
|
*
|
||||||
|
* Get the device type ID array for the endpoint. This array is aligned with the device type version array.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
* @param[out] device_type_count_ptr the pointer of device type ID array length.
|
||||||
|
*
|
||||||
|
* @return device type ID array on success.
|
||||||
|
* @return NULL when the endpoint or the device_type_count_ptr is NULL.
|
||||||
|
*/
|
||||||
|
uint32_t *get_device_type_ids(endpoint_t *endpoint, uint8_t *device_type_count_ptr);
|
||||||
|
|
||||||
|
/** Get device type version array
|
||||||
|
*
|
||||||
|
* Get the device type version array for the endpoint. This array is aligned with the device type ID array.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
* @param[out] device_type_count_ptr the pointer of device type version array length.
|
||||||
|
*
|
||||||
|
* @return device type version array on success.
|
||||||
|
* @return NULL when the endpoint or the device_type_count_ptr is NULL.
|
||||||
|
*/
|
||||||
|
uint8_t *get_device_type_versions(endpoint_t *endpoint, uint8_t *device_type_count_ptr);
|
||||||
|
|
||||||
|
/** Set parent endpoint
|
||||||
|
*
|
||||||
|
* Set the parent endpoint. This is useful in correctly setting the parts_list attribute for the parent, when the
|
||||||
|
* parent is a composite endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
* @param[out] parent_endpoint Parent endpoint handle.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_parent_endpoint(endpoint_t *endpoint, endpoint_t *parent_endpoint);
|
||||||
|
|
||||||
|
/** Get private data
|
||||||
|
*
|
||||||
|
* Get the private data passed while creating the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the endpoint.
|
||||||
|
*
|
||||||
|
* @return Private data on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
void *get_priv_data(uint16_t endpoint_id);
|
||||||
|
|
||||||
|
/** Set private data
|
||||||
|
*
|
||||||
|
* Set the private data after creating the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the endpoint.
|
||||||
|
* @param[in] priv_data Private data of the endpoint.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return ESP_ERR_INVALID_STATE or ESP_ERR_NOT_FOUND in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_priv_data(uint16_t endpoint_id, void *priv_data);
|
||||||
|
|
||||||
|
/** Set identify
|
||||||
|
*
|
||||||
|
* Set identify to the endpoint. The identify pointer should be dynamically allocated using 'chip::Platform::New<Identify>()',
|
||||||
|
* and once Matter stack is done using it, it will be freed by 'chip::Platform::Delete()'.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint id.
|
||||||
|
* @param[in] identify Identify pointer.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_identify(uint16_t endpoint_id, void *identify);
|
||||||
|
|
||||||
|
/** Enable endpoint
|
||||||
|
*
|
||||||
|
* Enable the endpoint which has been previously created.
|
||||||
|
*
|
||||||
|
* @note: This API only needs to be called for endpoints created after calling esp_matter::start(). It should be
|
||||||
|
* called after all the clusters, attributes and commands have been added to the created endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t enable(endpoint_t *endpoint);
|
||||||
|
|
||||||
|
} /* endpoint */
|
||||||
|
|
||||||
|
namespace cluster {
|
||||||
|
|
||||||
|
/** Cluster plugin server init callback
|
||||||
|
*
|
||||||
|
* This callback will be called when the endpoints are initialised. This should be set to upstream's
|
||||||
|
* `Matter<cluster_name>PluginServerInitCallback` API, if it exists.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/** Cluster add bounds callback
|
||||||
|
*
|
||||||
|
* This callback will be called when the endpoints are initialised.
|
||||||
|
*/
|
||||||
|
typedef void (*add_bounds_callback_t)(cluster_t *cluster);
|
||||||
|
|
||||||
|
/** Generic function
|
||||||
|
*
|
||||||
|
* This can be used to add additional functions based on `cluster_flags_t`.
|
||||||
|
*/
|
||||||
|
typedef void (*function_generic_t)();
|
||||||
|
|
||||||
|
/** Create cluster
|
||||||
|
*
|
||||||
|
* This will create a new cluster and add it to the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
* @param[in] cluster_id Cluster ID for the cluster.
|
||||||
|
* @param[in] flags Bitmap of `cluster_flags_t`.
|
||||||
|
*
|
||||||
|
* @return Cluster handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
cluster_t *create(endpoint_t *endpoint, uint32_t cluster_id, uint8_t flags);
|
||||||
|
|
||||||
|
/** Destroy cluster
|
||||||
|
*
|
||||||
|
* This will destroy the cluster which has been created and added to the endpoint. It also destroys the associated
|
||||||
|
* attributes, commands and events.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t destroy(cluster_t *cluster);
|
||||||
|
|
||||||
|
/** Get cluster
|
||||||
|
*
|
||||||
|
* Get the cluster present on the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
* @param[in] cluster_id Cluster ID for the cluster.
|
||||||
|
*
|
||||||
|
* @return Cluster handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
cluster_t *get(endpoint_t *endpoint, uint32_t cluster_id);
|
||||||
|
|
||||||
|
/** Get cluster
|
||||||
|
*
|
||||||
|
* Get the cluster present on the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint id.
|
||||||
|
* @param[in] cluster_id Cluster ID for the cluster.
|
||||||
|
*
|
||||||
|
* @return Cluster handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
cluster_t *get(uint16_t endpoint_id, uint32_t cluster_id);
|
||||||
|
|
||||||
|
/** Get first cluster
|
||||||
|
*
|
||||||
|
* Get the first cluster present on the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint Endpoint handle.
|
||||||
|
*
|
||||||
|
* @return Cluster handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
cluster_t *get_first(endpoint_t *endpoint);
|
||||||
|
|
||||||
|
/** Get next cluster
|
||||||
|
*
|
||||||
|
* Get the next cluster present on the endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return Cluster handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
cluster_t *get_next(cluster_t *cluster);
|
||||||
|
|
||||||
|
/** Get cluster ID
|
||||||
|
*
|
||||||
|
* Get the cluster ID for the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return Cluster ID on success.
|
||||||
|
* @return Invalid CLuster ID (0xFFFF'FFFF) in case of failure.
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
* callback should be set to upstream's `Matter<cluster_name>PluginServerInitCallback` API for the cluster, if it
|
||||||
|
* exists.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] callback Plugin server init callback.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/** Set server cluster add bounds callback
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] callback Add bounds callback.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_add_bounds_callback(cluster_t *cluster, add_bounds_callback_t callback);
|
||||||
|
|
||||||
|
/** Get cluster plugin server init callback
|
||||||
|
*
|
||||||
|
* Get the cluster plugin server init callback which has previously been set.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return Plugin server init callback.
|
||||||
|
* @return NULL in case of failure or if it has not been set.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/** Get server cluster add bounds callback
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return add bounds callback.
|
||||||
|
* @return NULL in case of failure or if it has not been set.
|
||||||
|
*/
|
||||||
|
add_bounds_callback_t get_add_bounds_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
|
||||||
|
* to upstream's `Matter<cluster_name>Server<function_type>Callback` or
|
||||||
|
* `emberAf<cluster_name>Server<function_type>Callback` API, if it exists. The corresponding function_flags must be be
|
||||||
|
* set.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] function_list Array of function_generic_t.
|
||||||
|
* @param[in] function_flags Bitmap of cluster flags corresponding to the function_list.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t add_function_list(cluster_t *cluster, const function_generic_t *function_list, int function_flags);
|
||||||
|
|
||||||
|
} /* cluster */
|
||||||
|
|
||||||
|
namespace attribute {
|
||||||
|
|
||||||
|
/** Create attribute
|
||||||
|
*
|
||||||
|
* This will create a new attribute and add it to the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] attribute_id Attribute ID for the attribute.
|
||||||
|
* @param[in] flags Bitmap of `attribute_flags_t`.
|
||||||
|
* @param[in] val Default type and value of the attribute. Use appropriate elements as per the value type.
|
||||||
|
* @param[in] max_val_size For attributes of type char string and long char string, the size should correspond to the
|
||||||
|
* maximum size defined in the specification. However, for other types of attributes, this
|
||||||
|
* parameter remains unused, and therefore the default value is set to 0
|
||||||
|
*
|
||||||
|
* @return Attribute handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
attribute_t *create(cluster_t *cluster, uint32_t attribute_id, uint16_t flags, esp_matter_attr_val_t val,
|
||||||
|
uint16_t max_val_size = 0);
|
||||||
|
|
||||||
|
/** Get attribute
|
||||||
|
*
|
||||||
|
* Get the attribute present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] attribute_id Attribute ID for the attribute.
|
||||||
|
*
|
||||||
|
* @return Attribute handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
attribute_t *get(cluster_t *cluster, uint32_t attribute_id);
|
||||||
|
|
||||||
|
/** Get attribute
|
||||||
|
*
|
||||||
|
* Get the attribute present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint id..
|
||||||
|
* @param[in] cluster_id Cluster ID for the Cluster.
|
||||||
|
* @param[in] attribute_id Attribute ID for the attribute.
|
||||||
|
*
|
||||||
|
* @return Attribute handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
attribute_t *get(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get first attribute
|
||||||
|
*
|
||||||
|
* Get the first attribute present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return Attribute handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
attribute_t *get_first(cluster_t *cluster);
|
||||||
|
|
||||||
|
/** Get next attribute
|
||||||
|
*
|
||||||
|
* Get the next attribute present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
*
|
||||||
|
* @return Attribute handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
attribute_t *get_next(attribute_t *attribute);
|
||||||
|
|
||||||
|
/** Get attribute ID
|
||||||
|
*
|
||||||
|
* Get the attribute ID for the attribute.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
*
|
||||||
|
* @return Attribute ID on success.
|
||||||
|
* @return Invalid Attribute ID (0xFFFF'FFFF) in case of failure.
|
||||||
|
*/
|
||||||
|
uint32_t get_id(attribute_t *attribute);
|
||||||
|
|
||||||
|
/** Set attribute val
|
||||||
|
*
|
||||||
|
* Set/Update the value of the attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag) in the database.
|
||||||
|
*
|
||||||
|
* @note: Once `esp_matter::start()` is done, `attribute::update()` should be used to update the attribute value.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_val(attribute_t *attribute, esp_matter_attr_val_t *val);
|
||||||
|
|
||||||
|
/** Get attribute val
|
||||||
|
*
|
||||||
|
* Get the value of the attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag) from the database.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
* @param[out] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t get_val(attribute_t *attribute, esp_matter_attr_val_t *val);
|
||||||
|
|
||||||
|
/** Add attribute bounds
|
||||||
|
*
|
||||||
|
* Add bounds to the attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag). Bounds cannot be added to string/array type attributes.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
* @param[in] min Minimum allowed value.
|
||||||
|
* @param[in] max Maximum allowed value.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t add_bounds(attribute_t *attribute, esp_matter_attr_val_t min, esp_matter_attr_val_t max);
|
||||||
|
|
||||||
|
/** Get attribute bounds
|
||||||
|
*
|
||||||
|
* Get the bounds which have been added to the attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag).
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
* @param[in] bounds Pointer to `esp_matter_attr_bounds_t`.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t get_bounds(attribute_t *attribute, esp_matter_attr_bounds_t *bounds);
|
||||||
|
|
||||||
|
/** Get attribute flags
|
||||||
|
*
|
||||||
|
* Get the attribute flags for the attribute.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
*
|
||||||
|
* @return Attribute flags.
|
||||||
|
*/
|
||||||
|
uint16_t get_flags(attribute_t *attribute);
|
||||||
|
|
||||||
|
/** Set attribute override
|
||||||
|
*
|
||||||
|
* Set the override callback for the attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag). For attribute read and write calls, instead of doing that from the
|
||||||
|
* common database, this callback will be called.
|
||||||
|
*
|
||||||
|
* This can be used if the application or some component wants to maintain the attribute's value in the application or
|
||||||
|
* in that component respectively. It can also be used if the attribute value needs to be dynamically fetched and is
|
||||||
|
* difficult to maintain in the database.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
* @param[in] callback Override callback.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_override_callback(attribute_t *attribute, callback_t callback);
|
||||||
|
|
||||||
|
/** Get attribute override
|
||||||
|
*
|
||||||
|
* Get the override callback for the attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag).
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
*
|
||||||
|
* @return Attribute override callback.
|
||||||
|
*/
|
||||||
|
callback_t get_override_callback(attribute_t *attribute);
|
||||||
|
|
||||||
|
/** Set attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag) deferred persistence
|
||||||
|
*
|
||||||
|
* Only non-volatile attributes can be set with deferred presistence. If an attribute is configured with deferred
|
||||||
|
* presistence, any modifications to it will be enacted in its persistent storage with a specific delay
|
||||||
|
* (CONFIG_ESP_MATTER_DEFERRED_ATTR_PERSISTENCE_TIME_MS)
|
||||||
|
*
|
||||||
|
* It could be used for the non-volatile attribues which might be changed rapidly, such as CurrentLevel in LevelControl
|
||||||
|
* cluster.
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_deferred_persistence(attribute_t *attribute);
|
||||||
|
|
||||||
|
} /* attribute */
|
||||||
|
|
||||||
|
namespace command {
|
||||||
|
|
||||||
|
/** Command callback
|
||||||
|
*
|
||||||
|
* Command callback which is called when the command is invoked.
|
||||||
|
*
|
||||||
|
* @note: If the `COMMAND_FLAG_CUSTOM` is set, the default command response is sent internally based on the
|
||||||
|
* return value from the callback.
|
||||||
|
*
|
||||||
|
* @param[in] command_path Common structure for endpoint, cluster and commands IDs.
|
||||||
|
* @param[in] tlv_data Command data in TLV format.
|
||||||
|
* @param[in] opaque_ptr This is a pointer which is used internally.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
typedef esp_err_t (*callback_t)(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr);
|
||||||
|
|
||||||
|
/** Create command
|
||||||
|
*
|
||||||
|
* This will create a new command and add it to the cluster.
|
||||||
|
*
|
||||||
|
* @note: For commands which are not defined in the spec the `COMMAND_FLAG_CUSTOM` flag must be set. This
|
||||||
|
* will send the command response internally, after the command callback is called.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] command_id Command ID for the command.
|
||||||
|
* @param[in] flags Bitmap of `command_flags_t`.
|
||||||
|
* @param[in] callback Command callback
|
||||||
|
*
|
||||||
|
* @return Command handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
command_t *create(cluster_t *cluster, uint32_t command_id, uint8_t flags, callback_t callback);
|
||||||
|
|
||||||
|
/** Get command
|
||||||
|
*
|
||||||
|
* Get the command present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] command_id Command ID for the command.
|
||||||
|
* @param[in] flags Command flags for the command to be fetched.
|
||||||
|
*
|
||||||
|
* @return Command handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
command_t *get(cluster_t *cluster, uint32_t command_id, uint16_t flags);
|
||||||
|
|
||||||
|
/** Get first command
|
||||||
|
*
|
||||||
|
* Get the first command present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return Command handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
command_t *get_first(cluster_t *cluster);
|
||||||
|
|
||||||
|
/** Get next command
|
||||||
|
*
|
||||||
|
* Get the next command present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] command Command handle.
|
||||||
|
*
|
||||||
|
* @return Command handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
command_t *get_next(command_t *command);
|
||||||
|
|
||||||
|
/** Get command ID
|
||||||
|
*
|
||||||
|
* Get the command ID for the command.
|
||||||
|
*
|
||||||
|
* @param[in] command Command handle.
|
||||||
|
*
|
||||||
|
* @return Command ID on success.
|
||||||
|
* @return Invalid Command ID (0xFFFF'FFFF) in case of failure.
|
||||||
|
*/
|
||||||
|
uint32_t get_id(command_t *command);
|
||||||
|
|
||||||
|
/** Get command callback
|
||||||
|
*
|
||||||
|
* Get the command callback for the command.
|
||||||
|
*
|
||||||
|
* @param[in] command Command handle.
|
||||||
|
*
|
||||||
|
* @return Command callback on success.
|
||||||
|
* @return NULL in case of failure or if the callback was not set when creating the command.
|
||||||
|
*/
|
||||||
|
callback_t get_callback(command_t *command);
|
||||||
|
|
||||||
|
/** Get command user_callback
|
||||||
|
*
|
||||||
|
* Get the command user_callback for the command.
|
||||||
|
*
|
||||||
|
* @param[in] command Command handle.
|
||||||
|
*
|
||||||
|
* @return Command user_callback on success.
|
||||||
|
* @return NULL in case of failure or if the callback was not set when creating the command.
|
||||||
|
*/
|
||||||
|
callback_t get_user_callback(command_t *command);
|
||||||
|
|
||||||
|
/** Set command user_callback
|
||||||
|
*
|
||||||
|
* Set the user_callback for the command.
|
||||||
|
*
|
||||||
|
* @param[in] command Command handle.
|
||||||
|
* @param[in] user_callback callback_t.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void set_user_callback(command_t *command, callback_t user_callback);
|
||||||
|
|
||||||
|
/** Get command flags
|
||||||
|
*
|
||||||
|
* Get the command flags for the command.
|
||||||
|
*
|
||||||
|
* @param[in] command Command handle.
|
||||||
|
*
|
||||||
|
* @return Command flags.
|
||||||
|
*/
|
||||||
|
uint16_t get_flags(command_t *command);
|
||||||
|
|
||||||
|
} /* command */
|
||||||
|
|
||||||
|
namespace event {
|
||||||
|
|
||||||
|
/** Create event
|
||||||
|
*
|
||||||
|
* This will create a new event and add it to the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] event_id Event ID for the event.
|
||||||
|
*
|
||||||
|
* @return Event handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
event_t *create(cluster_t *cluster, uint32_t event_id);
|
||||||
|
|
||||||
|
/** Get event
|
||||||
|
*
|
||||||
|
* Get the event present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
* @param[in] event_id Event ID for the command.
|
||||||
|
*
|
||||||
|
* @return Event handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
event_t *get(cluster_t *cluster, uint32_t event_id);
|
||||||
|
|
||||||
|
/** Get first event
|
||||||
|
*
|
||||||
|
* Get the first event present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] cluster Cluster handle.
|
||||||
|
*
|
||||||
|
* @return Event handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
event_t *get_first(cluster_t *cluster);
|
||||||
|
|
||||||
|
/** Get next event
|
||||||
|
*
|
||||||
|
* Get the next event present on the cluster.
|
||||||
|
*
|
||||||
|
* @param[in] event Event handle.
|
||||||
|
*
|
||||||
|
* @return Event handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
event_t *get_next(event_t *event);
|
||||||
|
|
||||||
|
/** Get event ID
|
||||||
|
*
|
||||||
|
* Get the event ID for the event.
|
||||||
|
*
|
||||||
|
* @param[in] event Event handle.
|
||||||
|
*
|
||||||
|
* @return Event ID on success.
|
||||||
|
* @return Invalid Event ID (0xFFFF'FFFF) in case of failure.
|
||||||
|
*/
|
||||||
|
uint32_t get_id(event_t *event);
|
||||||
|
|
||||||
|
} /* event */
|
||||||
|
} /* esp_matter */
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include <esp_matter.h>
|
||||||
|
#include <esp_matter_attribute_utils.h>
|
||||||
|
#include <esp_matter_data_model.h>
|
||||||
|
#include <esp_matter_data_model_priv.h>
|
||||||
|
|
||||||
|
#include <app/util/attribute-storage.h>
|
||||||
|
#include <protocols/interaction_model/StatusCode.h>
|
||||||
|
|
||||||
|
using chip::Protocols::InteractionModel::Status;
|
||||||
|
using namespace chip;
|
||||||
|
|
||||||
|
static const char *TAG = "data_model";
|
||||||
|
|
||||||
|
namespace esp_matter {
|
||||||
|
|
||||||
|
static esp_err_t execute_override_callback(attribute_t *attribute, attribute::callback_type_t type,
|
||||||
|
uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id,
|
||||||
|
esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
attribute::callback_t override_callback = attribute::get_override_callback(attribute);
|
||||||
|
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
||||||
|
if (override_callback) {
|
||||||
|
return override_callback(type, endpoint_id, cluster_id, attribute_id, val, priv_data);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG,
|
||||||
|
"Attribute override callback not set for Endpoint 0x%04" PRIX16 "'s Cluster 0x%08" PRIX32
|
||||||
|
"'s Attribute 0x%08" PRIX32 ", calling the common callback",
|
||||||
|
endpoint_id, cluster_id, attribute_id);
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
} // namespace esp_matter
|
||||||
|
|
||||||
|
using namespace esp_matter;
|
||||||
|
|
||||||
|
Status emberAfExternalAttributeReadCallback(EndpointId endpoint_id, ClusterId cluster_id,
|
||||||
|
const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer,
|
||||||
|
uint16_t max_read_length)
|
||||||
|
{
|
||||||
|
/* Get value */
|
||||||
|
uint32_t attribute_id = matter_attribute->attributeId;
|
||||||
|
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
|
||||||
|
VerifyOrReturnError(attribute, Status::Failure);
|
||||||
|
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||||
|
|
||||||
|
int flags = attribute::get_flags(attribute);
|
||||||
|
if (flags & ATTRIBUTE_FLAG_OVERRIDE) {
|
||||||
|
esp_err_t err =
|
||||||
|
execute_override_callback(attribute, attribute::READ, endpoint_id, cluster_id, attribute_id, &val);
|
||||||
|
VerifyOrReturnValue(err == ESP_OK, Status::Failure);
|
||||||
|
} else {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here, the val_print function gets called on attribute read. */
|
||||||
|
attribute::val_print(endpoint_id, cluster_id, attribute_id, &val, true);
|
||||||
|
|
||||||
|
/* Get size */
|
||||||
|
uint16_t attribute_size = 0;
|
||||||
|
attribute::get_data_from_attr_val(&val, NULL, &attribute_size, NULL);
|
||||||
|
VerifyOrReturnValue(attribute_size <= max_read_length, Status::ResourceExhausted,
|
||||||
|
ESP_LOGE(TAG,
|
||||||
|
"Insufficient space for reading Endpoint 0x%04" PRIX16 "'s Cluster 0x%08" PRIX32
|
||||||
|
"'s Attribute 0x%08" PRIX32 ": required: %" PRIu16 ", max: %" PRIu16 "",
|
||||||
|
endpoint_id, cluster_id, attribute_id, attribute_size, max_read_length));
|
||||||
|
|
||||||
|
/* Assign value */
|
||||||
|
attribute::get_data_from_attr_val(&val, NULL, &attribute_size, buffer);
|
||||||
|
return Status::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status emberAfExternalAttributeWriteCallback(EndpointId endpoint_id, ClusterId cluster_id,
|
||||||
|
const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer)
|
||||||
|
{
|
||||||
|
/* Get value */
|
||||||
|
uint32_t attribute_id = matter_attribute->attributeId;
|
||||||
|
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
|
||||||
|
VerifyOrReturnError(attribute, Status::Failure);
|
||||||
|
|
||||||
|
/* Get val */
|
||||||
|
/* This creates a new variable val, and stores the new attribute value in the new variable.
|
||||||
|
The value in esp-matter data model is updated only when attribute::set_val() is called */
|
||||||
|
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||||
|
attribute::get_attr_val_from_data(&val, matter_attribute->attributeType, matter_attribute->size, buffer,
|
||||||
|
matter_attribute);
|
||||||
|
|
||||||
|
int flags = attribute::get_flags(attribute);
|
||||||
|
if (flags & ATTRIBUTE_FLAG_OVERRIDE) {
|
||||||
|
esp_err_t err =
|
||||||
|
execute_override_callback(attribute, attribute::WRITE, endpoint_id, cluster_id, attribute_id, &val);
|
||||||
|
Status status = (err == ESP_OK) ? Status::Success : Status::Failure;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update val */
|
||||||
|
VerifyOrReturnValue(val.type != ESP_MATTER_VAL_TYPE_INVALID, Status::Failure);
|
||||||
|
attribute::set_val(attribute, &val);
|
||||||
|
return Status::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No-op function, used to force linking this file, instead of the weak functions from other files.
|
||||||
|
extern "C" void data_model_utils_impl(void) {}
|
||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_matter.h>
|
#include <esp_matter_data_model.h>
|
||||||
#include <platform/DeviceControlServer.h>
|
#include <platform/DeviceControlServer.h>
|
||||||
|
|
||||||
namespace esp_matter {
|
namespace esp_matter {
|
||||||
+1
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <esp_matter_attribute.h>
|
#include <esp_matter_attribute.h>
|
||||||
|
#include <esp_matter_data_model.h>
|
||||||
|
|
||||||
#define ESP_MATTER_NONE_FEATURE_ID 0x0000
|
#define ESP_MATTER_NONE_FEATURE_ID 0x0000
|
||||||
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_matter_attribute_utils.h>
|
||||||
|
#include <app/util/attribute-storage.h>
|
||||||
|
|
||||||
|
namespace esp_matter {
|
||||||
|
namespace node {
|
||||||
|
|
||||||
|
esp_err_t store_min_unused_endpoint_id();
|
||||||
|
|
||||||
|
esp_err_t read_min_unused_endpoint_id();
|
||||||
|
|
||||||
|
} // namespace node
|
||||||
|
namespace endpoint {
|
||||||
|
|
||||||
|
esp_err_t enable_all();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace attribute {
|
||||||
|
esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type,
|
||||||
|
uint16_t *attribute_size, uint8_t *value);
|
||||||
|
|
||||||
|
esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttributeType attribute_type,
|
||||||
|
uint16_t attribute_size, uint8_t *value,
|
||||||
|
const EmberAfAttributeMetadata * attribute_metadata);
|
||||||
|
}
|
||||||
|
} // namespace esp_matter
|
||||||
@@ -18,94 +18,26 @@
|
|||||||
This is a common include file which includes all the other esp_matter component files which would be required by the
|
This is a common include file which includes all the other esp_matter component files which would be required by the
|
||||||
application.
|
application.
|
||||||
*/
|
*/
|
||||||
|
#include <sdkconfig.h>
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
#include <esp_matter_attribute.h>
|
#include <esp_matter_attribute.h>
|
||||||
#include <esp_matter_attribute_utils.h>
|
|
||||||
#include <esp_matter_client.h>
|
|
||||||
#include <esp_matter_cluster.h>
|
#include <esp_matter_cluster.h>
|
||||||
#include <esp_matter_command.h>
|
#include <esp_matter_command.h>
|
||||||
#include <esp_matter_core.h>
|
|
||||||
#include <esp_matter_endpoint.h>
|
#include <esp_matter_endpoint.h>
|
||||||
#include <esp_matter_event.h>
|
#include <esp_matter_event.h>
|
||||||
#include <esp_matter_feature.h>
|
#include <esp_matter_feature.h>
|
||||||
#include <esp_matter_identify.h>
|
#include <esp_matter_data_model.h>
|
||||||
|
#endif // CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
#include <app/server/Dnssd.h>
|
#include <app/server/Dnssd.h>
|
||||||
|
#include <esp_matter_attribute_utils.h>
|
||||||
|
#include <esp_matter_identify.h>
|
||||||
|
#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
|
#include <esp_matter_client.h>
|
||||||
|
#include <esp_matter_core.h>
|
||||||
#include <platform/CHIPDeviceEvent.h>
|
#include <platform/CHIPDeviceEvent.h>
|
||||||
#include <platform/CHIPDeviceLayer.h>
|
#include <platform/CHIPDeviceLayer.h>
|
||||||
|
|
||||||
namespace esp_matter {
|
|
||||||
|
|
||||||
/** Endpoint flags */
|
|
||||||
typedef enum endpoint_flags {
|
|
||||||
/** No specific flags */
|
|
||||||
ENDPOINT_FLAG_NONE = 0x00,
|
|
||||||
/** The endpoint can be destroyed using `endpoint::destroy()` */
|
|
||||||
ENDPOINT_FLAG_DESTROYABLE = 0x01,
|
|
||||||
/** The endpoint is a bridged node */
|
|
||||||
ENDPOINT_FLAG_BRIDGE = 0x02,
|
|
||||||
} endpoint_flags_t;
|
|
||||||
|
|
||||||
/** Cluster flags */
|
|
||||||
typedef enum cluster_flags {
|
|
||||||
/** No specific flags */
|
|
||||||
CLUSTER_FLAG_NONE = 0x00,
|
|
||||||
/** The cluster has an init function (function_flag) */
|
|
||||||
CLUSTER_FLAG_INIT_FUNCTION = MATTER_CLUSTER_FLAG_INIT_FUNCTION, /* 0x01 */
|
|
||||||
/** The cluster has an attribute changed function (function_flag) */
|
|
||||||
CLUSTER_FLAG_ATTRIBUTE_CHANGED_FUNCTION = MATTER_CLUSTER_FLAG_ATTRIBUTE_CHANGED_FUNCTION, /* 0x02 */
|
|
||||||
/** The cluster has a shutdown function (function_flag) */
|
|
||||||
CLUSTER_FLAG_SHUTDOWN_FUNCTION = MATTER_CLUSTER_FLAG_SHUTDOWN_FUNCTION, /* 0x10 */
|
|
||||||
/** The cluster has a pre attribute changed function (function_flag) */
|
|
||||||
CLUSTER_FLAG_PRE_ATTRIBUTE_CHANGED_FUNCTION = MATTER_CLUSTER_FLAG_PRE_ATTRIBUTE_CHANGED_FUNCTION, /* 0x20 */
|
|
||||||
/** The cluster is a server cluster */
|
|
||||||
CLUSTER_FLAG_SERVER = MATTER_CLUSTER_FLAG_SERVER, /* 0x40 */
|
|
||||||
/** The cluster is a client cluster */
|
|
||||||
CLUSTER_FLAG_CLIENT = MATTER_CLUSTER_FLAG_CLIENT, /* 0x80 */
|
|
||||||
} cluster_flags_t;
|
|
||||||
|
|
||||||
/** Attribute flags */
|
|
||||||
typedef enum attribute_flags {
|
|
||||||
/** No specific flags */
|
|
||||||
ATTRIBUTE_FLAG_NONE = 0x00,
|
|
||||||
/** The attribute is writable and can be directly changed by clients */
|
|
||||||
ATTRIBUTE_FLAG_WRITABLE = MATTER_ATTRIBUTE_FLAG_WRITABLE, /* 0x01 */
|
|
||||||
/** The attribute is non volatile and its value will be stored in NVS */
|
|
||||||
ATTRIBUTE_FLAG_NONVOLATILE = MATTER_ATTRIBUTE_FLAG_NONVOLATILE, /* 0x02 */
|
|
||||||
/** The attribute has bounds */
|
|
||||||
ATTRIBUTE_FLAG_MIN_MAX = MATTER_ATTRIBUTE_FLAG_MIN_MAX, /* 0x04 */
|
|
||||||
ATTRIBUTE_FLAG_MUST_USE_TIMED_WRITE = MATTER_ATTRIBUTE_FLAG_MUST_USE_TIMED_WRITE, /* 0x08 */
|
|
||||||
/** The attribute uses external storage for its value. If attributes
|
|
||||||
have this flag enabled, as all of them are stored in the ESP Matter database. */
|
|
||||||
ATTRIBUTE_FLAG_EXTERNAL_STORAGE = MATTER_ATTRIBUTE_FLAG_EXTERNAL_STORAGE, /* 0x10 */
|
|
||||||
ATTRIBUTE_FLAG_SINGLETON = MATTER_ATTRIBUTE_FLAG_SINGLETON, /* 0x20 */
|
|
||||||
ATTRIBUTE_FLAG_NULLABLE = MATTER_ATTRIBUTE_FLAG_NULLABLE, /* 0x40 */
|
|
||||||
/** The attribute read and write are overridden. The attribute value will be fetched from and will be updated using
|
|
||||||
the override callback. The value of this attribute is not maintained internally. */
|
|
||||||
ATTRIBUTE_FLAG_OVERRIDE = ATTRIBUTE_FLAG_NULLABLE << 1, /* 0x80 */
|
|
||||||
/** The attribute is non-volatile but its value will be changed frequently. If an attribute has this flag, its value
|
|
||||||
will not be written to flash immediately. A timer will be started and the attribute value will be written after
|
|
||||||
timeout. */
|
|
||||||
ATTRIBUTE_FLAG_DEFERRED = ATTRIBUTE_FLAG_NULLABLE << 2, /* 0x100 */
|
|
||||||
/** The attribute is managed internally and is not stored in the ESP Matter database.
|
|
||||||
If not set, ATTRIBUTE_FLAG_EXTERNAL_STORAGE flag will be enabled. */
|
|
||||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY = ATTRIBUTE_FLAG_NULLABLE << 3, /* 0x200 */
|
|
||||||
} attribute_flags_t;
|
|
||||||
|
|
||||||
/** Command flags */
|
|
||||||
typedef enum command_flags {
|
|
||||||
/** No specific flags */
|
|
||||||
COMMAND_FLAG_NONE = 0x00,
|
|
||||||
/** The command is not a standard command */
|
|
||||||
COMMAND_FLAG_CUSTOM = 0x01,
|
|
||||||
/** The command is client generated */
|
|
||||||
COMMAND_FLAG_ACCEPTED = 0x02,
|
|
||||||
/** The command is server generated */
|
|
||||||
COMMAND_FLAG_GENERATED = 0x04,
|
|
||||||
} command_flags_t;
|
|
||||||
|
|
||||||
} /* esp_matter */
|
|
||||||
|
|
||||||
namespace chip {
|
namespace chip {
|
||||||
namespace DeviceLayer {
|
namespace DeviceLayer {
|
||||||
namespace DeviceEventType {
|
namespace DeviceEventType {
|
||||||
|
|||||||
@@ -1012,23 +1012,11 @@ static esp_err_t execute_callback(callback_type_t type, uint16_t endpoint_id, ui
|
|||||||
uint32_t attribute_id, esp_matter_attr_val_t *val)
|
uint32_t attribute_id, esp_matter_attr_val_t *val)
|
||||||
{
|
{
|
||||||
if (attribute_callback) {
|
if (attribute_callback) {
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
||||||
return attribute_callback(type, endpoint_id, cluster_id, attribute_id, val, priv_data);
|
#else
|
||||||
}
|
void *priv_data = nullptr;
|
||||||
return ESP_OK;
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t execute_override_callback(attribute_t *attribute, callback_type_t type, uint16_t endpoint_id,
|
|
||||||
uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val)
|
|
||||||
{
|
|
||||||
callback_t override_callback = attribute::get_override_callback(attribute);
|
|
||||||
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
|
||||||
if (override_callback) {
|
|
||||||
return override_callback(type, endpoint_id, cluster_id, attribute_id, val, priv_data);
|
|
||||||
} else {
|
|
||||||
ESP_LOGI(TAG, "Attribute override callback not set for Endpoint 0x%04" PRIX16 "'s Cluster 0x%08" PRIX32 "'s Attribute 0x%08" PRIX32 ", calling the common callback",
|
|
||||||
endpoint_id, cluster_id, attribute_id);
|
|
||||||
if (attribute_callback)
|
|
||||||
return attribute_callback(type, endpoint_id, cluster_id, attribute_id, val, priv_data);
|
return attribute_callback(type, endpoint_id, cluster_id, attribute_id, val, priv_data);
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -2110,6 +2098,7 @@ esp_err_t report(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_i
|
|||||||
lock::status_t lock_status = lock::chip_stack_lock(portMAX_DELAY);
|
lock::status_t lock_status = lock::chip_stack_lock(portMAX_DELAY);
|
||||||
VerifyOrReturnError(lock_status != lock::FAILED, ESP_FAIL, ESP_LOGE(TAG, "Could not get task context"));
|
VerifyOrReturnError(lock_status != lock::FAILED, ESP_FAIL, ESP_LOGE(TAG, "Could not get task context"));
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
/* Get attribute */
|
/* Get attribute */
|
||||||
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
|
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
|
||||||
if (!attribute) {
|
if (!attribute) {
|
||||||
@@ -2133,7 +2122,7 @@ esp_err_t report(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_i
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
attribute::set_val(attribute, val);
|
attribute::set_val(attribute, val);
|
||||||
|
#endif
|
||||||
/* Report attribute */
|
/* Report attribute */
|
||||||
MatterReportingAttributeChangeCallback(endpoint_id, cluster_id, attribute_id);
|
MatterReportingAttributeChangeCallback(endpoint_id, cluster_id, attribute_id);
|
||||||
|
|
||||||
@@ -2180,64 +2169,3 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &p
|
|||||||
/* Callback to application */
|
/* Callback to application */
|
||||||
execute_callback(attribute::POST_UPDATE, endpoint_id, cluster_id, attribute_id, &val);
|
execute_callback(attribute::POST_UPDATE, endpoint_id, cluster_id, attribute_id, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status emberAfExternalAttributeReadCallback(EndpointId endpoint_id, ClusterId cluster_id,
|
|
||||||
const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer,
|
|
||||||
uint16_t max_read_length)
|
|
||||||
{
|
|
||||||
/* Get value */
|
|
||||||
uint32_t attribute_id = matter_attribute->attributeId;
|
|
||||||
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
|
|
||||||
VerifyOrReturnError(attribute, Status::Failure);
|
|
||||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
|
||||||
|
|
||||||
int flags = attribute::get_flags(attribute);
|
|
||||||
if (flags & ATTRIBUTE_FLAG_OVERRIDE) {
|
|
||||||
esp_err_t err = execute_override_callback(attribute, attribute::READ, endpoint_id, cluster_id, attribute_id,
|
|
||||||
&val);
|
|
||||||
VerifyOrReturnValue(err == ESP_OK, Status::Failure);
|
|
||||||
} else {
|
|
||||||
attribute::get_val(attribute, &val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here, the val_print function gets called on attribute read. */
|
|
||||||
attribute::val_print(endpoint_id, cluster_id, attribute_id, &val, true);
|
|
||||||
|
|
||||||
/* Get size */
|
|
||||||
uint16_t attribute_size = 0;
|
|
||||||
attribute::get_data_from_attr_val(&val, NULL, &attribute_size, NULL);
|
|
||||||
VerifyOrReturnValue(attribute_size <= max_read_length, Status::ResourceExhausted, ESP_LOGE(TAG, "Insufficient space for reading Endpoint 0x%04" PRIX16 "'s Cluster 0x%08" PRIX32 "'s Attribute 0x%08" PRIX32
|
|
||||||
": required: %" PRIu16 ", max: %" PRIu16 "", endpoint_id, cluster_id, attribute_id, attribute_size, max_read_length));
|
|
||||||
|
|
||||||
/* Assign value */
|
|
||||||
attribute::get_data_from_attr_val(&val, NULL, &attribute_size, buffer);
|
|
||||||
return Status::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status emberAfExternalAttributeWriteCallback(EndpointId endpoint_id, ClusterId cluster_id,
|
|
||||||
const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer)
|
|
||||||
{
|
|
||||||
/* Get value */
|
|
||||||
uint32_t attribute_id = matter_attribute->attributeId;
|
|
||||||
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
|
|
||||||
VerifyOrReturnError(attribute, Status::Failure);
|
|
||||||
|
|
||||||
/* Get val */
|
|
||||||
/* This creates a new variable val, and stores the new attribute value in the new variable.
|
|
||||||
The value in esp-matter data model is updated only when attribute::set_val() is called */
|
|
||||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
|
||||||
attribute::get_attr_val_from_data(&val, matter_attribute->attributeType, matter_attribute->size, buffer, matter_attribute);
|
|
||||||
|
|
||||||
int flags = attribute::get_flags(attribute);
|
|
||||||
if (flags & ATTRIBUTE_FLAG_OVERRIDE) {
|
|
||||||
esp_err_t err = execute_override_callback(attribute, attribute::WRITE, endpoint_id, cluster_id, attribute_id,
|
|
||||||
&val);
|
|
||||||
Status status = (err == ESP_OK) ? Status::Success : Status::Failure;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update val */
|
|
||||||
VerifyOrReturnValue(val.type != ESP_MATTER_VAL_TYPE_INVALID, Status::Failure);
|
|
||||||
attribute::set_val(attribute, &val);
|
|
||||||
return Status::Success;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -450,5 +450,21 @@ esp_err_t report(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_i
|
|||||||
*/
|
*/
|
||||||
void val_print(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val, bool is_read);
|
void val_print(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val, bool is_read);
|
||||||
|
|
||||||
|
/** Get attribute val raw
|
||||||
|
*
|
||||||
|
* Get the value of the attribute in the database, without the attribute handle.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the attribute.
|
||||||
|
* @param[in] cluster_id Cluster ID of the attribute.
|
||||||
|
* @param[in] attribute_id Attribute ID of the attribute.
|
||||||
|
* @param[out] value Pointer to an allocated buffer for the attribute value.
|
||||||
|
* @param[in] attribute_size Size of the allocated buffer.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t get_val_raw(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, uint8_t *value,
|
||||||
|
uint16_t attribute_size);
|
||||||
|
|
||||||
} /* attribute */
|
} /* attribute */
|
||||||
} /* esp_matter */
|
} /* esp_matter */
|
||||||
|
|||||||
@@ -25,10 +25,12 @@
|
|||||||
#include <app/MessageDef/StatusIB.h>
|
#include <app/MessageDef/StatusIB.h>
|
||||||
#include <app/ReadClient.h>
|
#include <app/ReadClient.h>
|
||||||
#include <app/ReadPrepareParams.h>
|
#include <app/ReadPrepareParams.h>
|
||||||
#include <app/clusters/bindings/BindingManager.h>
|
|
||||||
#include <core/Optional.h>
|
#include <core/Optional.h>
|
||||||
#include <core/TLVReader.h>
|
#include <core/TLVReader.h>
|
||||||
#include <core/TLVWriter.h>
|
#include <core/TLVWriter.h>
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
|
#include <app/clusters/bindings/BindingManager.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "app/CommandPathParams.h"
|
#include "app/CommandPathParams.h"
|
||||||
#include "app/CommandSender.h"
|
#include "app/CommandSender.h"
|
||||||
@@ -87,11 +89,12 @@ void esp_matter_connection_failure_callback(void *context, const ScopedNodeId &p
|
|||||||
esp_err_t connect(case_session_mgr_t *case_session_mgr, uint8_t fabric_index, uint64_t node_id,
|
esp_err_t connect(case_session_mgr_t *case_session_mgr, uint8_t fabric_index, uint64_t node_id,
|
||||||
request_handle_t *req_handle)
|
request_handle_t *req_handle)
|
||||||
{
|
{
|
||||||
|
VerifyOrReturnError(req_handle, ESP_ERR_INVALID_ARG);
|
||||||
VerifyOrReturnError(case_session_mgr, ESP_ERR_INVALID_ARG);
|
VerifyOrReturnError(case_session_mgr, ESP_ERR_INVALID_ARG);
|
||||||
static Callback<chip::OnDeviceConnected> success_callback(esp_matter_connection_success_callback, NULL);
|
static Callback<chip::OnDeviceConnected> success_callback(esp_matter_connection_success_callback, NULL);
|
||||||
static Callback<chip::OnDeviceConnectionFailure> failure_callback(esp_matter_connection_failure_callback, NULL);
|
static Callback<chip::OnDeviceConnectionFailure> failure_callback(esp_matter_connection_failure_callback, NULL);
|
||||||
|
|
||||||
request_handle_t *context = chip::Platform::New<request_handle_t>(req_handle);
|
request_handle_t *context = chip::Platform::New<request_handle_t>(*req_handle);
|
||||||
VerifyOrReturnError(context, ESP_ERR_NO_MEM, ESP_LOGE(TAG, "failed to alloc memory for the command handle"));
|
VerifyOrReturnError(context, ESP_ERR_NO_MEM, ESP_LOGE(TAG, "failed to alloc memory for the command handle"));
|
||||||
success_callback.mContext = static_cast<void *>(context);
|
success_callback.mContext = static_cast<void *>(context);
|
||||||
failure_callback.mContext = static_cast<void *>(context);
|
failure_callback.mContext = static_cast<void *>(context);
|
||||||
@@ -109,6 +112,7 @@ esp_err_t group_request_send(uint8_t fabric_index, request_handle_t *req_handle)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
static void esp_matter_command_client_binding_callback(const EmberBindingTableEntry &binding,
|
static void esp_matter_command_client_binding_callback(const EmberBindingTableEntry &binding,
|
||||||
OperationalDeviceProxy *peer_device, void *context)
|
OperationalDeviceProxy *peer_device, void *context)
|
||||||
{
|
{
|
||||||
@@ -151,7 +155,8 @@ static void esp_matter_binding_context_release(void *context)
|
|||||||
|
|
||||||
esp_err_t cluster_update(uint16_t local_endpoint_id, request_handle_t *req_handle)
|
esp_err_t cluster_update(uint16_t local_endpoint_id, request_handle_t *req_handle)
|
||||||
{
|
{
|
||||||
request_handle_t *context = chip::Platform::New<request_handle_t>(req_handle);
|
VerifyOrReturnError(req_handle, ESP_ERR_INVALID_ARG);
|
||||||
|
request_handle_t *context = chip::Platform::New<request_handle_t>(*req_handle);
|
||||||
VerifyOrReturnError(context, ESP_ERR_NO_MEM, ESP_LOGE(TAG, "failed to alloc memory for the request handle"));
|
VerifyOrReturnError(context, ESP_ERR_NO_MEM, ESP_LOGE(TAG, "failed to alloc memory for the request handle"));
|
||||||
chip::ClusterId notified_cluster_id = chip::kInvalidClusterId;
|
chip::ClusterId notified_cluster_id = chip::kInvalidClusterId;
|
||||||
if (req_handle->type == INVOKE_CMD) {
|
if (req_handle->type == INVOKE_CMD) {
|
||||||
@@ -199,6 +204,7 @@ void binding_init()
|
|||||||
{
|
{
|
||||||
initialize_binding_manager = true;
|
initialize_binding_manager = true;
|
||||||
}
|
}
|
||||||
|
#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
|
|
||||||
namespace interaction {
|
namespace interaction {
|
||||||
using chip::app::DataModel::EncodableToTLV;
|
using chip::app::DataModel::EncodableToTLV;
|
||||||
|
|||||||
@@ -23,7 +23,151 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
namespace esp_matter {
|
namespace esp_matter {
|
||||||
|
/* Client APIs */
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
|
/** Client request types
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
INVOKE_CMD = 0,
|
||||||
|
READ_ATTR = 1,
|
||||||
|
READ_EVENT = 2,
|
||||||
|
WRITE_ATTR = 3,
|
||||||
|
SUBSCRIBE_ATTR = 4,
|
||||||
|
SUBSCRIBE_EVENT = 5,
|
||||||
|
} request_type_t;
|
||||||
|
|
||||||
|
/** Request handle as the input when calling `connect()` or `cluster_update()`
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct request_handle {
|
||||||
|
request_type_t type;
|
||||||
|
union {
|
||||||
|
chip::app::AttributePathParams attribute_path;
|
||||||
|
chip::app::EventPathParams event_path;
|
||||||
|
chip::app::CommandPathParams command_path;
|
||||||
|
};
|
||||||
|
/* This could be the command data field when the request type is INVOKE_CMD,
|
||||||
|
* or the attribute value data when the request type is WRITE_ATTR.
|
||||||
|
*/
|
||||||
|
void *request_data;
|
||||||
|
request_handle() : type(INVOKE_CMD), request_data(NULL) {}
|
||||||
|
request_handle(struct request_handle& req) : type(req.type), request_data(req.request_data)
|
||||||
|
{
|
||||||
|
if (req.type == INVOKE_CMD) {
|
||||||
|
command_path = req.command_path;
|
||||||
|
} else if (req.type == WRITE_ATTR || req.type == READ_ATTR || req.type == SUBSCRIBE_ATTR) {
|
||||||
|
attribute_path = req.attribute_path;
|
||||||
|
} else if (req.type == READ_EVENT || req.type == SUBSCRIBE_EVENT) {
|
||||||
|
event_path = req.event_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} request_handle_t;
|
||||||
|
|
||||||
|
/** Peer device handle */
|
||||||
|
typedef chip::DeviceProxy peer_device_t;
|
||||||
|
|
||||||
|
/** CASE Session Manager */
|
||||||
|
typedef chip::CASESessionManager case_session_mgr_t;
|
||||||
|
|
||||||
|
/** Request send callback
|
||||||
|
*
|
||||||
|
* This callback will be called when `connect()` or `cluster_update()` is called and the connection completes. The
|
||||||
|
* send_request APIs can then be called from the callback.
|
||||||
|
*
|
||||||
|
* @param[in] peer_device Peer device handle. This can be passed to the send_command APIs.
|
||||||
|
* @param[in] req_handle Request handle used by `connect()` or `cluster_update()`.
|
||||||
|
* @param[in] priv_data (Optional) Private data associated with the callback. This will be passed to callback. It
|
||||||
|
* should stay allocated throughout the lifetime of the device.
|
||||||
|
*/
|
||||||
|
typedef void (*request_callback_t)(peer_device_t *peer_device, request_handle_t *req_handle, void *priv_data);
|
||||||
|
|
||||||
|
/** Group request send callback
|
||||||
|
*
|
||||||
|
* This callback will be called when `cluster_update()` is called and the group request is triggered for binding cluster.
|
||||||
|
*
|
||||||
|
* @note: The request type should be INVOKE_CMD and the command should not expect a response.
|
||||||
|
*
|
||||||
|
* @param[in] fabric_index The index of the fabric that the group command is sent to.
|
||||||
|
* @param[in] req_handle Request handle used by `cluster_update()`.
|
||||||
|
* @param[in] priv_data (Optional) Private data associated with the callback. This will be passed to callback. It
|
||||||
|
* should stay allocated throughout the lifetime of the device.
|
||||||
|
*/
|
||||||
|
typedef void (*group_request_callback_t)(uint8_t fabric_index, request_handle_t *req_handle, void *priv_data);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
|
/** Initialize binding
|
||||||
|
*
|
||||||
|
* This should be called if the Binding cluster has been created. It just sets a flag for the binding manager to be
|
||||||
|
* initialized.
|
||||||
|
* If the cluster::binding::create() is being used, this is called internally.
|
||||||
|
*/
|
||||||
|
void binding_init();
|
||||||
|
|
||||||
|
/** Initialize binding manager
|
||||||
|
*
|
||||||
|
* This initializes the binding manager. It is called after the matter thread has been started.
|
||||||
|
*/
|
||||||
|
void binding_manager_init();
|
||||||
|
#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER
|
||||||
|
|
||||||
|
/** Connect
|
||||||
|
*
|
||||||
|
* Connect to another device on the same fabric to send a request.
|
||||||
|
*
|
||||||
|
* @param[in] case_session_mgr CASE Session Manager to find or establish the session
|
||||||
|
* @param[in] fabric_index Fabric index.
|
||||||
|
* @param[in] node_id Node ID of the other device.
|
||||||
|
* @param[in] req_handle Request to be sent to the remote device.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t connect(case_session_mgr_t *case_session_mgr, uint8_t fabric_index, uint64_t node_id,
|
||||||
|
request_handle_t *req_handle);
|
||||||
|
|
||||||
|
/** group_request_send
|
||||||
|
*
|
||||||
|
* on the same fabric to send a group request.
|
||||||
|
*
|
||||||
|
* @param[in] fabric_index Fabric index.
|
||||||
|
* @param[in] req_handle Request to be sent to the group.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t group_request_send(uint8_t fabric_index, request_handle_t *req_handle);
|
||||||
|
|
||||||
|
/** Set request send callback
|
||||||
|
*
|
||||||
|
* Set the common request send callback and the group request send callback. The common callback will be called
|
||||||
|
* when `connect()` or `cluster_update()` is called and the connection completes. The group callback will be called
|
||||||
|
* when `cluster_update()` is called and the group request is triggered.
|
||||||
|
*
|
||||||
|
* @param[in] callback request send callback.
|
||||||
|
* @param[in] g_callback group request send callback
|
||||||
|
* @param[in] priv_data (Optional) Private data associated with the callback. This will be passed to callback. It
|
||||||
|
* should stay allocated throughout the lifetime of the device.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_request_callback(request_callback_t callback, group_request_callback_t g_callback, void *priv_data);
|
||||||
|
|
||||||
|
/** Cluster update
|
||||||
|
*
|
||||||
|
* For an already binded device, this API can be used to get the request send callback, and the send_request APIs can
|
||||||
|
* then be called from the callback.
|
||||||
|
*
|
||||||
|
* @param[in] local_endpoint_id The ID of the local endpoint with a binding cluster.
|
||||||
|
* @param[in] req_handle Request information to notify the bound cluster changed.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t cluster_update(uint16_t local_endpoint_id, request_handle_t *req_handle);
|
||||||
|
|
||||||
namespace interaction {
|
namespace interaction {
|
||||||
|
|
||||||
using chip::Optional;
|
using chip::Optional;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,9 @@
|
|||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_matter_core.h>
|
#include <esp_matter_core.h>
|
||||||
#include <esp_matter_icd_configuration.h>
|
#include <esp_matter_icd_configuration.h>
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
|
#include <esp_matter_data_model.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <app/icd/server/ICDConfigurationData.h>
|
#include <app/icd/server/ICDConfigurationData.h>
|
||||||
#include <lib/core/Optional.h>
|
#include <lib/core/Optional.h>
|
||||||
@@ -107,21 +110,25 @@ static esp_err_t set_active_threshold(uint32_t active_threshold_ms)
|
|||||||
return chip::Test::ICDConfigurationDataTestAccess::SetActiveThreshold(Milliseconds32(active_threshold_ms));
|
return chip::Test::ICDConfigurationDataTestAccess::SetActiveThreshold(Milliseconds32(active_threshold_ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
static bool s_enable_icd_server = true;
|
static bool s_enable_icd_server = true;
|
||||||
|
|
||||||
bool get_icd_server_enabled()
|
bool get_icd_server_enabled()
|
||||||
{
|
{
|
||||||
return s_enable_icd_server;
|
return s_enable_icd_server;
|
||||||
}
|
}
|
||||||
|
#endif // CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
|
|
||||||
esp_err_t set_configuration_data(config_t *config)
|
esp_err_t set_configuration_data(config_t *config)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "config cannot be NULL");
|
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "config cannot be NULL");
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
if (!config->enable_icd_server) {
|
if (!config->enable_icd_server) {
|
||||||
ESP_RETURN_ON_FALSE(!node::get(), ESP_ERR_INVALID_STATE, TAG,
|
ESP_RETURN_ON_FALSE(!esp_matter::node::get(), ESP_ERR_INVALID_STATE, TAG,
|
||||||
"Could not disable ICD server after data model is created");
|
"Could not disable ICD server after data model is created");
|
||||||
}
|
}
|
||||||
s_enable_icd_server = config->enable_icd_server;
|
s_enable_icd_server = config->enable_icd_server;
|
||||||
|
#endif // CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
ESP_RETURN_ON_FALSE(!is_started(), ESP_ERR_INVALID_STATE, TAG,
|
ESP_RETURN_ON_FALSE(!is_started(), ESP_ERR_INVALID_STATE, TAG,
|
||||||
"Could not change ICD configuration data after Matter is started");
|
"Could not change ICD configuration data after Matter is started");
|
||||||
ESP_RETURN_ON_ERROR(set_polling_intervals(config->fast_interval_ms, config->slow_interval_ms), TAG,
|
ESP_RETURN_ON_ERROR(set_polling_intervals(config->fast_interval_ms, config->slow_interval_ms), TAG,
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ namespace esp_matter {
|
|||||||
namespace icd {
|
namespace icd {
|
||||||
|
|
||||||
typedef struct config {
|
typedef struct config {
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
bool enable_icd_server;
|
bool enable_icd_server;
|
||||||
|
#endif
|
||||||
std::optional<uint32_t> fast_interval_ms;
|
std::optional<uint32_t> fast_interval_ms;
|
||||||
std::optional<uint32_t> slow_interval_ms;
|
std::optional<uint32_t> slow_interval_ms;
|
||||||
std::optional<uint32_t> active_mode_duration_ms;
|
std::optional<uint32_t> active_mode_duration_ms;
|
||||||
@@ -27,9 +29,11 @@ typedef struct config {
|
|||||||
std::optional<uint32_t> active_threshold_ms;
|
std::optional<uint32_t> active_threshold_ms;
|
||||||
} config_t;
|
} config_t;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
/** Get whether ICD server is enabled for Matter end-device
|
/** Get whether ICD server is enabled for Matter end-device
|
||||||
*/
|
*/
|
||||||
bool get_icd_server_enabled();
|
bool get_icd_server_enabled();
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Set ICD configuration data
|
/** Set ICD configuration data
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -18,12 +18,23 @@
|
|||||||
|
|
||||||
#include <app/clusters/identify-server/identify-server.h>
|
#include <app/clusters/identify-server/identify-server.h>
|
||||||
|
|
||||||
|
#ifndef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
|
#include <app/util/attribute-storage.h>
|
||||||
|
#include <zap-generated/gen_config.h>
|
||||||
|
#if defined(MATTER_DM_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT) && MATTER_DM_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT > 0
|
||||||
|
#define USE_IDENTIFY_ARRAY
|
||||||
|
#endif
|
||||||
|
#endif // !CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
|
|
||||||
static const char *TAG = "esp_matter_identify";
|
static const char *TAG = "esp_matter_identify";
|
||||||
|
|
||||||
namespace esp_matter {
|
namespace esp_matter {
|
||||||
namespace identification {
|
namespace identification {
|
||||||
|
|
||||||
static callback_t identification_callback = NULL;
|
static callback_t identification_callback = NULL;
|
||||||
|
#ifdef USE_IDENTIFY_ARRAY
|
||||||
|
static Identify *g_identifies[MATTER_DM_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT];
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_err_t set_callback(callback_t callback)
|
esp_err_t set_callback(callback_t callback)
|
||||||
{
|
{
|
||||||
@@ -34,8 +45,18 @@ esp_err_t set_callback(callback_t callback)
|
|||||||
static esp_err_t execute_callback(callback_type_t type, uint16_t endpoint_id, uint8_t effect_id, uint8_t effect_variant)
|
static esp_err_t execute_callback(callback_type_t type, uint16_t endpoint_id, uint8_t effect_id, uint8_t effect_variant)
|
||||||
{
|
{
|
||||||
if (identification_callback) {
|
if (identification_callback) {
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
||||||
return identification_callback(type, endpoint_id, effect_id, effect_variant, priv_data);
|
return identification_callback(type, endpoint_id, effect_id, effect_variant, priv_data);
|
||||||
|
#else // CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
|
void *ctx = nullptr;
|
||||||
|
#ifdef USE_IDENTIFY_ARRAY
|
||||||
|
uint16_t index = emberAfGetClusterServerEndpointIndex(endpoint_id, chip::app::Clusters::Identify::Id,
|
||||||
|
MATTER_DM_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT);
|
||||||
|
ctx = index < MATTER_ARRAY_SIZE(g_identifies) ? g_identifies[index] : nullptr;
|
||||||
|
#endif // USE_IDENTIFY_ARRAY
|
||||||
|
return identification_callback(type, endpoint_id, effect_id, effect_variant, ctx);
|
||||||
|
#endif // !CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -43,30 +64,42 @@ static esp_err_t execute_callback(callback_type_t type, uint16_t endpoint_id, ui
|
|||||||
static void start_cb(Identify *identify)
|
static void start_cb(Identify *identify)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Start callback");
|
ESP_LOGI(TAG, "Start callback");
|
||||||
execute_callback(START, identify->mEndpoint, static_cast<uint8_t>(identify->mCurrentEffectIdentifier), static_cast<uint8_t>(identify->mEffectVariant));
|
execute_callback(START, identify->mEndpoint, static_cast<uint8_t>(identify->mCurrentEffectIdentifier),
|
||||||
|
static_cast<uint8_t>(identify->mEffectVariant));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_cb(Identify *identify)
|
static void stop_cb(Identify *identify)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Stop callback");
|
ESP_LOGI(TAG, "Stop callback");
|
||||||
execute_callback(STOP, identify->mEndpoint, static_cast<uint8_t>(identify->mCurrentEffectIdentifier), static_cast<uint8_t>(identify->mEffectVariant));
|
execute_callback(STOP, identify->mEndpoint, static_cast<uint8_t>(identify->mCurrentEffectIdentifier),
|
||||||
|
static_cast<uint8_t>(identify->mEffectVariant));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void effect_cb(Identify *identify)
|
static void effect_cb(Identify *identify)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Effect callback");
|
ESP_LOGI(TAG, "Effect callback");
|
||||||
execute_callback(EFFECT, identify->mEndpoint, static_cast<uint8_t>(identify->mCurrentEffectIdentifier), static_cast<uint8_t>(identify->mEffectVariant));
|
execute_callback(EFFECT, identify->mEndpoint, static_cast<uint8_t>(identify->mCurrentEffectIdentifier),
|
||||||
|
static_cast<uint8_t>(identify->mEffectVariant));
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t init(uint16_t endpoint_id, uint8_t identify_type, uint8_t effect_identifier, uint8_t effect_variant)
|
esp_err_t init(uint16_t endpoint_id, uint8_t identify_type, uint8_t effect_identifier, uint8_t effect_variant)
|
||||||
{
|
{
|
||||||
Identify *identify = chip::Platform::New<Identify>(endpoint_id, start_cb, stop_cb, (chip::app::Clusters::Identify::IdentifyTypeEnum)identify_type,
|
Identify *identify = chip::Platform::New<Identify>(
|
||||||
effect_cb, static_cast<chip::app::Clusters::Identify::EffectIdentifierEnum>(effect_identifier),
|
endpoint_id, start_cb, stop_cb, (chip::app::Clusters::Identify::IdentifyTypeEnum)identify_type, effect_cb,
|
||||||
|
static_cast<chip::app::Clusters::Identify::EffectIdentifierEnum>(effect_identifier),
|
||||||
static_cast<chip::app::Clusters::Identify::EffectVariantEnum>(effect_variant));
|
static_cast<chip::app::Clusters::Identify::EffectVariantEnum>(effect_variant));
|
||||||
VerifyOrReturnError(identify, ESP_FAIL, ESP_LOGE(TAG, "Fail to create identify object"));
|
VerifyOrReturnError(identify, ESP_FAIL, ESP_LOGE(TAG, "Fail to create identify object"));
|
||||||
|
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
|
||||||
endpoint::set_identify(endpoint_id, (void *)identify);
|
endpoint::set_identify(endpoint_id, (void *)identify);
|
||||||
|
#elif defined(USE_IDENTIFY_ARRAY)
|
||||||
|
uint16_t index = emberAfGetClusterServerEndpointIndex(endpoint_id, chip::app::Clusters::Identify::Id,
|
||||||
|
MATTER_DM_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT);
|
||||||
|
if (index < MATTER_ARRAY_SIZE(g_identifies)) {
|
||||||
|
g_identifies[index] = identify;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* identification */
|
} // namespace identification
|
||||||
} /* esp_matter */
|
} // namespace esp_matter
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
|
#include <app-common/zap-generated/cluster-enums.h>
|
||||||
|
|
||||||
namespace esp_matter {
|
namespace esp_matter {
|
||||||
namespace identification {
|
namespace identification {
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ using chip::Server;
|
|||||||
using chip::DeviceLayer::ExtendedOTARequestorDriver;
|
using chip::DeviceLayer::ExtendedOTARequestorDriver;
|
||||||
|
|
||||||
using namespace esp_matter;
|
using namespace esp_matter;
|
||||||
using namespace esp_matter::endpoint;
|
|
||||||
using namespace esp_matter::cluster;
|
|
||||||
|
|
||||||
#if CONFIG_ENABLE_OTA_REQUESTOR
|
#if CONFIG_ENABLE_OTA_REQUESTOR
|
||||||
DefaultOTARequestor gRequestorCore;
|
DefaultOTARequestor gRequestorCore;
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
idf_component_register(SRC_DIRS "${CMAKE_CURRENT_LIST_DIR}"
|
set(src_dirs_list )
|
||||||
INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}"
|
set(include_dirs_list )
|
||||||
|
|
||||||
|
if (CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
||||||
|
list(APPEND src_dirs_list "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
list(APPEND include_dirs_list "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
endif()
|
||||||
|
idf_component_register(SRC_DIRS ${src_dirs_list}
|
||||||
|
INCLUDE_DIRS ${include_dirs_list}
|
||||||
REQUIRES esp_matter)
|
REQUIRES esp_matter)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <sdkconfig.h>
|
#include <sdkconfig.h>
|
||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_matter_core.h>
|
#include <esp_matter_data_model.h>
|
||||||
|
|
||||||
#define MAX_BRIDGED_DEVICE_COUNT \
|
#define MAX_BRIDGED_DEVICE_COUNT \
|
||||||
CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT - 1 - CONFIG_ESP_MATTER_AGGREGATOR_ENDPOINT_COUNT
|
CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT - 1 - CONFIG_ESP_MATTER_AGGREGATOR_ENDPOINT_COUNT
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ if (CONFIG_ESP_MATTER_CONTROLLER_ENABLE)
|
|||||||
list(APPEND include_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/core"
|
list(APPEND include_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/core"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/commands"
|
"${CMAKE_CURRENT_SOURCE_DIR}/commands"
|
||||||
"${MATTER_SDK_PATH}/zzz_generated/chip-tool"
|
"${MATTER_SDK_PATH}/zzz_generated/chip-tool"
|
||||||
"${MATTER_SDK_PATH}/examples/chip-tool/")
|
"${MATTER_SDK_PATH}/examples/chip-tool/"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/data_model_provider")
|
||||||
|
|
||||||
if (CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER)
|
if (CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER)
|
||||||
list(APPEND exclude_srcs_list "${CMAKE_CURRENT_SOURCE_DIR}/core/esp_matter_controller_client.cpp"
|
list(APPEND exclude_srcs_list "${CMAKE_CURRENT_SOURCE_DIR}/core/esp_matter_controller_client.cpp"
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include <setup_payload/SetupPayload.h>
|
#include <setup_payload/SetupPayload.h>
|
||||||
|
|
||||||
using namespace chip::app::Clusters;
|
using namespace chip::app::Clusters;
|
||||||
using namespace esp_matter::cluster;
|
|
||||||
using namespace esp_matter::client;
|
using namespace esp_matter::client;
|
||||||
static const char *TAG = "cluster_command";
|
static const char *TAG = "cluster_command";
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
|
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
|
||||||
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
|
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
|
||||||
#include <crypto/CHIPCryptoPAL.h>
|
#include <crypto/CHIPCryptoPAL.h>
|
||||||
#include <data-model-providers/codegen/Instance.h>
|
#include <controller_data_model_provider.h>
|
||||||
#include <lib/core/CHIPError.h>
|
#include <lib/core/CHIPError.h>
|
||||||
#include <lib/core/DataModelTypes.h>
|
#include <lib/core/DataModelTypes.h>
|
||||||
#include <lib/support/CHIPMem.h>
|
#include <lib/support/CHIPMem.h>
|
||||||
@@ -70,7 +70,7 @@ esp_err_t matter_controller_client::init(NodeId node_id, FabricId fabric_id, uin
|
|||||||
factory_init_params.opCertStore = &m_operational_cert_store;
|
factory_init_params.opCertStore = &m_operational_cert_store;
|
||||||
factory_init_params.enableServerInteractions = m_operational_advertising;
|
factory_init_params.enableServerInteractions = m_operational_advertising;
|
||||||
factory_init_params.sessionKeystore = &m_session_key_store;
|
factory_init_params.sessionKeystore = &m_session_key_store;
|
||||||
factory_init_params.dataModelProvider = chip::app::CodegenDataModelProviderInstance(&m_default_storage);
|
factory_init_params.dataModelProvider = &data_model::provider::get_instance();
|
||||||
m_controller_node_id = node_id;
|
m_controller_node_id = node_id;
|
||||||
m_controller_fabric_id = fabric_id;
|
m_controller_fabric_id = fabric_id;
|
||||||
|
|
||||||
|
|||||||
+130
@@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <app/AttributePathParams.h>
|
||||||
|
#include <app/AttributeValueDecoder.h>
|
||||||
|
#include <app/AttributeValueEncoder.h>
|
||||||
|
#include <app/CommandHandler.h>
|
||||||
|
#include <app/ConcreteAttributePath.h>
|
||||||
|
#include <app/ConcreteClusterPath.h>
|
||||||
|
#include <app/ConcreteCommandPath.h>
|
||||||
|
#include <app/data-model-provider/ActionReturnStatus.h>
|
||||||
|
#include <app/data-model-provider/MetadataTypes.h>
|
||||||
|
#include <app/data-model-provider/OperationTypes.h>
|
||||||
|
#include <app/data-model-provider/Provider.h>
|
||||||
|
#include <lib/support/ReadOnlyBuffer.h>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
using chip::ClusterId;
|
||||||
|
using chip::CommandId;
|
||||||
|
using chip::EndpointId;
|
||||||
|
using chip::ReadOnlyBufferBuilder;
|
||||||
|
using chip::app::AttributePathParams;
|
||||||
|
using chip::app::AttributeValueDecoder;
|
||||||
|
using chip::app::AttributeValueEncoder;
|
||||||
|
using chip::app::CommandHandler;
|
||||||
|
using chip::app::ConcreteAttributePath;
|
||||||
|
using chip::app::ConcreteClusterPath;
|
||||||
|
using chip::app::ConcreteCommandPath;
|
||||||
|
using chip::app::DataModel::AcceptedCommandEntry;
|
||||||
|
using chip::app::DataModel::ActionReturnStatus;
|
||||||
|
using chip::app::DataModel::AttributeEntry;
|
||||||
|
using chip::app::DataModel::ClusterInfo;
|
||||||
|
using chip::app::DataModel::DeviceTypeEntry;
|
||||||
|
using chip::app::DataModel::EndpointEntry;
|
||||||
|
using chip::app::DataModel::InvokeRequest;
|
||||||
|
using chip::app::DataModel::ListWriteOperation;
|
||||||
|
using chip::app::DataModel::ReadAttributeRequest;
|
||||||
|
using chip::app::DataModel::ServerClusterEntry;
|
||||||
|
using chip::app::DataModel::WriteAttributeRequest;
|
||||||
|
using chip::TLV::TLVReader;
|
||||||
|
|
||||||
|
namespace esp_matter {
|
||||||
|
namespace controller {
|
||||||
|
namespace data_model {
|
||||||
|
|
||||||
|
// TODO: The client-only controller has no data model, use an empty data model provider for it.
|
||||||
|
// We should finish the functions after enabling dynamic server for the controller.
|
||||||
|
class provider : public chip::app::DataModel::Provider {
|
||||||
|
public:
|
||||||
|
static provider &get_instance()
|
||||||
|
{
|
||||||
|
static provider instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIP_ERROR Shutdown() override { return CHIP_NO_ERROR; }
|
||||||
|
|
||||||
|
ActionReturnStatus ReadAttribute(const ReadAttributeRequest &request, AttributeValueEncoder &encoder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionReturnStatus WriteAttribute(const WriteAttributeRequest &request, AttributeValueDecoder &decoder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListAttributeWriteNotification(const ConcreteAttributePath &aPath, ListWriteOperation opType) override {}
|
||||||
|
|
||||||
|
std::optional<ActionReturnStatus> InvokeCommand(const InvokeRequest &request, TLVReader &input_arguments,
|
||||||
|
CommandHandler *handler) override
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderMetadataTree overrides
|
||||||
|
CHIP_ERROR Endpoints(ReadOnlyBufferBuilder<EndpointEntry> &builder) override { return CHIP_NO_ERROR; }
|
||||||
|
CHIP_ERROR SemanticTags(EndpointId endpointId, ReadOnlyBufferBuilder<SemanticTag> &builder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
CHIP_ERROR DeviceTypes(EndpointId endpointId, ReadOnlyBufferBuilder<DeviceTypeEntry> &builder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
CHIP_ERROR ClientClusters(EndpointId endpointId, ReadOnlyBufferBuilder<ClusterId> &builder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
CHIP_ERROR ServerClusters(EndpointId endpointId, ReadOnlyBufferBuilder<ServerClusterEntry> &builder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIP_ERROR Attributes(const ConcreteClusterPath &path, ReadOnlyBufferBuilder<AttributeEntry> &builder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
CHIP_ERROR GeneratedCommands(const ConcreteClusterPath &path, ReadOnlyBufferBuilder<CommandId> &builder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
CHIP_ERROR AcceptedCommands(const ConcreteClusterPath &path,
|
||||||
|
ReadOnlyBufferBuilder<AcceptedCommandEntry> &builder) override
|
||||||
|
{
|
||||||
|
return CHIP_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Temporary_ReportAttributeChanged(const AttributePathParams &path) override {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
provider() = default;
|
||||||
|
~provider() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace data_model
|
||||||
|
} // namespace controller
|
||||||
|
} // namespace esp_matter
|
||||||
+6
-5
@@ -21,12 +21,13 @@ PROJECT_NAME = "Programming Guide"
|
|||||||
## and used to include in API reference documentation
|
## and used to include in API reference documentation
|
||||||
|
|
||||||
INPUT = \
|
INPUT = \
|
||||||
$(PROJECT_PATH)/components/esp_matter/esp_matter_endpoint.h \
|
$(PROJECT_PATH)/components/esp_matter/data_model/esp_matter_endpoint.h \
|
||||||
$(PROJECT_PATH)/components/esp_matter/esp_matter_cluster.h \
|
$(PROJECT_PATH)/components/esp_matter/data_model/esp_matter_cluster.h \
|
||||||
$(PROJECT_PATH)/components/esp_matter/esp_matter_attribute.h \
|
$(PROJECT_PATH)/components/esp_matter/data_model/esp_matter_attribute.h \
|
||||||
$(PROJECT_PATH)/components/esp_matter/esp_matter_command.h \
|
$(PROJECT_PATH)/components/esp_matter/data_model/esp_matter_command.h \
|
||||||
|
$(PROJECT_PATH)/components/esp_matter/data_model/esp_matter_event.h \
|
||||||
|
$(PROJECT_PATH)/components/esp_matter/data_model/esp_matter_data_model.h \
|
||||||
$(PROJECT_PATH)/components/esp_matter/esp_matter_core.h \
|
$(PROJECT_PATH)/components/esp_matter/esp_matter_core.h \
|
||||||
$(PROJECT_PATH)/components/esp_matter/esp_matter_event.h \
|
|
||||||
$(PROJECT_PATH)/components/esp_matter/esp_matter_client.h \
|
$(PROJECT_PATH)/components/esp_matter/esp_matter_client.h \
|
||||||
|
|
||||||
## Get warnings for functions that have no documentation for their parameters or return value
|
## Get warnings for functions that have no documentation for their parameters or return value
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Data Model
|
||||||
|
==========
|
||||||
|
|
||||||
|
This has the high level APIs for Data Model.
|
||||||
|
|
||||||
|
API reference
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. include-build-file:: inc/esp_matter_data_model.inc
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
esp_matter_data_model.rst
|
||||||
esp_matter_endpoint.rst
|
esp_matter_endpoint.rst
|
||||||
esp_matter_cluster.rst
|
esp_matter_cluster.rst
|
||||||
esp_matter_attribute.rst
|
esp_matter_attribute.rst
|
||||||
|
|||||||
@@ -648,7 +648,7 @@ for clarity on the terms like endpoints, clusters, etc. that are used in this se
|
|||||||
node_t *node = node::create(&node_config, app_attribute_update_cb, NULL);
|
node_t *node = node::create(&node_config, app_attribute_update_cb, NULL);
|
||||||
|
|
||||||
- We will use the ``color_temperature_light`` standard device type in this
|
- We will use the ``color_temperature_light`` standard device type in this
|
||||||
case. All standard device types are available in :project_file:`esp_matter_endpoint.h <components/esp_matter/esp_matter_endpoint.h>` header file.
|
case. All standard device types are available in :project_file:`esp_matter_endpoint.h <components/esp_matter/data_model/esp_matter_endpoint.h>` header file.
|
||||||
Each device type has a set of default configuration that can be
|
Each device type has a set of default configuration that can be
|
||||||
specific as well.
|
specific as well.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -170,7 +170,7 @@ A1.8 Why does free RAM increase after first commissioning
|
|||||||
After the first commissioning, you may notice that the free RAM increases. This is because, by default,
|
After the first commissioning, you may notice that the free RAM increases. This is because, by default,
|
||||||
BLE is only used for the commissioning process. Once the commissioning is complete, BLE is deinitialized,
|
BLE is only used for the commissioning process. Once the commissioning is complete, BLE is deinitialized,
|
||||||
and all the memory allocated to it is recovered. Here's the link to the
|
and all the memory allocated to it is recovered. Here's the link to the
|
||||||
:project_file:`implementation which frees the BLE memory <components/esp_matter/esp_matter_core.cpp#L859-L891>`.
|
:project_file:`implementation which frees the BLE memory <components/esp_matter/esp_matter_core.cpp#L287-L290>`.
|
||||||
|
|
||||||
However, if you want to continue using the BLE even after the commissioning process, you can disable the
|
However, if you want to continue using the BLE even after the commissioning process, you can disable the
|
||||||
``CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING``. This will ensure that the memory allocated to the BLE functionality
|
``CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING``. This will ensure that the memory allocated to the BLE functionality
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
idf_component_register(SRCS "app_bridged_device.cpp"
|
set(srcs_list )
|
||||||
INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}"
|
set(include_dirs_list )
|
||||||
|
if (CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
||||||
|
list(APPEND srcs_list "app_bridged_device.cpp")
|
||||||
|
list(APPEND include_dirs_list "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_component_register(SRCS ${srcs_list}
|
||||||
|
INCLUDE_DIRS ${include_dirs_list}
|
||||||
REQUIRES esp_matter_bridge)
|
REQUIRES esp_matter_bridge)
|
||||||
|
|||||||
@@ -6,31 +6,15 @@ if(NOT DEFINED ENV{ESP_MATTER_PATH})
|
|||||||
message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo")
|
message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo")
|
||||||
endif(NOT DEFINED ENV{ESP_MATTER_PATH})
|
endif(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||||
|
|
||||||
if(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
|
||||||
if("${IDF_TARGET}" STREQUAL "esp32" OR "${IDF_TARGET}" STREQUAL "")
|
|
||||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32_devkit_c)
|
|
||||||
elseif("${IDF_TARGET}" STREQUAL "esp32c3")
|
|
||||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c3_devkit_m)
|
|
||||||
elseif("${IDF_TARGET}" STREQUAL "esp32s3")
|
|
||||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32s3_devkit_c)
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unsupported IDF_TARGET")
|
|
||||||
endif()
|
|
||||||
endif(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
|
||||||
|
|
||||||
set(ESP_MATTER_PATH $ENV{ESP_MATTER_PATH})
|
set(ESP_MATTER_PATH $ENV{ESP_MATTER_PATH})
|
||||||
set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip)
|
set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip)
|
||||||
|
|
||||||
# This should be done before using the IDF_TARGET variable.
|
# This should be done before using the IDF_TARGET variable.
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
include($ENV{ESP_MATTER_DEVICE_PATH}/esp_matter_device.cmake)
|
|
||||||
|
|
||||||
set(EXTRA_COMPONENT_DIRS
|
set(EXTRA_COMPONENT_DIRS
|
||||||
"${ESP_MATTER_PATH}/examples/common"
|
|
||||||
"${MATTER_SDK_PATH}/config/esp32/components"
|
"${MATTER_SDK_PATH}/config/esp32/components"
|
||||||
"${ESP_MATTER_PATH}/components"
|
"${ESP_MATTER_PATH}/components")
|
||||||
"${ESP_MATTER_PATH}/device_hal/device"
|
|
||||||
${extra_components_dirs_append})
|
|
||||||
|
|
||||||
project(controller)
|
project(controller)
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <esp_spiffs.h>
|
#include <esp_spiffs.h>
|
||||||
#include <platform/ESP32/OpenthreadLauncher.h>
|
#include <platform/ESP32/OpenthreadLauncher.h>
|
||||||
#endif // CONFIG_OPENTHREAD_BORDER_ROUTER
|
#endif // CONFIG_OPENTHREAD_BORDER_ROUTER
|
||||||
#include <app_reset.h>
|
|
||||||
#include <common_macros.h>
|
#include <common_macros.h>
|
||||||
|
|
||||||
#include <app/server/Server.h>
|
#include <app/server/Server.h>
|
||||||
@@ -32,10 +31,6 @@
|
|||||||
static const char *TAG = "app_main";
|
static const char *TAG = "app_main";
|
||||||
uint16_t switch_endpoint_id = 0;
|
uint16_t switch_endpoint_id = 0;
|
||||||
|
|
||||||
using namespace esp_matter;
|
|
||||||
using namespace esp_matter::attribute;
|
|
||||||
using namespace esp_matter::endpoint;
|
|
||||||
|
|
||||||
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
|
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
|
||||||
{
|
{
|
||||||
switch (event->Type) {
|
switch (event->Type) {
|
||||||
|
|||||||
@@ -27,3 +27,6 @@ CONFIG_DEVICE_VENDOR_ID=0x131B
|
|||||||
# Disable STA and AP
|
# Disable STA and AP
|
||||||
CONFIG_ENABLE_WIFI_STATION=n
|
CONFIG_ENABLE_WIFI_STATION=n
|
||||||
CONFIG_ENABLE_WIFI_AP=n
|
CONFIG_ENABLE_WIFI_AP=n
|
||||||
|
|
||||||
|
# Disable Matter server as the test app doesn't start Matter server
|
||||||
|
CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER=n
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <esp_matter.h>
|
#include <esp_matter.h>
|
||||||
#include <esp_matter_console.h>
|
#include <esp_matter_console.h>
|
||||||
|
#include <esp_matter_identify.h>
|
||||||
|
|
||||||
#include <common_macros.h>
|
#include <common_macros.h>
|
||||||
#include <app_priv.h>
|
#include <app_priv.h>
|
||||||
@@ -110,6 +111,9 @@ extern "C" void app_main()
|
|||||||
err = esp_matter::start(app_event_cb);
|
err = esp_matter::start(app_event_cb);
|
||||||
ABORT_APP_ON_FAILURE(err == ESP_OK, ESP_LOGE(TAG, "Failed to start Matter, err:%d", err));
|
ABORT_APP_ON_FAILURE(err == ESP_OK, ESP_LOGE(TAG, "Failed to start Matter, err:%d", err));
|
||||||
|
|
||||||
|
esp_matter::identification::init(1, 0);
|
||||||
|
esp_matter::identification::set_callback(nullptr);
|
||||||
|
|
||||||
/* Starting driver with default values */
|
/* Starting driver with default values */
|
||||||
app_driver_light_set_defaults(light_endpoint_id);
|
app_driver_light_set_defaults(light_endpoint_id);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user