RaspberrPi project source code
guowenxue
2023-08-26 d6b4a750258b34c79e3c643595a0ae1cb0e18bed
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_client.h
27  * @brief API of an SNTPv4 client library that can send time requests and receive time response to/from
28  * SNTP/NTP servers. The library follows the Best Practices suggested in the the SNTPv4 specification,
29  * [RFC 4330](https://tools.ietf.org/html/rfc4330).
30  * The library can be used to run an SNTP client in a dedicated deamon task to periodically synchronize
31  * time from the Internet.
32  */
33
34 #ifndef CORE_SNTP_CLIENT_H_
35 #define CORE_SNTP_CLIENT_H_
36
37 /* Standard include. */
38 #include <stdint.h>
39 #include <stddef.h>
40 #include <stdbool.h>
41
42 /* Include coreSNTP Serializer header. */
43 #include "core_sntp_serializer.h"
44
45 /* *INDENT-OFF* */
46 #ifdef __cplusplus
47     extern "C" {
48 #endif
49 /* *INDENT-ON* */
50
51 /**
52  * @ingroup sntp_constants
53  * @brief The default UDP port supported by SNTP/NTP servers for client-server
54  * communication.
55  *
56  * @note It is possible for a server to use a different port number than
57  * the default port when using the Network Time Security protocol as the security
58  * mechanism for SNTP communication. For more information, refer to Section 4.1.8
59  * of [RFC 8915](https://tools.ietf.org/html/rfc8915).
60  */
61 #define SNTP_DEFAULT_SERVER_PORT    ( 123U )
62
63 /**
64  * @ingroup sntp_struct_types
65  * @brief Structure representing information for a time server.
66  */
67 typedef struct SntpServerInfo
68 {
69     const char * pServerName; /**<@brief The time server name. */
70     size_t serverNameLen;     /**<@brief The length of the server name.*/
71     uint16_t port;            /**<@brief The UDP port supported by the server
72                                * for SNTP/NTP communication. */
73 } SntpServerInfo_t;
74
75 /**
76  * @ingroup sntp_callback_types
77  * @brief Interface for user-defined function to resolve time server domain-name
78  * to an IPv4 address.
79  * The SNTP client library attempts to resolve the DNS of the time-server being
80  * used every time the @ref Sntp_SendTimeRequest API is called.
81  *
82  * @param[in] pServerAddr The time-server whose IPv4 address is to be resolved.
83  * @param[out] pIpV4Addr This should be filled with the resolved IPv4 address.
84  * of @p pTimeServer.
85  *
86  * @return `true` if DNS resolution is successful; otherwise `false` to represent
87  * failure.
88  */
89 typedef bool ( * SntpResolveDns_t )( const SntpServerInfo_t * pServerAddr,
90                                      uint32_t * pIpV4Addr );
91
92 /**
93  * @ingroup sntp_callback_types
94  * @brief Interface for user-defined function to obtain the current system time
95  * in SNTP timestamp format.
96  *
97  * @note If your platform follows UNIX representation of time, the
98  * #SNTP_TIME_AT_UNIX_EPOCH_SECS and #SNTP_FRACTION_VALUE_PER_MICROSECOND macros
99  * can be used to convert UNIX time to SNTP timestamp.
100  *
101  * @param[out] pCurrentTime This should be filled with the current system time
102  * in SNTP timestamp format.
103  *
104  * @return `true` if obtaining system time is successful; otherwise `false` to
105  * represent failure.
106  */
107 typedef void ( * SntpGetTime_t )( SntpTimestamp_t * pCurrentTime );
108
109 /**
110  * @ingroup sntp_callback_types
111  * @brief Interface for user-defined function to update the system clock time
112  * so that it is synchronized the time server used for getting current time.
113  *
114  * @param[in] pTimeServer The time server used to request time.
115  * @param[in] pServerTime The current time returned by the @p pTimeServer.
116  * @param[in] clockOffsetMs The calculated clock offset (in milliseconds) of the
117  * system relative to the server time.
118  * @param[in] leapSecondInfo Information about whether there is about an upcoming
119  * leap second adjustment of insertion or deletion in the last minute before midnight
120  * on the last day of the current month. For more information on leap seconds, refer
121  * to https://www.nist.gov/pml/time-and-frequency-division/leap-seconds-faqs. Depending
122  * on the accuracy requirements of the system clock, the user can choose to account
123  * for the leap second or ignore it in their system clock update logic.
124  *
125  * @note If the @p clockOffsetMs is positive, then the system time is BEHIND the server time,
126  * and if the @p clockOffsetMs, the system time is AHEAD of the server time. To correct the
127  * system time, the user can use either of "step", "slew" OR combination of the two clock
128  * discipline methodologies depending on the application needs.
129  * If the application requires a smooth time continuum of system time, then the "slew"
130  * discipline methodology can be used with the clock offset value, @p clockOffSetMs, to correct
131  * the system clock gradually with a "slew rate".
132  * If the application can accept sudden jump in time (forward or backward), then
133  * the "step" discipline methodology can be used to directly update the system
134  * clock with the current server time, @p pServerTime, every time the coreSNTP library
135  * calls the interface.
136  */
137 typedef void ( * SntpSetTime_t )( const SntpServerInfo_t * pTimeServer,
138                                   const SntpTimestamp_t * pServerTime,
139                                   int64_t clockOffsetMs,
140                                   SntpLeapSecondInfo_t leapSecondInfo );
141
142 /**
143  * @ingroup sntp_struct_types
144  * @typedef NetworkContext_t
145  * @brief A user-defined type for context that is passed to the transport interface functions.
146  * It MUST be defined by the user to use the library.
147  * It is of incomplete type to allow user to define to the needs of their transport
148  * interface implementation.
149  */
150 struct NetworkContext;
151 typedef struct NetworkContext NetworkContext_t;
152
153 /**
154  * @ingroup sntp_callback_types
155  * @brief Interface for user-defined function to send time request as a single datagram
156  * to server on the network over User Datagram Protocol (UDP).
157  *
158  * @note It is RECOMMENDED that the send operation is non-blocking, i.e. it
159  * SHOULD immediately return when the entire UDP data cannot be sent over the
160  * network. In such a case, the coreSNTP library will re-try send operation
161  * for a maximum period of blocking time passed to the @ref Sntp_SendTimeRequest API.
162  *
163  * @note If the size of the SNTP packet exceeds the Maximum Transmission Unit (MTU)
164  * supported by the network interface of the device, the user-defined implementation
165  * MAY either support fragmentation of UDP packets OR use a size for authentication data
166  * that allows the SNTP packet to fit within the MTU required size threshold. (Note that
167  * the size of SNTP packet is #SNTP_PACKET_BASE_SIZE + authentication data.)
168  *
169  * @param[in,out] pNetworkContext The user defined NetworkContext_t which
170  * is opaque to the coreSNTP library.
171  * @param[in] serverAddr The IPv4 address of the time server to send the data to.
172  * @param[in] serverPort The port of the server to send data to.
173  * @param[in] pBuffer The buffer containing the data to send over the network.
174  * @param[in] bytesToSend The size of data in @p pBuffer to send.
175  *
176  * @return The function SHOULD return one of the following integer codes:
177  * - @p bytesToSend when all requested data is successfully transmitted over the
178  * network.
179  * - 0 when no data could be sent over the network (due to network buffer being
180  * full, for example), and the send operation can be retried.
181  * - < 0 when the send operation failed to send any data due to an internal error,
182  * and operation cannot be retried.
183  */
184 typedef int32_t ( * UdpTransportSendTo_t )( NetworkContext_t * pNetworkContext,
185                                             uint32_t serverAddr,
186                                             uint16_t serverPort,
187                                             const void * pBuffer,
188                                             uint16_t bytesToSend );
189
190 /**
191  * @ingroup sntp_callback_types
192  * @brief Interface for user-defined function to receive the server response, to a time
193  * request (sent through the @ref UdpTransportSendTo_t function), from the network over
194  * User Datagram Protocol (UDP).
195  *
196  * @note It is RECOMMENDED that the read operation is non-blocking, i.e. it
197  * SHOULD immediately return when no data is available on the network.
198  * In such a case, the coreSNTP library will re-try send operation for a maximum period
199  * of blocking time passed through the @ref Sntp_ReceiveTimeResponse API.
200  *
201  * @note If the size of the SNTP response packet from the server exceeds the
202  * Maximum Transmission Unit (MTU) supported by the network interface of the device,
203  * the user-defined implementation of the interface MAY either support receiving and
204  * assembling fragmented UDP packets OR use an authentication data size that allows
205  * SNTP packet to fit within the MTU required packet size threshold. (Note that
206  * the size of SNTP packet is #SNTP_PACKET_BASE_SIZE + authentication data.)
207  *
208  * @param[in,out] pNetworkContext The user defined NetworkContext_t which
209  * is opaque to the coreSNTP library.
210  * @param[in] serverAddr The IPv4 address of the time server to receive data from.
211  * @param[in] serverPort The port of the server to receive data from.
212  * @param[out] pBuffer This SHOULD be filled with data received from the network.
213  * @param[in] bytesToRecv The expected number of bytes to receive from the
214  * server.
215  *
216  * @return The function SHOULD return one of the following integer codes:
217  * - @p bytesToRecv value if all the requested number of bytes are received
218  * from the network.
219  * - ZERO when no data is available on the network, and the operation can be
220  * retried.
221  * - < 0 when the read operation failed due to internal error, and operation cannot
222  * be retried.
223  */
224 typedef int32_t ( * UdpTransportRecvFrom_t )( NetworkContext_t * pNetworkContext,
225                                               uint32_t serverAddr,
226                                               uint16_t serverPort,
227                                               void * pBuffer,
228                                               uint16_t bytesToRecv );
229
230 /**
231  * @ingroup sntp_struct_types
232  * @brief Struct representing the UDP transport interface for user-defined functions
233  * that coreSNTP library depends on for performing read/write network operations.
234  */
235 typedef struct UdpTransportIntf
236 {
237     NetworkContext_t * pUserContext; /**<@brief The user-defined context for storing
238                                       * network socket information. */
239     UdpTransportSendTo_t sendTo;     /**<@brief The user-defined UDP send function. */
240     UdpTransportRecvFrom_t recvFrom; /**<@brief The user-defined UDP receive function. */
241 } UdpTransportInterface_t;
242
243 /**
244  * @ingroup sntp_struct_types
245  * @typedef SntpAuthContext_t
246  * @brief A user-defined type for context that is passed to the authentication interface functions.
247  * It MUST be defined by the user to use the library.
248  * It is of incomplete type to allow user to defined to the the needs of their authentication
249  * interface implementation.
250  */
251 struct SntpAuthContext;
252 typedef struct SntpAuthContext SntpAuthContext_t;
253
254 /**
255  * @ingroup sntp_callback_types
256  * @brief Interface for user-defined function to generate and append
257  * authentication code in an SNTP request buffer for the SNTP client to be
258  * authenticated by the time server, if a security mechanism is used.
259  *
260  * The user can choose to implement with any security mechanism, symmetric
261  * key-based (like AES-CMAC) or asymmetric key-based (like Network Time Security),
262  * depending on the security mechanism supported by the time server being used
263  * to synchronize time with.
264  *
265  * @note The function SHOULD generate the authentication data for the first
266  * #SNTP_PACKET_BASE_SIZE bytes of SNTP request packet present in the passed buffer
267  * @p pBuffer, and fill the generated authentication data after #SNTP_PACKET_BASE_SIZE
268  * bytes in the buffer.
269  *
270  * @param[in,out] pContext The user defined NetworkContext_t which
271  * is opaque to the coreSNTP library.
272  * @param[in] pTimeServer The time server being used to request time from.
273  * This parameter is useful to choose the security mechanism when multiple time
274  * servers are configured in the library, and they require different security
275  * mechanisms or authentication credentials to use.
276  * @param[in, out] pBuffer This buffer SHOULD be filled with the authentication
277  * code generated from the #SNTP_PACKET_BASE_SIZE bytes of SNTP request data
278  * present in it.
279  * @param[in] bufferSize The maximum amount of data that can be held by the buffer,
280  * @p pBuffer.
281  * @param[out] pAuthCodeSize This should be filled with size of the authentication
282  * data appended to the SNTP request buffer, @p pBuffer. This value plus
283  * #SNTP_PACKET_BASE_SIZE should not exceed the buffer size, @p bufferSize.
284  *
285  * @return The function SHOULD return one of the following integer codes:
286  * - #SntpSuccess when the authentication data is successfully appended to @p pBuffer.
287  * - #SntpErrorBufferTooSmall when the user-supplied buffer (to the SntpContext_t through
288  * @ref Sntp_Init) is not large enough to hold authentication data.
289  * - #SntpErrorAuthFailure for failure to generate authentication data due to internal
290  * error.
291  */
292 typedef SntpStatus_t (* SntpGenerateAuthCode_t )( SntpAuthContext_t * pContext,
293                                                   const SntpServerInfo_t * pTimeServer,
294                                                   void * pBuffer,
295                                                   size_t bufferSize,
296                                                   uint16_t * pAuthCodeSize );
297
298 /**
299  * @ingroup sntp_callback_types
300  * @brief Interface for user-defined function to authenticate server by validating
301  * the authentication code present in its SNTP response to a time request, if
302  * a security mechanism is supported by the server.
303  *
304  * The user can choose to implement with any security mechanism, symmetric
305  * key-based (like AES-CMAC) or asymmetric key-based (like Network Time Security),
306  * depending on the security mechanism supported by the time server being used
307  * to synchronize time with.
308  *
309  * @note In an SNTP response, the authentication code is present only after the
310  * first #SNTP_PACKET_BASE_SIZE bytes. Depending on the security mechanism used,
311  * the first #SNTP_PACKET_BASE_SIZE bytes MAY be used in validating the
312  * authentication data sent by the server.
313  *
314  * @param[in,out] pContext The user defined NetworkContext_t which
315  * is opaque to the coreSNTP library.
316  * @param[in] pTimeServer The time server that has to be authenticated from its
317  * SNTP response.
318  * This parameter is useful to choose the security mechanism when multiple time
319  * servers are configured in the library, and they require different security
320  * mechanisms or authentication credentials to use.
321  * @param[in] pResponseData The SNTP response from the server that contains the
322  * authentication code after the first #SNTP_PACKET_BASE_SIZE bytes.
323  * @param[in] responseSize The total size of the response from the server.
324  *
325  * @return The function SHOULD return one of the following integer codes:
326  * - #SntpSuccess when the server is successfully authenticated.
327  * - #SntpServerNotAuthenticated when server could not be authenticated.
328  * - #SntpErrorAuthFailure for failure to authenticate server due to internal
329  * error.
330  */
331 typedef SntpStatus_t (* SntpValidateServerAuth_t )( SntpAuthContext_t * pContext,
332                                                     const SntpServerInfo_t * pTimeServer,
333                                                     const void * pResponseData,
334                                                     uint16_t responseSize );
335
336 /**
337  * @ingroup sntp_struct_types
338  * @brief Struct representing the authentication interface for securely
339  * communicating with time servers.
340  *
341  * @note Using a security mechanism is OPTIONAL for using the coreSNTP
342  * library i.e. a user does not need to define the authentication interface
343  * if they are not using a security mechanism for SNTP communication.
344  */
345 typedef struct SntpAuthenticationIntf
346 {
347     /**
348      *@brief The user-defined context for storing information like
349      * key credentials required for cryptographic operations in the
350      * security mechanism used for communicating with server.
351      */
352     SntpAuthContext_t * pAuthContext;
353
354     /**
355      * @brief The user-defined function for appending client authentication data.
356      * */
357     SntpGenerateAuthCode_t generateClientAuth;
358
359     /**
360      * @brief The user-defined function for authenticating server from its SNTP
361      * response.
362      */
363     SntpValidateServerAuth_t validateServerAuth;
364 } SntpAuthenticationInterface_t;
365
366 /**
367  * @ingroup sntp_struct_types
368  * @brief Structure for a context that stores state for managing a long-running
369  * SNTP client that periodically polls time and synchronizes system clock.
370  */
371 typedef struct SntpContext
372 {
373     /**
374      * @brief List of time servers in decreasing priority order configured
375      * for the SNTP client.
376      * Only a single server is configured for use at a time across polling
377      * attempts until the server rejects a time request or there is a response
378      * timeout, after which, the next server in the list is used for subsequent
379      * polling requests.
380      */
381     const SntpServerInfo_t * pTimeServers;
382
383     /**
384      * @brief Number of servers configured for use.
385      */
386     size_t numOfServers;
387
388     /**
389      * @brief The index for the currently configured time server for time querying
390      * from the list of time servers in @ref pTimeServers.
391      */
392     size_t currentServerIndex;
393
394     /**
395      * @brief The user-supplied buffer for storing network data of both SNTP requests
396      * and SNTP response.
397      */
398     uint8_t * pNetworkBuffer;
399
400     /**
401      * @brief The size of the network buffer.
402      */
403     size_t bufferSize;
404
405     /**
406      * @brief The user-supplied function for resolving DNS name of time servers.
407      */
408     SntpResolveDns_t resolveDnsFunc;
409
410     /**
411      * @brief The user-supplied function for obtaining the current system time.
412      */
413     SntpGetTime_t getTimeFunc;
414
415     /**
416      * @brief The user-supplied function for correcting system time after receiving
417      * time from a server.
418      */
419     SntpSetTime_t setTimeFunc;
420
421     /**
422      * @brief The user-defined interface for performing User Datagram Protocol (UDP)
423      * send and receive network operations.
424      */
425     UdpTransportInterface_t networkIntf;
426
427     /**
428      * @brief The user-defined interface for incorporating security mechanism of
429      * adding client authentication in SNTP request as well as authenticating server
430      * from SNTP response.
431      *
432      * @note If the application will not use security mechanism for any of the
433      * configured servers, then this interface can be undefined.
434      */
435     SntpAuthenticationInterface_t authIntf;
436
437     /**
438      * @brief Cache of the resolved Ipv4 address of the current server being used for
439      * time synchronization.
440      * As a Best Practice functionality, the client library attempts to resolve the
441      * DNS of the time-server every time the @ref Sntp_SendTimeRequest API is called.
442      */
443     uint32_t currentServerAddr;
444
445     /**
446      * @brief Cache of the timestamp of sending the last time request to a server
447      * for replay attack protection by checking that the server response contains
448      * the same timestamp in its "originate timestamp" field.
449      */
450     SntpTimestamp_t lastRequestTime;
451
452     /**
453      * @brief State member for storing the size of the SNTP packet that includes
454      * both #SNTP_PACKET_BASE_SIZE bytes plus any authentication data, if a security
455      * mechanism is used.
456      * This value is used for expecting the same size for an SNTP response
457      * from the server.
458      */
459     uint16_t sntpPacketSize;
460
461     /**
462      * @brief The timeout duration (in milliseconds) for receiving a response, through
463      * @ref Sntp_ReceiveTimeResponse API, from a server after the request for time is
464      * sent to it through @ref Sntp_SendTimeRequest API.
465      */
466     uint32_t responseTimeoutMs;
467 } SntpContext_t;
468
469 /**
470  * @brief Initializes a context for SNTP client communication with SNTP/NTP
471  * servers.
472  *
473  * @param[out] pContext The user-supplied memory for the context that will be
474  * initialized to represent an SNTP client.
475  * @param[in] pTimeServers The list of decreasing order of priority of time
476  * servers that should be used by the SNTP client. This list MUST stay in
477  * scope for all the time of use of the context.
478  * @param[in] numOfServers The number of servers in the list, @p pTimeServers.
479  * @param[in] serverResponseTimeoutMs The timeout duration (in milliseconds) for
480  * receiving server response for time requests. The same timeout value is used for
481  * each server in the @p pTimeServers list.
482  * @param[in] pNetworkBuffer The user-supplied memory that will be used for
483  * storing network data for SNTP client-server communication. The buffer
484  * MUST stay in scope for all the time of use of the context.
485  * @param[in] bufferSize The size of the passed buffer @p pNetworkBuffer. The buffer
486  * SHOULD be appropriately sized for storing an entire SNTP packet which includes
487  * both #SNTP_PACKET_BASE_SIZE bytes of standard SNTP packet size, and space for
488  * authentication data, if security mechanism is used to communicate with any of
489  * the time servers configured for use.
490  * @param[in] resolveDnsFunc The user-defined function for DNS resolution of time
491  * server.
492  * @param[in] getSystemTimeFunc The user-defined function for querying system
493  * time.
494  * @param[in] setSystemTimeFunc The user-defined function for correcting system
495  * time for every successful time response received from a server.
496  * @param[in] pTransportIntf The user-defined function for performing network
497  * send/recv operations over UDP.
498  * @param[in] pAuthIntf The user-defined interface for generating client authentication
499  * in SNTP requests and authenticating servers in SNTP responses, if security mechanism
500  * is used in SNTP communication with server(s). If security mechanism is not used in
501  * communication with any of the configured servers (in @p pTimeServers), then the
502  * @ref SntpAuthenticationInterface_t does not need to be defined and this parameter
503  * can be NULL.
504  *
505  * @return This function returns one of the following:
506  * - #SntpSuccess if the context is initialized.
507  * - #SntpErrorBadParameter if any of the passed parameters in invalid.
508  * - #SntpErrorBufferTooSmall if the buffer does not have the minimum size
509  * required for a valid SNTP response packet.
510  */
511 /* @[define_sntp_init] */
512 SntpStatus_t Sntp_Init( SntpContext_t * pContext,
513                         const SntpServerInfo_t * pTimeServers,
514                         size_t numOfServers,
515                         uint32_t serverResponseTimeoutMs,
516                         uint8_t * pNetworkBuffer,
517                         size_t bufferSize,
518                         SntpResolveDns_t resolveDnsFunc,
519                         SntpGetTime_t getSystemTimeFunc,
520                         SntpSetTime_t setSystemTimeFunc,
521                         const UdpTransportInterface_t * pTransportIntf,
522                         const SntpAuthenticationInterface_t * pAuthIntf );
523 /* @[define_sntp_init] */
524
525
526 /**
527  * @brief Sends a request for time from the currently configured server (in the
528  * context).
529  * If the user has provided an authentication interface, the client
530  * authentication code is appended to the request before sending over the network
531  * by calling the @ref SntpGenerateAuthCode_t function of the
532  * @ref SntpAuthenticationInterface_t.
533  *
534  * @note This function will ONLY send a request if there is a server available
535  * in the configured list that has not rejected an earlier request for time.
536  * This adheres to the Best Practice functionality specified in [Section 10 Point 8
537  * of SNTPv4 specification](https://tools.ietf.org/html/rfc4330#section-10).
538  *
539  * @param[in] pContext The context representing an SNTPv4 client.
540  * @param[in] randomNumber A random number serializing the SNTP request packet
541  * to protect against spoofing attacks by attackers that are off the network path
542  * of the SNTP client-server communication. This mechanism is suggested by SNTPv4
543  * specification in [RFC 4330 Section 3](https://tools.ietf.org/html/rfc4330#section-3).
544  * @param[in] blockTimeMs The maximum duration of time (in milliseconds) the function will
545  * block on attempting to send time request to the server over the network. If a zero
546  * block time value is provided, then the function will attempt to send the packet ONLY
547  * once.
548  *
549  * @note It is RECOMMENDED that a True Random Number Generator is used to generate the
550  * random number by using a hardware module, like Hardware Security Module (HSM), Secure Element,
551  * etc, as the entropy source.
552  *
553  * @return The API function returns one of the following:
554  *  - #SntpSuccess if a time request is successfully sent to the currently configured
555  * time server in the context.
556  *  - #SntpErrorBadParameter if an invalid context is passed to the function.
557  *  - #SntpErrorContextNotInitialized if an uninitialized or invalid context is passed
558  * to the function.
559  *  - #SntpErrorDnsFailure if there is failure in the user-defined function for
560  * DNS resolution of the time server.
561  *  - #SntpErrorNetworkFailure if the SNTP request could not be sent over the network
562  * through the user-defined transport interface.
563  *  - #SntpErrorAuthFailure if there was a failure in generating the client
564  * authentication code in the user-defined authentication interface.
565  *  - #SntpErrorSendTimeout if the time request packet could not be sent over the
566  * network for the entire @p blockTimeMs duration.
567  */
568 /* @[define_sntp_sendtimerequest] */
569 SntpStatus_t Sntp_SendTimeRequest( SntpContext_t * pContext,
570                                    uint32_t randomNumber,
571                                    uint32_t blockTimeMs );
572 /* @[define_sntp_sendtimerequest] */
573
574
575 /**
576  * @brief Receives a time response from the server that has been requested for time with
577  * the @ref Sntp_SendTimeRequest API function.
578  * Once an accepted response containing time from server is received, this function calls
579  * the user-defined @ref SntpSetTime_t function to update the system time.
580  *
581  * @note If the user has provided an authentication interface to the client
582  * (through @ref Sntp_Init), the server response is authenticated by calling the
583  * @ref SntpValidateServerAuth_t function of the @ref SntpAuthenticationInterface_t interface.
584  *
585  * @note On receiving a successful server response containing server time,
586  * this API calculates the clock offset value of the system clock relative to the
587  * server before calling the user-defined @ref SntpSetTime_t function for updating
588  * the system time.
589  *
590  * @note For correct calculation of clock-offset, the server and client times MUST be within
591  * ~68 years (or 2^31 seconds) of each other. In the special case when the server and client
592  * times are exactly 2^31 seconds apart, the library ASSUMES that the server time is ahead
593  * of the client time, and returns the positive clock-offset value of INT32_MAX seconds.
594  *
595  * @note This API will rotate the server of use in the library for the next time request
596  * (through the @ref Sntp_SendTimeRequest) if either of following events occur:
597  *  - The server has responded with a rejection for the time request.
598  *                         OR
599  *  - The server response wait has timed out.
600  * If all the servers configured in the context have been used, the API will rotate server for
601  * time query back to the first server in the list which will be used in next time request.
602  *
603  * @param[in] pContext The context representing an SNTPv4 client.
604  * @param[in] blockTimeMs The maximum duration of time (in milliseconds) the function will
605  * block on receiving a response from the server unless either the response is received
606  * OR a response timeout occurs.
607  *
608  * @note This function can be called multiple times with zero or small blocking times
609  * to poll whether server response is received until either the response response is
610  * received from the server OR a response timeout has occurred.
611  *
612  * @return This API functions returns one of the following:
613  *  - #SntpSuccess if a successful server response is received.
614  *  - #SntpErrorContextNotInitialized if an uninitialized or invalid context is passed
615  * to the function.
616  *  - #SntpErrorBadParameter if an invalid context is passed to the function.
617  *  - #SntpErrorNetworkFailure if there is a failure in the user-defined transport
618  *  - #SntpErrorAuthFailure if an internal error occurs in the user-defined
619  * authentication interface when validating the server response.
620  *  - #SntpServerNotAuthenticated when the server could not be authenticated from
621  * its response with the user-defined authentication interface.
622  *  - #SntpInvalidResponse if the server response fails sanity checks expected in an
623  * SNTP response packet.
624  *  - #SntpErrorResponseTimeout if a timeout has occurred in receiving response from
625  * the server.
626  *  - #SntpRejectedResponse if the server responded with a rejection for the time
627  * request.
628  */
629 /* @[define_sntp_receivetimeresponse] */
630 SntpStatus_t Sntp_ReceiveTimeResponse( SntpContext_t * pContext,
631                                        uint32_t blockTimeMs );
632 /* @[define_sntp_receivetimeresponse] */
633
634 /**
635  * @brief Converts @ref SntpStatus_t to its equivalent
636  * string.
637  *
638  * @note The returned string MUST NOT be modified.
639  *
640  * @param[in] status The status to convert to a string.
641  *
642  * @return The string representation of the status
643  * code.
644  */
645 /* @[define_sntp_statustostr] */
646 const char * Sntp_StatusToStr( SntpStatus_t status );
647 /* @[define_sntp_statustostr] */
648
649 /* *INDENT-OFF* */
650 #ifdef __cplusplus
651     }
652 #endif
653 /* *INDENT-ON* */
654
655 #endif /* ifndef CORE_SNTP_CLIENT_H_ */