OSDN Git Service

Bluetooth: Add missing cmd_status handler for LE_Start_Encryption
authorJohan Hedberg <johan.hedberg@intel.com>
Mon, 24 Mar 2014 12:39:04 +0000 (14:39 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 24 Mar 2014 14:51:55 +0000 (07:51 -0700)
It is possible that the HCI_LE_Start_Encryption command fails in an
early stage and triggers a command status event with the failure code.
In such a case we need to properly notify the hci_conn object and
cleanly bring the connection down. This patch adds the missing command
status handler for this HCI command.

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

index 9ee081b..4977491 100644 (file)
@@ -1725,6 +1725,36 @@ unlock:
        hci_dev_unlock(hdev);
 }
 
+static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
+{
+       struct hci_cp_le_start_enc *cp;
+       struct hci_conn *conn;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+       if (!status)
+               return;
+
+       hci_dev_lock(hdev);
+
+       cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
+       if (!cp)
+               goto unlock;
+
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+       if (!conn)
+               goto unlock;
+
+       if (conn->state != BT_CONNECTED)
+               goto unlock;
+
+       hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
+       hci_conn_drop(conn);
+
+unlock:
+       hci_dev_unlock(hdev);
+}
+
 static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        __u8 status = *((__u8 *) skb->data);
@@ -2636,6 +2666,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
                hci_cs_le_create_conn(hdev, ev->status);
                break;
 
+       case HCI_OP_LE_START_ENC:
+               hci_cs_le_start_enc(hdev, ev->status);
+               break;
+
        default:
                BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
                break;