LINUX.ORG.RU

«Как восстановить bluetooth адаптер с обнуленным адресом» или «Боремся с EADDRNOTAVAIL»

 , , ,


2

2

Когда то создавал тему :https://www.linux.org.ru/forum/general/13867818?lastmod=1512381418394#comment-13868385 (комментарий)

Но вместо помощи получил несколько шуточных комментов... Вообщем оказалось, что таких «стрелков-по-собственным-ногам» в гугле можно найти достаточно. И ни одного решения.

Так вот: решением является временный запуск пропатченного ядра и изменение адреса из-под него.

Патч необходимо накладывать на net/bluetooth/hci_core.c (моя версия ядра 4.10.17)

--- hci_core.c	2017-12-18 20:07:05.814845399 +0200
+++ /usr/src/linux-source-4.10.0/linux-source-4.10.0/net/bluetooth/hci_core.c	2017-02-20 00:34:00.000000000 +0200
@@ -1304,11 +1304,10 @@
 		 * This check is only valid for BR/EDR controllers
 		 * since AMP controllers do not have an address.
 		 */
-		if ((!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
+		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
 		    hdev->dev_type == HCI_PRIMARY &&
 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
-		    !bacmp(&hdev->static_addr, BDADDR_ANY)) && 0 ) {
-			printk("BACMP 1");
+		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
 			ret = -EADDRNOTAVAIL;
 			goto done;
 		}
@@ -1364,11 +1363,10 @@
 		 * support changing the public address, fail the power
 		 * on procedure.
 		 */
-		if ((bacmp(&hdev->public_addr, BDADDR_ANY) &&
-		    hdev->set_bdaddr) || 1 )
+		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
+		    hdev->set_bdaddr)
 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
 		else
-			printk("BACMP 2");
 			ret = -EADDRNOTAVAIL;
 	}
 

(Просто убрал «подозрительные» проверки корректности адреса перед включением)

Собираем - устанавливаем - запускаем новое ядро - поднимаем интерфейс «hciconfig hci0 up» - меняем адрес - загружаемся в старое ядро - радуемся =)

В теории можно также запихнуть set_bdaddr в модуль, и вообще копнуть глубже и сделать красивее... но времени не хватает, так что звиняйте...

Если возникнут вопросы - с радостью отвечу!



Последнее исправление: cyber_eagle (всего исправлений: 2)

diff -u (или git diff), пожалуйста. Обычные диффы (не контекстные) читать и накладывать невозможно.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от xaizek

Нет...тоесть не совсем... Там везде стоят проверки на корректность адреса (аналогично той, что при включении). Вполне возможно, что они так же избыточны. Но это нужно проверить экспериментально...Пока что я ничего не исправлял.

cyber_eagle
() автор топика
Ответ на: комментарий от intelfx
--- hci_core.c	2017-12-18 20:07:05.814845399 +0200
+++ /usr/src/linux-source-4.10.0/linux-source-4.10.0/net/bluetooth/hci_core.c	2017-02-20 00:34:00.000000000 +0200
@@ -1304,11 +1304,10 @@
 		 * This check is only valid for BR/EDR controllers
 		 * since AMP controllers do not have an address.
 		 */
-		if ((!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
+		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
 		    hdev->dev_type == HCI_PRIMARY &&
 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
-		    !bacmp(&hdev->static_addr, BDADDR_ANY)) && 0 ) {
-			printk("BACMP 1");
+		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
 			ret = -EADDRNOTAVAIL;
 			goto done;
 		}
@@ -1364,11 +1363,10 @@
 		 * support changing the public address, fail the power
 		 * on procedure.
 		 */
-		if ((bacmp(&hdev->public_addr, BDADDR_ANY) &&
-		    hdev->set_bdaddr) || 1 )
+		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
+		    hdev->set_bdaddr)
 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
 		else
-			printk("BACMP 2");
 			ret = -EADDRNOTAVAIL;
 	}
 
cyber_eagle
() автор топика

Бобра тебе, птыц! Я как раз собирался ломать в следующем году что-то подобное.

r3lgar ★★★★★
()
Ответ на: комментарий от cyber_eagle

С bluetooth-ом так не проканает. Нужно специальное железо. В ограниченном варианте можно обойтись модификацией прошивки адаптера.

sergej ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.