Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restyle Add API to invalid sessions/exchanges for UpdateNOC command #19567

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/messaging/ExchangeContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ ExchangeContext::~ExchangeContext()
VerifyOrDie(mExchangeMgr != nullptr && GetReferenceCount() == 0);
VerifyOrDie(!IsAckPending());

if (IsAutoReleaseSession() && mSession)
mSession->AsSecureSession()->MarkForRemoval();

#if CONFIG_DEVICE_LAYER && CHIP_DEVICE_CONFIG_ENABLE_SED
// Make sure that the exchange withdraws the request for Sleepy End Device active mode.
UpdateSEDIntervalMode(false);
Expand Down
14 changes: 14 additions & 0 deletions src/messaging/ExchangeMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,5 +376,19 @@ void ExchangeManager::CloseAllContextsForDelegate(const ExchangeDelegate * deleg
});
}

void ExchangeManager::AbortExchangesForFabricExceptOne(FabricIndex fabricIndex, ExchangeContext * deferred)
{
mContextPool.ForEachActiveObject([&](auto * ec) {
if (ec->HasSessionHandle() && ec->GetSessionHandle()->GetPeer().GetFabricIndex() == fabricIndex)
{
if (ec == deferred)
ec->SetAutoReleaseSession();
else
ec->Abort();
}
return Loop::Continue;
});
}

} // namespace Messaging
} // namespace chip
4 changes: 4 additions & 0 deletions src/messaging/ExchangeMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ class DLL_EXPORT ExchangeManager : public SessionMessageDelegate
*/
void CloseAllContextsForDelegate(const ExchangeDelegate * delegate);

// This API is used by UpdateNOC command, to abort all exchanges except the given one, whose abort is deferred until UpdateNOC
// command finishing its work.
void AbortExchangesForFabricExceptOne(FabricIndex fabricIndex, ExchangeContext * deferred);

SessionManager * GetSessionManager() const { return mSessionManager; }

ReliableMessageMgr * GetReliableMessageMgr() { return &mReliableMessageMgr; };
Expand Down
17 changes: 17 additions & 0 deletions src/messaging/ReliableMessageContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ class ReliableMessageContext
/// Determine whether this exchange is a EphemeralExchange for replying a StandaloneAck
bool IsEphemeralExchange() const;

// For UpdateNOC command, I'm the last exchange, I must release the session when finishing my work.
void SetAutoReleaseSession();
bool IsAutoReleaseSession();

/**
* Get the reliable message manager that corresponds to this reliable
* message context.
Expand Down Expand Up @@ -164,6 +168,9 @@ class ReliableMessageContext

/// When set, signifies that the exchange created sorely for replying a StandaloneAck
kFlagEphemeralExchange = (1u << 9),

/// When set, automatically release the session when finishing its work. Used by UpdateNOC command
kFlagAutoReleaseSession = (1u << 10),
};

BitFlags<Flags> mFlags; // Internal state flags
Expand Down Expand Up @@ -245,5 +252,15 @@ inline bool ReliableMessageContext::IsEphemeralExchange() const
return mFlags.Has(Flags::kFlagEphemeralExchange);
}

inline void ReliableMessageContext::SetAutoReleaseSession()
{
mFlags.Set(Flags::kFlagAutoReleaseSession, true);
}

inline bool ReliableMessageContext::IsAutoReleaseSession()
{
return mFlags.Has(Flags::kFlagAutoReleaseSession);
}

} // namespace Messaging
} // namespace chip
22 changes: 22 additions & 0 deletions src/transport/SecureSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void SecureSession::MarkForRemoval()
NotifySessionReleased();
return;
case State::kActive:
case State::kInactive:
Release(); // Decrease the ref which is retained at Activate
mState = State::kPendingRemoval;
NotifySessionReleased();
Expand All @@ -49,6 +50,27 @@ void SecureSession::MarkForRemoval()
}
}

void SecureSession::MarkForInactive()
{
ChipLogDetail(Inet, "SecureSession[%p]: MarkForInactive Type:%d LSID:%d", this, to_underlying(mSecureSessionType),
mLocalSessionId);
ReferenceCountedHandle<Transport::Session> ref(*this);
switch (mState)
{
case State::kPairing:
VerifyOrDie(false);
return;
case State::kActive:
// By setting this state, IsActiveSession() will return false, which prevent creating new exchanges.
mState = State::kInactive;
return;
case State::kInactive:
case State::kPendingRemoval:
// Do nothing
return;
}
}

Access::SubjectDescriptor SecureSession::GetSubjectDescriptor() const
{
Access::SubjectDescriptor subjectDescriptor;
Expand Down
8 changes: 8 additions & 0 deletions src/transport/SecureSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ class SecureSession : public Session, public ReferenceCounted<SecureSession, Sec
/// @brief Mark as pending removal, all holders to this session will be cleared, and disallow future grab
void MarkForRemoval();

// Used by UpdateNOC command to prevent any new exchange created on the session.
void MarkForInactive();

Session::SessionType GetSessionType() const override { return Session::SessionType::kSecure; }
#if CHIP_PROGRESS_LOGGING
const char * GetSessionTypeString() const override { return "secure"; };
Expand Down Expand Up @@ -249,6 +252,11 @@ class SecureSession : public Session, public ReferenceCounted<SecureSession, Sec
// grab this session, when all SessionHandles go out of scope, the
// session object will be released automatically.
kPendingRemoval = 3,

// For UpdateNOC command, the session still functional, but it can't
// yield any new exchanges, the last exchange running UpdateNOC command
// will close the session soon.
kInactive = 4,
};

friend class SecureSessionDeleter;
Expand Down
28 changes: 28 additions & 0 deletions src/transport/SessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,34 @@ void SessionManager::ExpireAllPASEPairings()
});
}

void SessionManager::ReleaseSessionsForFabricExceptOne(FabricIndex fabricIndex, const SessionHandle & deferred)
{
mSecureSessions.ForEachSession([&](auto session) {
if (session->GetPeer().GetFabricIndex() == fabricIndex)
{
if (session == exception->AsSecureSession())
session->MarkForInactive();
else
session->MarkForRemoval();
}
return Loop::Continue;
});
}

void SessionManager::ReleaseSessionForNodeExceptOne(const ScopedNodeId & node, const SessionHandle & exception)
{
mSecureSessions.ForEachSession([&](auto session) {
if (session->GetPeer() == node)
{
if (session == exception->AsSecureSession())
session->MarkForInactive();
else
session->MarkForRemoval();
}
return Loop::Continue;
});
}

Optional<SessionHandle> SessionManager::AllocateSession(SecureSession::Type secureSessionType,
const ScopedNodeId & sessionEvictionHint)
{
Expand Down
4 changes: 4 additions & 0 deletions src/transport/SessionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate
void ExpireAllPairingsForFabric(FabricIndex fabric);
void ExpireAllPASEPairings();

// This API is used by UpdateNOC command, to invalidate all sessions except the given one, whose release is deferred until
// UpdateNOC command finishing its work.
void ReleaseSessionsForFabricExceptOne(FabricIndex fabricIndex, const SessionHandle & deferred);

/**
* @brief
* Return the System Layer pointer used by current SessionManager.
Expand Down