5 * Copyright (C) 2007-2009 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 void append_profiles(DBusMessageIter *dict)
32 DBusMessageIter entry, value, iter;
33 const char *key = "Profiles";
35 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
38 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
40 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
41 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
44 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
45 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
46 __connman_profile_list(&iter);
47 dbus_message_iter_close_container(&value, &iter);
49 dbus_message_iter_close_container(&entry, &value);
51 dbus_message_iter_close_container(dict, &entry);
54 static void append_services(DBusMessageIter *dict)
56 DBusMessageIter entry, value, iter;
57 const char *key = "Services";
59 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
62 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
64 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
65 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
68 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
69 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
70 __connman_service_list(&iter);
71 dbus_message_iter_close_container(&value, &iter);
73 dbus_message_iter_close_container(&entry, &value);
75 dbus_message_iter_close_container(dict, &entry);
78 static void append_devices(DBusMessageIter *dict)
80 DBusMessageIter entry, value, iter;
81 const char *key = "Devices";
83 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
86 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
88 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
89 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
92 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
93 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
94 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
95 dbus_message_iter_close_container(&value, &iter);
97 dbus_message_iter_close_container(&entry, &value);
99 dbus_message_iter_close_container(dict, &entry);
102 static void append_connections(DBusMessageIter *dict)
104 DBusMessageIter entry, value, iter;
105 const char *key = "Connections";
107 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
110 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
112 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
113 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
116 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
117 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
118 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
119 dbus_message_iter_close_container(&value, &iter);
121 dbus_message_iter_close_container(&entry, &value);
123 dbus_message_iter_close_container(dict, &entry);
126 static void append_available_technologies(DBusMessageIter *dict)
128 DBusMessageIter entry, value, iter;
129 const char *key = "AvailableTechnologies";
131 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
134 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
136 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
137 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
140 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
141 DBUS_TYPE_STRING_AS_STRING, &iter);
142 __connman_notifier_list_registered(&iter);
143 dbus_message_iter_close_container(&value, &iter);
145 dbus_message_iter_close_container(&entry, &value);
147 dbus_message_iter_close_container(dict, &entry);
150 static void append_enabled_technologies(DBusMessageIter *dict)
152 DBusMessageIter entry, value, iter;
153 const char *key = "EnabledTechnologies";
155 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
158 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
160 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
161 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
164 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
165 DBUS_TYPE_STRING_AS_STRING, &iter);
166 __connman_notifier_list_enabled(&iter);
167 dbus_message_iter_close_container(&value, &iter);
169 dbus_message_iter_close_container(&entry, &value);
171 dbus_message_iter_close_container(dict, &entry);
174 static void append_connected_technologies(DBusMessageIter *dict)
176 DBusMessageIter entry, value, iter;
177 const char *key = "ConnectedTechnologies";
179 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
182 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
184 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
185 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
188 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
189 DBUS_TYPE_STRING_AS_STRING, &iter);
190 __connman_notifier_list_connected(&iter);
191 dbus_message_iter_close_container(&value, &iter);
193 dbus_message_iter_close_container(&entry, &value);
195 dbus_message_iter_close_container(dict, &entry);
198 static void append_available_debugs(DBusMessageIter *dict)
200 DBusMessageIter entry, value, iter;
201 const char *key = "AvailableDebugs";
203 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
206 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
208 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
209 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
212 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
213 DBUS_TYPE_STRING_AS_STRING, &iter);
214 __connman_debug_list_available(&iter);
215 dbus_message_iter_close_container(&value, &iter);
217 dbus_message_iter_close_container(&entry, &value);
219 dbus_message_iter_close_container(dict, &entry);
222 static void append_enabled_debugs(DBusMessageIter *dict)
224 DBusMessageIter entry, value, iter;
225 const char *key = "EnabledDebugs";
227 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
230 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
232 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
233 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
236 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
237 DBUS_TYPE_STRING_AS_STRING, &iter);
238 __connman_debug_list_enabled(&iter);
239 dbus_message_iter_close_container(&value, &iter);
241 dbus_message_iter_close_container(&entry, &value);
243 dbus_message_iter_close_container(dict, &entry);
246 static DBusMessage *get_properties(DBusConnection *conn,
247 DBusMessage *msg, void *data)
250 DBusMessageIter array, dict;
251 connman_bool_t offlinemode;
254 DBG("conn %p", conn);
256 if (__connman_security_check_privilege(msg,
257 CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
258 return __connman_error_permission_denied(msg);
260 reply = dbus_message_new_method_return(msg);
264 dbus_message_iter_init_append(reply, &array);
266 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
267 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
268 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
269 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
271 str = __connman_profile_active_path();
273 connman_dbus_dict_append_variant(&dict, "ActiveProfile",
274 DBUS_TYPE_OBJECT_PATH, &str);
276 append_profiles(&dict);
277 append_services(&dict);
279 append_devices(&dict);
280 append_connections(&dict);
282 if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
287 connman_dbus_dict_append_variant(&dict, "State",
288 DBUS_TYPE_STRING, &str);
290 offlinemode = __connman_profile_get_offlinemode();
291 connman_dbus_dict_append_variant(&dict, "OfflineMode",
292 DBUS_TYPE_BOOLEAN, &offlinemode);
294 append_available_technologies(&dict);
295 append_enabled_technologies(&dict);
296 append_connected_technologies(&dict);
298 str = __connman_service_default();
300 connman_dbus_dict_append_variant(&dict, "DefaultTechnology",
301 DBUS_TYPE_STRING, &str);
303 append_available_debugs(&dict);
304 append_enabled_debugs(&dict);
306 dbus_message_iter_close_container(&array, &dict);
311 static DBusMessage *set_property(DBusConnection *conn,
312 DBusMessage *msg, void *data)
314 DBusMessageIter iter, value;
318 DBG("conn %p", conn);
320 if (dbus_message_iter_init(msg, &iter) == FALSE)
321 return __connman_error_invalid_arguments(msg);
323 dbus_message_iter_get_basic(&iter, &name);
324 dbus_message_iter_next(&iter);
325 dbus_message_iter_recurse(&iter, &value);
327 if (__connman_security_check_privilege(msg,
328 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
329 return __connman_error_permission_denied(msg);
331 type = dbus_message_iter_get_arg_type(&value);
333 if (g_str_equal(name, "OfflineMode") == TRUE) {
334 connman_bool_t offlinemode;
336 if (type != DBUS_TYPE_BOOLEAN)
337 return __connman_error_invalid_arguments(msg);
339 dbus_message_iter_get_basic(&value, &offlinemode);
341 __connman_profile_set_offlinemode(offlinemode);
343 __connman_profile_save_default();
344 } else if (g_str_equal(name, "ActiveProfile") == TRUE) {
347 dbus_message_iter_get_basic(&value, &str);
349 return __connman_error_not_supported(msg);
351 return __connman_error_invalid_property(msg);
353 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
356 static DBusMessage *get_state(DBusConnection *conn,
357 DBusMessage *msg, void *data)
361 DBG("conn %p", conn);
363 if (__connman_security_check_privilege(msg,
364 CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
365 return __connman_error_permission_denied(msg);
367 if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
372 return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str,
376 static DBusMessage *create_profile(DBusConnection *conn,
377 DBusMessage *msg, void *data)
379 const char *name, *path;
382 DBG("conn %p", conn);
384 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
387 if (__connman_security_check_privilege(msg,
388 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
389 return __connman_error_permission_denied(msg);
391 err = __connman_profile_create(name, &path);
393 return __connman_error_failed(msg, -err);
395 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
399 static DBusMessage *remove_profile(DBusConnection *conn,
400 DBusMessage *msg, void *data)
405 DBG("conn %p", conn);
407 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
410 if (__connman_security_check_privilege(msg,
411 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
412 return __connman_error_permission_denied(msg);
414 err = __connman_profile_remove(path);
416 return __connman_error_failed(msg, -err);
418 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
421 static DBusMessage *request_scan(DBusConnection *conn,
422 DBusMessage *msg, void *data)
424 enum connman_service_type type;
428 DBG("conn %p", conn);
430 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
433 if (g_strcmp0(str, "") == 0)
434 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
435 else if (g_strcmp0(str, "wifi") == 0)
436 type = CONNMAN_SERVICE_TYPE_WIFI;
437 else if (g_strcmp0(str, "wimax") == 0)
438 type = CONNMAN_SERVICE_TYPE_WIMAX;
440 return __connman_error_invalid_arguments(msg);
442 err = __connman_element_request_scan(type);
444 if (err == -EINPROGRESS) {
445 connman_error("Invalid return code from scan");
449 return __connman_error_failed(msg, -err);
452 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
455 static DBusConnection *connection = NULL;
457 static enum connman_service_type technology_type;
458 static connman_bool_t technology_enabled;
459 static DBusMessage *technology_pending = NULL;
460 static guint technology_timeout = 0;
462 static void technology_reply(int error)
466 if (technology_timeout > 0) {
467 g_source_remove(technology_timeout);
468 technology_timeout = 0;
471 if (technology_pending != NULL) {
475 reply = __connman_error_failed(technology_pending,
478 g_dbus_send_message(connection, reply);
480 g_dbus_send_reply(connection, technology_pending,
483 dbus_message_unref(technology_pending);
484 technology_pending = NULL;
487 technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
490 static gboolean technology_abort(gpointer user_data)
494 technology_timeout = 0;
496 technology_reply(ETIMEDOUT);
501 static void technology_notify(enum connman_service_type type,
502 connman_bool_t enabled)
504 DBG("type %d enabled %d", type, enabled);
506 if (type == technology_type && enabled == technology_enabled)
510 static struct connman_notifier technology_notifier = {
512 .priority = CONNMAN_NOTIFIER_PRIORITY_HIGH,
513 .service_enabled= technology_notify,
516 static DBusMessage *enable_technology(DBusConnection *conn,
517 DBusMessage *msg, void *data)
519 enum connman_service_type type;
523 DBG("conn %p", conn);
525 if (technology_pending != NULL)
526 return __connman_error_in_progress(msg);
528 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
531 if (g_strcmp0(str, "ethernet") == 0)
532 type = CONNMAN_SERVICE_TYPE_ETHERNET;
533 else if (g_strcmp0(str, "wifi") == 0)
534 type = CONNMAN_SERVICE_TYPE_WIFI;
535 else if (g_strcmp0(str, "wimax") == 0)
536 type = CONNMAN_SERVICE_TYPE_WIMAX;
537 else if (g_strcmp0(str, "bluetooth") == 0)
538 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
539 else if (g_strcmp0(str, "cellular") == 0)
540 type = CONNMAN_SERVICE_TYPE_CELLULAR;
542 return __connman_error_invalid_arguments(msg);
544 if (__connman_notifier_is_enabled(type) == TRUE)
545 return __connman_error_already_enabled(msg);
547 technology_type = type;
548 technology_enabled = TRUE;
549 technology_pending = dbus_message_ref(msg);
551 err = __connman_element_enable_technology(type);
552 if (err < 0 && err != -EINPROGRESS)
553 technology_reply(-err);
555 technology_timeout = g_timeout_add_seconds(15,
556 technology_abort, NULL);
561 static DBusMessage *disable_technology(DBusConnection *conn,
562 DBusMessage *msg, void *data)
564 enum connman_service_type type;
568 DBG("conn %p", conn);
570 if (technology_pending != NULL)
571 return __connman_error_in_progress(msg);
573 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
576 if (g_strcmp0(str, "ethernet") == 0)
577 type = CONNMAN_SERVICE_TYPE_ETHERNET;
578 else if (g_strcmp0(str, "wifi") == 0)
579 type = CONNMAN_SERVICE_TYPE_WIFI;
580 else if (g_strcmp0(str, "wimax") == 0)
581 type = CONNMAN_SERVICE_TYPE_WIMAX;
582 else if (g_strcmp0(str, "bluetooth") == 0)
583 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
584 else if (g_strcmp0(str, "cellular") == 0)
585 type = CONNMAN_SERVICE_TYPE_CELLULAR;
587 return __connman_error_invalid_arguments(msg);
589 if (__connman_notifier_is_enabled(type) == FALSE)
590 return __connman_error_already_disabled(msg);
592 technology_type = type;
593 technology_enabled = FALSE;
594 technology_pending = dbus_message_ref(msg);
596 err = __connman_element_disable_technology(type);
597 if (err < 0 && err != -EINPROGRESS)
598 technology_reply(-err);
600 technology_timeout = g_timeout_add_seconds(10,
601 technology_abort, NULL);
606 static DBusMessage *connect_service(DBusConnection *conn,
607 DBusMessage *msg, void *data)
611 DBG("conn %p", conn);
613 if (__connman_security_check_privilege(msg,
614 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
615 return __connman_error_permission_denied(msg);
617 err = __connman_service_create_and_connect(msg);
619 if (err == -EINPROGRESS) {
620 connman_error("Invalid return code from connect");
624 return __connman_error_failed(msg, -err);
630 static DBusMessage *register_agent(DBusConnection *conn,
631 DBusMessage *msg, void *data)
633 const char *sender, *path;
636 DBG("conn %p", conn);
638 sender = dbus_message_get_sender(msg);
640 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
643 err = __connman_agent_register(sender, path);
645 return __connman_error_failed(msg, -err);
647 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
650 static DBusMessage *unregister_agent(DBusConnection *conn,
651 DBusMessage *msg, void *data)
653 const char *sender, *path;
656 DBG("conn %p", conn);
658 sender = dbus_message_get_sender(msg);
660 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
663 err = __connman_agent_unregister(sender, path);
665 return __connman_error_failed(msg, -err);
667 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
670 static GDBusMethodTable manager_methods[] = {
671 { "GetProperties", "", "a{sv}", get_properties },
672 { "SetProperty", "sv", "", set_property },
673 { "GetState", "", "s", get_state },
674 { "CreateProfile", "s", "o", create_profile },
675 { "RemoveProfile", "o", "", remove_profile },
676 { "RequestScan", "s", "", request_scan },
677 { "EnableTechnology", "s", "", enable_technology,
678 G_DBUS_METHOD_FLAG_ASYNC },
679 { "DisableTechnology", "s", "", disable_technology,
680 G_DBUS_METHOD_FLAG_ASYNC },
681 { "ConnectService", "a{sv}", "o", connect_service,
682 G_DBUS_METHOD_FLAG_ASYNC },
683 { "RegisterAgent", "o", "", register_agent },
684 { "UnregisterAgent", "o", "", unregister_agent },
688 static GDBusSignalTable manager_signals[] = {
689 { "PropertyChanged", "sv" },
690 { "StateChanged", "s" },
694 static DBusMessage *nm_sleep(DBusConnection *conn,
695 DBusMessage *msg, void *data)
699 DBG("conn %p", conn);
701 reply = dbus_message_new_method_return(msg);
705 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
710 static DBusMessage *nm_wake(DBusConnection *conn,
711 DBusMessage *msg, void *data)
715 DBG("conn %p", conn);
717 reply = dbus_message_new_method_return(msg);
721 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
727 NM_STATE_UNKNOWN = 0,
731 NM_STATE_DISCONNECTED
734 static DBusMessage *nm_state(DBusConnection *conn,
735 DBusMessage *msg, void *data)
740 DBG("conn %p", conn);
742 reply = dbus_message_new_method_return(msg);
746 if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
747 state = NM_STATE_CONNECTED;
749 state = NM_STATE_DISCONNECTED;
751 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &state,
757 static GDBusMethodTable nm_methods[] = {
758 { "sleep", "", "", nm_sleep },
759 { "wake", "", "", nm_wake },
760 { "state", "", "u", nm_state },
764 static gboolean nm_compat = FALSE;
766 int __connman_manager_init(gboolean compat)
770 connection = connman_dbus_get_connection();
771 if (connection == NULL)
774 if (connman_notifier_register(&technology_notifier) < 0)
775 connman_error("Failed to register technology notifier");
777 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
778 CONNMAN_MANAGER_INTERFACE,
780 manager_signals, NULL, NULL, NULL);
782 if (compat == TRUE) {
783 g_dbus_register_interface(connection, NM_PATH, NM_INTERFACE,
784 nm_methods, NULL, NULL, NULL, NULL);
792 void __connman_manager_cleanup(void)
796 connman_notifier_unregister(&technology_notifier);
798 if (connection == NULL)
801 if (nm_compat == TRUE) {
802 g_dbus_unregister_interface(connection, NM_PATH, NM_INTERFACE);
805 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
806 CONNMAN_MANAGER_INTERFACE);
808 dbus_connection_unref(connection);