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
30 static DBusMessage *get_properties(DBusConnection *conn,
31 DBusMessage *msg, void *data)
34 DBusMessageIter array, dict;
35 connman_bool_t offlinemode, sessionmode;
40 reply = dbus_message_new_method_return(msg);
44 dbus_message_iter_init_append(reply, &array);
46 connman_dbus_dict_open(&array, &dict);
48 str = __connman_profile_active_path();
50 connman_dbus_dict_append_basic(&dict, "ActiveProfile",
51 DBUS_TYPE_OBJECT_PATH, &str);
53 connman_dbus_dict_append_array(&dict, "Profiles",
54 DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL);
55 connman_dbus_dict_append_array(&dict, "Services",
56 DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL);
57 connman_dbus_dict_append_array(&dict, "Technologies",
58 DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
60 str = __connman_notifier_get_state();
61 connman_dbus_dict_append_basic(&dict, "State",
62 DBUS_TYPE_STRING, &str);
64 offlinemode = __connman_profile_get_offlinemode();
65 connman_dbus_dict_append_basic(&dict, "OfflineMode",
66 DBUS_TYPE_BOOLEAN, &offlinemode);
68 connman_dbus_dict_append_array(&dict, "AvailableTechnologies",
69 DBUS_TYPE_STRING, __connman_notifier_list_registered, NULL);
70 connman_dbus_dict_append_array(&dict, "EnabledTechnologies",
71 DBUS_TYPE_STRING, __connman_notifier_list_enabled, NULL);
72 connman_dbus_dict_append_array(&dict, "ConnectedTechnologies",
73 DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL);
75 str = __connman_service_default();
77 connman_dbus_dict_append_basic(&dict, "DefaultTechnology",
78 DBUS_TYPE_STRING, &str);
80 connman_dbus_dict_append_array(&dict, "AvailableDebugs",
81 DBUS_TYPE_STRING, __connman_debug_list_available, NULL);
82 connman_dbus_dict_append_array(&dict, "EnabledDebugs",
83 DBUS_TYPE_STRING, __connman_debug_list_enabled, NULL);
85 sessionmode = __connman_session_mode();
86 connman_dbus_dict_append_basic(&dict, "SessionMode",
90 connman_dbus_dict_close(&array, &dict);
95 static DBusMessage *set_property(DBusConnection *conn,
96 DBusMessage *msg, void *data)
98 DBusMessageIter iter, value;
102 DBG("conn %p", conn);
104 if (dbus_message_iter_init(msg, &iter) == FALSE)
105 return __connman_error_invalid_arguments(msg);
107 dbus_message_iter_get_basic(&iter, &name);
108 dbus_message_iter_next(&iter);
109 dbus_message_iter_recurse(&iter, &value);
111 type = dbus_message_iter_get_arg_type(&value);
113 if (g_str_equal(name, "OfflineMode") == TRUE) {
114 connman_bool_t offlinemode;
116 if (type != DBUS_TYPE_BOOLEAN)
117 return __connman_error_invalid_arguments(msg);
119 dbus_message_iter_get_basic(&value, &offlinemode);
121 __connman_profile_set_offlinemode(offlinemode, TRUE);
123 __connman_profile_save_default();
124 } else if (g_str_equal(name, "ActiveProfile") == TRUE) {
127 dbus_message_iter_get_basic(&value, &str);
129 return __connman_error_not_supported(msg);
130 } else if (g_str_equal(name, "SessionMode") == TRUE) {
131 connman_bool_t sessionmode;
133 if (type != DBUS_TYPE_BOOLEAN)
134 return __connman_error_invalid_arguments(msg);
136 dbus_message_iter_get_basic(&value, &sessionmode);
138 __connman_session_set_mode(sessionmode);
140 return __connman_error_invalid_property(msg);
142 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
145 static DBusMessage *get_state(DBusConnection *conn,
146 DBusMessage *msg, void *data)
150 DBG("conn %p", conn);
152 str = __connman_notifier_get_state();
154 return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str,
158 static DBusMessage *create_profile(DBusConnection *conn,
159 DBusMessage *msg, void *data)
161 const char *name, *path;
164 DBG("conn %p", conn);
166 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
169 err = __connman_profile_create(name, &path);
171 return __connman_error_failed(msg, -err);
173 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
177 static DBusMessage *remove_profile(DBusConnection *conn,
178 DBusMessage *msg, void *data)
183 DBG("conn %p", conn);
185 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
188 err = __connman_profile_remove(path);
190 return __connman_error_failed(msg, -err);
192 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
195 static DBusMessage *remove_provider(DBusConnection *conn,
196 DBusMessage *msg, void *data)
201 DBG("conn %p", conn);
203 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
206 err = __connman_provider_remove(path);
208 return __connman_error_failed(msg, -err);
210 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
213 static DBusMessage *request_scan(DBusConnection *conn,
214 DBusMessage *msg, void *data)
216 enum connman_service_type type;
220 DBG("conn %p", conn);
222 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
225 if (g_strcmp0(str, "") == 0)
226 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
227 else if (g_strcmp0(str, "wifi") == 0)
228 type = CONNMAN_SERVICE_TYPE_WIFI;
229 else if (g_strcmp0(str, "wimax") == 0)
230 type = CONNMAN_SERVICE_TYPE_WIMAX;
232 return __connman_error_invalid_arguments(msg);
234 err = __connman_element_request_scan(type);
236 if (err == -EINPROGRESS) {
237 connman_error("Invalid return code from scan");
241 return __connman_error_failed(msg, -err);
244 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
247 static DBusConnection *connection = NULL;
249 static enum connman_service_type technology_type;
250 static connman_bool_t technology_enabled;
251 static DBusMessage *technology_pending = NULL;
252 static guint technology_timeout = 0;
254 static void technology_reply(int error)
258 if (technology_timeout > 0) {
259 g_source_remove(technology_timeout);
260 technology_timeout = 0;
263 if (technology_pending != NULL) {
267 reply = __connman_error_failed(technology_pending,
270 g_dbus_send_message(connection, reply);
272 g_dbus_send_reply(connection, technology_pending,
275 dbus_message_unref(technology_pending);
276 technology_pending = NULL;
279 technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
282 static gboolean technology_abort(gpointer user_data)
286 technology_timeout = 0;
288 technology_reply(ETIMEDOUT);
293 static void technology_notify(enum connman_service_type type,
294 connman_bool_t enabled)
296 DBG("type %d enabled %d", type, enabled);
298 if (type == technology_type && enabled == technology_enabled)
302 static struct connman_notifier technology_notifier = {
304 .priority = CONNMAN_NOTIFIER_PRIORITY_HIGH,
305 .service_enabled= technology_notify,
308 static DBusMessage *enable_technology(DBusConnection *conn,
309 DBusMessage *msg, void *data)
311 enum connman_service_type type;
315 DBG("conn %p", conn);
317 if (technology_pending != NULL)
318 return __connman_error_in_progress(msg);
320 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
323 if (g_strcmp0(str, "ethernet") == 0)
324 type = CONNMAN_SERVICE_TYPE_ETHERNET;
325 else if (g_strcmp0(str, "wifi") == 0)
326 type = CONNMAN_SERVICE_TYPE_WIFI;
327 else if (g_strcmp0(str, "wimax") == 0)
328 type = CONNMAN_SERVICE_TYPE_WIMAX;
329 else if (g_strcmp0(str, "bluetooth") == 0)
330 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
331 else if (g_strcmp0(str, "cellular") == 0)
332 type = CONNMAN_SERVICE_TYPE_CELLULAR;
334 return __connman_error_invalid_arguments(msg);
336 if (__connman_notifier_is_registered(type) == FALSE)
337 return __connman_error_not_registered(msg);
339 if (__connman_notifier_is_enabled(type) == TRUE)
340 return __connman_error_already_enabled(msg);
342 technology_type = type;
343 technology_enabled = TRUE;
344 technology_pending = dbus_message_ref(msg);
346 err = __connman_element_enable_technology(type);
347 if (err < 0 && err != -EINPROGRESS)
348 technology_reply(-err);
350 technology_timeout = g_timeout_add_seconds(15,
351 technology_abort, NULL);
356 static DBusMessage *disable_technology(DBusConnection *conn,
357 DBusMessage *msg, void *data)
359 enum connman_service_type type;
363 DBG("conn %p", conn);
365 if (technology_pending != NULL)
366 return __connman_error_in_progress(msg);
368 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
371 if (g_strcmp0(str, "ethernet") == 0)
372 type = CONNMAN_SERVICE_TYPE_ETHERNET;
373 else if (g_strcmp0(str, "wifi") == 0)
374 type = CONNMAN_SERVICE_TYPE_WIFI;
375 else if (g_strcmp0(str, "wimax") == 0)
376 type = CONNMAN_SERVICE_TYPE_WIMAX;
377 else if (g_strcmp0(str, "bluetooth") == 0)
378 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
379 else if (g_strcmp0(str, "cellular") == 0)
380 type = CONNMAN_SERVICE_TYPE_CELLULAR;
382 return __connman_error_invalid_arguments(msg);
384 if (__connman_notifier_is_registered(type) == FALSE)
385 return __connman_error_not_registered(msg);
387 if (__connman_notifier_is_enabled(type) == FALSE)
388 return __connman_error_already_disabled(msg);
390 technology_type = type;
391 technology_enabled = FALSE;
392 technology_pending = dbus_message_ref(msg);
394 err = __connman_element_disable_technology(type);
395 if (err < 0 && err != -EINPROGRESS)
396 technology_reply(-err);
398 technology_timeout = g_timeout_add_seconds(10,
399 technology_abort, NULL);
404 static DBusMessage *get_services(DBusConnection *conn,
405 DBusMessage *msg, void *data)
408 DBusMessageIter iter, array;
410 reply = dbus_message_new_method_return(msg);
414 dbus_message_iter_init_append(reply, &iter);
416 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
417 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
418 DBUS_TYPE_OBJECT_PATH_AS_STRING
419 DBUS_TYPE_ARRAY_AS_STRING
420 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
421 DBUS_TYPE_STRING_AS_STRING
422 DBUS_TYPE_VARIANT_AS_STRING
423 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
424 DBUS_STRUCT_END_CHAR_AS_STRING, &array);
426 __connman_service_list_struct(&array);
428 dbus_message_iter_close_container(&iter, &array);
433 static DBusMessage *lookup_service(DBusConnection *conn,
434 DBusMessage *msg, void *data)
436 const char *pattern, *path;
439 DBG("conn %p", conn);
441 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
444 err = __connman_service_lookup(pattern, &path);
446 return __connman_error_failed(msg, -err);
448 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
452 static DBusMessage *connect_service(DBusConnection *conn,
453 DBusMessage *msg, void *data)
457 DBG("conn %p", conn);
459 if (__connman_session_mode() == TRUE) {
460 connman_info("Session mode enabled: "
461 "direct service connect disabled");
463 return __connman_error_failed(msg, -EINVAL);
466 err = __connman_service_create_and_connect(msg);
468 if (err == -EINPROGRESS) {
469 connman_error("Invalid return code from connect");
473 return __connman_error_failed(msg, -err);
480 static DBusMessage *connect_provider(DBusConnection *conn,
481 DBusMessage *msg, void *data)
485 DBG("conn %p", conn);
487 if (__connman_session_mode() == TRUE) {
488 connman_info("Session mode enabled: "
489 "direct provider connect disabled");
491 return __connman_error_failed(msg, -EINVAL);
494 err = __connman_provider_create_and_connect(msg);
496 if (err == -EINPROGRESS) {
497 connman_error("Invalid return code from connect");
501 return __connman_error_failed(msg, -err);
507 static DBusMessage *register_agent(DBusConnection *conn,
508 DBusMessage *msg, void *data)
510 const char *sender, *path;
513 DBG("conn %p", conn);
515 sender = dbus_message_get_sender(msg);
517 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
520 err = __connman_agent_register(sender, path);
522 return __connman_error_failed(msg, -err);
524 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
527 static DBusMessage *unregister_agent(DBusConnection *conn,
528 DBusMessage *msg, void *data)
530 const char *sender, *path;
533 DBG("conn %p", conn);
535 sender = dbus_message_get_sender(msg);
537 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
540 err = __connman_agent_unregister(sender, path);
542 return __connman_error_failed(msg, -err);
544 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
547 static DBusMessage *register_counter(DBusConnection *conn,
548 DBusMessage *msg, void *data)
550 const char *sender, *path;
551 unsigned int accuracy, period;
554 DBG("conn %p", conn);
556 sender = dbus_message_get_sender(msg);
558 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
559 DBUS_TYPE_UINT32, &accuracy,
560 DBUS_TYPE_UINT32, &period,
563 /* FIXME: add handling of accuracy parameter */
565 err = __connman_counter_register(sender, path, period);
567 return __connman_error_failed(msg, -err);
569 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
572 static DBusMessage *unregister_counter(DBusConnection *conn,
573 DBusMessage *msg, void *data)
575 const char *sender, *path;
578 DBG("conn %p", conn);
580 sender = dbus_message_get_sender(msg);
582 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
585 err = __connman_counter_unregister(sender, path);
587 return __connman_error_failed(msg, -err);
589 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
592 static DBusMessage *create_session(DBusConnection *conn,
593 DBusMessage *msg, void *data)
597 DBG("conn %p", conn);
599 err = __connman_session_create(msg);
601 return __connman_error_failed(msg, -err);
603 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
606 static DBusMessage *destroy_session(DBusConnection *conn,
607 DBusMessage *msg, void *data)
611 DBG("conn %p", conn);
613 err = __connman_session_destroy(msg);
615 return __connman_error_failed(msg, -err);
617 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
620 static GDBusMethodTable manager_methods[] = {
621 { "GetProperties", "", "a{sv}", get_properties },
622 { "SetProperty", "sv", "", set_property },
623 { "GetState", "", "s", get_state },
624 { "CreateProfile", "s", "o", create_profile },
625 { "RemoveProfile", "o", "", remove_profile },
626 { "RemoveProvider", "o", "", remove_provider },
627 { "RequestScan", "s", "", request_scan },
628 { "EnableTechnology", "s", "", enable_technology,
629 G_DBUS_METHOD_FLAG_ASYNC },
630 { "DisableTechnology", "s", "", disable_technology,
631 G_DBUS_METHOD_FLAG_ASYNC },
632 { "GetServices", "", "a(oa{sv})", get_services },
633 { "LookupService", "s", "o", lookup_service, },
634 { "ConnectService", "a{sv}", "o", connect_service,
635 G_DBUS_METHOD_FLAG_ASYNC },
636 { "ConnectProvider", "a{sv}", "o", connect_provider,
637 G_DBUS_METHOD_FLAG_ASYNC },
638 { "RegisterAgent", "o", "", register_agent },
639 { "UnregisterAgent", "o", "", unregister_agent },
640 { "RegisterCounter", "ouu", "", register_counter },
641 { "UnregisterCounter", "o", "", unregister_counter },
642 { "CreateSession", "a{sv}o", "o", create_session },
643 { "DestroySession", "o", "", destroy_session },
647 static GDBusSignalTable manager_signals[] = {
648 { "PropertyChanged", "sv" },
649 { "StateChanged", "s" },
653 int __connman_manager_init(void)
657 connection = connman_dbus_get_connection();
658 if (connection == NULL)
661 if (connman_notifier_register(&technology_notifier) < 0)
662 connman_error("Failed to register technology notifier");
664 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
665 CONNMAN_MANAGER_INTERFACE,
667 manager_signals, NULL, NULL, NULL);
672 void __connman_manager_cleanup(void)
676 connman_notifier_unregister(&technology_notifier);
678 if (connection == NULL)
681 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
682 CONNMAN_MANAGER_INTERFACE);
684 dbus_connection_unref(connection);