commit | author | age
|
d6b4a7
|
1 |
/* |
G |
2 |
* coreSNTP v1.2.0 |
|
3 |
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
|
4 |
* |
|
5 |
* SPDX-License-Identifier: MIT |
|
6 |
* |
|
7 |
* Permission is hereby granted, free of charge, to any person obtaining a copy of |
|
8 |
* this software and associated documentation files (the "Software"), to deal in |
|
9 |
* the Software without restriction, including without limitation the rights to |
|
10 |
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
|
11 |
* the Software, and to permit persons to whom the Software is furnished to do so, |
|
12 |
* subject to the following conditions: |
|
13 |
* |
|
14 |
* The above copyright notice and this permission notice shall be included in all |
|
15 |
* copies or substantial portions of the Software. |
|
16 |
* |
|
17 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
18 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
|
19 |
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
|
20 |
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
|
21 |
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
22 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
23 |
*/ |
|
24 |
|
|
25 |
/** |
|
26 |
* @file core_sntp_serializer.h |
|
27 |
* @brief API for serializing SNTP request packets and, and de-serializing SNTP |
|
28 |
* response packets. |
|
29 |
* This API layer adheres to the SNTPv4 specification defined in |
|
30 |
* [RFC 4330](https://tools.ietf.org/html/rfc4330). |
|
31 |
*/ |
|
32 |
|
|
33 |
#ifndef CORE_SNTP_SERIALIZER_H_ |
|
34 |
#define CORE_SNTP_SERIALIZER_H_ |
|
35 |
|
|
36 |
/* Standard include. */ |
|
37 |
#include <stdint.h> |
|
38 |
#include <stddef.h> |
|
39 |
|
|
40 |
/* *INDENT-OFF* */ |
|
41 |
#ifdef __cplusplus |
|
42 |
extern "C" { |
|
43 |
#endif |
|
44 |
/* *INDENT-ON* */ |
|
45 |
|
|
46 |
/** |
|
47 |
* @ingroup sntp_constants |
|
48 |
* @brief The base packet size of request and response of the (S)NTP protocol. |
|
49 |
* @note This is the packet size without any authentication headers for security |
|
50 |
* mechanism. If the application uses a security mechanism for communicating with |
|
51 |
* an (S)NTP server, it can add authentication data after the SNTP packet is |
|
52 |
* serialized with the @ref Sntp_SerializeRequest API function. |
|
53 |
*/ |
|
54 |
#define SNTP_PACKET_BASE_SIZE ( 48U ) |
|
55 |
|
|
56 |
/** |
|
57 |
* @ingroup sntp_constants |
|
58 |
* @brief Number of SNTP timestamp fractions in 1 microsecond. |
|
59 |
* |
|
60 |
* The fraction's part of an SNTP timestamp is 32-bits wide, thereby, giving a |
|
61 |
* resolution of 2^(-32) seconds ~ 232 picoseconds. |
|
62 |
* |
|
63 |
* @note The application can use this value to convert microseconds part of system |
|
64 |
* time into SNTP timestamp fractions. For example, if the microseconds |
|
65 |
* part of system time is n microseconds, the fractions value to be used for the |
|
66 |
* SNTP timestamp part will be n * SNTP_FRACTION_VALUE_PER_MICROSECOND. |
|
67 |
*/ |
|
68 |
#define SNTP_FRACTION_VALUE_PER_MICROSECOND ( 4295U ) |
|
69 |
|
|
70 |
/** |
|
71 |
* @ingroup sntp_constants |
|
72 |
* @brief The seconds part of SNTP time at the UNIX epoch time, which represents |
|
73 |
* an offset of 70 years (in seconds) between SNTP epoch and UNIX epoch time. |
|
74 |
* SNTP uses 1st Jan 1900 UTC as the epoch time, whereas UNIX standard uses |
|
75 |
* 1st Jan 1970 UTC as the epoch time, thereby, causing an offset of 70 years |
|
76 |
* between them. |
|
77 |
* |
|
78 |
* Difference of 70 years = ((70 * 365) + 17 leap days) * 24 * 3600 seconds |
|
79 |
* |
|
80 |
* @note If your system follows UNIX time, the application can use this value to |
|
81 |
* convert seconds part of a system time to seconds part of the equivalent SNTP |
|
82 |
* time. For example, if the seconds part of system time is n seconds, the seconds |
|
83 |
* value to be used for the SNTP timestamp will be n + SNTP_TO_UNIX_OFFSET_SECS. |
|
84 |
*/ |
|
85 |
#define SNTP_TIME_AT_UNIX_EPOCH_SECS ( 2208988800U ) |
|
86 |
|
|
87 |
/** |
|
88 |
* @ingroup sntp_constants |
|
89 |
* @brief The seconds value of SNTP timestamp for the largest UNIX time when |
|
90 |
* using signed 32-bit integer for seconds. |
|
91 |
* The largest time representable with a 32-bit signed integer in UNIX time |
|
92 |
* is 19 Jan 2038 3h 14m 7s UTC. However, as the SNTP time overflows at |
|
93 |
* 7 Feb 2036 6h 28m 16s UTC, therefore, the SNTP time for the largest UNIX time |
|
94 |
* represents the time duration between the 2 timestamps. |
|
95 |
* |
|
96 |
* SNTP Time at Largest Time Duration in the range |
|
97 |
* Signed 32-bit UNIX time = [7 Feb 2036 6:28:16, 19 Jan 2038 3:14:07] |
|
98 |
*/ |
|
99 |
#define SNTP_TIME_AT_LARGEST_UNIX_TIME_SECS ( 61505151U ) |
|
100 |
|
|
101 |
/** |
|
102 |
* @ingroup sntp_constants |
|
103 |
* @brief The UNIX time (in seconds) at the smallest SNTP time in era 1, |
|
104 |
* i.e. UNIX time at 7 Feb 2036 6:28:16 UTC/ |
|
105 |
* |
|
106 |
* Time Duration = 7 Feb 6:28:16 UTC (SNTP Era 1 Epoch) - |
|
107 |
* 1 Jan 1970 0:0:0 UTC (UNIX epoch) |
|
108 |
* = 66 years, 37 days, 6 hours, 28 minutes and 16 seconds |
|
109 |
* = ((66 * 365) + 16 leap days) * 24 * 3600) + (6 * 3600) |
|
110 |
* + (28 * 60) + 16 |
|
111 |
*/ |
|
112 |
#define UNIX_TIME_SECS_AT_SNTP_ERA_1_SMALLEST_TIME ( 2085978496U ) |
|
113 |
|
|
114 |
/** |
|
115 |
* @ingroup sntp_constants |
|
116 |
* @brief The fixed-length of any Kiss-o'-Death message ASCII code sent |
|
117 |
* in an SNTP server response. |
|
118 |
* @note An SNTP server sends a Kiss-o'-Death message to reject a time request |
|
119 |
* from the client. For more information on the Kiss-o'-Death codes, refer to the |
|
120 |
* [SNTPv4 specification Section 8](https://tools.ietf.org/html/rfc4330#section-8). |
|
121 |
*/ |
|
122 |
#define SNTP_KISS_OF_DEATH_CODE_LENGTH ( 4U ) |
|
123 |
|
|
124 |
/** |
|
125 |
* @ingroup sntp_constants |
|
126 |
* @brief The value for the #SntpResponseData_t.rejectedResponseCode member |
|
127 |
* when that the server response packet does not contain a Kiss-o'-Death |
|
128 |
* message, and therefore, does not have a "kiss code". |
|
129 |
* The server sends a "kiss-code" only when it rejects an SNTP request |
|
130 |
* with a Kiss-o'-Death message. |
|
131 |
*/ |
|
132 |
#define SNTP_KISS_OF_DEATH_CODE_NONE ( 0U ) |
|
133 |
|
|
134 |
/** |
|
135 |
* @ingroup sntp_enum_types |
|
136 |
* @brief Enumeration of status codes that can be returned |
|
137 |
* by the coreSNTP Library API. |
|
138 |
*/ |
|
139 |
typedef enum SntpStatus |
|
140 |
{ |
|
141 |
/** |
|
142 |
* @brief Successful operation of an SNTP API. |
|
143 |
*/ |
|
144 |
SntpSuccess, |
|
145 |
|
|
146 |
/** |
|
147 |
* @brief Invalid parameter passed to an API function. |
|
148 |
*/ |
|
149 |
SntpErrorBadParameter, |
|
150 |
|
|
151 |
/** |
|
152 |
* @brief Server sent a Kiss-o'-Death message to reject the request for time. |
|
153 |
* This status can be returned by the @ref Sntp_ReceiveTimeResponse API. |
|
154 |
*/ |
|
155 |
SntpRejectedResponse, |
|
156 |
|
|
157 |
/** |
|
158 |
* @brief Server sent a Kiss-o'-Death message with non-retryable code (i.e. DENY or RSTR). |
|
159 |
*/ |
|
160 |
SntpRejectedResponseChangeServer, |
|
161 |
|
|
162 |
/** |
|
163 |
* @brief Server sent a Kiss-o'-Death message with a RATE code, which means that |
|
164 |
* client should back-off before retrying. |
|
165 |
*/ |
|
166 |
SntpRejectedResponseRetryWithBackoff, |
|
167 |
|
|
168 |
/** |
|
169 |
* @brief Server sent a Kiss-o'-Death message with a code, specific to the server. |
|
170 |
* Application can inspect the ASCII kiss-code from @ref Sntp_DeserializeResponse API. |
|
171 |
*/ |
|
172 |
SntpRejectedResponseOtherCode, |
|
173 |
|
|
174 |
/** |
|
175 |
* @brief Application provided insufficient buffer space for serializing |
|
176 |
* or de-serializing an SNTP packet. |
|
177 |
* The minimum size of an SNTP packet is #SNTP_PACKET_BASE_SIZE |
|
178 |
* bytes. */ |
|
179 |
SntpErrorBufferTooSmall, |
|
180 |
|
|
181 |
/** |
|
182 |
* @brief Server response failed validation checks for expected data in SNTP packet. |
|
183 |
*/ |
|
184 |
SntpInvalidResponse, |
|
185 |
|
|
186 |
/** |
|
187 |
* @brief Poll interval value is under 1 second which cannot be calculated |
|
188 |
* by @ref Sntp_CalculatePollInterval. |
|
189 |
*/ |
|
190 |
SntpZeroPollInterval, |
|
191 |
|
|
192 |
/** |
|
193 |
* @brief SNTP timestamp cannot be converted to UNIX time as time does not lie |
|
194 |
* in time range supported by Sntp_ConvertToUnixTime. |
|
195 |
*/ |
|
196 |
SntpErrorTimeNotSupported, |
|
197 |
|
|
198 |
/** |
|
199 |
* @brief The user-defined DNS resolution interface, @ref SntpResolveDns_t, failed to resolve |
|
200 |
* address for a time server. This status is returned by the @ref Sntp_SendTimeRequest API. |
|
201 |
*/ |
|
202 |
SntpErrorDnsFailure, |
|
203 |
|
|
204 |
/** |
|
205 |
* @brief Networking operation of sending or receiving SNTP packet through the user-defined UDP |
|
206 |
* transport interface, @ref UdpTransportInterface_t, failed. |
|
207 |
* This status is returned by either of @ref Sntp_SendTimeRequest OR @ref Sntp_ReceiveTimeResponse |
|
208 |
* APIs. |
|
209 |
*/ |
|
210 |
SntpErrorNetworkFailure, |
|
211 |
|
|
212 |
/** |
|
213 |
* @brief Time server is not authenticated from the authentication data in its response. |
|
214 |
* This status can be returned by the user-supplied definition of the |
|
215 |
* @ref SntpValidateServerAuth_t authentication interface. |
|
216 |
*/ |
|
217 |
SntpServerNotAuthenticated, |
|
218 |
|
|
219 |
/** |
|
220 |
* @brief Failure from the user-supplied authentication interface, @ref SntpAuthenticationInterface_t, |
|
221 |
* in either generating authentication data for SNTP request OR validating the authentication |
|
222 |
* data in SNTP response from server. |
|
223 |
*/ |
|
224 |
SntpErrorAuthFailure, |
|
225 |
|
|
226 |
/** |
|
227 |
* @brief A timeout occurred in sending time request packet over the network to a server through the |
|
228 |
* @ref Sntp_SendTimeRequest API. |
|
229 |
*/ |
|
230 |
SntpErrorSendTimeout, |
|
231 |
|
|
232 |
/** |
|
233 |
* @brief A timeout has occurred in receiving server response with the @ref Sntp_ReceiveTimeResponse |
|
234 |
* API. |
|
235 |
*/ |
|
236 |
SntpErrorResponseTimeout, |
|
237 |
|
|
238 |
/** |
|
239 |
* @brief No SNTP packet for server response is received from the network by the |
|
240 |
* @ref Sntp_ReceiveTimeResponse API. |
|
241 |
*/ |
|
242 |
SntpNoResponseReceived, |
|
243 |
|
|
244 |
/** |
|
245 |
* @brief The SNTP context passed to @ref Sntp_SendTimeRequest or @ref Sntp_ReceiveTimeResponse APIs is |
|
246 |
* is uninitialized. |
|
247 |
*/ |
|
248 |
SntpErrorContextNotInitialized |
|
249 |
} SntpStatus_t; |
|
250 |
|
|
251 |
/** |
|
252 |
* @ingroup sntp_enum_types |
|
253 |
* @brief Enumeration for leap second information that an SNTP server can |
|
254 |
* send its response to a time request. An SNTP server sends information about |
|
255 |
* whether there is an upcoming leap second adjustment in the last day of the |
|
256 |
* current month. |
|
257 |
* |
|
258 |
* @note A leap second is an adjustment made in atomic clock time because Earth's rotation |
|
259 |
* can be inconsistent. Leap seconds are usually incorporated as an extra second insertion |
|
260 |
* or second deletion in the last minute before midnight i.e. in the minute of 23h:59m UTC |
|
261 |
* on the last day of June or December. For more information on leap seconds, refer to |
|
262 |
* https://www.nist.gov/pml/time-and-frequency-division/leap-seconds-faqs. |
|
263 |
*/ |
|
264 |
typedef enum SntpLeapSecondInfo |
|
265 |
{ |
|
266 |
NoLeapSecond = 0x00, /** <@brief There is no upcoming leap second adjustment. */ |
|
267 |
LastMinuteHas61Seconds = 0x01, /** <@brief A leap second should be inserted in the last minute before midnight. */ |
|
268 |
LastMinuteHas59Seconds = 0x02, /** <@brief A leap second should be deleted from the last minute before midnight. */ |
|
269 |
AlarmServerNotSynchronized = 0x03 /** <@brief An alarm condition meaning that server's time is not synchronized |
|
270 |
* to an upstream NTP (or SNTP) server. */ |
|
271 |
} SntpLeapSecondInfo_t; |
|
272 |
|
|
273 |
/** |
|
274 |
* @ingroup sntp_struct_types |
|
275 |
* @brief Structure representing an SNTP timestamp. |
|
276 |
* |
|
277 |
* @note The SNTP timestamp uses 1st January 1900 0h 0m 0s Coordinated Universal Time (UTC) |
|
278 |
* as the primary epoch i.e. the timestamp represents current time as the amount of time since |
|
279 |
* the epoch time. |
|
280 |
* Refer to the [SNTPv4 specification](https://tools.ietf.org/html/rfc4330#section-3) for more |
|
281 |
* information of the SNTP timestamp format. |
|
282 |
*/ |
|
283 |
typedef struct SntpTimestamp |
|
284 |
{ |
|
285 |
uint32_t seconds; /**< @brief Number of seconds since epoch time. */ |
|
286 |
uint32_t fractions; /**< @brief The fractions part of the SNTP timestamp with resolution |
|
287 |
* of 2^(-32) ~ 232 picoseconds. */ |
|
288 |
} SntpTimestamp_t; |
|
289 |
|
|
290 |
/** |
|
291 |
* @ingroup sntp_struct_types |
|
292 |
* @brief Structure representing data parsed from an SNTP response from server |
|
293 |
* as well as data of arithmetic calculations derived from the response. |
|
294 |
*/ |
|
295 |
typedef struct SntpResponse |
|
296 |
{ |
|
297 |
/** |
|
298 |
* @brief The timestamp sent by the server. |
|
299 |
*/ |
|
300 |
SntpTimestamp_t serverTime; |
|
301 |
|
|
302 |
/** |
|
303 |
* @brief The information of an upcoming leap second in the |
|
304 |
* server response. |
|
305 |
*/ |
|
306 |
SntpLeapSecondInfo_t leapSecondType; |
|
307 |
|
|
308 |
/** |
|
309 |
* @brief If a server responded with Kiss-o'-Death message to reject |
|
310 |
* time request, this is the fixed length ASCII code sequence for the |
|
311 |
* rejection. |
|
312 |
* |
|
313 |
* The Kiss-o'-Death code is always #SNTP_KISS_OF_DEATH_CODE_LENGTH |
|
314 |
* bytes long. |
|
315 |
* |
|
316 |
* @note If the server does not send a Kiss-o'-Death message in its |
|
317 |
* response, this value will be #SNTP_KISS_OF_DEATH_CODE_NONE. |
|
318 |
*/ |
|
319 |
uint32_t rejectedResponseCode; |
|
320 |
|
|
321 |
/** |
|
322 |
* @brief The offset (in milliseconds) of the system clock relative to the server time |
|
323 |
* calculated from timestamps in the client SNTP request and server SNTP response packets. |
|
324 |
* If the the system time is BEHIND the server time, then the clock-offset value is > 0. |
|
325 |
* If the system time is AHEAD of the server time, then the clock-offset value is < 0. |
|
326 |
* |
|
327 |
* @note This information can be used to synchronize the system clock with a "slew", |
|
328 |
* "step" OR combination of the two clock correction methodologies depending on the degree |
|
329 |
* of system clock drift (represented by the clock-offset) and the application's |
|
330 |
* tolerance for system clock error. |
|
331 |
* |
|
332 |
* @note The library calculates the clock-offset value using the On-Wire |
|
333 |
* protocol suggested by the NTPv4 specification. For more information, |
|
334 |
* refer to https://tools.ietf.org/html/rfc5905#section-8. |
|
335 |
* |
|
336 |
* @note The library ASSUMES that the server and client systems are within |
|
337 |
* ~68 years of each other clock, whether in the same NTP era or across adjacent |
|
338 |
* NTP eras. Thus, the client and system times MUST be within ~68 years (or |
|
339 |
* 2^31 seconds exactly) of each other for correct calculation of clock-offset. |
|
340 |
* |
|
341 |
* @note When the server and client times are exactly 2^31 (or INT32_MAX + 1 ) |
|
342 |
* seconds apart, the library ASSUMES that the server time is ahead of the client |
|
343 |
* time, and return the clock-offset value of INT32_MAX. |
|
344 |
*/ |
|
345 |
int64_t clockOffsetMs; |
|
346 |
} SntpResponseData_t; |
|
347 |
|
|
348 |
|
|
349 |
/** |
|
350 |
* @brief Serializes an SNTP request packet to use for querying a |
|
351 |
* time server. |
|
352 |
* |
|
353 |
* This function will fill only #SNTP_PACKET_BASE_SIZE bytes of data in the |
|
354 |
* passed buffer. |
|
355 |
* |
|
356 |
* @param[in, out] pRequestTime The current time of the system, expressed as time |
|
357 |
* since the SNTP epoch (i.e. 0h of 1st Jan 1900 ). This time will be serialized |
|
358 |
* in the SNTP request packet. The function will use this parameter to return the |
|
359 |
* timestamp serialized in the SNTP request. To protect against attacks spoofing |
|
360 |
* server responses, the timestamp MUST NOT be zero in value. |
|
361 |
* @param[in] randomNumber A random number (generated by a True Random Generator) |
|
362 |
* for use in the SNTP request packet to protect against replay attacks as suggested |
|
363 |
* by SNTPv4 specification. For more information, refer to |
|
364 |
* [RFC 4330 Section 3](https://tools.ietf.org/html/rfc4330#section-3). |
|
365 |
* @param[out] pBuffer The buffer that will be populated with the serialized |
|
366 |
* SNTP request packet. |
|
367 |
* @param[in] bufferSize The size of the @p pBuffer buffer. It should be at least |
|
368 |
* #SNTP_PACKET_BASE_SIZE bytes in size. |
|
369 |
* |
|
370 |
* @note It is recommended to use a True Random Generator (TRNG) to generate |
|
371 |
* the random number. |
|
372 |
* @note The application MUST save the @p pRequestTime value for de-serializing |
|
373 |
* the server response with @ref Sntp_DeserializeResponse API. |
|
374 |
* |
|
375 |
* @return This function returns one of the following: |
|
376 |
* - #SntpSuccess when serialization operation is successful. |
|
377 |
* - #SntpErrorBadParameter if an invalid parameter is passed. |
|
378 |
* - #SntpErrorBufferTooSmall if the buffer does not have the minimum size |
|
379 |
* for serializing an SNTP request packet. |
|
380 |
*/ |
|
381 |
/* @[define_sntp_serializerequest] */ |
|
382 |
SntpStatus_t Sntp_SerializeRequest( SntpTimestamp_t * pRequestTime, |
|
383 |
uint32_t randomNumber, |
|
384 |
void * pBuffer, |
|
385 |
size_t bufferSize ); |
|
386 |
/* @[define_sntp_serializerequest] */ |
|
387 |
|
|
388 |
/** |
|
389 |
* @brief De-serializes an SNTP packet received from a server as a response |
|
390 |
* to a SNTP request. |
|
391 |
* |
|
392 |
* This function will parse only the #SNTP_PACKET_BASE_SIZE bytes of data |
|
393 |
* in the passed buffer. |
|
394 |
* |
|
395 |
* @note If the server has sent a Kiss-o'-Death message to reject the associated |
|
396 |
* time request, the API function will return the appropriate return code and, |
|
397 |
* also, provide the ASCII code (of fixed length, #SNTP_KISS_OF_DEATH_CODE_LENGTH bytes) |
|
398 |
* in the #SntpResponseData_t.rejectedResponseCode member of @p pParsedResponse parameter, |
|
399 |
* parsed from the response packet. |
|
400 |
* The application SHOULD respect the server rejection and take appropriate action |
|
401 |
* based on the rejection code. |
|
402 |
* If the server response represents an accepted SNTP client request, then the API |
|
403 |
* function will set the #SntpResponseData_t.rejectedResponseCode member of |
|
404 |
* @p pParsedResponse parameter to #SNTP_KISS_OF_DEATH_CODE_NONE. |
|
405 |
* |
|
406 |
* @note If the server has positively responded with its clock time, then this API |
|
407 |
* function will calculate the clock-offset. For the clock-offset to be correctly |
|
408 |
* calculated, the system clock MUST be within ~68 years (or 2^31 seconds) of the server |
|
409 |
* time mentioned. This function supports clock-offset calculation when server and client |
|
410 |
* timestamps are in adjacent NTP eras, with one system is in NTP era 0 (i.e. before 7 Feb 2036 |
|
411 |
* 6h:28m:14s UTC) and another system in NTP era 1 (on or after 7 Feb 2036 6h:28m:14s UTC). |
|
412 |
* |
|
413 |
* @note In the special case when the server and client times are exactly 2^31 seconds apart, |
|
414 |
* the library ASSUMES that the server time is ahead of the client time, and returns the |
|
415 |
* positive clock-offset value of INT32_MAX seconds. |
|
416 |
* |
|
417 |
* @param[in] pRequestTime The system time used in the SNTP request packet |
|
418 |
* that is associated with the server response. This MUST be the same as the |
|
419 |
* time returned by the @ref Sntp_SerializeRequest API. To protect against attacks |
|
420 |
* spoofing server responses, this timestamp MUST NOT be zero in value. |
|
421 |
* @param[in] pResponseRxTime The time of the system, expressed as time since the |
|
422 |
* SNTP epoch (i.e. 0h of 1st Jan 1900 ), at receiving SNTP response from server. |
|
423 |
* This time will be used to calculate system clock offset relative to server. |
|
424 |
* @param[in] pResponseBuffer The buffer containing the SNTP response from the |
|
425 |
* server. |
|
426 |
* @param[in] bufferSize The size of the @p pResponseBuffer containing the SNTP |
|
427 |
* response. It MUST be at least #SNTP_PACKET_BASE_SIZE bytes |
|
428 |
* long for a valid SNTP response. |
|
429 |
* @param[out] pParsedResponse The information parsed from the SNTP response packet. |
|
430 |
* If possible to calculate without overflow, it also contains the system clock |
|
431 |
* offset relative to the server time. |
|
432 |
* |
|
433 |
* @return This function returns one of the following: |
|
434 |
* - #SntpSuccess if the de-serialization operation is successful. |
|
435 |
* - #SntpErrorBadParameter if an invalid parameter is passed. |
|
436 |
* - #SntpErrorBufferTooSmall if the buffer does not have the minimum size |
|
437 |
* required for a valid SNTP response packet. |
|
438 |
* - #SntpInvalidResponse if the response fails sanity checks expected in an |
|
439 |
* SNTP response. |
|
440 |
* - #SntpRejectedResponseChangeServer if the server rejected with a code |
|
441 |
* indicating that client cannot be retry requests to it. |
|
442 |
* - #SntpRejectedResponseRetryWithBackoff if the server rejected with a code |
|
443 |
* indicating that client should back-off before retrying request. |
|
444 |
* - #SntpRejectedResponseOtherCode if the server rejected with a code that |
|
445 |
* application can inspect in the @p pParsedResponse parameter. |
|
446 |
*/ |
|
447 |
/* @[define_sntp_deserializeresponse] */ |
|
448 |
SntpStatus_t Sntp_DeserializeResponse( const SntpTimestamp_t * pRequestTime, |
|
449 |
const SntpTimestamp_t * pResponseRxTime, |
|
450 |
const void * pResponseBuffer, |
|
451 |
size_t bufferSize, |
|
452 |
SntpResponseData_t * pParsedResponse ); |
|
453 |
/* @[define_sntp_deserializeresponse] */ |
|
454 |
|
|
455 |
/** |
|
456 |
* @brief Utility to calculate the poll interval of sending periodic time queries |
|
457 |
* to servers to achieve a desired system clock accuracy for a given |
|
458 |
* frequency tolerance of the system clock. |
|
459 |
* |
|
460 |
* For example, from the SNTPv4 specification, "if the frequency tolerance |
|
461 |
* is 200 parts per million (PPM) and the required accuracy is one minute, |
|
462 |
* the maximum timeout is about 3.5 days". In this example, the system |
|
463 |
* clock frequency tolerance is 200 PPM and the desired accuracy is |
|
464 |
* 60000 milliseconds (or 1 minute) for which this API function |
|
465 |
* will return the maximum poll interval value as 2^18 seconds (or ~3 days). |
|
466 |
* |
|
467 |
* @note The poll interval returned is a power of 2, which is the |
|
468 |
* standard way to represent the value. According to the SNTPv4 specification |
|
469 |
* Best Practices, an SNTP client SHOULD NOT have a poll interval less than 15 seconds. |
|
470 |
* https://tools.ietf.org/html/rfc4330#section-10. This API function DOES NOT |
|
471 |
* support poll interval calculation less than 1 second. |
|
472 |
* |
|
473 |
* @param[in] clockFreqTolerance The frequency tolerance of system clock |
|
474 |
* in parts per million (PPM) units. This parameter MUST be non-zero. |
|
475 |
* @param[in] desiredAccuracy The acceptable maximum drift, in milliseconds, |
|
476 |
* for the system clock. The maximum value (0xFFFF) represents ~1 minute of |
|
477 |
* desired clock accuracy. This parameter MUST be non-zero. |
|
478 |
* @param[out] pPollInterval This is filled with the poll interval, in seconds |
|
479 |
* calculated as the closest power of 2 value that will achieve either the |
|
480 |
* exact desired or higher clock accuracy @p desiredAccuracy, for the given clock |
|
481 |
* frequency tolerance, @p clockFreqTolerance. |
|
482 |
* |
|
483 |
* @return Returns one of the following: |
|
484 |
* - #SntpSuccess if calculation is successful. |
|
485 |
* - #SntpErrorBadParameter for an invalid parameter passed to the function. |
|
486 |
* - #SntpZeroPollInterval if calculated poll interval is less than 1 second. |
|
487 |
*/ |
|
488 |
/* @[define_sntp_calculatepollinterval] */ |
|
489 |
SntpStatus_t Sntp_CalculatePollInterval( uint16_t clockFreqTolerance, |
|
490 |
uint16_t desiredAccuracy, |
|
491 |
uint32_t * pPollInterval ); |
|
492 |
/* @[define_sntp_calculatepollinterval] */ |
|
493 |
|
|
494 |
|
|
495 |
/** |
|
496 |
* @brief Utility to convert SNTP timestamp (that uses 1st Jan 1900 as the epoch) to |
|
497 |
* UNIX timestamp (that uses 1st Jan 1970 as the epoch). |
|
498 |
* |
|
499 |
* @note This function can ONLY handle conversions of SNTP timestamps that lie in the |
|
500 |
* range from 1st Jan 1970 0h 0m 0s, the UNIX epoch time, to 19th Jan 2038 3h 14m 7s, |
|
501 |
* the maximum UNIX time that can be represented in a signed 32 bit integer. (The |
|
502 |
* limitation is to support systems that use signed 32-bit integer to represent the |
|
503 |
* seconds part of the UNIX time.) |
|
504 |
* |
|
505 |
* @note This function supports overflow of the SNTP timestamp (from the 7 Feb 2036 |
|
506 |
* 6h 28m 16s time, i.e. SNTP era 1) by treating the timestamps with seconds part |
|
507 |
* in the range [0, 61,505,152] seconds where the upper limit represents the UNIX |
|
508 |
* overflow time (i.e. 19 Jan 2038 3h 14m 7s) for systems that use signed 32-bit |
|
509 |
* integer to represent time. |
|
510 |
* |
|
511 |
* @param[in] pSntpTime The SNTP timestamp to convert to UNIX time. |
|
512 |
* @param[out] pUnixTimeSecs This will be filled with the seconds part of the |
|
513 |
* UNIX time equivalent of the SNTP time, @p pSntpTime. |
|
514 |
* @param[out] pUnixTimeMicrosecs This will be filled with the microseconds part |
|
515 |
* of the UNIX time equivalent of the SNTP time, @p pSntpTime. |
|
516 |
* |
|
517 |
* @return Returns one of the following: |
|
518 |
* - #SntpSuccess if conversion to UNIX time is successful |
|
519 |
* - #SntpErrorBadParameter if any of the passed parameters are NULL. |
|
520 |
* - #SntpErrorTimeNotSupported if the passed SNTP time does not lie in the |
|
521 |
* supported time range. |
|
522 |
*/ |
|
523 |
/* @[define_sntp_converttounixtime] */ |
|
524 |
SntpStatus_t Sntp_ConvertToUnixTime( const SntpTimestamp_t * pSntpTime, |
|
525 |
uint32_t * pUnixTimeSecs, |
|
526 |
uint32_t * pUnixTimeMicrosecs ); |
|
527 |
/* @[define_sntp_converttounixtime] */ |
|
528 |
|
|
529 |
/* *INDENT-OFF* */ |
|
530 |
#ifdef __cplusplus |
|
531 |
} |
|
532 |
#endif |
|
533 |
/* *INDENT-ON* */ |
|
534 |
|
|
535 |
#endif /* ifndef CORE_SNTP_SERIALIZER_H_ */ |