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

          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        7850 :     uint32_t TakePendingPeerAckMessageCounter()
      69             :     {
      70        7850 :         SetAckPending(false);
      71        7850 :         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        9490 : inline bool ReliableMessageContext::AutoRequestAck() const
     222             : {
     223        9490 :     return mFlags.Has(Flags::kFlagAutoRequestAck);
     224             : }
     225             : 
     226      173098 : inline bool ReliableMessageContext::IsAckPending() const
     227             : {
     228      173098 :     return mFlags.Has(Flags::kFlagAckPending);
     229             : }
     230             : 
     231       15799 : inline bool ReliableMessageContext::IsWaitingForAck() const
     232             : {
     233       15799 :     return mFlags.Has(Flags::kFlagWaitingForAck);
     234             : }
     235             : 
     236        9411 : inline bool ReliableMessageContext::HasPiggybackAckPending() const
     237             : {
     238        9411 :     return mFlags.Has(Flags::kFlagAckMessageCounterIsValid);
     239             : }
     240             : 
     241        3268 : inline void ReliableMessageContext::SetAutoRequestAck(bool autoReqAck)
     242             : {
     243        3268 :     mFlags.Set(Flags::kFlagAutoRequestAck, autoReqAck);
     244        3268 : }
     245             : 
     246       18863 : inline void ReliableMessageContext::SetAckPending(bool inAckPending)
     247             : {
     248       18863 :     mFlags.Set(Flags::kFlagAckPending, inAckPending);
     249       18863 : }
     250             : 
     251        7888 : inline bool ReliableMessageContext::IsEphemeralExchange() const
     252             : {
     253        7888 :     return mFlags.Has(Flags::kFlagEphemeralExchange);
     254             : }
     255             : 
     256          38 : inline bool ReliableMessageContext::WaitingForResponseOrAck() const
     257             : {
     258          38 :     return mFlags.Has(Flags::kFlagWaitingForResponseOrAck);
     259             : }
     260             : 
     261       20457 : inline void ReliableMessageContext::SetWaitingForResponseOrAck(bool waitingForResponseOrAck)
     262             : {
     263       20457 :     mFlags.Set(Flags::kFlagWaitingForResponseOrAck, waitingForResponseOrAck);
     264       20457 : }
     265             : 
     266             : } // namespace Messaging
     267             : } // namespace chip

Generated by: LCOV version 1.14