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
32 static DBusMessage *get_properties(DBusConnection *conn,
33 DBusMessage *msg, void *data)
36 DBusMessageIter array, dict;
37 connman_bool_t offlinemode, sessionmode;
42 reply = dbus_message_new_method_return(msg);
46 dbus_message_iter_init_append(reply, &array);
48 connman_dbus_dict_open(&array, &dict);
50 str = __connman_profile_active_path();
52 connman_dbus_dict_append_basic(&dict, "ActiveProfile",
53 DBUS_TYPE_OBJECT_PATH, &str);
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 *remove_provider(DBusConnection *conn,
159 DBusMessage *msg, void *data)
164 DBG("conn %p", conn);
166 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
169 err = __connman_provider_remove(path);
171 return __connman_error_failed(msg, -err);
173 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
176 static DBusMessage *request_scan(DBusConnection *conn,
177 DBusMessage *msg, void *data)
179 enum connman_service_type type;
183 DBG("conn %p", conn);
185 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
188 if (g_strcmp0(str, "") == 0)
189 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
190 else if (g_strcmp0(str, "wifi") == 0)
191 type = CONNMAN_SERVICE_TYPE_WIFI;
192 else if (g_strcmp0(str, "wimax") == 0)
193 type = CONNMAN_SERVICE_TYPE_WIMAX;
195 return __connman_error_invalid_arguments(msg);
197 err = __connman_device_request_scan(type);
199 if (err == -EINPROGRESS) {
200 connman_error("Invalid return code from scan");
204 return __connman_error_failed(msg, -err);
207 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
210 static DBusConnection *connection = NULL;
212 static enum connman_service_type technology_type;
213 static connman_bool_t technology_enabled;
214 static DBusMessage *technology_pending = NULL;
215 static guint technology_timeout = 0;
217 static void technology_reply(int error)
221 if (technology_timeout > 0) {
222 g_source_remove(technology_timeout);
223 technology_timeout = 0;
226 if (technology_pending != NULL) {
230 reply = __connman_error_failed(technology_pending,
233 g_dbus_send_message(connection, reply);
235 g_dbus_send_reply(connection, technology_pending,
238 dbus_message_unref(technology_pending);
239 technology_pending = NULL;
242 technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
245 static gboolean technology_abort(gpointer user_data)
249 technology_timeout = 0;
251 technology_reply(ETIMEDOUT);
256 static void technology_notify(enum connman_service_type type,
257 connman_bool_t enabled)
259 DBG("type %d enabled %d", type, enabled);
261 if (type == technology_type && enabled == technology_enabled)
265 static struct connman_notifier technology_notifier = {
267 .priority = CONNMAN_NOTIFIER_PRIORITY_HIGH,
268 .service_enabled= technology_notify,
271 static DBusMessage *enable_technology(DBusConnection *conn,
272 DBusMessage *msg, void *data)
274 enum connman_service_type type;
278 DBG("conn %p", conn);
280 if (technology_pending != NULL)
281 return __connman_error_in_progress(msg);
283 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
286 if (g_strcmp0(str, "ethernet") == 0)
287 type = CONNMAN_SERVICE_TYPE_ETHERNET;
288 else if (g_strcmp0(str, "wifi") == 0)
289 type = CONNMAN_SERVICE_TYPE_WIFI;
290 else if (g_strcmp0(str, "wimax") == 0)
291 type = CONNMAN_SERVICE_TYPE_WIMAX;
292 else if (g_strcmp0(str, "bluetooth") == 0)
293 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
294 else if (g_strcmp0(str, "cellular") == 0)
295 type = CONNMAN_SERVICE_TYPE_CELLULAR;
297 return __connman_error_invalid_arguments(msg);
299 if (__connman_notifier_is_registered(type) == FALSE)
300 return __connman_error_not_registered(msg);
302 if (__connman_notifier_is_enabled(type) == TRUE)
303 return __connman_error_already_enabled(msg);
305 technology_type = type;
306 technology_enabled = TRUE;
307 technology_pending = dbus_message_ref(msg);
309 err = __connman_device_enable_technology(type);
310 if (err < 0 && err != -EINPROGRESS)
311 technology_reply(-err);
313 technology_timeout = g_timeout_add_seconds(15,
314 technology_abort, NULL);
319 static DBusMessage *disable_technology(DBusConnection *conn,
320 DBusMessage *msg, void *data)
322 enum connman_service_type type;
326 DBG("conn %p", conn);
328 if (technology_pending != NULL)
329 return __connman_error_in_progress(msg);
331 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
334 if (g_strcmp0(str, "ethernet") == 0)
335 type = CONNMAN_SERVICE_TYPE_ETHERNET;
336 else if (g_strcmp0(str, "wifi") == 0)
337 type = CONNMAN_SERVICE_TYPE_WIFI;
338 else if (g_strcmp0(str, "wimax") == 0)
339 type = CONNMAN_SERVICE_TYPE_WIMAX;
340 else if (g_strcmp0(str, "bluetooth") == 0)
341 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
342 else if (g_strcmp0(str, "cellular") == 0)
343 type = CONNMAN_SERVICE_TYPE_CELLULAR;
345 return __connman_error_invalid_arguments(msg);
347 if (__connman_notifier_is_registered(type) == FALSE)
348 return __connman_error_not_registered(msg);
350 if (__connman_notifier_is_enabled(type) == FALSE)
351 return __connman_error_already_disabled(msg);
353 technology_type = type;
354 technology_enabled = FALSE;
355 technology_pending = dbus_message_ref(msg);
357 err = __connman_device_disable_technology(type);
358 if (err < 0 && err != -EINPROGRESS)
359 technology_reply(-err);
361 technology_timeout = g_timeout_add_seconds(10,
362 technology_abort, NULL);
367 static DBusMessage *get_services(DBusConnection *conn,
368 DBusMessage *msg, void *data)
371 DBusMessageIter iter, array;
373 reply = dbus_message_new_method_return(msg);
377 dbus_message_iter_init_append(reply, &iter);
379 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
380 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
381 DBUS_TYPE_OBJECT_PATH_AS_STRING
382 DBUS_TYPE_ARRAY_AS_STRING
383 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
384 DBUS_TYPE_STRING_AS_STRING
385 DBUS_TYPE_VARIANT_AS_STRING
386 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
387 DBUS_STRUCT_END_CHAR_AS_STRING, &array);
389 __connman_service_list_struct(&array);
391 dbus_message_iter_close_container(&iter, &array);
396 static DBusMessage *lookup_service(DBusConnection *conn,
397 DBusMessage *msg, void *data)
399 const char *pattern, *path;
402 DBG("conn %p", conn);
404 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
407 err = __connman_service_lookup(pattern, &path);
409 return __connman_error_failed(msg, -err);
411 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
415 static DBusMessage *connect_service(DBusConnection *conn,
416 DBusMessage *msg, void *data)
420 DBG("conn %p", conn);
422 if (__connman_session_mode() == TRUE) {
423 connman_info("Session mode enabled: "
424 "direct service connect disabled");
426 return __connman_error_failed(msg, -EINVAL);
429 err = __connman_service_create_and_connect(msg);
431 if (err == -EINPROGRESS) {
432 connman_error("Invalid return code from connect");
436 return __connman_error_failed(msg, -err);
442 static DBusMessage *provision_service(DBusConnection *conn, DBusMessage *msg,
447 DBG("conn %p", conn);
449 err = __connman_service_provision(msg);
451 return __connman_error_failed(msg, -err);
456 static DBusMessage *connect_provider(DBusConnection *conn,
457 DBusMessage *msg, void *data)
461 DBG("conn %p", conn);
463 if (__connman_session_mode() == TRUE) {
464 connman_info("Session mode enabled: "
465 "direct provider connect disabled");
467 return __connman_error_failed(msg, -EINVAL);
470 err = __connman_provider_create_and_connect(msg);
472 if (err == -EINPROGRESS) {
473 connman_error("Invalid return code from connect");
477 return __connman_error_failed(msg, -err);
483 static DBusMessage *register_agent(DBusConnection *conn,
484 DBusMessage *msg, void *data)
486 const char *sender, *path;
489 DBG("conn %p", conn);
491 sender = dbus_message_get_sender(msg);
493 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
496 err = __connman_agent_register(sender, path);
498 return __connman_error_failed(msg, -err);
500 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
503 static DBusMessage *unregister_agent(DBusConnection *conn,
504 DBusMessage *msg, void *data)
506 const char *sender, *path;
509 DBG("conn %p", conn);
511 sender = dbus_message_get_sender(msg);
513 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
516 err = __connman_agent_unregister(sender, path);
518 return __connman_error_failed(msg, -err);
520 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
523 static DBusMessage *register_counter(DBusConnection *conn,
524 DBusMessage *msg, void *data)
526 const char *sender, *path;
527 unsigned int accuracy, period;
530 DBG("conn %p", conn);
532 sender = dbus_message_get_sender(msg);
534 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
535 DBUS_TYPE_UINT32, &accuracy,
536 DBUS_TYPE_UINT32, &period,
539 /* FIXME: add handling of accuracy parameter */
541 err = __connman_counter_register(sender, path, period);
543 return __connman_error_failed(msg, -err);
545 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
548 static DBusMessage *unregister_counter(DBusConnection *conn,
549 DBusMessage *msg, void *data)
551 const char *sender, *path;
554 DBG("conn %p", conn);
556 sender = dbus_message_get_sender(msg);
558 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
561 err = __connman_counter_unregister(sender, path);
563 return __connman_error_failed(msg, -err);
565 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
568 static DBusMessage *create_session(DBusConnection *conn,
569 DBusMessage *msg, void *data)
573 DBG("conn %p", conn);
575 err = __connman_session_create(msg);
577 return __connman_error_failed(msg, -err);
579 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
582 static DBusMessage *destroy_session(DBusConnection *conn,
583 DBusMessage *msg, void *data)
587 DBG("conn %p", conn);
589 err = __connman_session_destroy(msg);
591 return __connman_error_failed(msg, -err);
593 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
596 static DBusMessage *request_private_network(DBusConnection *conn,
597 DBusMessage *msg, void *data)
602 DBG("conn %p", conn);
604 sender = dbus_message_get_sender(msg);
606 err = __connman_private_network_request(msg, sender);
608 return __connman_error_failed(msg, -err);
613 static DBusMessage *release_private_network(DBusConnection *conn,
614 DBusMessage *msg, void *data)
619 DBG("conn %p", conn);
621 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
624 err = __connman_private_network_release(path);
626 return __connman_error_failed(msg, -err);
628 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
631 static GDBusMethodTable manager_methods[] = {
632 { "GetProperties", "", "a{sv}", get_properties },
633 { "SetProperty", "sv", "", set_property },
634 { "GetState", "", "s", get_state },
635 { "RemoveProvider", "o", "", remove_provider },
636 { "RequestScan", "s", "", request_scan },
637 { "EnableTechnology", "s", "", enable_technology,
638 G_DBUS_METHOD_FLAG_ASYNC },
639 { "DisableTechnology", "s", "", disable_technology,
640 G_DBUS_METHOD_FLAG_ASYNC },
641 { "GetServices", "", "a(oa{sv})", get_services },
642 { "LookupService", "s", "o", lookup_service, },
643 { "ConnectService", "a{sv}", "o", connect_service,
644 G_DBUS_METHOD_FLAG_ASYNC },
645 { "ProvisionService", "s", "", provision_service,
646 G_DBUS_METHOD_FLAG_ASYNC },
647 { "ConnectProvider", "a{sv}", "o", connect_provider,
648 G_DBUS_METHOD_FLAG_ASYNC },
649 { "RegisterAgent", "o", "", register_agent },
650 { "UnregisterAgent", "o", "", unregister_agent },
651 { "RegisterCounter", "ouu", "", register_counter },
652 { "UnregisterCounter", "o", "", unregister_counter },
653 { "CreateSession", "a{sv}o", "o", create_session },
654 { "DestroySession", "o", "", destroy_session },
655 { "RequestPrivateNetwork", "", "oa{sv}h",
656 request_private_network,
657 G_DBUS_METHOD_FLAG_ASYNC },
658 { "ReleasePrivateNetwork", "o", "",
659 release_private_network },
663 static GDBusSignalTable manager_signals[] = {
664 { "PropertyChanged", "sv" },
665 { "StateChanged", "s" },
669 int __connman_manager_init(void)
673 connection = connman_dbus_get_connection();
674 if (connection == NULL)
677 if (connman_notifier_register(&technology_notifier) < 0)
678 connman_error("Failed to register technology notifier");
680 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
681 CONNMAN_MANAGER_INTERFACE,
683 manager_signals, NULL, NULL, NULL);
688 void __connman_manager_cleanup(void)
692 connman_notifier_unregister(&technology_notifier);
694 if (connection == NULL)
697 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
698 CONNMAN_MANAGER_INTERFACE);
700 dbus_connection_unref(connection);