Skip to content

Commit

Permalink
Complete the idea
Browse files Browse the repository at this point in the history
  • Loading branch information
kghost committed Jun 9, 2022
1 parent 2f2fb5f commit bc4a550
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/messaging/ExchangeContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,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
9 changes: 6 additions & 3 deletions src/messaging/ExchangeMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,15 @@ void ExchangeManager::CloseAllContextsForDelegate(const ExchangeDelegate * deleg
});
}

void ExchangeManager::AbortExchangeForNodeExceptOne(const ScopedNodeId & node, ExchangeContext * stay)
void ExchangeManager::AbortExchangeForNodeExceptOne(const ScopedNodeId & node, ExchangeContext * exception)
{
mContextPool.ForEachActiveObject([&](auto * ec) {
if (ec != stay && ec->HasSessionHandle() && ec->GetSessionHandle()->GetPeer() == node)
if (ec->HasSessionHandle() && ec->GetSessionHandle()->GetPeer() == node)
{
ec->Abort();
if (ec == exception)
ec->SetAutoReleaseSession();
else
ec->Abort();
}
return Loop::Continue;
});
Expand Down
17 changes: 17 additions & 0 deletions src/messaging/ReliableMessageContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ class ReliableMessageContext
/// Determine whether this exchange is requesting Sleepy End Device active mode
bool IsRequestingActiveMode() 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 @@ -158,6 +162,9 @@ class ReliableMessageContext

/// When set, signifies that the exchange is requesting Sleepy End Device active mode.
kFlagActiveMode = (1u << 8),

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

BitFlags<Flags> mFlags; // Internal state flags
Expand Down Expand Up @@ -234,5 +241,15 @@ inline void ReliableMessageContext::SetRequestingActiveMode(bool activeMode)
mFlags.Set(Flags::kFlagActiveMode, activeMode);
}

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
9 changes: 6 additions & 3 deletions src/transport/SessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,12 +387,15 @@ void SessionManager::ExpireAllPASEPairings()
});
}

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

0 comments on commit bc4a550

Please sign in to comment.