5 * Copyright (C) 2007-2013 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 #include <connman/agent.h>
34 static bool connman_state_idle;
35 static dbus_bool_t sessionmode;
38 static void append_wifi_vsies_structs(DBusMessageIter *iter, void *user_data)
40 __connman_wifi_vsie_list_struct(iter);
43 static DBusMessage *get_wifi_vsies(DBusConnection *conn,
44 DBusMessage *msg, void *data)
48 DBG("ConnMan, get_wifi_vsies API called");
50 reply = dbus_message_new_method_return(msg);
54 __connman_dbus_append_objpath_dict_array(reply,
55 append_wifi_vsies_structs, NULL);
61 static DBusMessage *get_properties(DBusConnection *conn,
62 DBusMessage *msg, void *data)
65 DBusMessageIter array, dict;
66 dbus_bool_t offlinemode;
71 reply = dbus_message_new_method_return(msg);
75 dbus_message_iter_init_append(reply, &array);
77 connman_dbus_dict_open(&array, &dict);
79 str = __connman_notifier_get_state();
80 connman_dbus_dict_append_basic(&dict, "State",
81 DBUS_TYPE_STRING, &str);
83 offlinemode = __connman_technology_get_offlinemode();
84 connman_dbus_dict_append_basic(&dict, "OfflineMode",
85 DBUS_TYPE_BOOLEAN, &offlinemode);
87 connman_dbus_dict_append_basic(&dict, "SessionMode",
91 connman_dbus_dict_close(&array, &dict);
96 static DBusMessage *set_property(DBusConnection *conn,
97 DBusMessage *msg, void *data)
99 DBusMessageIter iter, value;
103 DBG("conn %p", conn);
105 if (!dbus_message_iter_init(msg, &iter))
106 return __connman_error_invalid_arguments(msg);
108 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
109 return __connman_error_invalid_arguments(msg);
111 dbus_message_iter_get_basic(&iter, &name);
112 dbus_message_iter_next(&iter);
114 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
115 return __connman_error_invalid_arguments(msg);
117 dbus_message_iter_recurse(&iter, &value);
119 type = dbus_message_iter_get_arg_type(&value);
121 if (g_str_equal(name, "OfflineMode")) {
122 dbus_bool_t offlinemode;
124 if (type != DBUS_TYPE_BOOLEAN)
125 return __connman_error_invalid_arguments(msg);
127 dbus_message_iter_get_basic(&value, &offlinemode);
131 if (connman_dbus_get_connection_unix_user_sync(conn,
132 dbus_message_get_sender(msg),
134 DBG("Can not get unix user id!");
135 return __connman_error_permission_denied(msg);
138 if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
139 DBG("Not allow this user to turn on offlinemode now!");
140 return __connman_error_permission_denied(msg);
143 __connman_technology_set_offlinemode(offlinemode);
144 } else if (g_str_equal(name, "SessionMode")) {
146 if (type != DBUS_TYPE_BOOLEAN)
147 return __connman_error_invalid_arguments(msg);
149 dbus_message_iter_get_basic(&value, &sessionmode);
152 return __connman_error_invalid_property(msg);
154 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
157 static void append_technology_structs(DBusMessageIter *iter, void *user_data)
159 __connman_technology_list_struct(iter);
162 static DBusMessage *get_technologies(DBusConnection *conn,
163 DBusMessage *msg, void *data)
167 #if !defined TIZEN_EXT
171 reply = dbus_message_new_method_return(msg);
175 __connman_dbus_append_objpath_dict_array(reply,
176 append_technology_structs, NULL);
181 static DBusMessage *remove_provider(DBusConnection *conn,
182 DBusMessage *msg, void *data)
187 DBG("conn %p", conn);
189 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
192 err = __connman_provider_remove_by_path(path);
194 return __connman_error_failed(msg, -err);
196 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
199 static DBusConnection *connection = NULL;
201 static void idle_state(bool idle)
204 DBG("idle %d", idle);
206 connman_state_idle = idle;
208 if (!connman_state_idle)
212 static struct connman_notifier technology_notifier = {
214 .priority = CONNMAN_NOTIFIER_PRIORITY_HIGH,
215 .idle_state = idle_state,
218 static void append_service_structs(DBusMessageIter *iter, void *user_data)
220 __connman_service_list_struct(iter);
223 static DBusMessage *get_services(DBusConnection *conn,
224 DBusMessage *msg, void *data)
228 reply = dbus_message_new_method_return(msg);
232 __connman_dbus_append_objpath_dict_array(reply,
233 append_service_structs, NULL);
238 static void append_peer_structs(DBusMessageIter *iter, void *user_data)
240 __connman_peer_list_struct(iter);
243 static DBusMessage *get_peers(DBusConnection *conn,
244 DBusMessage *msg, void *data)
248 reply = dbus_message_new_method_return(msg);
252 __connman_dbus_append_objpath_dict_array(reply,
253 append_peer_structs, NULL);
257 static DBusMessage *connect_provider(DBusConnection *conn,
258 DBusMessage *msg, void *data)
262 DBG("conn %p", conn);
264 err = __connman_provider_create_and_connect(msg);
266 return __connman_error_failed(msg, -err);
271 static DBusMessage *register_agent(DBusConnection *conn,
272 DBusMessage *msg, void *data)
274 const char *sender, *path;
277 DBG("conn %p", conn);
279 sender = dbus_message_get_sender(msg);
281 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
284 err = connman_agent_register(sender, path);
286 return __connman_error_failed(msg, -err);
288 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
291 static DBusMessage *unregister_agent(DBusConnection *conn,
292 DBusMessage *msg, void *data)
294 const char *sender, *path;
297 DBG("conn %p", conn);
299 sender = dbus_message_get_sender(msg);
301 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
304 err = connman_agent_unregister(sender, path);
306 return __connman_error_failed(msg, -err);
308 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
311 static DBusMessage *register_counter(DBusConnection *conn,
312 DBusMessage *msg, void *data)
314 const char *sender, *path;
315 unsigned int accuracy, period;
318 DBG("conn %p", conn);
320 sender = dbus_message_get_sender(msg);
322 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
323 DBUS_TYPE_UINT32, &accuracy,
324 DBUS_TYPE_UINT32, &period,
327 /* FIXME: add handling of accuracy parameter */
329 err = __connman_counter_register(sender, path, period);
331 return __connman_error_failed(msg, -err);
333 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
336 static DBusMessage *unregister_counter(DBusConnection *conn,
337 DBusMessage *msg, void *data)
339 const char *sender, *path;
342 DBG("conn %p", conn);
344 sender = dbus_message_get_sender(msg);
346 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
349 err = __connman_counter_unregister(sender, path);
351 return __connman_error_failed(msg, -err);
353 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
356 static DBusMessage *create_session(DBusConnection *conn,
357 DBusMessage *msg, void *data)
361 DBG("conn %p", conn);
363 err = __connman_session_create(msg);
365 if (err == -EINPROGRESS)
368 return __connman_error_failed(msg, -err);
371 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
374 static DBusMessage *destroy_session(DBusConnection *conn,
375 DBusMessage *msg, void *data)
379 DBG("conn %p", conn);
381 err = __connman_session_destroy(msg);
383 return __connman_error_failed(msg, -err);
385 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
388 static DBusMessage *request_private_network(DBusConnection *conn,
389 DBusMessage *msg, void *data)
394 DBG("conn %p", conn);
396 sender = dbus_message_get_sender(msg);
398 err = __connman_private_network_request(msg, sender);
400 return __connman_error_failed(msg, -err);
405 static DBusMessage *release_private_network(DBusConnection *conn,
406 DBusMessage *msg, void *data)
411 DBG("conn %p", conn);
413 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
416 err = __connman_private_network_release(path);
418 return __connman_error_failed(msg, -err);
420 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
423 static int parse_peers_service_specs(DBusMessageIter *array,
424 const unsigned char **spec, int *spec_len,
425 const unsigned char **query, int *query_len,
428 *spec = *query = NULL;
429 *spec_len = *query_len = *version = 0;
431 while (dbus_message_iter_get_arg_type(array) ==
432 DBUS_TYPE_DICT_ENTRY) {
433 DBusMessageIter entry, inter, value;
436 dbus_message_iter_recurse(array, &entry);
437 dbus_message_iter_get_basic(&entry, &key);
439 dbus_message_iter_next(&entry);
441 dbus_message_iter_recurse(&entry, &inter);
443 if (!g_strcmp0(key, "BonjourResponse")) {
444 dbus_message_iter_recurse(&inter, &value);
445 dbus_message_iter_get_fixed_array(&value,
447 } else if (!g_strcmp0(key, "BonjourQuery")) {
448 dbus_message_iter_recurse(&inter, &value);
449 dbus_message_iter_get_fixed_array(&value,
451 } else if (!g_strcmp0(key, "UpnpService")) {
452 dbus_message_iter_get_basic(&inter, spec);
453 *spec_len = strlen((const char *)*spec)+1;
454 } else if (!g_strcmp0(key, "UpnpVersion")) {
455 dbus_message_iter_get_basic(&inter, version);
456 } else if (!g_strcmp0(key, "WiFiDisplayIEs")) {
460 dbus_message_iter_recurse(&inter, &value);
461 dbus_message_iter_get_fixed_array(&value,
466 dbus_message_iter_next(array);
469 if ((*query && !*spec && !*version) ||
470 (!*spec && !*query) || (!*spec && *version))
476 static DBusMessage *register_peer_service(DBusConnection *conn,
477 DBusMessage *msg, void *data)
479 const unsigned char *spec, *query;
480 DBusMessageIter iter, array;
481 int spec_len, query_len;
489 owner = dbus_message_get_sender(msg);
491 dbus_message_iter_init(msg, &iter);
492 dbus_message_iter_recurse(&iter, &array);
494 ret = parse_peers_service_specs(&array, &spec, &spec_len,
495 &query, &query_len, &version);
499 dbus_message_iter_next(&iter);
500 dbus_message_iter_get_basic(&iter, &master);
502 ret = __connman_peer_service_register(owner, msg, spec, spec_len,
503 query, query_len, version,master);
505 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
506 if (ret == -EINPROGRESS)
509 return __connman_error_failed(msg, -ret);
512 static DBusMessage *unregister_peer_service(DBusConnection *conn,
513 DBusMessage *msg, void *data)
515 const unsigned char *spec, *query;
516 DBusMessageIter iter, array;
517 int spec_len, query_len;
524 owner = dbus_message_get_sender(msg);
526 dbus_message_iter_init(msg, &iter);
527 dbus_message_iter_recurse(&iter, &array);
529 ret = parse_peers_service_specs(&array, &spec, &spec_len,
530 &query, &query_len, &version);
534 ret = __connman_peer_service_unregister(owner, spec, spec_len,
535 query, query_len, version);
537 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
539 return __connman_error_failed(msg, -ret);
543 static const GDBusMethodTable manager_methods[] = {
544 { GDBUS_METHOD("GetProperties",
545 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
547 { GDBUS_ASYNC_METHOD("SetProperty",
548 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
549 NULL, set_property) },
550 { GDBUS_METHOD("GetTechnologies",
551 NULL, GDBUS_ARGS({ "technologies", "a(oa{sv})" }),
553 { GDBUS_DEPRECATED_METHOD("RemoveProvider",
554 GDBUS_ARGS({ "provider", "o" }), NULL,
556 { GDBUS_METHOD("GetServices",
557 NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
559 { GDBUS_METHOD("GetPeers",
560 NULL, GDBUS_ARGS({ "peers", "a(oa{sv})" }),
562 { GDBUS_DEPRECATED_ASYNC_METHOD("ConnectProvider",
563 GDBUS_ARGS({ "provider", "a{sv}" }),
564 GDBUS_ARGS({ "path", "o" }),
566 { GDBUS_METHOD("RegisterAgent",
567 GDBUS_ARGS({ "path", "o" }), NULL,
569 { GDBUS_METHOD("UnregisterAgent",
570 GDBUS_ARGS({ "path", "o" }), NULL,
572 { GDBUS_METHOD("RegisterCounter",
573 GDBUS_ARGS({ "path", "o" }, { "accuracy", "u" },
575 NULL, register_counter) },
576 { GDBUS_METHOD("UnregisterCounter",
577 GDBUS_ARGS({ "path", "o" }), NULL,
578 unregister_counter) },
579 { GDBUS_ASYNC_METHOD("CreateSession",
580 GDBUS_ARGS({ "settings", "a{sv}" },
581 { "notifier", "o" }),
582 GDBUS_ARGS({ "session", "o" }),
584 { GDBUS_METHOD("DestroySession",
585 GDBUS_ARGS({ "session", "o" }), NULL,
587 { GDBUS_ASYNC_METHOD("RequestPrivateNetwork",
588 NULL, GDBUS_ARGS({ "path", "o" },
589 { "settings", "a{sv}" },
591 request_private_network) },
592 { GDBUS_METHOD("ReleasePrivateNetwork",
593 GDBUS_ARGS({ "path", "o" }), NULL,
594 release_private_network) },
595 { GDBUS_ASYNC_METHOD("RegisterPeerService",
596 GDBUS_ARGS({ "specification", "a{sv}" },
597 { "master", "b" }), NULL,
598 register_peer_service) },
599 { GDBUS_METHOD("UnregisterPeerService",
600 GDBUS_ARGS({ "specification", "a{sv}" }), NULL,
601 unregister_peer_service) },
602 #if defined TIZEN_EXT
603 { GDBUS_METHOD("GetVsies",
604 NULL, GDBUS_ARGS({ "Vsie", "a(oa{sv})" }),
610 static const GDBusSignalTable manager_signals[] = {
611 { GDBUS_SIGNAL("PropertyChanged",
612 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
613 { GDBUS_SIGNAL("TechnologyAdded",
614 GDBUS_ARGS({ "path", "o" },
615 { "properties", "a{sv}" })) },
616 { GDBUS_SIGNAL("TechnologyRemoved",
617 GDBUS_ARGS({ "path", "o" })) },
618 { GDBUS_SIGNAL("ServicesChanged",
619 GDBUS_ARGS({ "changed", "a(oa{sv})" },
620 { "removed", "ao" })) },
621 { GDBUS_SIGNAL("PeersChanged",
622 GDBUS_ARGS({ "changed", "a(oa{sv})" },
623 { "removed", "ao" })) },
627 int __connman_manager_init(void)
631 connection = connman_dbus_get_connection();
635 if (connman_notifier_register(&technology_notifier) < 0)
636 connman_error("Failed to register technology notifier");
638 g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
639 CONNMAN_MANAGER_INTERFACE,
641 manager_signals, NULL, NULL, NULL);
643 connman_state_idle = true;
648 void __connman_manager_cleanup(void)
655 connman_notifier_unregister(&technology_notifier);
657 g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
658 CONNMAN_MANAGER_INTERFACE);
660 dbus_connection_unref(connection);