X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=plugins%2Fbluetooth.c;h=9e1aaa2c26a97c4be6e31f9afe38e701611349a3;hb=091f5fa9229897a52424cd442b325f97d361dbc3;hp=9a73e96f1e063c1b109a3415e7be2aba93c8c0e8;hpb=b8015e1eddca7c246826f74e6a06fb3da1b011d4;p=framework%2Fconnectivity%2Fconnman.git diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c index 9a73e96..9e1aaa2 100644 --- a/plugins/bluetooth.c +++ b/plugins/bluetooth.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -99,7 +99,8 @@ static void connect_reply(DBusPendingCall *call, void *user_data) if (dbus_set_error_from_message(&error, reply) == TRUE) { connman_error("%s", error.message); dbus_error_free(&error); - goto done; + + goto err; } if (dbus_message_get_args(reply, &error, @@ -110,11 +111,11 @@ static void connect_reply(DBusPendingCall *call, void *user_data) dbus_error_free(&error); } else connman_error("Wrong arguments for connect"); - goto done; + goto err; } if (interface == NULL) - goto done; + goto err; DBG("interface %s", interface); @@ -124,7 +125,15 @@ static void connect_reply(DBusPendingCall *call, void *user_data) connman_network_set_connected(network, TRUE); -done: + dbus_message_unref(reply); + + dbus_pending_call_unref(call); + + return; +err: + + connman_network_set_connected(network, FALSE); + dbus_message_unref(reply); dbus_pending_call_unref(call); @@ -437,7 +446,7 @@ static void network_properties_reply(DBusPendingCall *call, void *user_data) connman_network_set_group(network, ident); - g_hash_table_insert(bluetooth_networks, g_strdup(path), network); + g_hash_table_replace(bluetooth_networks, g_strdup(path), network); done: dbus_message_unref(reply); @@ -540,7 +549,7 @@ static gboolean adapter_changed(DBusConnection *connection, static gboolean device_removed(DBusConnection *connection, DBusMessage *message, void *user_data) { - const char *network_path, *identifier; + const char *network_path; struct connman_network *network; struct connman_device *device; DBusMessageIter iter; @@ -560,12 +569,8 @@ static gboolean device_removed(DBusConnection *connection, if (device == NULL) return TRUE; - identifier = connman_network_get_identifier(network); - g_hash_table_remove(bluetooth_networks, network_path); - connman_device_remove_network(device, identifier); - return TRUE; } @@ -594,6 +599,36 @@ static gboolean device_changed(DBusConnection *connection, return TRUE; } +static void remove_device_networks(struct connman_device *device) +{ + GHashTableIter iter; + gpointer key, value; + GSList *key_list = NULL; + GSList *list; + + if (bluetooth_networks == NULL) + return; + + g_hash_table_iter_init(&iter, bluetooth_networks); + + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { + struct connman_network *network = value; + + if (connman_network_get_device(network) != device) + continue; + + key_list = g_slist_append(key_list, key); + } + + for (list = key_list; list != NULL; list = list->next) { + const char *network_path = list->data; + + g_hash_table_remove(bluetooth_networks, network_path); + } + + g_slist_free(key_list); +} + static void adapter_properties_reply(DBusPendingCall *call, void *user_data) { char *path = user_data; @@ -660,6 +695,8 @@ update: if (powered == TRUE) check_networks(device, &networks); + else + remove_device_networks(device); done: dbus_message_unref(reply); @@ -776,10 +813,26 @@ static void unregister_device(gpointer data) DBG(""); + remove_device_networks(device); + connman_device_unregister(device); connman_device_unref(device); } +static void remove_network(gpointer data) +{ + struct connman_network *network = data; + struct connman_device *device; + + DBG("network %p", network); + + device = connman_network_get_device(network); + if (device != NULL) + connman_device_remove_network(device, network); + + connman_network_unref(network); +} + static void bluetooth_connect(DBusConnection *connection, void *user_data) { DBusMessage *message; @@ -791,7 +844,7 @@ static void bluetooth_connect(DBusConnection *connection, void *user_data) g_free, unregister_device); bluetooth_networks = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, NULL); + g_free, remove_network); message = dbus_message_new_method_call(BLUEZ_SERVICE, "/", BLUEZ_MANAGER_INTERFACE, LIST_ADAPTERS); @@ -825,15 +878,31 @@ static void bluetooth_disconnect(DBusConnection *connection, void *user_data) return; g_hash_table_destroy(bluetooth_networks); + bluetooth_networks = NULL; g_hash_table_destroy(bluetooth_devices); bluetooth_devices = NULL; } static int bluetooth_probe(struct connman_device *device) { + GHashTableIter iter; + gpointer key, value; + DBG("device %p", device); - return 0; + if (bluetooth_devices == NULL) + return -ENOTSUP; + + g_hash_table_iter_init(&iter, bluetooth_devices); + + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { + struct connman_device *device_pan = value; + + if (device == device_pan) + return 0; + } + + return -ENOTSUP; } static void bluetooth_remove(struct connman_device *device) @@ -948,6 +1017,7 @@ static void tech_remove(struct connman_technology *technology) static void server_register_reply(DBusPendingCall *call, void *user_data) { + struct connman_technology *technology = user_data; DBusError error; DBusMessage *reply; @@ -968,9 +1038,38 @@ static void server_register_reply(DBusPendingCall *call, void *user_data) dbus_message_unref(reply); dbus_pending_call_unref(call); + connman_technology_tethering_notify(technology, TRUE); } +static void server_unregister_reply(DBusPendingCall *call, void *user_data) +{ + struct connman_technology *technology = user_data; + DBusError error; + DBusMessage *reply; + + DBG(""); + + reply = dbus_pending_call_steal_reply(call); + + dbus_error_init(&error); + + if (dbus_set_error_from_message(&error, reply) == TRUE) { + connman_error("%s", error.message); + dbus_error_free(&error); + dbus_message_unref(reply); + dbus_pending_call_unref(call); + return; + } + + dbus_message_unref(reply); + dbus_pending_call_unref(call); + + connman_technology_tethering_notify(technology, FALSE); +} + + static void server_register(const char *path, const char *uuid, + struct connman_technology *technology, const char *bridge, connman_bool_t enabled) { DBusMessage *message; @@ -1008,54 +1107,62 @@ static void server_register(const char *path, const char *uuid, return; } - dbus_pending_call_set_notify(call, server_register_reply, - g_strdup(path), g_free); + if (enabled == TRUE) + dbus_pending_call_set_notify(call, server_register_reply, + technology, NULL); + else + dbus_pending_call_set_notify(call, server_unregister_reply, + technology, NULL); dbus_message_unref(message); } -static void enable_nap(gpointer key, gpointer value, - gpointer user_data) +struct tethering_info { + struct connman_technology *technology; + const char *bridge; +}; + +static void enable_nap(gpointer key, gpointer value, gpointer user_data) { + struct tethering_info *info = user_data; struct connman_device *device = value; - const char *bridge = user_data; const char *path; + DBG(""); + path = connman_device_get_string(device, "Path"); - server_register(path, "nap", bridge, TRUE); + server_register(path, "nap", info->technology, info->bridge, TRUE); } -static void disable_nap(gpointer key, gpointer value, - gpointer user_data) +static void disable_nap(gpointer key, gpointer value, gpointer user_data) { + struct tethering_info *info = user_data; struct connman_device *device = value; - const char *bridge = user_data; const char *path; + DBG(""); + path = connman_device_get_string(device, "Path"); - server_register(path, "nap", bridge, FALSE); + server_register(path, "nap", info->technology, info->bridge, FALSE); } static int tech_set_tethering(struct connman_technology *technology, + const char *identifier, const char *passphrase, const char *bridge, connman_bool_t enabled) { - char *bridge_name = g_strdup(bridge); + struct tethering_info info = { + .technology = technology, + .bridge = bridge, + }; DBG("bridge %s", bridge); - if (bridge_name == NULL) - return -ENOMEM; - if (enabled) - g_hash_table_foreach(bluetooth_devices, - enable_nap, bridge_name); + g_hash_table_foreach(bluetooth_devices, enable_nap, &info); else - g_hash_table_foreach(bluetooth_devices, - disable_nap, bridge_name); - - g_free(bridge_name); + g_hash_table_foreach(bluetooth_devices, disable_nap, &info); return 0; } @@ -1139,7 +1246,7 @@ static int bluetooth_init(void) if (err < 0) { connman_device_driver_unregister(&bluetooth_driver); connman_network_driver_unregister(&pan_driver); - return err; + goto remove; } return 0;