Skip to content

Commit

Permalink
Better handling for the multiple fabric tables live during controller…
Browse files Browse the repository at this point in the history
… startup. (#19578)

We should be using fabric indices with the right fabric table, not
assuming they have matching fabric indices.
  • Loading branch information
bzbarsky-apple authored Jun 14, 2022
1 parent 104d1c4 commit 1a2c719
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
26 changes: 14 additions & 12 deletions src/darwin/Framework/CHIP/CHIPDeviceController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,9 @@ @implementation CHIPDeviceController (InternalMethods)
return fabricIdx;
}

- (CHIP_ERROR)isRunningOnFabric:(chip::FabricInfo *)fabric isRunning:(BOOL *)isRunning
- (CHIP_ERROR)isRunningOnFabric:(chip::FabricTable *)fabricTable
fabricIndex:(chip::FabricIndex)fabricIndex
isRunning:(BOOL *)isRunning
{
if (![self isRunning]) {
*isRunning = NO;
Expand All @@ -743,26 +745,26 @@ - (CHIP_ERROR)isRunningOnFabric:(chip::FabricInfo *)fabric isRunning:(BOOL *)isR
return CHIP_ERROR_INCORRECT_STATE;
}

if (ourFabric->GetFabricId() != fabric->GetFabricId()) {
chip::FabricInfo * otherFabric = fabricTable->FindFabricWithIndex(fabricIndex);
if (!otherFabric) {
// Also surprising!
return CHIP_ERROR_INCORRECT_STATE;
}

if (ourFabric->GetFabricId() != otherFabric->GetFabricId()) {
*isRunning = NO;
return CHIP_NO_ERROR;
}

// "fabric" comes from a different fabric table for the moment, but it's a
// fabric table that is: (1) readonly, (2) has stack lifetime, and (3) uses
// the same storage as _cppCommissioner->GetFabricTable(), so it turns out
// that in practice they have the same fabric indices and this logic is OK.
//
// TODO: stop relying on that.
const chip::FabricTable * fabricTable = _cppCommissioner->GetFabricTable();
if (!fabricTable) {
const chip::FabricTable * ourFabricTable = _cppCommissioner->GetFabricTable();
if (!ourFabricTable) {
// Surprising as well!
return CHIP_ERROR_INCORRECT_STATE;
}

chip::Crypto::P256PublicKey ourRootPublicKey, otherRootPublicKey;
ReturnErrorOnFailure(fabricTable->FetchRootPubkey(ourFabric->GetFabricIndex(), ourRootPublicKey));
ReturnErrorOnFailure(fabricTable->FetchRootPubkey(fabric->GetFabricIndex(), otherRootPublicKey));
ReturnErrorOnFailure(ourFabricTable->FetchRootPubkey(ourFabric->GetFabricIndex(), ourRootPublicKey));
ReturnErrorOnFailure(fabricTable->FetchRootPubkey(otherFabric->GetFabricIndex(), otherRootPublicKey));

*isRunning = (ourRootPublicKey.Matches(otherRootPublicKey));
return CHIP_NO_ERROR;
Expand Down
13 changes: 8 additions & 5 deletions src/darwin/Framework/CHIP/CHIPDeviceController_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
@class MatterControllerFactory;

namespace chip {
class FabricInfo;
class FabricTable;
} // namespace chip

NS_ASSUME_NONNULL_BEGIN
Expand Down Expand Up @@ -66,16 +66,19 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithFactory:(MatterControllerFactory *)factory queue:(dispatch_queue_t)queue;

/**
* Check whether this controller is running on the given fabric. The FabricInfo
* might be from a one-off fabric table. This method MUST be called from the
* Matter work queue.
* Check whether this controller is running on the given fabric, as represented
* by the provided FabricTable and fabric index. The provided fabric table may
* not be the same as the fabric table this controller is using. This method
* MUST be called from the Matter work queue.
*
* Might return failure, in which case we don't know whether it's running on the
* given fabric. Otherwise it will set *isRunning to the right boolean value.
*
* Only MatterControllerFactory should be calling this.
*/
- (CHIP_ERROR)isRunningOnFabric:(chip::FabricInfo *)fabric isRunning:(BOOL *)isRunning;
- (CHIP_ERROR)isRunningOnFabric:(chip::FabricTable *)fabricTable
fabricIndex:(chip::FabricIndex)fabricIndex
isRunning:(BOOL *)isRunning;

@end

Expand Down
3 changes: 2 additions & 1 deletion src/darwin/Framework/CHIP/MatterControllerFactory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ - (CHIPDeviceController * _Nullable)startControllerOnExistingFabric:(CHIPDeviceC

for (CHIPDeviceController * existing in _controllers) {
BOOL isRunning = YES; // assume the worst
if ([existing isRunningOnFabric:fabric isRunning:&isRunning] != CHIP_NO_ERROR) {
if ([existing isRunningOnFabric:&fabricTable fabricIndex:fabric->GetFabricIndex() isRunning:&isRunning]
!= CHIP_NO_ERROR) {
CHIP_LOG_ERROR("Can't tell what fabric a controller is running on. Not safe to start.");
return;
}
Expand Down

0 comments on commit 1a2c719

Please sign in to comment.