Matter SDK Coverage Report
Current view: top level - messaging - ExchangeMgr.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 14 14
Test Date: 2025-01-17 19:00:11 Functions: 76.9 % 13 10

            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              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
      53              :     ,
      54              :                                    public SessionConnectionDelegate
      55              : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
      56              : {
      57              :     friend class ExchangeContext;
      58              : 
      59              : public:
      60              :     ExchangeManager();
      61              :     ExchangeManager(const ExchangeManager &)           = delete;
      62              :     ExchangeManager operator=(const ExchangeManager &) = delete;
      63              : 
      64              :     /**
      65              :      *  Initialize the ExchangeManager object. Within the lifetime
      66              :      *  of this instance, this method is invoked once after object
      67              :      *  construction until a call to Shutdown is made to terminate the
      68              :      *  instance.
      69              :      *
      70              :      *  @param[in]    sessionManager    A pointer to the SessionManager object.
      71              :      *
      72              :      *  @retval #CHIP_ERROR_INCORRECT_STATE If the state is not equal to
      73              :      *          kState_NotInitialized.
      74              :      *  @retval #CHIP_NO_ERROR On success.
      75              :      *
      76              :      */
      77              :     CHIP_ERROR Init(SessionManager * sessionManager);
      78              : 
      79              :     /**
      80              :      *  Shutdown the ExchangeManager. This terminates this instance
      81              :      *  of the object and releases all held resources.
      82              :      *
      83              :      * Please see documentation for SessionManager::Shutdown() for ordering
      84              :      * dependecies between that and this Shutdown() method.
      85              :      *
      86              :      *  @note
      87              :      *     The protocol should only call this function after ensuring that
      88              :      *     there are no active ExchangeContext objects (again, see
      89              :      *     SessionManager::Shutdown() documentation). Furthermore, it is the
      90              :      *     onus of the application to de-allocate the ExchangeManager
      91              :      *     object after calling ExchangeManager::Shutdown().
      92              :      */
      93              :     void Shutdown();
      94              : 
      95              :     /**
      96              :      *  Creates a new ExchangeContext with a given peer CHIP node specified by the peer node identifier.
      97              :      *
      98              :      *  @param[in]    session       The identifier of the secure session (possibly
      99              :      *                              the empty session for a non-secure exchange)
     100              :      *                              for which the ExchangeContext is being set up.
     101              :      *
     102              :      *  @param[in]    delegate      A pointer to ExchangeDelegate.
     103              :      *  @param[in]    isInitiator   Set to true if the exchange is created on the initiator. This is generally true
     104              :      *                              except in unit tests.
     105              :      *
     106              :      *  @return   A pointer to the created ExchangeContext object On success. Otherwise NULL if no object
     107              :      *            can be allocated or is available.
     108              :      */
     109              :     ExchangeContext * NewContext(const SessionHandle & session, ExchangeDelegate * delegate, bool isInitiator = true);
     110              : 
     111         3429 :     void ReleaseContext(ExchangeContext * ec) { mContextPool.ReleaseObject(ec); }
     112              : 
     113              :     /**
     114              :      *  Register an unsolicited message handler for a given protocol identifier. This handler would be
     115              :      *  invoked for all messages of the given protocol.
     116              :      *
     117              :      *  @param[in]    protocolId      The protocol identifier of the received message.
     118              :      *
     119              :      *  @param[in]    handler         A pointer to UnsolicitedMessageHandler.
     120              :      *
     121              :      *  @retval #CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS If the unsolicited message handler pool
     122              :      *                                                             is full and a new one cannot be allocated.
     123              :      *  @retval #CHIP_NO_ERROR On success.
     124              :      */
     125              :     CHIP_ERROR RegisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId, UnsolicitedMessageHandler * handler);
     126              : 
     127              :     /**
     128              :      *  Register an unsolicited message handler for a given protocol identifier and message type.
     129              :      *
     130              :      *  @param[in]    protocolId      The protocol identifier of the received message.
     131              :      *
     132              :      *  @param[in]    msgType         The message type of the corresponding protocol.
     133              :      *
     134              :      *  @param[in]    handler         A pointer to UnsolicitedMessageHandler.
     135              :      *
     136              :      *  @retval #CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS If the unsolicited message handler pool
     137              :      *                                                             is full and a new one cannot be allocated.
     138              :      *  @retval #CHIP_NO_ERROR On success.
     139              :      */
     140              :     CHIP_ERROR RegisterUnsolicitedMessageHandlerForType(Protocols::Id protocolId, uint8_t msgType,
     141              :                                                         UnsolicitedMessageHandler * handler);
     142              : 
     143              :     /**
     144              :      * A strongly-message-typed version of RegisterUnsolicitedMessageHandlerForType.
     145              :      */
     146              :     template <typename MessageType, typename = std::enable_if_t<std::is_enum<MessageType>::value>>
     147          336 :     CHIP_ERROR RegisterUnsolicitedMessageHandlerForType(MessageType msgType, UnsolicitedMessageHandler * handler)
     148              :     {
     149          336 :         return RegisterUnsolicitedMessageHandlerForType(Protocols::MessageTypeTraits<MessageType>::ProtocolId(),
     150          672 :                                                         to_underlying(msgType), handler);
     151              :     }
     152              : 
     153              :     /**
     154              :      *  Unregister an unsolicited message handler for a given protocol identifier.
     155              :      *
     156              :      *  @param[in]    protocolId     The protocol identifier of the received message.
     157              :      *
     158              :      *  @retval #CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER  If the matching unsolicited message handler
     159              :      *                                                       is not found.
     160              :      *  @retval #CHIP_NO_ERROR On success.
     161              :      */
     162              :     CHIP_ERROR UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId);
     163              : 
     164              :     /**
     165              :      *  Unregister an unsolicited message handler for a given protocol identifier and message type.
     166              :      *
     167              :      *  @param[in]    protocolId     The protocol identifier of the received message.
     168              :      *
     169              :      *  @param[in]    msgType       The message type of the corresponding protocol.
     170              :      *
     171              :      *  @retval #CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER  If the matching unsolicited message handler
     172              :      *                                                       is not found.
     173              :      *  @retval #CHIP_NO_ERROR On success.
     174              :      */
     175              :     CHIP_ERROR UnregisterUnsolicitedMessageHandlerForType(Protocols::Id protocolId, uint8_t msgType);
     176              : 
     177              :     /**
     178              :      * A strongly-message-typed version of UnregisterUnsolicitedMessageHandlerForType.
     179              :      */
     180              :     template <typename MessageType, typename = std::enable_if_t<std::is_enum<MessageType>::value>>
     181          342 :     CHIP_ERROR UnregisterUnsolicitedMessageHandlerForType(MessageType msgType)
     182              :     {
     183          342 :         return UnregisterUnsolicitedMessageHandlerForType(Protocols::MessageTypeTraits<MessageType>::ProtocolId(),
     184          684 :                                                           to_underlying(msgType));
     185              :     }
     186              : 
     187              :     /**
     188              :      * A method to call Close() on all contexts that have a given delegate as
     189              :      * their delegate.  To be used if the delegate is being destroyed.  This
     190              :      * method will guarantee that it does not call into the delegate.
     191              :      */
     192              :     void CloseAllContextsForDelegate(const ExchangeDelegate * delegate);
     193              : 
     194        27355 :     SessionManager * GetSessionManager() const { return mSessionManager; }
     195              : 
     196        25642 :     ReliableMessageMgr * GetReliableMessageMgr() { return &mReliableMessageMgr; };
     197              : 
     198              :     FabricIndex GetFabricIndex() const { return mFabricIndex; }
     199              : 
     200              :     uint16_t GetNextKeyId() { return ++mNextKeyId; }
     201              : 
     202              :     size_t GetNumActiveExchanges() { return mContextPool.Allocated(); }
     203              : 
     204              : private:
     205              :     enum class State
     206              :     {
     207              :         kState_NotInitialized = 0, // Used to indicate that the ExchangeManager is not initialized.
     208              :         kState_Initialized    = 1  // Used to indicate that the ExchangeManager is initialized.
     209              :     };
     210              : 
     211              :     struct UnsolicitedMessageHandlerSlot
     212              :     {
     213         3152 :         UnsolicitedMessageHandlerSlot() : ProtocolId(Protocols::NotSpecified) {}
     214              : 
     215         3432 :         constexpr void Reset() { Handler = nullptr; }
     216        19818 :         constexpr bool IsInUse() const { return Handler != nullptr; }
     217              :         // Matches() only returns a sensible value if IsInUse() is true.
     218         1620 :         constexpr bool Matches(Protocols::Id aProtocolId, int16_t aMessageType) const
     219              :         {
     220         1620 :             return ProtocolId == aProtocolId && MessageType == aMessageType;
     221              :         }
     222              : 
     223              :         Protocols::Id ProtocolId;
     224              :         // Message types are normally 8-bit unsigned ints, but we use
     225              :         // kAnyMessageType, which is negative, to represent a wildcard handler,
     226              :         // so need a type that can store both that and all valid message type
     227              :         // values.
     228              :         int16_t MessageType;
     229              : 
     230              :         UnsolicitedMessageHandler * Handler;
     231              :     };
     232              : 
     233              :     uint16_t mNextExchangeId;
     234              :     uint16_t mNextKeyId;
     235              :     State mState;
     236              : 
     237              :     FabricIndex mFabricIndex = 0;
     238              : 
     239              :     ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> mContextPool;
     240              : 
     241              :     SessionManager * mSessionManager;
     242              :     ReliableMessageMgr mReliableMessageMgr;
     243              : 
     244              :     UnsolicitedMessageHandlerSlot UMHandlerPool[CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS];
     245              : 
     246              :     CHIP_ERROR RegisterUMH(Protocols::Id protocolId, int16_t msgType, UnsolicitedMessageHandler * handler);
     247              :     CHIP_ERROR UnregisterUMH(Protocols::Id protocolId, int16_t msgType);
     248              : 
     249              :     void OnMessageReceived(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader, const SessionHandle & session,
     250              :                            DuplicateMessage isDuplicate, System::PacketBufferHandle && msgBuf) override;
     251              :     void SendStandaloneAckIfNeeded(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
     252              :                                    const SessionHandle & session, MessageFlags msgFlags, System::PacketBufferHandle && msgBuf);
     253              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     254              :     void OnTCPConnectionClosed(const SessionHandle & session, CHIP_ERROR conErr) override;
     255              : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
     256              : };
     257              : 
     258              : } // namespace Messaging
     259              : } // namespace chip
        

Generated by: LCOV version 2.0-1