[PATCH] core/adapter: probe profiles after loading ltks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When bluetoothd starts, it loads devices from storage.

During this process, it loads general info. That includes loading UUIDS,
and letting plugins decide whether they're interested in this device. Then
load_irks call is made to load identity resolving keys into kernel.

If during this process plugin decides it's interested in given device,
they might register device for auto connecting by calling
btd_device_add_attio_callback. This update kernel auto connect list.
update_white_list inside "net/bluetooth/hci_request.c" is called. It uses
hci_find_irk_by_addr to decide whether kernel know irk for given address
and shall not use whitelist. However irks were not loaded yet - they're
loaded by bluetoothd after all devices were initialized (and possibly
added to autoconnect).

Because of that, device public address is added to whitelist (instead of
resolvable private address), and whitelist is used. Even worse, after call
to load_irks, or after manually calling connect, device is still
improperly added to whitelist and will be unable to connect (timeout will
happen).

To fix that bluetoothd must call load_irks before letting plugins enable
autoconnect.
---
 src/adapter.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index a920b21..4abeaaa 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3457,6 +3457,14 @@ static uint8_t get_le_addr_type(GKeyFile *keyfile)
 	return addr_type;
 }
 
+static void probe_loaded_profiles(struct btd_device *device, gpointer data)
+{
+		GSList *list = btd_device_get_uuids(device);
+
+		if (list)
+			device_probe_profiles(device, list);
+}
+
 static void load_devices(struct btd_adapter *adapter)
 {
 	char dirname[PATH_MAX];
@@ -3465,6 +3473,7 @@ static void load_devices(struct btd_adapter *adapter)
 	GSList *ltks = NULL;
 	GSList *irks = NULL;
 	GSList *params = NULL;
+	GSList *added_devices = NULL;
 	DIR *dir;
 	struct dirent *entry;
 
@@ -3534,9 +3543,7 @@ static void load_devices(struct btd_adapter *adapter)
 
 		/* TODO: register services from pre-loaded list of primaries */
 
-		list = btd_device_get_uuids(device);
-		if (list)
-			device_probe_profiles(device, list);
+		added_devices = g_slist_append(added_devices, device);
 
 device_exist:
 		if (key_info) {
@@ -3564,6 +3571,10 @@ free:
 	g_slist_free_full(irks, g_free);
 	load_conn_params(adapter, params);
 	g_slist_free_full(params, g_free);
+
+	g_slist_foreach(added_devices, (GFunc)probe_loaded_profiles, NULL);
+	g_slist_free(added_devices);
+
 }
 
 int btd_adapter_block_address(struct btd_adapter *adapter,
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux