Bluetooth: mgmt: Fix sending redundant event for Advertising Instance
authorJohan Hedberg <johan.hedberg@intel.com>
Sun, 28 Aug 2016 17:53:34 +0000 (20:53 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 19 Sep 2016 18:19:34 +0000 (20:19 +0200)
When an Advertising Instance is removed, the Advertising Removed event
shouldn't be sent to the same socket that issued the Remove
Advertising command (it gets a command complete event instead). The
mgmt_advertising_removed() function already has a parameter for
skipping a specific socket, but there was no code to propagate the
right value to this parameter. This patch fixes the issue by making
sure the intermediate hci_req_clear_adv_instance() function gets the
socket pointer.

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

index b0e23dfc5c3402654f2586b4e29dac9966c1c841..9968b1c7c03a21c99b6497f109d014475965430c 100644 (file)
@@ -1194,7 +1194,7 @@ static void adv_timeout_expire(struct work_struct *work)
 
        hci_req_init(&req, hdev);
 
-       hci_req_clear_adv_instance(hdev, &req, instance, false);
+       hci_req_clear_adv_instance(hdev, NULL, &req, instance, false);
 
        if (list_empty(&hdev->adv_instances))
                __hci_req_disable_advertising(&req);
@@ -1284,8 +1284,9 @@ static void cancel_adv_timeout(struct hci_dev *hdev)
  *   setting.
  * - force == false: Only instances that have a timeout will be removed.
  */
-void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
-                               u8 instance, bool force)
+void hci_req_clear_adv_instance(struct hci_dev *hdev, struct sock *sk,
+                               struct hci_request *req, u8 instance,
+                               bool force)
 {
        struct adv_info *adv_instance, *n, *next_instance = NULL;
        int err;
@@ -1311,7 +1312,7 @@ void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
                        rem_inst = adv_instance->instance;
                        err = hci_remove_adv_instance(hdev, rem_inst);
                        if (!err)
-                               mgmt_advertising_removed(NULL, hdev, rem_inst);
+                               mgmt_advertising_removed(sk, hdev, rem_inst);
                }
        } else {
                adv_instance = hci_find_adv_instance(hdev, instance);
@@ -1325,7 +1326,7 @@ void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
 
                        err = hci_remove_adv_instance(hdev, instance);
                        if (!err)
-                               mgmt_advertising_removed(NULL, hdev, instance);
+                               mgmt_advertising_removed(sk, hdev, instance);
                }
        }
 
index b2d044bdc732f9ba47f22557459e69e1ec6e5654..ac1e11006f385e2b05df78f026c8d7438c2d368c 100644 (file)
@@ -73,8 +73,9 @@ void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance);
 
 int __hci_req_schedule_adv_instance(struct hci_request *req, u8 instance,
                                    bool force);
-void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
-                               u8 instance, bool force);
+void hci_req_clear_adv_instance(struct hci_dev *hdev, struct sock *sk,
+                               struct hci_request *req, u8 instance,
+                               bool force);
 
 void __hci_req_update_class(struct hci_request *req);
 
index 9071886df19450b356a4dc7c91152db2461f4e8d..f9af5f7c2ea22e61bc137f90e63975b14d29c8da 100644 (file)
@@ -929,7 +929,7 @@ static int clean_up_hci_state(struct hci_dev *hdev)
                hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
        }
 
-       hci_req_clear_adv_instance(hdev, NULL, 0x00, false);
+       hci_req_clear_adv_instance(hdev, NULL, NULL, 0x00, false);
 
        if (hci_dev_test_flag(hdev, HCI_LE_ADV))
                __hci_req_disable_advertising(&req);
@@ -1697,7 +1697,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
        enabled = lmp_host_le_capable(hdev);
 
        if (!val)
-               hci_req_clear_adv_instance(hdev, NULL, 0x00, true);
+               hci_req_clear_adv_instance(hdev, NULL, NULL, 0x00, true);
 
        if (!hdev_is_powered(hdev) || val == enabled) {
                bool changed = false;
@@ -6182,7 +6182,7 @@ static int remove_advertising(struct sock *sk, struct hci_dev *hdev,
 
        hci_req_init(&req, hdev);
 
-       hci_req_clear_adv_instance(hdev, &req, cp->instance, true);
+       hci_req_clear_adv_instance(hdev, sk, &req, cp->instance, true);
 
        if (list_empty(&hdev->adv_instances))
                __hci_req_disable_advertising(&req);