From 390559230fb0d3628ef0a58cea3b536767dc1a36 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Tue, 9 Nov 2021 18:47:26 +0100 Subject: [PATCH] [chip-tool] Add configure-fabric into the pairing module so chip-tool can pair multiple times to the same accessory (#11559) --- examples/chip-tool/BUILD.gn | 2 + .../chip-tool/commands/common/CHIPCommand.cpp | 4 +- .../chip-tool/commands/pairing/Commands.h | 2 + .../pairing/ConfigureFabricCommand.cpp | 25 ++++++++++ .../commands/pairing/ConfigureFabricCommand.h | 33 ++++++++++++ .../chip-tool/config/PersistentStorage.cpp | 50 ++++++++++++++++++- examples/chip-tool/config/PersistentStorage.h | 19 +++++++ src/controller/CHIPDeviceController.cpp | 4 +- 8 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 examples/chip-tool/commands/pairing/ConfigureFabricCommand.cpp create mode 100644 examples/chip-tool/commands/pairing/ConfigureFabricCommand.h diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index a396695715b774..67551c0617e951 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -38,6 +38,8 @@ executable("chip-tool") { # TODO - enable CommissionedListCommand once DNS Cache is implemented # "commands/pairing/CommissionedListCommand.cpp", # "commands/pairing/CommissionedListCommand.h", + "commands/pairing/ConfigureFabricCommand.cpp", + "commands/pairing/ConfigureFabricCommand.h", "commands/pairing/PairingCommand.cpp", "commands/payload/AdditionalDataParseCommand.cpp", "commands/payload/SetupPayloadParseCommand.cpp", diff --git a/examples/chip-tool/commands/common/CHIPCommand.cpp b/examples/chip-tool/commands/common/CHIPCommand.cpp index 6d70fc68d8016e..c36b7786c9cd2f 100644 --- a/examples/chip-tool/commands/common/CHIPCommand.cpp +++ b/examples/chip-tool/commands/common/CHIPCommand.cpp @@ -61,8 +61,8 @@ CHIP_ERROR CHIPCommand::Run() // TODO - OpCreds should only be generated for pairing command // store the credentials in persistent storage, and // generate when not available in the storage. - ReturnLogErrorOnFailure(mOpCredsIssuer.GenerateNOCChainAfterValidation(mStorage.GetLocalNodeId(), 0, ephemeralKey.Pubkey(), - rcacSpan, icacSpan, nocSpan)); + ReturnLogErrorOnFailure(mOpCredsIssuer.GenerateNOCChainAfterValidation(mStorage.GetLocalNodeId(), mStorage.GetFabricId(), + ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan)); chip::Controller::FactoryInitParams factoryInitParams; factoryInitParams.fabricStorage = &mFabricStorage; diff --git a/examples/chip-tool/commands/pairing/Commands.h b/examples/chip-tool/commands/pairing/Commands.h index 8b3dc38b241314..696171e06fa2d3 100644 --- a/examples/chip-tool/commands/pairing/Commands.h +++ b/examples/chip-tool/commands/pairing/Commands.h @@ -19,6 +19,7 @@ #pragma once #include "CommissionedListCommand.h" +#include "ConfigureFabricCommand.h" #include "PairingCommand.h" class Unpair : public PairingCommand @@ -172,6 +173,7 @@ void registerCommandsPairing(Commands & commands) make_unique(), // TODO - enable CommissionedListCommand once DNS Cache is implemented // make_unique(), + make_unique(), }; commands.Register(clusterName, clusterCommands); diff --git a/examples/chip-tool/commands/pairing/ConfigureFabricCommand.cpp b/examples/chip-tool/commands/pairing/ConfigureFabricCommand.cpp new file mode 100644 index 00000000000000..cf486f802d41ca --- /dev/null +++ b/examples/chip-tool/commands/pairing/ConfigureFabricCommand.cpp @@ -0,0 +1,25 @@ +/* + * 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 "ConfigureFabricCommand.h" + +CHIP_ERROR ConfigureFabricCommand::Run() +{ + ReturnLogErrorOnFailure(mStorage.Init()); + return mStorage.SetFabric(mFabricName); +} diff --git a/examples/chip-tool/commands/pairing/ConfigureFabricCommand.h b/examples/chip-tool/commands/pairing/ConfigureFabricCommand.h new file mode 100644 index 00000000000000..043b2bddcc08fa --- /dev/null +++ b/examples/chip-tool/commands/pairing/ConfigureFabricCommand.h @@ -0,0 +1,33 @@ +/* + * 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 ConfigureFabricCommand : public Command +{ +public: + ConfigureFabricCommand() : Command("configure-fabric") { AddArgument("name", &mFabricName); } + CHIP_ERROR Run() override; + +private: + PersistentStorage mStorage; + char * mFabricName; +}; diff --git a/examples/chip-tool/config/PersistentStorage.cpp b/examples/chip-tool/config/PersistentStorage.cpp index 8eff627554f626..6fdde413fbab61 100644 --- a/examples/chip-tool/config/PersistentStorage.cpp +++ b/examples/chip-tool/config/PersistentStorage.cpp @@ -37,6 +37,10 @@ constexpr const char kDefaultSectionName[] = "Default"; constexpr const char kPortKey[] = "ListenPort"; constexpr const char kLoggingKey[] = "LoggingLevel"; constexpr const char kLocalNodeIdKey[] = "LocalNodeId"; +constexpr const char kFabricIdKey[] = "LocalFabricId"; +constexpr const FabricId kFabricAlpha = 1; +constexpr const FabricId kFabricBeta = 2; +constexpr const FabricId kFabricGamma = 3; constexpr LogCategory kDefaultLoggingLevel = kLogCategory_Detail; namespace { @@ -156,9 +160,11 @@ CHIP_ERROR PersistentStorage::CommitConfig() uint16_t PersistentStorage::GetListenPort() { CHIP_ERROR err = CHIP_NO_ERROR; - // By default chip-tool listens on CHIP_PORT + 1. This is done in order to avoid + + // By default chip-tool listens on CHIP_PORT + N. This is done in order to avoid // having 2 servers listening on CHIP_PORT when one runs an accessory server locally. - uint16_t chipListenPort = CHIP_PORT + 1; + FabricId N = GetFabricId(); + uint16_t chipListenPort = static_cast(CHIP_PORT + N); char value[6]; uint16_t size = static_cast(sizeof(value)); @@ -228,3 +234,43 @@ CHIP_ERROR PersistentStorage::SetLocalNodeId(NodeId value) uint64_t nodeId = Encoding::LittleEndian::HostSwap64(value); return SyncSetKeyValue(kLocalNodeIdKey, &nodeId, sizeof(nodeId)); } + +FabricId PersistentStorage::GetFabricId() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + uint64_t fabricId; + uint16_t size = static_cast(sizeof(fabricId)); + err = SyncGetKeyValue(kFabricIdKey, &fabricId, size); + if (err == CHIP_NO_ERROR) + { + return static_cast(Encoding::LittleEndian::HostSwap64(fabricId)); + } + + return kFabricAlpha; +} + +CHIP_ERROR PersistentStorage::SetFabric(const char * fabricName) +{ + uint64_t fabricId = kFabricAlpha; + + if (strcasecmp(fabricName, "alpha") == 0) + { + fabricId = kFabricAlpha; + } + else if (strcasecmp(fabricName, "beta") == 0) + { + fabricId = kFabricBeta; + } + else if (strcasecmp(fabricName, "gamma") == 0) + { + fabricId = kFabricGamma; + } + else + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + fabricId = Encoding::LittleEndian::HostSwap64(fabricId); + return SyncSetKeyValue(kFabricIdKey, &fabricId, sizeof(fabricId)); +} diff --git a/examples/chip-tool/config/PersistentStorage.h b/examples/chip-tool/config/PersistentStorage.h index c2832a3c407e29..10f4bb1ad76d5d 100644 --- a/examples/chip-tool/config/PersistentStorage.h +++ b/examples/chip-tool/config/PersistentStorage.h @@ -42,6 +42,25 @@ class PersistentStorage : public chip::PersistentStorageDelegate // Store local node id. CHIP_ERROR SetLocalNodeId(chip::NodeId nodeId); + /** + * @brief + * Configure the fabric used for pairing and sending commands. + * + * @param[in] fabricName The name of the fabric. It must be one of the following strings: + * - alpha + * - beta + * - gamma + * + * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. + */ + CHIP_ERROR SetFabric(const char * fabricName); + + /** + * @brief + * Return the stored fabric id, or the one for the "alpha" fabric if nothing is stored. + */ + chip::FabricId GetFabricId(); + private: CHIP_ERROR CommitConfig(); inipp::Ini mConfig; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index fad37bdd3fccb8..f2a187445d349e 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1341,7 +1341,9 @@ CHIP_ERROR DeviceCommissioner::ProcessOpCSR(const ByteSpan & NOCSRElements, cons ChipLogProgress(Controller, "Getting certificate chain for the device from the issuer"); mOperationalCredentialsDelegate->SetNodeIdForNextNOCRequest(device->GetDeviceId()); - mOperationalCredentialsDelegate->SetFabricIdForNextNOCRequest(0); + + FabricInfo * fabric = mSystemState->Fabrics()->FindFabricWithIndex(mFabricIndex); + mOperationalCredentialsDelegate->SetFabricIdForNextNOCRequest(fabric->GetFabricId()); return mOperationalCredentialsDelegate->GenerateNOCChain(NOCSRElements, AttestationSignature, ByteSpan(), ByteSpan(), ByteSpan(), &mDeviceNOCChainCallback);