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, tethering;
40 if (__connman_security_check_privilege(msg,
41 CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
42 return __connman_error_permission_denied(msg);
44 reply = dbus_message_new_method_return(msg);
48 dbus_message_iter_init_append(reply, &array);
50 connman_dbus_dict_open(&array, &dict);
52 str = __connman_profile_active_path();
54 connman_dbus_dict_append_basic(&dict, "ActiveProfile",
55 DBUS_TYPE_OBJECT_PATH, &str);
57 connman_dbus_dict_append_array(&dict, "Profiles",
58 DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL);
59 connman_dbus_dict_append_array(&dict, "Services",
60 DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL);
61 connman_dbus_dict_append_array(&dict, "Providers",
62 DBUS_TYPE_OBJECT_PATH, __connman_provider_list, NULL);
63 connman_dbus_dict_append_array(&dict, "Technologies",
64 DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
66 str = __connman_notifier_get_state();
67 connman_dbus_dict_append_basic(&dict, "State",
68 DBUS_TYPE_STRING, &str);
70 offlinemode = __connman_profile_get_offlinemode();
71 connman_dbus_dict_append_basic(&dict, "OfflineMode",
72 DBUS_TYPE_BOOLEAN, &offlinemode);
74 tethering = __connman_tethering_get_status();
75 connman_dbus_dict_append_basic(&dict, "Tethering",
76 DBUS_TYPE_BOOLEAN, &tethering);
78 connman_dbus_dict_append_array(&dict, "AvailableTechnologies",
79 DBUS_TYPE_STRING, __connman_notifier_list_registered, NULL);
80 connman_dbus_dict_append_array(&dict, "EnabledTechnologies",
81 DBUS_TYPE_STRING, __connman_notifier_list_enabled, NULL);
82 connman_dbus_dict_append_array(&dict, "ConnectedTechnologies",
83 DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL);
85 str = __connman_service_default();
87 connman_dbus_dict_append_basic(&dict, "DefaultTechnology",
88 DBUS_TYPE_STRING, &str);
90 connman_dbus_dict_append_array(&dict, "AvailableDebugs",
91 DBUS_TYPE_STRING, __connman_debug_list_available, NULL);
92 connman_dbus_dict_append_array(&dict, "EnabledDebugs",
93 DBUS_TYPE_STRING, __connman_debug_list_enabled, NULL);
95 connman_dbus_dict_close(&array, &dict);
100 static DBusMessage *set_property(DBusConnection *conn,
101 DBusMessage *msg, void *data)
103 DBusMessageIter iter, value;
107 DBG("conn %p", conn);
109 if (dbus_message_iter_init(msg, &iter) == FALSE)
110 return __connman_error_invalid_arguments(msg);
112 dbus_message_iter_get_basic(&iter, &name);
113 dbus_message_iter_next(&iter);
114 dbus_message_iter_recurse(&iter, &value);
116 if (__connman_security_check_privilege(msg,
117 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
118 return __connman_error_permission_denied(msg);
120 type = dbus_message_iter_get_arg_type(&value);
122 if (g_str_equal(name, "OfflineMode") == TRUE) {
123 connman_bool_t offlinemode;
125 if (type != DBUS_TYPE_BOOLEAN)
126 return __connman_error_invalid_arguments(msg);
128 dbus_message_iter_get_basic(&value, &offlinemode);
130 __connman_profile_set_offlinemode(offlinemode);
132 __connman_profile_save_default();
133 } else if (g_str_equal(name, "Tethering") == TRUE) {
134 connman_bool_t tethering;
136 if (type != DBUS_TYPE_BOOLEAN)
137 return __connman_error_invalid_arguments(msg);
139 dbus_message_iter_get_basic(&value, &tethering);
141 if (__connman_tethering_set_status(tethering) < 0)
142 return __connman_error_invalid_arguments(msg);
144 connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
145 CONNMAN_MANAGER_INTERFACE, "Tethering",
146 DBUS_TYPE_BOOLEAN, &tethering);
147 } else if (g_str_equal(name, "ActiveProfile") == TRUE) {
150 dbus_message_iter_get_basic(&value, &str);
152 return __connman_error_not_supported(msg);
154 return __connman_error_invalid_property(msg);
156 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
159 static DBusMessage *get_state(DBusConnection *conn,
160 DBusMessage *msg, void *data)
164 DBG("conn %p", conn);
166 if (__connman_security_check_privilege(msg,
167 CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
168 return __connman_error_permission_denied(msg);
170 str = __connman_notifier_get_state();
172 return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str,
176 static DBusMessage *create_profile(DBusConnection *conn,
177 DBusMessage *msg, void *data)
179 const char *name, *path;
182 DBG("conn %p", conn);
184 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
187 if (__connman_security_check_privilege(msg,
188 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
189 return __connman_error_permission_denied(msg);
191 err = __connman_profile_create(name, &path);
193 return __connman_error_failed(msg, -err);
195 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
199 static DBusMessage *remove_profile(DBusConnection *conn,
200 DBusMessage *msg, void *data)
205 DBG("conn %p", conn);
207 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
210 if (__connman_security_check_privilege(msg,
211 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
212 return __connman_error_permission_denied(msg);
214 err = __connman_profile_remove(path);
216 return __connman_error_failed(msg, -err);
218 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
221 static DBusMessage *remove_provider(DBusConnection *conn,
222 DBusMessage *msg, void *data)
227 DBG("conn %p", conn);
229 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path,
232 if (__connman_security_check_privilege(msg,
233 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
234 return __connman_error_permission_denied(msg);
236 err = __connman_provider_remove(path);
238 return __connman_error_failed(msg, -err);
240 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
243 static DBusMessage *request_scan(DBusConnection *conn,
244 DBusMessage *msg, void *data)
246 enum connman_service_type type;
250 DBG("conn %p", conn);
252 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
255 if (g_strcmp0(str, "") == 0)
256 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
257 else if (g_strcmp0(str, "wifi") == 0)
258 type = CONNMAN_SERVICE_TYPE_WIFI;
259 else if (g_strcmp0(str, "wimax") == 0)
260 type = CONNMAN_SERVICE_TYPE_WIMAX;
262 return __connman_error_invalid_arguments(msg);
264 err = __connman_element_request_scan(type);
266 if (err == -EINPROGRESS) {
267 connman_error("Invalid return code from scan");
271 return __connman_error_failed(msg, -err);
274 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
277 static DBusConnection *connection = NULL;
279 static enum connman_service_type technology_type;
280 static connman_bool_t technology_enabled;
281 static DBusMessage *technology_pending = NULL;
282 static guint technology_timeout = 0;
284 static void technology_reply(int error)
288 if (technology_timeout > 0) {
289 g_source_remove(technology_timeout);
290 technology_timeout = 0;
293 if (technology_pending != NULL) {
297 reply = __connman_error_failed(technology_pending,
300 g_dbus_send_message(connection, reply);
302 g_dbus_send_reply(connection, technology_pending,
305 dbus_message_unref(technology_pending);
306 technology_pending = NULL;
309 technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
312 static gboolean technology_abort(gpointer user_data)
316 technology_timeout = 0;
318 technology_reply(ETIMEDOUT);
323 static void technology_notify(enum connman_service_type type,
324 connman_bool_t enabled)
326 DBG("type %d enabled %d", type, enabled);
328 if (type == technology_type && enabled == technology_enabled)
332 static struct connman_notifier technology_notifier = {
334 .priority = CONNMAN_NOTIFIER_PRIORITY_HIGH,
335 .service_enabled= technology_notify,
338 static DBusMessage *enable_technology(DBusConnection *conn,
339 DBusMessage *msg, void *data)
341 enum connman_service_type type;
345 DBG("conn %p", conn);
347 if (technology_pending != NULL)
348 return __connman_error_in_progress(msg);
350 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
353 if (g_strcmp0(str, "ethernet") == 0)
354 type = CONNMAN_SERVICE_TYPE_ETHERNET;
355 else if (g_strcmp0(str, "wifi") == 0)
356 type = CONNMAN_SERVICE_TYPE_WIFI;
357 else if (g_strcmp0(str, "wimax") == 0)
358 type = CONNMAN_SERVICE_TYPE_WIMAX;
359 else if (g_strcmp0(str, "bluetooth") == 0)
360 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
361 else if (g_strcmp0(str, "cellular") == 0)
362 type = CONNMAN_SERVICE_TYPE_CELLULAR;
364 return __connman_error_invalid_arguments(msg);
366 if (__connman_notifier_is_registered(type) == FALSE)
367 return __connman_error_not_registered(msg);
369 if (__connman_notifier_is_enabled(type) == TRUE)
370 return __connman_error_already_enabled(msg);
372 technology_type = type;
373 technology_enabled = TRUE;
374 technology_pending = dbus_message_ref(msg);
376 err = __connman_element_enable_technology(type);
377 if (err < 0 && err != -EINPROGRESS)
378 technology_reply(-err);
380 technology_timeout = g_timeout_add_seconds(15,
381 technology_abort, NULL);
386 static DBusMessage *disable_technology(DBusConnection *conn,
387 DBusMessage *msg, void *data)
389 enum connman_service_type type;
393 DBG("conn %p", conn);
395 if (technology_pending != NULL)
396 return __connman_error_in_progress(msg);
398 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
401 if (g_strcmp0(str, "ethernet") == 0)
402 type = CONNMAN_SERVICE_TYPE_ETHERNET;
403 else if (g_strcmp0(str, "wifi") == 0)
404 type = CONNMAN_SERVICE_TYPE_WIFI;
405 else if (g_strcmp0(str, "wimax") == 0)
406 type = CONNMAN_SERVICE_TYPE_WIMAX;
407 else if (g_strcmp0(str, "bluetooth") == 0)
408 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
409 else if (g_strcmp0(str, "cellular") == 0)
410 type = CONNMAN_SERVICE_TYPE_CELLULAR;
412 return __connman_error_invalid_arguments(msg);
414 if (__connman_notifier_is_registered(type) == FALSE)
415 return __connman_error_not_registered(msg);
417 if (__connman_notifier_is_enabled(type) == FALSE)
418 return __connman_error_already_disabled(msg);
420 technology_type = type;
421 technology_enabled = FALSE;
422 technology_pending = dbus_message_ref(msg);
424 err = __connman_element_disable_technology(type);
425 if (err < 0 && err != -EINPROGRESS)
426 technology_reply(-err);
428 technology_timeout = g_timeout_add_seconds(10,
429 technology_abort, NULL);
434 static DBusMessage *get_services(DBusConnection *conn,
435 DBusMessage *msg, void *data)
438 DBusMessageIter iter, array;
440 reply = dbus_message_new_method_return(msg);
444 dbus_message_iter_init_append(reply, &iter);
446 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
447 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
448 DBUS_TYPE_OBJECT_PATH_AS_STRING
449 DBUS_TYPE_ARRAY_AS_STRING
450 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
451 DBUS_TYPE_STRING_AS_STRING
452 DBUS_TYPE_VARIANT_AS_STRING
453 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
454 DBUS_STRUCT_END_CHAR_AS_STRING, &array);
456 __connman_service_list_struct(&array);
458 dbus_message_iter_close_container(&iter, &array);
463 static DBusMessage *lookup_service(DBusConnection *conn,
464 DBusMessage *msg, void *data)
466 const char *pattern, *path;
469 DBG("conn %p", conn);
471 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
474 err = __connman_service_lookup(pattern, &path);
476 return __connman_error_failed(msg, -err);
478 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
482 static DBusMessage *connect_service(DBusConnection *conn,
483 DBusMessage *msg, void *data)
487 DBG("conn %p", conn);
489 if (__connman_security_check_privilege(msg,
490 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
491 return __connman_error_permission_denied(msg);
493 err = __connman_service_create_and_connect(msg);
495 if (err == -EINPROGRESS) {
496 connman_error("Invalid return code from connect");
500 return __connman_error_failed(msg, -err);
507 static DBusMessage *connect_provider(DBusConnection *conn,
508 DBusMessage *msg, void *data)
512 DBG("conn %p", conn);
514 if (__connman_security_check_privilege(msg,
515 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
516 return __connman_error_permission_denied(msg);
518 err = __connman_provider_create_and_connect(msg);
520 if (err == -EINPROGRESS) {
521 connman_error("Invalid return code from connect");
525 return __connman_error_failed(msg, -err);
531 static DBusMessage *register_agent(DBusConnection *conn,
532 DBusMessage *msg, void *data)
534 const char *sender, *path;
537 DBG("conn %p", conn);
539 sender = dbus_message_get_sender(msg);
541 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
544 err = __connman_agent_register(sender, path);
546 return __connman_error_failed(msg, -err);
548 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
551 static DBusMessage *unregister_agent(DBusConnection *conn,
552 DBusMessage *msg, void *data)
554 const char *sender, *path;
557 DBG("conn %p", conn);
559 sender = dbus_message_get_sender(msg);
561 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
564 err = __connman_agent_unregister(sender, path);
566 return __connman_error_failed(msg, -err);
568 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
571 static DBusMessage *register_counter(DBusConnection *conn,
572 DBusMessage *msg, void *data)
574 const char *sender, *path;
575 unsigned int accuracy, period;
578 DBG("conn %p", conn);
580 sender = dbus_message_get_sender(msg);
582 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
583 DBUS_TYPE_UINT32, &accuracy,
584 DBUS_TYPE_UINT32, &period,
587 /* FIXME: add handling of accuracy parameter */
589 err = __connman_counter_register(sender, path, period);
591 return __connman_error_failed(msg, -err);
593 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
596 static DBusMessage *unregister_counter(DBusConnection *conn,
597 DBusMessage *msg, void *data)
599 const char *sender, *path;
602 DBG("conn %p", conn);
604 sender = dbus_message_get_sender(msg);
606 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
609 err = __connman_counter_unregister(sender, path);
611 return __connman_error_failed(msg, -err);
613 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
616 static DBusMessage *request_session(DBusConnection *conn,
617 DBusMessage *msg, void *data)
619 const char *bearer, *sender, *service_path;
620 struct connman_service *service;
622 DBG("conn %p", conn);
624 sender = dbus_message_get_sender(msg);
626 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &bearer,
629 service = __connman_session_request(bearer, sender);
631 return __connman_error_failed(msg, EINVAL);
633 service_path = __connman_service_get_path(service);
635 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &service_path,
639 static DBusMessage *release_session(DBusConnection *conn,
640 DBusMessage *msg, void *data)
645 DBG("conn %p", conn);
647 sender = dbus_message_get_sender(msg);
649 err = __connman_session_release(sender);
651 return __connman_error_failed(msg, -err);
653 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
656 static GDBusMethodTable manager_methods[] = {
657 { "GetProperties", "", "a{sv}", get_properties },
658 { "SetProperty", "sv", "", set_property },
659 { "GetState", "", "s", get_state },
660 { "CreateProfile", "s", "o", create_profile },
661 { "RemoveProfile", "o", "", remove_profile },
662 { "RemoveProvider", "s", "", remove_provider },
663 { "RequestScan", "s", "", request_scan },
664 { "EnableTechnology", "s", "", enable_technology,
665 G_DBUS_METHOD_FLAG_ASYNC },
666 { "DisableTechnology", "s", "", disable_technology,
667 G_DBUS_METHOD_FLAG_ASYNC },
668 { "GetServices", "", "a(oa{sv})", get_services },
669 { "LookupService", "s", "o", lookup_service, },
670 { "ConnectService", "a{sv}", "o", connect_service,
671 G_DBUS_METHOD_FLAG_ASYNC },
672 { "ConnectProvider", "a{sv}", "o", connect_provider,
673 G_DBUS_METHOD_FLAG_ASYNC },
674 { "RegisterAgent", "o", "", register_agent },
675 { "UnregisterAgent", "o", "", unregister_agent },
676 { "RegisterCounter", "ouu", "", register_counter },
677 { "UnregisterCounter", "o", "", unregister_counter },
678 { "RequestSession", "s", "o", request_session },
679 { "ReleaseSession", "s", "", release_session },
683 static GDBusSignalTable manager_signals[] = {
684 { "PropertyChanged", "sv" },
685 { "StateChanged", "s" },
689 static DBusMessage *nm_sleep(DBusConnection *conn,
690 DBusMessage *msg, void *data)
694 DBG("conn %p", conn);
696 reply = dbus_message_new_method_return(msg);
700 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
705 static DBusMessage *nm_wake(DBusConnection *conn,
706 DBusMessage *msg, void *data)
710 DBG("conn %p", conn);
712 reply = dbus_message_new_method_return(msg);
716 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
722 NM_STATE_UNKNOWN = 0,
726 NM_STATE_DISCONNECTED
729 static DBusMessage *nm_state(DBusConnection *conn,
730 DBusMessage *msg, void *data)
735 DBG("conn %p", conn);
737 reply = dbus_message_new_method_return(msg);
741 if (__connman_notifier_count_connected() > 0)
742 state = NM_STATE_CONNECTED;
744 state = NM_STATE_DISCONNECTED;
746 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &state,
752 static GDBusMethodTable nm_methods[] = {
753 { "sleep", "", "", nm_sleep },
754 { "wake", "", "", nm_wake },
755 { "state", "", "u", nm_state },
759 static gboolean nm_compat = FALSE;
761 int __connman_manager_init(gboolean compat)
765 connection = connman_dbus_get_connection();
766 if (connection == NULL)
769 if (connman_notifier_register(&technology_notifier) < 0)
770 connman_error("Failed to register technology notifier");
772 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
773 CONNMAN_MANAGER_INTERFACE,
775 manager_signals, NULL, NULL, NULL);
777 if (compat == TRUE) {
778 g_dbus_register_interface(connection, NM_PATH, NM_INTERFACE,
779 nm_methods, NULL, NULL, NULL, NULL);
787 void __connman_manager_cleanup(void)
791 connman_notifier_unregister(&technology_notifier);
793 if (connection == NULL)
796 if (nm_compat == TRUE) {
797 g_dbus_unregister_interface(connection, NM_PATH, NM_INTERFACE);
800 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
801 CONNMAN_MANAGER_INTERFACE);
803 dbus_connection_unref(connection);