Skip to content

Commit

Permalink
Cleanup OperationalCredentials if the fail-safe timer expires (#16212)
Browse files Browse the repository at this point in the history
* Cleanup OperationalCredentials if the fail-safe timer expires

* Address review comments

* Capture failSafeContext in CommissioningFailedTimerComplete event

* Clear things out from the CASESessionManager
  • Loading branch information
yufengwangca authored Mar 18, 2022
1 parent fea74e6 commit 472c351
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,57 @@ FabricInfo * RetrieveCurrentFabric(CommandHandler * aCommandHandler)
return Server::GetInstance().GetFabricTable().FindFabricWithIndex(index);
}

void FailSafeCleanup(const chip::DeviceLayer::ChipDeviceEvent * event)
{
emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Call to FailSafeCleanup");

FabricIndex fabricIndex = event->CommissioningComplete.PeerFabricIndex;

// If an AddNOC or UpdateNOC command has been successfully invoked, terminate all CASE sessions associated with the Fabric
// whose Fabric Index is recorded in the Fail-Safe context (see ArmFailSafe Command) by clearing any associated Secure
// Session Context at the Server.
if (event->CommissioningComplete.AddNocCommandHasBeenInvoked || event->CommissioningComplete.UpdateNocCommandHasBeenInvoked)
{
CASESessionManager * caseSessionManager = Server::GetInstance().GetCASESessionManager();
if (caseSessionManager)
{
FabricInfo * fabricInfo = Server::GetInstance().GetFabricTable().FindFabricWithIndex(fabricIndex);
VerifyOrReturn(fabricInfo != nullptr);

caseSessionManager->ReleaseSessionsForFabric(fabricInfo->GetCompressedId());
}

Server::GetInstance().GetSecureSessionManager().ExpireAllPairingsForFabric(fabricIndex);
}

// If an AddNOC command had been successfully invoked, achieve the equivalent effect of invoking the RemoveFabric command
// against the Fabric Index stored in the Fail-Safe Context for the Fabric Index that was the subject of the AddNOC
// command.
if (event->CommissioningComplete.AddNocCommandHasBeenInvoked)
{
Server::GetInstance().GetFabricTable().Delete(fabricIndex);
}

// If an UpdateNOC command had been successfully invoked, revert the state of operational key pair, NOC and ICAC for that
// Fabric to the state prior to the Fail-Safe timer being armed, for the Fabric Index that was the subject of the UpdateNOC
// command.
if (event->CommissioningComplete.UpdateNocCommandHasBeenInvoked)
{
// TODO: Revert the state of operational key pair, NOC and ICAC
}
}

void OnPlatformEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
if (event->Type == DeviceLayer::DeviceEventType::kCommissioningComplete)
{
if (event->CommissioningComplete.Status != CHIP_NO_ERROR)
{
FailSafeCleanup(event);
}
}
}

} // anonymous namespace

// As per specifications section 11.22.5.1. Constant RESP_MAX
Expand Down Expand Up @@ -341,6 +392,8 @@ void MatterOperationalCredentialsPluginServerInitCallback(void)
registerAttributeAccessOverride(&gAttrAccess);

Server::GetInstance().GetFabricTable().AddFabricDelegate(&gFabricDelegate);

DeviceLayer::PlatformMgrImpl().AddEventHandler(OnPlatformEventHandler);
}

namespace {
Expand Down Expand Up @@ -599,7 +652,7 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(app::CommandHandler * co

// The Fabric Index associated with the armed fail-safe context SHALL be updated to match the Fabric
// Index just allocated.
failSafeContext.SetNocCommandInvoked(fabricIndex);
failSafeContext.SetAddNocCommandInvoked(fabricIndex);

exit:

Expand Down Expand Up @@ -666,7 +719,7 @@ bool emberAfOperationalCredentialsClusterUpdateNOCCallback(app::CommandHandler *

// The Fabric Index associated with the armed fail-safe context SHALL be updated to match the Fabric
// Index associated with the UpdateNOC command being invoked.
failSafeContext.SetNocCommandInvoked(fabricIndex);
failSafeContext.SetUpdateNocCommandInvoked(fabricIndex);

exit:

Expand Down
2 changes: 2 additions & 0 deletions src/include/platform/CHIPDeviceEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ struct ChipDeviceEvent final
CHIP_ERROR Status;
uint64_t PeerNodeId;
FabricIndex PeerFabricIndex;
bool AddNocCommandHasBeenInvoked;
bool UpdateNocCommandHasBeenInvoked;
} CommissioningComplete;

struct
Expand Down
23 changes: 16 additions & 7 deletions src/include/platform/FailSafeContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,20 @@ class FailSafeContext
return (accessingFabricIndex == mFabricIndex);
}

inline bool NocCommandHasBeenInvoked() const { return mNocCommandHasBeenInvoked; }
inline bool NocCommandHasBeenInvoked() const { return mAddNocCommandHasBeenInvoked || mUpdateNocCommandHasBeenInvoked; }
inline bool AddNocCommandHasBeenInvoked() { return mAddNocCommandHasBeenInvoked; }
inline bool UpdateNocCommandHasBeenInvoked() { return mUpdateNocCommandHasBeenInvoked; }

inline void SetNocCommandInvoked(FabricIndex nocFabricIndex)
inline void SetAddNocCommandInvoked(FabricIndex nocFabricIndex)
{
mNocCommandHasBeenInvoked = true;
mFabricIndex = nocFabricIndex;
mAddNocCommandHasBeenInvoked = true;
mFabricIndex = nocFabricIndex;
}

inline void SetUpdateNocCommandInvoked(FabricIndex nocFabricIndex)
{
mUpdateNocCommandHasBeenInvoked = true;
mFabricIndex = nocFabricIndex;
}

inline FabricIndex GetFabricIndex() const
Expand All @@ -72,9 +80,10 @@ class FailSafeContext
private:
// ===== Private members reserved for use by this class only.

bool mFailSafeArmed = false;
bool mNocCommandHasBeenInvoked = false;
FabricIndex mFabricIndex = kUndefinedFabricIndex;
bool mFailSafeArmed = false;
bool mAddNocCommandHasBeenInvoked = false;
bool mUpdateNocCommandHasBeenInvoked = false;
FabricIndex mFabricIndex = kUndefinedFabricIndex;

// TODO:: Track the state of what was mutated during fail-safe.

Expand Down
13 changes: 9 additions & 4 deletions src/platform/DeviceControlServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,16 @@ DeviceControlServer & DeviceControlServer::DeviceControlSvr()
CHIP_ERROR DeviceControlServer::CommissioningComplete(NodeId peerNodeId, FabricIndex accessingFabricIndex)
{
VerifyOrReturnError(CHIP_NO_ERROR == mFailSafeContext.DisarmFailSafe(), CHIP_ERROR_INTERNAL);

ChipDeviceEvent event;
event.Type = DeviceEventType::kCommissioningComplete;
event.CommissioningComplete.PeerNodeId = peerNodeId;
event.CommissioningComplete.PeerFabricIndex = accessingFabricIndex;
event.CommissioningComplete.Status = CHIP_NO_ERROR;

event.Type = DeviceEventType::kCommissioningComplete;
event.CommissioningComplete.PeerNodeId = peerNodeId;
event.CommissioningComplete.PeerFabricIndex = accessingFabricIndex;
event.CommissioningComplete.AddNocCommandHasBeenInvoked = mFailSafeContext.AddNocCommandHasBeenInvoked();
event.CommissioningComplete.UpdateNocCommandHasBeenInvoked = mFailSafeContext.UpdateNocCommandHasBeenInvoked();
event.CommissioningComplete.Status = CHIP_NO_ERROR;

return PlatformMgr().PostEvent(&event);
}

Expand Down
22 changes: 12 additions & 10 deletions src/platform/FailSafeContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,17 @@ void FailSafeContext::HandleArmFailSafe(System::Layer * layer, void * aAppState)

void FailSafeContext::CommissioningFailedTimerComplete()
{
// TODO: If the fail-safe timer expires before the CommissioningComplete command is
// successfully invoked, conduct clean-up steps.

ChipDeviceEvent event;
event.Type = DeviceEventType::kCommissioningComplete;
event.CommissioningComplete.Status = CHIP_ERROR_TIMEOUT;
CHIP_ERROR status = PlatformMgr().PostEvent(&event);
event.Type = DeviceEventType::kCommissioningComplete;
event.CommissioningComplete.PeerFabricIndex = mFabricIndex;
event.CommissioningComplete.AddNocCommandHasBeenInvoked = mAddNocCommandHasBeenInvoked;
event.CommissioningComplete.UpdateNocCommandHasBeenInvoked = mUpdateNocCommandHasBeenInvoked;
event.CommissioningComplete.Status = CHIP_ERROR_TIMEOUT;
CHIP_ERROR status = PlatformMgr().PostEvent(&event);

mFailSafeArmed = false;
mNocCommandHasBeenInvoked = false;
mFailSafeArmed = false;
mAddNocCommandHasBeenInvoked = false;
mUpdateNocCommandHasBeenInvoked = false;

if (status != CHIP_NO_ERROR)
{
Expand All @@ -62,8 +63,9 @@ CHIP_ERROR FailSafeContext::ArmFailSafe(FabricIndex accessingFabricIndex, System

CHIP_ERROR FailSafeContext::DisarmFailSafe()
{
mFailSafeArmed = false;
mNocCommandHasBeenInvoked = false;
mFailSafeArmed = false;
mAddNocCommandHasBeenInvoked = false;
mUpdateNocCommandHasBeenInvoked = false;
DeviceLayer::SystemLayer().CancelTimer(HandleArmFailSafe, this);
return CHIP_NO_ERROR;
}
Expand Down

0 comments on commit 472c351

Please sign in to comment.