Bluetooth: mgmt: Managing only BR/EDR HCI controllers
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Thu, 19 Jul 2012 14:03:40 +0000 (17:03 +0300)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Mon, 6 Aug 2012 18:02:54 +0000 (15:02 -0300)
Add check that HCI controller is BR/EDR. AMP controller shall not be
managed by mgmt interface and consequently user space.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c
net/bluetooth/mgmt.c

index 41b26648e79e56fe4b648777a8430eac3e3035d1..5c7a5f819fcfb02778765614fc45ed7cbf98e0a4 100644 (file)
@@ -1050,7 +1050,7 @@ int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 int mgmt_interleaved_discovery(struct hci_dev *hdev);
 int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-
+bool mgmt_valid_hdev(struct hci_dev *hdev);
 int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
 
 /* HCI info for socket */
index d4de5db18d5a8e48d950a368e7ef93840d269a07..fa974a19d365e78031cc53977871a1e2b8df2016 100644 (file)
@@ -696,7 +696,8 @@ int hci_dev_open(__u16 dev)
                hci_dev_hold(hdev);
                set_bit(HCI_UP, &hdev->flags);
                hci_notify(hdev, HCI_DEV_UP);
-               if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
+               if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
+                   mgmt_valid_hdev(hdev)) {
                        hci_dev_lock(hdev);
                        mgmt_powered(hdev, 1);
                        hci_dev_unlock(hdev);
@@ -797,7 +798,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
         * and no tasks are scheduled. */
        hdev->close(hdev);
 
-       if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
+       if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
+           mgmt_valid_hdev(hdev)) {
                hci_dev_lock(hdev);
                mgmt_powered(hdev, 0);
                hci_dev_unlock(hdev);
index ad6613d17ca6de815be200b9576d6ecf510fef0d..2a0f695e33d40562e04338190de5184bcdfbcbb5 100644 (file)
@@ -193,6 +193,11 @@ static u8 mgmt_status_table[] = {
        MGMT_STATUS_CONNECT_FAILED,     /* MAC Connection Failed */
 };
 
+bool mgmt_valid_hdev(struct hci_dev *hdev)
+{
+       return hdev->dev_type == HCI_BREDR;
+}
+
 static u8 mgmt_status(u8 hci_status)
 {
        if (hci_status < ARRAY_SIZE(mgmt_status_table))
@@ -317,7 +322,6 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
                           u16 data_len)
 {
        struct mgmt_rp_read_index_list *rp;
-       struct list_head *p;
        struct hci_dev *d;
        size_t rp_len;
        u16 count;
@@ -328,7 +332,10 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
        read_lock(&hci_dev_list_lock);
 
        count = 0;
-       list_for_each(p, &hci_dev_list) {
+       list_for_each_entry(d, &hci_dev_list, list) {
+               if (!mgmt_valid_hdev(d))
+                       continue;
+
                count++;
        }
 
@@ -346,6 +353,9 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
                if (test_bit(HCI_SETUP, &d->dev_flags))
                        continue;
 
+               if (!mgmt_valid_hdev(d))
+                       continue;
+
                rp->index[i++] = cpu_to_le16(d->id);
                BT_DBG("Added hci%u", d->id);
        }
@@ -2820,6 +2830,9 @@ static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
 
 int mgmt_index_added(struct hci_dev *hdev)
 {
+       if (!mgmt_valid_hdev(hdev))
+               return -ENOTSUPP;
+
        return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
 }
 
@@ -2827,6 +2840,9 @@ int mgmt_index_removed(struct hci_dev *hdev)
 {
        u8 status = MGMT_STATUS_INVALID_INDEX;
 
+       if (!mgmt_valid_hdev(hdev))
+               return -ENOTSUPP;
+
        mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
 
        return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);