1 /*
2  * Copyright (c) 2017 Linaro Limited
3  * Copyright (c) 2019 Intel Corporation
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief SNTP (Simple Network Time Protocol)
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_NET_SNTP_H_
14 #define ZEPHYR_INCLUDE_NET_SNTP_H_
15 
16 #include <zephyr/net/socket.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /**
23  * @brief Simple Network Time Protocol API
24  * @defgroup sntp SNTP
25  * @since 1.10
26  * @version 0.8.0
27  * @ingroup networking
28  * @{
29  */
30 
31 /** Time as returned by SNTP API, fractional seconds since 1 Jan 1970 */
32 struct sntp_time {
33 	uint64_t seconds;        /**< Second value */
34 	uint32_t fraction;       /**< Fractional seconds value */
35 #if defined(CONFIG_SNTP_UNCERTAINTY)
36 	uint64_t uptime_us;      /**< Uptime in microseconds */
37 	uint32_t uncertainty_us; /**< Uncertainty in microseconds */
38 #endif
39 };
40 
41 /** SNTP context */
42 struct sntp_ctx {
43 
44 /** @cond INTERNAL_HIDDEN */
45 	struct {
46 		struct zsock_pollfd fds[1];
47 		int nfds;
48 		int fd;
49 	} sock;
50 /** @endcond */
51 
52 	/** Timestamp when the request was sent from client to server.
53 	 *  This is used to check if the originated timestamp in the server
54 	 *  reply matches the one in client request.
55 	 */
56 	struct sntp_time expected_orig_ts;
57 };
58 
59 /**
60  * @brief Initialize SNTP context
61  *
62  * @param ctx Address of sntp context.
63  * @param addr IP address of NTP/SNTP server.
64  * @param addr_len IP address length of NTP/SNTP server.
65  *
66  * @return 0 if ok, <0 if error.
67  */
68 int sntp_init(struct sntp_ctx *ctx, struct sockaddr *addr,
69 	      socklen_t addr_len);
70 
71 /**
72  * @brief Perform SNTP query
73  *
74  * @param ctx Address of sntp context.
75  * @param timeout Timeout of waiting for sntp response (in milliseconds).
76  * @param ts Timestamp including integer and fractional seconds since
77  * 1 Jan 1970 (output).
78  *
79  * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout).
80  */
81 int sntp_query(struct sntp_ctx *ctx, uint32_t timeout, struct sntp_time *ts);
82 
83 /**
84  * @brief Attempt to receive an SNTP response after issuing a query
85  *
86  * @param ctx Address of sntp context.
87  * @param timeout Timeout of waiting for sntp response (in milliseconds).
88  * @param ts Timestamp including integer and fractional seconds since
89  * 1 Jan 1970 (output).
90  *
91  * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout).
92  */
93 int sntp_recv_response(struct sntp_ctx *ctx, uint32_t timeout, struct sntp_time *ts);
94 
95 /**
96  * @brief Release SNTP context
97  *
98  * @param ctx Address of sntp context.
99  */
100 void sntp_close(struct sntp_ctx *ctx);
101 
102 /**
103  * @brief Convenience function to query SNTP in one-shot fashion
104  *
105  * Convenience wrapper which calls getaddrinfo(), sntp_init(),
106  * sntp_query(), and sntp_close().
107  *
108  * @param server Address of server in format addr[:port]
109  * @param timeout Query timeout
110  * @param ts Timestamp including integer and fractional seconds since
111  * 1 Jan 1970 (output).
112  *
113  * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout).
114  */
115 int sntp_simple(const char *server, uint32_t timeout,
116 		struct sntp_time *ts);
117 
118 /**
119  * @brief Convenience function to query SNTP in one-shot fashion
120  * using a pre-initialized address struct
121  *
122  * Convenience wrapper which calls sntp_init(), sntp_query() and
123  * sntp_close().
124  *
125  * @param addr IP address of NTP/SNTP server.
126  * @param addr_len IP address length of NTP/SNTP server.
127  * @param timeout Query timeout
128  * @param ts Timestamp including integer and fractional seconds since
129  * 1 Jan 1970 (output).
130  *
131  * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout).
132  */
133 int sntp_simple_addr(struct sockaddr *addr, socklen_t addr_len, uint32_t timeout,
134 		     struct sntp_time *ts);
135 
136 #ifdef __cplusplus
137 }
138 #endif
139 
140 /**
141  * @}
142  */
143 
144 #endif
145