Bluetooth: Enable/Disable address resolution during le create conn
authorSathish Narasimman <nsathish41@gmail.com>
Thu, 23 Jul 2020 12:39:01 +0000 (18:09 +0530)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 30 Jul 2020 07:34:43 +0000 (09:34 +0200)
In this patch if le_create_conn process is started restrict to
disable address resolution and same is disabled during
le_enh_connection_complete

Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/hci_conn.c
net/bluetooth/hci_event.c
net/bluetooth/hci_request.c
net/bluetooth/hci_request.h
net/bluetooth/mgmt.c

index be67361ff2f00b8373aa3acd410bd0f2fc122a59..9832f8445d43eba16fa7f12040d88a708fb58b76 100644 (file)
@@ -1003,6 +1003,11 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
        struct hci_request req;
        int err;
 
+       /* This ensures that during disable le_scan address resolution
+        * will not be disabled if it is followed by le_create_conn
+        */
+       bool rpa_le_conn = true;
+
        /* Let's make sure that le is enabled.*/
        if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
                if (lmp_le_capable(hdev))
@@ -1103,7 +1108,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
         * state.
         */
        if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
-               hci_req_add_le_scan_disable(&req);
+               hci_req_add_le_scan_disable(&req, rpa_le_conn);
                hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
        }
 
index 6388fb55b4d2411021302f3b9e08f70384647b2d..628831b15c0a70dffd7efb0540d617b04ba61808 100644 (file)
@@ -5228,6 +5228,10 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
                             le16_to_cpu(ev->interval),
                             le16_to_cpu(ev->latency),
                             le16_to_cpu(ev->supervision_timeout));
+
+       if (use_ll_privacy(hdev) &&
+           hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
+               hci_req_disable_address_resolution(hdev);
 }
 
 static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
index e48f0945a417978b5c2c87cae4523616bbfbda48..70e077cc7dfa3a03bf4e2848403999a41a84d8f4 100644 (file)
@@ -428,7 +428,7 @@ static void __hci_update_background_scan(struct hci_request *req)
                if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
                        return;
 
-               hci_req_add_le_scan_disable(req);
+               hci_req_add_le_scan_disable(req, false);
 
                BT_DBG("%s stopping background scanning", hdev->name);
        } else {
@@ -447,7 +447,7 @@ static void __hci_update_background_scan(struct hci_request *req)
                 * don't miss any advertising (due to duplicates filter).
                 */
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
-                       hci_req_add_le_scan_disable(req);
+                       hci_req_add_le_scan_disable(req, false);
 
                hci_req_add_le_passive_scan(req);
 
@@ -652,7 +652,7 @@ void __hci_req_update_eir(struct hci_request *req)
        hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
 }
 
-void hci_req_add_le_scan_disable(struct hci_request *req)
+void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn)
 {
        struct hci_dev *hdev = req->hdev;
 
@@ -676,8 +676,9 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
                hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
        }
 
+       /* Disable address resolution */
        if (use_ll_privacy(hdev) &&
-           hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) {
+           hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) && !rpa_le_conn) {
                __u8 enable = 0x00;
                hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
        }
@@ -1072,7 +1073,7 @@ static void hci_req_config_le_suspend_scan(struct hci_request *req)
 {
        /* Before changing params disable scan if enabled */
        if (hci_dev_test_flag(req->hdev, HCI_LE_SCAN))
-               hci_req_add_le_scan_disable(req);
+               hci_req_add_le_scan_disable(req, false);
 
        /* Configure params and enable scanning */
        hci_req_add_le_passive_scan(req);
@@ -1140,7 +1141,7 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
 
                /* Disable LE passive scan if enabled */
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
-                       hci_req_add_le_scan_disable(&req);
+                       hci_req_add_le_scan_disable(&req, false);
 
                /* Mark task needing completion */
                set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
@@ -1696,6 +1697,28 @@ int hci_req_update_adv_data(struct hci_dev *hdev, u8 instance)
        return hci_req_run(&req, NULL);
 }
 
+static void enable_addr_resolution_complete(struct hci_dev *hdev, u8 status,
+                                           u16 opcode)
+{
+       BT_DBG("%s status %u", hdev->name, status);
+}
+
+void hci_req_disable_address_resolution(struct hci_dev *hdev)
+{
+       struct hci_request req;
+       __u8 enable = 0x00;
+
+       if (!use_ll_privacy(hdev) &&
+           !hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
+               return;
+
+       hci_req_init(&req, hdev);
+
+       hci_req_add(&req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
+
+       hci_req_run(&req, enable_addr_resolution_complete);
+}
+
 static void adv_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
 {
        BT_DBG("%s status %u", hdev->name, status);
@@ -2667,7 +2690,7 @@ static void bg_scan_update(struct work_struct *work)
 
 static int le_scan_disable(struct hci_request *req, unsigned long opt)
 {
-       hci_req_add_le_scan_disable(req);
+       hci_req_add_le_scan_disable(req, false);
        return 0;
 }
 
@@ -2770,7 +2793,7 @@ static int le_scan_restart(struct hci_request *req, unsigned long opt)
                return 0;
        }
 
-       hci_req_add_le_scan_disable(req);
+       hci_req_add_le_scan_disable(req, false);
 
        if (use_ext_scan(hdev)) {
                struct hci_cp_le_set_ext_scan_enable ext_enable_cp;
@@ -2861,7 +2884,7 @@ static int active_scan(struct hci_request *req, unsigned long opt)
         * discovery scanning parameters.
         */
        if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
-               hci_req_add_le_scan_disable(req);
+               hci_req_add_le_scan_disable(req, false);
 
        /* All active scans will be done with either a resolvable private
         * address (when privacy feature has been enabled) or non-resolvable
@@ -2976,14 +2999,14 @@ bool hci_req_stop_discovery(struct hci_request *req)
 
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
                        cancel_delayed_work(&hdev->le_scan_disable);
-                       hci_req_add_le_scan_disable(req);
+                       hci_req_add_le_scan_disable(req, false);
                }
 
                ret = true;
        } else {
                /* Passive scanning */
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
-                       hci_req_add_le_scan_disable(req);
+                       hci_req_add_le_scan_disable(req, false);
                        ret = true;
                }
        }
index bbe892ab078abf7b4810525f93739bc6a932a3b5..6a12e84c66c40428fd177705e8d4ccbb44b17358 100644 (file)
@@ -65,11 +65,12 @@ void __hci_req_write_fast_connectable(struct hci_request *req, bool enable);
 void __hci_req_update_name(struct hci_request *req);
 void __hci_req_update_eir(struct hci_request *req);
 
-void hci_req_add_le_scan_disable(struct hci_request *req);
+void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn);
 void hci_req_add_le_passive_scan(struct hci_request *req);
 
 void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next);
 
+void hci_req_disable_address_resolution(struct hci_dev *hdev);
 void hci_req_reenable_advertising(struct hci_dev *hdev);
 void __hci_req_enable_advertising(struct hci_request *req);
 void __hci_req_disable_advertising(struct hci_request *req);
index f45105d2de7722dc9018ab5acd66f7d12dbab4e4..47bcfe2fb14c5915e7433edb88a971690d12d991 100644 (file)
@@ -5226,7 +5226,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
 
                hci_req_init(&req, hdev);
 
-               hci_req_add_le_scan_disable(&req);
+               hci_req_add_le_scan_disable(&req, false);
                hci_req_add_le_passive_scan(&req);
 
                hci_req_run(&req, NULL);