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
38 static gboolean nm_compat = FALSE;
40 static DBusMessage *get_properties(DBusConnection *conn,
41 DBusMessage *msg, void *data)
44 DBusMessageIter array, dict;
45 connman_bool_t offlinemode, tethering;
50 reply = dbus_message_new_method_return(msg);
54 dbus_message_iter_init_append(reply, &array);
56 connman_dbus_dict_open(&array, &dict);
58 str = __connman_profile_active_path();
60 connman_dbus_dict_append_basic(&dict, "ActiveProfile",
61 DBUS_TYPE_OBJECT_PATH, &str);
63 connman_dbus_dict_append_array(&dict, "Profiles",
64 DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL);
65 connman_dbus_dict_append_array(&dict, "Services",
66 DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL);
67 connman_dbus_dict_append_array(&dict, "Technologies",
68 DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
70 str = __connman_notifier_get_state();
71 connman_dbus_dict_append_basic(&dict, "State",
72 DBUS_TYPE_STRING, &str);
74 offlinemode = __connman_profile_get_offlinemode();
75 connman_dbus_dict_append_basic(&dict, "OfflineMode",
76 DBUS_TYPE_BOOLEAN, &offlinemode);
78 tethering = __connman_tethering_get_status();
79 connman_dbus_dict_append_basic(&dict, "Tethering",
80 DBUS_TYPE_BOOLEAN, &tethering);
82 connman_dbus_dict_append_array(&dict, "AvailableTechnologies",
83 DBUS_TYPE_STRING, __connman_notifier_list_registered, NULL);
84 connman_dbus_dict_append_array(&dict, "EnabledTechnologies",
85 DBUS_TYPE_STRING, __connman_notifier_list_enabled, NULL);
86 connman_dbus_dict_append_array(&dict, "ConnectedTechnologies",
87 DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL);
89 str = __connman_service_default();
91 connman_dbus_dict_append_basic(&dict, "DefaultTechnology",
92 DBUS_TYPE_STRING, &str);
94 connman_dbus_dict_append_array(&dict, "AvailableDebugs",
95 DBUS_TYPE_STRING, __connman_debug_list_available, NULL);
96 connman_dbus_dict_append_array(&dict, "EnabledDebugs",
97 DBUS_TYPE_STRING, __connman_debug_list_enabled, NULL);
99 connman_dbus_dict_close(&array, &dict);
104 static DBusMessage *set_property(DBusConnection *conn,
105 DBusMessage *msg, void *data)
107 DBusMessageIter iter, value;
111 DBG("conn %p", conn);
113 if (dbus_message_iter_init(msg, &iter) == FALSE)
114 return __connman_error_invalid_arguments(msg);
116 dbus_message_iter_get_basic(&iter, &name);
117 dbus_message_iter_next(&iter);
118 dbus_message_iter_recurse(&iter, &value);
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, TRUE);
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 str = __connman_notifier_get_state();
168 return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str,
172 static DBusMessage *create_profile(DBusConnection *conn,
173 DBusMessage *msg, void *data)
175 const char *name, *path;
178 DBG("conn %p", conn);
180 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
183 err = __connman_profile_create(name, &path);
185 return __connman_error_failed(msg, -err);
187 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
191 static DBusMessage *remove_profile(DBusConnection *conn,
192 DBusMessage *msg, void *data)
197 DBG("conn %p", conn);
199 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
202 err = __connman_profile_remove(path);
204 return __connman_error_failed(msg, -err);
206 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
209 static DBusMessage *remove_provider(DBusConnection *conn,
210 DBusMessage *msg, void *data)
215 DBG("conn %p", conn);
217 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
220 err = __connman_provider_remove(path);
222 return __connman_error_failed(msg, -err);
224 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
227 static DBusMessage *request_scan(DBusConnection *conn,
228 DBusMessage *msg, void *data)
230 enum connman_service_type type;
234 DBG("conn %p", conn);
236 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
239 if (g_strcmp0(str, "") == 0)
240 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
241 else if (g_strcmp0(str, "wifi") == 0)
242 type = CONNMAN_SERVICE_TYPE_WIFI;
243 else if (g_strcmp0(str, "wimax") == 0)
244 type = CONNMAN_SERVICE_TYPE_WIMAX;
246 return __connman_error_invalid_arguments(msg);
248 err = __connman_element_request_scan(type);
250 if (err == -EINPROGRESS) {
251 connman_error("Invalid return code from scan");
255 return __connman_error_failed(msg, -err);
258 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
261 static DBusConnection *connection = NULL;
263 static enum connman_service_type technology_type;
264 static connman_bool_t technology_enabled;
265 static DBusMessage *technology_pending = NULL;
266 static guint technology_timeout = 0;
268 static void technology_reply(int error)
272 if (technology_timeout > 0) {
273 g_source_remove(technology_timeout);
274 technology_timeout = 0;
277 if (technology_pending != NULL) {
281 reply = __connman_error_failed(technology_pending,
284 g_dbus_send_message(connection, reply);
286 g_dbus_send_reply(connection, technology_pending,
289 dbus_message_unref(technology_pending);
290 technology_pending = NULL;
293 technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
296 static gboolean technology_abort(gpointer user_data)
300 technology_timeout = 0;
302 technology_reply(ETIMEDOUT);
307 static void technology_notify(enum connman_service_type type,
308 connman_bool_t enabled)
310 DBG("type %d enabled %d", type, enabled);
312 if (type == technology_type && enabled == technology_enabled)
316 static void nm_send_signal(const char *name, dbus_uint32_t state)
320 signal = dbus_message_new_signal(NM_PATH, NM_INTERFACE, name);
324 dbus_message_append_args(signal, DBUS_TYPE_UINT32, &state,
327 g_dbus_send_message(connection, signal);
330 static void default_changed(struct connman_service *service)
338 state = NM_STATE_CONNECTED;
340 state = NM_STATE_DISCONNECTED;
342 DBG("%p %d", service, state);
344 /* older deprecated signal, in case applications still use this */
345 nm_send_signal("StateChange", state);
347 /* the preferred current signal */
348 nm_send_signal("StateChanged", state);
351 static struct connman_notifier technology_notifier = {
353 .priority = CONNMAN_NOTIFIER_PRIORITY_HIGH,
354 .service_enabled= technology_notify,
355 .default_changed= default_changed,
358 static DBusMessage *enable_technology(DBusConnection *conn,
359 DBusMessage *msg, void *data)
361 enum connman_service_type type;
365 DBG("conn %p", conn);
367 if (technology_pending != NULL)
368 return __connman_error_in_progress(msg);
370 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
373 if (g_strcmp0(str, "ethernet") == 0)
374 type = CONNMAN_SERVICE_TYPE_ETHERNET;
375 else if (g_strcmp0(str, "wifi") == 0)
376 type = CONNMAN_SERVICE_TYPE_WIFI;
377 else if (g_strcmp0(str, "wimax") == 0)
378 type = CONNMAN_SERVICE_TYPE_WIMAX;
379 else if (g_strcmp0(str, "bluetooth") == 0)
380 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
381 else if (g_strcmp0(str, "cellular") == 0)
382 type = CONNMAN_SERVICE_TYPE_CELLULAR;
384 return __connman_error_invalid_arguments(msg);
386 if (__connman_notifier_is_registered(type) == FALSE)
387 return __connman_error_not_registered(msg);
389 if (__connman_notifier_is_enabled(type) == TRUE)
390 return __connman_error_already_enabled(msg);
392 technology_type = type;
393 technology_enabled = TRUE;
394 technology_pending = dbus_message_ref(msg);
396 err = __connman_element_enable_technology(type);
397 if (err < 0 && err != -EINPROGRESS)
398 technology_reply(-err);
400 technology_timeout = g_timeout_add_seconds(15,
401 technology_abort, NULL);
406 static DBusMessage *disable_technology(DBusConnection *conn,
407 DBusMessage *msg, void *data)
409 enum connman_service_type type;
413 DBG("conn %p", conn);
415 if (technology_pending != NULL)
416 return __connman_error_in_progress(msg);
418 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
421 if (g_strcmp0(str, "ethernet") == 0)
422 type = CONNMAN_SERVICE_TYPE_ETHERNET;
423 else if (g_strcmp0(str, "wifi") == 0)
424 type = CONNMAN_SERVICE_TYPE_WIFI;
425 else if (g_strcmp0(str, "wimax") == 0)
426 type = CONNMAN_SERVICE_TYPE_WIMAX;
427 else if (g_strcmp0(str, "bluetooth") == 0)
428 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
429 else if (g_strcmp0(str, "cellular") == 0)
430 type = CONNMAN_SERVICE_TYPE_CELLULAR;
432 return __connman_error_invalid_arguments(msg);
434 if (__connman_notifier_is_registered(type) == FALSE)
435 return __connman_error_not_registered(msg);
437 if (__connman_notifier_is_enabled(type) == FALSE)
438 return __connman_error_already_disabled(msg);
440 technology_type = type;
441 technology_enabled = FALSE;
442 technology_pending = dbus_message_ref(msg);
444 err = __connman_element_disable_technology(type);
445 if (err < 0 && err != -EINPROGRESS)
446 technology_reply(-err);
448 technology_timeout = g_timeout_add_seconds(10,
449 technology_abort, NULL);
454 static DBusMessage *get_services(DBusConnection *conn,
455 DBusMessage *msg, void *data)
458 DBusMessageIter iter, array;
460 reply = dbus_message_new_method_return(msg);
464 dbus_message_iter_init_append(reply, &iter);
466 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
467 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
468 DBUS_TYPE_OBJECT_PATH_AS_STRING
469 DBUS_TYPE_ARRAY_AS_STRING
470 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
471 DBUS_TYPE_STRING_AS_STRING
472 DBUS_TYPE_VARIANT_AS_STRING
473 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
474 DBUS_STRUCT_END_CHAR_AS_STRING, &array);
476 __connman_service_list_struct(&array);
478 dbus_message_iter_close_container(&iter, &array);
483 static DBusMessage *lookup_service(DBusConnection *conn,
484 DBusMessage *msg, void *data)
486 const char *pattern, *path;
489 DBG("conn %p", conn);
491 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
494 err = __connman_service_lookup(pattern, &path);
496 return __connman_error_failed(msg, -err);
498 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
502 static DBusMessage *connect_service(DBusConnection *conn,
503 DBusMessage *msg, void *data)
507 DBG("conn %p", conn);
509 err = __connman_service_create_and_connect(msg);
511 if (err == -EINPROGRESS) {
512 connman_error("Invalid return code from connect");
516 return __connman_error_failed(msg, -err);
523 static DBusMessage *connect_provider(DBusConnection *conn,
524 DBusMessage *msg, void *data)
528 DBG("conn %p", conn);
530 err = __connman_provider_create_and_connect(msg);
532 if (err == -EINPROGRESS) {
533 connman_error("Invalid return code from connect");
537 return __connman_error_failed(msg, -err);
543 static DBusMessage *register_agent(DBusConnection *conn,
544 DBusMessage *msg, void *data)
546 const char *sender, *path;
549 DBG("conn %p", conn);
551 sender = dbus_message_get_sender(msg);
553 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
556 err = __connman_agent_register(sender, path);
558 return __connman_error_failed(msg, -err);
560 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
563 static DBusMessage *unregister_agent(DBusConnection *conn,
564 DBusMessage *msg, void *data)
566 const char *sender, *path;
569 DBG("conn %p", conn);
571 sender = dbus_message_get_sender(msg);
573 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
576 err = __connman_agent_unregister(sender, path);
578 return __connman_error_failed(msg, -err);
580 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
583 static DBusMessage *register_counter(DBusConnection *conn,
584 DBusMessage *msg, void *data)
586 const char *sender, *path;
587 unsigned int accuracy, period;
590 DBG("conn %p", conn);
592 sender = dbus_message_get_sender(msg);
594 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
595 DBUS_TYPE_UINT32, &accuracy,
596 DBUS_TYPE_UINT32, &period,
599 /* FIXME: add handling of accuracy parameter */
601 err = __connman_counter_register(sender, path, period);
603 return __connman_error_failed(msg, -err);
605 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
608 static DBusMessage *unregister_counter(DBusConnection *conn,
609 DBusMessage *msg, void *data)
611 const char *sender, *path;
614 DBG("conn %p", conn);
616 sender = dbus_message_get_sender(msg);
618 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
621 err = __connman_counter_unregister(sender, path);
623 return __connman_error_failed(msg, -err);
625 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
628 static DBusMessage *request_session(DBusConnection *conn,
629 DBusMessage *msg, void *data)
631 const char *bearer, *sender, *service_path;
632 struct connman_service *service;
634 DBG("conn %p", conn);
636 sender = dbus_message_get_sender(msg);
638 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &bearer,
641 service = __connman_session_request(bearer, sender);
643 return __connman_error_failed(msg, EINVAL);
645 service_path = __connman_service_get_path(service);
647 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &service_path,
651 static DBusMessage *release_session(DBusConnection *conn,
652 DBusMessage *msg, void *data)
657 DBG("conn %p", conn);
659 sender = dbus_message_get_sender(msg);
661 err = __connman_session_release(sender);
663 return __connman_error_failed(msg, -err);
665 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
668 static GDBusMethodTable manager_methods[] = {
669 { "GetProperties", "", "a{sv}", get_properties },
670 { "SetProperty", "sv", "", set_property },
671 { "GetState", "", "s", get_state },
672 { "CreateProfile", "s", "o", create_profile },
673 { "RemoveProfile", "o", "", remove_profile },
674 { "RemoveProvider", "o", "", remove_provider },
675 { "RequestScan", "s", "", request_scan },
676 { "EnableTechnology", "s", "", enable_technology,
677 G_DBUS_METHOD_FLAG_ASYNC },
678 { "DisableTechnology", "s", "", disable_technology,
679 G_DBUS_METHOD_FLAG_ASYNC },
680 { "GetServices", "", "a(oa{sv})", get_services },
681 { "LookupService", "s", "o", lookup_service, },
682 { "ConnectService", "a{sv}", "o", connect_service,
683 G_DBUS_METHOD_FLAG_ASYNC },
684 { "ConnectProvider", "a{sv}", "o", connect_provider,
685 G_DBUS_METHOD_FLAG_ASYNC },
686 { "RegisterAgent", "o", "", register_agent },
687 { "UnregisterAgent", "o", "", unregister_agent },
688 { "RegisterCounter", "ouu", "", register_counter },
689 { "UnregisterCounter", "o", "", unregister_counter },
690 { "RequestSession", "s", "o", request_session },
691 { "ReleaseSession", "s", "", release_session },
695 static GDBusSignalTable manager_signals[] = {
696 { "PropertyChanged", "sv" },
697 { "StateChanged", "s" },
701 static DBusMessage *nm_sleep(DBusConnection *conn,
702 DBusMessage *msg, void *data)
706 DBG("conn %p", conn);
708 reply = dbus_message_new_method_return(msg);
712 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
717 static DBusMessage *nm_wake(DBusConnection *conn,
718 DBusMessage *msg, void *data)
722 DBG("conn %p", conn);
724 reply = dbus_message_new_method_return(msg);
728 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
733 static DBusMessage *nm_state(DBusConnection *conn,
734 DBusMessage *msg, void *data)
739 DBG("conn %p", conn);
741 reply = dbus_message_new_method_return(msg);
745 if (__connman_notifier_count_connected() > 0)
746 state = NM_STATE_CONNECTED;
748 state = NM_STATE_DISCONNECTED;
750 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &state,
756 static GDBusMethodTable nm_methods[] = {
757 { "sleep", "", "", nm_sleep },
758 { "wake", "", "", nm_wake },
759 { "state", "", "u", nm_state },
763 int __connman_manager_init(gboolean compat)
767 connection = connman_dbus_get_connection();
768 if (connection == NULL)
771 if (connman_notifier_register(&technology_notifier) < 0)
772 connman_error("Failed to register technology notifier");
774 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
775 CONNMAN_MANAGER_INTERFACE,
777 manager_signals, NULL, NULL, NULL);
779 if (compat == TRUE) {
780 g_dbus_register_interface(connection, NM_PATH, NM_INTERFACE,
781 nm_methods, NULL, NULL, NULL, NULL);
789 void __connman_manager_cleanup(void)
793 connman_notifier_unregister(&technology_notifier);
795 if (connection == NULL)
798 if (nm_compat == TRUE) {
799 g_dbus_unregister_interface(connection, NM_PATH, NM_INTERFACE);
802 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
803 CONNMAN_MANAGER_INTERFACE);
805 dbus_connection_unref(connection);