Skip to content

Commit

Permalink
[chip-tool] Add configure-fabric into the pairing module so chip-tool…
Browse files Browse the repository at this point in the history
… can pair multiple times to the same accessory (#11559)
  • Loading branch information
vivien-apple authored and pull[bot] committed Feb 24, 2023
1 parent 436a095 commit 1044032
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 5 deletions.
2 changes: 2 additions & 0 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions examples/chip-tool/commands/common/CHIPCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions examples/chip-tool/commands/pairing/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include "CommissionedListCommand.h"
#include "ConfigureFabricCommand.h"
#include "PairingCommand.h"

class Unpair : public PairingCommand
Expand Down Expand Up @@ -172,6 +173,7 @@ void registerCommandsPairing(Commands & commands)
make_unique<OpenCommissioningWindow>(),
// TODO - enable CommissionedListCommand once DNS Cache is implemented
// make_unique<CommissionedListCommand>(),
make_unique<ConfigureFabricCommand>(),
};

commands.Register(clusterName, clusterCommands);
Expand Down
25 changes: 25 additions & 0 deletions examples/chip-tool/commands/pairing/ConfigureFabricCommand.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
33 changes: 33 additions & 0 deletions examples/chip-tool/commands/pairing/ConfigureFabricCommand.h
Original file line number Diff line number Diff line change
@@ -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;
};
50 changes: 48 additions & 2 deletions examples/chip-tool/config/PersistentStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<uint16_t>(CHIP_PORT + N);

char value[6];
uint16_t size = static_cast<uint16_t>(sizeof(value));
Expand Down Expand Up @@ -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<uint16_t>(sizeof(fabricId));
err = SyncGetKeyValue(kFabricIdKey, &fabricId, size);
if (err == CHIP_NO_ERROR)
{
return static_cast<FabricId>(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));
}
19 changes: 19 additions & 0 deletions examples/chip-tool/config/PersistentStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<char> mConfig;
Expand Down
4 changes: 3 additions & 1 deletion src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 1044032

Please sign in to comment.