summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2012-08-09 16:27:53 (GMT)
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-08-14 06:20:41 (GMT)
commit6b256ce8bd24af901d0b0abc0394b9a80ee1314f (patch)
treef69aa6ae629d760d04460a86ca8d401fe9b8e135 /plugins
parent387604eec8dde638ccd019805e21d636c84d49c8 (diff)
downloadconnman-6b256ce8bd24af901d0b0abc0394b9a80ee1314f.zip
connman-6b256ce8bd24af901d0b0abc0394b9a80ee1314f.tar.gz
connman-6b256ce8bd24af901d0b0abc0394b9a80ee1314f.tar.bz2
bluetooth: Defer add_networks() if adapter is not powered yet
In the case we add a new adapter and the adapter is powered off we would ignore the reported devices. Later when the adapter was powered on it would just not add those networks. Instead silently ignoring the devices, store the D-Bus paths in a hash table and process them as soon the adapter is powered. Fixes BMC#25322
Diffstat (limited to 'plugins')
-rw-r--r--plugins/bluetooth.c66
1 files changed, 63 insertions, 3 deletions
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 1e1fc48..44d32d1 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -69,6 +69,7 @@ static DBusConnection *connection;
static GHashTable *bluetooth_devices = NULL;
static GHashTable *bluetooth_networks = NULL;
+static GHashTable *pending_networks = NULL;
static int pan_probe(struct connman_network *network)
{
@@ -506,6 +507,23 @@ static void check_networks(DBusMessageIter *array)
}
}
+static void check_pending_networks(const char *adapter)
+{
+ GSList *networks, *list;
+
+ networks = g_hash_table_lookup(pending_networks, adapter);
+ if (networks == NULL)
+ return;
+
+ for (list = networks; list != NULL; list = list->next) {
+ char *path = list->data;
+
+ add_network(path);
+ }
+
+ g_hash_table_remove(pending_networks, adapter);
+}
+
static gboolean adapter_changed(DBusConnection *conn,
DBusMessage *message, void *user_data)
{
@@ -533,6 +551,8 @@ static gboolean adapter_changed(DBusConnection *conn,
dbus_message_iter_get_basic(&value, &val);
connman_device_set_powered(device, val);
+ if (val == TRUE)
+ check_pending_networks(path);
} else if (g_str_equal(key, "Discovering") == TRUE) {
dbus_bool_t val;
@@ -628,6 +648,32 @@ static void remove_device_networks(struct connman_device *device)
g_slist_free(key_list);
}
+static void add_pending_networks(const char *adapter, DBusMessageIter *array)
+{
+ DBusMessageIter value;
+ GSList *list = NULL;
+
+ if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(array, &value);
+
+ while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
+ const char *path;
+
+ dbus_message_iter_get_basic(&value, &path);
+
+ list = g_slist_prepend(list, g_strdup(path));
+
+ dbus_message_iter_next(&value);
+ }
+
+ if (list == NULL)
+ return;
+
+ g_hash_table_replace(pending_networks, g_strdup(adapter), list);
+}
+
static void adapter_properties_reply(DBusPendingCall *call, void *user_data)
{
char *path = user_data;
@@ -693,10 +739,11 @@ update:
connman_device_set_powered(device, powered);
connman_device_set_scanning(device, scanning);
- if (powered == TRUE)
- check_networks(&networks);
- else
+ if (powered == FALSE) {
remove_device_networks(device);
+ add_pending_networks(path, &networks);
+ } else
+ check_networks(&networks);
done:
dbus_message_unref(reply);
@@ -752,6 +799,7 @@ static void remove_adapter(DBusConnection *conn, const char *path)
DBG("path %s", path);
g_hash_table_remove(bluetooth_devices, path);
+ g_hash_table_remove(pending_networks, path);
}
static gboolean adapter_removed(DBusConnection *conn, DBusMessage *message,
@@ -833,6 +881,13 @@ static void remove_network(gpointer data)
connman_network_unref(network);
}
+static void remove_pending_networks(gpointer data)
+{
+ GSList *list = data;
+
+ g_slist_free_full(list, g_free);
+}
+
static void bluetooth_connect(DBusConnection *conn, void *user_data)
{
DBusMessage *message;
@@ -846,6 +901,9 @@ static void bluetooth_connect(DBusConnection *conn, void *user_data)
bluetooth_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, remove_network);
+ pending_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, remove_pending_networks);
+
message = dbus_message_new_method_call(BLUEZ_SERVICE, "/",
BLUEZ_MANAGER_INTERFACE, LIST_ADAPTERS);
if (message == NULL)
@@ -881,6 +939,8 @@ static void bluetooth_disconnect(DBusConnection *conn, void *user_data)
bluetooth_networks = NULL;
g_hash_table_destroy(bluetooth_devices);
bluetooth_devices = NULL;
+ g_hash_table_destroy(pending_networks);
+ pending_networks = NULL;
}
static int bluetooth_probe(struct connman_device *device)