mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
0890dbc8d9
controller: Add invoking commands and writing attributes commands for group_key_management cluster controller: Add invoking commands for groups cluster
230 lines
9.3 KiB
C++
230 lines
9.3 KiB
C++
// 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 <esp_check.h>
|
|
#include <esp_matter_commissioner.h>
|
|
#include <esp_matter_controller_group_settings.h>
|
|
#include <esp_matter_controller_utils.h>
|
|
|
|
using chip::FabricIndex;
|
|
using chip::KeysetId;
|
|
using chip::Credentials::GroupDataProvider;
|
|
|
|
constexpr char TAG[] = "groupsettings";
|
|
|
|
namespace esp_matter {
|
|
namespace controller {
|
|
namespace group_settings {
|
|
|
|
static bool find_keyset_id(FabricIndex fabric_index, uint16_t group_id, KeysetId &keyset_id)
|
|
{
|
|
GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider();
|
|
auto iter = group_data_provider->IterateGroupKeys(fabric_index);
|
|
GroupDataProvider::GroupKey group_key;
|
|
while (iter->Next(group_key)) {
|
|
if (group_key.group_id == group_id) {
|
|
keyset_id = group_key.keyset_id;
|
|
iter->Release();
|
|
return true;
|
|
}
|
|
}
|
|
iter->Release();
|
|
return false;
|
|
}
|
|
|
|
esp_err_t show_groups()
|
|
{
|
|
ESP_LOGI(TAG, " +-------------------------------------------------------------------------------------+");
|
|
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();
|
|
GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider();
|
|
auto iter = group_data_provider->IterateGroupInfo(fabric_index);
|
|
GroupDataProvider::GroupInfo group_info;
|
|
if (iter) {
|
|
while (iter->Next(group_info)) {
|
|
chip::KeysetId keyset_id;
|
|
if (find_keyset_id(fabric_index, group_info.group_id, keyset_id)) {
|
|
ESP_LOGI(TAG, " | 0x%-12x 0x%-13x %-50s |", group_info.group_id, keyset_id, group_info.name);
|
|
} else {
|
|
ESP_LOGI(TAG, " | 0x%-12x %-15s %-50s |", group_info.group_id, "None", group_info.name);
|
|
}
|
|
}
|
|
iter->Release();
|
|
}
|
|
ESP_LOGI(TAG, " +-------------------------------------------------------------------------------------+");
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t add_group(char *group_name, uint16_t group_id)
|
|
{
|
|
if (strlen(group_name) > CHIP_CONFIG_MAX_GROUP_NAME_LENGTH || group_id == chip::kUndefinedGroupId) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex();
|
|
GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider();
|
|
GroupDataProvider::GroupInfo group_info;
|
|
|
|
group_info.SetName(group_name);
|
|
group_info.group_id = group_id;
|
|
ESP_RETURN_ON_FALSE(CHIP_NO_ERROR == group_data_provider->SetGroupInfo(fabric_index, group_info), ESP_FAIL, TAG,
|
|
"Failed to set the group info");
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t remove_group(uint16_t group_id)
|
|
{
|
|
if (group_id == chip::kUndefinedGroupId) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex();
|
|
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");
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t show_keysets()
|
|
{
|
|
FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex();
|
|
GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider();
|
|
GroupDataProvider::KeySet keyset;
|
|
|
|
ESP_LOGI(TAG, " +-------------------------------------------------------------------------------------+");
|
|
ESP_LOGI(TAG, " | Available KeySets : |");
|
|
ESP_LOGI(TAG, " +-------------------------------------------------------------------------------------+");
|
|
ESP_LOGI(TAG, " | KeySet Id | Key Policy |");
|
|
|
|
auto iter = group_data_provider->IterateKeySets(fabric_index);
|
|
if (iter) {
|
|
while (iter->Next(keyset)) {
|
|
ESP_LOGI(TAG, " | 0x%-12x %-66s |", keyset.keyset_id,
|
|
(keyset.policy == GroupDataProvider::SecurityPolicy::kCacheAndSync) ? "Cache and Sync"
|
|
: "Trust First");
|
|
}
|
|
iter->Release();
|
|
}
|
|
ESP_LOGI(TAG, " +-------------------------------------------------------------------------------------+");
|
|
return ESP_OK;
|
|
}
|
|
|
|
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();
|
|
GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider();
|
|
|
|
auto iter = group_data_provider->IterateGroupKeys(fabric_index);
|
|
current_count = iter->Count();
|
|
iter->Release();
|
|
|
|
if (CHIP_NO_ERROR !=
|
|
group_data_provider->SetGroupKeyAt(fabric_index, current_count,
|
|
GroupDataProvider::GroupKey(group_id, keyset_id))) {
|
|
ESP_LOGE(TAG, "Failed to bind keyset");
|
|
return ESP_FAIL;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
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();
|
|
GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider();
|
|
|
|
auto iter = group_data_provider->IterateGroupKeys(fabric_index);
|
|
size_t max_count = iter->Count();
|
|
GroupDataProvider::GroupKey group_key;
|
|
while (iter->Next(group_key)) {
|
|
if (group_key.group_id == group_id && group_key.keyset_id == keyset_id) {
|
|
break;
|
|
}
|
|
index++;
|
|
}
|
|
iter->Release();
|
|
ESP_RETURN_ON_FALSE(index < max_count, ESP_ERR_NOT_FOUND, TAG, "Failed to find the group key");
|
|
ESP_RETURN_ON_FALSE(CHIP_NO_ERROR == group_data_provider->RemoveGroupKeyAt(fabric_index, index), ESP_FAIL, TAG,
|
|
"Failed to remove the group key");
|
|
return ESP_OK;
|
|
}
|
|
|
|
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();
|
|
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)) {
|
|
ESP_LOGE(TAG, "Failed to get the compressed fabric_id");
|
|
return ESP_FAIL;
|
|
}
|
|
if (key_policy != 0 && key_policy != 1) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
GroupDataProvider::KeySet keyset(keyset_id, GroupDataProvider::SecurityPolicy(key_policy), 1);
|
|
GroupDataProvider::EpochKey epoch_key;
|
|
epoch_key.start_time = validity_time;
|
|
uint8_t epoch_key_buf[GroupDataProvider::EpochKey::kLengthBytes];
|
|
if (oct_str_to_byte_arr(epoch_key_oct_str, epoch_key_buf) != GroupDataProvider::EpochKey::kLengthBytes) {
|
|
ESP_LOGE(TAG, "The epoch key octstring is wrong");
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
memcpy(epoch_key.key, epoch_key_buf, GroupDataProvider::EpochKey::kLengthBytes);
|
|
memcpy(keyset.epoch_keys, &epoch_key, sizeof(GroupDataProvider::EpochKey));
|
|
if (CHIP_NO_ERROR != group_data_provider->SetKeySet(fabric_index, compressed_fabric_id_span, keyset)) {
|
|
ESP_LOGE(TAG, "Failed to set keyset");
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t remove_keyset(uint16_t keyset_id)
|
|
{
|
|
FabricIndex fabric_index = commissioner::get_device_commissioner()->GetFabricIndex();
|
|
GroupDataProvider *group_data_provider = chip::Credentials::GetGroupDataProvider();
|
|
|
|
size_t index = 0;
|
|
CHIP_ERROR err = CHIP_NO_ERROR;
|
|
auto iter = group_data_provider->IterateGroupKeys(fabric_index);
|
|
GroupDataProvider::GroupKey group_key;
|
|
while (iter->Next(group_key)) {
|
|
if (group_key.keyset_id == keyset_id) {
|
|
err = group_data_provider->RemoveGroupKeyAt(fabric_index, index);
|
|
if (err != CHIP_NO_ERROR) {
|
|
break;
|
|
}
|
|
}
|
|
index++;
|
|
}
|
|
iter->Release();
|
|
|
|
if (err == CHIP_NO_ERROR) {
|
|
return ESP_OK;
|
|
}
|
|
ESP_RETURN_ON_FALSE(CHIP_NO_ERROR == group_data_provider->RemoveKeySet(fabric_index, keyset_id), ESP_FAIL, TAG,
|
|
"Failed to remove the keyset");
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
} // namespace group_settings
|
|
} // namespace controller
|
|
} // namespace esp_matter
|