From 8713f58a51801b58ed81577beb65a50bcffa09bf Mon Sep 17 00:00:00 2001 From: chendejin Date: Mon, 15 Apr 2024 10:57:08 +0800 Subject: [PATCH] Add commissioner discovery and user direct commissioning support --- components/esp_matter_console/CMakeLists.txt | 9 +- .../esp_matter_console/esp_matter_console.h | 9 ++ .../esp_matter_console_udc.cpp | 105 ++++++++++++++++++ .../core/esp_matter_controller_client.cpp | 10 ++ .../core/esp_matter_controller_client.h | 24 ++++ .../core/esp_matter_controller_console.cpp | 58 ++++++++++ 6 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 components/esp_matter_console/esp_matter_console_udc.cpp diff --git a/components/esp_matter_console/CMakeLists.txt b/components/esp_matter_console/CMakeLists.txt index 6b24e6aa5..d33d809ba 100644 --- a/components/esp_matter_console/CMakeLists.txt +++ b/components/esp_matter_console/CMakeLists.txt @@ -1,8 +1,7 @@ -set(srcs_list) +set(src_dirs) if (CONFIG_ENABLE_CHIP_SHELL) - list(APPEND srcs_list esp_matter_console.cpp esp_matter_console_diagnostics.cpp - esp_matter_console_wifi.cpp esp_matter_console_otcli.cpp) + list(APPEND src_dirs ".") endif() -idf_component_register(SRCS ${srcs_list} +idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS . - PRIV_REQUIRES chip mbedtls esp_timer bt openthread) + PRIV_REQUIRES chip mbedtls esp_timer bt openthread) \ No newline at end of file diff --git a/components/esp_matter_console/esp_matter_console.h b/components/esp_matter_console/esp_matter_console.h index b5dc52236..cf9454937 100644 --- a/components/esp_matter_console/esp_matter_console.h +++ b/components/esp_matter_console/esp_matter_console.h @@ -146,5 +146,14 @@ esp_err_t wifi_register_commands(); */ esp_err_t otcli_register_commands(); +/** Add UDC Commands + * + * Adds the default UDC commands. + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t udc_register_commands(); + } // namespace console } // namespace esp_matter diff --git a/components/esp_matter_console/esp_matter_console_udc.cpp b/components/esp_matter_console/esp_matter_console_udc.cpp new file mode 100644 index 000000000..4ca330e1d --- /dev/null +++ b/components/esp_matter_console/esp_matter_console_udc.cpp @@ -0,0 +1,105 @@ +// 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 +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT +#include +#include +#include +#endif + +namespace esp_matter { +namespace console { +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT +static const char *TAG = "esp_matter_console_udc"; +static engine udc_console; + +static esp_err_t send_udc_request(int argc, char *argv[]) +{ + ESP_RETURN_ON_FALSE(argc == 2, ESP_ERR_INVALID_ARG, TAG, "Incorrect arguments"); + chip::Inet::IPAddress commissioner; + chip::Inet::IPAddress::FromString(argv[0], commissioner); + uint16_t port = (uint16_t)strtol(argv[1], nullptr, 10); + chip::Protocols::UserDirectedCommissioning::IdentificationDeclaration id; + chip::Server::GetInstance().SendUserDirectedCommissioningRequest( + chip::Transport::PeerAddress::UDP(commissioner, port), id); + return ESP_OK; +} + +static esp_err_t send_udc_cancel(int argc, char *argv[]) +{ + ESP_RETURN_ON_FALSE(argc == 2, ESP_ERR_INVALID_ARG, TAG, "Incorrect arguments"); + chip::Inet::IPAddress commissioner; + chip::Inet::IPAddress::FromString(argv[0], commissioner); + uint16_t port = (uint16_t)strtol(argv[1], nullptr, 10); + chip::Protocols::UserDirectedCommissioning::IdentificationDeclaration id; + id.SetCancelPasscode(true); + chip::Server::GetInstance().SendUserDirectedCommissioningRequest( + chip::Transport::PeerAddress::UDP(commissioner, port), id); + return ESP_OK; +} + +static esp_err_t discover_commissioner(int argc, char *argv[]) +{ + ESP_LOGI(TAG, "Use 'matter dns browse commissioner' command to discovery commissioner"); + return ESP_OK; +} + +static esp_err_t udc_dispatch(int argc, char *argv[]) +{ + if (argc <= 0) { + udc_console.for_each_command(print_description, NULL); + return ESP_OK; + } + return udc_console.exec_command(argc, argv); +} +#endif + +esp_err_t udc_register_commands() +{ +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + static const command_t command = { + .name = "udc", + .description = "udc commands. Usage: matter esp udc .", + .handler = udc_dispatch, + }; + + static const command_t udc_commands[] = { + { + .name = "discover", + .description = "Discover commissioner", + .handler = discover_commissioner, + }, + { + .name = "send", + .description = "Send UDC message to address. Usage: matter esp udc send [address] [port].", + .handler = send_udc_request, + }, + { + .name = "cancel", + .description = "Send UDC cancel message to address. Usage: matter esp udc cancel [address] [port].", + .handler = send_udc_cancel, + }, + }; + udc_console.register_commands(udc_commands, sizeof(udc_commands) / sizeof(command_t)); + return add_commands(&command, 1); +#else + return ESP_OK; +#endif +} +} // namespace console +} // namespace esp_matter diff --git a/components/esp_matter_controller/core/esp_matter_controller_client.cpp b/components/esp_matter_controller/core/esp_matter_controller_client.cpp index 67bdea2e0..1416aba6c 100644 --- a/components/esp_matter_controller/core/esp_matter_controller_client.cpp +++ b/components/esp_matter_controller/core/esp_matter_controller_client.cpp @@ -50,6 +50,10 @@ using chip::Platform::ScopedMemoryBufferWithSize; namespace esp_matter { namespace controller { +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY +ESPCommissionerCallback commissioner_callback; +#endif + esp_err_t matter_controller_client::init(NodeId node_id, FabricId fabric_id, uint16_t listen_port) { chip::Controller::FactoryInitParams factory_init_params; @@ -153,6 +157,12 @@ esp_err_t matter_controller_client::setup_commissioner() compressed_fabric_id_span) == CHIP_NO_ERROR, ESP_FAIL, TAG, "Failed to set ipk for commissioner fabric"); // m_icd_client_storage.UpdateFabricList(fabric_index); + +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + get_discovery_controller()->SetUserDirectedCommissioningServer(get_commissioner()->GetUserDirectedCommissioningServer()); + get_discovery_controller()->SetCommissionerCallback(&commissioner_callback); +#endif + m_device_commissioner.RegisterPairingDelegate(&controller::pairing_command::get_instance()); return ESP_OK; diff --git a/components/esp_matter_controller/core/esp_matter_controller_client.h b/components/esp_matter_controller/core/esp_matter_controller_client.h index c273e4226..c005e445a 100644 --- a/components/esp_matter_controller/core/esp_matter_controller_client.h +++ b/components/esp_matter_controller/core/esp_matter_controller_client.h @@ -39,6 +39,9 @@ #include #include +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY +#include +#endif namespace esp_matter { namespace controller { @@ -91,6 +94,9 @@ public: #ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE esp_err_t setup_commissioner(); MatterDeviceCommissioner *get_commissioner() { return &m_device_commissioner; } +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + CommissionerDiscoveryController *get_discovery_controller() { return &m_commissioner_discovery_controller; } +#endif #else esp_err_t setup_controller(chip::MutableByteSpan &ipk); MatterDeviceController *get_controller() { return &m_device_controller; } @@ -115,11 +121,29 @@ private: #ifdef CONFIG_ESP_MATTER_COMMISSIONER_ENABLE chip::Controller::AutoCommissioner m_auto_commissioner; MatterDeviceCommissioner m_device_commissioner; +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + CommissionerDiscoveryController m_commissioner_discovery_controller; +#endif #else MatterDeviceController m_device_controller; #endif }; #endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY +class ESPCommissionerCallback : public CommissionerCallback { + void ReadyForCommissioning(uint32_t pincode, uint16_t longDiscriminator, PeerAddress peerAddress) override + { + NodeId gRemoteId = chip::kTestDeviceNodeId; + chip::RendezvousParameters params = chip::RendezvousParameters() + .SetSetupPINCode(pincode).SetDiscriminator(longDiscriminator).SetPeerAddress(peerAddress); + do { + chip::DRBG_get_bytes(reinterpret_cast(&gRemoteId), sizeof(gRemoteId)); + } while (!chip::IsOperationalNodeId(gRemoteId)); + matter_controller_client::get_instance().get_commissioner()->PairDevice(gRemoteId, params); + } +}; +#endif + } // namespace controller } // namespace esp_matter diff --git a/components/esp_matter_controller/core/esp_matter_controller_console.cpp b/components/esp_matter_controller/core/esp_matter_controller_console.cpp index f6cb848df..6800ca024 100644 --- a/components/esp_matter_controller/core/esp_matter_controller_console.cpp +++ b/components/esp_matter_controller/core/esp_matter_controller_console.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -225,6 +226,53 @@ static esp_err_t controller_pairing_handler(int argc, char **argv) } return ESP_ERR_INVALID_ARG; } + +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY +static esp_err_t controller_udc_handler(int argc, char **argv) +{ + if (argc < 1 || argc > 3) { + return ESP_ERR_INVALID_ARG; + } + if (strncmp(argv[0], "reset", sizeof("reset")) == 0) { + if (argc != 1) { + return ESP_ERR_INVALID_ARG; + } + controller::matter_controller_client::get_instance() + .get_commissioner()->GetUserDirectedCommissioningServer()->ResetUDCClientProcessingStates(); + } else if (strncmp(argv[0], "print", sizeof("print")) == 0) { + if (argc != 1) { + return ESP_ERR_INVALID_ARG; + } + controller::matter_controller_client::get_instance() + .get_commissioner()->GetUserDirectedCommissioningServer()->PrintUDCClients(); + } else if (strncmp(argv[0], "commission", sizeof("commission")) == 0) { + if (argc != 3) { + return ESP_ERR_INVALID_ARG; + } + uint32_t pincode = string_to_uint32(argv[1]); + printf("pincode %ld", pincode); + size_t index = (size_t)string_to_uint32(argv[2]); + controller::matter_controller_client &instance = controller::matter_controller_client::get_instance(); + UDCClientState *state = + instance.get_commissioner()->GetUserDirectedCommissioningServer()->GetUDCClients().GetUDCClientState(index); + ESP_RETURN_ON_FALSE(state != nullptr, ESP_FAIL, TAG, "UDC client not found"); + state->SetUDCClientProcessingState(chip::Controller::UDCClientProcessingState::kCommissioningNode); + + chip::NodeId gRemoteId = chip::kTestDeviceNodeId; + chip::RendezvousParameters params = chip::RendezvousParameters() + .SetSetupPINCode(pincode).SetDiscriminator(state->GetLongDiscriminator()).SetPeerAddress(state->GetPeerAddress()); + do { + chip::DRBG_get_bytes(reinterpret_cast(&gRemoteId), sizeof(gRemoteId)); + } while (!chip::IsOperationalNodeId(gRemoteId)); + + ESP_RETURN_ON_FALSE(instance.get_commissioner()->PairDevice(gRemoteId, params) == CHIP_NO_ERROR, ESP_FAIL, TAG, + "Failed to commission udc"); + } else { + return ESP_ERR_INVALID_ARG; + } + return ESP_OK; +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY #endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE #ifndef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER @@ -439,6 +487,16 @@ esp_err_t controller_register_commands() "\tUsage: controller group-settings ", .handler = controller_group_settings_handler, }, +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + { + .name = "udc", + .description = "UDC command.\n" + "\tUsage: controller udc reset OR\n" + "\tcontroller udc print OR\n" + "\tcontroller udc commission [pincode] [udc-entry]", + .handler = controller_udc_handler, + }, +#endif #endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE { .name = "invoke-cmd",