RE: [PATCH] clock: Add TimeSynced signal emitted when the system time
has been synced
by VAUTRIN Emmanuel (Canal Plus Prestataire)
Hello,
Finally, after running several campaigns, I faced (rarely) no time update after updating the timeservers lists.
It seems to work better with this second version.
From ced5a1988f5b0e7a44a278b0e270577e6b427f88 Mon Sep 17 00:00:00 2001
From: Emmanuel VAUTRIN <Emmanuel.VAUTRIN(a)cpexterne.org>
Date: Thu, 7 Jan 2021 17:27:39 +0100
Subject: [PATCH v2] clock: Implement Clock API time synchronization
Implement Clock API TimeserverSynced property, which indicates if the
current system time is synced via NTP servers.
Trigger a time synchronization when the TimeUpdate property is set to
auto.
Fix time synchronization when starting with an empty Timeservers list.
Emit a Time PropertyChanged signal on NTP synchronization success.
---
doc/clock-api.txt | 5 +++++
src/clock.c | 15 +++++++++++++++
src/connman.h | 3 +++
src/timeserver.c | 43 +++++++++++++++++++++++++++++++++++++++++--
4 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/doc/clock-api.txt b/doc/clock-api.txt
index 6818f5a8..48d29970 100644
--- a/doc/clock-api.txt
+++ b/doc/clock-api.txt
@@ -85,3 +85,8 @@ Properties uint64 Time [readonly or readwrite] [experimental]
This list of servers is used when TimeUpdates is set
to auto.
+
+ boolean TimeserverSynced [readonly] [experimental]
+
+ This value indicates if the current system time
+ is synced via NTP servers.
diff --git a/src/clock.c b/src/clock.c
index 0fde2c34..906538ac 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -173,6 +173,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
{
DBusMessage *reply;
DBusMessageIter array, dict;
+ dbus_bool_t is_synced;
struct timeval tv;
const char *str;
@@ -210,6 +211,10 @@ static DBusMessage *get_properties(DBusConnection *conn,
connman_dbus_dict_append_array(&dict, "Timeservers",
DBUS_TYPE_STRING, append_timeservers, NULL);
+ is_synced = __connman_timeserver_is_synced();
+ connman_dbus_dict_append_basic(&dict, "TimeserverSynced",
+ DBUS_TYPE_BOOLEAN, &is_synced);
+
connman_dbus_dict_close(&array, &dict);
return reply;
@@ -258,6 +263,7 @@ static DBusMessage *set_property(DBusConnection *conn,
if (settimeofday(&tv, NULL) < 0)
return __connman_error_invalid_arguments(msg);
+ __connman_timeserver_set_synced(false);
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "Time",
DBUS_TYPE_UINT64, &newval);
@@ -283,6 +289,13 @@ static DBusMessage *set_property(DBusConnection *conn,
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
DBUS_TYPE_STRING, &strval);
+
+ if (newval == TIME_UPDATES_AUTO) {
+ struct connman_service *service;
+
+ service = connman_service_get_default();
+ __connman_timeserver_conf_update(service);
+ }
} else if (g_str_equal(name, "Timezone")) {
const char *strval;
@@ -362,6 +375,8 @@ static DBusMessage *set_property(DBusConnection *conn,
connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "Timeservers",
DBUS_TYPE_STRING, append_timeservers, NULL);
+ } else if (g_str_equal(name, "TimeserverSynced")) {
+ return __connman_error_permission_denied(msg);
} else
return __connman_error_invalid_property(msg);
diff --git a/src/connman.h b/src/connman.h
index e51d94d0..50d52bbe 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -452,6 +452,9 @@ GSList *__connman_timeserver_get_all(struct connman_service *service);
void __connman_timeserver_sync(struct connman_service *service);
void __connman_timeserver_conf_update(struct connman_service *service);
+bool __connman_timeserver_is_synced(void);
+void __connman_timeserver_set_synced(bool status);
+
enum __connman_dhcpv6_status {
CONNMAN_DHCPV6_STATUS_FAIL = 0,
CONNMAN_DHCPV6_STATUS_SUCCEED = 1,
diff --git a/src/timeserver.c b/src/timeserver.c
index 5f0aca68..2675113b 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <gweb/gresolv.h>
#include <netdb.h>
+#include <sys/time.h>
#include "connman.h"
@@ -40,6 +41,7 @@ static GSList *ts_list = NULL;
static char *ts_current = NULL;
static int ts_recheck_id = 0;
static int ts_backoff_id = 0;
+static bool ts_is_synced = false;
static GResolv *resolv = NULL;
static int resolv_id = 0;
@@ -55,8 +57,24 @@ static void ntp_callback(bool success, void *user_data)
{
DBG("success %d", success);
+ __connman_timeserver_set_synced(success);
if (!success)
sync_next();
+ else {
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) == 0) {
+ dbus_uint64_t timestamp;
+
+ timestamp = tv.tv_sec;
+ connman_dbus_property_changed_basic(
+ CONNMAN_MANAGER_PATH,
+ CONNMAN_CLOCK_INTERFACE, "Time",
+ DBUS_TYPE_UINT64, ×tamp);
+ } else {
+ connman_warn("Failed to get current time");
+ }
+ }
}
static void save_timeservers(char **servers)
@@ -337,6 +355,8 @@ static void ts_reset(struct connman_service *service)
if (!resolv)
return;
+ __connman_timeserver_set_synced(false);
+
/*
* Before we start creating the new timeserver list we must stop
* any ongoing ntp query and server resolution.
@@ -366,6 +386,8 @@ static void ts_reset(struct connman_service *service)
__connman_service_timeserver_changed(service, timeservers_list);
+ ts_service = service;
+
if (!timeservers_list) {
DBG("No timeservers set.");
return;
@@ -373,7 +395,6 @@ static void ts_reset(struct connman_service *service)
ts_recheck_enable();
- ts_service = service;
timeserver_sync_start();
}
@@ -394,6 +415,24 @@ void __connman_timeserver_conf_update(struct connman_service *service)
}
+bool __connman_timeserver_is_synced(void)
+{
+ return ts_is_synced;
+}
+
+void __connman_timeserver_set_synced(bool status)
+{
+ if (ts_is_synced != status) {
+ dbus_bool_t is_synced;
+
+ ts_is_synced = status;
+ is_synced = status;
+ connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
+ CONNMAN_CLOCK_INTERFACE, "TimeserverSynced",
+ DBUS_TYPE_BOOLEAN, &is_synced);
+ }
+}
+
static int timeserver_start(struct connman_service *service)
{
char **nameservers;
@@ -467,7 +506,7 @@ int __connman_timeserver_system_set(char **servers)
save_timeservers(servers);
service = connman_service_get_default();
- __connman_timeserver_conf_update(service);
+ ts_reset(service);
return 0;
}
--
2.25.1
B.R.
Emmanuel