Skip to content

Commit

Permalink
Merge branch 'more_pairing_options' into 'main'
Browse files Browse the repository at this point in the history
components/esp_matter_controller: Added more pairing commands

See merge request app-frameworks/esp-matter!906
  • Loading branch information
dhrishi committed Oct 22, 2024
2 parents e2c5216 + 4490e9a commit 90d5411
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
Expand All @@ -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<const uint8_t *>(ssid), strlen(ssid));
chip::ByteSpan pwdSpan(reinterpret_cast<const uint8_t *>(pwd), strlen(pwd));
ByteSpan nameSpan(reinterpret_cast<const uint8_t *>(ssid), strlen(ssid));
ByteSpan pwdSpan(reinterpret_cast<const uint8_t *>(pwd), strlen(pwd));
CommissioningParameters commissioning_params =
CommissioningParameters().SetWiFiCredentials(Controller::WiFiCredentials(nameSpan, pwdSpan));
auto &controller_instance = esp_matter::controller::matter_controller_client::get_instance();
Expand All @@ -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<const uint8_t *>(ssid), strlen(ssid));
ByteSpan pwdSpan(reinterpret_cast<const uint8_t *>(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<const uint8_t *>(ssid), strlen(ssid));
ByteSpan pwdSpan(reinterpret_cast<const uint8_t *>(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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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);
}

if (result != ESP_OK) {
ESP_LOGE(TAG, "Pairing over code failed");
}
return ESP_ERR_INVALID_ARG;
return result;
}

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
Expand Down Expand Up @@ -518,7 +557,12 @@ 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> <dataset> <pincode> <discriminator>",
"\tcontroller pairing ble-thread <nodeid> <dataset> <pincode> <discriminator> OR\n"
"\tcontroller pairing ble-thread <nodeid> <dataset> <pincode> <discriminator> OR\n"
"\tcontroller pairing code <nodeid> <payload> OR\n"
"\tcontroller pairing code-wifi <nodeid> <ssid> <password> <payload> OR\n"
"\tcontroller pairing code-thread <nodeid> <dataset> <payload> OR\n"
"\tcontroller pairing code-wifi-thread <nodeid> <ssid> <password> <dataset> <payload>",
.handler = controller_pairing_handler,
},
{
Expand Down
31 changes: 28 additions & 3 deletions docs/en/developing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <ssid> <password>
matter esp controller pairing onnetwork <node_id> <setup_passcode>

- 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 <ssid> <password>
matter esp controller pairing ble-wifi <node_id> <ssid> <password> <pincode> <discriminator>

- 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 <ssid> <password>
matter esp controller pairing ble-thread <node_id> <dataset_tlvs> <pincode> <discriminator>

- **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 <node_id> <setup_payload>

::

matter esp controller pairing code-wifi <node_id> <ssid> <passphrase> <setup_payload>

::

matter esp controller pairing code-thread <node_id> <operationalDataset> <setup_payload>

::

matter esp controller pairing code-wifi-thread <node_id> <ssid> <passphrase> <operationalDataset> <setup_payload>


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:
Expand Down

0 comments on commit 90d5411

Please sign in to comment.