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