Matter SDK Coverage Report
Current view: top level - messaging - ReliableMessageMgr.h (source / functions) Coverage Total Hit
Test: SHA:f84fe08d06f240e801b5d923f8a938a9938ca110 Lines: 100.0 % 5 5
Test Date: 2025-02-22 08:08:07 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2020 Project CHIP Authors
       3              :  *    All rights reserved.
       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              :  *      This file defines the classes corresponding to CHIP reliable message
      21              :  *      protocol.
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <array>
      27              : #include <stdint.h>
      28              : 
      29              : #include <lib/core/CHIPError.h>
      30              : #include <lib/core/Optional.h>
      31              : #include <lib/support/BitFlags.h>
      32              : #include <lib/support/Pool.h>
      33              : #include <messaging/ExchangeContext.h>
      34              : #include <messaging/ReliableMessageAnalyticsDelegate.h>
      35              : #include <messaging/ReliableMessageProtocolConfig.h>
      36              : #include <system/SystemLayer.h>
      37              : #include <system/SystemPacketBuffer.h>
      38              : #include <transport/SessionUpdateDelegate.h>
      39              : #include <transport/raw/MessageHeader.h>
      40              : 
      41              : namespace chip {
      42              : namespace Messaging {
      43              : 
      44              : enum class SendMessageFlags : uint16_t;
      45              : class ReliableMessageContext;
      46              : 
      47              : class ReliableMessageMgr
      48              : {
      49              : public:
      50              :     /**
      51              :      *  @class RetransTableEntry
      52              :      *
      53              :      *  @brief
      54              :      *    This class is part of the CHIP Reliable Messaging Protocol and is used
      55              :      *    to keep track of CHIP messages that have been sent and are expecting an
      56              :      *    acknowledgment back. If the acknowledgment is not received within a
      57              :      *    specific timeout, the message would be retransmitted from this table.
      58              :      *
      59              :      */
      60              :     struct RetransTableEntry
      61              :     {
      62              :         RetransTableEntry(ReliableMessageContext * rc);
      63              :         ~RetransTableEntry();
      64              : 
      65              :         ExchangeHandle ec;                        /**< The context for the stored CHIP message. */
      66              :         EncryptedPacketBufferHandle retainedBuf;  /**< The packet buffer holding the CHIP message. */
      67              :         System::Clock::Timestamp nextRetransTime; /**< A counter representing the next retransmission time for the message. */
      68              :         uint8_t sendCount;                        /**< The number of times we have tried to send this entry,
      69              :                                                        including both successfully and failure send. */
      70              :     };
      71              : 
      72              :     ReliableMessageMgr(ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & contextPool);
      73              :     ~ReliableMessageMgr();
      74              : 
      75              :     void Init(chip::System::Layer * systemLayer);
      76              :     void Shutdown();
      77              : 
      78              :     /**
      79              :      * Iterate through active exchange contexts and retrans table entries.  If an
      80              :      * action needs to be triggered by ReliableMessageProtocol time facilities,
      81              :      * execute that action.
      82              :      */
      83              :     void ExecuteActions();
      84              : 
      85              :     /**
      86              :      * Handle physical wakeup of system due to ReliableMessageProtocol wakeup.
      87              :      *
      88              :      */
      89              :     static void Timeout(System::Layer * aSystemLayer, void * aAppState);
      90              : 
      91              :     /**
      92              :      *  Add a CHIP message into the retransmission table to be subsequently resent if a corresponding acknowledgment
      93              :      *  is not received within the retransmission timeout.
      94              :      *
      95              :      *  @param[in]    rc        A pointer to the ExchangeContext object.
      96              :      *
      97              :      *  @param[out]   rEntry    A pointer to a pointer of a retransmission table entry added into the table.
      98              :      *
      99              :      *  @retval  #CHIP_ERROR_RETRANS_TABLE_FULL If there is no empty slot left in the table for addition.
     100              :      *  @retval  #CHIP_NO_ERROR On success.
     101              :      */
     102              :     CHIP_ERROR AddToRetransTable(ReliableMessageContext * rc, RetransTableEntry ** rEntry);
     103              : 
     104              :     /**
     105              :      *  Calculate the backoff timer for the retransmission.
     106              :      *
     107              :      *  @param[in]   baseInterval         The base interval to use for the backoff calculation, either the active or idle interval.
     108              :      *  @param[in]   sendCount            Count of how many times this message
     109              :      *                                    has been retransmitted so far (0 if it has
     110              :      *                                    been sent only once with no retransmits,
     111              :      *                                    1 if it has been sent twice, etc).
     112              :      *  @param[in]   computeMaxPossible   Disable randomness such that the maximum value is used instead.
     113              :      *
     114              :      *  @retval  The backoff time value, including jitter.
     115              :      */
     116              :     static System::Clock::Timeout GetBackoff(System::Clock::Timeout baseInterval, uint8_t sendCount,
     117              :                                              bool computeMaxPossible = false);
     118              : 
     119              :     /**
     120              :      *  Start retranmisttion of cached encryped packet for current entry.
     121              :      *
     122              :      *  @param[in]   entry    A pointer to a retransmission table entry added into the table.
     123              :      *
     124              :      *  @retval  #CHIP_NO_ERROR On success.
     125              :      */
     126              :     void StartRetransmision(RetransTableEntry * entry);
     127              : 
     128              :     /**
     129              :      *  Iterate through active exchange contexts and retrans table entries. Clear the entry matching
     130              :      *  the specified ExchangeContext and the message ID from the retransmision table.
     131              :      *
     132              :      *  @param[in]    rc                 A pointer to the ExchangeContext object.
     133              :      *  @param[in]    ackMessageCounter  The acknowledged message counter of the received packet.
     134              :      *
     135              :      *  @retval  #CHIP_NO_ERROR On success.
     136              :      */
     137              :     bool CheckAndRemRetransTable(ReliableMessageContext * rc, uint32_t ackMessageCounter);
     138              : 
     139              :     /**
     140              :      *  Send the specified entry from the retransmission table.
     141              :      *
     142              :      *  @param[in]    entry     A pointer to a retransmission table entry object that needs to be sent.
     143              :      *
     144              :      *  @return  #CHIP_NO_ERROR On success, else corresponding CHIP_ERROR returned from SendMessage.
     145              :      */
     146              :     CHIP_ERROR SendFromRetransTable(RetransTableEntry * entry);
     147              : 
     148              :     /**
     149              :      *  Clear entries matching a specified ExchangeContext.
     150              :      *
     151              :      *  @param[in]    rc    A pointer to the ExchangeContext object.
     152              :      *
     153              :      */
     154              :     void ClearRetransTable(ReliableMessageContext * rc);
     155              : 
     156              :     /**
     157              :      *  Clear an entry in the retransmission table.
     158              :      *
     159              :      *  @param[in]    rEntry   A reference to the RetransTableEntry object.
     160              :      *
     161              :      */
     162              :     void ClearRetransTable(RetransTableEntry & rEntry);
     163              : 
     164              :     /**
     165              :      * Iterate through active exchange contexts and retrans table entries.
     166              :      * Determine how many ReliableMessageProtocol ticks we need to sleep before we
     167              :      * need to physically wake the CPU to perform an action.  Set a timer to go off
     168              :      * when we next need to wake the system.
     169              :      *
     170              :      */
     171              :     void StartTimer();
     172              : 
     173              :     /**
     174              :      * Stop the timer for retransmistion on current node.
     175              :      *
     176              :      */
     177              :     void StopTimer();
     178              : 
     179              :     /**
     180              :      *  Registers a delegate to perform an address lookup and update all active sessions.
     181              :      *
     182              :      *  @param[in] sessionUpdateDelegate - Pointer to delegate to perform address lookup
     183              :      *             that will update all active session. A null pointer is allowed if you
     184              :      *             no longer have a valid delegate.
     185              :      *
     186              :      */
     187              :     void RegisterSessionUpdateDelegate(SessionUpdateDelegate * sessionUpdateDelegate);
     188              : 
     189              : #if CHIP_CONFIG_MRP_ANALYTICS_ENABLED
     190              :     /**
     191              :      *  Registers a delegate interested in analytic information
     192              :      *
     193              :      *  @param[in] analyticsDelegate - Pointer to delegate for reporting analytic
     194              :      */
     195              :     void RegisterAnalyticsDelegate(ReliableMessageAnalyticsDelegate * analyticsDelegate);
     196              : #endif // CHIP_CONFIG_MRP_ANALYTICS_ENABLED
     197              : 
     198              :     /**
     199              :      * Map a send error code to the error code we should actually use for
     200              :      * success checks.  This maps some error codes to CHIP_NO_ERROR as
     201              :      * appropriate.
     202              :      */
     203              :     static CHIP_ERROR MapSendError(CHIP_ERROR error, uint16_t exchangeId, bool isInitiator);
     204              : 
     205              : #if CHIP_CONFIG_TEST
     206              :     // Functions for testing
     207              :     int TestGetCountRetransTable();
     208              : 
     209              :     // Enumerate the retransmission table.  Clearing an entry while enumerating
     210              :     // that entry is allowed.  F must take a RetransTableEntry as an argument
     211              :     // and return Loop::Continue or Loop::Break.
     212              :     template <typename F>
     213              :     void EnumerateRetransTable(F && functor)
     214              :     {
     215              :         mRetransTable.ForEachActiveObject(std::forward<F>(functor));
     216              :     }
     217              : #endif // CHIP_CONFIG_TEST
     218              : 
     219              :     /**
     220              :      * Set the value to add to the MRP backoff time we compute.  This is meant to
     221              :      * account for high network latency on the sending side (us) that can't be
     222              :      * known to the message recipient and hence is not captured in the MRP
     223              :      * parameters the message recipient communicates to us.
     224              :      *
     225              :      * If set to NullOptional falls back to the compile-time
     226              :      * CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST.
     227              :      *
     228              :      * This is a static, not a regular member, because API consumers may need to
     229              :      * set this before actually bringing up the stack and having access to a
     230              :      * ReliableMessageMgr.
     231              :      */
     232              :     static void SetAdditionalMRPBackoffTime(const Optional<System::Clock::Timeout> & additionalTime);
     233              : 
     234              : private:
     235              :     /**
     236              :      * Calculates the next retransmission time for the entry
     237              :      * Function sets the nextRetransTime of the entry
     238              :      *
     239              :      * @param[in,out] entry RetransTableEntry for which we need to calculate the nextRetransTime
     240              :      */
     241              :     void CalculateNextRetransTime(RetransTableEntry & entry);
     242              : 
     243              :     ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & mContextPool;
     244              :     chip::System::Layer * mSystemLayer;
     245              : 
     246              :     /* Placeholder function to run a function for all exchanges */
     247              :     template <typename Function>
     248        25130 :     void ExecuteForAllContext(Function function)
     249              :     {
     250       231724 :         mContextPool.ForEachActiveObject([&](auto * ec) {
     251       206594 :             function(ec->GetReliableMessageContext());
     252       206594 :             return Loop::Continue;
     253              :         });
     254        25130 :     }
     255              : 
     256              :     void TicklessDebugDumpRetransTable(const char * log);
     257              : 
     258              : #if CHIP_CONFIG_MRP_ANALYTICS_ENABLED
     259              :     void NotifyMessageSendAnalytics(const RetransTableEntry & entry, const SessionHandle & sessionHandle,
     260              :                                     const ReliableMessageAnalyticsDelegate::EventType & eventType);
     261              : #endif // CHIP_CONFIG_MRP_ANALYTICS_ENABLED
     262              : 
     263              :     // ReliableMessageProtocol Global tables for timer context
     264              :     ObjectPool<RetransTableEntry, CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE> mRetransTable;
     265              : 
     266              :     SessionUpdateDelegate * mSessionUpdateDelegate = nullptr;
     267              : #if CHIP_CONFIG_MRP_ANALYTICS_ENABLED
     268              :     ReliableMessageAnalyticsDelegate * mAnalyticsDelegate = nullptr;
     269              : #endif // CHIP_CONFIG_MRP_ANALYTICS_ENABLED
     270              : 
     271              :     static System::Clock::Timeout sAdditionalMRPBackoffTime;
     272              : };
     273              : 
     274              : } // namespace Messaging
     275              : } // namespace chip
        

Generated by: LCOV version 2.0-1