77c55dbf4ba07551e12670314fdd36a0ae494a3a
[platform/upstream/connectedhomeip.git] / src / messaging / ReliableMessageContext.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 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 <core/CHIPError.h>
32 #include <inet/InetLayer.h>
33 #include <lib/core/ReferenceCounted.h>
34 #include <support/DLLUtil.h>
35 #include <system/SystemLayer.h>
36 #include <transport/raw/MessageHeader.h>
37
38 namespace chip {
39 namespace Messaging {
40
41 class ChipMessageInfo;
42 class ExchangeContext;
43 enum class MessageFlagValues : uint32_t;
44 class ReliableMessageContext;
45 class ReliableMessageMgr;
46
47 class ReliableMessageDelegate
48 {
49 public:
50     virtual ~ReliableMessageDelegate() {}
51
52     /* Application callbacks */
53     virtual void OnSendError(CHIP_ERROR err) = 0; /**< Application callback for error while sending. */
54     virtual void OnAckRcvd()                 = 0; /**< Application callback for received acknowledgment. */
55 };
56
57 class ReliableMessageContext
58 {
59 public:
60     ReliableMessageContext();
61
62     void Init(ReliableMessageMgr * manager, ExchangeContext * exchange);
63     void SetConfig(ReliableMessageProtocolConfig config) { mConfig = config; }
64     void SetDelegate(ReliableMessageDelegate * delegate) { mDelegate = delegate; }
65
66     /**
67      * Flush the pending Ack for current exchange.
68      *
69      */
70     CHIP_ERROR FlushAcks();
71
72     /**
73      *  Get the current retransmit timeout. It would be either the initial or
74      *  the active retransmit timeout based on whether the ExchangeContext has
75      *  an active message exchange going with its peer.
76      *
77      *  @return the current retransmit time.
78      */
79     uint64_t GetCurrentRetransmitTimeoutTick();
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 the ChipExchangeManager should not send an
112      *  acknowledgement.
113      *
114      *  For internal, debug use only.
115      */
116     bool ShouldDropAckDebug() const;
117
118     /**
119      *  Set whether the ChipExchangeManager should not send acknowledgements
120      *  for this context.
121      *
122      *  For internal, debug use only.
123      *
124      *  @param[in]  inDropAckDebug  A Boolean indicating whether (true) or not
125      *                         (false) the acknowledgements should be not
126      *                         sent for the exchange.
127      */
128     void SetDropAckDebug(bool inDropAckDebug);
129
130     /**
131      *  Determine whether there is already an acknowledgment pending to be sent to the peer on this exchange.
132      *
133      *  @return Returns 'true' if there is already an acknowledgment pending  on this exchange, else 'false'.
134      */
135     bool IsAckPending() const;
136
137     /**
138      *  Set if an acknowledgment needs to be sent back to the peer on this exchange.
139      *
140      *  @param[in]  inAckPending A Boolean indicating whether (true) or not
141      *                          (false) an acknowledgment should be sent back
142      *                          in response to a received message.
143      */
144     void SetAckPending(bool inAckPending);
145
146     /**
147      *  Determine whether peer requested acknowledgment for at least one message
148      *  on this exchange.
149      *
150      *  @return Returns 'true' if acknowledgment requested, else 'false'.
151      */
152     bool HasPeerRequestedAck() const;
153
154     /**
155      *  Set if an acknowledgment was requested in the last message received
156      *  on this exchange.
157      *
158      *  @param[in]  inPeerRequestedAck A Boolean indicating whether (true) or not
159      *                                 (false) an acknowledgment was requested
160      *                                 in the last received message.
161      */
162     void SetPeerRequestedAck(bool inPeerRequestedAck);
163
164     /**
165      *  Determine whether at least one message has been received
166      *  on this exchange from peer.
167      *
168      *  @return Returns 'true' if message received, else 'false'.
169      */
170     bool HasRcvdMsgFromPeer() const;
171
172     /**
173      *  Set if a message has been received from the peer
174      *  on this exchange.
175      *
176      *  @param[in]  inMsgRcvdFromPeer  A Boolean indicating whether (true) or not
177      *                                 (false) a message has been received
178      *                                 from the peer on this exchange context.
179      */
180     void SetMsgRcvdFromPeer(bool inMsgRcvdFromPeer);
181
182 private:
183     enum class Flags : uint16_t
184     {
185         /// When set, automatically request an acknowledgment whenever a message is sent via UDP.
186         kFlagAutoRequestAck = 0x0004,
187
188         /// Internal and debug only: when set, the exchange layer does not send an acknowledgment.
189         kFlagDropAckDebug = 0x0008,
190
191         /// If a response is expected for a message that is being sent.
192         kFlagResponseExpected = 0x0010,
193
194         /// When set, signifies that there is an acknowledgment pending to be sent back.
195         kFlagAckPending = 0x0020,
196
197         /// When set, signifies that at least one message received on this exchange requested an acknowledgment.
198         /// This flag is read by the application to decide if it needs to request an acknowledgment for the
199         /// response message it is about to send. This flag can also indicate whether peer is using ReliableMessageProtocol.
200         kFlagPeerRequestedAck = 0x0040,
201
202         /// When set, signifies that at least one message has been received from peer on this exchange context.
203         kFlagMsgRcvdFromPeer = 0x0080,
204     };
205
206     BitFlags<uint16_t, Flags> mFlags; // Internal state flags
207
208     void Retain();
209     void Release();
210     CHIP_ERROR HandleRcvdAck(uint32_t AckMsgId);
211     CHIP_ERROR HandleNeedsAck(uint32_t MessageId, BitFlags<uint32_t, MessageFlagValues> Flags);
212
213 private:
214     friend class ReliableMessageMgr;
215     friend class ExchangeContext;
216
217     ReliableMessageMgr * mManager;
218     ExchangeContext * mExchange;
219     ReliableMessageDelegate * mDelegate;
220     ReliableMessageProtocolConfig mConfig;
221     uint16_t mNextAckTimeTick; // Next time for triggering Solo Ack
222     uint32_t mPendingPeerAckId;
223 };
224
225 } // namespace Messaging
226 } // namespace chip