Merge branch 'feature/aggregator_device' into 'main'

esp_matter: Add aggregator device type for bridge apps

See merge request app-frameworks/esp-matter!187
This commit is contained in:
Shu Chen
2022-09-15 19:49:46 +08:00
20 changed files with 416 additions and 28 deletions
@@ -70,6 +70,30 @@ attribute_t *create_parts_list(cluster_t *cluster, uint8_t *value, uint16_t leng
} /* attribute */
} /* descriptor */
namespace actions {
namespace attribute {
attribute_t *create_action_list(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
{
return esp_matter::attribute::create(cluster, Actions::Attributes::ActionList::Id, ATTRIBUTE_FLAG_NONE,
esp_matter_array(value, length, count));
}
attribute_t *create_endpoint_lists(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
{
return esp_matter::attribute::create(cluster, Actions::Attributes::EndpointLists::Id, ATTRIBUTE_FLAG_NONE,
esp_matter_array(value, length, count));
}
attribute_t *create_setup_url(cluster_t *cluster, char *value, uint16_t length)
{
return esp_matter::attribute::create(cluster, Actions::Attributes::SetupURL::Id, ATTRIBUTE_FLAG_NONE,
esp_matter_char_str(value, length));
}
} /* attribute */
} /* actions */
namespace access_control {
namespace attribute {
@@ -42,6 +42,14 @@ attribute_t *create_parts_list(cluster_t *cluster, uint8_t *value, uint16_t leng
} /* attribute */
} /* descriptor */
namespace actions {
namespace attribute {
attribute_t *create_action_list(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
attribute_t *create_endpoint_lists(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
attribute_t *create_setup_url(cluster_t *cluster, char *value, uint16_t length);
} /* attribute */
} /* actions */
namespace access_control {
namespace attribute {
attribute_t *create_acl(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
@@ -102,6 +102,39 @@ cluster_t *create(endpoint_t *endpoint, uint8_t flags)
}
} /* descriptor */
namespace actions {
const function_generic_t *function_list = NULL;
const int function_flags = CLUSTER_FLAG_NONE;
cluster_t *create(endpoint_t *endpoint, uint8_t flags)
{
cluster_t *cluster = cluster::create(endpoint, Descriptor::Id, flags);
if (!cluster) {
ESP_LOGE(TAG, "Could not create cluster");
return NULL;
}
if (flags & CLUSTER_FLAG_SERVER) {
set_plugin_server_init_callback(cluster, NULL);
add_function_list(cluster, function_list, function_flags);
}
if (flags & CLUSTER_FLAG_CLIENT) {
set_plugin_client_init_callback(cluster, NULL);
create_default_binding_cluster(endpoint);
}
if (flags & CLUSTER_FLAG_SERVER) {
/* Attributes managed internally */
global::attribute::create_cluster_revision(cluster, 1);
global::attribute::create_feature_map(cluster, 0);
attribute::create_action_list(cluster, NULL, 0, 0);
attribute::create_endpoint_lists(cluster, NULL, 0, 0);
}
return cluster;
}
} /* actions */
namespace access_control {
const function_generic_t *function_list = NULL;
const int function_flags = CLUSTER_FLAG_NONE;
@@ -44,6 +44,10 @@ namespace descriptor {
cluster_t *create(endpoint_t *endpoint, uint8_t flags);
} /* descriptor */
namespace actions {
cluster_t *create(endpoint_t *endpoint, uint8_t flags);
} /* actions */
namespace access_control {
cluster_t *create(endpoint_t *endpoint, uint8_t flags);
} /* access_control */
@@ -1102,9 +1102,218 @@ static esp_err_t esp_matter_command_callback_go_to_tilt_percentage(const Concret
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_instance_action(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_instance_action_with_transition(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_start_action(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_start_action_with_duration(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_stop_action(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_pause_action(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_pause_action_with_duration(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_resume_action(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_enable_action(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_enable_action_with_duration(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_disable_action(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
static esp_err_t esp_matter_command_callback_disable_action_with_duration(const ConcreteCommandPath &command_path,
TLVReader &tlv_data, void *opaque_ptr)
{
// No actions are implemented, just return status NotFound.
// TODO: Add action callbacks for actions cluster.
CommandHandler *command_handler = (CommandHandler *)opaque_ptr;
command_handler->AddStatus(command_path, chip::Protocols::InteractionModel::Status::NotFound);
return ESP_OK;
}
namespace esp_matter {
namespace cluster {
namespace actions {
namespace command {
command_t *create_instant_action(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::InstantAction::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_instance_action);
}
command_t *create_instant_action_with_transition(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::InstantActionWithTransition::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_instance_action_with_transition);
}
command_t *create_start_action(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::StartAction::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_start_action);
}
command_t *create_start_action_with_duration(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::StartActionWithDuration::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_start_action_with_duration);
}
command_t *create_stop_action(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::StopAction::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_stop_action);
}
command_t *create_pause_action(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::PauseAction::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_pause_action);
}
command_t *create_pause_action_with_duration(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::PauseActionWithDuration::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_pause_action_with_duration);
}
command_t *create_resume_action(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::ResumeAction::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_resume_action);
}
command_t *create_enable_action(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::EnableAction::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_enable_action);
}
command_t *create_enable_action_with_duration(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::EnableActionWithDuration::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_enable_action_with_duration);
}
command_t *create_disable_action(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::DisableAction::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_disable_action);
}
command_t *create_disable_action_with_duration(cluster_t *cluster)
{
return esp_matter::command::create(cluster, Actions::Commands::DisableActionWithDuration::Id, COMMAND_FLAG_ACCEPTED,
esp_matter_command_callback_disable_action_with_duration);
}
} /* command */
} /* actions */
namespace diagnostics_network_thread {
namespace command {
@@ -25,6 +25,23 @@ namespace cluster {
* If a custom command needs to be created, the low level esp_matter::command::create() API can be used.
*/
namespace actions {
namespace command {
command_t *create_instant_action(cluster_t *cluster);
command_t *create_instant_action_with_transition(cluster_t *cluster);
command_t *create_start_action(cluster_t *cluster);
command_t *create_start_action_with_duration(cluster_t *cluster);
command_t *create_stop_action(cluster_t *cluster);
command_t *create_pause_action(cluster_t *cluster);
command_t *create_pause_action_with_duration(cluster_t *cluster);
command_t *create_resume_action(cluster_t *cluster);
command_t *create_enable_action(cluster_t *cluster);
command_t *create_enable_action_with_duration(cluster_t *cluster);
command_t *create_disable_action(cluster_t *cluster);
command_t *create_disable_action_with_duration(cluster_t *cluster);
} /* command */
} /* actions */
namespace diagnostics_network_thread {
namespace command {
command_t *create_reset_counts(cluster_t *cluster);
+4 -3
View File
@@ -377,7 +377,7 @@ static esp_err_t disable(endpoint_t *endpoint)
return ESP_OK;
}
esp_err_t enable(endpoint_t *endpoint)
esp_err_t enable(endpoint_t *endpoint, uint16_t parent_endpoint_id)
{
if (!endpoint) {
ESP_LOGE(TAG, "Endpoint cannot be NULL");
@@ -568,7 +568,7 @@ esp_err_t enable(endpoint_t *endpoint)
/* Add Endpoint */
endpoint_index = endpoint::get_next_index();
status = emberAfSetDynamicEndpoint(endpoint_index, current_endpoint->endpoint_id, endpoint_type, data_versions,
device_types);
device_types, parent_endpoint_id);
if (status != EMBER_ZCL_STATUS_SUCCESS) {
ESP_LOGE(TAG, "Error adding dynamic endpoint %d: 0x%x", current_endpoint->endpoint_id, status);
err = ESP_FAIL;
@@ -634,7 +634,8 @@ static esp_err_t enable_all()
endpoint_t *endpoint = get_first(node);
while (endpoint) {
enable(endpoint);
/* The normal endpoints do not have parent endpoint */
enable(endpoint, chip::kInvalidEndpointId);
endpoint = get_next(endpoint);
}
return ESP_OK;
+2 -1
View File
@@ -239,11 +239,12 @@ void *get_priv_data(uint16_t endpoint_id);
* called after all the clusters, attributes and commands have been added to the created endpoint.
*
* @param[in] endpoint Endpoint handle.
* @param[in] parent_endpoint_id Parent Endpoint Id for the endpoint to be enabled, applicable only for bridges.
*
* @return ESP_OK on success.
* @return error in case of failure.
*/
esp_err_t enable(endpoint_t *endpoint);
esp_err_t enable(endpoint_t *endpoint, uint16_t parent_endpoint_id);
} /* endpoint */
+18 -4
View File
@@ -18,7 +18,7 @@
/* Replace these with IDs from submodule whenever they are implemented */
#define ESP_MATTER_ROOT_NODE_DEVICE_TYPE_ID 0x0016
#define ESP_MATTER_BRIDGE_DEVICE_TYPE_ID 0x000E
#define ESP_MATTER_AGGREGATOR_DEVICE_TYPE_ID 0x000E
#define ESP_MATTER_BRIDGED_NODE_DEVICE_TYPE_ID 0x0013
#define ESP_MATTER_ON_OFF_LIGHT_DEVICE_TYPE_ID 0x0100
@@ -368,12 +368,26 @@ endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_dat
}
} /* thermostat */
namespace bridge {
namespace aggregator {
uint32_t get_device_type_id()
{
return ESP_MATTER_BRIDGE_DEVICE_TYPE_ID;
return ESP_MATTER_AGGREGATOR_DEVICE_TYPE_ID;
}
} /* bridge */
endpoint_t *create(node_t *node, uint8_t flags, void *priv_data)
{
endpoint_t *endpoint = endpoint::create(node, flags, priv_data);
if (!endpoint) {
ESP_LOGE(TAG, "Could not create endpoint");
return NULL;
}
add_device_type_id(endpoint, get_device_type_id());
descriptor::create(endpoint,CLUSTER_FLAG_SERVER);
return endpoint;
}
} /* aggregator */
namespace bridged_node {
uint32_t get_device_type_id()
+2 -1
View File
@@ -176,8 +176,9 @@ uint32_t get_device_type_id();
endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data);
} /* thermostat */
namespace bridge {
namespace aggregator {
uint32_t get_device_type_id();
endpoint_t *create(node_t *node, uint8_t flags, void *priv_data);
} /* bridge */
namespace bridged_node {
@@ -171,6 +171,23 @@ esp_err_t send_turbine_operation()
} /* event */
} /* pump_configuration_and_control */
namespace actions {
namespace event {
esp_err_t send_state_changed(EndpointId endpoint, uint16_t action_id, uint32_t invoke_id, uint8_t action_state)
{
/* Not implemented */
return ESP_OK;
}
esp_err_t send_action_failed(EndpointId endpoint, uint16_t action_id, uint32_t invoke_id, uint8_t action_state,
uint8_t error)
{
/* Not implemented */
return ESP_OK;
}
} /* event */
} /* actions */
namespace switch_cluster {
namespace event {
+10
View File
@@ -0,0 +1,10 @@
menu "ESP Matter Bridge"
config ESP_MATTER_AGGREGATOR_ENDPOINT_COUNT
int "The number of aggregator endpoints"
range 1 5
default 1
help
The number of aggregator endpoint for the bridge device
endmenu
@@ -23,10 +23,35 @@ static const char *TAG = "esp_matter_bridge";
using namespace esp_matter;
using namespace esp_matter::endpoint;
esp_matter_bridge_device_t *esp_matter_bridge_create_device(node_t *node)
esp_matter_bridge_device_t *esp_matter_bridge_create_device(node_t *node, uint16_t parent_endpoint_id)
{
endpoint_t *parent_endpoint = endpoint::get(node, parent_endpoint_id);
if (!node || !parent_endpoint) {
ESP_LOGE(TAG, "Cannot create a bridged device for a NULL node or an invalid parent endpoint");
return NULL;
}
uint8_t device_type_count = 0;
bool parent_endpoint_valid = false;
uint32_t *device_type_ids_ptr = get_device_type_ids(parent_endpoint, &device_type_count);
if (device_type_ids_ptr != NULL) {
for (uint8_t i = 0; i <= device_type_count; ++i) {
if (device_type_ids_ptr[i] == esp_matter::endpoint::aggregator::get_device_type_id()) {
parent_endpoint_valid = true;
break;
}
}
if (!parent_endpoint_valid) {
ESP_LOGE(TAG, "The device types of the parent endpoint must include aggregator");
return NULL;
}
} else {
ESP_LOGE(TAG, "Failed to get the device types of the parent endpoint");
return NULL;
}
esp_matter_bridge_device_t *dev = (esp_matter_bridge_device_t *)calloc(1, sizeof(esp_matter_bridge_device_t));
dev->node = node;
dev->parent_endpoint_id = parent_endpoint_id;
bridged_node::config_t bridged_node_config;
dev->endpoint = bridged_node::create(node, &bridged_node_config, ENDPOINT_FLAG_DESTROYABLE | ENDPOINT_FLAG_BRIDGE,
NULL);
@@ -35,7 +60,6 @@ esp_matter_bridge_device_t *esp_matter_bridge_create_device(node_t *node)
free(dev);
return NULL;
}
dev->endpoint_id = endpoint::get_id(dev->endpoint);
return dev;
}
@@ -18,15 +18,15 @@
#include <esp_err.h>
#include <esp_matter_core.h>
#define MAX_BRIDGED_DEVICE_COUNT CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT - 1
#define MAX_BRIDGED_DEVICE_COUNT CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT - 1 - CONFIG_ESP_MATTER_AGGREGATOR_ENDPOINT_COUNT
// There is an endpoint reserved as root endpoint
typedef struct esp_matter_bridge_device {
esp_matter::node_t *node;
esp_matter::endpoint_t *endpoint;
uint16_t endpoint_id;
uint16_t parent_endpoint_id;
} esp_matter_bridge_device_t;
esp_matter_bridge_device_t *esp_matter_bridge_create_device(esp_matter::node_t *node);
esp_matter_bridge_device_t *esp_matter_bridge_create_device(esp_matter::node_t *node, uint16_t parent_endpoint_id);
esp_err_t esp_matter_bridge_remove_device(esp_matter_bridge_device_t *bridged_device);
@@ -25,6 +25,8 @@ static const char *TAG = "app_main";
using namespace esp_matter;
using namespace esp_matter::attribute;
uint16_t aggregator_endpoint_id = chip::kInvalidEndpointId;
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
{
switch (event->Type) {
@@ -88,6 +90,13 @@ extern "C" void app_main()
ESP_LOGE(TAG, "Matter node creation failed");
}
endpoint_t *aggregator = endpoint::aggregator::create(node, ENDPOINT_FLAG_NONE, NULL);
if (!aggregator) {
ESP_LOGE(TAG, "Matter aggregator endpoint creation failed");
}
aggregator_endpoint_id = endpoint::get_id(aggregator);
/* Matter start */
err = esp_matter::start(app_event_cb);
if (err != ESP_OK) {
@@ -23,6 +23,8 @@ static const char *TAG = "blemesh_bridge";
using namespace chip::app::Clusters;
using namespace esp_matter;
using namespace esp_matter::cluster;
extern uint16_t aggregator_endpoint_id;
/** Mesh Spec 4.2.1: "The Composition Data state contains information about a node,
* the elements it includes, and the supported models. Composition Data Page 0 is mandatory."
@@ -50,7 +52,7 @@ static esp_err_t blemesh_bridge_init_bridged_onoff_light(esp_matter_bridge_devic
on_off::config_t config;
on_off::create(dev->endpoint, &config, CLUSTER_MASK_SERVER, ESP_MATTER_NONE_FEATURE_ID);
endpoint::add_device_type_id(dev->endpoint, endpoint::on_off_light::get_device_type_id());
if (endpoint::enable(dev->endpoint) != ESP_OK) {
if (endpoint::enable(dev->endpoint, dev->parent_endpoint_id) != ESP_OK) {
ESP_LOGE(TAG, "ESP Matter enable dynamic endpoint failed");
endpoint::destroy(dev->node, dev->endpoint);
return ESP_FAIL;
@@ -69,7 +71,9 @@ esp_err_t blemesh_bridge_match_bridged_onoff_light(uint8_t *composition_data, ui
ESP_LOGI(TAG, "Bridged node for 0x%04x bridged device on endpoint %d has been created", blemesh_addr,
app_bridge_get_matter_endpointid_by_blemesh_addr(blemesh_addr));
} else {
app_bridged_device_t *bridged_device = app_bridge_create_bridged_device(node, ESP_MATTER_BRIDGED_DEVICE_TYPE_BLEMESH, app_bridge_blemesh_address(blemesh_addr));
app_bridged_device_t *bridged_device =
app_bridge_create_bridged_device(node, aggregator_endpoint_id, ESP_MATTER_BRIDGED_DEVICE_TYPE_BLEMESH,
app_bridge_blemesh_address(blemesh_addr));
ESP_RETURN_ON_FALSE(bridged_device, ESP_FAIL, TAG, "Failed to create bridged device (on_off light)");
ESP_RETURN_ON_ERROR(blemesh_bridge_init_bridged_onoff_light(bridged_device->dev), TAG, "Failed to initialize the bridged node");
ESP_LOGI(TAG, "Create/Update bridged node for 0x%04x bridged device on endpoint %d", blemesh_addr,
@@ -45,7 +45,7 @@ app_bridged_device_address_t app_bridge_blemesh_address(uint16_t blemesh_addr)
}
/** Bridged Device APIs */
app_bridged_device_t *app_bridge_create_bridged_device(node_t *node,
app_bridged_device_t *app_bridge_create_bridged_device(node_t *node, uint16_t parent_endpoint_id,
app_bridged_device_type_t bridged_device_type, app_bridged_device_address_t bridged_device_address)
{
if (g_current_bridged_device_count >= MAX_BRIDGED_DEVICE_COUNT) {
@@ -53,7 +53,7 @@ app_bridged_device_t *app_bridge_create_bridged_device(node_t *node,
return NULL;
}
app_bridged_device_t *new_dev = (app_bridged_device_t *)calloc(1, sizeof(app_bridged_device_t));
new_dev->dev = esp_matter_bridge_create_device(node);
new_dev->dev = esp_matter_bridge_create_device(node, parent_endpoint_id);
if (!(new_dev->dev)) {
ESP_LOGE(TAG, "Failed to create the basic bridged device");
free(new_dev);
@@ -71,7 +71,7 @@ app_bridged_device_t *app_bridge_get_device_by_matter_endpointid(uint16_t matter
{
app_bridged_device_t *current_dev = g_bridged_device_list;
while (current_dev) {
if (current_dev->dev && (current_dev->dev->endpoint_id == matter_endpointid)) {
if (current_dev->dev && (esp_matter::endpoint::get_id(current_dev->dev->endpoint) == matter_endpointid)) {
return current_dev;
}
current_dev = current_dev->next;
@@ -131,7 +131,7 @@ uint16_t app_bridge_get_matter_endpointid_by_zigbee_shortaddr(uint16_t zigbee_sh
while (current_dev) {
if (current_dev->dev_type == ESP_MATTER_BRIDGED_DEVICE_TYPE_ZIGBEE && current_dev->dev
&& current_dev->dev_addr.zigbee_shortaddr == zigbee_shortaddr) {
return current_dev->dev->endpoint_id;
return esp_matter::endpoint::get_id(current_dev->dev->endpoint);
}
current_dev = current_dev->next;
}
@@ -143,7 +143,7 @@ uint16_t app_bridge_get_zigbee_shortaddr_by_matter_endpointid(uint16_t matter_en
app_bridged_device_t *current_dev = g_bridged_device_list;
while (current_dev) {
if ((current_dev->dev_type == ESP_MATTER_BRIDGED_DEVICE_TYPE_ZIGBEE) && current_dev->dev
&& (current_dev->dev->endpoint_id == matter_endpointid)) {
&& (esp_matter::endpoint::get_id(current_dev->dev->endpoint) == matter_endpointid)) {
return current_dev->dev_addr.zigbee_shortaddr;
}
current_dev = current_dev->next;
@@ -171,7 +171,7 @@ uint16_t app_bridge_get_matter_endpointid_by_blemesh_addr(uint16_t blemesh_addr)
while (current_dev) {
if ((current_dev->dev_type == ESP_MATTER_BRIDGED_DEVICE_TYPE_BLEMESH) && current_dev->dev
&& (current_dev->dev_addr.blemesh_addr == blemesh_addr)) {
return current_dev->dev->endpoint_id;
return esp_matter::endpoint::get_id(current_dev->dev->endpoint);
}
current_dev = current_dev->next;
}
@@ -183,7 +183,7 @@ uint16_t app_bridge_get_blemesh_addr_by_matter_endpointid(uint16_t matter_endpoi
app_bridged_device_t *current_dev = g_bridged_device_list;
while (current_dev) {
if ((current_dev->dev_type == ESP_MATTER_BRIDGED_DEVICE_TYPE_BLEMESH) && current_dev->dev
&& (current_dev->dev->endpoint_id == matter_endpointid)) {
&& (esp_matter::endpoint::get_id(current_dev->dev->endpoint) == matter_endpointid)) {
return current_dev->dev_addr.blemesh_addr;
}
current_dev = current_dev->next;
@@ -59,7 +59,7 @@ app_bridged_device_address_t app_bridge_zigbee_address(uint8_t zigbee_endpointid
app_bridged_device_address_t app_bridge_blemesh_address(uint16_t blemesh_addr);
/** Bridged Device APIs */
app_bridged_device_t *app_bridge_create_bridged_device(node_t *node,
app_bridged_device_t *app_bridge_create_bridged_device(node_t *node, uint16_t parent_endpoint_id,
app_bridged_device_type_t bridged_device_type, app_bridged_device_address_t bridged_device_address);
app_bridged_device_t *app_bridge_get_device_by_matter_endpointid(uint16_t matter_endpointid);
+9
View File
@@ -24,6 +24,8 @@ static const char *TAG = "app_main";
using namespace esp_matter;
using namespace esp_matter::attribute;
uint16_t aggregator_endpoint_id = chip::kInvalidEndpointId;
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
{
switch (event->Type) {
@@ -87,6 +89,13 @@ extern "C" void app_main()
ESP_LOGE(TAG, "Matter node creation failed");
}
endpoint_t *aggregator = endpoint::aggregator::create(node, ENDPOINT_FLAG_NONE, NULL);
if (!aggregator) {
ESP_LOGE(TAG, "Matter aggregator endpoint creation failed");
} else {
aggregator_endpoint_id = endpoint::get_id(aggregator);
}
/* Matter start */
err = esp_matter::start(app_event_cb);
if (err != ESP_OK) {
@@ -20,6 +20,8 @@ using namespace chip::app::Clusters;
using namespace esp_matter;
using namespace esp_matter::cluster;
extern uint16_t aggregator_endpoint_id;
static esp_err_t zigbee_bridge_init_bridged_onoff_light(esp_matter_bridge_device_t *dev)
{
if (!dev) {
@@ -30,7 +32,7 @@ static esp_err_t zigbee_bridge_init_bridged_onoff_light(esp_matter_bridge_device
on_off::config_t config;
on_off::create(dev->endpoint, &config, CLUSTER_MASK_SERVER, ESP_MATTER_NONE_FEATURE_ID);
endpoint::add_device_type_id(dev->endpoint, endpoint::on_off_light::get_device_type_id());
if (endpoint::enable(dev->endpoint) != ESP_OK) {
if (endpoint::enable(dev->endpoint, dev->parent_endpoint_id) != ESP_OK) {
ESP_LOGE(TAG, "ESP Matter enable dynamic endpoint failed");
endpoint::destroy(dev->node, dev->endpoint);
return ESP_FAIL;
@@ -50,8 +52,9 @@ void zigbee_bridge_find_bridged_on_off_light_cb(zb_uint8_t zdo_status, zb_uint16
ESP_LOGI(TAG, "Bridged node for 0x%04x zigbee device on endpoint %d has been created", addr,
app_bridge_get_matter_endpointid_by_zigbee_shortaddr(addr));
} else {
app_bridged_device_t *bridged_device = app_bridge_create_bridged_device(
node, ESP_MATTER_BRIDGED_DEVICE_TYPE_ZIGBEE, app_bridge_zigbee_address(endpoint, addr));
app_bridged_device_t *bridged_device =
app_bridge_create_bridged_device(node, aggregator_endpoint_id, ESP_MATTER_BRIDGED_DEVICE_TYPE_ZIGBEE,
app_bridge_zigbee_address(endpoint, addr));
if (!bridged_device) {
ESP_LOGE(TAG, "Failed to create zigbee bridged device (on_off light)");
return;
@@ -78,7 +81,7 @@ esp_err_t zigbee_bridge_attribute_update(uint16_t endpoint_id, uint32_t cluster_
esp_zb_zcl_on_off_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = zigbee_device->dev_addr.zigbee_shortaddr;
cmd_req.zcl_basic_cmd.dst_endpoint = zigbee_device->dev_addr.zigbee_endpointid;
cmd_req.zcl_basic_cmd.src_endpoint = zigbee_device->dev->endpoint_id;
cmd_req.zcl_basic_cmd.src_endpoint = esp_matter::endpoint::get_id(zigbee_device->dev->endpoint);
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.on_off_cmd_id = val->val.b ? ZB_ZCL_CMD_ON_OFF_ON_ID : ZB_ZCL_CMD_ON_OFF_OFF_ID;
esp_zb_zcl_on_off_cmd_req(&cmd_req);