diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2013-10-06 04:08:57 -0400 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2013-10-06 04:50:50 -0400 |
commit | a5c8f270e4dae14ea5cb88e477ed1092955f8722 (patch) | |
tree | e35aedc474c06bb345c049437b322afbc0a226b5 /net/bluetooth | |
parent | a646bd81945b337b1cf37dea4734847947a0d9ad (diff) |
Bluetooth: Reject enabling controllers without valid addresses
In case of a single mode LE-only controller it is possible that no
public address is used. These type of controllers require a random
address to be configured.
Without a configured static random address, such a controller is
not functional. So reject powering on the controller in this case
until it gets configured with a random address.
The controller setup stage is still run since it is the only way
to determinate if a public address is available or not. So it is
similar on how RFKILL gets handled during initial setup of the
controller.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 0d5fe0843f5e..4a9b8dda754e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1196,13 +1196,29 @@ static int hci_dev_do_open(struct hci_dev *hdev) | |||
1196 | goto done; | 1196 | goto done; |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | /* Check for rfkill but allow the HCI setup stage to proceed | 1199 | if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { |
1200 | * (which in itself doesn't cause any RF activity). | 1200 | /* Check for rfkill but allow the HCI setup stage to |
1201 | */ | 1201 | * proceed (which in itself doesn't cause any RF activity). |
1202 | if (test_bit(HCI_RFKILLED, &hdev->dev_flags) && | 1202 | */ |
1203 | !test_bit(HCI_SETUP, &hdev->dev_flags)) { | 1203 | if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { |
1204 | ret = -ERFKILL; | 1204 | ret = -ERFKILL; |
1205 | goto done; | 1205 | goto done; |
1206 | } | ||
1207 | |||
1208 | /* Check for valid public address or a configured static | ||
1209 | * random adddress, but let the HCI setup proceed to | ||
1210 | * be able to determine if there is a public address | ||
1211 | * or not. | ||
1212 | * | ||
1213 | * This check is only valid for BR/EDR controllers | ||
1214 | * since AMP controllers do not have an address. | ||
1215 | */ | ||
1216 | if (hdev->dev_type == HCI_BREDR && | ||
1217 | !bacmp(&hdev->bdaddr, BDADDR_ANY) && | ||
1218 | !bacmp(&hdev->static_addr, BDADDR_ANY)) { | ||
1219 | ret = -EADDRNOTAVAIL; | ||
1220 | goto done; | ||
1221 | } | ||
1206 | } | 1222 | } |
1207 | 1223 | ||
1208 | if (test_bit(HCI_UP, &hdev->flags)) { | 1224 | if (test_bit(HCI_UP, &hdev->flags)) { |
@@ -1288,6 +1304,10 @@ int hci_dev_open(__u16 dev) | |||
1288 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) | 1304 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) |
1289 | cancel_delayed_work(&hdev->power_off); | 1305 | cancel_delayed_work(&hdev->power_off); |
1290 | 1306 | ||
1307 | /* After this call it is guaranteed that the setup procedure | ||
1308 | * has finished. This means that error conditions like RFKILL | ||
1309 | * or no valid public or static random address apply. | ||
1310 | */ | ||
1291 | flush_workqueue(hdev->req_workqueue); | 1311 | flush_workqueue(hdev->req_workqueue); |
1292 | 1312 | ||
1293 | err = hci_dev_do_open(hdev); | 1313 | err = hci_dev_do_open(hdev); |
@@ -1703,7 +1723,14 @@ static void hci_power_on(struct work_struct *work) | |||
1703 | return; | 1723 | return; |
1704 | } | 1724 | } |
1705 | 1725 | ||
1706 | if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { | 1726 | /* During the HCI setup phase, a few error conditions are |
1727 | * ignored and they need to be checked now. If they are still | ||
1728 | * valid, it is important to turn the device back off. | ||
1729 | */ | ||
1730 | if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || | ||
1731 | (hdev->dev_type == HCI_BREDR && | ||
1732 | !bacmp(&hdev->bdaddr, BDADDR_ANY) && | ||
1733 | !bacmp(&hdev->static_addr, BDADDR_ANY))) { | ||
1707 | clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); | 1734 | clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); |
1708 | hci_dev_do_close(hdev); | 1735 | hci_dev_do_close(hdev); |
1709 | } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { | 1736 | } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { |