Matter SDK Coverage Report
Current view: top level - messaging - ReliableMessageContext.cpp (source / functions) Coverage Total Hit
Test: SHA:6e8676be6142bb541fa68048c77f2fc56a21c7b1 Lines: 90.2 % 61 55
Test Date: 2025-01-29 08:09:34 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 implements the CHIP reliable message protocol.
      21              :  *
      22              :  */
      23              : 
      24              : #include <inttypes.h>
      25              : 
      26              : #include <lib/core/CHIPEncoding.h>
      27              : #include <lib/support/CodeUtils.h>
      28              : #include <lib/support/Defer.h>
      29              : #include <messaging/ErrorCategory.h>
      30              : #include <messaging/ExchangeContext.h>
      31              : #include <messaging/ExchangeMgr.h>
      32              : #include <messaging/Flags.h>
      33              : #include <messaging/ReliableMessageContext.h>
      34              : #include <messaging/ReliableMessageMgr.h>
      35              : #include <platform/PlatformManager.h>
      36              : #include <protocols/Protocols.h>
      37              : #include <protocols/secure_channel/Constants.h>
      38              : 
      39              : using namespace chip::DeviceLayer;
      40              : 
      41              : namespace chip {
      42              : namespace Messaging {
      43              : 
      44         3561 : ReliableMessageContext::ReliableMessageContext() : mNextAckTime(0), mPendingPeerAckMessageCounter(0) {}
      45              : 
      46        29763 : ExchangeContext * ReliableMessageContext::GetExchangeContext()
      47              : {
      48        29763 :     return static_cast<ExchangeContext *>(this);
      49              : }
      50              : 
      51        34883 : ReliableMessageMgr * ReliableMessageContext::GetReliableMessageMgr()
      52              : {
      53        34883 :     return static_cast<ExchangeContext *>(this)->GetExchangeMgr()->GetReliableMessageMgr();
      54              : }
      55              : 
      56        16678 : void ReliableMessageContext::SetWaitingForAck(bool waitingForAck)
      57              : {
      58        16678 :     mFlags.Set(Flags::kFlagWaitingForAck, waitingForAck);
      59        16678 : }
      60              : 
      61         3654 : CHIP_ERROR ReliableMessageContext::FlushAcks()
      62              : {
      63         3654 :     CHIP_ERROR err = CHIP_NO_ERROR;
      64              : 
      65         3654 :     if (IsAckPending())
      66              :     {
      67         1665 :         err = SendStandaloneAckMessage();
      68              : 
      69         1665 :         if (err == CHIP_NO_ERROR)
      70              :         {
      71         1662 :             ChipLogDetail(ExchangeManager,
      72              :                           "Flushed pending ack for MessageCounter:" ChipLogFormatMessageCounter
      73              :                           " on exchange " ChipLogFormatExchange,
      74              :                           mPendingPeerAckMessageCounter, ChipLogValueExchange(GetExchangeContext()));
      75              :         }
      76              :     }
      77              : 
      78         3654 :     return err;
      79              : }
      80              : 
      81              : /**
      82              :  *  Process received Ack. Remove the corresponding message context from the RetransTable and execute the application
      83              :  *  callback
      84              :  *
      85              :  *  @note
      86              :  *    This message is part of the CHIP Reliable Messaging protocol.
      87              :  *
      88              :  *  @param[in]    ackMessageCounter         The acknowledged message counter of the incoming message.
      89              :  */
      90         8206 : void ReliableMessageContext::HandleRcvdAck(uint32_t ackMessageCounter)
      91              : {
      92              :     // Msg is an Ack; Check Retrans Table and remove message context
      93         8206 :     if (GetReliableMessageMgr()->CheckAndRemRetransTable(this, ackMessageCounter))
      94              :     {
      95         8194 :         SetWaitingForResponseOrAck(false);
      96              :     }
      97              :     else
      98              :     {
      99              :         // This can happen quite easily due to a packet with a piggyback ack
     100              :         // being lost and retransmitted.
     101           12 :         ChipLogDetail(ExchangeManager,
     102              :                       "CHIP MessageCounter:" ChipLogFormatMessageCounter " not in RetransTable on exchange " ChipLogFormatExchange,
     103              :                       ackMessageCounter, ChipLogValueExchange(GetExchangeContext()));
     104              :     }
     105         8206 : }
     106              : 
     107         8277 : CHIP_ERROR ReliableMessageContext::HandleNeedsAck(uint32_t messageCounter, BitFlags<MessageFlagValues> messageFlags)
     108              : {
     109         8277 :     CHIP_ERROR err = HandleNeedsAckInner(messageCounter, messageFlags);
     110              : 
     111              :     // Schedule next physical wakeup on function exit
     112         8277 :     GetReliableMessageMgr()->StartTimer();
     113              : 
     114         8277 :     return err;
     115              : }
     116              : 
     117         8277 : CHIP_ERROR ReliableMessageContext::HandleNeedsAckInner(uint32_t messageCounter, BitFlags<MessageFlagValues> messageFlags)
     118              : 
     119              : {
     120              :     // If the message IS a duplicate there will never be a response to it, so we
     121              :     // should not wait for one and just immediately send a standalone ack.
     122         8277 :     if (messageFlags.Has(MessageFlagValues::kDuplicateMessage))
     123              :     {
     124            5 :         ChipLogDetail(ExchangeManager,
     125              :                       "Forcing tx of solitary ack for duplicate MessageCounter:" ChipLogFormatMessageCounter
     126              :                       " on exchange " ChipLogFormatExchange,
     127              :                       messageCounter, ChipLogValueExchange(GetExchangeContext()));
     128              : 
     129            5 :         bool wasAckPending = IsAckPending() && mPendingPeerAckMessageCounter != messageCounter;
     130              : 
     131            5 :         bool messageCounterWasValid = HasPiggybackAckPending();
     132              : 
     133              :         // Temporary store currently pending ack message counter (even if there is none).
     134            5 :         uint32_t tempAckMessageCounter = mPendingPeerAckMessageCounter;
     135              : 
     136            5 :         SetPendingPeerAckMessageCounter(messageCounter);
     137            5 :         CHIP_ERROR err = SendStandaloneAckMessage();
     138              : 
     139            5 :         if (wasAckPending)
     140              :         {
     141              :             // Restore previously pending ack message counter.
     142            0 :             SetPendingPeerAckMessageCounter(tempAckMessageCounter);
     143              :         }
     144            5 :         else if (messageCounterWasValid)
     145              :         {
     146              :             // Restore the previous value, so later piggybacks will pick it up,
     147              :             // but don't set out "ack is pending" state, because we didn't use
     148              :             // to have it set.
     149            2 :             mPendingPeerAckMessageCounter = tempAckMessageCounter;
     150              :         }
     151              :         // Otherwise don't restore the invalid old mPendingPeerAckMessageCounter
     152              :         // value, so we preserve the invariant that once we have had an ack
     153              :         // pending we always have a valid mPendingPeerAckMessageCounter.
     154              : 
     155            5 :         return err;
     156              :     }
     157              :     // Otherwise, the message IS NOT a duplicate.
     158              : 
     159         8272 :     if (IsAckPending())
     160              :     {
     161            0 :         ChipLogDetail(ExchangeManager,
     162              :                       "Pending ack queue full; forcing tx of solitary ack for MessageCounter:" ChipLogFormatMessageCounter
     163              :                       " on exchange " ChipLogFormatExchange,
     164              :                       mPendingPeerAckMessageCounter, ChipLogValueExchange(GetExchangeContext()));
     165              :         // Send the Ack for the currently pending Ack in a SecureChannel::StandaloneAck message.
     166            0 :         ReturnErrorOnFailure(SendStandaloneAckMessage());
     167              :     }
     168              : 
     169              :     // Replace the Pending ack message counter.
     170         8272 :     SetPendingPeerAckMessageCounter(messageCounter);
     171              :     using namespace System::Clock::Literals;
     172         8272 :     mNextAckTime = System::SystemClock().GetMonotonicTimestamp() + CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT;
     173         8272 :     return CHIP_NO_ERROR;
     174              : }
     175              : 
     176         1672 : CHIP_ERROR ReliableMessageContext::SendStandaloneAckMessage()
     177              : {
     178              :     // Allocate a buffer for the null message
     179         1672 :     System::PacketBufferHandle msgBuf = MessagePacketBuffer::New(0);
     180         1672 :     if (msgBuf.IsNull())
     181              :     {
     182            0 :         return CHIP_ERROR_NO_MEMORY;
     183              :     }
     184              : 
     185         3344 :     CHIP_ERROR err = GetExchangeContext()->SendMessage(Protocols::SecureChannel::MsgType::StandaloneAck, std::move(msgBuf),
     186         1672 :                                                        BitFlags<SendMessageFlags>{ SendMessageFlags::kNoAutoRequestAck });
     187         1672 :     if (IsSendErrorNonCritical(err))
     188              :     {
     189            0 :         ChipLogError(ExchangeManager,
     190              :                      "Non-crit err %" CHIP_ERROR_FORMAT " sending solitary ack for MessageCounter:" ChipLogFormatMessageCounter
     191              :                      " on exchange " ChipLogFormatExchange,
     192              :                      err.Format(), mPendingPeerAckMessageCounter, ChipLogValueExchange(GetExchangeContext()));
     193            0 :         return CHIP_NO_ERROR;
     194              :     }
     195         1672 :     if (err != CHIP_NO_ERROR)
     196              :     {
     197            3 :         ChipLogError(ExchangeManager,
     198              :                      "Failed to send Solitary ack for MessageCounter:" ChipLogFormatMessageCounter
     199              :                      " on exchange " ChipLogFormatExchange ":%" CHIP_ERROR_FORMAT,
     200              :                      mPendingPeerAckMessageCounter, ChipLogValueExchange(GetExchangeContext()), err.Format());
     201              :     }
     202              : 
     203         1672 :     return err;
     204         1672 : }
     205              : 
     206         8301 : void ReliableMessageContext::SetPendingPeerAckMessageCounter(uint32_t aPeerAckMessageCounter)
     207              : {
     208         8301 :     mPendingPeerAckMessageCounter = aPeerAckMessageCounter;
     209         8301 :     SetAckPending(true);
     210         8301 :     mFlags.Set(Flags::kFlagAckMessageCounterIsValid);
     211         8301 : }
     212              : 
     213              : } // namespace Messaging
     214              : } // namespace chip
        

Generated by: LCOV version 2.0-1