summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2012-08-09 18:27:53 +0200
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-08-14 09:20:41 +0300
commit6b256ce8bd24af901d0b0abc0394b9a80ee1314f (patch)
treef69aa6ae629d760d04460a86ca8d401fe9b8e135
parent387604eec8dde638ccd019805e21d636c84d49c8 (diff)
downloadconnman-6b256ce8bd24af901d0b0abc0394b9a80ee1314f.tar.gz
connman-6b256ce8bd24af901d0b0abc0394b9a80ee1314f.tar.bz2
connman-6b256ce8bd24af901d0b0abc0394b9a80ee1314f.zip
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
-rw-r--r--plugins/bluetooth.c66
1 files changed, 63 insertions, 3 deletions
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 1e1fc484..44d32d11 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)