From: Alok Barsode <[email protected]>
__connman_timerserver_sync() resolves system timeservers one at a time
and queries the resolved server or the 1st of the resolved servers for
time correction. If the resolution fails it resolves the next one.
__connman_timerserver_sync_next() resolves the next system timeserver.
__connman_timerserver_stop() stops this query.If the user modifies the
system timeserver list, we restart the ntp process.
---
include/timeserver.h | 1 -
src/connman.h | 4 ++
src/ntp.c | 2 +-
src/service.c | 7 ++-
src/timeserver.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++---
5 files changed, 142 insertions(+), 14 deletions(-)
diff --git a/include/timeserver.h b/include/timeserver.h
index 3749482..e37fada 100644
--- a/include/timeserver.h
+++ b/include/timeserver.h
@@ -38,7 +38,6 @@ extern "C" {
int connman_timeserver_append(const char *server);
int connman_timeserver_remove(const char *server);
-void connman_timeserver_sync(void);
int __connman_timeserver_system_append(const char *server);
int __connman_timeserver_system_remove(const char *server);
diff --git a/src/connman.h b/src/connman.h
index bd2b72f..52ba476 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -321,6 +321,10 @@ void __connman_timeserver_cleanup(void);
char **__connman_timeserver_system_get();
+int __connman_timeserver_sync(struct connman_service *service);
+void __connman_timeserver_sync_next();
+void __connman_timeserver_stop();
+
typedef void (* dhcp_cb) (struct connman_network *network,
connman_bool_t success);
int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback);
diff --git a/src/ntp.c b/src/ntp.c
index f70dfc7..4d3cd88 100644
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -329,7 +329,7 @@ send:
int __connman_ntp_start(char *server)
{
- DBG("");
+ DBG("%s", server);
if (server == NULL)
return -EINVAL;
diff --git a/src/service.c b/src/service.c
index 42117a3..2fe93fc 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3992,9 +3992,8 @@ static int service_indicate_state(struct connman_service
*service)
}
}
- if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
- connman_timeserver_sync();
- }
+ if (new_state == CONNMAN_SERVICE_STATE_ONLINE)
+ __connman_timeserver_sync(service);
if (new_state == CONNMAN_SERVICE_STATE_IDLE) {
connman_bool_t reconnect;
@@ -4065,6 +4064,8 @@ static int service_indicate_state(struct connman_service
*service)
dns_changed(service);
domain_changed(service);
+ __connman_timeserver_stop();
+
__connman_notifier_disconnect(service->type);
/*
diff --git a/src/timeserver.c b/src/timeserver.c
index 3bdc74f..2af173d 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -26,12 +26,24 @@
#include <errno.h>
#include <glib.h>
+#include <stdlib.h>
+#include <gweb/gresolv.h>
#include "connman.h"
static GSList *driver_list = NULL;
static GHashTable *server_hash = NULL;
+static char **system_timeservers = NULL;
+
+static GResolv *resolv = NULL;
+static int resolv_id = 0;
+static volatile int count;
+
+static void resolv_debug(const char *str, void *data)
+{
+ connman_info("%s: %s\n", (const char *) data, str);
+}
static void save_timeservers(char **servers)
{
GKeyFile *keyfile;
@@ -182,20 +194,128 @@ int connman_timeserver_remove(const char *server)
return driver->remove(server);
}
-void connman_timeserver_sync(void)
+/* Restart NTP procedure */
+static void connman_timeserver_restart()
{
- GSList *list;
+ if (resolv == NULL) {
+ DBG("No online service.");
+ return;
+ }
- DBG("");
+ /* Cancel current lookup */
+ if(resolv_id > 0)
+ g_resolv_cancel_lookup(resolv, resolv_id);
- for (list = driver_list; list; list = list->next) {
- struct connman_timeserver_driver *driver = list->data;
+ /* Reload system timeserver list */
+ if (system_timeservers != NULL) {
+ g_strfreev(system_timeservers);
+ system_timeservers = NULL;
+ }
- if (driver->sync == NULL)
- continue;
+ system_timeservers = load_timeservers();
+
+ if (system_timeservers == NULL)
+ return;
+
+ __connman_ntp_stop();
+
+ count = 0;
+
+ __connman_timeserver_sync_next();
+}
+
+static void resolv_result(GResolvResultStatus status, char **results, gpointer
user_data)
+{
+ int i;
+
+ DBG("status %d", status);
+
+ if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
+ if (results != NULL) {
+ for (i = 0; results[i]; i++)
+ DBG("result: %s", results[i]);
+
+ __connman_ntp_start(results[0]);
+
+ return;
+ }
+ }
+ __sync_fetch_and_add(&count, 1);
+ __connman_timeserver_sync_next();
+}
+
+void __connman_timeserver_sync_next()
+{
+ if (system_timeservers == NULL ||
+ system_timeservers[count] == NULL)
+ return;
+
+ DBG("Trying timeserver %s", system_timeservers[count]);
+
+ if (resolv)
+ resolv_id = g_resolv_lookup_hostname(resolv,
+ system_timeservers[count], resolv_result,
+ NULL);
+}
+
+int __connman_timeserver_sync(struct connman_service *service)
+{
+ char **nameservers = NULL;
+ int i;
+
+ DBG("service %p", service);
+
+ i = __connman_service_get_index(service);
+ if (i < 0)
+ return -EINVAL;
+
+ nameservers = connman_service_get_nameservers(service);
+ if (nameservers == NULL)
+ return -EINVAL;
- driver->sync();
+ resolv = g_resolv_new(i);
+ if (resolv == NULL)
+ return -ENOMEM;
+
+ if (getenv("CONNMAN_RESOLV_DEBUG"))
+ g_resolv_set_debug(resolv, resolv_debug, "RESOLV");
+
+ for (i = 0; nameservers[i] != NULL; i++)
+ g_resolv_add_nameserver(resolv, nameservers[i], 53, 0);
+
+ count = 0;
+
+ system_timeservers = load_timeservers();
+
+ if (system_timeservers == NULL || system_timeservers[count] == NULL) {
+ DBG("No timeservers set.");
+ return 0;
}
+
+ DBG("Trying server %s", system_timeservers[count]);
+
+ resolv_id = g_resolv_lookup_hostname(resolv, system_timeservers[count],
+ resolv_result, NULL);
+ return 0;
+}
+
+void __connman_timeserver_stop()
+{
+ DBG(" ");
+
+ if (resolv != NULL) {
+ g_resolv_unref(resolv);
+ resolv = NULL;
+ }
+
+ if (system_timeservers != NULL) {
+ g_strfreev(system_timeservers);
+ system_timeservers = NULL;
+ }
+
+ count = 0;
+
+ __connman_ntp_stop();
}
int __connman_timeserver_system_append(const char *server)
@@ -205,7 +325,7 @@ int __connman_timeserver_system_append(const char *server)
if (server == NULL) {
save_timeservers(servers);
- return 0;
+ goto restart;
}
DBG("server %s", server);
@@ -237,6 +357,8 @@ int __connman_timeserver_system_append(const char *server)
save_timeservers(servers);
g_strfreev(servers);
+restart:
+ connman_timeserver_restart();
return 0;
}
@@ -291,6 +413,8 @@ int __connman_timeserver_system_remove(const char *server)
save_timeservers(servers);
g_strfreev(servers);
+ connman_timeserver_restart();
+
return 0;
}
--
1.7.5.4
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman