Skip to content

Commit

Permalink
address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
pan-apple committed Nov 15, 2021
1 parent 9ba906f commit 83037da
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 104 deletions.
92 changes: 32 additions & 60 deletions src/app/CASESessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,29 @@

namespace chip {

CHIP_ERROR CASESessionManager::FindOrEstablishSession(NodeId deviceId, Transport::PeerAddress address,
Callback::Callback<OnDeviceConnected> * onConnection,
CHIP_ERROR CASESessionManager::FindOrEstablishSession(NodeId nodeId, Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure)
{
VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE);
PeerId peerId = mInitParams.sessionInitParams.fabricInfo->GetPeerIdForNode(deviceId);
OperationalDeviceProxy * session = FindSession(deviceId);
OperationalDeviceProxy * session = FindExistingSession(nodeId);
if (session == nullptr)
{
session = mActiveSessions.CreateObject(mInitParams.sessionInitParams, peerId);
if (session == nullptr)
{
onFailure->mCall(onFailure->mContext, deviceId, CHIP_ERROR_NO_MEMORY);
return CHIP_ERROR_NO_MEMORY;
}
}
Dnssd::ResolvedNodeData * nodeResolutionData = nullptr;
Dnssd::ResolvedNodeData cachedResolutionData;

bool validAddress = (address != Transport::PeerAddress::UDP(Inet::IPAddress::Any));
PeerId peerId = GetFabricInfo()->GetPeerIdForNode(nodeId);

if (!validAddress && mInitParams.dnsCache != nullptr)
{
Dnssd::ResolvedNodeData nodeData;
if (mInitParams.dnsCache->Lookup(peerId, nodeData) == CHIP_NO_ERROR)
if (mConfig.dnsCache != nullptr && mConfig.dnsCache->Lookup(peerId, cachedResolutionData) == CHIP_NO_ERROR)
{
address = ToPeerAddress(nodeData);
validAddress = true;
nodeResolutionData = &cachedResolutionData;
}
}

if (validAddress)
{
uint32_t idleInterval;
uint32_t activeInterval;
session->GetMRPIntervals(idleInterval, activeInterval);
CHIP_ERROR err = session->UpdateDeviceData(address, idleInterval, activeInterval);
if (err != CHIP_NO_ERROR)
// TODO - Implement LRU to evict least recently used session to handle mActiveSessions pool exhaustion
session = mActiveSessions.CreateObject(mConfig.sessionInitParams, peerId, nodeResolutionData);
if (session == nullptr)
{
ReleaseSession(session);
return err;
onFailure->mCall(onFailure->mContext, nodeId, CHIP_ERROR_NO_MEMORY);
return CHIP_ERROR_NO_MEMORY;
}
}

Expand All @@ -71,48 +55,33 @@ CHIP_ERROR CASESessionManager::FindOrEstablishSession(NodeId deviceId, Transport
return err;
}

void CASESessionManager::ReleaseSession(NodeId deviceId)
void CASESessionManager::ReleaseSession(NodeId nodeId)
{
ReleaseSession(FindSession(deviceId));
ReleaseSession(FindExistingSession(nodeId));
}

CHIP_ERROR CASESessionManager::ResolveDeviceAddress(NodeId deviceId)
CHIP_ERROR CASESessionManager::ResolveDeviceAddress(NodeId nodeId)
{
VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE);
return Dnssd::Resolver::Instance().ResolveNodeId(mInitParams.sessionInitParams.fabricInfo->GetPeerIdForNode(deviceId),
Inet::IPAddressType::kAny);
}

Transport::PeerAddress CASESessionManager::ToPeerAddress(const Dnssd::ResolvedNodeData & nodeData) const
{
Inet::InterfaceId interfaceId;

// Only use the mDNS resolution's InterfaceID for addresses that are IPv6 LLA.
// For all other addresses, we should rely on the device's routing table to route messages sent.
// Forcing messages down an InterfaceId might fail. For example, in bridged networks like Thread,
// mDNS advertisements are not usually received on the same interface the peer is reachable on.
if (nodeData.mAddress[0].IsIPv6LinkLocal())
{
interfaceId = nodeData.mInterfaceId;
}

return Transport::PeerAddress::UDP(nodeData.mAddress[0], nodeData.mPort, interfaceId);
return Dnssd::Resolver::Instance().ResolveNodeId(GetFabricInfo()->GetPeerIdForNode(nodeId), Inet::IPAddressType::kAny);
}

void CASESessionManager::OnNodeIdResolved(const Dnssd::ResolvedNodeData & nodeData)
{
VerifyOrReturn(mInitialized);
ChipLogProgress(Controller, "Address resolved for node: 0x" ChipLogFormatX64, ChipLogValueX64(nodeData.mPeerId.GetNodeId()));
VerifyOrReturn(mInitialized, ChipLogError(Controller, "OnNodeIdResolved was called in uninitialized state"));

if (mInitParams.dnsCache != nullptr)
if (mConfig.dnsCache != nullptr)
{
LogErrorOnFailure(mInitParams.dnsCache->Insert(nodeData));
LogErrorOnFailure(mConfig.dnsCache->Insert(nodeData));
}

OperationalDeviceProxy * session = FindSession(nodeData.mPeerId.GetNodeId());
VerifyOrReturn(session != nullptr);
OperationalDeviceProxy * session = FindExistingSession(nodeData.mPeerId.GetNodeId());
VerifyOrReturn(session != nullptr,
ChipLogDetail(Controller, "OnNodeIdResolved was called for a device with no active sessions, ignoring it."));

LogErrorOnFailure(session->UpdateDeviceData(
ToPeerAddress(nodeData), nodeData.GetMrpRetryIntervalIdle().ValueOr(CHIP_CONFIG_MRP_DEFAULT_IDLE_RETRY_INTERVAL),
session->ToPeerAddress(nodeData), nodeData.GetMrpRetryIntervalIdle().ValueOr(CHIP_CONFIG_MRP_DEFAULT_IDLE_RETRY_INTERVAL),
nodeData.GetMrpRetryIntervalActive().ValueOr(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL)));
}

Expand All @@ -121,21 +90,24 @@ void CASESessionManager::OnNodeIdResolutionFailed(const PeerId & peer, CHIP_ERRO
ChipLogError(Controller, "Error resolving node id: %s", ErrorStr(error));
}

CHIP_ERROR CASESessionManager::GetDeviceAddressAndPort(NodeId deviceId, Inet::IPAddress & addr, uint16_t & port)
CHIP_ERROR CASESessionManager::GetDeviceAddressAndPort(NodeId nodeId, Inet::IPAddress & addr, uint16_t & port)
{
VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE);

OperationalDeviceProxy * session = FindSession(deviceId);
OperationalDeviceProxy * session = FindExistingSession(nodeId);
VerifyOrReturnError(session != nullptr, CHIP_ERROR_NOT_CONNECTED);
VerifyOrReturnError(session->GetAddress(addr, port), CHIP_ERROR_NOT_CONNECTED);
return CHIP_NO_ERROR;
}

void CASESessionManager::OnNewConnection(SessionHandle sessionHandle, Messaging::ExchangeManager * mgr) {}
void CASESessionManager::OnNewConnection(SessionHandle sessionHandle, Messaging::ExchangeManager * mgr)
{
// TODO Update the MRP params based on the MRP params extracted from CASE, when this is available.
}

void CASESessionManager::OnConnectionExpired(SessionHandle sessionHandle, Messaging::ExchangeManager * mgr)
{
VerifyOrReturn(mInitialized);
VerifyOrReturn(mInitialized, ChipLogError(Controller, "OnConnectionExpired was called in uninitialized state"));

OperationalDeviceProxy * session = FindSession(sessionHandle);
VerifyOrReturn(session != nullptr,
Expand All @@ -159,7 +131,7 @@ OperationalDeviceProxy * CASESessionManager::FindSession(SessionHandle session)
return foundSession;
}

OperationalDeviceProxy * CASESessionManager::FindSession(NodeId id)
OperationalDeviceProxy * CASESessionManager::FindExistingSession(NodeId id)
{
OperationalDeviceProxy * foundSession = nullptr;
mActiveSessions.ForEachActiveObject([&](auto * activeSession) {
Expand Down
43 changes: 30 additions & 13 deletions src/app/CASESessionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,57 @@

namespace chip {

struct CASESessionManagerInitParams
struct CASESessionManagerConfig
{
DeviceProxyInitParams sessionInitParams;
Dnssd::DnssdCache<CHIP_CONFIG_MDNS_CACHE_SIZE> * dnsCache = nullptr;
};

/**
* This class provides the following
* 1. Manage a pool of operational device proxy objects for peer nodes that have active message exchange with the local node.
* 2. The pool contains atmost one device proxy object for a given peer node.
* 3. API to lookup an existing proxy object, or allocate a new one by triggering session establishment with the peer node.
* 4. During session establishment, trigger node ID resolution (if needed), and update the DNS-SD cache (if resolution is
* successful)
*/
class CASESessionManager : public Messaging::ExchangeMgrDelegate, public Dnssd::ResolverDelegate
{
public:
CASESessionManager(CASESessionManagerInitParams & params)
CASESessionManager(CASESessionManagerConfig & params)
{
VerifyOrReturn(params.sessionInitParams.Validate() == CHIP_NO_ERROR);

mInitParams = params;
mConfig = params;
mInitialized = true;
}

virtual ~CASESessionManager() {}

void Shutdown() { mInitialized = false; }

CHIP_ERROR FindOrEstablishSession(NodeId deviceId, Transport::PeerAddress addr,
Callback::Callback<OnDeviceConnected> * onConnection,
/**
* Find an existing session for the given node ID, or trigger a new session request.
*/
CHIP_ERROR FindOrEstablishSession(NodeId nodeId, Callback::Callback<OnDeviceConnected> * onConnection,
Callback::Callback<OnDeviceConnectionFailure> * onFailure);

OperationalDeviceProxy * FindExistingSession(NodeId deviceId) { return FindSession(deviceId); }
OperationalDeviceProxy * FindExistingSession(NodeId nodeId);

void ReleaseSession(NodeId nodeId);

FabricInfo * GetFabricInfo()
{
if (!mInitialized)
{
return nullptr;
}

void ReleaseSession(NodeId deviceId);
return mConfig.sessionInitParams.fabricInfo;
}

CHIP_ERROR ResolveDeviceAddress(NodeId deviceId);
CHIP_ERROR GetDeviceAddressAndPort(NodeId deviceId, Inet::IPAddress & addr, uint16_t & port);
CHIP_ERROR ResolveDeviceAddress(NodeId nodeId);
CHIP_ERROR GetDeviceAddressAndPort(NodeId nodeId, Inet::IPAddress & addr, uint16_t & port);

//////////// ExchangeMgrDelegate Implementation ///////////////
void OnNewConnection(SessionHandle session, Messaging::ExchangeManager * mgr) override;
Expand All @@ -72,14 +92,11 @@ class CASESessionManager : public Messaging::ExchangeMgrDelegate, public Dnssd::

private:
OperationalDeviceProxy * FindSession(SessionHandle session);
OperationalDeviceProxy * FindSession(NodeId id);
void ReleaseSession(OperationalDeviceProxy * device);

Transport::PeerAddress ToPeerAddress(const Dnssd::ResolvedNodeData & nodeData) const;

BitMapObjectPool<OperationalDeviceProxy, CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES> mActiveSessions;

CASESessionManagerInitParams mInitParams;
CASESessionManagerConfig mConfig;

bool mInitialized = false;
};
Expand Down
58 changes: 35 additions & 23 deletions src/app/OperationalDeviceProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include <transport/raw/MessageHeader.h>
#include <transport/raw/UDP.h>

#include <lib/dnssd/Resolver.h>

namespace chip {

struct DeviceProxyInitParams
Expand Down Expand Up @@ -71,13 +73,27 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, public SessionEsta
{
public:
virtual ~OperationalDeviceProxy();
OperationalDeviceProxy(DeviceProxyInitParams & params, PeerId peerId)
OperationalDeviceProxy(DeviceProxyInitParams & params, PeerId peerId, const Dnssd::ResolvedNodeData * nodeResolutionData)
{
VerifyOrReturn(params.Validate() == CHIP_NO_ERROR);

mInitParams = params;
mPeerId = peerId;
mState = State::NeedsAddress;

if (nodeResolutionData != nullptr)
{
mDeviceAddress = ToPeerAddress(*nodeResolutionData);

mMrpIdleInterval = nodeResolutionData->GetMrpRetryIntervalIdle().ValueOr(CHIP_CONFIG_MRP_DEFAULT_IDLE_RETRY_INTERVAL);
mMrpActiveInterval =
nodeResolutionData->GetMrpRetryIntervalActive().ValueOr(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL);

mState = State::Initialized;
}
else
{
mState = State::NeedsAddress;
}
}

void Clear();
Expand Down Expand Up @@ -112,27 +128,6 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, public SessionEsta
CHIP_ERROR Disconnect() override;

NodeId GetDeviceId() const override { return mPeerId.GetNodeId(); }
/*
// ----- Messaging -----
CHIP_ERROR SendReadAttributeRequest(app::AttributePathParams aPath, Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback, app::TLVDataFilter aTlvDataFilter) override;
CHIP_ERROR SendSubscribeAttributeRequest(app::AttributePathParams aPath, uint16_t mMinIntervalFloorSeconds,
uint16_t mMaxIntervalCeilingSeconds, Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback) override;
CHIP_ERROR SendWriteAttributeRequest(app::WriteClientHandle aHandle, Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback) override;
CHIP_ERROR SendCommands(app::CommandSender * commandObj) override;
void AddReportHandler(EndpointId endpoint, ClusterId cluster, AttributeId attribute, Callback::Cancelable *
onReportCallback, app::TLVDataFilter tlvDataFilter) override;
void AddIMResponseHandler(void * commandObj, Callback::Cancelable * onSuccessCallback, Callback::Cancelable *
onFailureCallback, app::TLVDataFilter tlvDataFilter = nullptr) override; void CancelIMResponseHandler(void * commandObj)
override;
*/

/**
* Update data of the device.
Expand Down Expand Up @@ -164,6 +159,23 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, public SessionEsta

bool GetAddress(Inet::IPAddress & addr, uint16_t & port) const override;

static Transport::PeerAddress ToPeerAddress(const Dnssd::ResolvedNodeData & nodeData)
{
Inet::InterfaceId interfaceId = Inet::InterfaceId::Null();

// TODO - Revisit usage of InterfaceID only for addresses that are IPv6 LLA
// Only use the DNS-SD resolution's InterfaceID for addresses that are IPv6 LLA.
// For all other addresses, we should rely on the device's routing table to route messages sent.
// Forcing messages down an InterfaceId might fail. For example, in bridged networks like Thread,
// mDNS advertisements are not usually received on the same interface the peer is reachable on.
if (nodeData.mAddress[0].IsIPv6LinkLocal())
{
interfaceId = nodeData.mInterfaceId;
}

return Transport::PeerAddress::UDP(nodeData.mAddress[0], nodeData.mPort, interfaceId);
}

private:
enum class State
{
Expand Down
Loading

0 comments on commit 83037da

Please sign in to comment.