Bluetooth: Add support for Unconfigured Index Added events
authorMarcel Holtmann <marcel@holtmann.org>
Wed, 2 Jul 2014 19:30:54 +0000 (21:30 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 3 Jul 2014 15:42:58 +0000 (17:42 +0200)
When a controller is in unconfigured state it is currently hidden
from the management interface. This change now announces the new
controller with an Unconfigured Index Added event and allows clients
to easily detect the controller.

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

index 5b3e8009edddd104d461704a4af09f6ac37d8055..7da29fd748d8718dcdb79ae40a277d7609a58779 100644 (file)
@@ -640,3 +640,5 @@ struct mgmt_ev_new_conn_param {
        __le16 latency;
        __le16 timeout;
 } __packed;
+
+#define MGMT_EV_UNCONF_INDEX_ADDED     0x001d
index 395b014ad0e80f19b016776fa261ab079cb9be81..df25a8329ecc71055d7aba62459fc97923364ffc 100644 (file)
@@ -2806,14 +2806,18 @@ static void hci_power_on(struct work_struct *work)
        if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
                /* For unconfigured devices, set the HCI_RAW flag
                 * so that userspace can easily identify them.
-                *
-                * If the device is fully configured and ready for
-                * operation, announce it via management interface.
                 */
                if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
                        set_bit(HCI_RAW, &hdev->flags);
-               else
-                       mgmt_index_added(hdev);
+
+               /* For fully configured devices, this will send
+                * the Index Added event. For unconfigured devices,
+                * it will send Unconfigued Index Added event.
+                *
+                * Devices with HCI_QUIRK_RAW_DEVICE are ignored
+                * and no event will be send.
+                */
+               mgmt_index_added(hdev);
        }
 }
 
@@ -4032,8 +4036,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
        cancel_work_sync(&hdev->power_on);
 
        if (!test_bit(HCI_INIT, &hdev->flags) &&
-           !test_bit(HCI_SETUP, &hdev->dev_flags) &&
-           !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
+           !test_bit(HCI_SETUP, &hdev->dev_flags)) {
                hci_dev_lock(hdev);
                mgmt_index_removed(hdev);
                hci_dev_unlock(hdev);
index db9610323d4da236c4edc154984b56ace1ee7648..ba13ad8e25c6b81157bcdade9a51d12c3871bc07 100644 (file)
@@ -453,8 +453,7 @@ static int hci_sock_release(struct socket *sock)
 
        if (hdev) {
                if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
-                       if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
-                               mgmt_index_added(hdev);
+                       mgmt_index_added(hdev);
                        clear_bit(HCI_USER_CHANNEL, &hdev->dev_flags);
                        hci_dev_close(hdev->id);
                }
@@ -706,14 +705,12 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
                        goto done;
                }
 
-               if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
-                       mgmt_index_removed(hdev);
+               mgmt_index_removed(hdev);
 
                err = hci_dev_open(hdev->id);
                if (err) {
                        clear_bit(HCI_USER_CHANNEL, &hdev->dev_flags);
-                       if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
-                               mgmt_index_added(hdev);
+                       mgmt_index_added(hdev);
                        hci_dev_put(hdev);
                        goto done;
                }
index 1ab98980054c2cc368c4b9df80f625a26a3c1f32..ab70d5858db9932819afcb9b94ad45783bef907e 100644 (file)
@@ -118,6 +118,7 @@ static const u16 mgmt_events[] = {
        MGMT_EV_DEVICE_ADDED,
        MGMT_EV_DEVICE_REMOVED,
        MGMT_EV_NEW_CONN_PARAM,
+       MGMT_EV_UNCONF_INDEX_ADDED,
 };
 
 #define CACHE_TIMEOUT  msecs_to_jiffies(2 * 1000)
@@ -5373,7 +5374,13 @@ void mgmt_index_added(struct hci_dev *hdev)
        if (hdev->dev_type != HCI_BREDR)
                return;
 
-       mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
+       if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+               return;
+
+       if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+               mgmt_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, NULL, 0, NULL);
+       else
+               mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
 }
 
 void mgmt_index_removed(struct hci_dev *hdev)
@@ -5383,6 +5390,9 @@ void mgmt_index_removed(struct hci_dev *hdev)
        if (hdev->dev_type != HCI_BREDR)
                return;
 
+       if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+               return;
+
        mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
 
        mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);