diff mbox series

[BlueZ] adapter: Fix execute "LE Add Device To Resolving List" command fail

Message ID 20240821013505.1344247-1-clancy_shang@163.com (mailing list archive)
State New, archived
Headers show
Series [BlueZ] adapter: Fix execute "LE Add Device To Resolving List" command fail | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/BuildEll success Build ELL PASS
tedd_an/BluezMake success Bluez Make PASS
tedd_an/MakeCheck fail BlueZ Make Check FAIL:
tedd_an/MakeDistcheck fail Make Distcheck FAIL: Package cups was not found in the pkg-config search path. Perhaps you should add the directory containing `cups.pc' to the PKG_CONFIG_PATH environment variable No package 'cups' found make[4]: *** [Makefile:11766: test-suite.log] Error 1 make[3]: *** [Makefile:11874: check-TESTS] Error 2 make[2]: *** [Makefile:12303: check-am] Error 2 make[1]: *** [Makefile:12305: check] Error 2 make: *** [Makefile:12226: distcheck] Error 1
tedd_an/CheckValgrind fail Check Valgrind FAIL: tools/mgmt-tester.c: In function ‘main’: tools/mgmt-tester.c:12725:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without 12725 | int main(int argc, char *argv[]) | ^~~~ make[3]: *** [Makefile:11766: test-suite.log] Error 1 make[2]: *** [Makefile:11874: check-TESTS] Error 2 make[1]: *** [Makefile:12303: check-am] Error 2 make: *** [Makefile:12305: check] Error 2
tedd_an/CheckSmatch success CheckSparse PASS
tedd_an/bluezmakeextell success Make External ELL PASS
tedd_an/IncrementalBuild success Incremental Build PASS
tedd_an/ScanBuild success Scan Build PASS

Commit Message

clancy_shang Aug. 21, 2024, 1:35 a.m. UTC
From: Clancy Shang <clancy.shang@quectel.com>

According to Bluetooth Core Specification Version 5.4 | Vol 4, Part E,
7.8.38, if there is an existing entry in the resolving list with the same
non-zero Peer_IRK, the Controller should return the error code Invalid
HCI Command Parameters (0x12), so fix it.

Test environment:
I tested with the game controller device, and the steps are as follows:
1. The game controller device enters advertising pairing mode and then
   connects.
2. Disconnect.
3. Make the hand shank enter advertising pairing mode again and then
   reconnect.
4. Reproduce.
The step one and step four, the game controller device is the same device
but with a different privacy static address, causing the same IRK.

There could be some trouble if it is fixed in the kernel.
Firstly, there would be two devices in the paired list, but only the latest
device can be conneted. Actually they are the same device.
Secondly, the display will show two devices too.

Signed-off-by: Clancy Shang <clancy.shang@quectel.com>
---
 src/adapter.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

Comments

bluez.test.bot@gmail.com Aug. 21, 2024, 3:51 a.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=881529

---Test result---

Test Summary:
CheckPatch                    PASS      0.47 seconds
GitLint                       PASS      0.28 seconds
BuildEll                      PASS      24.68 seconds
BluezMake                     PASS      1734.66 seconds
MakeCheck                     FAIL      13.54 seconds
MakeDistcheck                 FAIL      159.10 seconds
CheckValgrind                 FAIL      250.32 seconds
CheckSmatch                   PASS      352.53 seconds
bluezmakeextell               PASS      120.90 seconds
IncrementalBuild              PASS      1568.75 seconds
ScanBuild                     PASS      996.95 seconds

Details
##############################
Test: MakeCheck - FAIL
Desc: Run Bluez Make Check
Output:

make[3]: *** [Makefile:11766: test-suite.log] Error 1
make[2]: *** [Makefile:11874: check-TESTS] Error 2
make[1]: *** [Makefile:12303: check-am] Error 2
make: *** [Makefile:12305: check] Error 2
##############################
Test: MakeDistcheck - FAIL
Desc: Run Bluez Make Distcheck
Output:

Package cups was not found in the pkg-config search path.
Perhaps you should add the directory containing `cups.pc'
to the PKG_CONFIG_PATH environment variable
No package 'cups' found
make[4]: *** [Makefile:11766: test-suite.log] Error 1
make[3]: *** [Makefile:11874: check-TESTS] Error 2
make[2]: *** [Makefile:12303: check-am] Error 2
make[1]: *** [Makefile:12305: check] Error 2
make: *** [Makefile:12226: distcheck] Error 1
##############################
Test: CheckValgrind - FAIL
Desc: Run Bluez Make Check with Valgrind
Output:

tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12725:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12725 | int main(int argc, char *argv[])
      |     ^~~~
make[3]: *** [Makefile:11766: test-suite.log] Error 1
make[2]: *** [Makefile:11874: check-TESTS] Error 2
make[1]: *** [Makefile:12303: check-am] Error 2
make: *** [Makefile:12305: check] Error 2


---
Regards,
Linux Bluetooth
diff mbox series

Patch

diff --git a/src/adapter.c b/src/adapter.c
index 85ddfc165..c6021f173 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -8901,6 +8901,73 @@  static void store_irk(struct btd_adapter *adapter, const bdaddr_t *peer,
 	g_key_file_free(key_file);
 }
 
+static void delete_existing_irk_from_directory(
+						struct btd_adapter *adapter,
+						const unsigned char *key)
+{
+	char dirname[PATH_MAX];
+	GError *gerr = NULL;
+	DIR *dir;
+	struct dirent *entry;
+
+	create_filename(dirname, PATH_MAX, "/%s",
+				btd_adapter_get_storage_dir(adapter));
+
+	dir = opendir(dirname);
+	if (!dir) {
+		btd_error(adapter->dev_id,
+				"Unable to open adapter storage directory: %s",
+								dirname);
+		return;
+	}
+
+	while ((entry = readdir(dir)) != NULL) {
+		struct btd_device *device;
+		char filename[PATH_MAX];
+		GKeyFile *key_file;
+		struct irk_info *irk_info;
+		uint8_t bdaddr_type;
+
+		if (entry->d_type == DT_UNKNOWN)
+			entry->d_type = util_get_dt(dirname, entry->d_name);
+
+		if (entry->d_type != DT_DIR || bachk(entry->d_name) < 0)
+			continue;
+
+		create_filename(filename, PATH_MAX, "/%s/%s/info",
+					btd_adapter_get_storage_dir(adapter),
+					entry->d_name);
+
+		key_file = g_key_file_new();
+		if (!g_key_file_load_from_file(key_file, filename,
+								0, &gerr)) {
+			error("Unable to load key file from %s: (%s)",
+					filename, gerr->message);
+			g_clear_error(&gerr);
+		}
+
+		bdaddr_type = get_addr_type(key_file);
+
+		irk_info = get_irk_info(key_file, entry->d_name, bdaddr_type);
+
+		if (irk_info) {
+			if (!memcmp(irk_info->val, key, 16)) {
+				DBG("Has same irk, delete it");
+				device = btd_adapter_find_device(adapter,
+							&irk_info->bdaddr,
+							irk_info->bdaddr_type);
+				if (device)
+					btd_adapter_remove_device(adapter,
+									device);
+			}
+		}
+		g_key_file_free(key_file);
+	}
+
+	closedir(dir);
+
+}
+
 static void new_irk_callback(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -8950,6 +9017,8 @@  static void new_irk_callback(uint16_t index, uint16_t length,
 	if (!persistent)
 		return;
 
+	delete_existing_irk_from_directory(adapter, irk->val);
+
 	store_irk(adapter, &addr->bdaddr, addr->type, irk->val);
 
 	btd_device_set_temporary(device, false);