xref: /aosp_15_r20/external/pigweed/pw_transfer/public/pw_transfer/internal/config.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 // Configuration macros for the transfer module.
16 #pragma once
17 
18 #include <chrono>
19 #include <cinttypes>
20 #include <limits>
21 
22 #include "pw_chrono/system_clock.h"
23 
24 // The log level to use for this module. Logs below this level are omitted.
25 #ifndef PW_TRANSFER_CONFIG_LOG_LEVEL
26 #define PW_TRANSFER_CONFIG_LOG_LEVEL PW_LOG_LEVEL_INFO
27 #endif  // PW_TRANSFER_CONFIG_LOG_LEVEL
28 
29 // Turns on logging of individual chunks. Data and parameter chunk logging has
30 // additional configuration
31 #ifndef PW_TRANSFER_CONFIG_DEBUG_CHUNKS
32 #define PW_TRANSFER_CONFIG_DEBUG_CHUNKS 0
33 #endif  // PW_TRANSFER_CONFIG_DEBUG_CHUNKS
34 
35 // Turns on logging of data and parameter chunks.
36 #ifndef PW_TRANSFER_CONFIG_DEBUG_DATA_CHUNKS
37 #define PW_TRANSFER_CONFIG_DEBUG_DATA_CHUNKS 0
38 #endif  // PW_TRANSFER_CONFIG_DEBUG_DATA_CHUNKS
39 
40 #ifdef PW_TRANSFER_DEFAULT_MAX_RETRIES
41 #pragma message(                                      \
42     "PW_TRANSFER_DEFAULT_MAX_RETRIES is deprecated; " \
43     "Use PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES and " \
44     "PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES instead.")
45 #endif  // PW_TRANSFER_DEFAULT_MAX_RETRIES
46 
47 #ifdef PW_TRANSFER_DEFAULT_TIMEOUT_MS
48 #pragma message(                                     \
49     "PW_TRANSFER_DEFAULT_TIMEOUT_MS is deprecated; " \
50     "Use PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS and " \
51     "PW_TRANSFER_DEFAULT_SERVER_TIMEOUT_MS instead.")
52 #endif  // PW_TRANSFER_DEFAULT_TIMEOUT_MS
53 
54 // The default maximum number of times a transfer client should retry sending a
55 // chunk when no response is received. Can later be configured per-transfer when
56 // starting one.
57 #ifndef PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES
58 
59 // Continue to accept the old deprecated setting until projects have migrated.
60 #ifdef PW_TRANSFER_DEFAULT_MAX_RETRIES
61 #define PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES PW_TRANSFER_DEFAULT_MAX_RETRIES
62 #else
63 #define PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES 3
64 #endif  // PW_TRANSFER_DEFAULT_MAX_RETRIES
65 
66 #endif  // PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES
67 
68 static_assert(PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES >= 0 &&
69               PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES <=
70                   static_cast<uint32_t>(std::numeric_limits<uint8_t>::max()));
71 
72 // The default maximum number of times a transfer server should retry sending a
73 // chunk when no response is received.
74 //
75 // In typical setups, retries are driven by the client, and timeouts on the
76 // server are used only to clean up resources, so this defaults to 0.
77 #ifndef PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES
78 
79 // Continue to accept the old deprecated setting until projects have migrated.
80 #ifdef PW_TRANSFER_DEFAULT_MAX_RETRIES
81 #define PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES PW_TRANSFER_DEFAULT_MAX_RETRIES
82 #else
83 #define PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES 0
84 #endif  // PW_TRANSFER_DEFAULT_MAX_RETRIES
85 
86 #endif  // PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES
87 
88 // GCC emits spurious -Wtype-limits warnings for the static_assert.
89 PW_MODIFY_DIAGNOSTICS_PUSH();
90 PW_MODIFY_DIAGNOSTIC_GCC(ignored, "-Wtype-limits");
91 static_assert(PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES >= 0 &&
92               PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES <=
93                   std::numeric_limits<uint8_t>::max());
94 PW_MODIFY_DIAGNOSTICS_POP();
95 
96 // The default maximum number of times a transfer should retry sending a chunk
97 // over the course of its entire lifetime.
98 // This number should be high, particularly if long-running transfers are
99 // expected. Its purpose is to prevent transfers from getting stuck in an
100 // infinite loop.
101 #ifndef PW_TRANSFER_DEFAULT_MAX_LIFETIME_RETRIES
102 #define PW_TRANSFER_DEFAULT_MAX_LIFETIME_RETRIES \
103   (static_cast<uint32_t>(PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES) * 1000u)
104 #endif  // PW_TRANSFER_DEFAULT_MAX_LIFETIME_RETRIES
105 
106 static_assert(PW_TRANSFER_DEFAULT_MAX_LIFETIME_RETRIES >
107                   PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES &&
108               PW_TRANSFER_DEFAULT_MAX_LIFETIME_RETRIES <=
109                   std::numeric_limits<uint32_t>::max());
110 
111 // The default amount of time, in milliseconds, to wait for a chunk to arrive
112 // in a transfer client before retrying. This can later be configured
113 // per-transfer.
114 #ifndef PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS
115 
116 // Continue to accept the old deprecated setting until projects have migrated.
117 #ifdef PW_TRANSFER_DEFAULT_TIMEOUT_MS
118 #define PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS PW_TRANSFER_DEFAULT_TIMEOUT_MS
119 #else
120 #define PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS 2000
121 #endif  // PW_TRANSFER_DEFAULT_TIMEOUT_MS
122 
123 #endif  // PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS
124 
125 static_assert(PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS > 0);
126 
127 // The default amount of time, in milliseconds, to wait for a chunk to arrive
128 // on the server before retrying. This can later be configured per-transfer.
129 #ifndef PW_TRANSFER_DEFAULT_SERVER_TIMEOUT_MS
130 
131 // Continue to accept the old deprecated setting until projects have migrated.
132 #ifdef PW_TRANSFER_DEFAULT_TIMEOUT_MS
133 #define PW_TRANSFER_DEFAULT_SERVER_TIMEOUT_MS PW_TRANSFER_DEFAULT_TIMEOUT_MS
134 #else
135 #define PW_TRANSFER_DEFAULT_SERVER_TIMEOUT_MS \
136   (static_cast<uint32_t>(PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS) * 5u)
137 #endif  // PW_TRANSFER_DEFAULT_TIMEOUT_MS
138 
139 #endif  // PW_TRANSFER_DEFAULT_SERVER_TIMEOUT_MS
140 
141 static_assert(PW_TRANSFER_DEFAULT_SERVER_TIMEOUT_MS > 0);
142 
143 // The default amount of time, in milliseconds, for a client to wait for an
144 // initial response from the transfer server before retrying. This can later be
145 // configured // per-transfer.
146 //
147 // This is set separately to PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS as transfers
148 // may require additional time for resource initialization (e.g. erasing a flash
149 // region before writing to it).
150 #ifndef PW_TRANSFER_DEFAULT_INITIAL_TIMEOUT_MS
151 #define PW_TRANSFER_DEFAULT_INITIAL_TIMEOUT_MS \
152   PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS
153 #endif  // PW_TRANSFER_DEFAULT_INITIAL_TIMEOUT_MS
154 
155 static_assert(PW_TRANSFER_DEFAULT_INITIAL_TIMEOUT_MS > 0);
156 
157 // The fractional position within a window at which a receive transfer should
158 // extend its window size to minimize the amount of time the transmitter
159 // spends blocked.
160 //
161 // For example, a divisor of 2 will extend the window when half of the
162 // requested data has been received, a divisor of three will extend at a third
163 // of the window, and so on.
164 #ifndef PW_TRANSFER_DEFAULT_EXTEND_WINDOW_DIVISOR
165 #define PW_TRANSFER_DEFAULT_EXTEND_WINDOW_DIVISOR 2
166 #endif  // PW_TRANSFER_DEFAULT_EXTEND_WINDOW_DIVISOR
167 
168 static_assert(PW_TRANSFER_DEFAULT_EXTEND_WINDOW_DIVISOR > 1);
169 
170 // Number of chunks to send repetitative logs at full rate before reducing to
171 // rate_limit. Retransmit parameter chunks will restart at this chunk count
172 // limit.
173 // Default is first 10 parameter logs will be sent, then reduced to one log
174 // every `RATE_PERIOD_MS`
175 #ifndef PW_TRANSFER_LOG_DEFAULT_CHUNKS_BEFORE_RATE_LIMIT
176 #define PW_TRANSFER_LOG_DEFAULT_CHUNKS_BEFORE_RATE_LIMIT 10
177 #endif  // PW_TRANSFER_LOG_DEFAULT_CHUNKS_BEFORE_RATE_LIMIT
178 
179 static_assert(PW_TRANSFER_LOG_DEFAULT_CHUNKS_BEFORE_RATE_LIMIT > 0);
180 
181 // The minimum time between repetative logs after the rate limit has been
182 // applied (after CHUNKS_BEFORE_RATE_LIMIT parameter chunks).
183 // Default is to reduce repetative logs to once every 10 seconds after
184 // `CHUNKS_BEFORE_RATE_LIMIT` parameter chunks have been sent.
185 #ifndef PW_TRANSFER_LOG_DEFAULT_RATE_PERIOD_MS
186 #define PW_TRANSFER_LOG_DEFAULT_RATE_PERIOD_MS 10000
187 #endif  // PW_TRANSFER_DEFAULT_MIN_RATE_PERIOD_MS
188 
189 static_assert(PW_TRANSFER_LOG_DEFAULT_RATE_PERIOD_MS >= 0);
190 
191 // Maximum time to wait for a transfer event to be processed before dropping
192 // further queued events. In systems which can perform long-running operations
193 // to process transfer data, this can be used to prevent threads from blocking
194 // for extended periods. A value of 0 results in indefinite blocking.
195 #ifndef PW_TRANSFER_EVENT_PROCESSING_TIMEOUT_MS
196 #define PW_TRANSFER_EVENT_PROCESSING_TIMEOUT_MS \
197   PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS
198 #endif  // PW_TRANSFER_EVENT_PROCESSING_TIMEOUT_MS
199 
200 static_assert(PW_TRANSFER_EVENT_PROCESSING_TIMEOUT_MS >= 0);
201 
202 namespace pw::transfer::cfg {
203 
204 inline constexpr uint8_t kDefaultMaxClientRetries =
205     PW_TRANSFER_DEFAULT_MAX_CLIENT_RETRIES;
206 inline constexpr uint8_t kDefaultMaxServerRetries =
207     PW_TRANSFER_DEFAULT_MAX_SERVER_RETRIES;
208 inline constexpr uint16_t kDefaultMaxLifetimeRetries =
209     PW_TRANSFER_DEFAULT_MAX_LIFETIME_RETRIES;
210 
211 inline constexpr chrono::SystemClock::duration kDefaultClientTimeout =
212     chrono::SystemClock::for_at_least(
213         std::chrono::milliseconds(PW_TRANSFER_DEFAULT_CLIENT_TIMEOUT_MS));
214 inline constexpr chrono::SystemClock::duration kDefaultServerTimeout =
215     chrono::SystemClock::for_at_least(
216         std::chrono::milliseconds(PW_TRANSFER_DEFAULT_SERVER_TIMEOUT_MS));
217 
218 inline constexpr chrono::SystemClock::duration kDefaultInitialChunkTimeout =
219     chrono::SystemClock::for_at_least(
220         std::chrono::milliseconds(PW_TRANSFER_DEFAULT_INITIAL_TIMEOUT_MS));
221 
222 inline constexpr uint32_t kDefaultExtendWindowDivisor =
223     PW_TRANSFER_DEFAULT_EXTEND_WINDOW_DIVISOR;
224 
225 inline constexpr uint16_t kLogDefaultChunksBeforeRateLimit =
226     PW_TRANSFER_LOG_DEFAULT_CHUNKS_BEFORE_RATE_LIMIT;
227 inline constexpr chrono::SystemClock::duration kLogDefaultRateLimit =
228     chrono::SystemClock::for_at_least(
229         std::chrono::milliseconds(PW_TRANSFER_LOG_DEFAULT_RATE_PERIOD_MS));
230 
231 inline constexpr bool kWaitForEventProcessingIndefinitely =
232     PW_TRANSFER_EVENT_PROCESSING_TIMEOUT_MS == 0;
233 inline constexpr chrono::SystemClock::duration kEventProcessingTimeout =
234     chrono::SystemClock::for_at_least(
235         std::chrono::milliseconds(PW_TRANSFER_EVENT_PROCESSING_TIMEOUT_MS));
236 
237 }  // namespace pw::transfer::cfg
238