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 #include <zephyr/net/socket_service.h> 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 /** 24 * @brief Simple Network Time Protocol API 25 * @defgroup sntp SNTP 26 * @since 1.10 27 * @version 0.8.0 28 * @ingroup networking 29 * @{ 30 */ 31 32 /** Time as returned by SNTP API, fractional seconds since 1 Jan 1970 */ 33 struct sntp_time { 34 uint64_t seconds; /**< Second value */ 35 uint32_t fraction; /**< Fractional seconds value */ 36 #if defined(CONFIG_SNTP_UNCERTAINTY) 37 uint64_t uptime_us; /**< Uptime in microseconds */ 38 uint32_t uncertainty_us; /**< Uncertainty in microseconds */ 39 #endif 40 }; 41 42 /** SNTP context */ 43 struct sntp_ctx { 44 45 /** @cond INTERNAL_HIDDEN */ 46 struct { 47 struct zsock_pollfd fds[1]; 48 int nfds; 49 int fd; 50 } sock; 51 /** @endcond */ 52 53 /** Timestamp when the request was sent from client to server. 54 * This is used to check if the originated timestamp in the server 55 * reply matches the one in client request. 56 */ 57 struct sntp_time expected_orig_ts; 58 }; 59 60 /** 61 * @brief Initialize SNTP context 62 * 63 * @param ctx Address of sntp context. 64 * @param addr IP address of NTP/SNTP server. 65 * @param addr_len IP address length of NTP/SNTP server. 66 * 67 * @return 0 if ok, <0 if error. 68 */ 69 int sntp_init(struct sntp_ctx *ctx, struct sockaddr *addr, 70 socklen_t addr_len); 71 72 /** 73 * @brief Perform SNTP query 74 * 75 * @param ctx Address of sntp context. 76 * @param timeout Timeout of waiting for sntp response (in milliseconds). 77 * @param ts Timestamp including integer and fractional seconds since 78 * 1 Jan 1970 (output). 79 * 80 * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout). 81 */ 82 int sntp_query(struct sntp_ctx *ctx, uint32_t timeout, struct sntp_time *ts); 83 84 /** 85 * @brief Attempt to receive an SNTP response after issuing a query 86 * 87 * @param ctx Address of sntp context. 88 * @param timeout Timeout of waiting for sntp response (in milliseconds). 89 * @param ts Timestamp including integer and fractional seconds since 90 * 1 Jan 1970 (output). 91 * 92 * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout). 93 */ 94 int sntp_recv_response(struct sntp_ctx *ctx, uint32_t timeout, struct sntp_time *ts); 95 96 /** 97 * @brief Release SNTP context 98 * 99 * @param ctx Address of sntp context. 100 */ 101 void sntp_close(struct sntp_ctx *ctx); 102 103 /** 104 * @brief Initialise SNTP context for async operation 105 * 106 * Asynchronous operation is powered by @kconfig{CONFIG_NET_SOCKETS_SERVICE}. 107 * 108 * @param ctx Address of sntp context. 109 * @param addr IP address of NTP/SNTP server. 110 * @param addr_len IP address length of NTP/SNTP server. 111 * @param service Socket service defined by @ref NET_SOCKET_SERVICE_SYNC_DEFINE 112 * 113 * @return 0 if ok, <0 if error. 114 */ 115 int sntp_init_async(struct sntp_ctx *ctx, struct sockaddr *addr, socklen_t addr_len, 116 const struct net_socket_service_desc *service); 117 118 /** 119 * @brief Send the SNTP query 120 * 121 * @param ctx Address of sntp context. 122 * 123 * @return 0 if ok, <0 if error. 124 */ 125 int sntp_send_async(struct sntp_ctx *ctx); 126 127 /** 128 * @brief Read the result of the SNTP query 129 * 130 * Must be called from the callback attached to the @ref net_socket_service_desc 131 * context. 132 * 133 * @param event Event pointer extracted from the service work callback 134 * @param ts Timestamp including integer and fractional seconds since 135 * 1 Jan 1970 (output). 136 * 137 * @return 0 if ok, <0 if error 138 */ 139 int sntp_read_async(struct net_socket_service_event *event, struct sntp_time *ts); 140 141 /** 142 * @brief Release SNTP context 143 * 144 * @param service Socket service defined by @ref NET_SOCKET_SERVICE_SYNC_DEFINE 145 */ 146 void sntp_close_async(const struct net_socket_service_desc *service); 147 148 /** 149 * @brief Convenience function to query SNTP in one-shot fashion 150 * 151 * Convenience wrapper which calls getaddrinfo(), sntp_init(), 152 * sntp_query(), and sntp_close(). 153 * 154 * @param server Address of server in format addr[:port] 155 * @param timeout Query timeout 156 * @param ts Timestamp including integer and fractional seconds since 157 * 1 Jan 1970 (output). 158 * 159 * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout). 160 */ 161 int sntp_simple(const char *server, uint32_t timeout, 162 struct sntp_time *ts); 163 164 /** 165 * @brief Convenience function to query SNTP in one-shot fashion 166 * using a pre-initialized address struct 167 * 168 * Convenience wrapper which calls sntp_init(), sntp_query() and 169 * sntp_close(). 170 * 171 * @param addr IP address of NTP/SNTP server. 172 * @param addr_len IP address length of NTP/SNTP server. 173 * @param timeout Query timeout 174 * @param ts Timestamp including integer and fractional seconds since 175 * 1 Jan 1970 (output). 176 * 177 * @return 0 if ok, <0 if error (-ETIMEDOUT if timeout). 178 */ 179 int sntp_simple_addr(struct sockaddr *addr, socklen_t addr_len, uint32_t timeout, 180 struct sntp_time *ts); 181 182 #ifdef __cplusplus 183 } 184 #endif 185 186 /** 187 * @} 188 */ 189 190 #endif 191