Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / messaging / ReliableMessageMgr.h
1 /*
2  *    Copyright (c) 2020 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 classes corresponding to CHIP reliable message
21  *      protocol.
22  */
23
24 #pragma once
25
26 #include <array>
27 #include <stdint.h>
28
29 #include <messaging/ExchangeContext.h>
30 #include <messaging/ReliableMessageProtocolConfig.h>
31
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>
38
39 namespace chip {
40 namespace Messaging {
41
42 enum class SendMessageFlags : uint16_t;
43 class ReliableMessageContext;
44
45 class ReliableMessageMgr
46 {
47 public:
48     /**
49      *  @class RetransTableEntry
50      *
51      *  @brief
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.
56      *
57      */
58     struct RetransTableEntry
59     {
60         RetransTableEntry();
61
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. */
66     };
67
68 public:
69     ReliableMessageMgr(std::array<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & contextPool);
70     ~ReliableMessageMgr();
71
72     void Init(chip::System::Layer * systemLayer, SecureSessionMgr * sessionMgr);
73     void Shutdown();
74
75     /**
76      * Return a tick counter value given a time period.
77      *
78      * @param[in]  newTime        Timestamp value of in milliseconds.
79      *
80      * @return Tick count for the time period.
81      */
82     uint64_t GetTickCounterFromTimePeriod(uint64_t period);
83
84     /**
85      * Return a tick counter value between the given time and the stored time.
86      *
87      * @param[in]  newTime        Timestamp value of in milliseconds.
88      *
89      * @return Tick count of the difference between the given time and the stored time.
90      */
91     uint64_t GetTickCounterFromTimeDelta(uint64_t newTime);
92
93     /**
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.
97      */
98     void ExecuteActions();
99
100     /**
101      * Handle physical wakeup of system due to ReliableMessageProtocol wakeup.
102      *
103      */
104     static void Timeout(System::Layer * aSystemLayer, void * aAppState, System::Error aError);
105
106     /**
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.
109      *
110      *  @param[in]    rc        A pointer to the ExchangeContext object.
111      *
112      *  @param[out]   rEntry    A pointer to a pointer of a retransmission table entry added into the table.
113      *
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.
116      */
117     CHIP_ERROR AddToRetransTable(ReliableMessageContext * rc, RetransTableEntry ** rEntry);
118
119     /**
120      *  Start retranmisttion of cached encryped packet for current entry.
121      *
122      *  @param[in]   entry    A pointer to a retransmission table entry added into the table.
123      *
124      *  @retval  #CHIP_NO_ERROR On success.
125      */
126     void StartRetransmision(RetransTableEntry * entry);
127
128     /**
129      *  Pause retranmisttion of current exchange for specified period.
130      *
131      *  @param[in]    rc                A pointer to the ExchangeContext object.
132      *
133      *  @param[in]    PauseTimeMillis   Pause period in milliseconds.
134      *
135      *  @retval  #CHIP_NO_ERROR On success.
136      */
137     void PauseRetransmision(ReliableMessageContext * rc, uint32_t PauseTimeMillis);
138
139     /**
140      *  Re-start retranmisttion of cached encryped packet for current entry.
141      *
142      *  @param[in]   entry    A pointer to a retransmission table entry added into the table.
143      *
144      *  @retval  #CHIP_NO_ERROR On success.
145      */
146     void ResumeRetransmision(ReliableMessageContext * rc);
147
148     /**
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.
151      *
152      *  @param[in]    rc        A pointer to the ExchangeContext object.
153      *
154      *  @param[in]    msgId     message ID which has been acked.
155      *
156      *  @retval  #CHIP_NO_ERROR On success.
157      */
158     bool CheckAndRemRetransTable(ReliableMessageContext * rc, uint32_t msgId);
159
160     /**
161      *  Send the specified entry from the retransmission table.
162      *
163      *  @param[in]    entry     A pointer to a retransmission table entry object that needs to be sent.
164      *
165      *  @return  #CHIP_NO_ERROR On success, else corresponding CHIP_ERROR returned from SendMessage.
166      */
167     CHIP_ERROR SendFromRetransTable(RetransTableEntry * entry);
168
169     /**
170      *  Clear entries matching a specified ExchangeContext.
171      *
172      *  @param[in]    rc    A pointer to the ExchangeContext object.
173      *
174      */
175     void ClearRetransTable(ReliableMessageContext * rc);
176
177     /**
178      *  Clear an entry in the retransmission table.
179      *
180      *  @param[in]    rEntry   A reference to the RetransTableEntry object.
181      *
182      */
183     void ClearRetransTable(RetransTableEntry & rEntry);
184
185     /**
186      *  Fail entries matching a specified ExchangeContext.
187      *
188      *  @param[in]    rc    A pointer to the ExchangeContext object.
189      *
190      *  @param[in]    err   The error for failing table entries.
191      *
192      */
193     void FailRetransTableEntries(ReliableMessageContext * rc, CHIP_ERROR err);
194
195     /**
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.
200      *
201      */
202     void StartTimer();
203
204     /**
205      * Stop the timer for retransmistion on current node.
206      *
207      */
208     void StopTimer();
209
210     /**
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.
217      *
218      */
219     void ExpireTicks();
220
221     // Functions for testing
222     int TestGetCountRetransTable();
223     void TestSetIntervalShift(uint16_t value) { mTimerIntervalShift = value; }
224
225 private:
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
232
233     /* Placeholder function to run a function for all exchanges */
234     template <typename Function>
235     void ExecuteForAllContext(Function function)
236     {
237         for (auto & ec : mContextPool)
238         {
239             function(ec.GetReliableMessageContext());
240         }
241     }
242
243     void TicklessDebugDumpRetransTable(const char * log);
244
245     // ReliableMessageProtocol Global tables for timer context
246     RetransTableEntry mRetransTable[CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE];
247 };
248
249 } // namespace Messaging
250 } // namespace chip