5 * Copyright (C) 2007-2010 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
33 TIME_UPDATES_UNKNOWN = 0,
34 TIME_UPDATES_MANUAL = 1,
35 TIME_UPDATES_AUTO = 2,
38 enum timezone_updates {
39 TIMEZONE_UPDATES_UNKNOWN = 0,
40 TIMEZONE_UPDATES_MANUAL = 1,
41 TIMEZONE_UPDATES_AUTO = 2,
44 static enum time_updates time_updates_config = TIME_UPDATES_AUTO;
45 static enum timezone_updates timezone_updates_config = TIMEZONE_UPDATES_AUTO;
47 static char *timezone_config = NULL;
48 static char **timeservers_config = NULL;
50 static const char *time_updates2string(enum time_updates value)
53 case TIME_UPDATES_UNKNOWN:
55 case TIME_UPDATES_MANUAL:
57 case TIME_UPDATES_AUTO:
64 static enum time_updates string2time_updates(const char *value)
66 if (g_strcmp0(value, "manual") == 0)
67 return TIME_UPDATES_MANUAL;
68 else if (g_strcmp0(value, "auto") == 0)
69 return TIME_UPDATES_AUTO;
71 return TIME_UPDATES_UNKNOWN;
74 static const char *timezone_updates2string(enum timezone_updates value)
77 case TIMEZONE_UPDATES_UNKNOWN:
79 case TIMEZONE_UPDATES_MANUAL:
81 case TIMEZONE_UPDATES_AUTO:
88 static enum timezone_updates string2timezone_updates(const char *value)
90 if (g_strcmp0(value, "manual") == 0)
91 return TIMEZONE_UPDATES_MANUAL;
92 else if (g_strcmp0(value, "auto") == 0)
93 return TIMEZONE_UPDATES_AUTO;
95 return TIMEZONE_UPDATES_UNKNOWN;
98 static void append_timeservers(DBusMessageIter *iter, void *user_data)
102 if (timeservers_config == NULL)
105 for (i = 0; timeservers_config[i] != NULL; i++) {
106 dbus_message_iter_append_basic(iter,
107 DBUS_TYPE_STRING, ×ervers_config[i]);
111 static DBusMessage *get_properties(DBusConnection *conn,
112 DBusMessage *msg, void *data)
115 DBusMessageIter array, dict;
119 DBG("conn %p", conn);
121 reply = dbus_message_new_method_return(msg);
125 dbus_message_iter_init_append(reply, &array);
127 connman_dbus_dict_open(&array, &dict);
129 if (gettimeofday(&tv, NULL) == 0) {
130 dbus_uint64_t val = tv.tv_sec;
132 connman_dbus_dict_append_basic(&dict, "Time",
133 DBUS_TYPE_UINT64, &val);
136 str = time_updates2string(time_updates_config);
138 connman_dbus_dict_append_basic(&dict, "TimeUpdates",
139 DBUS_TYPE_STRING, &str);
141 if (timezone_config != NULL)
142 connman_dbus_dict_append_basic(&dict, "Timezone",
143 DBUS_TYPE_STRING, &timezone_config);
145 str = timezone_updates2string(timezone_updates_config);
147 connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
148 DBUS_TYPE_STRING, &str);
150 connman_dbus_dict_append_array(&dict, "Timeservers",
151 DBUS_TYPE_STRING, append_timeservers, NULL);
153 connman_dbus_dict_close(&array, &dict);
158 static DBusMessage *set_property(DBusConnection *conn,
159 DBusMessage *msg, void *data)
161 DBusMessageIter iter, value;
165 DBG("conn %p", conn);
167 if (dbus_message_iter_init(msg, &iter) == FALSE)
168 return __connman_error_invalid_arguments(msg);
170 dbus_message_iter_get_basic(&iter, &name);
171 dbus_message_iter_next(&iter);
172 dbus_message_iter_recurse(&iter, &value);
174 type = dbus_message_iter_get_arg_type(&value);
176 if (g_str_equal(name, "Time") == TRUE) {
178 dbus_uint64_t newval;
180 if (type != DBUS_TYPE_UINT64)
181 return __connman_error_invalid_arguments(msg);
183 if (time_updates_config != TIME_UPDATES_MANUAL)
184 return __connman_error_permission_denied(msg);
186 dbus_message_iter_get_basic(&value, &newval);
191 if (settimeofday(&tv, NULL) < 0)
192 return __connman_error_invalid_arguments(msg);
194 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
195 CONNMAN_CLOCK_INTERFACE, "Time",
196 DBUS_TYPE_UINT64, &newval);
197 } else if (g_str_equal(name, "TimeUpdates") == TRUE) {
199 enum time_updates newval;
201 if (type != DBUS_TYPE_STRING)
202 return __connman_error_invalid_arguments(msg);
204 dbus_message_iter_get_basic(&value, &strval);
205 newval = string2time_updates(strval);
207 if (newval == TIME_UPDATES_UNKNOWN)
208 return __connman_error_invalid_arguments(msg);
210 if (newval == time_updates_config)
211 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
213 time_updates_config = newval;
215 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
216 CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
217 DBUS_TYPE_STRING, &strval);
218 } else if (g_str_equal(name, "Timezone") == TRUE) {
221 if (type != DBUS_TYPE_STRING)
222 return __connman_error_invalid_arguments(msg);
224 if (timezone_updates_config != TIMEZONE_UPDATES_MANUAL)
225 return __connman_error_permission_denied(msg);
227 dbus_message_iter_get_basic(&value, &strval);
229 if (__connman_timezone_change(strval) < 0)
230 return __connman_error_invalid_arguments(msg);
231 } else if (g_str_equal(name, "TimezoneUpdates") == TRUE) {
233 enum timezone_updates newval;
235 if (type != DBUS_TYPE_STRING)
236 return __connman_error_invalid_arguments(msg);
238 dbus_message_iter_get_basic(&value, &strval);
239 newval = string2timezone_updates(strval);
241 if (newval == TIMEZONE_UPDATES_UNKNOWN)
242 return __connman_error_invalid_arguments(msg);
244 if (newval == timezone_updates_config)
245 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
247 timezone_updates_config = newval;
249 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
250 CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
251 DBUS_TYPE_STRING, &strval);
252 } else if (g_str_equal(name, "Timeservers") == TRUE) {
253 DBusMessageIter entry;
256 if (type != DBUS_TYPE_ARRAY)
257 return __connman_error_invalid_arguments(msg);
259 str = g_string_new(NULL);
261 return __connman_error_invalid_arguments(msg);
263 dbus_message_iter_recurse(&value, &entry);
265 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
268 dbus_message_iter_get_basic(&entry, &val);
269 dbus_message_iter_next(&entry);
272 g_string_append_printf(str, " %s", val);
274 g_string_append(str, val);
277 g_strfreev(timeservers_config);
280 timeservers_config = g_strsplit_set(str->str, " ", 0);
282 timeservers_config = NULL;
284 g_string_free(str, TRUE);
286 connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
287 CONNMAN_CLOCK_INTERFACE, "Timeservers",
288 DBUS_TYPE_STRING, append_timeservers, NULL);
290 return __connman_error_invalid_property(msg);
292 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
295 static GDBusMethodTable clock_methods[] = {
296 { "GetProperties", "", "a{sv}", get_properties },
297 { "SetProperty", "sv", "", set_property },
301 static GDBusSignalTable clock_signals[] = {
302 { "PropertyChanged", "sv" },
306 static DBusConnection *connection = NULL;
308 void __connman_clock_update_timezone(void)
312 g_free(timezone_config);
313 timezone_config = __connman_timezone_lookup();
315 if (timezone_config == NULL)
318 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
319 CONNMAN_CLOCK_INTERFACE, "Timezone",
320 DBUS_TYPE_STRING, &timezone_config);
323 int __connman_clock_init(void)
327 connection = connman_dbus_get_connection();
328 if (connection == NULL)
331 __connman_timezone_init();
333 timezone_config = __connman_timezone_lookup();
335 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
336 CONNMAN_CLOCK_INTERFACE,
337 clock_methods, clock_signals,
343 void __connman_clock_cleanup(void)
347 if (connection == NULL)
350 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
351 CONNMAN_CLOCK_INTERFACE);
353 dbus_connection_unref(connection);
355 __connman_timezone_cleanup();
357 g_free(timezone_config);
358 g_strfreev(timeservers_config);