5 * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 enum timezone_updates {
33 TIMEZONE_UPDATES_UNKNOWN = 0,
34 TIMEZONE_UPDATES_MANUAL = 1,
35 TIMEZONE_UPDATES_AUTO = 2,
38 static enum time_updates time_updates_config = TIME_UPDATES_AUTO;
39 static enum timezone_updates timezone_updates_config = TIMEZONE_UPDATES_AUTO;
41 static char *timezone_config = NULL;
43 static bool time_updated = false;
46 static const char *time_updates2string(enum time_updates value)
49 case TIME_UPDATES_UNKNOWN:
51 case TIME_UPDATES_MANUAL:
53 case TIME_UPDATES_AUTO:
60 static enum time_updates string2time_updates(const char *value)
62 if (g_strcmp0(value, "manual") == 0)
63 return TIME_UPDATES_MANUAL;
64 else if (g_strcmp0(value, "auto") == 0)
65 return TIME_UPDATES_AUTO;
67 return TIME_UPDATES_UNKNOWN;
70 static const char *timezone_updates2string(enum timezone_updates value)
73 case TIMEZONE_UPDATES_UNKNOWN:
75 case TIMEZONE_UPDATES_MANUAL:
77 case TIMEZONE_UPDATES_AUTO:
84 static enum timezone_updates string2timezone_updates(const char *value)
86 if (g_strcmp0(value, "manual") == 0)
87 return TIMEZONE_UPDATES_MANUAL;
88 else if (g_strcmp0(value, "auto") == 0)
89 return TIMEZONE_UPDATES_AUTO;
91 return TIMEZONE_UPDATES_UNKNOWN;
94 static void clock_properties_load(void)
98 enum time_updates time_value;
99 enum timezone_updates timezone_value;
101 keyfile = __connman_storage_load_global();
105 str = g_key_file_get_string(keyfile, "global", "TimeUpdates", NULL);
107 time_value = string2time_updates(str);
108 if (time_value != TIME_UPDATES_UNKNOWN)
109 time_updates_config = time_value;
113 str = g_key_file_get_string(keyfile, "global", "TimezoneUpdates",
116 timezone_value = string2timezone_updates(str);
117 if (timezone_value != TIMEZONE_UPDATES_UNKNOWN)
118 timezone_updates_config = timezone_value;
122 #if defined TIZEN_EXT
123 str = g_key_file_get_string(keyfile, "global", "Timeservers", NULL);
125 if (str && str[0] == ';') {
126 DBG("Set time_updates_config to MANUAL.");
127 time_updates_config = TIME_UPDATES_MANUAL;
133 g_key_file_free(keyfile);
136 static void clock_properties_save(void)
141 keyfile = __connman_storage_load_global();
143 keyfile = g_key_file_new();
145 str = time_updates2string(time_updates_config);
147 g_key_file_set_string(keyfile, "global", "TimeUpdates", str);
149 g_key_file_remove_key(keyfile, "global", "TimeUpdates", NULL);
151 str = timezone_updates2string(timezone_updates_config);
153 g_key_file_set_string(keyfile, "global", "TimezoneUpdates",
156 g_key_file_remove_key(keyfile, "global", "TimezoneUpdates",
159 __connman_storage_save_global(keyfile);
161 g_key_file_free(keyfile);
164 enum time_updates __connman_clock_timeupdates(void)
166 return time_updates_config;
169 static void append_timeservers(DBusMessageIter *iter, void *user_data)
172 char **timeservers = __connman_timeserver_system_get();
177 for (i = 0; timeservers[i]; i++) {
178 dbus_message_iter_append_basic(iter,
179 DBUS_TYPE_STRING, ×ervers[i]);
182 g_strfreev(timeservers);
185 static DBusMessage *get_properties(DBusConnection *conn,
186 DBusMessage *msg, void *data)
189 DBusMessageIter array, dict;
190 dbus_bool_t is_synced;
193 #if defined TIZEN_EXT
194 dbus_bool_t val = time_updated;
197 DBG("conn %p", conn);
199 reply = dbus_message_new_method_return(msg);
203 dbus_message_iter_init_append(reply, &array);
205 connman_dbus_dict_open(&array, &dict);
207 #if defined TIZEN_EXT
208 connman_dbus_dict_append_basic(&dict, "TimeUpdated",
213 if (gettimeofday(&tv, NULL) == 0) {
214 dbus_uint64_t val = tv.tv_sec;
216 connman_dbus_dict_append_basic(&dict, "Time",
217 DBUS_TYPE_UINT64, &val);
220 str = time_updates2string(time_updates_config);
222 connman_dbus_dict_append_basic(&dict, "TimeUpdates",
223 DBUS_TYPE_STRING, &str);
226 connman_dbus_dict_append_basic(&dict, "Timezone",
227 DBUS_TYPE_STRING, &timezone_config);
229 str = timezone_updates2string(timezone_updates_config);
231 connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
232 DBUS_TYPE_STRING, &str);
234 connman_dbus_dict_append_array(&dict, "Timeservers",
235 DBUS_TYPE_STRING, append_timeservers, NULL);
237 is_synced = __connman_timeserver_is_synced();
238 connman_dbus_dict_append_basic(&dict, "TimeserverSynced",
239 DBUS_TYPE_BOOLEAN, &is_synced);
241 connman_dbus_dict_close(&array, &dict);
246 static DBusMessage *set_property(DBusConnection *conn,
247 DBusMessage *msg, void *data)
249 DBusMessageIter iter, value;
253 DBG("conn %p", conn);
255 if (!dbus_message_iter_init(msg, &iter))
256 return __connman_error_invalid_arguments(msg);
258 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
259 return __connman_error_invalid_arguments(msg);
261 dbus_message_iter_get_basic(&iter, &name);
262 dbus_message_iter_next(&iter);
264 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
265 return __connman_error_invalid_arguments(msg);
267 dbus_message_iter_recurse(&iter, &value);
269 type = dbus_message_iter_get_arg_type(&value);
271 if (g_str_equal(name, "Time")) {
272 #if defined TIZEN_EXT
273 /* Tizen updates time (ntp) by system service */
275 return __connman_error_permission_denied(msg);
278 dbus_uint64_t newval;
280 if (type != DBUS_TYPE_UINT64)
281 return __connman_error_invalid_arguments(msg);
283 if (time_updates_config != TIME_UPDATES_MANUAL)
284 return __connman_error_permission_denied(msg);
286 dbus_message_iter_get_basic(&value, &newval);
291 if (settimeofday(&tv, NULL) < 0)
292 return __connman_error_invalid_arguments(msg);
294 __connman_timeserver_set_synced(false);
295 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
296 CONNMAN_CLOCK_INTERFACE, "Time",
297 DBUS_TYPE_UINT64, &newval);
299 } else if (g_str_equal(name, "TimeUpdates")) {
301 enum time_updates newval;
303 if (type != DBUS_TYPE_STRING)
304 return __connman_error_invalid_arguments(msg);
306 dbus_message_iter_get_basic(&value, &strval);
307 newval = string2time_updates(strval);
309 if (newval == TIME_UPDATES_UNKNOWN)
310 return __connman_error_invalid_arguments(msg);
312 if (newval == time_updates_config)
313 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
315 time_updates_config = newval;
317 clock_properties_save();
318 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
319 CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
320 DBUS_TYPE_STRING, &strval);
322 if (newval == TIME_UPDATES_AUTO) {
323 struct connman_service *service;
325 service = connman_service_get_default();
326 __connman_timeserver_conf_update(service);
328 } else if (g_str_equal(name, "Timezone")) {
331 if (type != DBUS_TYPE_STRING)
332 return __connman_error_invalid_arguments(msg);
334 if (timezone_updates_config != TIMEZONE_UPDATES_MANUAL)
335 return __connman_error_permission_denied(msg);
337 dbus_message_iter_get_basic(&value, &strval);
339 if (__connman_timezone_change(strval) < 0)
340 return __connman_error_invalid_arguments(msg);
341 } else if (g_str_equal(name, "TimezoneUpdates")) {
343 enum timezone_updates newval;
345 if (type != DBUS_TYPE_STRING)
346 return __connman_error_invalid_arguments(msg);
348 dbus_message_iter_get_basic(&value, &strval);
349 newval = string2timezone_updates(strval);
351 if (newval == TIMEZONE_UPDATES_UNKNOWN)
352 return __connman_error_invalid_arguments(msg);
354 if (newval == timezone_updates_config)
355 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
357 timezone_updates_config = newval;
359 clock_properties_save();
360 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
361 CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
362 DBUS_TYPE_STRING, &strval);
363 } else if (g_str_equal(name, "Timeservers")) {
364 DBusMessageIter entry;
369 if (type != DBUS_TYPE_ARRAY)
370 return __connman_error_invalid_arguments(msg);
372 dbus_message_iter_recurse(&value, &entry);
374 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
378 dbus_message_iter_get_basic(&entry, &val);
380 new_head = __connman_timeserver_add_list(list, val);
381 if (list != new_head) {
386 dbus_message_iter_next(&entry);
390 str = g_new0(char *, count+1);
394 str[count] = list->data;
395 list = g_slist_delete_link(list, list);
399 __connman_timeserver_system_set(str);
401 #if defined TIZEN_EXT
403 if (str[0][0] == '\0') {
404 DBG("Set time_updates_config to MANUAL.");
405 time_updates_config = TIMEZONE_UPDATES_MANUAL;
407 DBG("Set time_updates_config to AUTO.");
408 time_updates_config = TIMEZONE_UPDATES_AUTO;
411 DBG("Set time_updates_config to MANUAL.");
412 time_updates_config = TIMEZONE_UPDATES_MANUAL;
419 connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
420 CONNMAN_CLOCK_INTERFACE, "Timeservers",
421 DBUS_TYPE_STRING, append_timeservers, NULL);
422 } else if (g_str_equal(name, "TimeserverSynced")) {
423 return __connman_error_permission_denied(msg);
425 return __connman_error_invalid_property(msg);
427 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
430 static const GDBusMethodTable clock_methods[] = {
431 { GDBUS_METHOD("GetProperties",
432 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
434 { GDBUS_METHOD("SetProperty",
435 GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
440 static const GDBusSignalTable clock_signals[] = {
441 { GDBUS_SIGNAL("PropertyChanged",
442 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
446 static DBusConnection *connection = NULL;
448 #if defined TIZEN_EXT
449 void __connman_clock_set_time_updated(bool updated)
451 time_updated = updated;
455 void __connman_clock_update_timezone(void)
459 g_free(timezone_config);
460 timezone_config = __connman_timezone_lookup();
462 if (!timezone_config)
465 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
466 CONNMAN_CLOCK_INTERFACE, "Timezone",
467 DBUS_TYPE_STRING, &timezone_config);
470 int __connman_clock_init(void)
474 connection = connman_dbus_get_connection();
478 __connman_timezone_init();
480 timezone_config = __connman_timezone_lookup();
482 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
483 CONNMAN_CLOCK_INTERFACE,
484 clock_methods, clock_signals,
487 clock_properties_load();
491 void __connman_clock_cleanup(void)
498 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
499 CONNMAN_CLOCK_INTERFACE);
501 dbus_connection_unref(connection);
503 __connman_timezone_cleanup();
505 g_free(timezone_config);