Skip to content

Commit

Permalink
Bluetooth: Refactor discovery stopping into its own function
Browse files Browse the repository at this point in the history
We'll need to reuse the same logic for stopping discovery also when
cleaning up HCI state when powering off. This patch refactors the code
out to its own function that can later (in a subsequent patch) be used
also for the power off case.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Cc: stable@vger.kernel.org
  • Loading branch information
Johan Hedberg authored and Marcel Holtmann committed Jun 13, 2014
1 parent 50143a4 commit 21a60d3
Showing 1 changed file with 49 additions and 44 deletions.
93 changes: 49 additions & 44 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,43 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
}
}

static void hci_stop_discovery(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;
struct hci_cp_remote_name_req_cancel cp;
struct inquiry_entry *e;

switch (hdev->discovery.state) {
case DISCOVERY_FINDING:
if (test_bit(HCI_INQUIRY, &hdev->flags)) {
hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
} else {
cancel_delayed_work(&hdev->le_scan_disable);
hci_req_add_le_scan_disable(req);
}

break;

case DISCOVERY_RESOLVING:
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
NAME_PENDING);
if (!e)
return;

bacpy(&cp.bdaddr, &e->data.bdaddr);
hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
&cp);

break;

default:
/* Passive scanning */
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
hci_req_add_le_scan_disable(req);
break;
}
}

static int clean_up_hci_state(struct hci_dev *hdev)
{
struct hci_request req;
Expand Down Expand Up @@ -3574,8 +3611,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
{
struct mgmt_cp_stop_discovery *mgmt_cp = data;
struct pending_cmd *cmd;
struct hci_cp_remote_name_req_cancel cp;
struct inquiry_entry *e;
struct hci_request req;
int err;

Expand Down Expand Up @@ -3605,52 +3640,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,

hci_req_init(&req, hdev);

switch (hdev->discovery.state) {
case DISCOVERY_FINDING:
if (test_bit(HCI_INQUIRY, &hdev->flags)) {
hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
} else {
cancel_delayed_work(&hdev->le_scan_disable);

hci_req_add_le_scan_disable(&req);
}

break;

case DISCOVERY_RESOLVING:
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
NAME_PENDING);
if (!e) {
mgmt_pending_remove(cmd);
err = cmd_complete(sk, hdev->id,
MGMT_OP_STOP_DISCOVERY, 0,
&mgmt_cp->type,
sizeof(mgmt_cp->type));
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
goto unlock;
}

bacpy(&cp.bdaddr, &e->data.bdaddr);
hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
&cp);
hci_stop_discovery(&req);

break;

default:
BT_DBG("unknown discovery state %u", hdev->discovery.state);

mgmt_pending_remove(cmd);
err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
MGMT_STATUS_FAILED, &mgmt_cp->type,
sizeof(mgmt_cp->type));
err = hci_req_run(&req, stop_discovery_complete);
if (!err) {
hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
goto unlock;
}

err = hci_req_run(&req, stop_discovery_complete);
if (err < 0)
mgmt_pending_remove(cmd);
else
hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
mgmt_pending_remove(cmd);

/* If no HCI commands were sent we're done */
if (err == -ENODATA) {
err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
&mgmt_cp->type, sizeof(mgmt_cp->type));
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
}

unlock:
hci_dev_unlock(hdev);
Expand Down

0 comments on commit 21a60d3

Please sign in to comment.