Bluetooth: Fix issue with switching BR/EDR back on when disabled
authorMarcel Holtmann <marcel@holtmann.org>
Wed, 14 Jan 2015 22:40:42 +0000 (14:40 -0800)
committerJohan Hedberg <johan.hedberg@intel.com>
Thu, 15 Jan 2015 08:27:47 +0000 (10:27 +0200)
For dual-mode controllers it is possible to disable BR/EDR and operate
as LE single mode controllers with a static random address. If that is
the case, then refuse switching BR/EDR back on after the controller has
been powered.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
net/bluetooth/mgmt.c

index e531da8059230eebe69af26bea9e3fad94dba6f8..cae612658ba9f27891a24f5fc2cd0a8d777ebdfb 100644 (file)
@@ -4683,6 +4683,21 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
                err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
                                 MGMT_STATUS_REJECTED);
                goto unlock;
+       } else {
+               /* When configuring a dual-mode controller to operate
+                * with LE only and using a static address, then switching
+                * BR/EDR back on is not allowed.
+                *
+                * Dual-mode controllers shall operate with the public
+                * address as its identity address for BR/EDR and LE. So
+                * reject the attempt to create an invalid configuration.
+                */
+               if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
+                   bacmp(&hdev->static_addr, BDADDR_ANY)) {
+                       err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
+                                        MGMT_STATUS_REJECTED);
+                       goto unlock;
+               }
        }
 
        if (mgmt_pending_find(MGMT_OP_SET_BREDR, hdev)) {