diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index cda02a820a4569..7f5a419fe7dd25 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -34,6 +34,8 @@ executable("chip-tool") { "commands/discover/DiscoverCommand.cpp", "commands/discover/DiscoverCommissionablesCommand.cpp", "commands/discover/DiscoverCommissionersCommand.cpp", + "commands/pairing/CommissionedListCommand.cpp", + "commands/pairing/CommissionedListCommand.h", "commands/pairing/PairingCommand.cpp", "commands/payload/AdditionalDataParseCommand.cpp", "commands/payload/SetupPayloadParseCommand.cpp", diff --git a/examples/chip-tool/commands/pairing/Commands.h b/examples/chip-tool/commands/pairing/Commands.h index 40e11b5380040b..3b7ba676271605 100644 --- a/examples/chip-tool/commands/pairing/Commands.h +++ b/examples/chip-tool/commands/pairing/Commands.h @@ -18,6 +18,7 @@ #pragma once +#include "CommissionedListCommand.h" #include "PairingCommand.h" class Unpair : public PairingCommand @@ -169,6 +170,7 @@ void registerCommandsPairing(Commands & commands) make_unique(), make_unique(), make_unique(), + make_unique(), }; commands.Register(clusterName, clusterCommands); diff --git a/examples/chip-tool/commands/pairing/CommissionedListCommand.cpp b/examples/chip-tool/commands/pairing/CommissionedListCommand.cpp new file mode 100644 index 00000000000000..ed617fc07cf6d9 --- /dev/null +++ b/examples/chip-tool/commands/pairing/CommissionedListCommand.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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 "CommissionedListCommand.h" + +#include +#include +#include +#include + +CHIP_ERROR CommissionedListCommand::Run() +{ + ReturnLogErrorOnFailure(mStorage.Init()); + return PrintInformation(); +} + +CHIP_ERROR CommissionedListCommand::PrintInformation() +{ + uint64_t pairedNodesIds[chip::Controller::kNumMaxPairedDevices]; + uint16_t pairedNodesIdsSize = sizeof(pairedNodesIds); + memset(pairedNodesIds, 0, pairedNodesIdsSize); + + PERSISTENT_KEY_OP(static_cast(0), chip::kPairedDeviceListKeyPrefix, key, + ReturnLogErrorOnFailure(mStorage.SyncGetKeyValue(key, pairedNodesIds, pairedNodesIdsSize))); + + chip::SerializableU64Set devices; + devices.Deserialize(chip::ByteSpan((uint8_t *) pairedNodesIds, pairedNodesIdsSize)); + + uint16_t pairedDevicesCount = 0; + while (pairedNodesIds[pairedDevicesCount] != 0x0 && pairedDevicesCount < chip::Controller::kNumMaxPairedDevices) + { + pairedDevicesCount++; + } + + if (pairedDevicesCount == 0) + { + ChipLogProgress(chipTool, "No paired devices."); + } + else + { + fprintf(stdout, "NOTES: Only the devices locally commissioned with chip-tool are displayed.\n"); + fprintf(stdout, "+---------------------------------------------------------------------------------------------+\n"); + fprintf(stdout, "| NodeId | Address | Port | Interface |\n"); + fprintf(stdout, "+---------------------------------------------------------------------------------------------+\n"); + for (uint16_t i = 0; i < pairedDevicesCount; i++) + { + ReturnLogErrorOnFailure(PrintDeviceInformation(pairedNodesIds[i])); + } + fprintf(stdout, "+---------------------------------------------------------------------------------------------+\n"); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommissionedListCommand::PrintDeviceInformation(chip::NodeId deviceId) +{ + chip::Controller::SerializedDevice deviceInfo; + uint16_t size = sizeof(deviceInfo.inner); + + PERSISTENT_KEY_OP(deviceId, chip::kPairedDeviceKeyPrefix, key, + ReturnLogErrorOnFailure(mStorage.SyncGetKeyValue(key, deviceInfo.inner, size))); + VerifyOrReturnError(size <= sizeof(deviceInfo.inner), CHIP_ERROR_INVALID_DEVICE_DESCRIPTOR); + + chip::Controller::SerializableDevice serializable; + constexpr size_t maxlen = BASE64_ENCODED_LEN(sizeof(serializable)); + const size_t len = strnlen(chip::Uint8::to_const_char(&deviceInfo.inner[0]), maxlen); + + VerifyOrReturnError(len < sizeof(chip::Controller::SerializedDevice), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(chip::CanCastTo(len), CHIP_ERROR_INVALID_ARGUMENT); + + CHIP_ZERO_AT(serializable); + const uint16_t deserializedLen = chip::Base64Decode(chip::Uint8::to_const_char(deviceInfo.inner), static_cast(len), + chip::Uint8::to_uchar(reinterpret_cast(&serializable))); + + VerifyOrReturnError(deserializedLen > 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(deserializedLen <= sizeof(serializable), CHIP_ERROR_INVALID_ARGUMENT); + + const uint16_t port = chip::Encoding::LittleEndian::HostSwap16(serializable.mDevicePort); + fprintf(stderr, "| 0x%-16" PRIx64 " | %-45s | %-5u| %-15s |\n", deviceId, serializable.mDeviceAddr, port, + serializable.mInterfaceName); + + return CHIP_NO_ERROR; +} diff --git a/examples/chip-tool/commands/pairing/CommissionedListCommand.h b/examples/chip-tool/commands/pairing/CommissionedListCommand.h new file mode 100644 index 00000000000000..6d04f93b452f4e --- /dev/null +++ b/examples/chip-tool/commands/pairing/CommissionedListCommand.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ + +#pragma once + +#include "../../config/PersistentStorage.h" +#include "../common/Command.h" + +class CommissionedListCommand : public Command +{ +public: + CommissionedListCommand() : Command("list") {} + CHIP_ERROR Run() override; + +private: + CHIP_ERROR PrintInformation(); + CHIP_ERROR PrintDeviceInformation(chip::NodeId deviceId); + + PersistentStorage mStorage; +};