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 1 : void CASESessionManager::Shutdown()
33 : {
34 1 : AddressResolve::Resolver::Instance().Shutdown();
35 1 : }
36 :
37 0 : void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
38 : Callback::Callback<OnDeviceConnectionFailure> * onFailure,
39 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
40 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
41 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
42 : TransportPayloadCapability transportPayloadCapability,
43 : const Optional<AddressResolve::ResolveResult> & fallbackResolveResult)
44 : {
45 0 : FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr,
46 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
47 : attemptCount, onRetry,
48 : #endif
49 : transportPayloadCapability, fallbackResolveResult);
50 0 : }
51 :
52 0 : void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
53 : Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
54 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
55 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
56 : #endif
57 : TransportPayloadCapability transportPayloadCapability)
58 : {
59 0 : FindOrEstablishSessionHelper(peerId, onConnection, nullptr, onSetupFailure,
60 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
61 : attemptCount, onRetry,
62 : #endif
63 : transportPayloadCapability);
64 0 : }
65 :
66 0 : void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
67 : std::nullptr_t,
68 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
69 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
70 : #endif
71 : TransportPayloadCapability transportPayloadCapability)
72 : {
73 0 : FindOrEstablishSessionHelper(peerId, onConnection, nullptr, nullptr,
74 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
75 : attemptCount, onRetry,
76 : #endif
77 : transportPayloadCapability);
78 0 : }
79 :
80 0 : void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback<OnDeviceConnected> * onConnection,
81 : Callback::Callback<OnDeviceConnectionFailure> * onFailure,
82 : TransportPayloadCapability transportPayloadCapability)
83 : {
84 0 : FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr,
85 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
86 : 1 /* attemptCount */, nullptr /* onRetry */,
87 : #endif
88 : transportPayloadCapability);
89 0 : }
90 :
91 0 : void CASESessionManager::FindOrEstablishSessionHelper(const ScopedNodeId & peerId,
92 : Callback::Callback<OnDeviceConnected> * onConnection,
93 : Callback::Callback<OnDeviceConnectionFailure> * onFailure,
94 : Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
95 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
96 : uint8_t attemptCount, Callback::Callback<OnDeviceConnectionRetry> * onRetry,
97 : #endif
98 : TransportPayloadCapability transportPayloadCapability,
99 : const Optional<AddressResolve::ResolveResult> & fallbackResolveResult)
100 : {
101 0 : ChipLogDetail(CASESessionManager, "FindOrEstablishSession: PeerId = [%d:" ChipLogFormatX64 "]", peerId.GetFabricIndex(),
102 : ChipLogValueX64(peerId.GetNodeId()));
103 :
104 0 : bool forAddressUpdate = false;
105 0 : OperationalSessionSetup * session = FindExistingSessionSetup(peerId, forAddressUpdate);
106 0 : if (session == nullptr)
107 : {
108 0 : ChipLogDetail(CASESessionManager, "FindOrEstablishSession: No existing OperationalSessionSetup instance found");
109 0 : session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this);
110 :
111 0 : if (session == nullptr)
112 : {
113 0 : if (onFailure != nullptr)
114 : {
115 0 : onFailure->mCall(onFailure->mContext, peerId, CHIP_ERROR_NO_MEMORY);
116 : }
117 :
118 0 : if (onSetupFailure != nullptr)
119 : {
120 : OperationalSessionSetup::ConnectionFailureInfo failureInfo(peerId, CHIP_ERROR_NO_MEMORY,
121 0 : SessionEstablishmentStage::kUnknown);
122 0 : onSetupFailure->mCall(onSetupFailure->mContext, failureInfo);
123 : }
124 0 : return;
125 : }
126 : }
127 :
128 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
129 0 : session->UpdateAttemptCount(attemptCount);
130 0 : if (onRetry)
131 : {
132 0 : session->AddRetryHandler(onRetry);
133 : }
134 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
135 :
136 : #if CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
137 : // Set fallback resolve result if provided
138 : if (fallbackResolveResult.HasValue())
139 : {
140 : session->SetFallbackResolveResult(fallbackResolveResult.Value());
141 : }
142 : #endif // CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
143 :
144 0 : if (onFailure != nullptr)
145 : {
146 0 : session->Connect(onConnection, onFailure, transportPayloadCapability);
147 : }
148 :
149 0 : if (onSetupFailure != nullptr)
150 : {
151 0 : session->Connect(onConnection, onSetupFailure, transportPayloadCapability);
152 : }
153 : }
154 :
155 0 : void CASESessionManager::ReleaseSessionsForFabric(FabricIndex fabricIndex)
156 : {
157 0 : mConfig.sessionSetupPool->ReleaseAllSessionSetupsForFabric(fabricIndex);
158 0 : }
159 :
160 0 : void CASESessionManager::ReleaseAllSessions()
161 : {
162 0 : mConfig.sessionSetupPool->ReleaseAllSessionSetup();
163 0 : }
164 :
165 0 : CHIP_ERROR CASESessionManager::GetPeerAddress(const ScopedNodeId & peerId, Transport::PeerAddress & addr,
166 : TransportPayloadCapability transportPayloadCapability)
167 : {
168 0 : ReturnErrorOnFailure(mConfig.sessionInitParams.Validate());
169 0 : auto optionalSessionHandle = FindExistingSession(peerId, transportPayloadCapability);
170 0 : VerifyOrReturnError(optionalSessionHandle.HasValue(), CHIP_ERROR_NOT_CONNECTED);
171 0 : addr = optionalSessionHandle.Value()->AsSecureSession()->GetPeerAddress();
172 0 : return CHIP_NO_ERROR;
173 0 : }
174 :
175 0 : void CASESessionManager::UpdatePeerAddress(ScopedNodeId peerId)
176 : {
177 0 : bool forAddressUpdate = true;
178 0 : OperationalSessionSetup * session = FindExistingSessionSetup(peerId, forAddressUpdate);
179 0 : if (session == nullptr)
180 : {
181 0 : ChipLogDetail(CASESessionManager, "UpdatePeerAddress: No existing OperationalSessionSetup instance found");
182 :
183 0 : session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this);
184 0 : if (session == nullptr)
185 : {
186 0 : ChipLogDetail(CASESessionManager, "UpdatePeerAddress: Failed to allocate OperationalSessionSetup instance");
187 0 : return;
188 : }
189 : }
190 : else
191 : {
192 0 : ChipLogDetail(CASESessionManager,
193 : "UpdatePeerAddress: Found existing OperationalSessionSetup instance for peerId[" ChipLogFormatX64 "]",
194 : ChipLogValueX64(peerId.GetNodeId()));
195 : }
196 :
197 0 : session->PerformAddressUpdate();
198 : }
199 :
200 0 : OperationalSessionSetup * CASESessionManager::FindExistingSessionSetup(const ScopedNodeId & peerId, bool forAddressUpdate) const
201 : {
202 0 : return mConfig.sessionSetupPool->FindSessionSetup(peerId, forAddressUpdate);
203 : }
204 :
205 0 : Optional<SessionHandle> CASESessionManager::FindExistingSession(const ScopedNodeId & peerId,
206 : const TransportPayloadCapability transportPayloadCapability) const
207 : {
208 0 : return mConfig.sessionInitParams.sessionManager->FindSecureSessionForNode(
209 0 : peerId, MakeOptional(Transport::SecureSession::Type::kCASE), transportPayloadCapability);
210 : }
211 :
212 0 : void CASESessionManager::ReleaseSession(const ScopedNodeId & peerId)
213 : {
214 0 : auto * session = mConfig.sessionSetupPool->FindSessionSetup(peerId, false);
215 0 : ReleaseSession(session);
216 0 : }
217 :
218 0 : void CASESessionManager::ReleaseSession(OperationalSessionSetup * session)
219 : {
220 0 : if (session != nullptr)
221 : {
222 0 : mConfig.sessionSetupPool->Release(session);
223 : }
224 0 : }
225 :
226 : } // namespace chip
|