Bluetooth: Use hci_conn_hash_lookup_le() when possible
[linux-2.6-block.git] / net / bluetooth / hci_event.c
index 186041866315a4e107de086df52142f39d6c6ee3..504892cfb25a8e2e1d126c3ecac13f3d949d1ad9 100644 (file)
@@ -55,7 +55,12 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
        wake_up_bit(&hdev->flags, HCI_INQUIRY);
 
        hci_dev_lock(hdev);
-       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+       /* Set discovery state to stopped if we're not doing LE active
+        * scanning.
+        */
+       if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+           hdev->le_scan_type != LE_SCAN_ACTIVE)
+               hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
        hci_dev_unlock(hdev);
 
        hci_conn_check_pending(hdev);
@@ -1910,7 +1915,8 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
 
        hci_dev_lock(hdev);
 
-       conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
+       conn = hci_conn_hash_lookup_le(hdev, &cp->peer_addr,
+                                      cp->peer_addr_type);
        if (!conn)
                goto unlock;
 
@@ -4648,8 +4654,8 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
        /* If we're not connectable only connect devices that we have in
         * our pend_le_conns list.
         */
-       params = hci_explicit_connect_lookup(hdev, addr, addr_type);
-
+       params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
+                                          addr_type);
        if (!params)
                return NULL;
 
@@ -4719,6 +4725,27 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
        struct hci_conn *conn;
        bool match;
        u32 flags;
+       u8 *ptr, real_len;
+
+       /* Find the end of the data in case the report contains padded zero
+        * bytes at the end causing an invalid length value.
+        *
+        * When data is NULL, len is 0 so there is no need for extra ptr
+        * check as 'ptr < data + 0' is already false in such case.
+        */
+       for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) {
+               if (ptr + 1 + *ptr > data + len)
+                       break;
+       }
+
+       real_len = ptr - data;
+
+       /* Adjust for actual length */
+       if (len != real_len) {
+               BT_ERR_RATELIMITED("%s advertising data length corrected",
+                                  hdev->name);
+               len = real_len;
+       }
 
        /* If the direct address is present, then this report is from
         * a LE Direct Advertising Report event. In that case it is