Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2021 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : #include <app/CASESessionManager.h>
20 : #include <lib/address_resolve/AddressResolve.h>
21 :
22 : namespace chip {
23 :
24 1 : CHIP_ERROR CASESessionManager::Init(chip::System::Layer * systemLayer, const CASESessionManagerConfig & params)
25 : {
26 1 : ReturnErrorOnFailure(params.sessionInitParams.Validate());
27 1 : mConfig = params;
28 1 : params.sessionInitParams.exchangeMgr->GetReliableMessageMgr()->RegisterSessionUpdateDelegate(this);
29 1 : return AddressResolve::Resolver::Instance().Init(systemLayer);
30 : }
31 :
32 0 : void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
33 : Callback::Callback<OnDeviceConnectionFailure> * onFailure
34 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
35 : ,
36 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
37 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
38 : )
39 : {
40 0 : FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr
41 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
42 : ,
43 : attemptCount, onRetry
44 : #endif
45 : );
46 0 : }
47 :
48 0 : void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
49 : Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure
50 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
51 : ,
52 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
53 : #endif
54 : )
55 : {
56 0 : FindOrEstablishSessionHelper(peerId, onConnection, nullptr, onSetupFailure
57 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
58 : ,
59 : attemptCount, onRetry
60 : #endif
61 : );
62 0 : }
63 :
64 0 : void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
65 : nullptr_t
66 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
67 : ,
68 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
69 : #endif
70 : )
71 : {
72 0 : FindOrEstablishSessionHelper(peerId, onConnection, nullptr, nullptr
73 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
74 : ,
75 : attemptCount, onRetry
76 : #endif
77 : );
78 0 : }
79 :
80 0 : void CASESessionManager::FindOrEstablishSessionHelper(const ScopedNodeId & peerId,
81 : Callback::Callback<OnDeviceConnected> * onConnection,
82 : Callback::Callback<OnDeviceConnectionFailure> * onFailure,
83 : Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure
84 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
85 : ,
86 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry
87 : #endif
88 : )
89 : {
90 0 : ChipLogDetail(CASESessionManager, "FindOrEstablishSession: PeerId = [%d:" ChipLogFormatX64 "]", peerId.GetFabricIndex(),
91 : ChipLogValueX64(peerId.GetNodeId()));
92 :
93 0 : bool forAddressUpdate = false;
94 0 : OperationalSessionSetup * session = FindExistingSessionSetup(peerId, forAddressUpdate);
95 0 : if (session == nullptr)
96 : {
97 0 : ChipLogDetail(CASESessionManager, "FindOrEstablishSession: No existing OperationalSessionSetup instance found");
98 0 : session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this);
99 :
100 0 : if (session == nullptr)
101 : {
102 0 : if (onFailure != nullptr)
103 : {
104 0 : onFailure->mCall(onFailure->mContext, peerId, CHIP_ERROR_NO_MEMORY);
105 : }
106 :
107 0 : if (onSetupFailure != nullptr)
108 : {
109 : OperationalSessionSetup::ConnnectionFailureInfo failureInfo(peerId, CHIP_ERROR_NO_MEMORY,
110 0 : SessionEstablishmentStage::kUnknown);
111 0 : onSetupFailure->mCall(onSetupFailure->mContext, failureInfo);
112 : }
113 0 : return;
114 : }
115 : }
116 :
117 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
118 0 : session->UpdateAttemptCount(attemptCount);
119 0 : if (onRetry)
120 : {
121 0 : session->AddRetryHandler(onRetry);
122 : }
123 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
124 :
125 0 : if (onFailure != nullptr)
126 : {
127 0 : session->Connect(onConnection, onFailure);
128 : }
129 :
130 0 : if (onSetupFailure != nullptr)
131 : {
132 0 : session->Connect(onConnection, onSetupFailure);
133 : }
134 : }
135 :
136 0 : void CASESessionManager::ReleaseSessionsForFabric(FabricIndex fabricIndex)
137 : {
138 0 : mConfig.sessionSetupPool->ReleaseAllSessionSetupsForFabric(fabricIndex);
139 0 : }
140 :
141 0 : void CASESessionManager::ReleaseAllSessions()
142 : {
143 0 : mConfig.sessionSetupPool->ReleaseAllSessionSetup();
144 0 : }
145 :
146 0 : CHIP_ERROR CASESessionManager::GetPeerAddress(const ScopedNodeId & peerId, Transport::PeerAddress & addr)
147 : {
148 0 : ReturnErrorOnFailure(mConfig.sessionInitParams.Validate());
149 0 : auto optionalSessionHandle = FindExistingSession(peerId);
150 0 : ReturnErrorCodeIf(!optionalSessionHandle.HasValue(), CHIP_ERROR_NOT_CONNECTED);
151 0 : addr = optionalSessionHandle.Value()->AsSecureSession()->GetPeerAddress();
152 0 : return CHIP_NO_ERROR;
153 0 : }
154 :
155 0 : void CASESessionManager::UpdatePeerAddress(ScopedNodeId peerId)
156 : {
157 0 : bool forAddressUpdate = true;
158 0 : OperationalSessionSetup * session = FindExistingSessionSetup(peerId, forAddressUpdate);
159 0 : if (session == nullptr)
160 : {
161 0 : ChipLogDetail(CASESessionManager, "UpdatePeerAddress: No existing OperationalSessionSetup instance found");
162 :
163 0 : session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this);
164 0 : if (session == nullptr)
165 : {
166 0 : ChipLogDetail(CASESessionManager, "UpdatePeerAddress: Failed to allocate OperationalSessionSetup instance");
167 0 : return;
168 : }
169 : }
170 : else
171 : {
172 0 : ChipLogDetail(CASESessionManager,
173 : "UpdatePeerAddress: Found existing OperationalSessionSetup instance for peerId[" ChipLogFormatX64 "]",
174 : ChipLogValueX64(peerId.GetNodeId()));
175 : }
176 :
177 0 : session->PerformAddressUpdate();
178 : }
179 :
180 0 : OperationalSessionSetup * CASESessionManager::FindExistingSessionSetup(const ScopedNodeId & peerId, bool forAddressUpdate) const
181 : {
182 0 : return mConfig.sessionSetupPool->FindSessionSetup(peerId, forAddressUpdate);
183 : }
184 :
185 0 : Optional<SessionHandle> CASESessionManager::FindExistingSession(const ScopedNodeId & peerId) const
186 : {
187 0 : return mConfig.sessionInitParams.sessionManager->FindSecureSessionForNode(peerId,
188 0 : MakeOptional(Transport::SecureSession::Type::kCASE));
189 : }
190 :
191 0 : void CASESessionManager::ReleaseSession(OperationalSessionSetup * session)
192 : {
193 0 : if (session != nullptr)
194 : {
195 0 : mConfig.sessionSetupPool->Release(session);
196 : }
197 0 : }
198 :
199 : } // namespace chip
|