/* * * 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 #include namespace chip { CHIP_ERROR CASESessionManager::Init(chip::System::Layer * systemLayer, const CASESessionManagerConfig & params) { ReturnErrorOnFailure(params.sessionInitParams.Validate()); mConfig = params; params.sessionInitParams.exchangeMgr->GetReliableMessageMgr()->RegisterSessionUpdateDelegate(this); return AddressResolve::Resolver::Instance().Init(systemLayer); } void CASESessionManager::Shutdown() { AddressResolve::Resolver::Instance().Shutdown(); } void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, Callback::Callback * onFailure, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES uint8_t attemptCount, Callback::Callback * onRetry, #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES TransportPayloadCapability transportPayloadCapability) { FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES attemptCount, onRetry, #endif transportPayloadCapability); } void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, Callback::Callback * onSetupFailure, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES uint8_t attemptCount, Callback::Callback * onRetry, #endif TransportPayloadCapability transportPayloadCapability) { FindOrEstablishSessionHelper(peerId, onConnection, nullptr, onSetupFailure, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES attemptCount, onRetry, #endif transportPayloadCapability); } void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, std::nullptr_t, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES uint8_t attemptCount, Callback::Callback * onRetry, #endif TransportPayloadCapability transportPayloadCapability) { FindOrEstablishSessionHelper(peerId, onConnection, nullptr, nullptr, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES attemptCount, onRetry, #endif transportPayloadCapability); } void CASESessionManager::FindOrEstablishSessionHelper(const ScopedNodeId & peerId, Callback::Callback * onConnection, Callback::Callback * onFailure, Callback::Callback * onSetupFailure, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES uint8_t attemptCount, Callback::Callback * onRetry, #endif TransportPayloadCapability transportPayloadCapability) { ChipLogDetail(CASESessionManager, "FindOrEstablishSession: PeerId = [%d:" ChipLogFormatX64 "]", peerId.GetFabricIndex(), ChipLogValueX64(peerId.GetNodeId())); bool forAddressUpdate = false; OperationalSessionSetup * session = FindExistingSessionSetup(peerId, forAddressUpdate); if (session == nullptr) { ChipLogDetail(CASESessionManager, "FindOrEstablishSession: No existing OperationalSessionSetup instance found"); session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this); if (session == nullptr) { if (onFailure != nullptr) { onFailure->mCall(onFailure->mContext, peerId, CHIP_ERROR_NO_MEMORY); } if (onSetupFailure != nullptr) { OperationalSessionSetup::ConnectionFailureInfo failureInfo(peerId, CHIP_ERROR_NO_MEMORY, SessionEstablishmentStage::kUnknown); onSetupFailure->mCall(onSetupFailure->mContext, failureInfo); } return; } } #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES session->UpdateAttemptCount(attemptCount); if (onRetry) { session->AddRetryHandler(onRetry); } #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES if (onFailure != nullptr) { session->Connect(onConnection, onFailure, transportPayloadCapability); } if (onSetupFailure != nullptr) { session->Connect(onConnection, onSetupFailure, transportPayloadCapability); } } void CASESessionManager::ReleaseSessionsForFabric(FabricIndex fabricIndex) { mConfig.sessionSetupPool->ReleaseAllSessionSetupsForFabric(fabricIndex); } void CASESessionManager::ReleaseAllSessions() { mConfig.sessionSetupPool->ReleaseAllSessionSetup(); } CHIP_ERROR CASESessionManager::GetPeerAddress(const ScopedNodeId & peerId, Transport::PeerAddress & addr, TransportPayloadCapability transportPayloadCapability) { ReturnErrorOnFailure(mConfig.sessionInitParams.Validate()); auto optionalSessionHandle = FindExistingSession(peerId, transportPayloadCapability); VerifyOrReturnError(optionalSessionHandle.HasValue(), CHIP_ERROR_NOT_CONNECTED); addr = optionalSessionHandle.Value()->AsSecureSession()->GetPeerAddress(); return CHIP_NO_ERROR; } void CASESessionManager::UpdatePeerAddress(ScopedNodeId peerId) { bool forAddressUpdate = true; OperationalSessionSetup * session = FindExistingSessionSetup(peerId, forAddressUpdate); if (session == nullptr) { ChipLogDetail(CASESessionManager, "UpdatePeerAddress: No existing OperationalSessionSetup instance found"); session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this); if (session == nullptr) { ChipLogDetail(CASESessionManager, "UpdatePeerAddress: Failed to allocate OperationalSessionSetup instance"); return; } } else { ChipLogDetail(CASESessionManager, "UpdatePeerAddress: Found existing OperationalSessionSetup instance for peerId[" ChipLogFormatX64 "]", ChipLogValueX64(peerId.GetNodeId())); } session->PerformAddressUpdate(); } OperationalSessionSetup * CASESessionManager::FindExistingSessionSetup(const ScopedNodeId & peerId, bool forAddressUpdate) const { return mConfig.sessionSetupPool->FindSessionSetup(peerId, forAddressUpdate); } Optional CASESessionManager::FindExistingSession(const ScopedNodeId & peerId, const TransportPayloadCapability transportPayloadCapability) const { return mConfig.sessionInitParams.sessionManager->FindSecureSessionForNode( peerId, MakeOptional(Transport::SecureSession::Type::kCASE), transportPayloadCapability); } void CASESessionManager::ReleaseSession(OperationalSessionSetup * session) { if (session != nullptr) { mConfig.sessionSetupPool->Release(session); } } } // namespace chip