Skip to content

Commit b9832a2

Browse files
Fix --commissioner-nodeid handling in interactive mode. (#22496)
1. Instead of keying commissioners by just name in chip-tool, key them by the (name, commissioner-node-id) pair. 2. Allow multiple commissioners for the same fabric (as long as they have different node ids). Fixes project-chip/connectedhomeip#22454
1 parent 152a1f1 commit b9832a2

File tree

3 files changed

+70
-22
lines changed

3 files changed

+70
-22
lines changed

examples/chip-tool/commands/common/CHIPCommand.cpp

+46-17
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include "TraceHandlers.h"
3232
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
3333

34-
std::map<std::string, std::unique_ptr<chip::Controller::DeviceCommissioner>> CHIPCommand::mCommissioners;
34+
std::map<CHIPCommand::CommissionerIdentity, std::unique_ptr<chip::Controller::DeviceCommissioner>> CHIPCommand::mCommissioners;
3535
std::set<CHIPCommand *> CHIPCommand::sDeferredCleanups;
3636

3737
using DeviceControllerFactory = chip::Controller::DeviceControllerFactory;
@@ -125,7 +125,8 @@ CHIP_ERROR CHIPCommand::MaybeSetUpStack()
125125

126126
ReturnErrorOnFailure(GetAttestationTrustStore(mPaaTrustStorePath.ValueOr(nullptr), &sTrustStore));
127127

128-
ReturnLogErrorOnFailure(InitializeCommissioner(kIdentityNull, kIdentityNullFabricId));
128+
CommissionerIdentity nullIdentity{ kIdentityNull, chip::kUndefinedNodeId };
129+
ReturnLogErrorOnFailure(InitializeCommissioner(nullIdentity, kIdentityNullFabricId));
129130

130131
// After initializing first commissioner, add the additional CD certs once
131132
{
@@ -176,7 +177,10 @@ void CHIPCommand::MaybeTearDownStack()
176177

177178
CHIP_ERROR CHIPCommand::EnsureCommissionerForIdentity(std::string identity)
178179
{
179-
if (mCommissioners.find(identity) != mCommissioners.end())
180+
chip::NodeId nodeId;
181+
ReturnErrorOnFailure(GetCommissionerNodeId(identity, &nodeId));
182+
CommissionerIdentity lookupKey{ identity, nodeId };
183+
if (mCommissioners.find(lookupKey) != mCommissioners.end())
180184
{
181185
return CHIP_NO_ERROR;
182186
}
@@ -205,7 +209,7 @@ CHIP_ERROR CHIPCommand::EnsureCommissionerForIdentity(std::string identity)
205209
}
206210
}
207211

208-
return InitializeCommissioner(identity, fabricId);
212+
return InitializeCommissioner(lookupKey, fabricId);
209213
}
210214

211215
CHIP_ERROR CHIPCommand::Run()
@@ -306,6 +310,27 @@ std::string CHIPCommand::GetIdentity()
306310
return name;
307311
}
308312

313+
CHIP_ERROR CHIPCommand::GetCommissionerNodeId(std::string identity, chip::NodeId * nodeId)
314+
{
315+
if (mCommissionerNodeId.HasValue())
316+
{
317+
*nodeId = mCommissionerNodeId.Value();
318+
return CHIP_NO_ERROR;
319+
}
320+
321+
if (identity == kIdentityNull)
322+
{
323+
*nodeId = chip::kUndefinedNodeId;
324+
return CHIP_NO_ERROR;
325+
}
326+
327+
ReturnLogErrorOnFailure(mCommissionerStorage.Init(identity.c_str()));
328+
329+
*nodeId = mCommissionerStorage.GetLocalNodeId();
330+
331+
return CHIP_NO_ERROR;
332+
}
333+
309334
chip::FabricId CHIPCommand::CurrentCommissionerId()
310335
{
311336
chip::FabricId id;
@@ -348,17 +373,20 @@ chip::Controller::DeviceCommissioner & CHIPCommand::GetCommissioner(std::string
348373
// identities.
349374
VerifyOrDie(EnsureCommissionerForIdentity(identity) == CHIP_NO_ERROR);
350375

351-
auto item = mCommissioners.find(identity);
376+
chip::NodeId nodeId;
377+
VerifyOrDie(GetCommissionerNodeId(identity, &nodeId) == CHIP_NO_ERROR);
378+
CommissionerIdentity lookupKey{ identity, nodeId };
379+
auto item = mCommissioners.find(lookupKey);
352380
VerifyOrDie(item != mCommissioners.end());
353381
return *item->second;
354382
}
355383

356-
void CHIPCommand::ShutdownCommissioner(std::string key)
384+
void CHIPCommand::ShutdownCommissioner(const CommissionerIdentity & key)
357385
{
358386
mCommissioners[key].get()->Shutdown();
359387
}
360388

361-
CHIP_ERROR CHIPCommand::InitializeCommissioner(std::string key, chip::FabricId fabricId)
389+
CHIP_ERROR CHIPCommand::InitializeCommissioner(const CommissionerIdentity & identity, chip::FabricId fabricId)
362390
{
363391
chip::Platform::ScopedMemoryBuffer<uint8_t> noc;
364392
chip::Platform::ScopedMemoryBuffer<uint8_t> icac;
@@ -381,7 +409,7 @@ CHIP_ERROR CHIPCommand::InitializeCommissioner(std::string key, chip::FabricId f
381409
// TODO - OpCreds should only be generated for pairing command
382410
// store the credentials in persistent storage, and
383411
// generate when not available in the storage.
384-
ReturnLogErrorOnFailure(mCommissionerStorage.Init(key.c_str()));
412+
ReturnLogErrorOnFailure(mCommissionerStorage.Init(identity.mName.c_str()));
385413
if (mUseMaxSizedCerts.HasValue())
386414
{
387415
auto option = CredentialIssuerCommands::CredentialIssuerOptions::kMaximizeCertificateSizes;
@@ -395,14 +423,15 @@ CHIP_ERROR CHIPCommand::InitializeCommissioner(std::string key, chip::FabricId f
395423
chip::MutableByteSpan rcacSpan(rcac.Get(), chip::Controller::kMaxCHIPDERCertLength);
396424

397425
ReturnLogErrorOnFailure(ephemeralKey.Initialize());
398-
chip::NodeId nodeId = mCommissionerNodeId.ValueOr(mCommissionerStorage.GetLocalNodeId());
399426

400-
ReturnLogErrorOnFailure(mCredIssuerCmds->GenerateControllerNOCChain(
401-
nodeId, fabricId, mCommissionerStorage.GetCommissionerCATs(), ephemeralKey, rcacSpan, icacSpan, nocSpan));
402-
commissionerParams.operationalKeypair = &ephemeralKey;
403-
commissionerParams.controllerRCAC = rcacSpan;
404-
commissionerParams.controllerICAC = icacSpan;
405-
commissionerParams.controllerNOC = nocSpan;
427+
ReturnLogErrorOnFailure(mCredIssuerCmds->GenerateControllerNOCChain(identity.mLocalNodeId, fabricId,
428+
mCommissionerStorage.GetCommissionerCATs(),
429+
ephemeralKey, rcacSpan, icacSpan, nocSpan));
430+
commissionerParams.operationalKeypair = &ephemeralKey;
431+
commissionerParams.controllerRCAC = rcacSpan;
432+
commissionerParams.controllerICAC = icacSpan;
433+
commissionerParams.controllerNOC = nocSpan;
434+
commissionerParams.permitMultiControllerFabrics = true;
406435
}
407436

408437
// TODO: Initialize IPK epoch key in ExampleOperationalCredentials issuer rather than relying on DefaultIpkValue
@@ -411,7 +440,7 @@ CHIP_ERROR CHIPCommand::InitializeCommissioner(std::string key, chip::FabricId f
411440

412441
ReturnLogErrorOnFailure(DeviceControllerFactory::GetInstance().SetupCommissioner(commissionerParams, *(commissioner.get())));
413442

414-
if (key != kIdentityNull)
443+
if (identity.mName != kIdentityNull)
415444
{
416445
// Initialize Group Data, including IPK
417446
chip::FabricIndex fabricIndex = commissioner->GetFabricIndex();
@@ -428,7 +457,7 @@ CHIP_ERROR CHIPCommand::InitializeCommissioner(std::string key, chip::FabricId f
428457
chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, fabricIndex, defaultIpk, compressed_fabric_id_span));
429458
}
430459

431-
mCommissioners[key] = std::move(commissioner);
460+
mCommissioners[identity] = std::move(commissioner);
432461

433462
return CHIP_NO_ERROR;
434463
}

examples/chip-tool/commands/common/CHIPCommand.h

+21-3
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class CHIPCommand : public Command
128128

129129
#ifdef CONFIG_USE_LOCAL_STORAGE
130130
PersistentStorage mDefaultStorage;
131+
// TODO: It's pretty weird that we re-init mCommissionerStorage for every
132+
// identity without shutting it down or something in between...
131133
PersistentStorage mCommissionerStorage;
132134
#endif // CONFIG_USE_LOCAL_STORAGE
133135
chip::PersistentStorageOperationalKeystore mOperationalKeystore;
@@ -137,6 +139,7 @@ class CHIPCommand : public Command
137139
CredentialIssuerCommands * mCredIssuerCmds;
138140

139141
std::string GetIdentity();
142+
CHIP_ERROR GetCommissionerNodeId(std::string identity, chip::NodeId * nodeId);
140143
void SetIdentity(const char * name);
141144

142145
// This method returns the commissioner instance to be used for running the command.
@@ -152,10 +155,25 @@ class CHIPCommand : public Command
152155

153156
CHIP_ERROR EnsureCommissionerForIdentity(std::string identity);
154157

155-
CHIP_ERROR InitializeCommissioner(std::string key, chip::FabricId fabricId);
156-
void ShutdownCommissioner(std::string key);
158+
// Commissioners are keyed by name and local node id.
159+
struct CommissionerIdentity
160+
{
161+
bool operator<(const CommissionerIdentity & other) const
162+
{
163+
return mName < other.mName || (mName == other.mName && mLocalNodeId < other.mLocalNodeId);
164+
}
165+
std::string mName;
166+
chip::NodeId mLocalNodeId;
167+
};
168+
169+
// InitializeCommissioner uses various members, so can't be static. This is
170+
// obviously a little odd, since the commissioners are then shared across
171+
// multiple commands in interactive mode...
172+
CHIP_ERROR InitializeCommissioner(const CommissionerIdentity & identity, chip::FabricId fabricId);
173+
void ShutdownCommissioner(const CommissionerIdentity & key);
157174
chip::FabricId CurrentCommissionerId();
158-
static std::map<std::string, std::unique_ptr<ChipDeviceCommissioner>> mCommissioners;
175+
176+
static std::map<CommissionerIdentity, std::unique_ptr<ChipDeviceCommissioner>> mCommissioners;
159177
static std::set<CHIPCommand *> sDeferredCleanups;
160178

161179
chip::Optional<char *> mCommissionerName;

examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,13 @@ void CHIPCommand::StopWaiting()
8686

8787
chip::Controller::DeviceCommissioner & CHIPCommand::CurrentCommissioner()
8888
{
89-
auto item = mCommissioners.find(GetIdentity());
89+
CommissionerIdentity identity{ GetIdentity(), chip::kUndefinedNodeId };
90+
auto item = mCommissioners.find(identity);
9091
return *item->second;
9192
}
9293

9394
constexpr chip::FabricId kIdentityOtherFabricId = 4;
94-
std::map<std::string, std::unique_ptr<chip::Controller::DeviceCommissioner>> CHIPCommand::mCommissioners;
95+
std::map<CHIPCommand::CommissionerIdentity, std::unique_ptr<chip::Controller::DeviceCommissioner>> CHIPCommand::mCommissioners;
9596

9697
std::string CHIPCommand::GetIdentity()
9798
{

0 commit comments

Comments
 (0)