Skip to content

Commit

Permalink
TCP connection setup/management and CASESession association.
Browse files Browse the repository at this point in the history
Add TCPConnect()/TCPDisconnect() API for explicit connection setup.
Currently, connecting to a peer is coupled with sending a message to the
peer.
This decouples the two and creates a clear API for connecting to a peer
address. Goes along with the existing Disconnect() API.
This would be essential during activation of retained sessions by solely
connecting to the peer and associating with the retained session.

Surface Connection completion and Closure callbacks and hook them
through SessionManager(TransportMgr delegate) and CASESession.

Mark SecureSession as defunct on connection closures.

Modify ActiveConnectionState in TCPBase to hold state for each
connection, so that it is able to handle the various control flow paths.

Associate a session with a connection object.

Associate the PeerAddress with the session early. Pass the PeerAddress
in the Find APIs. This helps check against the correct TransportType
when searching for a Sesssion in the SessionTable.

Add a `large payload` flag in EstablishSession() and Session lookup
functions to create/associate with the correct session and transport.

Have default configurations for TCP in a separate TCPConfig.h.

Refactor echo_requester.cpp and echo_responder.cpp to use the session
associated with the connection.

Handle Connection closure at ExchangeMgr and uplevel to corresponding
ExchangeContext using the corresponding session handle.

Add tests around connection establishment in TestTCP.
  • Loading branch information
pidarped committed Apr 25, 2024
1 parent 8a4dffc commit a931fd9
Show file tree
Hide file tree
Showing 43 changed files with 2,058 additions and 370 deletions.
2 changes: 2 additions & 0 deletions examples/shell/shell_common/include/Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
#include <protocols/secure_channel/MessageCounterManager.h>
#include <transport/SessionHolder.h>
#include <transport/SessionManager.h>
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
#include <transport/raw/TCP.h>
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
#include <transport/raw/UDP.h>

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
Expand Down
65 changes: 30 additions & 35 deletions src/app/CASESessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,62 +30,55 @@ CHIP_ERROR CASESessionManager::Init(chip::System::Layer * systemLayer, const CAS
}

void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure
Callback::Callback<OnDeviceConnectionFailure> * onFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
)
TransportPayloadCapability transportPayloadCapability)
{
FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr
FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
attemptCount, onRetry
attemptCount, onRetry,
#endif
);
transportPayloadCapability);
}

void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure
Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
#endif
)
TransportPayloadCapability transportPayloadCapability)
{
FindOrEstablishSessionHelper(peerId, onConnection, nullptr, onSetupFailure
FindOrEstablishSessionHelper(peerId, onConnection, nullptr, onSetupFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
attemptCount, onRetry
attemptCount, onRetry,
#endif
);
transportPayloadCapability);
}

void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
std::nullptr_t
std::nullptr_t,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
#endif
)
TransportPayloadCapability transportPayloadCapability)
{
FindOrEstablishSessionHelper(peerId, onConnection, nullptr, nullptr
FindOrEstablishSessionHelper(peerId, onConnection, nullptr, nullptr,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
attemptCount, onRetry
attemptCount, onRetry,
#endif
);
transportPayloadCapability);
}

void CASESessionManager::FindOrEstablishSessionHelper(const ScopedNodeId & peerId,
Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure,
Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure
Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
#endif
)
TransportPayloadCapability transportPayloadCapability)
{
ChipLogDetail(CASESessionManager, "FindOrEstablishSession: PeerId = [%d:" ChipLogFormatX64 "]", peerId.GetFabricIndex(),
ChipLogValueX64(peerId.GetNodeId()));
Expand Down Expand Up @@ -124,12 +117,12 @@ void CASESessionManager::FindOrEstablishSessionHelper(const ScopedNodeId & peerI

if (onFailure != nullptr)
{
session->Connect(onConnection, onFailure);
session->Connect(onConnection, onFailure, transportPayloadCapability);
}

if (onSetupFailure != nullptr)
{
session->Connect(onConnection, onSetupFailure);
session->Connect(onConnection, onSetupFailure, transportPayloadCapability);
}
}

Expand All @@ -143,10 +136,11 @@ void CASESessionManager::ReleaseAllSessions()
mConfig.sessionSetupPool->ReleaseAllSessionSetup();
}

CHIP_ERROR CASESessionManager::GetPeerAddress(const ScopedNodeId & peerId, Transport::PeerAddress & addr)
CHIP_ERROR CASESessionManager::GetPeerAddress(const ScopedNodeId & peerId, Transport::PeerAddress & addr,
TransportPayloadCapability transportPayloadCapability)
{
ReturnErrorOnFailure(mConfig.sessionInitParams.Validate());
auto optionalSessionHandle = FindExistingSession(peerId);
auto optionalSessionHandle = FindExistingSession(peerId, transportPayloadCapability);
ReturnErrorCodeIf(!optionalSessionHandle.HasValue(), CHIP_ERROR_NOT_CONNECTED);
addr = optionalSessionHandle.Value()->AsSecureSession()->GetPeerAddress();
return CHIP_NO_ERROR;
Expand Down Expand Up @@ -182,10 +176,11 @@ OperationalSessionSetup * CASESessionManager::FindExistingSessionSetup(const Sco
return mConfig.sessionSetupPool->FindSessionSetup(peerId, forAddressUpdate);
}

Optional<SessionHandle> CASESessionManager::FindExistingSession(const ScopedNodeId & peerId) const
Optional<SessionHandle> CASESessionManager::FindExistingSession(const ScopedNodeId & peerId,
const TransportPayloadCapability transportPayloadCapability) const
{
return mConfig.sessionInitParams.sessionManager->FindSecureSessionForNode(peerId,
MakeOptional(Transport::SecureSession::Type::kCASE));
return mConfig.sessionInitParams.sessionManager->FindSecureSessionForNode(
peerId, MakeOptional(Transport::SecureSession::Type::kCASE), transportPayloadCapability);
}

void CASESessionManager::ReleaseSession(OperationalSessionSetup * session)
Expand Down
35 changes: 19 additions & 16 deletions src/app/CASESessionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <lib/support/Pool.h>
#include <platform/CHIPDeviceLayer.h>
#include <transport/SessionDelegate.h>
#include <transport/SessionManager.h>
#include <transport/SessionUpdateDelegate.h>

namespace chip {
Expand Down Expand Up @@ -78,12 +79,11 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess
* setup is not successful.
*/
void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure
Callback::Callback<OnDeviceConnectionFailure> * onFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
uint8_t attemptCount = 1, Callback::Callback<OnDeviceConnectionRetry> * onRetry = nullptr
uint8_t attemptCount = 1, Callback::Callback<OnDeviceConnectionRetry> * onRetry = nullptr,
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
);
TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload);

/**
* Find an existing session for the given node ID or trigger a new session request.
Expand All @@ -106,14 +106,14 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess
* @param onSetupFailure A callback to be called upon an extended device connection failure.
* @param attemptCount The number of retry attempts if session setup fails (default is 1).
* @param onRetry A callback to be called on a retry attempt (enabled by a config flag).
* @param transportPayloadCapability An indicator of what payload types the session needs to be able to transport.
*/
void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure
Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
uint8_t attemptCount = 1, Callback::Callback<OnDeviceConnectionRetry> * onRetry = nullptr
uint8_t attemptCount = 1, Callback::Callback<OnDeviceConnectionRetry> * onRetry = nullptr,
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
);
TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload);

/**
* Find an existing session for the given node ID or trigger a new session request.
Expand All @@ -134,13 +134,13 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess
* @param onConnection A callback to be called upon successful connection establishment.
* @param attemptCount The number of retry attempts if session setup fails (default is 1).
* @param onRetry A callback to be called on a retry attempt (enabled by a config flag).
* @param transportPayloadCapability An indicator of what payload types the session needs to be able to transport.
*/
void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection, std::nullptr_t
void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection, std::nullptr_t,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
,
uint8_t attemptCount = 1, Callback::Callback<OnDeviceConnectionRetry> * onRetry = nullptr
uint8_t attemptCount = 1, Callback::Callback<OnDeviceConnectionRetry> * onRetry = nullptr,
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
);
TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload);

void ReleaseSessionsForFabric(FabricIndex fabricIndex);

Expand All @@ -154,7 +154,8 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess
* an ongoing session with the peer node. If the session doesn't exist, the API will return
* `CHIP_ERROR_NOT_CONNECTED` error.
*/
CHIP_ERROR GetPeerAddress(const ScopedNodeId & peerId, Transport::PeerAddress & addr);
CHIP_ERROR GetPeerAddress(const ScopedNodeId & peerId, Transport::PeerAddress & addr,
TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload);

//////////// OperationalSessionReleaseDelegate Implementation ///////////////
void ReleaseSession(OperationalSessionSetup * device) override;
Expand All @@ -165,15 +166,17 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess
private:
OperationalSessionSetup * FindExistingSessionSetup(const ScopedNodeId & peerId, bool forAddressUpdate = false) const;

Optional<SessionHandle> FindExistingSession(const ScopedNodeId & peerId) const;
Optional<SessionHandle> FindExistingSession(
const ScopedNodeId & peerId,
const TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload) const;

void FindOrEstablishSessionHelper(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure,
Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
#endif
);
TransportPayloadCapability transportPayloadCapability);

CASESessionManagerConfig mConfig;
};
Expand Down
28 changes: 21 additions & 7 deletions src/app/OperationalSessionSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ bool OperationalSessionSetup::AttachToExistingSecureSession()
mState == State::WaitingForRetry,
false);

auto sessionHandle =
mInitParams.sessionManager->FindSecureSessionForNode(mPeerId, MakeOptional(Transport::SecureSession::Type::kCASE));
auto sessionHandle = mInitParams.sessionManager->FindSecureSessionForNode(
mPeerId, MakeOptional(Transport::SecureSession::Type::kCASE), mTransportPayloadCapability);
if (!sessionHandle.HasValue())
return false;

Expand All @@ -93,11 +93,13 @@ bool OperationalSessionSetup::AttachToExistingSecureSession()

void OperationalSessionSetup::Connect(Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure,
Callback::Callback<OnSetupFailure> * onSetupFailure)
Callback::Callback<OnSetupFailure> * onSetupFailure,
TransportPayloadCapability transportPayloadCapability)
{
CHIP_ERROR err = CHIP_NO_ERROR;
bool isConnected = false;

mTransportPayloadCapability = transportPayloadCapability;
//
// Always enqueue our user provided callbacks into our callback list.
// If anything goes wrong below, we'll trigger failures (including any queued from
Expand Down Expand Up @@ -180,15 +182,17 @@ void OperationalSessionSetup::Connect(Callback::Callback<OnDeviceConnected> * on
}

void OperationalSessionSetup::Connect(Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure)
Callback::Callback<OnDeviceConnectionFailure> * onFailure,
TransportPayloadCapability transportPayloadCapability)
{
Connect(onConnection, onFailure, nullptr);
Connect(onConnection, onFailure, nullptr, transportPayloadCapability);
}

void OperationalSessionSetup::Connect(Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnSetupFailure> * onSetupFailure)
Callback::Callback<OnSetupFailure> * onSetupFailure,
TransportPayloadCapability transportPayloadCapability)
{
Connect(onConnection, nullptr, onSetupFailure);
Connect(onConnection, nullptr, onSetupFailure, transportPayloadCapability);
}

void OperationalSessionSetup::UpdateDeviceData(const Transport::PeerAddress & addr, const ReliableMessageProtocolConfig & config)
Expand Down Expand Up @@ -288,6 +292,16 @@ void OperationalSessionSetup::UpdateDeviceData(const Transport::PeerAddress & ad

CHIP_ERROR OperationalSessionSetup::EstablishConnection(const ReliableMessageProtocolConfig & config)
{
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
// TODO: Combine LargePayload flag with DNS-SD advertisements from peer.
// Issue #32348.
if (mTransportPayloadCapability == TransportPayloadCapability::kLargePayload)
{
// Set the transport type for carrying large payloads
mDeviceAddress.SetTransportType(chip::Transport::Type::kTcp);
}
#endif

mCASEClient = mClientPool->Allocate();
ReturnErrorCodeIf(mCASEClient == nullptr, CHIP_ERROR_NO_MEMORY);

Expand Down
Loading

0 comments on commit a931fd9

Please sign in to comment.