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 g_key_file_free(keyfile);
125 static void clock_properties_save(void)
130 keyfile = __connman_storage_load_global();
132 keyfile = g_key_file_new();
134 str = time_updates2string(time_updates_config);
136 g_key_file_set_string(keyfile, "global", "TimeUpdates", str);
138 g_key_file_remove_key(keyfile, "global", "TimeUpdates", NULL);
140 str = timezone_updates2string(timezone_updates_config);
142 g_key_file_set_string(keyfile, "global", "TimezoneUpdates",
145 g_key_file_remove_key(keyfile, "global", "TimezoneUpdates",
148 __connman_storage_save_global(keyfile);
150 g_key_file_free(keyfile);
153 enum time_updates __connman_clock_timeupdates(void)
155 return time_updates_config;
158 static void append_timeservers(DBusMessageIter *iter, void *user_data)
161 char **timeservers = __connman_timeserver_system_get();
166 for (i = 0; timeservers[i]; i++) {
167 dbus_message_iter_append_basic(iter,
168 DBUS_TYPE_STRING, ×ervers[i]);
171 g_strfreev(timeservers);
174 static DBusMessage *get_properties(DBusConnection *conn,
175 DBusMessage *msg, void *data)
178 DBusMessageIter array, dict;
179 dbus_bool_t is_synced;
182 #if defined TIZEN_EXT
183 dbus_bool_t val = time_updated;
186 DBG("conn %p", conn);
188 reply = dbus_message_new_method_return(msg);
192 dbus_message_iter_init_append(reply, &array);
194 connman_dbus_dict_open(&array, &dict);
196 #if defined TIZEN_EXT
197 connman_dbus_dict_append_basic(&dict, "TimeUpdated",
202 if (gettimeofday(&tv, NULL) == 0) {
203 dbus_uint64_t val = tv.tv_sec;
205 connman_dbus_dict_append_basic(&dict, "Time",
206 DBUS_TYPE_UINT64, &val);
209 str = time_updates2string(time_updates_config);
211 connman_dbus_dict_append_basic(&dict, "TimeUpdates",
212 DBUS_TYPE_STRING, &str);
215 connman_dbus_dict_append_basic(&dict, "Timezone",
216 DBUS_TYPE_STRING, &timezone_config);
218 str = timezone_updates2string(timezone_updates_config);
220 connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
221 DBUS_TYPE_STRING, &str);
223 connman_dbus_dict_append_array(&dict, "Timeservers",
224 DBUS_TYPE_STRING, append_timeservers, NULL);
226 is_synced = __connman_timeserver_is_synced();
227 connman_dbus_dict_append_basic(&dict, "TimeserverSynced",
228 DBUS_TYPE_BOOLEAN, &is_synced);
230 connman_dbus_dict_close(&array, &dict);
235 static DBusMessage *set_property(DBusConnection *conn,
236 DBusMessage *msg, void *data)
238 DBusMessageIter iter, value;
242 DBG("conn %p", conn);
244 if (!dbus_message_iter_init(msg, &iter))
245 return __connman_error_invalid_arguments(msg);
247 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
248 return __connman_error_invalid_arguments(msg);
250 dbus_message_iter_get_basic(&iter, &name);
251 dbus_message_iter_next(&iter);
253 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
254 return __connman_error_invalid_arguments(msg);
256 dbus_message_iter_recurse(&iter, &value);
258 type = dbus_message_iter_get_arg_type(&value);
260 if (g_str_equal(name, "Time")) {
261 #if defined TIZEN_EXT
262 /* Tizen updates time (ntp) by system service */
264 return __connman_error_permission_denied(msg);
267 dbus_uint64_t newval;
269 if (type != DBUS_TYPE_UINT64)
270 return __connman_error_invalid_arguments(msg);
272 if (time_updates_config != TIME_UPDATES_MANUAL)
273 return __connman_error_permission_denied(msg);
275 dbus_message_iter_get_basic(&value, &newval);
280 if (settimeofday(&tv, NULL) < 0)
281 return __connman_error_invalid_arguments(msg);
283 __connman_timeserver_set_synced(false);
284 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
285 CONNMAN_CLOCK_INTERFACE, "Time",
286 DBUS_TYPE_UINT64, &newval);
288 } else if (g_str_equal(name, "TimeUpdates")) {
290 enum time_updates newval;
292 if (type != DBUS_TYPE_STRING)
293 return __connman_error_invalid_arguments(msg);
295 dbus_message_iter_get_basic(&value, &strval);
296 newval = string2time_updates(strval);
298 if (newval == TIME_UPDATES_UNKNOWN)
299 return __connman_error_invalid_arguments(msg);
301 if (newval == time_updates_config)
302 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
304 time_updates_config = newval;
306 clock_properties_save();
307 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
308 CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
309 DBUS_TYPE_STRING, &strval);
311 if (newval == TIME_UPDATES_AUTO) {
312 struct connman_service *service;
314 service = connman_service_get_default();
315 __connman_timeserver_conf_update(service);
317 } else if (g_str_equal(name, "Timezone")) {
320 if (type != DBUS_TYPE_STRING)
321 return __connman_error_invalid_arguments(msg);
323 if (timezone_updates_config != TIMEZONE_UPDATES_MANUAL)
324 return __connman_error_permission_denied(msg);
326 dbus_message_iter_get_basic(&value, &strval);
328 if (__connman_timezone_change(strval) < 0)
329 return __connman_error_invalid_arguments(msg);
330 } else if (g_str_equal(name, "TimezoneUpdates")) {
332 enum timezone_updates newval;
334 if (type != DBUS_TYPE_STRING)
335 return __connman_error_invalid_arguments(msg);
337 dbus_message_iter_get_basic(&value, &strval);
338 newval = string2timezone_updates(strval);
340 if (newval == TIMEZONE_UPDATES_UNKNOWN)
341 return __connman_error_invalid_arguments(msg);
343 if (newval == timezone_updates_config)
344 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
346 timezone_updates_config = newval;
348 clock_properties_save();
349 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
350 CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
351 DBUS_TYPE_STRING, &strval);
352 } else if (g_str_equal(name, "Timeservers")) {
353 DBusMessageIter entry;
358 if (type != DBUS_TYPE_ARRAY)
359 return __connman_error_invalid_arguments(msg);
361 dbus_message_iter_recurse(&value, &entry);
363 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
367 dbus_message_iter_get_basic(&entry, &val);
369 new_head = __connman_timeserver_add_list(list, val);
370 if (list != new_head) {
375 dbus_message_iter_next(&entry);
379 str = g_new0(char *, count+1);
383 str[count] = list->data;
384 list = g_slist_delete_link(list, list);
388 __connman_timeserver_system_set(str);
393 connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
394 CONNMAN_CLOCK_INTERFACE, "Timeservers",
395 DBUS_TYPE_STRING, append_timeservers, NULL);
396 } else if (g_str_equal(name, "TimeserverSynced")) {
397 return __connman_error_permission_denied(msg);
399 return __connman_error_invalid_property(msg);
401 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
404 static const GDBusMethodTable clock_methods[] = {
405 { GDBUS_METHOD("GetProperties",
406 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
408 { GDBUS_METHOD("SetProperty",
409 GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
414 static const GDBusSignalTable clock_signals[] = {
415 { GDBUS_SIGNAL("PropertyChanged",
416 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
420 static DBusConnection *connection = NULL;
422 #if defined TIZEN_EXT
423 void __connman_clock_set_time_updated(bool updated)
425 time_updated = updated;
429 void __connman_clock_update_timezone(void)
433 g_free(timezone_config);
434 timezone_config = __connman_timezone_lookup();
436 if (!timezone_config)
439 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
440 CONNMAN_CLOCK_INTERFACE, "Timezone",
441 DBUS_TYPE_STRING, &timezone_config);
444 int __connman_clock_init(void)
448 connection = connman_dbus_get_connection();
452 __connman_timezone_init();
454 timezone_config = __connman_timezone_lookup();
456 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
457 CONNMAN_CLOCK_INTERFACE,
458 clock_methods, clock_signals,
461 clock_properties_load();
465 void __connman_clock_cleanup(void)
472 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
473 CONNMAN_CLOCK_INTERFACE);
475 dbus_connection_unref(connection);
477 __connman_timezone_cleanup();
479 g_free(timezone_config);