5 * Copyright (C) 2007-2012 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 const char *time_updates2string(enum time_updates value)
46 case TIME_UPDATES_UNKNOWN:
48 case TIME_UPDATES_MANUAL:
50 case TIME_UPDATES_AUTO:
57 static enum time_updates string2time_updates(const char *value)
59 if (g_strcmp0(value, "manual") == 0)
60 return TIME_UPDATES_MANUAL;
61 else if (g_strcmp0(value, "auto") == 0)
62 return TIME_UPDATES_AUTO;
64 return TIME_UPDATES_UNKNOWN;
67 static const char *timezone_updates2string(enum timezone_updates value)
70 case TIMEZONE_UPDATES_UNKNOWN:
72 case TIMEZONE_UPDATES_MANUAL:
74 case TIMEZONE_UPDATES_AUTO:
81 static enum timezone_updates string2timezone_updates(const char *value)
83 if (g_strcmp0(value, "manual") == 0)
84 return TIMEZONE_UPDATES_MANUAL;
85 else if (g_strcmp0(value, "auto") == 0)
86 return TIMEZONE_UPDATES_AUTO;
88 return TIMEZONE_UPDATES_UNKNOWN;
91 enum time_updates __connman_clock_timeupdates(void)
93 return time_updates_config;
96 static void append_timeservers(DBusMessageIter *iter, void *user_data)
99 char **timeservers = __connman_timeserver_system_get();
101 if (timeservers == NULL)
104 for (i = 0; timeservers[i] != NULL; i++) {
105 dbus_message_iter_append_basic(iter,
106 DBUS_TYPE_STRING, ×ervers[i]);
109 g_strfreev(timeservers);
112 static DBusMessage *get_properties(DBusConnection *conn,
113 DBusMessage *msg, void *data)
116 DBusMessageIter array, dict;
120 DBG("conn %p", conn);
122 reply = dbus_message_new_method_return(msg);
126 dbus_message_iter_init_append(reply, &array);
128 connman_dbus_dict_open(&array, &dict);
130 if (gettimeofday(&tv, NULL) == 0) {
131 dbus_uint64_t val = tv.tv_sec;
133 connman_dbus_dict_append_basic(&dict, "Time",
134 DBUS_TYPE_UINT64, &val);
137 str = time_updates2string(time_updates_config);
139 connman_dbus_dict_append_basic(&dict, "TimeUpdates",
140 DBUS_TYPE_STRING, &str);
142 if (timezone_config != NULL)
143 connman_dbus_dict_append_basic(&dict, "Timezone",
144 DBUS_TYPE_STRING, &timezone_config);
146 str = timezone_updates2string(timezone_updates_config);
148 connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
149 DBUS_TYPE_STRING, &str);
151 connman_dbus_dict_append_array(&dict, "Timeservers",
152 DBUS_TYPE_STRING, append_timeservers, NULL);
154 connman_dbus_dict_close(&array, &dict);
159 static DBusMessage *set_property(DBusConnection *conn,
160 DBusMessage *msg, void *data)
162 DBusMessageIter iter, value;
166 DBG("conn %p", conn);
168 if (dbus_message_iter_init(msg, &iter) == FALSE)
169 return __connman_error_invalid_arguments(msg);
171 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
172 return __connman_error_invalid_arguments(msg);
174 dbus_message_iter_get_basic(&iter, &name);
175 dbus_message_iter_next(&iter);
177 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
178 return __connman_error_invalid_arguments(msg);
180 dbus_message_iter_recurse(&iter, &value);
182 type = dbus_message_iter_get_arg_type(&value);
184 if (g_str_equal(name, "Time") == TRUE) {
186 dbus_uint64_t newval;
188 if (type != DBUS_TYPE_UINT64)
189 return __connman_error_invalid_arguments(msg);
191 if (time_updates_config != TIME_UPDATES_MANUAL)
192 return __connman_error_permission_denied(msg);
194 dbus_message_iter_get_basic(&value, &newval);
199 if (settimeofday(&tv, NULL) < 0)
200 return __connman_error_invalid_arguments(msg);
202 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
203 CONNMAN_CLOCK_INTERFACE, "Time",
204 DBUS_TYPE_UINT64, &newval);
205 } else if (g_str_equal(name, "TimeUpdates") == TRUE) {
207 enum time_updates newval;
209 if (type != DBUS_TYPE_STRING)
210 return __connman_error_invalid_arguments(msg);
212 dbus_message_iter_get_basic(&value, &strval);
213 newval = string2time_updates(strval);
215 if (newval == TIME_UPDATES_UNKNOWN)
216 return __connman_error_invalid_arguments(msg);
218 if (newval == time_updates_config)
219 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
221 time_updates_config = newval;
223 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
224 CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
225 DBUS_TYPE_STRING, &strval);
226 } else if (g_str_equal(name, "Timezone") == TRUE) {
229 if (type != DBUS_TYPE_STRING)
230 return __connman_error_invalid_arguments(msg);
232 if (timezone_updates_config != TIMEZONE_UPDATES_MANUAL)
233 return __connman_error_permission_denied(msg);
235 dbus_message_iter_get_basic(&value, &strval);
237 if (__connman_timezone_change(strval) < 0)
238 return __connman_error_invalid_arguments(msg);
239 } else if (g_str_equal(name, "TimezoneUpdates") == TRUE) {
241 enum timezone_updates newval;
243 if (type != DBUS_TYPE_STRING)
244 return __connman_error_invalid_arguments(msg);
246 dbus_message_iter_get_basic(&value, &strval);
247 newval = string2timezone_updates(strval);
249 if (newval == TIMEZONE_UPDATES_UNKNOWN)
250 return __connman_error_invalid_arguments(msg);
252 if (newval == timezone_updates_config)
253 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
255 timezone_updates_config = newval;
257 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
258 CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
259 DBUS_TYPE_STRING, &strval);
260 } else if (g_str_equal(name, "Timeservers") == TRUE) {
261 DBusMessageIter entry;
266 if (type != DBUS_TYPE_ARRAY)
267 return __connman_error_invalid_arguments(msg);
269 dbus_message_iter_recurse(&value, &entry);
271 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
275 dbus_message_iter_get_basic(&entry, &val);
277 new_head = __connman_timeserver_add_list(list, val);
278 if (list != new_head) {
283 dbus_message_iter_next(&entry);
287 str = g_new0(char *, count+1);
289 while (list != NULL) {
291 str[count] = list->data;
292 list = g_slist_delete_link(list, list);
296 __connman_timeserver_system_set(str);
301 connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
302 CONNMAN_CLOCK_INTERFACE, "Timeservers",
303 DBUS_TYPE_STRING, append_timeservers, NULL);
305 return __connman_error_invalid_property(msg);
307 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
310 static const GDBusMethodTable clock_methods[] = {
311 { GDBUS_METHOD("GetProperties",
312 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
314 { GDBUS_METHOD("SetProperty",
315 GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
320 static const GDBusSignalTable clock_signals[] = {
321 { GDBUS_SIGNAL("PropertyChanged",
322 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
326 static DBusConnection *connection = NULL;
328 void __connman_clock_update_timezone(void)
332 g_free(timezone_config);
333 timezone_config = __connman_timezone_lookup();
335 if (timezone_config == NULL)
338 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
339 CONNMAN_CLOCK_INTERFACE, "Timezone",
340 DBUS_TYPE_STRING, &timezone_config);
343 int __connman_clock_init(void)
347 connection = connman_dbus_get_connection();
348 if (connection == NULL)
351 __connman_timezone_init();
353 timezone_config = __connman_timezone_lookup();
355 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
356 CONNMAN_CLOCK_INTERFACE,
357 clock_methods, clock_signals,
363 void __connman_clock_cleanup(void)
367 if (connection == NULL)
370 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
371 CONNMAN_CLOCK_INTERFACE);
373 dbus_connection_unref(connection);
375 __connman_timezone_cleanup();
377 g_free(timezone_config);