LCOV - code coverage report
Current view: top level - messaging - ExchangeMgr.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 14 14 100.0 %
Date: 2024-02-15 08:20:41 Functions: 10 13 76.9 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2020 Project CHIP Authors
       4             :  *
       5             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6             :  *    you may not use this file except in compliance with the License.
       7             :  *    You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  *    Unless required by applicable law or agreed to in writing, software
      12             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  *    See the License for the specific language governing permissions and
      15             :  *    limitations under the License.
      16             :  */
      17             : 
      18             : /**
      19             :  *    @file
      20             :  *      Defines the CHIP ExchangeManager class and its supporting types
      21             :  *      for Exchange management.
      22             :  *
      23             :  */
      24             : 
      25             : #pragma once
      26             : 
      27             : #include <array>
      28             : 
      29             : #include <lib/support/DLLUtil.h>
      30             : #include <lib/support/Pool.h>
      31             : #include <lib/support/TypeTraits.h>
      32             : #include <messaging/ExchangeContext.h>
      33             : #include <messaging/ReliableMessageMgr.h>
      34             : #include <protocols/Protocols.h>
      35             : #include <transport/SessionManager.h>
      36             : 
      37             : namespace chip {
      38             : namespace Messaging {
      39             : 
      40             : class ExchangeContext;
      41             : class ExchangeDelegate;
      42             : 
      43             : static constexpr int16_t kAnyMessageType = -1;
      44             : 
      45             : /**
      46             :  *  @brief
      47             :  *    This class is used to manage ExchangeContexts with other CHIP nodes.
      48             :  *    It works on be behalf of higher layers, creating ExchangeContexts and
      49             :  *    handling the registration/unregistration of unsolicited message handlers.
      50             :  */
      51             : class DLL_EXPORT ExchangeManager : public SessionMessageDelegate
      52             : {
      53             :     friend class ExchangeContext;
      54             : 
      55             : public:
      56             :     ExchangeManager();
      57             :     ExchangeManager(const ExchangeManager &)           = delete;
      58             :     ExchangeManager operator=(const ExchangeManager &) = delete;
      59             : 
      60             :     /**
      61             :      *  Initialize the ExchangeManager object. Within the lifetime
      62             :      *  of this instance, this method is invoked once after object
      63             :      *  construction until a call to Shutdown is made to terminate the
      64             :      *  instance.
      65             :      *
      66             :      *  @param[in]    sessionManager    A pointer to the SessionManager object.
      67             :      *
      68             :      *  @retval #CHIP_ERROR_INCORRECT_STATE If the state is not equal to
      69             :      *          kState_NotInitialized.
      70             :      *  @retval #CHIP_NO_ERROR On success.
      71             :      *
      72             :      */
      73             :     CHIP_ERROR Init(SessionManager * sessionManager);
      74             : 
      75             :     /**
      76             :      *  Shutdown the ExchangeManager. This terminates this instance
      77             :      *  of the object and releases all held resources.
      78             :      *
      79             :      *  @note
      80             :      *     The protocol should only call this function after ensuring that
      81             :      *     there are no active ExchangeContext objects. Furthermore, it is the
      82             :      *     onus of the application to de-allocate the ExchangeManager
      83             :      *     object after calling ExchangeManager::Shutdown().
      84             :      */
      85             :     void Shutdown();
      86             : 
      87             :     /**
      88             :      *  Creates a new ExchangeContext with a given peer CHIP node specified by the peer node identifier.
      89             :      *
      90             :      *  @param[in]    session       The identifier of the secure session (possibly
      91             :      *                              the empty session for a non-secure exchange)
      92             :      *                              for which the ExchangeContext is being set up.
      93             :      *
      94             :      *  @param[in]    delegate      A pointer to ExchangeDelegate.
      95             :      *  @param[in]    isInitiator   Set to true if the exchange is created on the initiator. This is generally true
      96             :      *                              except in unit tests.
      97             :      *
      98             :      *  @return   A pointer to the created ExchangeContext object On success. Otherwise NULL if no object
      99             :      *            can be allocated or is available.
     100             :      */
     101             :     ExchangeContext * NewContext(const SessionHandle & session, ExchangeDelegate * delegate, bool isInitiator = true);
     102             : 
     103        3268 :     void ReleaseContext(ExchangeContext * ec) { mContextPool.ReleaseObject(ec); }
     104             : 
     105             :     /**
     106             :      *  Register an unsolicited message handler for a given protocol identifier. This handler would be
     107             :      *  invoked for all messages of the given protocol.
     108             :      *
     109             :      *  @param[in]    protocolId      The protocol identifier of the received message.
     110             :      *
     111             :      *  @param[in]    handler         A pointer to UnsolicitedMessageHandler.
     112             :      *
     113             :      *  @retval #CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS If the unsolicited message handler pool
     114             :      *                                                             is full and a new one cannot be allocated.
     115             :      *  @retval #CHIP_NO_ERROR On success.
     116             :      */
     117             :     CHIP_ERROR RegisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId, UnsolicitedMessageHandler * handler);
     118             : 
     119             :     /**
     120             :      *  Register an unsolicited message handler for a given protocol identifier and message type.
     121             :      *
     122             :      *  @param[in]    protocolId      The protocol identifier of the received message.
     123             :      *
     124             :      *  @param[in]    msgType         The message type of the corresponding protocol.
     125             :      *
     126             :      *  @param[in]    handler         A pointer to UnsolicitedMessageHandler.
     127             :      *
     128             :      *  @retval #CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS If the unsolicited message handler pool
     129             :      *                                                             is full and a new one cannot be allocated.
     130             :      *  @retval #CHIP_NO_ERROR On success.
     131             :      */
     132             :     CHIP_ERROR RegisterUnsolicitedMessageHandlerForType(Protocols::Id protocolId, uint8_t msgType,
     133             :                                                         UnsolicitedMessageHandler * handler);
     134             : 
     135             :     /**
     136             :      * A strongly-message-typed version of RegisterUnsolicitedMessageHandlerForType.
     137             :      */
     138             :     template <typename MessageType, typename = std::enable_if_t<std::is_enum<MessageType>::value>>
     139         300 :     CHIP_ERROR RegisterUnsolicitedMessageHandlerForType(MessageType msgType, UnsolicitedMessageHandler * handler)
     140             :     {
     141         300 :         return RegisterUnsolicitedMessageHandlerForType(Protocols::MessageTypeTraits<MessageType>::ProtocolId(),
     142         600 :                                                         to_underlying(msgType), handler);
     143             :     }
     144             : 
     145             :     /**
     146             :      *  Unregister an unsolicited message handler for a given protocol identifier.
     147             :      *
     148             :      *  @param[in]    protocolId     The protocol identifier of the received message.
     149             :      *
     150             :      *  @retval #CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER  If the matching unsolicited message handler
     151             :      *                                                       is not found.
     152             :      *  @retval #CHIP_NO_ERROR On success.
     153             :      */
     154             :     CHIP_ERROR UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId);
     155             : 
     156             :     /**
     157             :      *  Unregister an unsolicited message handler for a given protocol identifier and message type.
     158             :      *
     159             :      *  @param[in]    protocolId     The protocol identifier of the received message.
     160             :      *
     161             :      *  @param[in]    msgType       The message type of the corresponding protocol.
     162             :      *
     163             :      *  @retval #CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER  If the matching unsolicited message handler
     164             :      *                                                       is not found.
     165             :      *  @retval #CHIP_NO_ERROR On success.
     166             :      */
     167             :     CHIP_ERROR UnregisterUnsolicitedMessageHandlerForType(Protocols::Id protocolId, uint8_t msgType);
     168             : 
     169             :     /**
     170             :      * A strongly-message-typed version of UnregisterUnsolicitedMessageHandlerForType.
     171             :      */
     172             :     template <typename MessageType, typename = std::enable_if_t<std::is_enum<MessageType>::value>>
     173         307 :     CHIP_ERROR UnregisterUnsolicitedMessageHandlerForType(MessageType msgType)
     174             :     {
     175         307 :         return UnregisterUnsolicitedMessageHandlerForType(Protocols::MessageTypeTraits<MessageType>::ProtocolId(),
     176         614 :                                                           to_underlying(msgType));
     177             :     }
     178             : 
     179             :     /**
     180             :      * A method to call Close() on all contexts that have a given delegate as
     181             :      * their delegate.  To be used if the delegate is being destroyed.  This
     182             :      * method will guarantee that it does not call into the delegate.
     183             :      */
     184             :     void CloseAllContextsForDelegate(const ExchangeDelegate * delegate);
     185             : 
     186       26959 :     SessionManager * GetSessionManager() const { return mSessionManager; }
     187             : 
     188       25570 :     ReliableMessageMgr * GetReliableMessageMgr() { return &mReliableMessageMgr; };
     189             : 
     190             :     FabricIndex GetFabricIndex() const { return mFabricIndex; }
     191             : 
     192             :     uint16_t GetNextKeyId() { return ++mNextKeyId; }
     193             : 
     194             :     size_t GetNumActiveExchanges() { return mContextPool.Allocated(); }
     195             : 
     196             : private:
     197             :     enum class State
     198             :     {
     199             :         kState_NotInitialized = 0, // Used to indicate that the ExchangeManager is not initialized.
     200             :         kState_Initialized    = 1  // Used to indicate that the ExchangeManager is initialized.
     201             :     };
     202             : 
     203             :     struct UnsolicitedMessageHandlerSlot
     204             :     {
     205         608 :         UnsolicitedMessageHandlerSlot() : ProtocolId(Protocols::NotSpecified) {}
     206             : 
     207        3078 :         constexpr void Reset() { Handler = nullptr; }
     208       19432 :         constexpr bool IsInUse() const { return Handler != nullptr; }
     209             :         // Matches() only returns a sensible value if IsInUse() is true.
     210        1586 :         constexpr bool Matches(Protocols::Id aProtocolId, int16_t aMessageType) const
     211             :         {
     212        1586 :             return ProtocolId == aProtocolId && MessageType == aMessageType;
     213             :         }
     214             : 
     215             :         Protocols::Id ProtocolId;
     216             :         // Message types are normally 8-bit unsigned ints, but we use
     217             :         // kAnyMessageType, which is negative, to represent a wildcard handler,
     218             :         // so need a type that can store both that and all valid message type
     219             :         // values.
     220             :         int16_t MessageType;
     221             : 
     222             :         UnsolicitedMessageHandler * Handler;
     223             :     };
     224             : 
     225             :     uint16_t mNextExchangeId;
     226             :     uint16_t mNextKeyId;
     227             :     State mState;
     228             : 
     229             :     FabricIndex mFabricIndex = 0;
     230             : 
     231             :     ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> mContextPool;
     232             : 
     233             :     SessionManager * mSessionManager;
     234             :     ReliableMessageMgr mReliableMessageMgr;
     235             : 
     236             :     UnsolicitedMessageHandlerSlot UMHandlerPool[CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS];
     237             : 
     238             :     CHIP_ERROR RegisterUMH(Protocols::Id protocolId, int16_t msgType, UnsolicitedMessageHandler * handler);
     239             :     CHIP_ERROR UnregisterUMH(Protocols::Id protocolId, int16_t msgType);
     240             : 
     241             :     void OnMessageReceived(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader, const SessionHandle & session,
     242             :                            DuplicateMessage isDuplicate, System::PacketBufferHandle && msgBuf) override;
     243             :     void SendStandaloneAckIfNeeded(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
     244             :                                    const SessionHandle & session, MessageFlags msgFlags, System::PacketBufferHandle && msgBuf);
     245             : };
     246             : 
     247             : } // namespace Messaging
     248             : } // namespace chip

Generated by: LCOV version 1.14