Skip to content

Commit

Permalink
Bluetooth: mgmt: Fix sending redundant event for Advertising Instance
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johan Hedberg authored and Marcel Holtmann committed Sep 19, 2016
1 parent 38ceaa0 commit 37d3a1f
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 10 deletions.
11 changes: 6 additions & 5 deletions net/bluetooth/hci_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
}
}

Expand Down
5 changes: 3 additions & 2 deletions net/bluetooth/hci_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 37d3a1f

Please sign in to comment.