Bluetooth: Restrict BNEP flags to only valid ones
[firefly-linux-kernel-4.4.55.git] / net / bluetooth / hci_event.c
index c7376cd42b1cacd9e0225f5bb4a2b05bc01590ba..7c0f992602f5f907ad228c9ea0b9cc35b76fdcb4 100644 (file)
@@ -1066,7 +1066,6 @@ static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
        hci_dev_unlock(hdev);
 }
 
-
 static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
 {
        __u8 status = *((__u8 *) skb->data);
@@ -2126,7 +2125,16 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                goto unlock;
 
        if (list_empty(&discov->resolve)) {
-               hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+               /* When BR/EDR inquiry is active and no LE scanning is in
+                * progress, then change discovery state to indicate completion.
+                *
+                * When running LE scanning and BR/EDR inquiry simultaneously
+                * and the LE scan already finished, then change the discovery
+                * state to indicate completion.
+                */
+               if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+                   !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
+                       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
                goto unlock;
        }
 
@@ -2135,7 +2143,16 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                e->name_state = NAME_PENDING;
                hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
        } else {
-               hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+               /* When BR/EDR inquiry is active and no LE scanning is in
+                * progress, then change discovery state to indicate completion.
+                *
+                * When running LE scanning and BR/EDR inquiry simultaneously
+                * and the LE scan already finished, then change the discovery
+                * state to indicate completion.
+                */
+               if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+                   !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
+                       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
        }
 
 unlock:
@@ -3009,13 +3026,13 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        if (opcode != HCI_OP_NOP)
                cancel_delayed_work(&hdev->cmd_timer);
 
+       if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags))
+               atomic_set(&hdev->cmd_cnt, 1);
+
        hci_req_cmd_complete(hdev, opcode, status);
 
-       if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
-               atomic_set(&hdev->cmd_cnt, 1);
-               if (!skb_queue_empty(&hdev->cmd_q))
-                       queue_work(hdev->workqueue, &hdev->cmd_work);
-       }
+       if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
+               queue_work(hdev->workqueue, &hdev->cmd_work);
 }
 
 static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -3104,15 +3121,15 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
        if (opcode != HCI_OP_NOP)
                cancel_delayed_work(&hdev->cmd_timer);
 
+       if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags))
+               atomic_set(&hdev->cmd_cnt, 1);
+
        if (ev->status ||
-           (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req_event))
+           (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
                hci_req_cmd_complete(hdev, opcode, ev->status);
 
-       if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
-               atomic_set(&hdev->cmd_cnt, 1);
-               if (!skb_queue_empty(&hdev->cmd_q))
-                       queue_work(hdev->workqueue, &hdev->cmd_work);
-       }
+       if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
+               queue_work(hdev->workqueue, &hdev->cmd_work);
 }
 
 static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -3889,41 +3906,37 @@ static u8 bredr_oob_data_present(struct hci_conn *conn)
        if (!data)
                return 0x00;
 
-       if (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) {
-               if (bredr_sc_enabled(hdev)) {
-                       /* When Secure Connections is enabled, then just
-                        * return the present value stored with the OOB
-                        * data. The stored value contains the right present
-                        * information. However it can only be trusted when
-                        * not in Secure Connection Only mode.
-                        */
-                       if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
-                               return data->present;
-
-                       /* When Secure Connections Only mode is enabled, then
-                        * the P-256 values are required. If they are not
-                        * available, then do not declare that OOB data is
-                        * present.
-                        */
-                       if (!memcmp(data->rand256, ZERO_KEY, 16) ||
-                           !memcmp(data->hash256, ZERO_KEY, 16))
-                               return 0x00;
-
-                       return 0x02;
-               }
+       if (bredr_sc_enabled(hdev)) {
+               /* When Secure Connections is enabled, then just
+                * return the present value stored with the OOB
+                * data. The stored value contains the right present
+                * information. However it can only be trusted when
+                * not in Secure Connection Only mode.
+                */
+               if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
+                       return data->present;
 
-               /* When Secure Connections is not enabled or actually
-                * not supported by the hardware, then check that if
-                * P-192 data values are present.
+               /* When Secure Connections Only mode is enabled, then
+                * the P-256 values are required. If they are not
+                * available, then do not declare that OOB data is
+                * present.
                 */
-               if (!memcmp(data->rand192, ZERO_KEY, 16) ||
-                   !memcmp(data->hash192, ZERO_KEY, 16))
+               if (!memcmp(data->rand256, ZERO_KEY, 16) ||
+                   !memcmp(data->hash256, ZERO_KEY, 16))
                        return 0x00;
 
-               return 0x01;
+               return 0x02;
        }
 
-       return 0x00;
+       /* When Secure Connections is not enabled or actually
+        * not supported by the hardware, then check that if
+        * P-192 data values are present.
+        */
+       if (!memcmp(data->rand192, ZERO_KEY, 16) ||
+           !memcmp(data->hash192, ZERO_KEY, 16))
+               return 0x00;
+
+       return 0x01;
 }
 
 static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -4010,8 +4023,6 @@ static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
        conn->remote_cap = ev->capability;
        conn->remote_auth = ev->authentication;
-       if (ev->oob_data)
-               set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
 
 unlock:
        hci_dev_unlock(hdev);
@@ -5038,7 +5049,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 
        skb_pull(skb, HCI_EVENT_HDR_SIZE);
 
-       if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req_event == event) {
+       if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
                struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
                u16 opcode = __le16_to_cpu(cmd_hdr->opcode);