diff --git a/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.cpp b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.cpp index 27fd8f6a7..6057030f7 100644 --- a/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.cpp +++ b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.cpp @@ -91,13 +91,13 @@ CommissioningParameters pairing_command::get_commissioning_params() return CommissioningParameters(); } -void pairing_command::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData &nodeData) +void pairing_command::OnDiscoveredDevice(const Dnssd::CommissionNodeData &nodeData) { auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); // Ignore nodes with closed comissioning window VerifyOrReturn(nodeData.commissioningMode != 0); const uint16_t port = nodeData.port; - char buf[chip::Inet::IPAddress::kMaxStringLength]; + char buf[Inet::IPAddress::kMaxStringLength]; nodeData.ipAddress[0].ToString(buf); ESP_LOGI(TAG, "Discovered Device: %s:%u", buf, port); @@ -115,7 +115,7 @@ void pairing_command::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & esp_err_t pairing_on_network(NodeId node_id, uint32_t pincode) { - Dnssd::DiscoveryFilter filter(chip::Dnssd::DiscoveryFilterType::kNone); + Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kNone); 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; @@ -133,10 +133,10 @@ esp_err_t pairing_on_network(NodeId node_id, uint32_t pincode) esp_err_t pairing_ble_wifi(NodeId node_id, uint32_t pincode, uint16_t disc, const char *ssid, const char *pwd) { RendezvousParameters params = RendezvousParameters().SetSetupPINCode(pincode).SetDiscriminator(disc).SetPeerAddress( - chip::Transport::PeerAddress::BLE()); + Transport::PeerAddress::BLE()); - chip::ByteSpan nameSpan(reinterpret_cast(ssid), strlen(ssid)); - chip::ByteSpan pwdSpan(reinterpret_cast(pwd), strlen(pwd)); + ByteSpan nameSpan(reinterpret_cast(ssid), strlen(ssid)); + ByteSpan pwdSpan(reinterpret_cast(pwd), strlen(pwd)); CommissioningParameters commissioning_params = CommissioningParameters().SetWiFiCredentials(Controller::WiFiCredentials(nameSpan, pwdSpan)); auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); @@ -148,14 +148,63 @@ esp_err_t pairing_ble_thread(NodeId node_id, uint32_t pincode, uint16_t disc, ui uint8_t dataset_len) { RendezvousParameters params = RendezvousParameters().SetSetupPINCode(pincode).SetDiscriminator(disc).SetPeerAddress( - chip::Transport::PeerAddress::BLE()); + Transport::PeerAddress::BLE()); - chip::ByteSpan dataset_span(dataset_tlvs, dataset_len); + ByteSpan dataset_span(dataset_tlvs, dataset_len); 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 + +esp_err_t pairing_code(NodeId nodeId, const char *payload) +{ + CommissioningParameters commissioning_params = CommissioningParameters(); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->PairDevice(nodeId, payload, commissioning_params, DiscoveryType::kDiscoveryNetworkOnly); + return ESP_OK; +} + +esp_err_t pairing_code_thread(NodeId nodeId, const char *payload, uint8_t *dataset_buf, uint8_t dataset_len) +{ + ByteSpan dataset_span(dataset_buf, dataset_len); + + CommissioningParameters commissioning_params = CommissioningParameters().SetThreadOperationalDataset(dataset_span); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->PairDevice(nodeId, payload, commissioning_params, DiscoveryType::kAll); + + return ESP_OK; +} + +esp_err_t pairing_code_wifi(NodeId nodeId, const char *ssid, const char *password, const char *payload) +{ + ByteSpan nameSpan(reinterpret_cast(ssid), strlen(ssid)); + ByteSpan pwdSpan(reinterpret_cast(password), strlen(password)); + + CommissioningParameters commissioning_params = + CommissioningParameters().SetWiFiCredentials(Controller::WiFiCredentials(nameSpan, pwdSpan)); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->PairDevice(nodeId, payload, commissioning_params, DiscoveryType::kAll); + + return ESP_OK; +} + +esp_err_t pairing_code_wifi_thread(NodeId nodeId, const char *ssid, const char *password, const char *payload, + uint8_t *dataset_buf, uint8_t dataset_len) +{ + ByteSpan nameSpan(reinterpret_cast(ssid), strlen(ssid)); + ByteSpan pwdSpan(reinterpret_cast(password), strlen(password)); + ByteSpan dataset_span(dataset_buf, dataset_len); + + CommissioningParameters commissioning_params = + CommissioningParameters().SetWiFiCredentials(Controller::WiFiCredentials(nameSpan, pwdSpan)).SetThreadOperationalDataset( + dataset_span); + auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance(); + controller_instance.get_commissioner()->PairDevice(nodeId, payload, commissioning_params, DiscoveryType::kAll); + + return ESP_OK; +} + } // namespace controller } // namespace esp_matter diff --git a/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.h b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.h index e653dea5f..bfa32cbbc 100644 --- a/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.h +++ b/components/esp_matter_controller/commands/esp_matter_controller_pairing_command.h @@ -122,7 +122,60 @@ esp_err_t pairing_ble_wifi(NodeId node_id, uint32_t pincode, uint16_t disc, cons */ esp_err_t pairing_ble_thread(NodeId node_id, uint32_t pincode, uint16_t disc, uint8_t *dataset_tlvs, uint8_t dataset_len); -#endif +#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER + +/** + * Pair a on-network Matter end-device with a pairing code + * + * @param[in] node_id NodeId assigned to the Matter end-device. + * @param[in] payload Pairing code + * + * @return ESP_OK on success + * @return error in case of failure + */ +esp_err_t pairing_code(NodeId node_id, const char *payload); + +/** + * Pair a thread Matter end-device with a pairing code + * + * @param[in] node_id NodeId assigned to the Matter end-device. + * @param[in] payload Pairing code + * @param[in] dataset_buf Buffer containing the Thread network dataset + * @param[in] dataset_len Length of the dataset buffer + * + * @return ESP_OK on success + * @return error in case of failure + */ +esp_err_t pairing_code_thread(NodeId node_id, const char *payload, uint8_t *dataset_buf, uint8_t dataset_len); + +/** + * Pair a Wi-Fi Matter end-device with a pairing code + * + * @param[in] node_id NodeId assigned to the Matter end-device. + * @param[in] ssid SSID of the Wi-Fi AP. + * @param[in] password Password of the Wi-Fi AP. + * @param[in] payload Pairing code + * + * @return ESP_OK on success + * @return error in case of failure + */ +esp_err_t pairing_code_wifi(NodeId node_id, const char *ssid, const char *password, const char *payload); + +/** + * Pair a Matter end-device which supports both Wi-Fi as well as Thread with a pairing code + * + * @param[in] node_id NodeId that will be assigned to the Matter end-device. + * @param[in] ssid SSID of the Wi-Fi AP. + * @param[in] password Password of the Wi-Fi AP. + * @param[in] payload Pairing code + * @param[in] dataset_buf Buffer containing the Thread network dataset + * @param[in] dataset_len Length of the dataset buffer + * + * @return ESP_OK on success + * @return error in case of failure + */ +esp_err_t pairing_code_wifi_thread(NodeId node_id, const char *ssid, const char *password, const char *payload, + uint8_t *dataset_buf, uint8_t dataset_len); } // 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 4faf79922..c0a76ec13 100644 --- a/components/esp_matter_controller/core/esp_matter_controller_console.cpp +++ b/components/esp_matter_controller/core/esp_matter_controller_console.cpp @@ -174,37 +174,28 @@ static bool convert_hex_str_to_bytes(const char *hex_str, uint8_t *bytes, uint8_ #if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE static esp_err_t controller_pairing_handler(int argc, char **argv) { - if (argc < 3 || argc > 6) { - return ESP_ERR_INVALID_ARG; - } + VerifyOrReturnError(argc >= 3 && argc <= 6, ESP_ERR_INVALID_ARG); + esp_err_t result = ESP_ERR_INVALID_ARG; if (strncmp(argv[0], "onnetwork", sizeof("onnetwork")) == 0) { - if (argc != 3) { - return ESP_ERR_INVALID_ARG; - } + VerifyOrReturnError(argc == 3, ESP_ERR_INVALID_ARG); uint64_t nodeId = string_to_uint64(argv[1]); uint32_t pincode = string_to_uint32(argv[2]); return controller::pairing_on_network(nodeId, pincode); + #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER } else if (strncmp(argv[0], "ble-wifi", sizeof("ble-wifi")) == 0) { - if (argc != 6) { - return ESP_ERR_INVALID_ARG; - } + VerifyOrReturnError(argc == 6, ESP_ERR_INVALID_ARG); uint64_t nodeId = string_to_uint64(argv[1]); uint32_t pincode = string_to_uint32(argv[4]); uint16_t disc = string_to_uint16(argv[5]); - esp_err_t result = controller::pairing_ble_wifi(nodeId, pincode, disc, argv[2], argv[3]); - if (result != ESP_OK) { - ESP_LOGE(TAG, "Pairing over ble failed"); - } - return result; + result = controller::pairing_ble_wifi(nodeId, pincode, disc, argv[2], argv[3]); } else if (strncmp(argv[0], "ble-thread", sizeof("ble-thread")) == 0) { - if (argc != 5) { - return ESP_ERR_INVALID_ARG; - } + VerifyOrReturnError(argc == 5, ESP_ERR_INVALID_ARG); + uint8_t dataset_tlvs_buf[254]; uint8_t dataset_tlvs_len = sizeof(dataset_tlvs_buf); if (!convert_hex_str_to_bytes(argv[2], dataset_tlvs_buf, dataset_tlvs_len)) { @@ -214,19 +205,67 @@ static esp_err_t controller_pairing_handler(int argc, char **argv) uint32_t pincode = string_to_uint32(argv[3]); uint16_t disc = string_to_uint16(argv[4]); - esp_err_t result = controller::pairing_ble_thread(node_id, pincode, disc, dataset_tlvs_buf, dataset_tlvs_len); - if (result != ESP_OK) { - ESP_LOGE(TAG, "Pairing over ble failed"); - } - return result; + result = controller::pairing_ble_thread(node_id, pincode, disc, dataset_tlvs_buf, dataset_tlvs_len); #else // if !CONFIG_ENABLE_ESP32_BLE_CONTROLLER } else if (strncmp(argv[0], "ble-wifi", sizeof("ble-wifi")) == 0 || strncmp(argv[0], "ble-thread", sizeof("ble-thread")) == 0) { ESP_LOGE(TAG, "Please enable ENABLE_ESP32_BLE_CONTROLLER to use pairing %s command", argv[0]); return ESP_ERR_NOT_SUPPORTED; #endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER + } else if (strncmp(argv[0], "code", sizeof("code")) == 0) { + VerifyOrReturnError(argc == 3, ESP_ERR_INVALID_ARG); + + uint64_t nodeId = string_to_uint64(argv[1]); + const char *payload = argv[2]; + + result = controller::pairing_code(nodeId, payload); + + } else if (strncmp(argv[0], "code-thread", sizeof("code-thread")) == 0) { + VerifyOrReturnError(argc == 4, ESP_ERR_INVALID_ARG); + + uint64_t nodeId = string_to_uint64(argv[1]); + const char *payload = argv[3]; + + uint8_t dataset_tlvs_buf[254]; + uint8_t dataset_tlvs_len = sizeof(dataset_tlvs_buf); + if (!convert_hex_str_to_bytes(argv[2], dataset_tlvs_buf, dataset_tlvs_len)) { + return ESP_ERR_INVALID_ARG; + } + + result = controller::pairing_code_thread(nodeId, payload, dataset_tlvs_buf, dataset_tlvs_len); + + } else if (strncmp(argv[0], "code-wifi", sizeof("code-wifi")) == 0) { + VerifyOrReturnError(argc == 5, ESP_ERR_INVALID_ARG); + + uint64_t nodeId = string_to_uint64(argv[1]); + const char *ssid = argv[2]; + const char *password = argv[3]; + const char *payload = argv[4]; + + result = controller::pairing_code_wifi(nodeId, ssid, password, payload); + + } else if (strncmp(argv[0], "code-wifi-thread", sizeof("code-wifi-thread")) == 0) { + VerifyOrReturnError(argc == 6, ESP_ERR_INVALID_ARG); + + uint64_t nodeId = string_to_uint64(argv[1]); + const char *ssid = argv[2]; + const char *password = argv[3]; + const char *payload = argv[4]; + + uint8_t dataset_tlvs_buf[254]; + uint8_t dataset_tlvs_len = sizeof(dataset_tlvs_buf); + if (!convert_hex_str_to_bytes(argv[5], dataset_tlvs_buf, dataset_tlvs_len)) { + return ESP_ERR_INVALID_ARG; + } + + result = controller::pairing_code_wifi_thread(nodeId, ssid, password, payload, dataset_tlvs_buf, + dataset_tlvs_len); } - return ESP_ERR_INVALID_ARG; + + if (result != ESP_OK) { + ESP_LOGE(TAG, "Pairing over code failed"); + } + return result; } #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY @@ -518,7 +557,12 @@ esp_err_t controller_register_commands() .description = "Pairing a node.\n" "\tUsage: controller pairing onnetwork OR\n" "\tcontroller pairing ble-wifi OR\n" - "\tcontroller pairing ble-thread ", + "\tcontroller pairing ble-thread OR\n" + "\tcontroller pairing ble-thread OR\n" + "\tcontroller pairing code OR\n" + "\tcontroller pairing code-wifi OR\n" + "\tcontroller pairing code-thread OR\n" + "\tcontroller pairing code-wifi-thread ", .handler = controller_pairing_handler, }, { diff --git a/docs/en/developing.rst b/docs/en/developing.rst index 3ac219549..4cb9c9610 100644 --- a/docs/en/developing.rst +++ b/docs/en/developing.rst @@ -1283,27 +1283,52 @@ Once you have flashed the controller example onto the device, you can use the `d ~~~~~~~~~~~~~~~~~~~~~~~ The ``pairing`` commands are used for commissioning end-devices and are available when the ``Enable matter commissioner`` option is enabled. Here are three standard pairing methods: -- Onnetwork pairing. Prior to executing this commissioning method, it is necessary to connect both the controller and the end-device to the same network and ensure that the commissioning window of the end-device is open. To complete this process, you can use the command ``matter esp wifi connect``. After the devices are connected, the pairing process can be initiated. +- **Onnetwork pairing:** Prior to executing this commissioning method, it is necessary to connect both the controller and the end-device to the same network and ensure that the commissioning window of the end-device is open. To complete this process, you can use the command ``matter esp wifi connect``. After the devices are connected, the pairing process can be initiated. :: matter esp wifi connect matter esp controller pairing onnetwork -- Ble-wifi pairing. This pairing method is supported for ESP32S3. Before you execute this commissioning method, connect the controller to the Wi-Fi network and ensure that the end-device is in commissioning mode. You can use the command ``matter esp wifi connect`` to connect the controller to your wifi network. Then we can start the pairing. +- **Ble-wifi pairing:** This pairing method is supported for ESP32S3. Before you execute this commissioning method, connect the controller to the Wi-Fi network and ensure that the end-device is in commissioning mode. You can use the command ``matter esp wifi connect`` to connect the controller to your wifi network. Then we can start the pairing. :: matter esp wifi connect matter esp controller pairing ble-wifi -- Ble-thread pairing. This pairing method is supported for ESP32S3. Before you execute this commissioning method, connect the controller to the Wi-Fi network in which there is a Thread Border Router (BR). And please ensure that the end-device is in commissioning mode. You can use the command ``matter esp wifi connect`` to connect the controller to your Wi-Fi network. Get the dataset tlvs of the Thread network that the Thread BR is in. Then we can start the pairing. +- **Ble-thread pairing:** This pairing method is supported for ESP32S3. Before you execute this commissioning method, connect the controller to the Wi-Fi network in which there is a Thread Border Router (BR). And please ensure that the end-device is in commissioning mode. You can use the command ``matter esp wifi connect`` to connect the controller to your Wi-Fi network. Get the dataset tlvs of the Thread network that the Thread BR is in. Then we can start the pairing. :: matter esp wifi connect matter esp controller pairing ble-thread +- **Matter payload based pairing:** This method is similar to the previously mentioned pairing methods, but instead of accepting a PIN code and discriminator, it uses a Matter setup payload as input. The setup payload is parsed to extract the necessary information, which then initiates the pairing process. + +For the ``code`` pairing method, commissioner tries to discover the end-device only on the IP network. +However, when using ``code-wifi``, ``code-thread``, or ``code-wifi-thread``, and id +``CONFIG_ENABLE_ESP32_BLE_CONTROLLER`` is enabled, controller tries to discover the end-device on both the IP and BLE networks. + +Below are supported commands: + + :: + + matter esp controller pairing code + + :: + + matter esp controller pairing code-wifi + + :: + + matter esp controller pairing code-thread + + :: + + matter esp controller pairing code-wifi-thread + + 2.10.3 Cluster commands ~~~~~~~~~~~~~~~~~~~~~~~ The ``invoke-cmd`` command is used for sending cluster commands to the end-devices. It utilizes a ``cluster_command`` class to establish the sessions and send the command packets. The class constructor function could accept two callback inputs: