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