From: Alok Barsode Date: Fri, 3 Feb 2012 18:25:59 +0000 (+0200) Subject: ntp: NTP Query a Timeserver server IP X-Git-Tag: 2.0_alpha~628 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1db29a8c79e10f801d8d9ce0c861bf8b0a972f4d;p=framework%2Fconnectivity%2Fconnman.git ntp: NTP Query a Timeserver server IP __connman_ntp_start() takes a NTP server IP, and starts querying it for time correction.If a timeserver responds, we continue to query it every "Poll Interval" seconds for time corrections. __connman_ntp_stop() stops the polling process. --- diff --git a/src/connman.h b/src/connman.h index f55bcbd..5c63503 100644 --- a/src/connman.h +++ b/src/connman.h @@ -356,9 +356,8 @@ gboolean __connman_connection_update_gateway(void); void __connman_connection_gateway_activate(struct connman_service *service, enum connman_ipconfig_type type); -int __connman_ntp_start(const char *interface, const char *resolver, - const char *server); -void __connman_ntp_stop(const char *interface); +int __connman_ntp_start(char *server); +void __connman_ntp_stop(); int __connman_wpad_init(void); void __connman_wpad_cleanup(void); diff --git a/src/ntp.c b/src/ntp.c index fa4f624..f70dfc7 100644 --- a/src/ntp.c +++ b/src/ntp.c @@ -37,8 +37,6 @@ #include -#include - #include "connman.h" struct ntp_short { @@ -71,10 +69,12 @@ struct ntp_msg { #define LOGTOD(a) ((a) < 0 ? 1. / (1L << -(a)) : 1L << (int)(a)) +static guint channel_watch = 0; static struct timeval transmit_timeval; -static char *transmit_server; -static int transmit_fd; -static guint transmit_delay = 16; +static int transmit_fd = 0; + +static char *timeserver = NULL; +static gint poll_id = 0; static void send_packet(int fd, const char *server) { @@ -109,11 +109,12 @@ static void send_packet(int fd, const char *server) } } -static gboolean next_request(gpointer user_data) +static gboolean next_poll(gpointer user_data) { - DBG("server %s", transmit_server); + if (timeserver == NULL || transmit_fd == 0) + return FALSE; - send_packet(transmit_fd, transmit_server); + send_packet(transmit_fd, timeserver); return FALSE; } @@ -123,6 +124,7 @@ static void decode_msg(void *base, size_t len, struct timeval *tv) struct ntp_msg *msg = base; double org, rec, xmt, dst; double delay, offset; + static guint transmit_delay; if (len < sizeof(*msg)) { connman_error("Invalid response from time server"); @@ -166,6 +168,17 @@ static void decode_msg(void *base, size_t len, struct timeval *tv) DBG("offset=%f delay=%f", offset, delay); + /* Timeserver has responded. + * Now poll the server every transmit_delay seconds + * for time correction. + */ + if (poll_id > 0) + g_source_remove(poll_id); + + DBG("Timeserver %s, next sync in %d seconds", timeserver, transmit_delay); + + poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL); + if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) { struct timeval adj; @@ -200,8 +213,6 @@ static void decode_msg(void *base, size_t len, struct timeval *tv) } } -static guint channel_watch = 0; - static gboolean received_data(GIOChannel *channel, GIOCondition condition, gpointer user_data) { @@ -250,24 +261,25 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, decode_msg(iov.iov_base, iov.iov_len, tv); - g_timeout_add_seconds(transmit_delay, next_request, NULL); - return TRUE; } -static void start_ntp(const char *server) +static void start_ntp(char *server) { GIOChannel *channel; struct sockaddr_in addr; - int fd, tos = IPTOS_LOWDELAY, timestamp = 1; + int tos = IPTOS_LOWDELAY, timestamp = 1; + + if (server == NULL) + return; DBG("server %s", server); if (channel_watch > 0) - return; + goto send; - fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) { + transmit_fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (transmit_fd < 0) { connman_error("Failed to open time server socket"); return; } @@ -275,28 +287,28 @@ static void start_ntp(const char *server) memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + if (bind(transmit_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { connman_error("Failed to bind time server socket"); - close(fd); + close(transmit_fd); return; } - if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { + if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { connman_error("Failed to set type of service option"); - close(fd); + close(transmit_fd); return; } - if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, ×tamp, + if (setsockopt(transmit_fd, SOL_SOCKET, SO_TIMESTAMP, ×tamp, sizeof(timestamp)) < 0) { connman_error("Failed to enable timestamp support"); - close(fd); + close(transmit_fd); return; } - channel = g_io_channel_unix_new(fd); + channel = g_io_channel_unix_new(transmit_fd); if (channel == NULL) { - close(fd); + close(transmit_fd); return; } @@ -311,72 +323,42 @@ static void start_ntp(const char *server) g_io_channel_unref(channel); - transmit_fd = fd; - transmit_server = g_strdup(server); - - send_packet(fd, server); +send: + send_packet(transmit_fd, server); } -static void resolv_debug(const char *str, void *data) +int __connman_ntp_start(char *server) { - connman_info("%s: %s\n", (const char *) data, str); -} + DBG(""); -static GResolv *resolv = NULL; -static guint resolv_lookup = 0; + if (server == NULL) + return -EINVAL; -static void resolv_result(GResolvResultStatus status, - char **results, gpointer user_data) -{ - int i; - - resolv_lookup = 0; - - if (results != NULL) { - for (i = 0; results[i]; i++) - DBG("result: %s", results[i]); - - if (results[0] != NULL) - start_ntp(results[0]); - } -} - -int __connman_ntp_start(const char *interface, const char *resolver, - const char *server) -{ - DBG("interface %s server %s", interface, server); - - resolv = g_resolv_new(0); - if (resolv == NULL) - return -ENOMEM; + if (timeserver != NULL) + g_free(timeserver); - if (getenv("CONNMAN_RESOLV_DEBUG")) - g_resolv_set_debug(resolv, resolv_debug, "RESOLV"); + timeserver = g_strdup(server); - if (resolver != NULL) - g_resolv_add_nameserver(resolv, resolver, 53, 0); - - g_resolv_lookup_hostname(resolv, server, resolv_result, NULL); + start_ntp(timeserver); return 0; } -void __connman_ntp_stop(const char *interface) +void __connman_ntp_stop() { - DBG("interface %s", interface); + DBG(""); - if (resolv == NULL) - return; - - if (resolv_lookup > 0) { - g_resolv_cancel_lookup(resolv, resolv_lookup); - resolv_lookup = 0; - } + if (poll_id > 0) + g_source_remove(poll_id); if (channel_watch > 0) { g_source_remove(channel_watch); channel_watch = 0; + transmit_fd = 0; } - g_resolv_unref(resolv); + if (timeserver != NULL) { + g_free(timeserver); + timeserver = NULL; + } }