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