From 3a6287c9a5ef018220e0ddad6c8d741003e288e4 Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Thu, 2 Nov 2023 13:29:06 +0800 Subject: [PATCH] controller: Add ble-thread pairing command for commissioner --- .../esp_matter_controller_console.cpp | 86 ++++++++++++++----- .../esp_matter_controller_pairing_command.cpp | 27 ++++-- .../esp_matter_controller_pairing_command.h | 4 +- docs/en/developing.rst | 8 +- 4 files changed, 95 insertions(+), 30 deletions(-) diff --git a/components/esp_matter_controller/esp_matter_controller_console.cpp b/components/esp_matter_controller/esp_matter_controller_console.cpp index 1c6783e85..84ff48190 100644 --- a/components/esp_matter_controller/esp_matter_controller_console.cpp +++ b/components/esp_matter_controller/esp_matter_controller_console.cpp @@ -52,6 +52,41 @@ static esp_err_t controller_help_handler(int argc, char **argv) return ESP_OK; } +#if CONFIG_ENABLE_ESP32_BLE_CONTROLLER +static int char_to_int(char ch) +{ + if ('A' <= ch && ch <= 'F') { + return 10 + ch - 'A'; + } else if ('a' <= ch && ch <= 'f') { + return 10 + ch - 'a'; + } else if ('0' <= ch && ch <= '9') { + return ch - '0'; + } + return -1; +} + +static bool convert_hex_str_to_bytes(const char *hex_str, uint8_t *bytes, uint8_t &bytes_len) +{ + if (!hex_str) { + return false; + } + size_t hex_str_len = strlen(hex_str); + if (hex_str_len == 0 || hex_str_len % 2 != 0 || hex_str_len / 2 > bytes_len) { + return false; + } + bytes_len = hex_str_len / 2; + for (size_t i = 0; i < bytes_len; ++i) { + int byte_h = char_to_int(hex_str[2 * i]); + int byte_l = char_to_int(hex_str[2 * i + 1]); + if (byte_h < 0 || byte_l < 0) { + return false; + } + bytes[i] = (byte_h << 4) + byte_l; + } + return true; +} +#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER + #if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE static esp_err_t controller_pairing_handler(int argc, char **argv) { @@ -67,37 +102,44 @@ static esp_err_t controller_pairing_handler(int argc, char **argv) uint64_t nodeId = string_to_uint64(argv[1]); uint32_t pincode = string_to_uint32(argv[2]); return controller::pairing_on_network(nodeId, pincode); - } else if (strncmp(argv[0], "ble-wifi", sizeof("ble-wifi")) == 0) { #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER - if (argc != 6) { + } else if (strncmp(argv[0], "ble-wifi", sizeof("ble-wifi")) == 0) { + if (argc != 6) { return ESP_ERR_INVALID_ARG; } - - char *ssid = NULL, *pwd = NULL; - - ssid = strndup(argv[2], strlen(argv[2]) + 1); - pwd = strndup(argv[3], strlen(argv[3]) + 1); - if (ssid == NULL || pwd == NULL) { - return ESP_ERR_NO_MEM; - } - uint64_t nodeId = string_to_uint64(argv[1]); uint32_t pincode = string_to_uint32(argv[4]); - uint16_t disc = string_to_uint16(argv[5]); + uint16_t disc = string_to_uint16(argv[5]); - esp_err_t result = controller::pairing_ble_wifi(nodeId, pincode, disc, ssid, pwd); + 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"); - } - if (ssid != NULL) free(ssid); - if (pwd != NULL) free(pwd); - - return result; -#else - return ESP_ERR_NOT_SUPPORTED; -#endif + } + return result; } else if (strncmp(argv[0], "ble-thread", sizeof("ble-thread")) == 0) { + if (argc != 5) { + return 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)) { + return ESP_ERR_INVALID_ARG; + } + uint64_t node_id = string_to_uint64(argv[1]); + 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; +#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 } return ESP_ERR_INVALID_ARG; } @@ -288,7 +330,7 @@ esp_err_t controller_register_commands() .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] [pincode] [discriminator] [dataset]", + "\tcontroller pairing ble-thread [nodeid] [dataset] [pincode] [discriminator]", .handler = controller_pairing_handler, }, { diff --git a/components/esp_matter_controller/esp_matter_controller_pairing_command.cpp b/components/esp_matter_controller/esp_matter_controller_pairing_command.cpp index 5d2cc7289..454f4ef0d 100644 --- a/components/esp_matter_controller/esp_matter_controller_pairing_command.cpp +++ b/components/esp_matter_controller/esp_matter_controller_pairing_command.cpp @@ -71,7 +71,8 @@ void pairing_command::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) } } -void pairing_command::OnDeviceConnectedFn(void *context, ExchangeManager &exchangeMgr, const SessionHandle &sessionHandle) +void pairing_command::OnDeviceConnectedFn(void *context, ExchangeManager &exchangeMgr, + const SessionHandle &sessionHandle) { ESP_LOGI(TAG, "OnDeviceConnectedFn"); CommissionerDiscoveryController *cdc = esp_matter::commissioner::get_discovery_controller(); @@ -145,13 +146,27 @@ esp_err_t pairing_on_network(NodeId node_id, uint32_t pincode) } #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER -esp_err_t pairing_ble_wifi(NodeId node_id, uint32_t pincode, uint16_t disc, const char * ssid, const char * pwd) +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()); + RendezvousParameters params = RendezvousParameters().SetSetupPINCode(pincode).SetDiscriminator(disc).SetPeerAddress( + chip::Transport::PeerAddress::BLE()); - chip::ByteSpan nameSpan(reinterpret_cast(ssid),strlen(ssid)); - chip::ByteSpan pwdSpan(reinterpret_cast(pwd),strlen(pwd)); - CommissioningParameters commissioning_params = CommissioningParameters().SetWiFiCredentials(Controller::WiFiCredentials(nameSpan, pwdSpan)); + chip::ByteSpan nameSpan(reinterpret_cast(ssid), strlen(ssid)); + 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); + 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) +{ + 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); return ESP_OK; } diff --git a/components/esp_matter_controller/esp_matter_controller_pairing_command.h b/components/esp_matter_controller/esp_matter_controller_pairing_command.h index 94cfc1e4a..248b45825 100644 --- a/components/esp_matter_controller/esp_matter_controller_pairing_command.h +++ b/components/esp_matter_controller/esp_matter_controller_pairing_command.h @@ -81,7 +81,9 @@ private: esp_err_t pairing_on_network(NodeId node_id, uint32_t pincode); #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER -esp_err_t pairing_ble_wifi(NodeId node_id, uint32_t pincode, uint16_t disc, const char * ssid, const char * pwd); +esp_err_t pairing_ble_wifi(NodeId node_id, uint32_t pincode, uint16_t disc, const char *ssid, const char *pwd); +esp_err_t pairing_ble_thread(NodeId node_id, uint32_t pincode, uint16_t disc, uint8_t *dataset_tlvs, + uint8_t dataset_len); #endif } // namespace controller diff --git a/docs/en/developing.rst b/docs/en/developing.rst index 3b7b0ae07..442763891 100644 --- a/docs/en/developing.rst +++ b/docs/en/developing.rst @@ -1159,6 +1159,7 @@ For example we want to use mode_select cluster in light example. This section introduces the Matter controller example. Now this example supports the following features of the standard Matter controller: - BLE-WiFi pairing +- BLE-Thread pairing - On-network pairing - Invoke cluster commands - Read attributes commands @@ -1190,7 +1191,12 @@ The ``pairing`` commands are used for commissioning end-devices and are availabl matter esp wifi connect matter esp controller pairing ble-wifi -- Ble-thread pairing. This commissioning method is still not supported on current controller example. +- 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 2.9.3 Cluster commands ~~~~~~~~~~~~~~~~~~~~~~