Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2021 Project CHIP Authors
4 : * Copyright (c) 2017 Nest Labs, Inc.
5 : * All rights reserved.
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : /**
21 : * @file
22 : * This file defines the configuration parameters that are required
23 : * for the CHIP Reliable Messaging Protocol.
24 : *
25 : */
26 : #pragma once
27 :
28 : #include <lib/core/CHIPConfig.h>
29 : #include <lib/core/Optional.h>
30 : #include <system/SystemClock.h>
31 : #include <system/SystemConfig.h>
32 :
33 : namespace chip {
34 :
35 : /**
36 : * @def CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
37 : *
38 : * @brief Base retry interval of the present node when it is in the active state.
39 : *
40 : * Base interval that a peer node should use to calculate the retransmission
41 : * timeout when it sends a message to the present node and the present node is
42 : * perceived by the peer as active.
43 : *
44 : * This value is announced to the peer using SAI (Session Active Interval) key
45 : * in the advertised DNS Service Discovery TXT records. Additionally, it is
46 : * exchanged in the initial phase of the PASE/CASE session establishment.
47 : *
48 : * In the case of a Thread device, the default value is increased to limit the
49 : * possibility of spurious retransmissions. The assumption is that the average
50 : * round-trip time of a big request-response pair is substantially longer in
51 : * a Thread network that potentially constists of multiple intermediate hops.
52 : */
53 : #ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
54 : #if CHIP_ENABLE_OPENTHREAD && !CHIP_DEVICE_LAYER_TARGET_LINUX
55 : #define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32)
56 : #else
57 : #define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (300_ms32)
58 : #endif
59 : #endif // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL && !CHIP_DEVICE_LAYER_TARGET_LINUX
60 :
61 : /**
62 : * @def CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
63 : *
64 : * @brief Base retry interval of the present node when it is in the idle state.
65 : *
66 : * Base interval that a peer node should use to calculate the retransmission
67 : * timeout when it sends a message to the present node and the present node is
68 : * perceived by the peer as idle.
69 : *
70 : * This value is announced to the peer using SII (Session Idle Interval) key
71 : * in the advertised DNS Service Discovery TXT records. Additionally, it is
72 : * exchanged in the initial phase of the PASE/CASE session establishment.
73 : *
74 : * In the case of a Thread device, the default value is increased to limit the
75 : * possibility of spurious retransmissions. The assumption is that the average
76 : * round-trip time of a big request-response pair is substantially longer in
77 : * a Thread network that potentially constists of multiple intermediate hops.
78 : */
79 : #ifndef CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
80 : #if CHIP_ENABLE_OPENTHREAD && !CHIP_DEVICE_LAYER_TARGET_LINUX
81 : #define CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL (2000_ms32)
82 : #else
83 : #define CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL (500_ms32)
84 : #endif
85 : #endif // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL && !CHIP_DEVICE_LAYER_TARGET_LINUX
86 :
87 : /**
88 : * @def CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT
89 : *
90 : * @brief
91 : * The default acknowledgment timeout in milliseconds.
92 : *
93 : */
94 : #ifndef CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT
95 : #define CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT (200_ms32)
96 : #endif // CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT
97 :
98 : /**
99 : * @def CHIP_CONFIG_RESOLVE_PEER_ON_FIRST_TRANSMIT_FAILURE
100 : *
101 : * @brief
102 : * Should an address lookup of the peer happen on every first message that fails
103 : * to send on the link.
104 : *
105 : * The default value to not perform lookup was selected because most implementations
106 : * of address lookup are not cache the and a request is sent on the link. Failing
107 : * to deliver the first message is far more likely to happen due to lossy link
108 : * than an actual address change where the peer did not reset. In the lossy link
109 : * situation, doing further DNS resolutions on a degraded link can exacerbate that
110 : * problem greatly. Additionally, every message that arrives from a peer updates the
111 : * address. If the peer has fallen off the link due to any other reason, a re-resolve
112 : * may not achieve an address that is reachable, even if a resolve response occurs.
113 : */
114 : #ifndef CHIP_CONFIG_RESOLVE_PEER_ON_FIRST_TRANSMIT_FAILURE
115 : #define CHIP_CONFIG_RESOLVE_PEER_ON_FIRST_TRANSMIT_FAILURE 0
116 : #endif // CHIP_CONFIG_RESOLVE_PEER_ON_FIRST_TRANSMIT_FAILURE
117 :
118 : /**
119 : * @def CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE
120 : *
121 : * @brief
122 : * The default size of the ReliableMessageProtocol retransmission table.
123 : *
124 : */
125 : #ifndef CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE
126 : #if CHIP_SYSTEM_CONFIG_USE_LWIP
127 :
128 : #if !CHIP_SYSTEM_CONFIG_LWIP_PBUF_FROM_CUSTOM_POOL && PBUF_POOL_SIZE != 0
129 : // Configure the table size to be less than the number of packet buffers to make sure
130 : // that not all buffers are held by the retransmission entries, in which case the device
131 : // is unable to receive an ACK and hence becomes unavailable until a message times out.
132 : #define CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE std::min(PBUF_POOL_SIZE - 1, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS)
133 : #else
134 : #define CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS
135 : #endif // !CHIP_SYSTEM_CONFIG_LWIP_PBUF_FROM_CUSTOM_POOL && PBUF_POOL_SIZE != 0
136 :
137 : #else // CHIP_SYSTEM_CONFIG_USE_LWIP
138 :
139 : #if CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE != 0
140 : // Configure the table size to be less than the number of packet buffers to make sure
141 : // that not all buffers are held by the retransmission entries, in which case the device
142 : // is unable to receive an ACK and hence becomes unavailable until a message times out.
143 : #define CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE \
144 : std::min(CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE - 1, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS)
145 : #else
146 : #define CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS
147 : #endif // CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE != 0
148 :
149 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
150 : #endif // CHIP_CONFIG_RMP_RETRANS_TABLE_SIZE
151 :
152 : /**
153 : * @def CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS
154 : *
155 : * @brief
156 : * The maximum number of retransmissions before giving up.
157 : *
158 : */
159 : #ifndef CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS
160 : #define CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS (4)
161 : #endif // CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS
162 :
163 : /**
164 : * @def CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST
165 : *
166 : * @brief
167 : * A constant value that should be added to the calculated retransmission
168 : * timeout when the present node transmits a message.
169 : *
170 : * The purpose for this constant is to limit the possibility of spurious
171 : * retransmissions in the scenario in which a sender that operates in a high-
172 : * latency network (such as Thread) sends a message to a receiver that operates
173 : * in a low-latency network (such as Wi-Fi). In this scenario, the SAI and SII
174 : * parameters advertised by the receiver are low although the average round-
175 : * trip time of a big request-response pair is long due to the nature of the
176 : * sender.
177 : */
178 : #ifndef CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST
179 : #if CHIP_ENABLE_OPENTHREAD && !CHIP_DEVICE_LAYER_TARGET_LINUX
180 : #define CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST (1500_ms)
181 : #else
182 : #define CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST (0_ms)
183 : #endif
184 : #endif // CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST
185 :
186 : inline constexpr System::Clock::Milliseconds32 kDefaultActiveTime = System::Clock::Milliseconds16(4000);
187 :
188 : /**
189 : * @brief
190 : * The ReliableMessageProtocol configuration.
191 : */
192 : struct ReliableMessageProtocolConfig
193 : {
194 138395 : ReliableMessageProtocolConfig(System::Clock::Milliseconds32 idleInterval, System::Clock::Milliseconds32 activeInterval,
195 138395 : System::Clock::Milliseconds16 activeThreshold = kDefaultActiveTime) :
196 138395 : mIdleRetransTimeout(idleInterval),
197 138395 : mActiveRetransTimeout(activeInterval), mActiveThresholdTime(activeThreshold)
198 138395 : {}
199 :
200 : // Configurable timeout in msec for retransmission of the first sent message.
201 : System::Clock::Milliseconds32 mIdleRetransTimeout;
202 :
203 : // Configurable timeout in msec for retransmission of all subsequent messages.
204 : System::Clock::Milliseconds32 mActiveRetransTimeout;
205 :
206 : // Configurable amount of time the node SHOULD stay active after network activity.
207 : System::Clock::Milliseconds16 mActiveThresholdTime;
208 :
209 8310 : bool operator==(const ReliableMessageProtocolConfig & that) const
210 : {
211 16573 : return mIdleRetransTimeout == that.mIdleRetransTimeout && mActiveRetransTimeout == that.mActiveRetransTimeout &&
212 16573 : mActiveThresholdTime == that.mActiveThresholdTime;
213 : }
214 :
215 : #if CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG
216 : /**
217 : * Set the local MRP configuration for the node.
218 : *
219 : * Passing a "no value" optional resets to the compiled-in settings
220 : * (CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL and
221 : * CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL).
222 : *
223 : * Otherwise the value set via this function is used instead of the
224 : * compiled-in settings, but can still be overridden by ICD configuration
225 : * and other things that would override the compiled-in settings.
226 : *
227 : * Changing the value via this function does not affect any existing
228 : * sessions or exchanges, but does affect the values we communicate to our
229 : * peer during future session establishments.
230 : *
231 : * @return whether the local MRP configuration actually changed as a result
232 : * of this call. If it did, callers may need to reset DNS-SD
233 : * advertising to advertise the updated values.
234 : */
235 : static bool SetLocalMRPConfig(const Optional<ReliableMessageProtocolConfig> & localMRPConfig);
236 : #endif // CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG
237 : };
238 :
239 : /// @brief The default MRP config. The value is defined by spec, and shall be same for all implementations,
240 : ReliableMessageProtocolConfig GetDefaultMRPConfig();
241 :
242 : /**
243 : * @brief The custom value of MRP config for the platform.
244 : * @return Missing If the value is same as default value defined by spec
245 : * Value The custom value for the platform
246 : *
247 : * @note This value is not used by our MRP manager. The value is advertised via mDNS or during PASE/CASE paring, and our peers
248 : * use it when communicating with us.
249 : */
250 : Optional<ReliableMessageProtocolConfig> GetLocalMRPConfig();
251 :
252 : /**
253 : * @brief
254 : * Returns the maximum transmission time depending on the last activity time.
255 : *
256 : * @param[in] activeInterval The active interval to use for the backoff calculation.
257 : * @param[in] idleInterval The idle interval to use for the backoff calculation.
258 : * @param[in] lastActivityTime The last time some activity has been recorded.
259 : * @param[in] activityThreshold The activity threshold for a node to be considered active.
260 : *
261 : * @return The maximum transmission time
262 : */
263 : System::Clock::Timeout GetRetransmissionTimeout(System::Clock::Timeout activeInterval, System::Clock::Timeout idleInterval,
264 : System::Clock::Timeout lastActivityTime, System::Clock::Timeout activityThreshold);
265 :
266 : #if CONFIG_BUILD_FOR_HOST_UNIT_TEST
267 :
268 : /**
269 : * @brief
270 : *
271 : * Overrides the local idle and active retransmission timeout parameters (which are usually set through compile
272 : * time defines). This is reserved for tests that need the ability to set these at runtime to make certain test scenarios possible.
273 : *
274 : */
275 : void OverrideLocalMRPConfig(System::Clock::Timeout idleRetransTimeout, System::Clock::Timeout activeRetransTimeout,
276 : System::Clock::Timeout activeThresholdTime = kDefaultActiveTime);
277 :
278 : /**
279 : * @brief
280 : *
281 : * Disables the overrides set previously in OverrideLocalMRPConfig().
282 : *
283 : */
284 : void ClearLocalMRPConfigOverride();
285 : #endif
286 :
287 : } // namespace chip
|