Bluetooth: mgmt: Fix device_connected sending order
authorJohan Hedberg <johan.hedberg@intel.com>
Sat, 12 May 2012 19:11:50 +0000 (16:11 -0300)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 14 May 2012 17:56:15 +0000 (13:56 -0400)
The mgmt_ev_device_connected signal must be sent before any event
indications happen for sockets associated with the connection. Otherwise
e.g. device authorization for the sockets will fail with ENOTCONN as
user space things that there is no baseband link.

This patch fixes the issue by ensuring that the device_connected event
if sent (if it hasn't been so already) as soon as the first ACL data
packet arrives from the remote device.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c

index edfd61addceca4b269891734646fedbe6fbe8606..d6dc44cd15b0729a90bc8963ae90182353ed7e10 100644 (file)
@@ -2784,6 +2784,14 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
        if (conn) {
                hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
 
+               hci_dev_lock(hdev);
+               if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
+                   !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
+                       mgmt_device_connected(hdev, &conn->dst, conn->type,
+                                             conn->dst_type, 0, NULL, 0,
+                                             conn->dev_class);
+               hci_dev_unlock(hdev);
+
                /* Send to upper protocol */
                l2cap_recv_acldata(conn, skb, flags);
                return;
index 53680fe84628f51903088a4f94cb398896a8e100..1266f78fa8e3283a6d854d1b808312b8916c981f 100644 (file)
@@ -2109,7 +2109,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
                goto unlock;
        }
 
-       if (!ev->status) {
+       if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
                struct hci_cp_remote_name_req cp;
                memset(&cp, 0, sizeof(cp));
                bacpy(&cp.bdaddr, &conn->dst);
@@ -2878,7 +2878,7 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
        if (conn->state != BT_CONFIG)
                goto unlock;
 
-       if (!ev->status) {
+       if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
                struct hci_cp_remote_name_req cp;
                memset(&cp, 0, sizeof(cp));
                bacpy(&cp.bdaddr, &conn->dst);