diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 793fc2a6bfc3b0..673dd007804cb7 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -39,6 +39,8 @@ static_library("app") { "AttributePathExpandIterator.h", "AttributePathParams.cpp", "AttributePathParams.h", + "CASESessionManager.cpp", + "CASESessionManager.h", "Command.cpp", "Command.h", "CommandHandler.cpp", diff --git a/src/app/CASESessionManager.cpp b/src/app/CASESessionManager.cpp new file mode 100644 index 00000000000000..ff152e47e6a22a --- /dev/null +++ b/src/app/CASESessionManager.cpp @@ -0,0 +1,166 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace chip { + +CHIP_ERROR CASESessionManager::FindOrEstablishSession(NodeId nodeId, Callback::Callback * onConnection, + Callback::Callback * onFailure) +{ + Dnssd::ResolvedNodeData resolutionData; + + PeerId peerId = GetFabricInfo()->GetPeerIdForNode(nodeId); + + bool nodeIDWasResolved = (mConfig.dnsCache != nullptr && mConfig.dnsCache->Lookup(peerId, resolutionData) == CHIP_NO_ERROR); + + OperationalDeviceProxy * session = FindExistingSession(nodeId); + if (session == nullptr) + { + // TODO - Implement LRU to evict least recently used session to handle mActiveSessions pool exhaustion + if (nodeIDWasResolved) + { + session = mActiveSessions.CreateObject(mConfig.sessionInitParams, peerId, resolutionData); + } + else + { + session = mActiveSessions.CreateObject(mConfig.sessionInitParams, peerId); + } + + if (session == nullptr) + { + onFailure->mCall(onFailure->mContext, nodeId, CHIP_ERROR_NO_MEMORY); + return CHIP_ERROR_NO_MEMORY; + } + } + else if (nodeIDWasResolved) + { + session->OnNodeIdResolved(resolutionData); + } + + CHIP_ERROR err = session->Connect(onConnection, onFailure); + if (err != CHIP_NO_ERROR) + { + ReleaseSession(session); + } + + return err; +} + +void CASESessionManager::ReleaseSession(NodeId nodeId) +{ + ReleaseSession(FindExistingSession(nodeId)); +} + +CHIP_ERROR CASESessionManager::ResolveDeviceAddress(NodeId nodeId) +{ + return Dnssd::Resolver::Instance().ResolveNodeId(GetFabricInfo()->GetPeerIdForNode(nodeId), Inet::IPAddressType::kAny); +} + +void CASESessionManager::OnNodeIdResolved(const Dnssd::ResolvedNodeData & nodeData) +{ + ChipLogProgress(Controller, "Address resolved for node: 0x" ChipLogFormatX64, ChipLogValueX64(nodeData.mPeerId.GetNodeId())); + + if (mConfig.dnsCache != nullptr) + { + LogErrorOnFailure(mConfig.dnsCache->Insert(nodeData)); + } + + 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( + session->ToPeerAddress(nodeData), nodeData.GetMrpRetryIntervalIdle().ValueOr(CHIP_CONFIG_MRP_DEFAULT_IDLE_RETRY_INTERVAL), + nodeData.GetMrpRetryIntervalActive().ValueOr(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL))); +} + +void CASESessionManager::OnNodeIdResolutionFailed(const PeerId & peer, CHIP_ERROR error) +{ + ChipLogError(Controller, "Error resolving node id: %s", ErrorStr(error)); +} + +CHIP_ERROR CASESessionManager::GetPeerAddress(NodeId nodeId, Transport::PeerAddress & addr) +{ + if (mConfig.dnsCache != nullptr) + { + Dnssd::ResolvedNodeData resolutionData; + ReturnErrorOnFailure(mConfig.dnsCache->Lookup(GetFabricInfo()->GetPeerIdForNode(nodeId), resolutionData)); + addr = OperationalDeviceProxy::ToPeerAddress(resolutionData); + return CHIP_NO_ERROR; + } + + OperationalDeviceProxy * session = FindExistingSession(nodeId); + VerifyOrReturnError(session != nullptr, CHIP_ERROR_NOT_CONNECTED); + addr = session->GetPeerAddress(); + return CHIP_NO_ERROR; +} + +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) +{ + OperationalDeviceProxy * session = FindSession(sessionHandle); + VerifyOrReturn(session != nullptr, + ChipLogDetail(Controller, "OnConnectionExpired was called for unknown device, ignoring it.")); + + session->OnConnectionExpired(sessionHandle); +} + +OperationalDeviceProxy * CASESessionManager::FindSession(SessionHandle session) +{ + OperationalDeviceProxy * foundSession = nullptr; + mActiveSessions.ForEachActiveObject([&](auto * activeSession) { + if (activeSession->MatchesSession(session)) + { + foundSession = activeSession; + return false; + } + return true; + }); + + return foundSession; +} + +OperationalDeviceProxy * CASESessionManager::FindExistingSession(NodeId id) +{ + OperationalDeviceProxy * foundSession = nullptr; + mActiveSessions.ForEachActiveObject([&](auto * activeSession) { + if (activeSession->GetDeviceId() == id) + { + foundSession = activeSession; + return false; + } + return true; + }); + + return foundSession; +} + +void CASESessionManager::ReleaseSession(OperationalDeviceProxy * session) +{ + if (session != nullptr) + { + mActiveSessions.ReleaseObject(session); + } +} + +} // namespace chip diff --git a/src/app/CASESessionManager.h b/src/app/CASESessionManager.h new file mode 100644 index 00000000000000..56fbdfca449d2a --- /dev/null +++ b/src/app/CASESessionManager.h @@ -0,0 +1,112 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace chip { + +struct CASESessionManagerConfig +{ + DeviceProxyInitParams sessionInitParams; + Dnssd::DnssdCache * 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() = delete; + + CASESessionManager(CASESessionManagerConfig & params) + { + VerifyOrReturn(params.sessionInitParams.Validate() == CHIP_NO_ERROR); + + mConfig = params; + } + + virtual ~CASESessionManager() {} + + /** + * Find an existing session for the given node ID, or trigger a new session request. + * The caller can optionally provide `onConnection` and `onFailure` callback objects. If provided, + * these will be used to inform the caller about successful or failed connection establishment. + * If the connection is already established, the `onConnection` callback will be immediately called. + */ + CHIP_ERROR FindOrEstablishSession(NodeId nodeId, Callback::Callback * onConnection, + Callback::Callback * onFailure); + + OperationalDeviceProxy * FindExistingSession(NodeId nodeId); + + void ReleaseSession(NodeId nodeId); + + FabricInfo * GetFabricInfo() { return mConfig.sessionInitParams.fabricInfo; } + + /** + * This API triggers the DNS-SD resolution for the given node ID. The node ID will be looked up + * on the fabric that was configured for the CASESessionManager object. + * + * The results of the DNS-SD resolution request is provided to the class via `ResolverDelegate` + * implementation of CASESessionManager. + */ + CHIP_ERROR ResolveDeviceAddress(NodeId nodeId); + + /** + * This API returns the address for the given node ID. + * If the CASESessionManager is configured with a DNS-SD cache, the cache is looked up + * for the node ID. + * If the DNS-SD cache is not available, the CASESessionManager looks up the list for + * 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(NodeId nodeId, Transport::PeerAddress & addr); + + //////////// ExchangeMgrDelegate Implementation /////////////// + void OnNewConnection(SessionHandle session, Messaging::ExchangeManager * mgr) override; + void OnConnectionExpired(SessionHandle session, Messaging::ExchangeManager * mgr) override; + + //////////// ResolverDelegate Implementation /////////////// + void OnNodeIdResolved(const Dnssd::ResolvedNodeData & nodeData) override; + void OnNodeIdResolutionFailed(const PeerId & peerId, CHIP_ERROR error) override; + void OnNodeDiscoveryComplete(const Dnssd::DiscoveredNodeData & nodeData) override {} + +private: + OperationalDeviceProxy * FindSession(SessionHandle session); + void ReleaseSession(OperationalDeviceProxy * device); + + BitMapObjectPool mActiveSessions; + + CASESessionManagerConfig mConfig; +}; + +} // namespace chip diff --git a/src/app/OperationalDeviceProxy.cpp b/src/app/OperationalDeviceProxy.cpp index 4aaddb4ce40df7..140beb734867c8 100644 --- a/src/app/OperationalDeviceProxy.cpp +++ b/src/app/OperationalDeviceProxy.cpp @@ -24,10 +24,11 @@ * messages to and from the corresponding CHIP devices. */ -#include +#include "OperationalDeviceProxy.h" + +#include "CommandSender.h" +#include "ReadPrepareParams.h" -#include -#include #include #include #include diff --git a/src/app/OperationalDeviceProxy.h b/src/app/OperationalDeviceProxy.h index fd495860d23ce1..a9cfa2725dcbd5 100644 --- a/src/app/OperationalDeviceProxy.h +++ b/src/app/OperationalDeviceProxy.h @@ -40,6 +40,8 @@ #include #include +#include + namespace chip { struct DeviceProxyInitParams @@ -50,6 +52,16 @@ struct DeviceProxyInitParams FabricInfo * fabricInfo = nullptr; Controller::DeviceControllerInteractionModelDelegate * imDelegate = nullptr; + + CHIP_ERROR Validate() + { + ReturnErrorCodeIf(sessionManager == nullptr, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorCodeIf(exchangeMgr == nullptr, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorCodeIf(idAllocator == nullptr, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorCodeIf(fabricInfo == nullptr, CHIP_ERROR_INCORRECT_STATE); + + return CHIP_NO_ERROR; + } }; class OperationalDeviceProxy; @@ -61,16 +73,20 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, public SessionEsta { public: virtual ~OperationalDeviceProxy(); - OperationalDeviceProxy(DeviceProxyInitParams params, PeerId peerId) + OperationalDeviceProxy(DeviceProxyInitParams & params, PeerId peerId) { - VerifyOrReturn(params.sessionManager != nullptr); - VerifyOrReturn(params.exchangeMgr != nullptr); - VerifyOrReturn(params.idAllocator != nullptr); - VerifyOrReturn(params.fabricInfo != nullptr); + VerifyOrReturn(params.Validate() == CHIP_NO_ERROR); mInitParams = params; mPeerId = peerId; - mState = State::NeedsAddress; + + mState = State::NeedsAddress; + } + + OperationalDeviceProxy(DeviceProxyInitParams & params, PeerId peerId, const Dnssd::ResolvedNodeData & nodeResolutionData) : + OperationalDeviceProxy(params, peerId) + { + OnNodeIdResolved(nodeResolutionData); } void Clear(); @@ -99,33 +115,25 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, public SessionEsta */ void OnConnectionExpired(SessionHandle session) override; + void OnNodeIdResolved(const Dnssd::ResolvedNodeData & nodeResolutionData) + { + 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); + + if (mState == State::NeedsAddress) + { + mState = State::Initialized; + } + } + /** * Mark any open session with the device as expired. */ 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. @@ -157,6 +165,25 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, public SessionEsta bool GetAddress(Inet::IPAddress & addr, uint16_t & port) const override; + Transport::PeerAddress GetPeerAddress() const { return mDeviceAddress; } + + 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 { diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 8c66429cb1799d..a4a168a68956ab 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -149,6 +149,22 @@ CHIP_ERROR DeviceController::Init(ControllerInitParams params) ReturnErrorOnFailure(ProcessControllerNOCChain(params)); + DeviceProxyInitParams deviceInitParams = { + .sessionManager = params.systemState->SessionMgr(), + .exchangeMgr = params.systemState->ExchangeMgr(), + .idAllocator = &mIDAllocator, + .fabricInfo = params.systemState->Fabrics()->FindFabricWithIndex(mFabricIndex), + .imDelegate = params.systemState->IMDelegate(), + }; + + CASESessionManagerConfig sessionManagerConfig = { + .sessionInitParams = deviceInitParams, + .dnsCache = &mDNSCache, + }; + + mCASESessionManager = chip::Platform::New(sessionManagerConfig); + VerifyOrReturnError(mCASESessionManager != nullptr, CHIP_ERROR_NO_MEMORY); + mSystemState = params.systemState->Retain(); mState = State::Initialized; return CHIP_NO_ERROR; @@ -227,6 +243,9 @@ CHIP_ERROR DeviceController::Shutdown() mDeviceDiscoveryDelegate = nullptr; #endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD + chip::Platform::Delete(mCASESessionManager); + mCASESessionManager = nullptr; + return CHIP_NO_ERROR; } @@ -240,117 +259,17 @@ bool DeviceController::DoesDevicePairingExist(const PeerId & deviceId) return false; } -CHIP_ERROR DeviceController::GetOperationalDeviceWithAddress(NodeId deviceId, const Transport::PeerAddress & addr, - Callback::Callback * onConnection, - Callback::Callback * onFailure) -{ - OperationalDeviceProxy * device = FindOperationalDevice(deviceId); - if (device == nullptr) - { - FabricInfo * fabric = mSystemState->Fabrics()->FindFabricWithIndex(mFabricIndex); - VerifyOrReturnError(fabric != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - DeviceProxyInitParams initParams = { - .sessionManager = mSystemState->SessionMgr(), - .exchangeMgr = mSystemState->ExchangeMgr(), - .idAllocator = &mIDAllocator, - .fabricInfo = fabric, - .imDelegate = mSystemState->IMDelegate(), - }; - - PeerId peerID = fabric->GetPeerId(); - peerID.SetNodeId(deviceId); - - device = mOperationalDevices.CreateObject(initParams, peerID); - if (device == nullptr) - { - onFailure->mCall(onFailure->mContext, deviceId, CHIP_ERROR_NO_MEMORY); - return CHIP_ERROR_NO_MEMORY; - } - } - - CHIP_ERROR err = CHIP_NO_ERROR; - if (addr != Transport::PeerAddress::UDP(Inet::IPAddress::Any)) - { - uint32_t idleInterval; - uint32_t activeInterval; - device->GetMRPIntervals(idleInterval, activeInterval); - err = device->UpdateDeviceData(addr, idleInterval, activeInterval); - if (err != CHIP_NO_ERROR) - { - ReleaseOperationalDevice(device); - return err; - } - } - - err = device->Connect(onConnection, onFailure); - if (err != CHIP_NO_ERROR) - { - ReleaseOperationalDevice(device); - } - - return err; -} - -CHIP_ERROR DeviceController::UpdateDevice(NodeId deviceId) +void DeviceController::ReleaseOperationalDevice(NodeId remoteDeviceId) { -#if CHIP_DEVICE_CONFIG_ENABLE_DNSSD - return Dnssd::Resolver::Instance().ResolveNodeId(PeerId().SetCompressedFabricId(GetCompressedFabricId()).SetNodeId(deviceId), - chip::Inet::IPAddressType::kAny); -#else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; -#endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD + VerifyOrReturn(mState == State::Initialized, + ChipLogError(Controller, "ReleaseOperationalDevice was called in incorrect state")); + mCASESessionManager->ReleaseSession(remoteDeviceId); } -void DeviceController::OnNewConnection(SessionHandle session, Messaging::ExchangeManager * mgr) {} - void DeviceController::OnConnectionExpired(SessionHandle session, Messaging::ExchangeManager * mgr) { VerifyOrReturn(mState == State::Initialized, ChipLogError(Controller, "OnConnectionExpired was called in incorrect state")); - - OperationalDeviceProxy * device = FindOperationalDevice(session); - VerifyOrReturn(device != nullptr, ChipLogDetail(Controller, "OnConnectionExpired was called for unknown device, ignoring it.")); - - device->OnConnectionExpired(session); -} - -OperationalDeviceProxy * DeviceController::FindOperationalDevice(SessionHandle session) -{ - OperationalDeviceProxy * foundDevice = nullptr; - mOperationalDevices.ForEachActiveObject([&](auto * deviceProxy) { - if (deviceProxy->MatchesSession(session)) - { - foundDevice = deviceProxy; - return false; - } - return true; - }); - - return foundDevice; -} - -OperationalDeviceProxy * DeviceController::FindOperationalDevice(NodeId id) -{ - OperationalDeviceProxy * foundDevice = nullptr; - mOperationalDevices.ForEachActiveObject([&](auto * deviceProxy) { - if (deviceProxy->GetDeviceId() == id) - { - foundDevice = deviceProxy; - return false; - } - return true; - }); - - return foundDevice; -} - -void DeviceController::ReleaseOperationalDevice(NodeId id) -{ - ReleaseOperationalDevice(FindOperationalDevice(id)); -} - -void DeviceController::ReleaseOperationalDevice(OperationalDeviceProxy * device) -{ - mOperationalDevices.ReleaseObject(device); + mCASESessionManager->OnConnectionExpired(session, mgr); } CHIP_ERROR DeviceController::InitializePairedDeviceList() @@ -422,9 +341,11 @@ void DeviceController::PersistNextKeyId() CHIP_ERROR DeviceController::GetPeerAddressAndPort(PeerId peerId, Inet::IPAddress & addr, uint16_t & port) { - VerifyOrReturnError(GetCompressedFabricId() == peerId.GetCompressedFabricId(), CHIP_ERROR_INVALID_ARGUMENT); - OperationalDeviceProxy * device = FindOperationalDevice(peerId.GetNodeId()); - VerifyOrReturnError(device->GetAddress(addr, port), CHIP_ERROR_NOT_CONNECTED); + VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); + Transport::PeerAddress peerAddr; + ReturnErrorOnFailure(mCASESessionManager->GetPeerAddress(peerId.GetNodeId(), peerAddr)); + addr = peerAddr.GetIPAddress(); + port = peerAddr.GetPort(); return CHIP_NO_ERROR; } @@ -473,7 +394,7 @@ CHIP_ERROR DeviceController::OpenCommissioningWindowWithCallback(NodeId deviceId ChipLogProgress(Controller, "OpenCommissioningWindow for device ID %" PRIu64, deviceId); VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); - OperationalDeviceProxy * device = FindOperationalDevice(deviceId); + OperationalDeviceProxy * device = mCASESessionManager->FindExistingSession(deviceId); VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT); std::string QRCode; @@ -567,22 +488,20 @@ Transport::PeerAddress DeviceController::ToPeerAddress(const chip::Dnssd::Resolv void DeviceController::OnNodeIdResolved(const chip::Dnssd::ResolvedNodeData & nodeData) { - OperationalDeviceProxy * device = FindOperationalDevice(nodeData.mPeerId.GetNodeId()); - VerifyOrReturn(device != nullptr); - - CHIP_ERROR err = device->UpdateDeviceData( - ToPeerAddress(nodeData), nodeData.GetMrpRetryIntervalIdle().ValueOr(CHIP_CONFIG_MRP_DEFAULT_IDLE_RETRY_INTERVAL), - nodeData.GetMrpRetryIntervalActive().ValueOr(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL)); - + VerifyOrReturn(mState == State::Initialized, ChipLogError(Controller, "OnNodeIdResolved was called in incorrect state")); + mCASESessionManager->OnNodeIdResolved(nodeData); if (mDeviceAddressUpdateDelegate != nullptr) { - mDeviceAddressUpdateDelegate->OnAddressUpdateComplete(nodeData.mPeerId.GetNodeId(), err); + mDeviceAddressUpdateDelegate->OnAddressUpdateComplete(nodeData.mPeerId.GetNodeId(), CHIP_NO_ERROR); } }; void DeviceController::OnNodeIdResolutionFailed(const chip::PeerId & peer, CHIP_ERROR error) { ChipLogError(Controller, "Error resolving node id: %s", ErrorStr(error)); + VerifyOrReturn(mState == State::Initialized, + ChipLogError(Controller, "OnNodeIdResolutionFailed was called in incorrect state")); + mCASESessionManager->OnNodeIdResolutionFailed(peer, error); if (mDeviceAddressUpdateDelegate != nullptr) { @@ -887,6 +806,8 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam device->SetActive(true); err = device->GetPairing().Pair(params.GetPeerAddress(), params.GetSetupPINCode(), keyID, exchangeCtxt, this); + SuccessOrExit(err); + // Immediately persist the updted mNextKeyID value // TODO maybe remove FreeRendezvousSession() since mNextKeyID is always persisted immediately PersistNextKeyId(); @@ -1614,9 +1535,10 @@ void DeviceCommissioner::OnNodeIdResolved(const chip::Dnssd::ResolvedNodeData & mDeviceBeingCommissioned = nullptr; } - GetOperationalDeviceWithAddress(nodeData.mPeerId.GetNodeId(), ToPeerAddress(nodeData), &mOnDeviceConnectedCallback, - &mOnDeviceConnectionFailureCallback); + mDNSCache.Insert(nodeData); + mCASESessionManager->FindOrEstablishSession(nodeData.mPeerId.GetNodeId(), &mOnDeviceConnectedCallback, + &mOnDeviceConnectionFailureCallback); DeviceController::OnNodeIdResolved(nodeData); } diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 86315339e57964..8cf10ea0f8dbb8 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -28,6 +28,7 @@ #pragma once +#include #include #include #include @@ -216,17 +217,6 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeMgrDelegate, */ virtual CHIP_ERROR Shutdown(); - CHIP_ERROR GetOperationalDevice(NodeId deviceId, Callback::Callback * onConnection, - Callback::Callback * onFailure) - { - return GetOperationalDeviceWithAddress(deviceId, Transport::PeerAddress::UDP(Inet::IPAddress::Any), onConnection, - onFailure); - } - - CHIP_ERROR GetOperationalDeviceWithAddress(NodeId deviceId, const Transport::PeerAddress & addr, - Callback::Callback * onConnection, - Callback::Callback * onFailure); - CHIP_ERROR GetPeerAddressAndPort(PeerId peerId, Inet::IPAddress & addr, uint16_t & port); /** @@ -243,8 +233,8 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeMgrDelegate, virtual CHIP_ERROR GetConnectedDevice(NodeId deviceId, Callback::Callback * onConnection, Callback::Callback * onFailure) { - return GetOperationalDeviceWithAddress(deviceId, Transport::PeerAddress::UDP(Inet::IPAddress::Any), onConnection, - onFailure); + VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); + return mCASESessionManager->FindOrEstablishSession(deviceId, onConnection, onFailure); } /** @@ -255,7 +245,11 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeMgrDelegate, * * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. */ - CHIP_ERROR UpdateDevice(NodeId deviceId); + CHIP_ERROR UpdateDevice(NodeId deviceId) + { + VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); + return mCASESessionManager->ResolveDeviceAddress(deviceId); + } /** * @brief @@ -336,15 +330,6 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeMgrDelegate, */ uint64_t GetFabricId() const { return mFabricId; } - DeviceControllerInteractionModelDelegate * GetInteractionModelDelegate() - { - if (mSystemState != nullptr) - { - return mSystemState->IMDelegate(); - } - return nullptr; - } - void ReleaseOperationalDevice(NodeId remoteDeviceId); protected: @@ -356,7 +341,9 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeMgrDelegate, State mState; - BitMapObjectPool mOperationalDevices; + CASESessionManager * mCASESessionManager = nullptr; + + Dnssd::DnssdCache mDNSCache; SerializableU64Set mPairedDevices; bool mPairedDevicesInitialized; @@ -390,7 +377,7 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeMgrDelegate, uint16_t mVendorId; //////////// ExchangeMgrDelegate Implementation /////////////// - void OnNewConnection(SessionHandle session, Messaging::ExchangeManager * mgr) override; + void OnNewConnection(SessionHandle session, Messaging::ExchangeManager * mgr) override {} void OnConnectionExpired(SessionHandle session, Messaging::ExchangeManager * mgr) override; #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD @@ -401,12 +388,8 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeMgrDelegate, #endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD private: - OperationalDeviceProxy * FindOperationalDevice(SessionHandle session); - OperationalDeviceProxy * FindOperationalDevice(NodeId id); void ReleaseOperationalDevice(OperationalDeviceProxy * device); - void ReleaseAllDevices(); - Callback::Callback mOpenPairingSuccessCallback; Callback::Callback mOpenPairingFailureCallback;