From e39a21e7707b47837060fec2ab8f12fd1477755f Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Mon, 29 Jan 2024 18:17:11 +0800 Subject: [PATCH] Add client-only controller and commissioner --- components/esp_matter/esp_matter_client.cpp | 13 +- components/esp_matter/esp_matter_core.cpp | 4 + .../esp_matter_controller/CMakeLists.txt | 25 +- components/esp_matter_controller/Kconfig | 44 +++- .../esp_matter_attestation_trust_store.cpp | 0 .../esp_matter_attestation_trust_store.h | 0 .../esp_matter_controller_cluster_command.cpp | 47 ++-- .../esp_matter_controller_cluster_command.h | 20 +- .../esp_matter_controller_pairing_command.cpp | 50 ++-- .../esp_matter_controller_pairing_command.h | 57 +++- .../esp_matter_controller_read_command.cpp | 40 +-- .../esp_matter_controller_read_command.h | 60 ++++- ...sp_matter_controller_subscribe_command.cpp | 35 ++- .../esp_matter_controller_subscribe_command.h | 70 +++++ .../esp_matter_controller_write_command.cpp | 31 ++- .../esp_matter_controller_write_command.h | 14 + .../matter_controller_cluster.cpp | 2 +- .../matter_controller_device_mgr.cpp | 8 + .../matter_controller_device_mgr.h | 2 + .../core/esp_matter_controller_client.cpp | 236 +++++++++++++++++ .../core/esp_matter_controller_client.h | 125 +++++++++ .../esp_matter_controller_console.cpp | 161 ++++++------ .../esp_matter_controller_console.h | 0 ...p_matter_controller_credentials_issuer.cpp | 62 +++++ ...esp_matter_controller_credentials_issuer.h | 78 ++++++ .../esp_matter_controller_group_settings.cpp | 66 ++++- .../esp_matter_controller_group_settings.h | 61 +++++ .../esp_matter_controller_utils.cpp | 4 +- .../{ => core}/esp_matter_controller_utils.h | 17 +- .../esp_matter_commissioner.cpp | 247 ------------------ .../esp_matter_commissioner.h | 43 --- examples/controller/CMakeLists.txt | 5 - examples/controller/README.md | 11 +- examples/controller/main/app_main.cpp | 26 +- examples/controller/main/esp_ot_config.h | 2 +- .../controller/main/matter_project_config.h | 15 ++ examples/controller/sdkconfig.defaults | 3 + .../controller/sdkconfig.defaults.esp32s3 | 3 + examples/controller/sdkconfig.defaults.otbr | 21 +- 39 files changed, 1154 insertions(+), 554 deletions(-) rename components/esp_matter_controller/{ => attestation_store}/esp_matter_attestation_trust_store.cpp (100%) rename components/esp_matter_controller/{ => attestation_store}/esp_matter_attestation_trust_store.h (100%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_cluster_command.cpp (87%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_cluster_command.h (80%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_pairing_command.cpp (73%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_pairing_command.h (70%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_read_command.cpp (86%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_read_command.h (71%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_subscribe_command.cpp (93%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_subscribe_command.h (70%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_write_command.cpp (84%) rename components/esp_matter_controller/{ => commands}/esp_matter_controller_write_command.h (87%) create mode 100644 components/esp_matter_controller/core/esp_matter_controller_client.cpp create mode 100644 components/esp_matter_controller/core/esp_matter_controller_client.h rename components/esp_matter_controller/{ => core}/esp_matter_controller_console.cpp (80%) rename components/esp_matter_controller/{ => core}/esp_matter_controller_console.h (100%) create mode 100644 components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.cpp create mode 100644 components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.h rename components/esp_matter_controller/{ => core}/esp_matter_controller_group_settings.cpp (75%) rename components/esp_matter_controller/{ => core}/esp_matter_controller_group_settings.h (50%) rename components/esp_matter_controller/{ => core}/esp_matter_controller_utils.cpp (96%) rename components/esp_matter_controller/{ => core}/esp_matter_controller_utils.h (80%) delete mode 100644 components/esp_matter_controller/esp_matter_commissioner.cpp delete mode 100644 components/esp_matter_controller/esp_matter_commissioner.h create mode 100644 examples/controller/main/matter_project_config.h diff --git a/components/esp_matter/esp_matter_client.cpp b/components/esp_matter/esp_matter_client.cpp index f2fe3af5c..c6f1901fa 100644 --- a/components/esp_matter/esp_matter_client.cpp +++ b/components/esp_matter/esp_matter_client.cpp @@ -22,6 +22,7 @@ #if CONFIG_ESP_MATTER_ENABLE_DATA_MODEL #include #include "app/CASESessionManager.h" +#include "app/CommandSender.h" #include "app/InteractionModelEngine.h" #endif // CONFIG_ESP_MATTER_ENABLE_DATA_MODEL @@ -242,7 +243,8 @@ esp_err_t send_command(void *ctx, peer_device_t *remote_device, const CommandPat ESP_LOGE(TAG, "No memory for command sender"); return ESP_ERR_NO_MEM; } - if (command_sender->PrepareCommand(command_path, /* aStartDataStruct */ false) != CHIP_NO_ERROR) { + chip::app::CommandSender::PrepareCommandParameters prepare_command_params; + if (command_sender->PrepareCommand(command_path, prepare_command_params) != CHIP_NO_ERROR) { ESP_LOGE(TAG, "Failed to prepare command"); return ESP_FAIL; } @@ -256,7 +258,8 @@ esp_err_t send_command(void *ctx, peer_device_t *remote_device, const CommandPat ESP_LOGE(TAG, "Failed to convert json string to TLV"); return err; } - if (command_sender->FinishCommand(timed_invoke_timeout_ms) != CHIP_NO_ERROR) { + chip::app::CommandSender::FinishCommandParameters finish_command_params(timed_invoke_timeout_ms); + if (command_sender->FinishCommand(finish_command_params) != CHIP_NO_ERROR) { ESP_LOGE(TAG, "Failed to finish command"); return ESP_FAIL; } @@ -284,7 +287,8 @@ esp_err_t send_group_command(const uint8_t fabric_index, const CommandPathParams ESP_LOGE(TAG, "No memory for command sender"); return ESP_ERR_NO_MEM; } - if (command_sender->PrepareCommand(command_path, /* aStartDataStruct */ false) != CHIP_NO_ERROR) { + chip::app::CommandSender::PrepareCommandParameters prepare_command_params; + if (command_sender->PrepareCommand(command_path, prepare_command_params) != CHIP_NO_ERROR) { ESP_LOGE(TAG, "Failed to prepare command"); return ESP_FAIL; } @@ -298,7 +302,8 @@ esp_err_t send_group_command(const uint8_t fabric_index, const CommandPathParams ESP_LOGE(TAG, "Failed to convert json string to TLV"); return err; } - if (command_sender->FinishCommand(chip::NullOptional) != CHIP_NO_ERROR) { + chip::app::CommandSender::FinishCommandParameters finish_command_params; + if (command_sender->FinishCommand(finish_command_params) != CHIP_NO_ERROR) { ESP_LOGE(TAG, "Failed to finish command"); return ESP_FAIL; } diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index e1e5d2a4b..a2978bf4b 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -1037,6 +1037,7 @@ static esp_err_t chip_init(event_callback_t callback, intptr_t callback_arg) // Wait for the matter stack to be initialized xTaskNotifyWait(0, 0, NULL, portMAX_DELAY); #endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER + return ESP_OK; } @@ -1068,11 +1069,14 @@ esp_err_t start(event_callback_t callback, intptr_t callback_arg) return err; } esp_matter_started = true; +#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER + // If Matter server is not enabled. we will never use minimum unused endpoint id. err = node::read_min_unused_endpoint_id(); // If the min_unused_endpoint_id is not found, we will write the current min_unused_endpoint_id in nvs. if (err == ESP_ERR_NVS_NOT_FOUND) { err = node::store_min_unused_endpoint_id(); } +#endif return err; } diff --git a/components/esp_matter_controller/CMakeLists.txt b/components/esp_matter_controller/CMakeLists.txt index f4cebdd91..c4c0faa56 100644 --- a/components/esp_matter_controller/CMakeLists.txt +++ b/components/esp_matter_controller/CMakeLists.txt @@ -3,18 +3,29 @@ set(include_dirs_list ) set(exclude_srcs_list ) if (CONFIG_ESP_MATTER_CONTROLLER_ENABLE) - list(APPEND src_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/logger/zap-generated") - list(APPEND include_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/logger") + list(APPEND src_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/core" + "${CMAKE_CURRENT_SOURCE_DIR}/commands" + "${CMAKE_CURRENT_SOURCE_DIR}/logger/zap-generated") + list(APPEND include_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/core" + "${CMAKE_CURRENT_SOURCE_DIR}/commands" + "${CMAKE_CURRENT_SOURCE_DIR}/logger") if (CONFIG_ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE) list(APPEND src_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/controller_custom_cluster") list(APPEND include_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/controller_custom_cluster") endif() - if (NOT CONFIG_ESP_MATTER_COMMISSIONER_ENABLE) - list(APPEND exclude_srcs_list "${CMAKE_CURRENT_SOURCE_DIR}/esp_matter_commissioner.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/esp_matter_controller_pairing_command.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/esp_matter_attestation_trust_store.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/esp_matter_controller_group_settings.cpp") + + if (CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) + list(APPEND exclude_srcs_list "${CMAKE_CURRENT_SOURCE_DIR}/core/esp_matter_controller_client.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/core/esp_matter_controller_credentials_issuer.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/core/esp_matter_controller_group_settings.cpp") + endif() + + if (CONFIG_ESP_MATTER_COMMISSIONER_ENABLE) + list(APPEND src_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/attestation_store") + list(APPEND include_dirs_list "${CMAKE_CURRENT_SOURCE_DIR}/attestation_store") + else() + list(APPEND exclude_srcs_list "${CMAKE_CURRENT_SOURCE_DIR}/commands/esp_matter_controller_pairing_command.cpp") endif() endif() diff --git a/components/esp_matter_controller/Kconfig b/components/esp_matter_controller/Kconfig index 6b91f85c6..b7c9a9330 100644 --- a/components/esp_matter_controller/Kconfig +++ b/components/esp_matter_controller/Kconfig @@ -6,20 +6,20 @@ menu "ESP Matter Controller" help Enable the controller. + config ESP_MATTER_CONTROLLER_VENDOR_ID + int "Matter Controller Vendor ID" + depends on ESP_MATTER_CONTROLLER_ENABLE && !ESP_MATTER_ENABLE_MATTER_SERVER + default 4891 + help + Vendor ID for the controller + config ESP_MATTER_COMMISSIONER_ENABLE bool "Enable matter commissioner" - depends on ESP_MATTER_CONTROLLER_ENABLE + depends on ESP_MATTER_CONTROLLER_ENABLE && !ESP_MATTER_ENABLE_MATTER_SERVER default y help Enable the matter commissioner in the ESP Matter controller. - config ESP_MATTER_COMMISSIONER_MAX_ACTIVE_DEVICES - int "Max active device" - depends on ESP_MATTER_COMMISSIONER_ENABLE - default 5 - help - Maximum number of active device the commissioner supports. - config ESP_MATTER_CONTROLLER_JSON_STRING_BUFFER_LEN int "Max JSON string buffer length" depends on ESP_MATTER_CONTROLLER_ENABLE @@ -30,8 +30,8 @@ menu "ESP Matter Controller" config ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE bool "Enable controller custom cluster" - depends on ESP_MATTER_CONTROLLER_ENABLE && !ESP_MATTER_COMMISSIONER_ENABLE - default y + depends on ESP_MATTER_CONTROLLER_ENABLE && ESP_MATTER_ENABLE_MATTER_SERVER + default n help Enable the custom cluster of matter controller in the ESP Matter controller for Rainmaker Fabric suppport. @@ -52,6 +52,30 @@ menu "ESP Matter Controller" help Read the PAA root certificates from the spiffs partition + config CUSTOM_ATTESTATION_TRUST_STORE + bool "Attestation Trust Store - Custom" + help + Use the custom Attestation Trust Store + + endchoice + + choice ESP_MATTER_COMMISSIONER_OPERATIONAL_CREDS_ISSUER + prompt "Operational Credentials Issuer" + depends on !ESP_MATTER_ENABLE_MATTER_SERVER + default TEST_OPERATIONAL_CREDS_ISSUER + help + This option determines how the commissioner generates the NOC chains for the end-devices and itself. + + config TEST_OPERATIONAL_CREDS_ISSUER + bool "Operational Credentials Issuer - Test" + help + Use the ExampleOperationalCredentialsIssuer from Matter controller Code + + config CUSTOM_OPERATIONAL_CREDS_ISSUER + bool "Operational Credentials Issuer - Custom" + help + Use the custom OperationalCredentialsIssuer + endchoice endmenu diff --git a/components/esp_matter_controller/esp_matter_attestation_trust_store.cpp b/components/esp_matter_controller/attestation_store/esp_matter_attestation_trust_store.cpp similarity index 100% rename from components/esp_matter_controller/esp_matter_attestation_trust_store.cpp rename to components/esp_matter_controller/attestation_store/esp_matter_attestation_trust_store.cpp diff --git a/components/esp_matter_controller/esp_matter_attestation_trust_store.h b/components/esp_matter_controller/attestation_store/esp_matter_attestation_trust_store.h similarity index 100% rename from components/esp_matter_controller/esp_matter_attestation_trust_store.h rename to components/esp_matter_controller/attestation_store/esp_matter_attestation_trust_store.h diff --git a/components/esp_matter_controller/esp_matter_controller_cluster_command.cpp b/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.cpp similarity index 87% rename from components/esp_matter_controller/esp_matter_controller_cluster_command.cpp rename to components/esp_matter_controller/commands/esp_matter_controller_cluster_command.cpp index 200adf157..7e1936e05 100644 --- a/components/esp_matter_controller/esp_matter_controller_cluster_command.cpp +++ b/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.cpp @@ -14,17 +14,14 @@ #include #include -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE -#include -#else -#include -#endif #include +#include #include #include #include #include +#include #include #include #include @@ -101,7 +98,8 @@ void decode_response(const ConcreteCommandPath &command_path, TLVReader *reader) } else if (command_path.mCommandId == ScenesManagement::Commands::StoreSceneResponse::Id) { decode_command_response(command_path, reader); } else if (command_path.mCommandId == ScenesManagement::Commands::GetSceneMembershipResponse::Id) { - decode_command_response(command_path, reader); + decode_command_response(command_path, + reader); } } @@ -209,11 +207,15 @@ esp_err_t cluster_command::dispatch_group_command(void *context) esp_err_t err = ESP_OK; cluster_command *cmd = reinterpret_cast(context); uint16_t group_id = cmd->m_destination_id & 0xFFFF; -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - uint8_t fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); -#else +#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER uint8_t fabric_index = get_fabric_index(); -#endif +#else +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + uint8_t fabric_index = matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + uint8_t fabric_index = matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER chip::app::CommandPathParams command_path = {cmd->m_endpoint_id, group_id, cmd->m_cluster_id, cmd->m_command_id, chip::app::CommandPathFlags::kGroupIdValid}; err = custom::command::send_group_command(fabric_index, command_path, cmd->m_command_data_field); @@ -226,18 +228,27 @@ esp_err_t cluster_command::send_command() if (is_group_command()) { return dispatch_group_command(reinterpret_cast(this)); } -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER + chip::Server &server = chip::Server::GetInstance(); + server.GetCASESessionManager()->FindOrEstablishSession(ScopedNodeId(m_destination_id, get_fabric_index()), + &on_device_connected_cb, &on_device_connection_failure_cb); + return ESP_OK; +#else + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE if (CHIP_NO_ERROR == - commissioner::get_device_commissioner()->GetConnectedDevice(m_destination_id, &on_device_connected_cb, - &on_device_connection_failure_cb)) { + controller_instance.get_commissioner()->GetConnectedDevice(m_destination_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { return ESP_OK; } #else - chip::Server *server = &(chip::Server::GetInstance()); - server->GetCASESessionManager()->FindOrEstablishSession(ScopedNodeId(m_destination_id, get_fabric_index()), - &on_device_connected_cb, &on_device_connection_failure_cb); - return ESP_OK; -#endif + if (CHIP_NO_ERROR == + controller_instance.get_controller()->GetConnectedDevice(m_destination_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { + return ESP_OK; + } +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER chip::Platform::Delete(this); return ESP_FAIL; } diff --git a/components/esp_matter_controller/esp_matter_controller_cluster_command.h b/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.h similarity index 80% rename from components/esp_matter_controller/esp_matter_controller_cluster_command.h rename to components/esp_matter_controller/commands/esp_matter_controller_cluster_command.h index db6bd76a1..ba75f626b 100644 --- a/components/esp_matter_controller/esp_matter_controller_cluster_command.h +++ b/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.h @@ -34,6 +34,7 @@ using esp_matter::cluster::custom::command::custom_command_callback; constexpr char k_empty_command_data_field[] = "{}"; constexpr size_t k_command_data_field_buffer_size = CONFIG_ESP_MATTER_CONTROLLER_JSON_STRING_BUFFER_LEN; +/** Cluster command class to send an invoke interaction command to a server **/ class cluster_command { public: cluster_command(uint64_t destination_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t command_id, @@ -89,8 +90,23 @@ private: custom_command_callback::on_error_callback_t on_error_cb; }; -esp_err_t send_invoke_cluster_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t command_id, - const char *command_data_field); +/** Send cluster invoke command + * + * @note When the destination_id is a Matter GroupId, the endpoint_id parameter will be ignored. + * @note When the command has no data field, command_data_field can be NULL. + * + * @param[in] destination_id NodeId or GroupId + * @param[in] endpoint_id EndpointId + * @param[in] cluster_id ClusterId + * @param[in] command_id CommandId + * @param[in] command_data_field Command data string with JSON format + * (https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html#cluster-commands) + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t send_invoke_cluster_command(uint64_t destination_id, uint16_t endpoint_id, uint32_t cluster_id, + uint32_t command_id, const char *command_data_field); } // namespace controller } // namespace esp_matter diff --git a/components/esp_matter_controller/esp_matter_controller_pairing_command.cpp b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.cpp similarity index 73% rename from components/esp_matter_controller/esp_matter_controller_pairing_command.cpp rename to components/esp_matter_controller/commands/esp_matter_controller_pairing_command.cpp index 454f4ef0d..e4465d161 100644 --- a/components/esp_matter_controller/esp_matter_controller_pairing_command.cpp +++ b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.cpp @@ -12,20 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include +#include #include static const char *TAG = "pairing_command"; -using namespace esp_matter::commissioner; using namespace chip; using namespace chip::Controller; namespace esp_matter { namespace controller { -pairing_command pairing_command::instance; - void pairing_command::OnStatusUpdate(DevicePairingDelegate::Status status) { switch (status) { @@ -60,14 +58,11 @@ void pairing_command::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) { if (err == CHIP_NO_ERROR) { ESP_LOGI(TAG, "Device commissioning completed with success - getting OperationalDeviceProxy"); - esp_matter::commissioner::get_device_commissioner()->GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, - &mOnDeviceConnectionFailureCallback); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, + &mOnDeviceConnectionFailureCallback); } else { ESP_LOGI(TAG, "Device commissioning Failure: Matter%s", ErrorStr(err)); - CommissionerDiscoveryController *cdc = esp_matter::commissioner::get_discovery_controller(); - if (cdc != nullptr) { - cdc->CommissioningFailed(err); - } } } @@ -75,24 +70,11 @@ void pairing_command::OnDeviceConnectedFn(void *context, ExchangeManager &exchan const SessionHandle &sessionHandle) { ESP_LOGI(TAG, "OnDeviceConnectedFn"); - CommissionerDiscoveryController *cdc = esp_matter::commissioner::get_discovery_controller(); - - if (cdc != nullptr) { - uint16_t vendorId = get_auto_commissioner()->GetCommissioningParameters().GetRemoteVendorId().Value(); - uint16_t productId = get_auto_commissioner()->GetCommissioningParameters().GetRemoteProductId().Value(); - ESP_LOGI(TAG, " ----- AutoCommissioner -- Commissionee vendorId=0x%04X productId=0x%04X", vendorId, productId); - - cdc->CommissioningSucceeded(vendorId, productId, get_instance().m_remote_node_id, exchangeMgr, sessionHandle); - } } void pairing_command::OnDeviceConnectionFailureFn(void *context, const ScopedNodeId &peerId, CHIP_ERROR err) { ESP_LOGI(TAG, "OnDeviceConnectionFailureFn - attempt to get OperationalDeviceProxy failed"); - CommissionerDiscoveryController *cdc = esp_matter::commissioner::get_discovery_controller(); - if (cdc != nullptr) { - cdc->CommissioningFailed(err); - } } CommissioningParameters pairing_command::get_commissioning_params() @@ -111,6 +93,7 @@ CommissioningParameters pairing_command::get_commissioning_params() void pairing_command::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData &nodeData) { + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); // Ignore nodes with closed comissioning window VerifyOrReturn(nodeData.commissionData.commissioningMode != 0); const uint16_t port = nodeData.resolutionData.port; @@ -119,7 +102,7 @@ void pairing_command::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData & ESP_LOGI(TAG, "Discovered Device: %s:%u", buf, port); // Stop Mdns discovery. TODO: Check whether it is a right method - get_device_commissioner()->RegisterDeviceDiscoveryDelegate(nullptr); + controller_instance.get_commissioner()->RegisterDeviceDiscoveryDelegate(nullptr); Inet::InterfaceId interfaceId = nodeData.resolutionData.ipAddress[0].IsIPv6LinkLocal() ? nodeData.resolutionData.interfaceId @@ -127,18 +110,19 @@ void pairing_command::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData & PeerAddress peerAddress = PeerAddress::UDP(nodeData.resolutionData.ipAddress[0], port, interfaceId); RendezvousParameters params = RendezvousParameters().SetSetupPINCode(m_setup_pincode).SetPeerAddress(peerAddress); CommissioningParameters commissioning_params = get_commissioning_params(); - get_device_commissioner()->PairDevice(m_remote_node_id, params, commissioning_params); + controller_instance.get_commissioner()->PairDevice(m_remote_node_id, params, commissioning_params); } esp_err_t pairing_on_network(NodeId node_id, uint32_t pincode) { Dnssd::DiscoveryFilter filter(chip::Dnssd::DiscoveryFilterType::kNone); - get_device_commissioner()->RegisterDeviceDiscoveryDelegate(&pairing_command::get_instance()); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->RegisterDeviceDiscoveryDelegate(&pairing_command::get_instance()); pairing_command::get_instance().m_pairing_mode = PAIRING_MODE_ONNETWORK; pairing_command::get_instance().m_setup_pincode = pincode; pairing_command::get_instance().m_remote_node_id = node_id; pairing_command::get_instance().m_pairing_network_type = NETWORK_TYPE_NONE; - if (CHIP_NO_ERROR != get_device_commissioner()->DiscoverCommissionableNodes(filter)) { + if (CHIP_NO_ERROR != controller_instance.get_commissioner()->DiscoverCommissionableNodes(filter)) { ESP_LOGE(TAG, "Failed to discover commissionable nodes"); return ESP_FAIL; } @@ -155,19 +139,21 @@ esp_err_t pairing_ble_wifi(NodeId node_id, uint32_t pincode, uint16_t disc, cons chip::ByteSpan pwdSpan(reinterpret_cast(pwd), strlen(pwd)); CommissioningParameters commissioning_params = CommissioningParameters().SetWiFiCredentials(Controller::WiFiCredentials(nameSpan, pwdSpan)); - get_device_commissioner()->PairDevice(node_id, params, commissioning_params); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->PairDevice(node_id, params, commissioning_params); return ESP_OK; } -esp_err_t pairing_ble_thread(NodeId node_id, uint32_t pincode, uint16_t disc, uint8_t *dataset_tlvs, uint8_t dataset_len) +esp_err_t pairing_ble_thread(NodeId node_id, uint32_t pincode, uint16_t disc, uint8_t *dataset_tlvs, + uint8_t dataset_len) { RendezvousParameters params = RendezvousParameters().SetSetupPINCode(pincode).SetDiscriminator(disc).SetPeerAddress( chip::Transport::PeerAddress::BLE()); chip::ByteSpan dataset_span(dataset_tlvs, dataset_len); - CommissioningParameters commissioning_params = - CommissioningParameters().SetThreadOperationalDataset(dataset_span); - get_device_commissioner()->PairDevice(node_id, params, commissioning_params); + CommissioningParameters commissioning_params = CommissioningParameters().SetThreadOperationalDataset(dataset_span); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->PairDevice(node_id, params, commissioning_params); return ESP_OK; } #endif diff --git a/components/esp_matter_controller/esp_matter_controller_pairing_command.h b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.h similarity index 70% rename from components/esp_matter_controller/esp_matter_controller_pairing_command.h rename to components/esp_matter_controller/commands/esp_matter_controller_pairing_command.h index 248b45825..eaaf9335d 100644 --- a/components/esp_matter_controller/esp_matter_controller_pairing_command.h +++ b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.h @@ -42,15 +42,10 @@ typedef enum pairing_mode { PAIRING_MODE_ONNETWORK, } pairing_mode_t; +/** Pairing command class to finish commissioning with Matter end-devices **/ class pairing_command : public chip::Controller::DevicePairingDelegate, public chip::Controller::DeviceDiscoveryDelegate { public: - pairing_command() - : mOnDeviceConnectedCallback(OnDeviceConnectedFn, this) - , mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) - { - } - /****************** DevicePairingDelegate Interface *****************/ void OnStatusUpdate(DevicePairingDelegate::Status status) override; void OnPairingComplete(CHIP_ERROR error) override; @@ -60,7 +55,11 @@ public: /****************** DeviceDiscoveryDelegate Interface ***************/ void OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData &nodeData) override; - static pairing_command &get_instance() { return instance; } + static pairing_command &get_instance() + { + static pairing_command s_instance; + return s_instance; + } NodeId m_remote_node_id; uint32_t m_setup_pincode; @@ -69,19 +68,57 @@ public: pairing_mode_t m_pairing_mode; private: - static pairing_command instance; + pairing_command() + : mOnDeviceConnectedCallback(OnDeviceConnectedFn, this) + , mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) + { + } + CommissioningParameters get_commissioning_params(); + static void OnDeviceConnectedFn(void *context, ExchangeManager &exchangeMgr, const SessionHandle &sessionHandle); static void OnDeviceConnectionFailureFn(void *context, const ScopedNodeId &peerId, CHIP_ERROR error); - CommissioningParameters get_commissioning_params(); - chip::Callback::Callback mOnDeviceConnectedCallback; chip::Callback::Callback mOnDeviceConnectionFailureCallback; }; +/** + * Pairing a Matter end-device on the same IP network + * + * @param[in] node_id NodeId assigned to the Matter end-device. + * @param[in] pincode Setup PIN code of the Matter end-device. + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t pairing_on_network(NodeId node_id, uint32_t pincode); #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER +/** + * Pairing a Matter over Wi-Fi end-device with BLE + * + * @param[in] node_id NodeId assigned to the Matter end-device. + * @param[in] pincode Setup PIN code of the Matter end-device. + * @param[in] disc Discriminator of the Matter end-device. + * @param[in] ssid SSID of the Wi-Fi AP. + * @param[in] pwd Password of the Wi-Fi AP. + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t pairing_ble_wifi(NodeId node_id, uint32_t pincode, uint16_t disc, const char *ssid, const char *pwd); + +/** + * Pairing a Matter over Thread end-device with BLE + * + * @param[in] node_id NodeId assigned to the Matter end-device. + * @param[in] pincode Setup PIN code of the Matter end-device. + * @param[in] disc Discriminator of the Matter end-device. + * @param[in] dataset_tlvs Dataset TLV string of the Thread network. + * @param[in] dataset_len Length of the dataset TLV string. + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t pairing_ble_thread(NodeId node_id, uint32_t pincode, uint16_t disc, uint8_t *dataset_tlvs, uint8_t dataset_len); #endif diff --git a/components/esp_matter_controller/esp_matter_controller_read_command.cpp b/components/esp_matter_controller/commands/esp_matter_controller_read_command.cpp similarity index 86% rename from components/esp_matter_controller/esp_matter_controller_read_command.cpp rename to components/esp_matter_controller/commands/esp_matter_controller_read_command.cpp index 72af00157..d6be69513 100644 --- a/components/esp_matter_controller/esp_matter_controller_read_command.cpp +++ b/components/esp_matter_controller/commands/esp_matter_controller_read_command.cpp @@ -12,13 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE -#include -#else -#include -#endif +#include #include #include "DataModelLogger.h" @@ -76,18 +73,27 @@ void read_command::on_device_connection_failure_fcn(void *context, const ScopedN esp_err_t read_command::send_command() { -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER + chip::Server &server = chip::Server::GetInstance(); + server.GetCASESessionManager()->FindOrEstablishSession(ScopedNodeId(m_node_id, get_fabric_index()), + &on_device_connected_cb, &on_device_connection_failure_cb); + return ESP_OK; +#else + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE if (CHIP_NO_ERROR == - commissioner::get_device_commissioner()->GetConnectedDevice(m_node_id, &on_device_connected_cb, - &on_device_connection_failure_cb)) { + controller_instance.get_commissioner()->GetConnectedDevice(m_node_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { return ESP_OK; } #else - chip::Server *server = &(chip::Server::GetInstance()); - server->GetCASESessionManager()->FindOrEstablishSession(ScopedNodeId(m_node_id, get_fabric_index()), - &on_device_connected_cb, &on_device_connection_failure_cb); - return ESP_OK; -#endif + if (CHIP_NO_ERROR == + controller_instance.get_controller()->GetConnectedDevice(m_node_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { + return ESP_OK; + } +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER chip::Platform::Delete(this); return ESP_FAIL; @@ -188,8 +194,8 @@ esp_err_t send_read_attr_command(uint64_t node_id, ScopedMemoryBufferWithSize(node_id, std::move(attr_paths), std::move(event_paths), nullptr, nullptr, nullptr); + read_command *cmd = chip::Platform::New(node_id, std::move(attr_paths), std::move(event_paths), + nullptr, nullptr, nullptr); if (!cmd) { ESP_LOGE(TAG, "Failed to alloc memory for read_command"); return ESP_ERR_NO_MEM; @@ -219,8 +225,8 @@ esp_err_t send_read_event_command(uint64_t node_id, ScopedMemoryBufferWithSize(node_id, std::move(attr_paths), std::move(event_paths), nullptr, nullptr, nullptr); + read_command *cmd = chip::Platform::New(node_id, std::move(attr_paths), std::move(event_paths), + nullptr, nullptr, nullptr); if (!cmd) { ESP_LOGE(TAG, "Failed to alloc memory for read_command"); return ESP_ERR_NO_MEM; diff --git a/components/esp_matter_controller/esp_matter_controller_read_command.h b/components/esp_matter_controller/commands/esp_matter_controller_read_command.h similarity index 71% rename from components/esp_matter_controller/esp_matter_controller_read_command.h rename to components/esp_matter_controller/commands/esp_matter_controller_read_command.h index a9bc034ab..0d6f8174d 100644 --- a/components/esp_matter_controller/esp_matter_controller_read_command.h +++ b/components/esp_matter_controller/commands/esp_matter_controller_read_command.h @@ -38,8 +38,10 @@ typedef enum { READ_EVENT, } read_command_type_t; +/** Read command class to send a read interaction command to a server **/ class read_command : public ReadClient::Callback { public: + /** Constructor for command with multiple paths**/ read_command(uint64_t node_id, ScopedMemoryBufferWithSize &&attr_paths, ScopedMemoryBufferWithSize &&event_paths, attribute_report_cb_t attribute_cb, read_done_cb_t read_cb_done, event_report_cb_t event_cb) @@ -54,7 +56,10 @@ public: , event_data_cb(event_cb) { } - + /** Constructor for command with single path. + * @note 0xFFFF could be used as wildcard EndpointId + * @note 0xFFFFFFFF could be used as wildcard ClusterId/AttributeId/EventId + */ read_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_or_event_id, read_command_type_t command_type, attribute_report_cb_t attribute_cb, read_done_cb_t read_cb_done, event_report_cb_t event_cb) @@ -113,19 +118,70 @@ private: attribute_report_cb_t attribute_data_cb; read_done_cb_t read_done_cb; event_report_cb_t event_data_cb; - }; +/** Send read command with multiple attribute paths + * + * @note The three arrays should has the same size and the order of the three arrays should be the same as + * the attribute paths. + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_ids EndpointId array of the multiple attribute paths + * @param[in] cluster_ids ClusterId array of the multiple attribute paths + * @param[in] attribute_ids AttributeId array of the multiple attribute paths + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_read_attr_command(uint64_t node_id, ScopedMemoryBufferWithSize &endpoint_ids, ScopedMemoryBufferWithSize &cluster_ids, ScopedMemoryBufferWithSize &attribute_ids); +/** Send read command with multiple event paths + * + * @note The three arrays should has the same size and the order of the three arrays should be the same as + * the event paths. + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_ids EndpointId array of the multiple event paths + * @param[in] cluster_ids ClusterId array of the multiple event paths + * @param[in] event_ids EventId array of the multiple event paths + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_read_event_command(uint64_t node_id, ScopedMemoryBufferWithSize &endpoint_ids, ScopedMemoryBufferWithSize &cluster_ids, ScopedMemoryBufferWithSize &event_ids); +/** Send read command with single attribute path + * + * @note 0xFFFF could be used as wildcard EndpointId + * @note 0xFFFFFFFF could be used as wildcard ClusterId/AttributeId/EventId + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_id EndpointId + * @param[in] cluster_id ClusterId + * @param[in] attribute_id AttributeId + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_read_attr_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id); +/** Send read command with single event path + * + * @note 0xFFFF could be used as wildcard EndpointId + * @note 0xFFFFFFFF could be used as wildcard ClusterId/AttributeId/EventId + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_id EndpointId + * @param[in] cluster_id ClusterId + * @param[in] event_id EventId + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_read_event_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t event_id); } // namespace controller diff --git a/components/esp_matter_controller/esp_matter_controller_subscribe_command.cpp b/components/esp_matter_controller/commands/esp_matter_controller_subscribe_command.cpp similarity index 93% rename from components/esp_matter_controller/esp_matter_controller_subscribe_command.cpp rename to components/esp_matter_controller/commands/esp_matter_controller_subscribe_command.cpp index 6bb1b2b26..63eb9cd63 100644 --- a/components/esp_matter_controller/esp_matter_controller_subscribe_command.cpp +++ b/components/esp_matter_controller/commands/esp_matter_controller_subscribe_command.cpp @@ -12,13 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE -#include -#else -#include -#endif +#include #include #include "DataModelLogger.h" @@ -92,18 +89,27 @@ void subscribe_command::on_device_connection_failure_fcn(void *context, const Sc esp_err_t subscribe_command::send_command() { -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - if (CHIP_NO_ERROR == - commissioner::get_device_commissioner()->GetConnectedDevice(m_node_id, &on_device_connected_cb, - &on_device_connection_failure_cb)) { - return ESP_OK; - } -#else +#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER chip::Server *server = &(chip::Server::GetInstance()); server->GetCASESessionManager()->FindOrEstablishSession(ScopedNodeId(m_node_id, get_fabric_index()), &on_device_connected_cb, &on_device_connection_failure_cb); return ESP_OK; -#endif +#else + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + if (CHIP_NO_ERROR == + controller_instance.get_commissioner()->GetConnectedDevice(m_node_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { + return ESP_OK; + } +#else + if (CHIP_NO_ERROR == + controller_instance.get_controller()->GetConnectedDevice(m_node_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { + return ESP_OK; + } +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER chip::Platform::Delete(this); return ESP_FAIL; } @@ -304,7 +310,8 @@ esp_err_t send_shutdown_subscription(uint64_t node_id, uint32_t subscription_id) if (CHIP_NO_ERROR != InteractionModelEngine::GetInstance()->ShutdownSubscription( #if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - ScopedNodeId(node_id, commissioner::get_device_commissioner()->GetFabricIndex()), subscription_id)) { + ScopedNodeId(node_id, matter_controller_client::get_instance().get_commissioner()->GetFabricIndex()), + subscription_id)) { #else ScopedNodeId(node_id, /* fabric index */ 1), subscription_id)) { #endif diff --git a/components/esp_matter_controller/esp_matter_controller_subscribe_command.h b/components/esp_matter_controller/commands/esp_matter_controller_subscribe_command.h similarity index 70% rename from components/esp_matter_controller/esp_matter_controller_subscribe_command.h rename to components/esp_matter_controller/commands/esp_matter_controller_subscribe_command.h index 7b2df2ae9..d23c88fce 100644 --- a/components/esp_matter_controller/esp_matter_controller_subscribe_command.h +++ b/components/esp_matter_controller/commands/esp_matter_controller_subscribe_command.h @@ -38,8 +38,10 @@ typedef enum { SUBSCRIBE_EVENT, } subscribe_command_type_t; +/** Subscribe command class to send a subscribe interaction command to a server **/ class subscribe_command : public ReadClient::Callback { public: + /** Constructor for command with multiple paths**/ subscribe_command(uint64_t node_id, ScopedMemoryBufferWithSize &&attr_paths, ScopedMemoryBufferWithSize &&event_paths, uint16_t min_interval, uint16_t max_interval, bool auto_resubscribe = true, attribute_report_cb_t attribute_cb = nullptr, @@ -61,6 +63,10 @@ public: { } + /** Constructor for command with single path. + * @note 0xFFFF could be used as wildcard EndpointId + * @note 0xFFFFFFFF could be used as wildcard ClusterId/AttributeId/EventId + */ subscribe_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_or_event_id, subscribe_command_type_t command_type, uint16_t min_interval, uint16_t max_interval, bool auto_resubscribe = true, attribute_report_cb_t attribute_cb = nullptr, @@ -135,20 +141,84 @@ private: subscribe_failure_cb_t subscribe_failure_cb; }; +/** Send subscribe command with multiple attribute paths + * + * @note The three arrays should has the same size and the order of the three arrays should be the same as + * the attribute paths. + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_ids EndpointId array of the multiple attribute paths + * @param[in] cluster_ids ClusterId array of the multiple attribute paths + * @param[in] attribute_ids AttributeId array of the multiple attribute paths + * @param[in] min_interval Minimum interval of the subscription + * @param[in] max_interval Maximum interval of the subscription + * @param[in] auto_resubscribe Auto re-subscribe flag + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_subscribe_attr_command(uint64_t node_id, ScopedMemoryBufferWithSize &endpoint_ids, ScopedMemoryBufferWithSize &cluster_ids, ScopedMemoryBufferWithSize &attribute_ids, uint16_t min_interval, uint16_t max_interval, bool auto_resubscribe = true); +/** Send subscribe command with multiple event paths + * + * @note The three arrays should has the same size and the order of the three arrays should be the same as + * the event paths. + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_ids EndpointId array of the multiple event paths + * @param[in] cluster_ids ClusterId array of the multiple event paths + * @param[in] event_ids EventId array of the multiple event paths + * @param[in] min_interval Minimum interval of the subscription + * @param[in] max_interval Maximum interval of the subscription + * @param[in] auto_resubscribe Auto re-subscribe flag + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_subscribe_event_command(uint64_t node_id, ScopedMemoryBufferWithSize &endpoint_ids, ScopedMemoryBufferWithSize &cluster_ids, ScopedMemoryBufferWithSize &event_ids, uint16_t min_interval, uint16_t max_interval, bool auto_resubscribe = true); +/** Send subscribe command with single attribute path + * + * @note 0xFFFF could be used as wildcard EndpointId + * @note 0xFFFFFFFF could be used as wildcard ClusterId/AttributeId/EventId + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_id EndpointId of the attribute path + * @param[in] cluster_id ClusterId of the attribute path + * @param[in] attribute_id AttributeId of the attribue path + * @param[in] min_interval Minimum interval of the subscription + * @param[in] max_interval Maximum interval of the subscription + * @param[in] auto_resubscribe Auto re-subscribe flag + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_subscribe_attr_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, uint16_t min_interval, uint16_t max_interval, bool auto_resubscribe = true); +/** Send subscribe command with single event path + * + * @note 0xFFFF could be used as wildcard EndpointId + * @note 0xFFFFFFFF could be used as wildcard ClusterId/AttributeId/EventId + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_id EndpointId of the event path + * @param[in] cluster_id ClusterId of the event path + * @param[in] event_id AttributeId of the event path + * @param[in] min_interval Minimum interval of the subscription + * @param[in] max_interval Maximum interval of the subscription + * @param[in] auto_resubscribe Auto re-subscribe flag + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_subscribe_event_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t event_id, uint16_t min_interval, uint16_t max_interval, bool auto_resubscribe = true); diff --git a/components/esp_matter_controller/esp_matter_controller_write_command.cpp b/components/esp_matter_controller/commands/esp_matter_controller_write_command.cpp similarity index 84% rename from components/esp_matter_controller/esp_matter_controller_write_command.cpp rename to components/esp_matter_controller/commands/esp_matter_controller_write_command.cpp index 2ca3796f7..a44a230e6 100644 --- a/components/esp_matter_controller/esp_matter_controller_write_command.cpp +++ b/components/esp_matter_controller/commands/esp_matter_controller_write_command.cpp @@ -13,14 +13,12 @@ // limitations under the License. #include +#include #include #include #include -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE -#include -#else + #include -#endif using namespace chip::app::Clusters; using chip::ByteSpan; @@ -117,18 +115,27 @@ void write_command::on_device_connection_failure_fcn(void *context, const Scoped esp_err_t write_command::send_command() { -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER + chip::Server &server = chip::Server::GetInstance(); + server.GetCASESessionManager()->FindOrEstablishSession(ScopedNodeId(m_node_id, get_fabric_index()), + &on_device_connected_cb, &on_device_connection_failure_cb); + return ESP_OK; +#else + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE if (CHIP_NO_ERROR == - commissioner::get_device_commissioner()->GetConnectedDevice(m_node_id, &on_device_connected_cb, - &on_device_connection_failure_cb)) { + controller_instance.get_commissioner()->GetConnectedDevice(m_node_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { return ESP_OK; } #else - chip::Server *server = &(chip::Server::GetInstance()); - server->GetCASESessionManager()->FindOrEstablishSession(ScopedNodeId(m_node_id, get_fabric_index()), - &on_device_connected_cb, &on_device_connection_failure_cb); - return ESP_OK; -#endif + if (CHIP_NO_ERROR == + controller_instance.get_controller()->GetConnectedDevice(m_node_id, &on_device_connected_cb, + &on_device_connection_failure_cb)) { + return ESP_OK; + } +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER chip::Platform::Delete(this); return ESP_FAIL; } diff --git a/components/esp_matter_controller/esp_matter_controller_write_command.h b/components/esp_matter_controller/commands/esp_matter_controller_write_command.h similarity index 87% rename from components/esp_matter_controller/esp_matter_controller_write_command.h rename to components/esp_matter_controller/commands/esp_matter_controller_write_command.h index cf511e0a5..d54de5d9e 100644 --- a/components/esp_matter_controller/esp_matter_controller_write_command.h +++ b/components/esp_matter_controller/commands/esp_matter_controller_write_command.h @@ -37,8 +37,10 @@ using esp_matter::client::peer_device_t; constexpr char *k_null_attribute_val_str = "null"; constexpr size_t k_attr_val_str_buf_size = CONFIG_ESP_MATTER_CONTROLLER_JSON_STRING_BUFFER_LEN; +/** Write command class to send a write interaction command to a server **/ class write_command : public WriteClient::Callback { public: + /** Constructor for command with an attribute path**/ write_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, const char *attribute_val_str) : m_node_id(node_id) @@ -98,6 +100,18 @@ private: chip::Callback::Callback on_device_connection_failure_cb; }; +/** Send write attribute command + * + * @param[in] node_id Remote NodeId + * @param[in] endpoint_id EndpointId + * @param[in] cluster_id ClusterId + * @param[in] attribute_id AttributeId + * @param[in] attr_val_json_str Attribute value string with JSON format + * (https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html#write-attribute-commands) + * + * @return ESP_OK on success. + * @return error in case of failure. + */ esp_err_t send_write_attr_command(uint64_t node_id, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, const char *attr_val_json_str); diff --git a/components/esp_matter_controller/controller_custom_cluster/matter_controller_cluster.cpp b/components/esp_matter_controller/controller_custom_cluster/matter_controller_cluster.cpp index 36f778cd6..d18333321 100644 --- a/components/esp_matter_controller/controller_custom_cluster/matter_controller_cluster.cpp +++ b/components/esp_matter_controller/controller_custom_cluster/matter_controller_cluster.cpp @@ -416,7 +416,7 @@ static esp_err_t fetch_rainmaker_group_id(uint16_t endpoint_id, ScopedMemoryBuff http_len = esp_http_client_fetch_headers(client); http_status_code = esp_http_client_get_status_code(client); if ((http_len > 0) && (http_status_code == 200)) { - http_len = esp_http_client_read_response(client, http_payload.Get(), http_payload.AllocatedSize() - 1 ); + http_len = esp_http_client_read_response(client, http_payload.Get(), http_payload.AllocatedSize() - 1); http_payload[http_len] = 0; } else { http_len = esp_http_client_read_response(client, http_payload.Get(), http_payload.AllocatedSize() - 1); diff --git a/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.cpp b/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.cpp index d9737219a..5d744bcef 100644 --- a/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.cpp +++ b/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.cpp @@ -89,6 +89,7 @@ void print_device_list(matter_device_t *dev_list) ESP_LOGI(TAG, " {"); ESP_LOGI(TAG, " endpoint_id: %d,", dev->endpoints[i].endpoint_id); ESP_LOGI(TAG, " device_type_id: 0x%lx,", dev->endpoints[i].device_type_id); + ESP_LOGI(TAG, " device_name: %s,", dev->endpoints[i].device_name); ESP_LOGI(TAG, " },"); } ESP_LOGI(TAG, " ]"); @@ -195,6 +196,13 @@ static esp_err_t get_metadata(jparse_ctx_t *jctx, matter_device_t *dev) json_obj_leave_array(jctx); } dev->endpoint_count = 1; + int device_name_len = ESP_MATTER_CONTROLLER_MAX_DEVICE_NAME_LEN; + if (json_obj_get_strlen(jctx, "deviceName", &device_name_len) == 0 && + device_name_len < ESP_MATTER_CONTROLLER_MAX_DEVICE_NAME_LEN) { + json_obj_get_string(jctx, "deviceName", dev->endpoints[0].device_name, + ESP_MATTER_CONTROLLER_MAX_DEVICE_NAME_LEN); + dev->endpoints[0].device_name[device_name_len] = 0; + } } json_obj_get_bool(jctx, "isRainmaker", &(dev->is_rainmaker_device)); json_obj_leave_object(jctx); diff --git a/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.h b/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.h index bd0c08e5e..34846cb75 100644 --- a/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.h +++ b/components/esp_matter_controller/controller_custom_cluster/matter_controller_device_mgr.h @@ -21,10 +21,12 @@ namespace controller { namespace device_mgr { #define ESP_MATTER_DEVICE_MAX_ENDPOINT 8 +#define ESP_MATTER_CONTROLLER_MAX_DEVICE_NAME_LEN 32 typedef struct endpoint_entry { uint16_t endpoint_id; uint32_t device_type_id; + char device_name[ESP_MATTER_CONTROLLER_MAX_DEVICE_NAME_LEN]; } endpoint_entry_t; typedef struct matter_device { diff --git a/components/esp_matter_controller/core/esp_matter_controller_client.cpp b/components/esp_matter_controller/core/esp_matter_controller_client.cpp new file mode 100644 index 000000000..67bdea2e0 --- /dev/null +++ b/components/esp_matter_controller/core/esp_matter_controller_client.cpp @@ -0,0 +1,236 @@ +// Copyright 2024 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 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#include +#endif + +#if CONFIG_ENABLE_ESP32_BLE_CONTROLLER +#include +#include +#endif + +#define TAG "MatterController" + +using chip::Platform::ScopedMemoryBufferWithSize; + +namespace esp_matter { +namespace controller { + +esp_err_t matter_controller_client::init(NodeId node_id, FabricId fabric_id, uint16_t listen_port) +{ + chip::Controller::FactoryInitParams factory_init_params; + ESP_RETURN_ON_FALSE(m_operational_keystore.Init(&m_default_storage) == CHIP_NO_ERROR, ESP_FAIL, TAG, + "Failed to initialize operational keystore"); + ESP_RETURN_ON_FALSE(m_operational_cert_store.Init(&m_default_storage) == CHIP_NO_ERROR, ESP_FAIL, TAG, + "Failed to initialize operational cert store"); + // ESP_RETURN_ON_FALSE(m_icd_client_storage.Init(&m_default_storage, &m_session_key_store) == CHIP_NO_ERROR, + // ESP_FAIL, TAG, "Failed to initialize ICD client store"); + factory_init_params.listenPort = listen_port; + factory_init_params.fabricIndependentStorage = &m_default_storage; + factory_init_params.operationalKeystore = &m_operational_keystore; + factory_init_params.opCertStore = &m_operational_cert_store; + factory_init_params.enableServerInteractions = m_operational_advertising; + factory_init_params.sessionKeystore = &m_session_key_store; + m_controller_node_id = node_id; + m_controller_fabric_id = fabric_id; + + m_group_data_provider.SetStorageDelegate(&m_default_storage); + m_group_data_provider.SetSessionKeystore(factory_init_params.sessionKeystore); + ESP_RETURN_ON_FALSE(m_group_data_provider.Init() == CHIP_NO_ERROR, ESP_FAIL, TAG, + "Failed to initialize group data provider"); + factory_init_params.groupDataProvider = + reinterpret_cast(&m_group_data_provider); + chip::Credentials::SetGroupDataProvider(factory_init_params.groupDataProvider); + ESP_RETURN_ON_FALSE(chip::Controller::DeviceControllerFactory::GetInstance().Init(factory_init_params) == + CHIP_NO_ERROR, + ESP_FAIL, TAG, "Failed to initialize DeviceControllerFactory"); + return ESP_OK; +} + +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +esp_err_t matter_controller_client::setup_commissioner() +{ +#if CONFIG_ENABLE_ESP32_BLE_CONTROLLER + CHIP_ERROR err = chip::DeviceLayer::Internal::BLEMgr().Init(); + // This function will return CHIP_ERROR_INCORRECT_STATE if BLE Manager is already initialized. + ESP_RETURN_ON_FALSE(err == CHIP_NO_ERROR || err == CHIP_ERROR_INCORRECT_STATE, ESP_FAIL, TAG, + "Failed to initialze the BLE manager"); + ESP_RETURN_ON_FALSE(chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(0, true) == CHIP_NO_ERROR, ESP_FAIL, TAG, + "Failed to configure BLEManager"); +#endif + chip::Controller::SetupParams commissioner_params; + const chip::Credentials::AttestationTrustStore *trust_store = chip::Credentials::get_attestation_trust_store(); + chip::Credentials::DeviceAttestationVerifier *dac_verifier = chip::Credentials::GetDefaultDACVerifier(trust_store); + chip::Credentials::SetDeviceAttestationVerifier(dac_verifier); + commissioner_params.deviceAttestationVerifier = dac_verifier; + m_credentials_issuer = get_credentials_issuer(); + ESP_RETURN_ON_FALSE(m_credentials_issuer, ESP_FAIL, TAG, + "Please set the custom credentials_issuer before calling setup_commissioner"); + ESP_RETURN_ON_ERROR(m_credentials_issuer->initialize_credentials_issuer(m_default_storage), TAG, + "Failed to initialize credentials_issuer"); + commissioner_params.operationalCredentialsDelegate = m_credentials_issuer->get_delegate(); + commissioner_params.controllerVendorId = chip::VendorId((uint16_t)CONFIG_ESP_MATTER_CONTROLLER_VENDOR_ID); + + // Commissioner NOC chain + ScopedMemoryBufferWithSize noc; + noc.Calloc(chip::Controller::kMaxCHIPDERCertLength); + ESP_RETURN_ON_FALSE(noc.Get(), ESP_ERR_NO_MEM, TAG, "Failed allocate memory for noc"); + chip::MutableByteSpan noc_span(noc.Get(), chip::Controller::kMaxCHIPDERCertLength); + ScopedMemoryBufferWithSize icac; + icac.Calloc(chip::Controller::kMaxCHIPDERCertLength); + ESP_RETURN_ON_FALSE(icac.Get(), ESP_ERR_NO_MEM, TAG, "Failed allocate memory for icac"); + chip::MutableByteSpan icac_span(icac.Get(), chip::Controller::kMaxCHIPDERCertLength); + ScopedMemoryBufferWithSize rcac; + rcac.Calloc(chip::Controller::kMaxCHIPDERCertLength); + ESP_RETURN_ON_FALSE(rcac.Get(), ESP_ERR_NO_MEM, TAG, "Failed allocate memory for rcac"); + chip::MutableByteSpan rcac_span(rcac.Get(), chip::Controller::kMaxCHIPDERCertLength); + // NOC Keypair + chip::Crypto::P256Keypair ephemeral_key; + ESP_RETURN_ON_FALSE(ephemeral_key.Initialize(chip::Crypto::ECPKeyTarget::ECDSA) == CHIP_NO_ERROR, ESP_FAIL, TAG, + "Failed to initialize ephemeral_key pair"); + ESP_RETURN_ON_ERROR(m_credentials_issuer->generate_controller_noc_chain(m_controller_node_id, + m_controller_fabric_id, ephemeral_key, + rcac_span, icac_span, noc_span), + TAG, "Failed to generate NOC chain"); + commissioner_params.operationalKeypair = &ephemeral_key; + commissioner_params.controllerRCAC = rcac_span; + commissioner_params.controllerICAC = icac_span; + commissioner_params.controllerNOC = noc_span; + commissioner_params.defaultCommissioner = &m_auto_commissioner; + commissioner_params.enableServerInteractions = m_operational_advertising; + auto &factory = chip::Controller::DeviceControllerFactory::GetInstance(); + ESP_RETURN_ON_FALSE(factory.SetupCommissioner(commissioner_params, m_device_commissioner) == CHIP_NO_ERROR, + ESP_FAIL, TAG, "Failed to setup commissioner"); + + // Initialize Group Data, including IPK + chip::FabricIndex fabric_index = m_device_commissioner.GetFabricIndex(); + ESP_RETURN_ON_FALSE(fabric_index != chip::kUndefinedFabricIndex, ESP_FAIL, TAG, "Invalid Fabric Index"); + uint8_t compressed_fabric_id[sizeof(uint64_t)] = {0}; + chip::MutableByteSpan compressed_fabric_id_span(compressed_fabric_id); + ESP_RETURN_ON_FALSE(m_device_commissioner.GetCompressedFabricIdBytes(compressed_fabric_id_span) == CHIP_NO_ERROR, + ESP_FAIL, TAG, "Failed to get compressed_fabric_id"); + chip::Credentials::GroupDataProvider *group_data_provider = + reinterpret_cast(&m_group_data_provider); + ESP_RETURN_ON_FALSE(chip::GroupTesting::InitData(group_data_provider, fabric_index, compressed_fabric_id_span) == + CHIP_NO_ERROR, + ESP_FAIL, TAG, "Failed to initialize group data"); + chip::ByteSpan default_ipk = chip::GroupTesting::DefaultIpkValue::GetDefaultIpk(); + ESP_RETURN_ON_FALSE(chip::Credentials::SetSingleIpkEpochKey(group_data_provider, fabric_index, default_ipk, + compressed_fabric_id_span) == CHIP_NO_ERROR, + ESP_FAIL, TAG, "Failed to set ipk for commissioner fabric"); + // m_icd_client_storage.UpdateFabricList(fabric_index); + m_device_commissioner.RegisterPairingDelegate(&controller::pairing_command::get_instance()); + + return ESP_OK; +} + +#else +esp_err_t matter_controller_client::setup_controller(chip::MutableByteSpan &ipk) +{ + chip::Controller::SetupParams controller_params; + // Controller doesn't need to verify device attestation. Set deviceAttestationVerifier to null. + controller_params.deviceAttestationVerifier = nullptr; + m_credentials_issuer = get_credentials_issuer(); + ESP_RETURN_ON_FALSE(m_credentials_issuer, ESP_FAIL, TAG, + "Please set the custom credentials_issuer before calling setup_controller"); + ESP_RETURN_ON_ERROR(m_credentials_issuer->initialize_credentials_issuer(m_default_storage), TAG, + "Failed to initialize credentials_issuer"); + controller_params.operationalCredentialsDelegate = m_credentials_issuer->get_delegate(); + controller_params.controllerVendorId = chip::VendorId((uint16_t)CONFIG_ESP_MATTER_CONTROLLER_VENDOR_ID); + // Commissioner NOC chain + ScopedMemoryBufferWithSize noc; + noc.Calloc(chip::Controller::kMaxCHIPDERCertLength); + ESP_RETURN_ON_FALSE(noc.Get(), ESP_ERR_NO_MEM, TAG, "Failed allocate memory for noc"); + chip::MutableByteSpan noc_span(noc.Get(), chip::Controller::kMaxCHIPDERCertLength); + ScopedMemoryBufferWithSize icac; + icac.Calloc(chip::Controller::kMaxCHIPDERCertLength); + ESP_RETURN_ON_FALSE(icac.Get(), ESP_ERR_NO_MEM, TAG, "Failed allocate memory for icac"); + chip::MutableByteSpan icac_span(icac.Get(), chip::Controller::kMaxCHIPDERCertLength); + ScopedMemoryBufferWithSize rcac; + rcac.Calloc(chip::Controller::kMaxCHIPDERCertLength); + ESP_RETURN_ON_FALSE(rcac.Get(), ESP_ERR_NO_MEM, TAG, "Failed allocate memory for rcac"); + chip::MutableByteSpan rcac_span(rcac.Get(), chip::Controller::kMaxCHIPDERCertLength); + chip::Crypto::P256Keypair ephemeral_key; + ESP_RETURN_ON_ERROR(m_credentials_issuer->generate_controller_noc_chain(m_controller_node_id, + m_controller_fabric_id, ephemeral_key, + rcac_span, icac_span, noc_span), + TAG, "Failed to generate NOC chain"); + // Check whether the keypair is initialized in generate_controller_noc_chain + bool is_keypair_initialized = false; + { + chip::Crypto::P256ECDSASignature signature; + is_keypair_initialized = ephemeral_key.ECDSA_sign_msg(NULL, 0, signature) != CHIP_ERROR_UNINITIALIZED; + } + // If not initialized, use an empty keypair. + controller_params.operationalKeypair = is_keypair_initialized ? &ephemeral_key : nullptr; + controller_params.controllerRCAC = rcac_span; + controller_params.controllerICAC = icac_span; + controller_params.controllerNOC = noc_span; + controller_params.defaultCommissioner = nullptr; + controller_params.enableServerInteractions = m_operational_advertising; + controller_params.permitMultiControllerFabrics = false; + auto &factory = chip::Controller::DeviceControllerFactory::GetInstance(); + ESP_RETURN_ON_FALSE(factory.SetupController(controller_params, m_device_controller) == CHIP_NO_ERROR, ESP_FAIL, TAG, + "Failed to setup controller"); + + chip::FabricIndex fabric_index = m_device_controller.GetFabricIndex(); + if (fabric_index != chip::kUndefinedFabricIndex && !ipk.empty()) { + // If we have created fabric in SetupController and IPK input is not empty, initialize Group Data with IPK. + // Otherwise we will initialize Group Data with IPK later. + uint8_t compressed_fabric_id[sizeof(uint64_t)] = {0}; + chip::MutableByteSpan compressed_fabric_id_span(compressed_fabric_id); + ESP_RETURN_ON_FALSE(m_device_controller.GetCompressedFabricIdBytes(compressed_fabric_id_span) == CHIP_NO_ERROR, + ESP_FAIL, TAG, "Failed to get compressed_fabric_id"); + chip::Credentials::GroupDataProvider *group_data_provider = + reinterpret_cast(&m_group_data_provider); + chip::Credentials::GroupDataProvider::KeySet keyset; + keyset.keyset_id = chip::Credentials::GroupDataProvider::kIdentityProtectionKeySetId; + keyset.policy = chip::app::Clusters::GroupKeyManagement::GroupKeySecurityPolicyEnum::kTrustFirst; + keyset.num_keys_used = 1; + keyset.epoch_keys[0].start_time = 0; + memcpy(keyset.epoch_keys[0].key, ipk.data(), chip::Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES); + ESP_RETURN_ON_FALSE(group_data_provider->SetKeySet(fabric_index, compressed_fabric_id_span, keyset) == + CHIP_NO_ERROR, + ESP_FAIL, TAG, "Failed to set ipk for commissioner fabric"); + } + + return ESP_OK; +} +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + +} // namespace controller +} // namespace esp_matter diff --git a/components/esp_matter_controller/core/esp_matter_controller_client.h b/components/esp_matter_controller/core/esp_matter_controller_client.h new file mode 100644 index 000000000..c273e4226 --- /dev/null +++ b/components/esp_matter_controller/core/esp_matter_controller_client.h @@ -0,0 +1,125 @@ +// Copyright 2022 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace esp_matter { +namespace controller { + +#ifndef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER +class matter_controller_client { +public: + class controller_storage_delegate : public chip::PersistentStorageDelegate { + CHIP_ERROR SyncGetKeyValue(const char *key, void *buffer, uint16_t &size) override + { + ESP_LOGD("MatterController", "Retrieving value from controller storage."); + size_t bytesRead = 0; + CHIP_ERROR err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(key, buffer, size, &bytesRead); + + if (err == CHIP_NO_ERROR) { + ESP_LOGD("MatterController", "Retrieved value from controller storage."); + } + size = static_cast(bytesRead); + return err; + } + + CHIP_ERROR SyncSetKeyValue(const char *key, const void *value, uint16_t size) override + { + ESP_LOGD("MatterController", "Stored value in controller storage"); + return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(key, value, size); + } + + CHIP_ERROR SyncDeleteKeyValue(const char *key) override + { + ESP_LOGD("MatterController", "Delete value in controller storage"); + return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(key); + } + }; + + using NodeId = ::chip::NodeId; + using FabricId = ::chip::FabricId; + using MatterDeviceCommissioner = ::chip::Controller::DeviceCommissioner; + using MatterDeviceController = ::chip::Controller::DeviceController; + + static constexpr uint16_t k_max_groups_per_fabric = 50; + static constexpr uint16_t k_max_group_keys_per_fabric = 25; + + static matter_controller_client &get_instance() + { + static matter_controller_client s_instance; + return s_instance; + } + + esp_err_t init(NodeId node_id, FabricId fabric_id, uint16_t listen_port); + +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_err_t setup_commissioner(); + MatterDeviceCommissioner *get_commissioner() { return &m_device_commissioner; } +#else + esp_err_t setup_controller(chip::MutableByteSpan &ipk); + MatterDeviceController *get_controller() { return &m_device_controller; } +#endif + +private: + matter_controller_client() {} + + bool m_operational_advertising = true; + controller_storage_delegate m_default_storage; + chip::PersistentStorageOperationalKeystore m_operational_keystore; + chip::Credentials::PersistentStorageOpCertStore m_operational_cert_store; + chip::Crypto::RawKeySessionKeystore m_session_key_store; + chip::Credentials::GroupDataProviderImpl m_group_data_provider{k_max_groups_per_fabric, + k_max_group_keys_per_fabric}; + credentials_issuer *m_credentials_issuer; + NodeId m_controller_node_id; + FabricId m_controller_fabric_id; + // TODO: Enable ICD client from ESP32 platform + // chip::app::DefaultICDClientStorage s_icd_client_storage; + +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + chip::Controller::AutoCommissioner m_auto_commissioner; + MatterDeviceCommissioner m_device_commissioner; +#else + MatterDeviceController m_device_controller; +#endif +}; +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER + +} // namespace controller +} // namespace esp_matter diff --git a/components/esp_matter_controller/esp_matter_controller_console.cpp b/components/esp_matter_controller/core/esp_matter_controller_console.cpp similarity index 80% rename from components/esp_matter_controller/esp_matter_controller_console.cpp rename to components/esp_matter_controller/core/esp_matter_controller_console.cpp index 708c5cdb8..f6cb848df 100644 --- a/components/esp_matter_controller/esp_matter_controller_console.cpp +++ b/components/esp_matter_controller/core/esp_matter_controller_console.cpp @@ -36,8 +36,8 @@ #include using chip::NodeId; -using chip::Platform::ScopedMemoryBufferWithSize; using chip::Inet::IPAddress; +using chip::Platform::ScopedMemoryBufferWithSize; using chip::Transport::PeerAddress; const static char *TAG = "controller_console"; @@ -50,7 +50,7 @@ static size_t get_array_size(const char *str) return 0; } size_t ret = 1; - for (size_t i = 0; i < strlen(str); ++ i) { + for (size_t i = 0; i < strlen(str); ++i) { if (str[i] == ',') { ret++; } @@ -133,7 +133,7 @@ static esp_err_t controller_help_handler(int argc, char **argv) return ESP_OK; } -#if CONFIG_ENABLE_ESP32_BLE_CONTROLLER +#if defined(CONFIG_ENABLE_ESP32_BLE_CONTROLLER) && defined(CONFIG_ESP_MATTER_COMMISSIONER_ENABLE) static int char_to_int(char ch) { if ('A' <= ch && ch <= 'F') { @@ -166,7 +166,7 @@ static bool convert_hex_str_to_bytes(const char *hex_str, uint8_t *bytes, uint8_ } return true; } -#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER +#endif // defined(CONFIG_ENABLE_ESP32_BLE_CONTROLLER) && defined(CONFIG_ESP_MATTER_COMMISSIONER_ENABLE) #if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE static esp_err_t controller_pairing_handler(int argc, char **argv) @@ -225,7 +225,9 @@ static esp_err_t controller_pairing_handler(int argc, char **argv) } return ESP_ERR_INVALID_ARG; } +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#ifndef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER static esp_err_t controller_group_settings_handler(int argc, char **argv) { if (argc >= 1) { @@ -290,7 +292,7 @@ static esp_err_t controller_group_settings_handler(int argc, char **argv) ESP_LOGI(TAG, "Unbind keyset : controller group-settings unbind-keyset "); return ESP_OK; } -#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif static esp_err_t controller_invoke_command_handler(int argc, char **argv) { @@ -416,82 +418,83 @@ static esp_err_t controller_dispatch(int argc, char **argv) esp_err_t controller_register_commands() { // Subcommands for root command: `controller ` - const static command_t controller_sub_commands[] = { - { - .name = "help", - .description = "print this page", - .handler = controller_help_handler, - }, + const static command_t controller_sub_commands[] = + { { + .name = "help", + .description = "print this page", + .handler = controller_help_handler, + }, #if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - { - .name = "pairing", - .description = "Pairing a node.\n" - "\tUsage: controller pairing onnetwork [nodeid] [pincode] OR\n" - "\tcontroller pairing ble-wifi [nodeid] [ssid] [password] [pincode] [discriminator] OR\n" - "\tcontroller pairing ble-thread [nodeid] [dataset] [pincode] [discriminator]", - .handler = controller_pairing_handler, - }, - { - .name = "group-settings", - .description = "Managing the groups and keysets of the controller.\n" - "\tUsage: controller group-settings ", - .handler = controller_group_settings_handler, - }, + { + .name = "pairing", + .description = "Pairing a node.\n" + "\tUsage: controller pairing onnetwork [nodeid] [pincode] OR\n" + "\tcontroller pairing ble-wifi [nodeid] [ssid] [password] [pincode] [discriminator] OR\n" + "\tcontroller pairing ble-thread [nodeid] [dataset] [pincode] [discriminator]", + .handler = controller_pairing_handler, + }, + { + .name = "group-settings", + .description = "Managing the groups and keysets of the controller.\n" + "\tUsage: controller group-settings ", + .handler = controller_group_settings_handler, + }, #endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - { - .name = "invoke-cmd", - .description = - "Send command to the nodes.\n" - "\tUsage: controller invoke-cmd [node-id|group-id] [endpoint-id] [cluster-id] [command-id] [payload]\n" - "\tNotes: group-id should start with prefix '0xFFFFFFFFFFFF', endpoint-id will be ignored if the fist " - "parameter is group-id.\n" - "\tNotes: The payload should be a JSON object that includes all the command data fields defined in the " - "SPEC. You can get the format of the payload from " - "https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html#cluster-commands", - .handler = controller_invoke_command_handler, - }, - { - .name = "read-attr", - .description = "Read attributes of the nodes.\n" - "\tUsage: controller read-attr [node-id] [endpoint-id] [cluster-id] [attr-id]", - .handler = controller_read_attr_handler, - }, - { - .name = "write-attr", - .description = "Write attributes of the nodes.\n" - "\tUsage: controller write-attr [node-id|group-id] [endpoint-id] [cluster-id] [attr-id] " - "[attr-value]\n" - "\tNotes: attr-value should be a JSON object that contains the attribute value JSON item." - "You can get the format of the attr-value from " - "https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html#write-attribute-commands", - .handler = controller_write_attr_handler, - }, - { - .name = "read-event", - .description = "Read events of the nodes.\n" - "\tUsage: controller read-event [node-id] [endpoint-id] [cluster-id] [event-id]", - .handler = controller_read_event_handler, - }, - { - .name = "subs-attr", - .description = "Subscribe attributes of the nodes.\n" - "\tUsage: controller subs-attr [node-id] [endpoint-id] [cluster-id] [attr-id] " - "[min-interval] [max-interval]", - .handler = controller_subscribe_attr_handler, - }, - { - .name = "subs-event", - .description = "Subscribe events of the nodes.\n" - "\tUsage: controller subs-attr [node-id] [endpoint-id] [cluster-id] [event-id] " - "[min-interval] [max-interval]", - .handler = controller_subscribe_event_handler, - }, - { - .name = "shutdown-subs", - .description = "Shutdown subscription.\n" - "\tUsage: controller shutdown-subs [node-id] [subscription-id]", - .handler = controller_shutdown_subscription_handler, - }, + { + .name = "invoke-cmd", + .description = + "Send command to the nodes.\n" + "\tUsage: controller invoke-cmd [node-id|group-id] [endpoint-id] [cluster-id] [command-id] [payload]\n" + "\tNotes: group-id should start with prefix '0xFFFFFFFFFFFF', endpoint-id will be ignored if the fist " + "parameter is group-id.\n" + "\tNotes: The payload should be a JSON object that includes all the command data fields defined in the " + "SPEC. You can get the format of the payload from " + "https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html#cluster-commands", + .handler = controller_invoke_command_handler, + }, + { + .name = "read-attr", + .description = "Read attributes of the nodes.\n" + "\tUsage: controller read-attr [node-id] [endpoint-id] [cluster-id] [attr-id]", + .handler = controller_read_attr_handler, + }, + { + .name = "write-attr", + .description = + "Write attributes of the nodes.\n" + "\tUsage: controller write-attr [node-id|group-id] [endpoint-id] [cluster-id] [attr-id] " + "[attr-value]\n" + "\tNotes: attr-value should be a JSON object that contains the attribute value JSON item." + "You can get the format of the attr-value from " + "https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html#write-attribute-commands", + .handler = controller_write_attr_handler, + }, + { + .name = "read-event", + .description = "Read events of the nodes.\n" + "\tUsage: controller read-event [node-id] [endpoint-id] [cluster-id] [event-id]", + .handler = controller_read_event_handler, + }, + { + .name = "subs-attr", + .description = "Subscribe attributes of the nodes.\n" + "\tUsage: controller subs-attr [node-id] [endpoint-id] [cluster-id] [attr-id] " + "[min-interval] [max-interval]", + .handler = controller_subscribe_attr_handler, + }, + { + .name = "subs-event", + .description = "Subscribe events of the nodes.\n" + "\tUsage: controller subs-attr [node-id] [endpoint-id] [cluster-id] [event-id] " + "[min-interval] [max-interval]", + .handler = controller_subscribe_event_handler, + }, + { + .name = "shutdown-subs", + .description = "Shutdown subscription.\n" + "\tUsage: controller shutdown-subs [node-id] [subscription-id]", + .handler = controller_shutdown_subscription_handler, + }, }; const static command_t controller_command = { diff --git a/components/esp_matter_controller/esp_matter_controller_console.h b/components/esp_matter_controller/core/esp_matter_controller_console.h similarity index 100% rename from components/esp_matter_controller/esp_matter_controller_console.h rename to components/esp_matter_controller/core/esp_matter_controller_console.h diff --git a/components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.cpp b/components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.cpp new file mode 100644 index 000000000..eeb1bcbd5 --- /dev/null +++ b/components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.cpp @@ -0,0 +1,62 @@ +// Copyright 2024 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 +#include +#include + +namespace esp_matter { +namespace controller { + +class example_credentials_issuer : public credentials_issuer { + esp_err_t initialize_credentials_issuer(chip::PersistentStorageDelegate &storage) override + { + return m_operational_creds_issuer.Initialize(storage) == CHIP_NO_ERROR ? ESP_OK : ESP_FAIL; + } + + chip::Controller::OperationalCredentialsDelegate *get_delegate() override { return &m_operational_creds_issuer; } + + esp_err_t generate_controller_noc_chain(chip::NodeId node_id, chip::FabricId fabric_id, + chip::Crypto::P256Keypair &keypair, chip::MutableByteSpan &rcac, + chip::MutableByteSpan &icac, chip::MutableByteSpan &noc) override + { + CHIP_ERROR err = m_operational_creds_issuer.GenerateNOCChainAfterValidation( + node_id, fabric_id, chip::kUndefinedCATs, keypair.Pubkey(), rcac, icac, noc); + return err == CHIP_NO_ERROR ? ESP_OK : ESP_FAIL; + } + +private: + chip::Controller::ExampleOperationalCredentialsIssuer m_operational_creds_issuer; +}; + +static credentials_issuer *s_custom_credentials_issuer = nullptr; + +void set_custom_credentials_issuer(credentials_issuer *issuer) +{ + s_custom_credentials_issuer = issuer; +} + +credentials_issuer *get_credentials_issuer() +{ +#ifdef CONFIG_TEST_OPERATIONAL_CREDS_ISSUER + static example_credentials_issuer s_creds_issuer; + return &s_creds_issuer; +#elif defined(CONFIG_CUSTOM_OPERATIONAL_CREDS_ISSUER) + return s_custom_credentials_issuer; +#endif + return nullptr; +} + +} // namespace controller +} // namespace esp_matter diff --git a/components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.h b/components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.h new file mode 100644 index 000000000..03a7fef95 --- /dev/null +++ b/components/esp_matter_controller/core/esp_matter_controller_credentials_issuer.h @@ -0,0 +1,78 @@ +// Copyright 2024 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace esp_matter { +namespace controller { +class credentials_issuer { +public: + virtual ~credentials_issuer() {} + + /** + * This function is used to initialize the Credentials Issuer, if needed. + * + * @param[in] storage A reference to the storage, where the Credentials Issuer can optionally use to access the + * keypair in storage. + * @return ESP_OK on success + * @return error in case of failure. + */ + virtual esp_err_t initialize_credentials_issuer(chip::PersistentStorageDelegate &storage) = 0; + + /** + * This function is used to get the OperationalCredentialsDelegate which is used to generate NOC chains for End + * Devices + * + * @return OperationalCredentialsDelegate of the Controller/Commissioner + */ + virtual chip::Controller::OperationalCredentialsDelegate *get_delegate() = 0; + + /** + * This function is used to Generate NOC Chain for the Controller/Commissioner. + * + * @param[in] nodeId The desired NodeId for the generated NOC Chain - May be optional/unused in some + * implementations. + * @param[in] fabricId The desired FabricId for the generated NOC Chain - May be optional/unused in some + * implementations. + * @param[in] keypair The desired Keypair for the generated NOC Chain - May be optional/unused in some + * implementations. + * @param[in,out] rcac Buffer to hold the Root Certificate of the generated NOC Chain. + * @param[in,out] icac Buffer to hold the Intermediate Certificate of the generated NOC Chain. + * @param[in,out] noc Buffer to hold the Leaf Certificate of the generated NOC Chain. + * + * @return ESP_OK on success + * @return error in case of failure. + */ + virtual esp_err_t generate_controller_noc_chain(chip::NodeId node_id, chip::FabricId fabric, + chip::Crypto::P256Keypair &keypair, chip::MutableByteSpan &rcac, + chip::MutableByteSpan &icac, chip::MutableByteSpan &noc) = 0; +}; + +void set_custom_credentials_issuer(credentials_issuer *issuer); + +credentials_issuer *get_credentials_issuer(); + +} // namespace controller +} // namespace esp_matter diff --git a/components/esp_matter_controller/esp_matter_controller_group_settings.cpp b/components/esp_matter_controller/core/esp_matter_controller_group_settings.cpp similarity index 75% rename from components/esp_matter_controller/esp_matter_controller_group_settings.cpp rename to components/esp_matter_controller/core/esp_matter_controller_group_settings.cpp index 38750e32a..739583c27 100644 --- a/components/esp_matter_controller/esp_matter_controller_group_settings.cpp +++ b/components/esp_matter_controller/core/esp_matter_controller_group_settings.cpp @@ -13,7 +13,7 @@ // limitations under the License. #include -#include +#include #include #include @@ -49,7 +49,12 @@ esp_err_t show_groups() ESP_LOGI(TAG, " | Available Groups : |"); ESP_LOGI(TAG, " +-------------------------------------------------------------------------------------+"); ESP_LOGI(TAG, " | Group Id | KeySet Id | Group Name |"); - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_matter::controller::matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + esp_matter::controller::matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); auto iter = group_data_provider->IterateGroupInfo(fabric_index); GroupDataProvider::GroupInfo group_info; @@ -74,7 +79,12 @@ esp_err_t add_group(char *group_name, uint16_t group_id) return ESP_ERR_INVALID_ARG; } - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_matter::controller::matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + esp_matter::controller::matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); GroupDataProvider::GroupInfo group_info; @@ -91,7 +101,12 @@ esp_err_t remove_group(uint16_t group_id) return ESP_ERR_INVALID_ARG; } - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_matter::controller::matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + esp_matter::controller::matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); ESP_RETURN_ON_FALSE(CHIP_NO_ERROR == group_data_provider->RemoveGroupInfo(fabric_index, group_id), ESP_FAIL, TAG, "Failed to remove the group info"); @@ -100,7 +115,12 @@ esp_err_t remove_group(uint16_t group_id) esp_err_t show_keysets() { - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_matter::controller::matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + esp_matter::controller::matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); GroupDataProvider::KeySet keyset; @@ -125,7 +145,12 @@ esp_err_t show_keysets() esp_err_t bind_keyset(uint16_t group_id, uint16_t keyset_id) { size_t current_count = 0; - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_matter::controller::matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + esp_matter::controller::matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); auto iter = group_data_provider->IterateGroupKeys(fabric_index); @@ -144,7 +169,12 @@ esp_err_t bind_keyset(uint16_t group_id, uint16_t keyset_id) esp_err_t unbind_keyset(uint16_t group_id, uint16_t keyset_id) { size_t index = 0; - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_matter::controller::matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + esp_matter::controller::matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); auto iter = group_data_provider->IterateGroupKeys(fabric_index); @@ -165,12 +195,23 @@ esp_err_t unbind_keyset(uint16_t group_id, uint16_t keyset_id) esp_err_t add_keyset(uint16_t keyset_id, uint8_t key_policy, uint64_t validity_time, char *epoch_key_oct_str) { - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + controller_instance.get_commissioner()->GetFabricIndex(); +#else + controller_instance.get_controller()->GetFabricIndex(); +#endif + GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); uint8_t compressed_fabric_id[sizeof(uint64_t)]; chip::MutableByteSpan compressed_fabric_id_span(compressed_fabric_id); if (CHIP_NO_ERROR != - commissioner::get_device_commissioner()->GetCompressedFabricIdBytes(compressed_fabric_id_span)) { +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + controller_instance.get_commissioner()->GetCompressedFabricIdBytes(compressed_fabric_id_span)) { +#else + controller_instance.get_controller()->GetCompressedFabricIdBytes(compressed_fabric_id_span)) { +#endif ESP_LOGE(TAG, "Failed to get the compressed fabric_id"); return ESP_FAIL; } @@ -197,7 +238,12 @@ esp_err_t add_keyset(uint16_t keyset_id, uint8_t key_policy, uint64_t validity_t esp_err_t remove_keyset(uint16_t keyset_id) { - FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex(); + FabricIndex fabric_index = +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + esp_matter::controller::matter_controller_client::get_instance().get_commissioner()->GetFabricIndex(); +#else + esp_matter::controller::matter_controller_client::get_instance().get_controller()->GetFabricIndex(); +#endif GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider(); size_t index = 0; diff --git a/components/esp_matter_controller/esp_matter_controller_group_settings.h b/components/esp_matter_controller/core/esp_matter_controller_group_settings.h similarity index 50% rename from components/esp_matter_controller/esp_matter_controller_group_settings.h rename to components/esp_matter_controller/core/esp_matter_controller_group_settings.h index 2e033c22f..fab0e4b2c 100644 --- a/components/esp_matter_controller/esp_matter_controller_group_settings.h +++ b/components/esp_matter_controller/core/esp_matter_controller_group_settings.h @@ -18,21 +18,82 @@ namespace esp_matter { namespace controller { namespace group_settings { +/** Group management functions for the client only controller **/ +/** + * Print groups information + */ esp_err_t show_groups(); +/** + * Add a group + * + * @param[in] group_name Group name + * @param[in] group_id Group ID + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t add_group(char *group_name, uint16_t group_id); +/** + * Leave a group + * + * @param[in] group_id Group ID + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t remove_group(uint16_t group_id); +/** + * Print group keysets + */ esp_err_t show_keysets(); +/** + * Bind a group keyset to a group + * + * @param[in] group_id Group ID + * @param[in] keyset_id Group Keyset ID + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t bind_keyset(uint16_t group_id, uint16_t keyset_id); +/** + * Unbind a group keyset to a group + * + * @param[in] group_id Group ID + * @param[in] keyset_id Group Keyset ID + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t unbind_keyset(uint16_t group_id, uint16_t keyset_id); +/** + * Add a group keyset + * + * @param[in] keyset_id Group Keyset ID + * @param[in] key_policy Key policy + * @param[in] validity_time Validity time for the keyset in second + * @param[in] epoch_key_oct_str Octet string of the Epoch key + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t add_keyset(uint16_t keyset_id, uint8_t key_policy, uint64_t validity_time, char *epoch_key_oct_str); +/** + * Remove a group keyset + * + * @param[in] keyset_id Group Keyset ID + * + * @return ESP_OK on success + * @return error in case of failure + */ esp_err_t remove_keyset(uint16_t keyset_id); } // namespace group_settings diff --git a/components/esp_matter_controller/esp_matter_controller_utils.cpp b/components/esp_matter_controller/core/esp_matter_controller_utils.cpp similarity index 96% rename from components/esp_matter_controller/esp_matter_controller_utils.cpp rename to components/esp_matter_controller/core/esp_matter_controller_utils.cpp index d7f98d5c0..062b3989c 100644 --- a/components/esp_matter_controller/esp_matter_controller_utils.cpp +++ b/components/esp_matter_controller/core/esp_matter_controller_utils.cpp @@ -18,7 +18,7 @@ namespace esp_matter { namespace controller { -#if !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER uint8_t s_controller_fabric_index = chip::kUndefinedFabricIndex; void set_fabric_index(uint8_t fabric_index) @@ -30,7 +30,7 @@ uint8_t get_fabric_index(void) { return s_controller_fabric_index; } -#endif // !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER } // namespace controller } // namespace esp_matter diff --git a/components/esp_matter_controller/esp_matter_controller_utils.h b/components/esp_matter_controller/core/esp_matter_controller_utils.h similarity index 80% rename from components/esp_matter_controller/esp_matter_controller_utils.h rename to components/esp_matter_controller/core/esp_matter_controller_utils.h index 115b9d865..e89881ad9 100644 --- a/components/esp_matter_controller/esp_matter_controller_utils.h +++ b/components/esp_matter_controller/core/esp_matter_controller_utils.h @@ -16,14 +16,14 @@ #include -#include #include +#include #include #include -using chip::Platform::ScopedMemoryBufferWithSize; using chip::app::AttributePathParams; using chip::app::EventPathParams; +using chip::Platform::ScopedMemoryBufferWithSize; namespace esp_matter { namespace controller { @@ -33,15 +33,16 @@ using event_report_cb_t = void (*)(uint64_t remote_node_id, const chip::app::Eve chip::TLV::TLVReader *data); using subscribe_done_cb_t = void (*)(uint64_t remote_node_id, uint32_t subscription_id); using subscribe_failure_cb_t = void (*)(void *subscribe_command); -using read_done_cb_t = void (*)(uint64_t remote_node_id, const ScopedMemoryBufferWithSize &attr_paths, +using read_done_cb_t = void (*)(uint64_t remote_node_id, + const ScopedMemoryBufferWithSize &attr_paths, const ScopedMemoryBufferWithSize &EventPathParams); -#if !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#if CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER /** * @brief Set the fabric index of the controller. - * The controller should be able to send commands to the devices on this fabric. - * - * This should be called after the controller is added to the fabric. + * If Matter server is enabled on the controller, the controller could join multiple fabrics. + * We should choose one on which the controller is able to send commands to other end-devices. + * This should be called after the controller server is added to the fabric. */ void set_fabric_index(uint8_t fabric_index); @@ -50,7 +51,7 @@ void set_fabric_index(uint8_t fabric_index); * */ uint8_t get_fabric_index(); -#endif // !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER } // namespace controller } // namespace esp_matter diff --git a/components/esp_matter_controller/esp_matter_commissioner.cpp b/components/esp_matter_controller/esp_matter_commissioner.cpp deleted file mode 100644 index 2f9c87428..000000000 --- a/components/esp_matter_controller/esp_matter_commissioner.cpp +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2022 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_ENABLE_ESP32_BLE_CONTROLLER -#include -#include -#endif - -using namespace chip; -using namespace chip::Credentials; -using namespace chip::DeviceLayer; -using namespace chip::Inet; -using namespace chip::Transport; -using namespace chip::app::Clusters; -using namespace chip::Controller; -using namespace chip::Messaging; -using namespace esp_matter::controller; - -class ControllerServerStorageDelegate : public PersistentStorageDelegate { - CHIP_ERROR SyncGetKeyValue(const char *key, void *buffer, uint16_t &size) override - { - ChipLogProgress(AppServer, "Retrieving value from controller server storage."); - size_t bytesRead = 0; - CHIP_ERROR err = PersistedStorage::KeyValueStoreMgr().Get(key, buffer, size, &bytesRead); - - if (err == CHIP_NO_ERROR) { - ChipLogProgress(AppServer, "Retrieved value from server storage."); - } - size = static_cast(bytesRead); - return err; - } - - CHIP_ERROR SyncSetKeyValue(const char *key, const void *value, uint16_t size) override - { - ChipLogProgress(AppServer, "Stored value in server storage"); - return PersistedStorage::KeyValueStoreMgr().Put(key, value, size); - } - - CHIP_ERROR SyncDeleteKeyValue(const char *key) override - { - ChipLogProgress(AppServer, "Delete value in server storage"); - return PersistedStorage::KeyValueStoreMgr().Delete(key); - } -}; - -constexpr uint64_t LOCAL_NODE_ID = 112233; - -ControllerServerStorageDelegate controller_server_storage; -ExampleOperationalCredentialsIssuer op_creds_issuer; -NodeId local_node_id = LOCAL_NODE_ID; -Credentials::GroupDataProviderImpl group_data_provider; -AutoCommissioner auto_commissioner; - -class ESPCommissionerCallback : public CommissionerCallback { - void ReadyForCommissioning(uint32_t pincode, uint16_t discriminator, PeerAddress peerAddress) override - { - esp_matter::controller::pairing_on_network(pincode, pairing_command::get_instance().m_remote_node_id); - } -}; - -ESPCommissionerCallback commissioner_callback; -DeviceCommissioner device_commissioner; -CommissionerDiscoveryController commissioner_discovery_controller; -Crypto::RawKeySessionKeystore session_keystore; - -constexpr uint16_t kUdcListenPort = 5560; - -namespace esp_matter { -namespace commissioner { -esp_err_t init(uint16_t commissioner_port) -{ -#if CONFIG_ENABLE_ESP32_BLE_CONTROLLER - CHIP_ERROR err = chip::DeviceLayer::Internal::BLEMgr().Init(); - err = chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(0, true); - - if (err != CHIP_NO_ERROR) { - ChipLogError(DeviceLayer, "BLEManager initialization failed: %s", ErrorStr(err)); - return ESP_FAIL; - } -#endif - - Controller::FactoryInitParams factoryParams; - Controller::SetupParams setupParams; - - // use a different listen port for the commissioner - factoryParams.listenPort = commissioner_port; - factoryParams.fabricIndependentStorage = &controller_server_storage; - factoryParams.fabricTable = &Server::GetInstance().GetFabricTable(); - factoryParams.sessionKeystore = &session_keystore; - - group_data_provider.SetStorageDelegate(&controller_server_storage); - group_data_provider.SetSessionKeystore(factoryParams.sessionKeystore); - if (group_data_provider.Init() != CHIP_NO_ERROR) { - return ESP_FAIL; - } - factoryParams.groupDataProvider = reinterpret_cast(&group_data_provider); - - setupParams.operationalCredentialsDelegate = &op_creds_issuer; - uint16_t vendor_id; - DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(vendor_id); - ChipLogProgress(Support, " ----- Commissioner using vendorId 0x%04X", vendor_id); - setupParams.controllerVendorId = static_cast(vendor_id); - - if (op_creds_issuer.Initialize(controller_server_storage) != CHIP_NO_ERROR) { - return ESP_FAIL; - } - - ChipLogProgress(Support, " ----- UDC listening on port %d", kUdcListenPort); - if (device_commissioner.SetUdcListenPort(kUdcListenPort) != CHIP_NO_ERROR) { - return ESP_FAIL; - } - - const Credentials::AttestationTrustStore *testingRootStore = Credentials::get_attestation_trust_store(); - SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore)); - - Platform::ScopedMemoryBuffer noc; - if (!noc.Alloc(Controller::kMaxCHIPDERCertLength)) { - return ESP_ERR_NO_MEM; - } - MutableByteSpan nocSpan(noc.Get(), Controller::kMaxCHIPDERCertLength); - - Platform::ScopedMemoryBuffer icac; - if (!icac.Alloc(Controller::kMaxCHIPDERCertLength)) { - return ESP_ERR_NO_MEM; - } - MutableByteSpan icacSpan(icac.Get(), Controller::kMaxCHIPDERCertLength); - - Platform::ScopedMemoryBuffer rcac; - if (!rcac.Alloc(Controller::kMaxCHIPDERCertLength)) { - return ESP_ERR_NO_MEM; - } - MutableByteSpan rcacSpan(rcac.Get(), Controller::kMaxCHIPDERCertLength); - - Crypto::P256Keypair ephemeralKey; - if (ephemeralKey.Initialize(Crypto::ECPKeyTarget::ECDSA) != CHIP_NO_ERROR) { - return ESP_FAIL; - } - - if (op_creds_issuer.GenerateNOCChainAfterValidation(local_node_id, /* fabricId = */ 1, chip::kUndefinedCATs, - ephemeralKey.Pubkey(), rcacSpan, icacSpan, - nocSpan) != CHIP_NO_ERROR) { - return ESP_FAIL; - } - setupParams.operationalKeypair = &ephemeralKey; - setupParams.controllerRCAC = rcacSpan; - setupParams.controllerICAC = icacSpan; - setupParams.controllerNOC = nocSpan; - setupParams.defaultCommissioner = &auto_commissioner; - - auto &factory = Controller::DeviceControllerFactory::GetInstance(); - if (factory.Init(factoryParams) != CHIP_NO_ERROR) { - return ESP_FAIL; - } - if (factory.SetupCommissioner(setupParams, *get_device_commissioner()) != CHIP_NO_ERROR) { - return ESP_FAIL; - } - - FabricIndex fabricIndex = device_commissioner.GetFabricIndex(); - if (fabricIndex == kUndefinedFabricIndex) { - return ESP_FAIL; - } - - uint8_t compressedFabricId[sizeof(uint64_t)] = {0}; - MutableByteSpan compressedFabricIdSpan(compressedFabricId); - if (device_commissioner.GetCompressedFabricIdBytes(compressedFabricIdSpan) != CHIP_NO_ERROR) { - return ESP_FAIL; - } - ChipLogProgress(Support, "Setting up group data for Fabric Index %u with Compressed Fabric ID:", - static_cast(fabricIndex)); - ChipLogByteSpan(Support, compressedFabricIdSpan); - - // TODO: Once ExampleOperationalCredentialsIssuer has support, set default IPK on it as well so - // that commissioned devices get the IPK set from real values rather than "test-only" internal hookups. - ByteSpan defaultIpk = chip::GroupTesting::DefaultIpkValue::GetDefaultIpk(); - if (CHIP_NO_ERROR != - chip::Credentials::SetSingleIpkEpochKey(reinterpret_cast(&group_data_provider), - fabricIndex, defaultIpk, compressedFabricIdSpan)) { - return ESP_FAIL; - } - - get_discovery_controller()->SetUserDirectedCommissioningServer( - get_device_commissioner()->GetUserDirectedCommissioningServer()); - get_discovery_controller()->SetCommissionerCallback(&commissioner_callback); - - get_device_commissioner()->RegisterPairingDelegate(&pairing_command::get_instance()); - - ChipLogProgress(Support, "InitCommissioner nodeId=0x" ChipLogFormatX64 " fabricIndex=0x%x", - ChipLogValueX64(get_device_commissioner()->GetNodeId()), static_cast(fabricIndex)); - - return ESP_OK; -} - -void shutdown() -{ - UserDirectedCommissioningServer *udcServer = get_device_commissioner()->GetUserDirectedCommissioningServer(); - if (udcServer != nullptr) { - udcServer->SetUserConfirmationProvider(nullptr); - } - - get_device_commissioner()->Shutdown(); -} - -DeviceCommissioner *get_device_commissioner() -{ - return &device_commissioner; -} - -CommissionerDiscoveryController *get_discovery_controller() -{ - return &commissioner_discovery_controller; -} - -AutoCommissioner *get_auto_commissioner() -{ - return &auto_commissioner; -} - -} // namespace commissioner -} // namespace esp_matter diff --git a/components/esp_matter_controller/esp_matter_commissioner.h b/components/esp_matter_controller/esp_matter_commissioner.h deleted file mode 100644 index 183693cdf..000000000 --- a/components/esp_matter_controller/esp_matter_commissioner.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2022 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 -#include -#include -#include -#include -#include -#include - -#if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE -using chip::NodeId; -using chip::Controller::AutoCommissioner; -using chip::Controller::DeviceCommissioner; -using chip::Controller::DevicePairingDelegate; -using chip::Transport::PeerAddress; - -namespace esp_matter { -namespace commissioner { - -esp_err_t init(uint16_t commissioner_port); -void shutdown(); - -DeviceCommissioner *get_device_commissioner(); -CommissionerDiscoveryController *get_discovery_controller(); -AutoCommissioner *get_auto_commissioner(); -} // namespace commissioner -} // namespace esp_matter -#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE diff --git a/examples/controller/CMakeLists.txt b/examples/controller/CMakeLists.txt index b56089d1d..f0e3ace13 100644 --- a/examples/controller/CMakeLists.txt +++ b/examples/controller/CMakeLists.txt @@ -37,11 +37,6 @@ project(controller) idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H" APPEND) idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND) -if (CONFIG_ESP_MATTER_COMMISSIONER_ENABLE) - idf_build_set_property(CXX_COMPILE_OPTIONS "-DCHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY=1;-DCHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES=${CONFIG_ESP_MATTER_COMMISSIONER_MAX_ACTIVE_DEVICES}" APPEND) - idf_build_set_property(C_COMPILE_OPTIONS "-DCHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY=1;-DCHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES=${CONFIG_ESP_MATTER_COMMISSIONER_MAX_ACTIVE_DEVICES}" APPEND) -endif() - # For RISCV chips, project_include.cmake sets -Wno-format, but does not clear various # flags that depend on -Wformat idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND) diff --git a/examples/controller/README.md b/examples/controller/README.md index 50184c049..a32bcaf8d 100644 --- a/examples/controller/README.md +++ b/examples/controller/README.md @@ -38,10 +38,10 @@ idf.py -p erase-flash flash monitor ### 4.3 Pair and Control -- Pairing the controller with chip-tool +- Connect the controller to Wi-Fi network with the device console ``` -./chip-tool pairing ble-wifi 0x7483 20202021 3840 +matter esp wifi connect {ssid} {password} ``` - Initializing a new Thread network dataset and commit it as the active one @@ -64,17 +64,16 @@ matter esp ot_cli ifconfig up matter esp ot_cli thread start ``` -- Pairing the Thread end-device with chip-tool and write the ACL +- Pairing the Thread end-device ``` -./chip-tool pairing ble-thread 0x7484 hex: 20202021 3840 -./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233, 25731], "targets":null}]' 0x7484 0 +matter esp controller pairing ble-thread 1234 20202021 3840 ``` - Control the Thread end-device on the device console (On/Off cluster Toggle command) ``` -matter esp controller invoke-cmd 0x7484 1 6 2 +matter esp controller invoke-cmd 1234 1 6 2 ``` ## A1 Appendix FAQs diff --git a/examples/controller/main/app_main.cpp b/examples/controller/main/app_main.cpp index eeece08f1..812855e28 100644 --- a/examples/controller/main/app_main.cpp +++ b/examples/controller/main/app_main.cpp @@ -11,15 +11,11 @@ #include #include -#include +#include #include #include #include #include -#if CONFIG_ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE -#include -#include -#endif // CONFIG_ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE #if CONFIG_OPENTHREAD_BORDER_ROUTER #include #include @@ -53,14 +49,8 @@ static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), }; + printf("init thread br\n"); esp_matter::thread_br_init(&config); -#endif -#if !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - // Check whether fabric exists at index 1, if yes, set the controller fabric index to 1. - // If you controller works on other fabrics, please set the fabric index to another value. - if (chip::Server::GetInstance().GetFabricTable().FindFabricWithIndex(1)) { - esp_matter::controller::set_fabric_index(1); - } #endif } break; @@ -86,22 +76,14 @@ extern "C" void app_main() esp_matter::console::thread_br_cli_register_command(); #endif // CONFIG_OPENTHREAD_BORDER_ROUTER && CONFIG_OPENTHREAD_CLI #endif // CONFIG_ENABLE_CHIP_SHELL -#if !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - // If there is no commissioner in the controller, we need a default node so that the controller can be commissioned - // to a specific fabric. - node::config_t node_config; - node_t *node = node::create(&node_config, NULL, NULL); - ABORT_APP_ON_FAILURE(node != nullptr, ESP_LOGE(TAG, "Failed to create Matter node")); - -#endif // !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - /* Matter start */ err = esp_matter::start(app_event_cb); ABORT_APP_ON_FAILURE(err == ESP_OK, ESP_LOGE(TAG, "Failed to start Matter, err:%d", err)); #if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE esp_matter::lock::chip_stack_lock(portMAX_DELAY); - esp_matter::commissioner::init(5580); + esp_matter::controller::matter_controller_client::get_instance().init(112233, 1, 5580); + esp_matter::controller::matter_controller_client::get_instance().setup_commissioner(); esp_matter::lock::chip_stack_unlock(); #endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE } diff --git a/examples/controller/main/esp_ot_config.h b/examples/controller/main/esp_ot_config.h index dbb5f34c4..97b8e4a09 100644 --- a/examples/controller/main/esp_ot_config.h +++ b/examples/controller/main/esp_ot_config.h @@ -28,7 +28,7 @@ { \ .radio_mode = RADIO_MODE_UART_RCP, \ .radio_uart_config = { \ - .port = 1, \ + .port = UART_NUM_1, \ .uart_config = \ { \ .baud_rate = 460800, \ diff --git a/examples/controller/main/matter_project_config.h b/examples/controller/main/matter_project_config.h new file mode 100644 index 000000000..ce0a9f8af --- /dev/null +++ b/examples/controller/main/matter_project_config.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifndef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER + +#ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE +// Enable or disable whether this device advertises as a commissioner. +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY 1 +#endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE + +// Number of devices a controller can be simultaneously connected to +#define CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES 8 + +#endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER diff --git a/examples/controller/sdkconfig.defaults b/examples/controller/sdkconfig.defaults index 70ab7199b..85b1a8fa3 100644 --- a/examples/controller/sdkconfig.defaults +++ b/examples/controller/sdkconfig.defaults @@ -50,3 +50,6 @@ CONFIG_MBEDTLS_HKDF_C=y # Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1) # unique local addresses for fabrics(MAX_FABRIC), a link local address(1) CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 + +# Enable project configurations +CONFIG_CHIP_PROJECT_CONFIG="main/matter_project_config.h" diff --git a/examples/controller/sdkconfig.defaults.esp32s3 b/examples/controller/sdkconfig.defaults.esp32s3 index b504434ec..7f49d0fe2 100644 --- a/examples/controller/sdkconfig.defaults.esp32s3 +++ b/examples/controller/sdkconfig.defaults.esp32s3 @@ -5,3 +5,6 @@ CONFIG_ENABLE_ESP32_BLE_CONTROLLER=y # Disable using ble for commissioning CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n + +# Disable Matter server +CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER=n diff --git a/examples/controller/sdkconfig.defaults.otbr b/examples/controller/sdkconfig.defaults.otbr index 5af29ae0a..5513e8585 100644 --- a/examples/controller/sdkconfig.defaults.otbr +++ b/examples/controller/sdkconfig.defaults.otbr @@ -44,9 +44,10 @@ CONFIG_MDNS_MULTIPLE_INSTANCE=y # Enable chip shell CONFIG_ENABLE_CHIP_SHELL=y CONFIG_ESP_MATTER_CONSOLE_TASK_STACK=4096 +CONFIG_CHIP_SHELL_CMD_LINE_BUF_MAX_LENGTH=512 # Increase Stack size -CONFIG_CHIP_TASK_STACK_SIZE=10240 +CONFIG_CHIP_TASK_STACK_SIZE=15360 CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 # Wi-Fi Settings @@ -54,8 +55,10 @@ CONFIG_ENABLE_WIFI_STATION=y CONFIG_ENABLE_WIFI_AP=n # Enable Controller and disable commissioner +CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER=n +CONFIG_ENABLE_CHIP_CONTROLLER_BUILD=y CONFIG_ESP_MATTER_CONTROLLER_ENABLE=y -CONFIG_ESP_MATTER_COMMISSIONER_ENABLE=n +CONFIG_ESP_MATTER_COMMISSIONER_ENABLE=y CONFIG_ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE=n # Disable chip test build @@ -72,3 +75,17 @@ CONFIG_ENABLE_ROUTE_HOOK=n # Use USB Jtag Console CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y + +# Enable project configurations +CONFIG_CHIP_PROJECT_CONFIG="main/matter_project_config.h" + +# Enable ble controller +CONFIG_ENABLE_ESP32_BLE_CONTROLLER=y + +# SPIRAM +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=512 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=8192 +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y