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;
49 static const char *time_updates2string(enum time_updates value)
52 case TIME_UPDATES_UNKNOWN:
54 case TIME_UPDATES_MANUAL:
56 case TIME_UPDATES_AUTO:
63 static enum time_updates string2time_updates(const char *value)
65 if (g_strcmp0(value, "manual") == 0)
66 return TIME_UPDATES_MANUAL;
67 else if (g_strcmp0(value, "auto") == 0)
68 return TIME_UPDATES_AUTO;
70 return TIME_UPDATES_UNKNOWN;
73 static const char *timezone_updates2string(enum timezone_updates value)
76 case TIMEZONE_UPDATES_UNKNOWN:
78 case TIMEZONE_UPDATES_MANUAL:
80 case TIMEZONE_UPDATES_AUTO:
87 static enum timezone_updates string2timezone_updates(const char *value)
89 if (g_strcmp0(value, "manual") == 0)
90 return TIMEZONE_UPDATES_MANUAL;
91 else if (g_strcmp0(value, "auto") == 0)
92 return TIMEZONE_UPDATES_AUTO;
94 return TIMEZONE_UPDATES_UNKNOWN;
97 static void append_timeservers(DBusMessageIter *iter, void *user_data)
100 char **timeservers = __connman_timeserver_system_get();
102 if (timeservers == NULL)
105 for (i = 0; timeservers[i] != NULL; i++) {
106 dbus_message_iter_append_basic(iter,
107 DBUS_TYPE_STRING, ×ervers[i]);
110 g_strfreev(timeservers);
113 static DBusMessage *get_properties(DBusConnection *conn,
114 DBusMessage *msg, void *data)
117 DBusMessageIter array, dict;
121 DBG("conn %p", conn);
123 reply = dbus_message_new_method_return(msg);
127 dbus_message_iter_init_append(reply, &array);
129 connman_dbus_dict_open(&array, &dict);
131 if (gettimeofday(&tv, NULL) == 0) {
132 dbus_uint64_t val = tv.tv_sec;
134 connman_dbus_dict_append_basic(&dict, "Time",
135 DBUS_TYPE_UINT64, &val);
138 str = time_updates2string(time_updates_config);
140 connman_dbus_dict_append_basic(&dict, "TimeUpdates",
141 DBUS_TYPE_STRING, &str);
143 if (timezone_config != NULL)
144 connman_dbus_dict_append_basic(&dict, "Timezone",
145 DBUS_TYPE_STRING, &timezone_config);
147 str = timezone_updates2string(timezone_updates_config);
149 connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
150 DBUS_TYPE_STRING, &str);
152 connman_dbus_dict_append_array(&dict, "Timeservers",
153 DBUS_TYPE_STRING, append_timeservers, NULL);
155 connman_dbus_dict_close(&array, &dict);
160 static DBusMessage *set_property(DBusConnection *conn,
161 DBusMessage *msg, void *data)
163 DBusMessageIter iter, value;
167 DBG("conn %p", conn);
169 if (dbus_message_iter_init(msg, &iter) == FALSE)
170 return __connman_error_invalid_arguments(msg);
172 dbus_message_iter_get_basic(&iter, &name);
173 dbus_message_iter_next(&iter);
174 dbus_message_iter_recurse(&iter, &value);
176 type = dbus_message_iter_get_arg_type(&value);
178 if (g_str_equal(name, "Time") == TRUE) {
180 dbus_uint64_t newval;
182 if (type == DBUS_TYPE_VARIANT) {
183 DBusMessageIter variant = value;
184 dbus_message_iter_recurse(&variant, &value);
185 type = dbus_message_iter_get_arg_type(&value);
187 if (type != DBUS_TYPE_UINT64)
188 return __connman_error_invalid_arguments(msg);
190 if (time_updates_config != TIME_UPDATES_MANUAL)
191 return __connman_error_permission_denied(msg);
193 dbus_message_iter_get_basic(&value, &newval);
198 if (settimeofday(&tv, NULL) < 0)
199 return __connman_error_invalid_arguments(msg);
201 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
202 CONNMAN_CLOCK_INTERFACE, "Time",
203 DBUS_TYPE_UINT64, &newval);
204 } else if (g_str_equal(name, "TimeUpdates") == TRUE) {
206 enum time_updates newval;
208 if (type == DBUS_TYPE_VARIANT) {
209 DBusMessageIter variant = value;
210 dbus_message_iter_recurse(&variant, &value);
211 type = dbus_message_iter_get_arg_type(&value);
213 if (type != DBUS_TYPE_STRING)
214 return __connman_error_invalid_arguments(msg);
216 dbus_message_iter_get_basic(&value, &strval);
217 newval = string2time_updates(strval);
219 if (newval == TIME_UPDATES_UNKNOWN)
220 return __connman_error_invalid_arguments(msg);
222 if (newval == time_updates_config)
223 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
225 time_updates_config = newval;
227 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
228 CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
229 DBUS_TYPE_STRING, &strval);
230 } else if (g_str_equal(name, "Timezone") == TRUE) {
233 if (type == DBUS_TYPE_VARIANT) {
234 DBusMessageIter variant = value;
235 dbus_message_iter_recurse(&variant, &value);
236 type = dbus_message_iter_get_arg_type(&value);
238 if (type != DBUS_TYPE_STRING)
239 return __connman_error_invalid_arguments(msg);
241 if (timezone_updates_config != TIMEZONE_UPDATES_MANUAL)
242 return __connman_error_permission_denied(msg);
244 dbus_message_iter_get_basic(&value, &strval);
246 if (__connman_timezone_change(strval) < 0)
247 return __connman_error_invalid_arguments(msg);
248 } else if (g_str_equal(name, "TimezoneUpdates") == TRUE) {
250 enum timezone_updates newval;
252 if (type == DBUS_TYPE_VARIANT) {
253 DBusMessageIter variant = value;
254 dbus_message_iter_recurse(&variant, &value);
255 type = dbus_message_iter_get_arg_type(&value);
257 if (type != DBUS_TYPE_STRING)
258 return __connman_error_invalid_arguments(msg);
260 dbus_message_iter_get_basic(&value, &strval);
261 newval = string2timezone_updates(strval);
263 if (newval == TIMEZONE_UPDATES_UNKNOWN)
264 return __connman_error_invalid_arguments(msg);
266 if (newval == timezone_updates_config)
267 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
269 timezone_updates_config = newval;
271 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
272 CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
273 DBUS_TYPE_STRING, &strval);
274 } else if (g_str_equal(name, "Timeservers") == TRUE) {
275 DBusMessageIter entry;
277 if (type == DBUS_TYPE_VARIANT) {
278 DBusMessageIter variant = value;
279 dbus_message_iter_recurse(&variant, &value);
280 type = dbus_message_iter_get_arg_type(&value);
282 if (type != DBUS_TYPE_ARRAY)
283 return __connman_error_invalid_arguments(msg);
285 dbus_message_iter_recurse(&value, &entry);
287 if (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_INVALID)
288 __connman_timeserver_system_append(NULL);
290 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
293 dbus_message_iter_get_basic(&entry, &val);
294 __connman_timeserver_system_append(val);
295 dbus_message_iter_next(&entry);
298 connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
299 CONNMAN_CLOCK_INTERFACE, "Timeservers",
300 DBUS_TYPE_STRING, append_timeservers, NULL);
302 return __connman_error_invalid_property(msg);
304 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
307 static GDBusMethodTable clock_methods[] = {
308 { "GetProperties", "", "a{sv}", get_properties },
309 { "SetProperty", "sv", "", set_property },
313 static GDBusSignalTable clock_signals[] = {
314 { "PropertyChanged", "sv" },
318 static DBusConnection *connection = NULL;
320 void __connman_clock_update_timezone(void)
324 g_free(timezone_config);
325 timezone_config = __connman_timezone_lookup();
327 if (timezone_config == NULL)
330 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
331 CONNMAN_CLOCK_INTERFACE, "Timezone",
332 DBUS_TYPE_STRING, &timezone_config);
335 int __connman_clock_init(void)
339 connection = connman_dbus_get_connection();
340 if (connection == NULL)
343 __connman_timezone_init();
345 timezone_config = __connman_timezone_lookup();
347 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
348 CONNMAN_CLOCK_INTERFACE,
349 clock_methods, clock_signals,
355 void __connman_clock_cleanup(void)
359 if (connection == NULL)
362 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
363 CONNMAN_CLOCK_INTERFACE);
365 dbus_connection_unref(connection);
367 __connman_timezone_cleanup();
369 g_free(timezone_config);