2 * Copyright (c) 2020 Project CHIP Authors
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * This file defines the classes corresponding to CHIP reliable message
29 #include <messaging/ExchangeContext.h>
30 #include <messaging/ReliableMessageProtocolConfig.h>
32 #include <core/CHIPError.h>
33 #include <support/BitFlags.h>
34 #include <system/SystemLayer.h>
35 #include <system/SystemPacketBuffer.h>
36 #include <system/SystemTimer.h>
37 #include <transport/raw/MessageHeader.h>
42 enum class SendMessageFlags : uint16_t;
43 class ReliableMessageContext;
45 class ReliableMessageMgr
49 * @class RetransTableEntry
52 * This class is part of the CHIP Reliable Messaging Protocol and is used
53 * to keep track of CHIP messages that have been sent and are expecting an
54 * acknowledgment back. If the acknowledgment is not received within a
55 * specific timeout, the message would be retransmitted from this table.
58 struct RetransTableEntry
62 ReliableMessageContext * rc; /**< The context for the stored CHIP message. */
63 EncryptedPacketBufferHandle retainedBuf; /**< The packet buffer holding the CHIP message. */
64 uint16_t nextRetransTimeTick; /**< A counter representing the next retransmission time for the message. */
65 uint8_t sendCount; /**< A counter representing the number of times the message has been sent. */
69 ReliableMessageMgr(std::array<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & contextPool);
70 ~ReliableMessageMgr();
72 void Init(chip::System::Layer * systemLayer, SecureSessionMgr * sessionMgr);
76 * Return a tick counter value given a time period.
78 * @param[in] newTime Timestamp value of in milliseconds.
80 * @return Tick count for the time period.
82 uint64_t GetTickCounterFromTimePeriod(uint64_t period);
85 * Return a tick counter value between the given time and the stored time.
87 * @param[in] newTime Timestamp value of in milliseconds.
89 * @return Tick count of the difference between the given time and the stored time.
91 uint64_t GetTickCounterFromTimeDelta(uint64_t newTime);
94 * Iterate through active exchange contexts and retrans table entries. If an
95 * action needs to be triggered by ReliableMessageProtocol time facilities,
96 * execute that action.
98 void ExecuteActions();
101 * Handle physical wakeup of system due to ReliableMessageProtocol wakeup.
104 static void Timeout(System::Layer * aSystemLayer, void * aAppState, System::Error aError);
107 * Add a CHIP message into the retransmission table to be subsequently resent if a corresponding acknowledgment
108 * is not received within the retransmission timeout.
110 * @param[in] rc A pointer to the ExchangeContext object.
112 * @param[out] rEntry A pointer to a pointer of a retransmission table entry added into the table.
114 * @retval #CHIP_ERROR_RETRANS_TABLE_FULL If there is no empty slot left in the table for addition.
115 * @retval #CHIP_NO_ERROR On success.
117 CHIP_ERROR AddToRetransTable(ReliableMessageContext * rc, RetransTableEntry ** rEntry);
120 * Start retranmisttion of cached encryped packet for current entry.
122 * @param[in] entry A pointer to a retransmission table entry added into the table.
124 * @retval #CHIP_NO_ERROR On success.
126 void StartRetransmision(RetransTableEntry * entry);
129 * Pause retranmisttion of current exchange for specified period.
131 * @param[in] rc A pointer to the ExchangeContext object.
133 * @param[in] PauseTimeMillis Pause period in milliseconds.
135 * @retval #CHIP_NO_ERROR On success.
137 void PauseRetransmision(ReliableMessageContext * rc, uint32_t PauseTimeMillis);
140 * Re-start retranmisttion of cached encryped packet for current entry.
142 * @param[in] entry A pointer to a retransmission table entry added into the table.
144 * @retval #CHIP_NO_ERROR On success.
146 void ResumeRetransmision(ReliableMessageContext * rc);
149 * Iterate through active exchange contexts and retrans table entries. Clear the entry matching
150 * the specified ExchangeContext and the message ID from the retransmision table.
152 * @param[in] rc A pointer to the ExchangeContext object.
154 * @param[in] msgId message ID which has been acked.
156 * @retval #CHIP_NO_ERROR On success.
158 bool CheckAndRemRetransTable(ReliableMessageContext * rc, uint32_t msgId);
161 * Send the specified entry from the retransmission table.
163 * @param[in] entry A pointer to a retransmission table entry object that needs to be sent.
165 * @return #CHIP_NO_ERROR On success, else corresponding CHIP_ERROR returned from SendMessage.
167 CHIP_ERROR SendFromRetransTable(RetransTableEntry * entry);
170 * Clear entries matching a specified ExchangeContext.
172 * @param[in] rc A pointer to the ExchangeContext object.
175 void ClearRetransTable(ReliableMessageContext * rc);
178 * Clear an entry in the retransmission table.
180 * @param[in] rEntry A reference to the RetransTableEntry object.
183 void ClearRetransTable(RetransTableEntry & rEntry);
186 * Fail entries matching a specified ExchangeContext.
188 * @param[in] rc A pointer to the ExchangeContext object.
190 * @param[in] err The error for failing table entries.
193 void FailRetransTableEntries(ReliableMessageContext * rc, CHIP_ERROR err);
196 * Iterate through active exchange contexts and retrans table entries.
197 * Determine how many ReliableMessageProtocol ticks we need to sleep before we
198 * need to physically wake the CPU to perform an action. Set a timer to go off
199 * when we next need to wake the system.
205 * Stop the timer for retransmistion on current node.
211 * Calculate number of virtual ReliableMessageProtocol ticks that have expired
212 * since we last called this function. Iterate through active exchange contexts
213 * and retrans table entries, subtracting expired virtual ticks to synchronize
214 * wakeup times with the current system time. Do not perform any actions beyond
215 * updating tick counts, actions will be performed by the physical
216 * ReliableMessageProtocol timer tick expiry.
221 // Functions for testing
222 int TestGetCountRetransTable();
223 void TestSetIntervalShift(uint16_t value) { mTimerIntervalShift = value; }
226 std::array<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & mContextPool;
227 chip::System::Layer * mSystemLayer;
228 SecureSessionMgr * mSessionMgr;
229 uint64_t mTimeStampBase; // ReliableMessageProtocol timer base value to add offsets to evaluate timeouts
230 System::Timer::Epoch mCurrentTimerExpiry; // Tracks when the ReliableMessageProtocol timer will next expire
231 uint16_t mTimerIntervalShift; // ReliableMessageProtocol Timer tick period shift
233 /* Placeholder function to run a function for all exchanges */
234 template <typename Function>
235 void ExecuteForAllContext(Function function)
237 for (auto & ec : mContextPool)
239 function(ec.GetReliableMessageContext());
243 void TicklessDebugDumpRetransTable(const char * log);
245 // ReliableMessageProtocol Global tables for timer context
246 RetransTableEntry mRetransTable[CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE];
249 } // namespace Messaging