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

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2020-2021 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 reliable message context for the CHIP Message
      21              :  *      Layer. The context is one-on-one relationship with a chip session.
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <stdint.h>
      27              : #include <string.h>
      28              : 
      29              : #include <messaging/ReliableMessageProtocolConfig.h>
      30              : 
      31              : #include <lib/core/CHIPError.h>
      32              : #include <lib/core/ReferenceCounted.h>
      33              : #include <lib/support/DLLUtil.h>
      34              : #include <messaging/ReliableMessageProtocolConfig.h>
      35              : #include <system/SystemLayer.h>
      36              : #include <transport/raw/MessageHeader.h>
      37              : 
      38              : namespace chip {
      39              : namespace app {
      40              : class TestCommandInteraction;
      41              : class TestReadInteraction;
      42              : class TestWriteInteraction;
      43              : } // namespace app
      44              : namespace Messaging {
      45              : 
      46              : class ChipMessageInfo;
      47              : class ExchangeContext;
      48              : enum class MessageFlagValues : uint32_t;
      49              : class ReliableMessageMgr;
      50              : 
      51              : class ReliableMessageContext
      52              : {
      53              : public:
      54              :     ReliableMessageContext();
      55              : 
      56              :     /**
      57              :      * Flush the pending Ack for current exchange.
      58              :      *
      59              :      */
      60              :     CHIP_ERROR FlushAcks();
      61              : 
      62              :     /**
      63              :      * Take the pending peer ack message counter from the context.  This must
      64              :      * only be called when HasPiggybackAckPending() is true.  After this call,
      65              :      * IsAckPending() will be false; it's the caller's responsibility to send
      66              :      * the ack.
      67              :      */
      68         8008 :     uint32_t TakePendingPeerAckMessageCounter()
      69              :     {
      70         8008 :         SetAckPending(false);
      71         8008 :         return mPendingPeerAckMessageCounter;
      72              :     }
      73              : 
      74              :     /**
      75              :      * Check whether we have a mPendingPeerAckMessageCounter. The counter is
      76              :      * valid once we receive a message which requests an ack. Once
      77              :      * mPendingPeerAckMessageCounter is valid, it never stops being valid.
      78              :      */
      79              :     bool HasPiggybackAckPending() const;
      80              : 
      81              :     /**
      82              :      *  Send a SecureChannel::StandaloneAck message.
      83              :      *
      84              :      *  @note  When sent via UDP, the null message is sent *without* requesting an acknowledgment,
      85              :      *  even in the case where the auto-request acknowledgment feature has been enabled on the
      86              :      *  exchange.
      87              :      *
      88              :      *  @retval  #CHIP_ERROR_NO_MEMORY   If no available PacketBuffers.
      89              :      *  @retval  #CHIP_NO_ERROR          If the method succeeded or the error wasn't critical.
      90              :      *  @retval  other                    Another critical error returned by SendMessage().
      91              :      */
      92              :     CHIP_ERROR SendStandaloneAckMessage();
      93              : 
      94              :     /**
      95              :      *  Determine whether an acknowledgment will be requested whenever a message is sent for the exchange.
      96              :      *
      97              :      *  @return Returns 'true' an acknowledgment will be requested whenever a message is sent, else 'false'.
      98              :      */
      99              :     bool AutoRequestAck() const;
     100              : 
     101              :     /**
     102              :      * Set whether an acknowledgment should be requested whenever a message is sent.
     103              :      *
     104              :      * @param[in] autoReqAck            A Boolean indicating whether or not an
     105              :      *                                  acknowledgment should be requested whenever a
     106              :      *                                  message is sent.
     107              :      */
     108              :     void SetAutoRequestAck(bool autoReqAck);
     109              : 
     110              :     /**
     111              :      *  Determine whether there is already an acknowledgment pending to be sent to the peer on this exchange.
     112              :      *
     113              :      *  @return Returns 'true' if there is already an acknowledgment pending  on this exchange, else 'false'.
     114              :      */
     115              :     bool IsAckPending() const;
     116              : 
     117              :     /// Determine whether the reliable message context is waiting for an ack.
     118              :     bool IsWaitingForAck() const;
     119              : 
     120              :     /// Set whether the reliable message context is waiting for an ack.
     121              :     void SetWaitingForAck(bool waitingForAck);
     122              : 
     123              :     /// Set if this exchange is requesting Sleepy End Device active mode
     124              :     void SetRequestingActiveMode(bool activeMode);
     125              : 
     126              :     /// Determine whether this exchange is a EphemeralExchange for replying a StandaloneAck
     127              :     bool IsEphemeralExchange() const;
     128              : 
     129              :     /**
     130              :      * Get the reliable message manager that corresponds to this reliable
     131              :      * message context.
     132              :      */
     133              :     ReliableMessageMgr * GetReliableMessageMgr();
     134              : 
     135              : protected:
     136              :     bool WaitingForResponseOrAck() const;
     137              :     void SetWaitingForResponseOrAck(bool waitingForResponseOrAck);
     138              : 
     139              :     enum class Flags : uint16_t
     140              :     {
     141              :         /// When set, signifies that this context is the initiator of the exchange.
     142              :         kFlagInitiator = (1u << 0),
     143              : 
     144              :         /// When set, signifies that a response is expected for a message that is being sent.
     145              :         kFlagResponseExpected = (1u << 1),
     146              : 
     147              :         /// When set, automatically request an acknowledgment whenever a message is sent via UDP.
     148              :         kFlagAutoRequestAck = (1u << 2),
     149              : 
     150              :         /// When set, signifies the reliable message context is waiting for an
     151              :         /// ack: a message that needs an ack has been sent, no ack has been
     152              :         /// received, and we have not yet run out of MRP retries.
     153              :         kFlagWaitingForAck = (1u << 3),
     154              : 
     155              :         /// When set, signifies that there is an acknowledgment pending to be sent back.
     156              :         kFlagAckPending = (1u << 4),
     157              : 
     158              :         /// When set, signifies that mPendingPeerAckMessageCounter is valid.
     159              :         /// The counter is valid once we receive a message which requests an ack.
     160              :         /// Once mPendingPeerAckMessageCounter is valid, it never stops being valid.
     161              :         kFlagAckMessageCounterIsValid = (1u << 5),
     162              : 
     163              :         /// When set, signifies that this exchange is waiting for a call to SendMessage.
     164              :         kFlagWillSendMessage = (1u << 6),
     165              : 
     166              :         /// When set, we have had Close() or Abort() called on us already.
     167              :         kFlagClosed = (1u << 7),
     168              : 
     169              :         /// When set, signifies that the exchange created sorely for replying a StandaloneAck
     170              :         kFlagEphemeralExchange = (1u << 8),
     171              : 
     172              :         /// When set, ignore session being released, because we are releasing it ourselves.
     173              :         kFlagIgnoreSessionRelease = (1u << 9),
     174              : 
     175              :         // This flag is used to determine if the peer (receiver) should be considered active or not.
     176              :         // When set, sender knows it has received at least one application-level message
     177              :         // from the peer and can assume the peer (receiver) is active.
     178              :         // If the flag is not set, we don't know if the peer (receiver) is active or not.
     179              :         kFlagReceivedAtLeastOneMessage = (1u << 10),
     180              : 
     181              :         /// When set:
     182              :         ///
     183              :         /// (1) We sent a message that expected a response (hence
     184              :         ///     IsResponseExpected() is true).
     185              :         /// (2) We have received neither a response nor an ack for that message.
     186              :         kFlagWaitingForResponseOrAck = (1u << 11),
     187              :     };
     188              : 
     189              :     BitFlags<Flags> mFlags; // Internal state flags
     190              : 
     191              : private:
     192              :     void HandleRcvdAck(uint32_t ackMessageCounter);
     193              :     CHIP_ERROR HandleNeedsAck(uint32_t messageCounter, BitFlags<MessageFlagValues> messageFlags);
     194              :     CHIP_ERROR HandleNeedsAckInner(uint32_t messageCounter, BitFlags<MessageFlagValues> messageFlags);
     195              :     ExchangeContext * GetExchangeContext();
     196              : 
     197              :     /**
     198              :      *  Set if an acknowledgment needs to be sent back to the peer on this exchange.
     199              :      *
     200              :      *  @param[in]  inAckPending A Boolean indicating whether (true) or not
     201              :      *                          (false) an acknowledgment should be sent back
     202              :      *                          in response to a received message.
     203              :      */
     204              :     void SetAckPending(bool inAckPending);
     205              : 
     206              :     // Set our pending peer ack message counter and any other state needed to ensure that we
     207              :     // will send that ack at some point.
     208              :     void SetPendingPeerAckMessageCounter(uint32_t aPeerAckMessageCounter);
     209              : 
     210              :     friend class ReliableMessageMgr;
     211              :     friend class ExchangeContext;
     212              :     friend class ExchangeMessageDispatch;
     213              :     friend class ::chip::app::TestCommandInteraction;
     214              :     friend class ::chip::app::TestReadInteraction;
     215              :     friend class ::chip::app::TestWriteInteraction;
     216              : 
     217              :     System::Clock::Timestamp mNextAckTime; // Next time for triggering Solo Ack
     218              :     uint32_t mPendingPeerAckMessageCounter;
     219              : };
     220              : 
     221         9728 : inline bool ReliableMessageContext::AutoRequestAck() const
     222              : {
     223         9728 :     return mFlags.Has(Flags::kFlagAutoRequestAck);
     224              : }
     225              : 
     226       174437 : inline bool ReliableMessageContext::IsAckPending() const
     227              : {
     228       174437 :     return mFlags.Has(Flags::kFlagAckPending);
     229              : }
     230              : 
     231        16119 : inline bool ReliableMessageContext::IsWaitingForAck() const
     232              : {
     233        16119 :     return mFlags.Has(Flags::kFlagWaitingForAck);
     234              : }
     235              : 
     236         9649 : inline bool ReliableMessageContext::HasPiggybackAckPending() const
     237              : {
     238         9649 :     return mFlags.Has(Flags::kFlagAckMessageCounterIsValid);
     239              : }
     240              : 
     241         3429 : inline void ReliableMessageContext::SetAutoRequestAck(bool autoReqAck)
     242              : {
     243         3429 :     mFlags.Set(Flags::kFlagAutoRequestAck, autoReqAck);
     244         3429 : }
     245              : 
     246        19340 : inline void ReliableMessageContext::SetAckPending(bool inAckPending)
     247              : {
     248        19340 :     mFlags.Set(Flags::kFlagAckPending, inAckPending);
     249        19340 : }
     250              : 
     251         8052 : inline bool ReliableMessageContext::IsEphemeralExchange() const
     252              : {
     253         8052 :     return mFlags.Has(Flags::kFlagEphemeralExchange);
     254              : }
     255              : 
     256           41 : inline bool ReliableMessageContext::WaitingForResponseOrAck() const
     257              : {
     258           41 :     return mFlags.Has(Flags::kFlagWaitingForResponseOrAck);
     259              : }
     260              : 
     261        20790 : inline void ReliableMessageContext::SetWaitingForResponseOrAck(bool waitingForResponseOrAck)
     262              : {
     263        20790 :     mFlags.Set(Flags::kFlagWaitingForResponseOrAck, waitingForResponseOrAck);
     264        20790 : }
     265              : 
     266              : } // namespace Messaging
     267              : } // namespace chip
        

Generated by: LCOV version 2.0-1