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;
181 #if defined TIZEN_EXT
182 dbus_bool_t val = time_updated;
185 DBG("conn %p", conn);
187 reply = dbus_message_new_method_return(msg);
191 dbus_message_iter_init_append(reply, &array);
193 connman_dbus_dict_open(&array, &dict);
195 #if defined TIZEN_EXT
196 connman_dbus_dict_append_basic(&dict, "TimeUpdated",
201 if (gettimeofday(&tv, NULL) == 0) {
202 dbus_uint64_t val = tv.tv_sec;
204 connman_dbus_dict_append_basic(&dict, "Time",
205 DBUS_TYPE_UINT64, &val);
208 str = time_updates2string(time_updates_config);
210 connman_dbus_dict_append_basic(&dict, "TimeUpdates",
211 DBUS_TYPE_STRING, &str);
214 connman_dbus_dict_append_basic(&dict, "Timezone",
215 DBUS_TYPE_STRING, &timezone_config);
217 str = timezone_updates2string(timezone_updates_config);
219 connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
220 DBUS_TYPE_STRING, &str);
222 connman_dbus_dict_append_array(&dict, "Timeservers",
223 DBUS_TYPE_STRING, append_timeservers, NULL);
225 connman_dbus_dict_close(&array, &dict);
230 static DBusMessage *set_property(DBusConnection *conn,
231 DBusMessage *msg, void *data)
233 DBusMessageIter iter, value;
237 DBG("conn %p", conn);
239 if (!dbus_message_iter_init(msg, &iter))
240 return __connman_error_invalid_arguments(msg);
242 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
243 return __connman_error_invalid_arguments(msg);
245 dbus_message_iter_get_basic(&iter, &name);
246 dbus_message_iter_next(&iter);
248 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
249 return __connman_error_invalid_arguments(msg);
251 dbus_message_iter_recurse(&iter, &value);
253 type = dbus_message_iter_get_arg_type(&value);
255 if (g_str_equal(name, "Time")) {
256 #if defined TIZEN_EXT
257 /* Tizen updates time (ntp) by system service */
259 return __connman_error_permission_denied(msg);
262 dbus_uint64_t newval;
264 if (type != DBUS_TYPE_UINT64)
265 return __connman_error_invalid_arguments(msg);
267 if (time_updates_config != TIME_UPDATES_MANUAL)
268 return __connman_error_permission_denied(msg);
270 dbus_message_iter_get_basic(&value, &newval);
275 if (settimeofday(&tv, NULL) < 0)
276 return __connman_error_invalid_arguments(msg);
278 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
279 CONNMAN_CLOCK_INTERFACE, "Time",
280 DBUS_TYPE_UINT64, &newval);
282 } else if (g_str_equal(name, "TimeUpdates")) {
284 enum time_updates newval;
286 if (type != DBUS_TYPE_STRING)
287 return __connman_error_invalid_arguments(msg);
289 dbus_message_iter_get_basic(&value, &strval);
290 newval = string2time_updates(strval);
292 if (newval == TIME_UPDATES_UNKNOWN)
293 return __connman_error_invalid_arguments(msg);
295 if (newval == time_updates_config)
296 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
298 time_updates_config = newval;
300 clock_properties_save();
301 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
302 CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
303 DBUS_TYPE_STRING, &strval);
304 } else if (g_str_equal(name, "Timezone")) {
307 if (type != DBUS_TYPE_STRING)
308 return __connman_error_invalid_arguments(msg);
310 if (timezone_updates_config != TIMEZONE_UPDATES_MANUAL)
311 return __connman_error_permission_denied(msg);
313 dbus_message_iter_get_basic(&value, &strval);
315 if (__connman_timezone_change(strval) < 0)
316 return __connman_error_invalid_arguments(msg);
317 } else if (g_str_equal(name, "TimezoneUpdates")) {
319 enum timezone_updates newval;
321 if (type != DBUS_TYPE_STRING)
322 return __connman_error_invalid_arguments(msg);
324 dbus_message_iter_get_basic(&value, &strval);
325 newval = string2timezone_updates(strval);
327 if (newval == TIMEZONE_UPDATES_UNKNOWN)
328 return __connman_error_invalid_arguments(msg);
330 if (newval == timezone_updates_config)
331 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
333 timezone_updates_config = newval;
335 clock_properties_save();
336 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
337 CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
338 DBUS_TYPE_STRING, &strval);
339 } else if (g_str_equal(name, "Timeservers")) {
340 DBusMessageIter entry;
345 if (type != DBUS_TYPE_ARRAY)
346 return __connman_error_invalid_arguments(msg);
348 dbus_message_iter_recurse(&value, &entry);
350 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
354 dbus_message_iter_get_basic(&entry, &val);
356 new_head = __connman_timeserver_add_list(list, val);
357 if (list != new_head) {
362 dbus_message_iter_next(&entry);
366 str = g_new0(char *, count+1);
370 str[count] = list->data;
371 list = g_slist_delete_link(list, list);
375 __connman_timeserver_system_set(str);
380 connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
381 CONNMAN_CLOCK_INTERFACE, "Timeservers",
382 DBUS_TYPE_STRING, append_timeservers, NULL);
384 return __connman_error_invalid_property(msg);
386 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
389 static const GDBusMethodTable clock_methods[] = {
390 { GDBUS_METHOD("GetProperties",
391 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
393 { GDBUS_METHOD("SetProperty",
394 GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
399 static const GDBusSignalTable clock_signals[] = {
400 { GDBUS_SIGNAL("PropertyChanged",
401 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
405 static DBusConnection *connection = NULL;
407 #if defined TIZEN_EXT
408 void __connman_clock_set_time_updated(bool updated)
410 time_updated = updated;
414 void __connman_clock_update_timezone(void)
418 g_free(timezone_config);
419 timezone_config = __connman_timezone_lookup();
421 if (!timezone_config)
424 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
425 CONNMAN_CLOCK_INTERFACE, "Timezone",
426 DBUS_TYPE_STRING, &timezone_config);
429 int __connman_clock_init(void)
433 connection = connman_dbus_get_connection();
437 __connman_timezone_init();
439 timezone_config = __connman_timezone_lookup();
441 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
442 CONNMAN_CLOCK_INTERFACE,
443 clock_methods, clock_signals,
446 clock_properties_load();
450 void __connman_clock_cleanup(void)
457 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
458 CONNMAN_CLOCK_INTERFACE);
460 dbus_connection_unref(connection);
462 __connman_timezone_cleanup();
464 g_free(timezone_config);