| /* |
| * |
| * Copyright (c) 2021 Project CHIP Authors |
| * |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #include <credentials/CertificateValidityPolicy.h> |
| #include <credentials/GroupDataProvider.h> |
| #include <messaging/ExchangeDelegate.h> |
| #include <messaging/ExchangeMgr.h> |
| #include <protocols/secure_channel/CASESession.h> |
| #include <system/SystemClock.h> |
| |
| namespace chip { |
| |
| class CASEServer : public SessionEstablishmentDelegate, |
| public Messaging::UnsolicitedMessageHandler, |
| public Messaging::ExchangeDelegate |
| { |
| public: |
| CASEServer() {} |
| ~CASEServer() override { Shutdown(); } |
| |
| /* |
| * This method will shutdown this object, releasing the strong reference to the pinned SecureSession object. |
| * It will also unregister the unsolicited handler and clear out the session object (which will release the weak |
| * reference through the underlying SessionHolder). |
| * |
| */ |
| void Shutdown() |
| { |
| if (mExchangeManager != nullptr) |
| { |
| mExchangeManager->UnregisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::CASE_Sigma1); |
| mExchangeManager = nullptr; |
| } |
| |
| GetSession().Clear(); |
| mPinnedSecureSession.ClearValue(); |
| } |
| |
| CHIP_ERROR ListenForSessionEstablishment(Messaging::ExchangeManager * exchangeManager, SessionManager * sessionManager, |
| FabricTable * fabrics, SessionResumptionStorage * sessionResumptionStorage, |
| Credentials::CertificateValidityPolicy * policy, |
| Credentials::GroupDataProvider * responderGroupDataProvider); |
| |
| //////////// SessionEstablishmentDelegate Implementation /////////////// |
| void OnSessionEstablishmentError(CHIP_ERROR error) override; |
| void OnSessionEstablished(const SessionHandle & session) override; |
| |
| //// UnsolicitedMessageHandler Implementation //// |
| CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override; |
| |
| //// ExchangeDelegate Implementation //// |
| CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, |
| System::PacketBufferHandle && payload) override; |
| void OnResponseTimeout(Messaging::ExchangeContext * ec) override {} |
| Messaging::ExchangeMessageDispatch & GetMessageDispatch() override { return GetSession().GetMessageDispatch(); } |
| |
| CASESession & GetSession() { return mPairingSession; } |
| |
| private: |
| Messaging::ExchangeManager * mExchangeManager = nullptr; |
| SessionResumptionStorage * mSessionResumptionStorage = nullptr; |
| Credentials::CertificateValidityPolicy * mCertificateValidityPolicy = nullptr; |
| |
| // |
| // When we're in the process of establishing a session, this is used |
| // to maintain an additional, strong reference to the underlying SecureSession. |
| // This is because the existing reference in PairingSession is a weak one |
| // (i.e a SessionHolder) and can lose its reference if the session is evicted |
| // for any reason. |
| // |
| // This initially points to a session that is not yet active. Upon activation, it |
| // transfers ownership of the session to the SecureSessionManager and this reference |
| // is released before simultaneously acquiring ownership of a new SecureSession. |
| // |
| Optional<SessionHandle> mPinnedSecureSession; |
| |
| CASESession mPairingSession; |
| SessionManager * mSessionManager = nullptr; |
| |
| FabricTable * mFabrics = nullptr; |
| Credentials::GroupDataProvider * mGroupDataProvider = nullptr; |
| |
| CHIP_ERROR InitCASEHandshake(Messaging::ExchangeContext * ec); |
| |
| /* |
| * This will clean up any state from a previous session establishment |
| * attempt (if any) and setup the machinery to listen for and handle |
| * any session handshakes there-after. |
| * |
| * If a session had previously been established successfully, previouslyEstablishedPeer |
| * should be set to the scoped node-id of the peer associated with that session. |
| * |
| */ |
| void PrepareForSessionEstablishment(const ScopedNodeId & previouslyEstablishedPeer = ScopedNodeId()); |
| |
| // If we are in the middle of handshake and receive a Sigma1 then respond with Busy status code. |
| // @param[in] ec Exchange Context |
| // @param[in] minimumWaitTime Minimum wait time reported to client before it can attempt to resend sigma1 |
| // |
| // @return CHIP_NO_ERROR on success, error code otherwise |
| CHIP_ERROR SendBusyStatusReport(Messaging::ExchangeContext * ec, System::Clock::Milliseconds16 minimumWaitTime); |
| }; |
| |
| } // namespace chip |