From 86eaaedbf6cb7dd43df12d232ad59c6952637e32 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Tue, 19 Nov 2024 11:54:33 +0530 Subject: [PATCH] components/esp-matter: Add Commissioner Control and Ecosystem Information clusters --- .../esp_matter/esp_matter_attribute.cpp | 28 ++++++++ components/esp_matter/esp_matter_attribute.h | 13 ++++ components/esp_matter/esp_matter_cluster.cpp | 66 +++++++++++++++++++ components/esp_matter/esp_matter_cluster.h | 15 +++++ components/esp_matter/esp_matter_command.cpp | 33 ++++++++++ components/esp_matter/esp_matter_command.h | 8 +++ .../esp_matter_delegate_callbacks.cpp | 11 ++++ .../esp_matter_delegate_callbacks.h | 1 + components/esp_matter/esp_matter_event.cpp | 10 +++ components/esp_matter/esp_matter_event.h | 6 ++ .../private/esp_matter_cluster_revisions.h | 8 +++ docs/en/app_guide.rst | 13 +++- 12 files changed, 211 insertions(+), 1 deletion(-) diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index c141447f4..d05ef40f5 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -4846,5 +4846,33 @@ attribute_t *create_current_low_power_mode_sensitivity(cluster_t *cluster, uint8 } /* attribute */ } /* energy_preference */ +namespace commissioner_control { +namespace attribute { +attribute_t *create_supported_device_categories(cluster_t *cluster, uint32_t value) +{ + return esp_matter::attribute::create(cluster, CommissionerControl::Attributes::SupportedDeviceCategories::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_bitmap32(value)); +} + +} /* attribute */ +} /* commissioner_control */ + +namespace ecosystem_information { +namespace attribute { +attribute_t *create_device_directory(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, EcosystemInformation::Attributes::DeviceDirectory::Id, ATTRIBUTE_FLAG_NONVOLATILE, + esp_matter_array(value, length, count)); +} + +attribute_t *create_location_directory(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, EcosystemInformation::Attributes::LocationDirectory::Id, ATTRIBUTE_FLAG_NONVOLATILE, + esp_matter_array(value, length, count)); +} + +} /* attribute */ +} /* ecosystem_information */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index a58bd45cf..c2fe84ec8 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -1181,5 +1181,18 @@ attribute_t *create_current_low_power_mode_sensitivity(cluster_t *cluster, uint8 } /* attribute */ } /* energy_preference */ +namespace commissioner_control { +namespace attribute { +attribute_t *create_supported_device_categories(cluster_t *cluster, uint32_t value); +} /* attribute */ +} /* commissioner_control */ + +namespace ecosystem_information { +namespace attribute { +attribute_t *create_device_directory(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +attribute_t *create_location_directory(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +} /* attribute */ +} /* ecosystem_information */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index c9aa7e768..8e203884c 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -3694,6 +3694,72 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ } } /* energy_preference */ +namespace commissioner_control { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features) +{ + cluster_t *cluster = cluster::create(endpoint, CommissionerControl::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_FLAG_SERVER) { + if (config -> delegate != nullptr) { + static const auto delegate_init_cb = CommissionerControlDelegateInitCB; + set_delegate_and_init_callback(cluster, delegate_init_cb, config->delegate); + } + static const auto plugin_server_init_cb = CALL_ONCE(MatterCommissionerControlPluginServerInitCallback); + set_plugin_server_init_callback(cluster, plugin_server_init_cb); + add_function_list(cluster, function_list, function_flags); + + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + + /** Attributes not managed internally **/ + global::attribute::create_cluster_revision(cluster, cluster_revision); + attribute::create_supported_device_categories(cluster, config->supported_device_categories); + } + + if (flags & CLUSTER_FLAG_CLIENT) { + create_default_binding_cluster(endpoint); + } + + event::create_commissioning_request_result(cluster); + return cluster; +} +} /* commissioner_control */ + +namespace ecosystem_information { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features) +{ + cluster_t *cluster = cluster::create(endpoint, EcosystemInformation::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_FLAG_SERVER) { + static const auto plugin_server_init_cb = CALL_ONCE(MatterEcosystemInformationPluginServerInitCallback); + set_plugin_server_init_callback(cluster, plugin_server_init_cb); + add_function_list(cluster, function_list, function_flags); + + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + attribute::create_device_directory(cluster, nullptr, 0, 0); + attribute::create_location_directory(cluster, nullptr, 0, 0); + + /** Attributes not managed internally **/ + global::attribute::create_cluster_revision(cluster, cluster_revision); + } + + return cluster; +} +} /* ecosystem_information */ + // namespace binary_input_basic { // // ToDo // } /* binary_input_basic */ diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 918ebdc7d..37b8ab53a 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -941,5 +941,20 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); } /* energy_preference */ +namespace commissioner_control { +typedef struct config { + uint32_t supported_device_categories; + void *delegate; + config() : supported_device_categories(0), delegate(nullptr) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* commissioner_control */ + +namespace ecosystem_information { +using config_t = common::config_t; +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* ecosystem_information */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index 02cfa2087..d45ea6e56 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -3285,6 +3285,38 @@ command_t *create_cancel_boost(cluster_t *cluster) } /* command */ } /* water_heater_management */ +namespace commissioner_control { +namespace command { +constexpr const command_entry_t accepted_command_list[] = { + {CommissionerControl::Commands::RequestCommissioningApproval::Id, COMMAND_FLAG_ACCEPTED, NULL}, + {CommissionerControl::Commands::CommissionNode::Id, COMMAND_FLAG_ACCEPTED, NULL}, +}; + +constexpr const command_entry_t generated_command_list[] = { + {CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id, COMMAND_FLAG_GENERATED, NULL}, +}; + +command_t *create_request_commissioning_approval(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, CommissionerControl::Commands::RequestCommissioningApproval::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_commission_node(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, CommissionerControl::Commands::CommissionNode::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_reverse_open_commissioning_window(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* commissioner_control */ + } /* cluster */ } /* esp_matter */ @@ -3332,6 +3364,7 @@ constexpr const cluster_command_t cluster_command_table[] = { {WiFiNetworkManagement::Id, GET_COMMAND_COUNT_LIST(cluster::wifi_network_management)}, {ThreadNetworkDirectory::Id, GET_COMMAND_COUNT_LIST(cluster::thread_network_directory)}, {WaterHeaterManagement::Id, GET_COMMAND_COUNT_LIST(cluster::water_heater_management)}, + {CommissionerControl::Id, GET_COMMAND_COUNT_LIST(cluster::commissioner_control)}, }; #if defined(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) && defined(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL) diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 4740cc052..31d519097 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -473,5 +473,13 @@ command_t *create_cancel_boost(cluster_t *cluster); } /* command */ } /* water_heater_management */ +namespace commissioner_control { +namespace command { +command_t *create_request_commissioning_approval(cluster_t *cluster); +command_t *create_commission_node(cluster_t *cluster); +command_t *create_reverse_open_commissioning_window(cluster_t *cluster); +} /* command */ +} /* commissioner_control */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_delegate_callbacks.cpp b/components/esp_matter/esp_matter_delegate_callbacks.cpp index 5613ced17..60a5ab84f 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.cpp +++ b/components/esp_matter/esp_matter_delegate_callbacks.cpp @@ -40,6 +40,7 @@ #include #include #include +#include using namespace chip::app::Clusters; namespace esp_matter { @@ -410,6 +411,16 @@ void EnergyPreferenceDelegateInitCB(void *delegate, uint16_t endpoint_id) EnergyPreference::SetDelegate(energy_preference_delegate); } +void CommissionerControlDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + if(delegate == nullptr) + { + return; + } + CommissionerControl::Delegate *commissioner_control_delegate = static_cast(delegate); + CommissionerControl::CommissionerControlServer::Instance().Init(*commissioner_control_delegate); +} + } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_delegate_callbacks.h b/components/esp_matter/esp_matter_delegate_callbacks.h index 5ec83761b..fd26d56ef 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.h +++ b/components/esp_matter/esp_matter_delegate_callbacks.h @@ -50,6 +50,7 @@ void ThreadBorderRouterManagementDelegateInitCB(void *delegate, uint16_t endpoin void ServiceAreaDelegateInitCB(void *delegate, uint16_t endpoint_id); void WaterHeaterManagementDelegateInitCB(void *delegate, uint16_t endpoint_id); void EnergyPreferenceDelegateInitCB(void *delegate, uint16_t endpoint_id); +void CommissionerControlDelegateInitCB(void *delegate, uint16_t endpoint_id); } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_event.cpp b/components/esp_matter/esp_matter_event.cpp index 6797ee4d1..5c233ddc4 100644 --- a/components/esp_matter/esp_matter_event.cpp +++ b/components/esp_matter/esp_matter_event.cpp @@ -759,5 +759,15 @@ event_t *create_boost_ended(cluster_t *cluster) } // namespace event } // namespace water_heater_management +namespace commissioner_control { +namespace event { +event_t *create_commissioning_request_result(cluster_t *cluster) +{ + return esp_matter::event::create(cluster, CommissionerControl::Events::CommissioningRequestResult::Id); +} + +} // namespace event +} // namespace commissioner_control + } // namespace cluster } // namespace esp_matter diff --git a/components/esp_matter/esp_matter_event.h b/components/esp_matter/esp_matter_event.h index 46a5d83dd..90f9e66fe 100644 --- a/components/esp_matter/esp_matter_event.h +++ b/components/esp_matter/esp_matter_event.h @@ -230,5 +230,11 @@ event_t *create_boost_ended(cluster_t *cluster); } // namespace event } // namespace water_heater_management +namespace commissioner_control { +namespace event { +event_t *create_commissioning_request_result(cluster_t *cluster); +} // namespace event +} // namespace commissioner_control + } // namespace cluster } // namespace esp_matter diff --git a/components/esp_matter/private/esp_matter_cluster_revisions.h b/components/esp_matter/private/esp_matter_cluster_revisions.h index b4e3646f3..e347135f0 100644 --- a/components/esp_matter/private/esp_matter_cluster_revisions.h +++ b/components/esp_matter/private/esp_matter_cluster_revisions.h @@ -395,6 +395,14 @@ namespace energy_preference { constexpr uint16_t cluster_revision = 1; } // namespace energy_preference +namespace commissioner_control { +constexpr uint16_t cluster_revision = 1; +} // namespace commissioner_control + +namespace ecosystem_information { +constexpr uint16_t cluster_revision = 1; +} // namespace ecosystem_information + } // namespace cluster } // namespace esp_matter diff --git a/docs/en/app_guide.rst b/docs/en/app_guide.rst index d3e540444..d479f262f 100644 --- a/docs/en/app_guide.rst +++ b/docs/en/app_guide.rst @@ -47,6 +47,7 @@ List of clusters with delegate: - Mode Select Cluster. - Water Heater Management Cluster. - Energy Preference Cluster. + - Commissioner Control Cluster. 9.1.1 Mode Base Cluster ----------------------- @@ -227,7 +228,7 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. `Water Heater Management`_, `Water Heater Management Delegate`_ -9.1.21 Energy Preference Cluster +9.1.22 Energy Preference Cluster -------------------------------- .. csv-table:: @@ -235,6 +236,14 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. `Energy Preference`_, `Energy Preference Delegate`_ +9.1.23 Commissioner Control Cluster +----------------------------------- + +.. csv-table:: + :header: "Delegate Class", "Reference Implementation" + + `Commissioner Control`_, `Commissioner Control Delegate`_ + .. note:: Make sure that after implementing delegate class, you set the delegate class pointer at the time of creating cluster. @@ -293,3 +302,5 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. .. _`Water Heater Management Delegate`: https://github.com/espressif/connectedhomeip/blob/ea679d2dc674f576f4d391d1d71af1489010e580/examples/energy-management-app/energy-management-common/water-heater/include/WhmDelegate.h .. _`Energy Preference`: https://github.com/espressif/connectedhomeip/blob/ea679d2dc674f576f4d391d1d71af1489010e580/src/app/clusters/energy-preference-server/energy-preference-server.h .. _`Energy Preference Delegate`: https://github.com/espressif/connectedhomeip/blob/ea679d2dc674f576f4d391d1d71af1489010e580/examples/all-clusters-app/all-clusters-common/src/energy-preference-delegate.cpp +.. _`Commissioner Control`: https://github.com/espressif/connectedhomeip/blob/ea679d2dc674f576f4d391d1d71af1489010e580/src/app/clusters/commissioner-control-server/commissioner-control-server.h +.. _`Commissioner Control Delegate`: https://github.com/espressif/connectedhomeip/blob/ea679d2dc674f576f4d391d1d71af1489010e580/examples/fabric-bridge-app/linux/include/CommissionerControl.h