diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 104 |
1 files changed, 56 insertions, 48 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 0fce54412ffd..af8e0a6243b7 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -1047,6 +1047,43 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status) | |||
1047 | } | 1047 | } |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | static void hci_stop_discovery(struct hci_request *req) | ||
1051 | { | ||
1052 | struct hci_dev *hdev = req->hdev; | ||
1053 | struct hci_cp_remote_name_req_cancel cp; | ||
1054 | struct inquiry_entry *e; | ||
1055 | |||
1056 | switch (hdev->discovery.state) { | ||
1057 | case DISCOVERY_FINDING: | ||
1058 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { | ||
1059 | hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
1060 | } else { | ||
1061 | cancel_delayed_work(&hdev->le_scan_disable); | ||
1062 | hci_req_add_le_scan_disable(req); | ||
1063 | } | ||
1064 | |||
1065 | break; | ||
1066 | |||
1067 | case DISCOVERY_RESOLVING: | ||
1068 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, | ||
1069 | NAME_PENDING); | ||
1070 | if (!e) | ||
1071 | return; | ||
1072 | |||
1073 | bacpy(&cp.bdaddr, &e->data.bdaddr); | ||
1074 | hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), | ||
1075 | &cp); | ||
1076 | |||
1077 | break; | ||
1078 | |||
1079 | default: | ||
1080 | /* Passive scanning */ | ||
1081 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | ||
1082 | hci_req_add_le_scan_disable(req); | ||
1083 | break; | ||
1084 | } | ||
1085 | } | ||
1086 | |||
1050 | static int clean_up_hci_state(struct hci_dev *hdev) | 1087 | static int clean_up_hci_state(struct hci_dev *hdev) |
1051 | { | 1088 | { |
1052 | struct hci_request req; | 1089 | struct hci_request req; |
@@ -1063,9 +1100,7 @@ static int clean_up_hci_state(struct hci_dev *hdev) | |||
1063 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) | 1100 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) |
1064 | disable_advertising(&req); | 1101 | disable_advertising(&req); |
1065 | 1102 | ||
1066 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) { | 1103 | hci_stop_discovery(&req); |
1067 | hci_req_add_le_scan_disable(&req); | ||
1068 | } | ||
1069 | 1104 | ||
1070 | list_for_each_entry(conn, &hdev->conn_hash.list, list) { | 1105 | list_for_each_entry(conn, &hdev->conn_hash.list, list) { |
1071 | struct hci_cp_disconnect dc; | 1106 | struct hci_cp_disconnect dc; |
@@ -2996,8 +3031,13 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev, | |||
2996 | } | 3031 | } |
2997 | 3032 | ||
2998 | if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) { | 3033 | if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) { |
2999 | /* Continue with pairing via SMP */ | 3034 | /* Continue with pairing via SMP. The hdev lock must be |
3035 | * released as SMP may try to recquire it for crypto | ||
3036 | * purposes. | ||
3037 | */ | ||
3038 | hci_dev_unlock(hdev); | ||
3000 | err = smp_user_confirm_reply(conn, mgmt_op, passkey); | 3039 | err = smp_user_confirm_reply(conn, mgmt_op, passkey); |
3040 | hci_dev_lock(hdev); | ||
3001 | 3041 | ||
3002 | if (!err) | 3042 | if (!err) |
3003 | err = cmd_complete(sk, hdev->id, mgmt_op, | 3043 | err = cmd_complete(sk, hdev->id, mgmt_op, |
@@ -3574,8 +3614,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
3574 | { | 3614 | { |
3575 | struct mgmt_cp_stop_discovery *mgmt_cp = data; | 3615 | struct mgmt_cp_stop_discovery *mgmt_cp = data; |
3576 | struct pending_cmd *cmd; | 3616 | struct pending_cmd *cmd; |
3577 | struct hci_cp_remote_name_req_cancel cp; | ||
3578 | struct inquiry_entry *e; | ||
3579 | struct hci_request req; | 3617 | struct hci_request req; |
3580 | int err; | 3618 | int err; |
3581 | 3619 | ||
@@ -3605,52 +3643,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
3605 | 3643 | ||
3606 | hci_req_init(&req, hdev); | 3644 | hci_req_init(&req, hdev); |
3607 | 3645 | ||
3608 | switch (hdev->discovery.state) { | 3646 | hci_stop_discovery(&req); |
3609 | case DISCOVERY_FINDING: | ||
3610 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { | ||
3611 | hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
3612 | } else { | ||
3613 | cancel_delayed_work(&hdev->le_scan_disable); | ||
3614 | |||
3615 | hci_req_add_le_scan_disable(&req); | ||
3616 | } | ||
3617 | |||
3618 | break; | ||
3619 | 3647 | ||
3620 | case DISCOVERY_RESOLVING: | 3648 | err = hci_req_run(&req, stop_discovery_complete); |
3621 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, | 3649 | if (!err) { |
3622 | NAME_PENDING); | 3650 | hci_discovery_set_state(hdev, DISCOVERY_STOPPING); |
3623 | if (!e) { | ||
3624 | mgmt_pending_remove(cmd); | ||
3625 | err = cmd_complete(sk, hdev->id, | ||
3626 | MGMT_OP_STOP_DISCOVERY, 0, | ||
3627 | &mgmt_cp->type, | ||
3628 | sizeof(mgmt_cp->type)); | ||
3629 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
3630 | goto unlock; | ||
3631 | } | ||
3632 | |||
3633 | bacpy(&cp.bdaddr, &e->data.bdaddr); | ||
3634 | hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), | ||
3635 | &cp); | ||
3636 | |||
3637 | break; | ||
3638 | |||
3639 | default: | ||
3640 | BT_DBG("unknown discovery state %u", hdev->discovery.state); | ||
3641 | |||
3642 | mgmt_pending_remove(cmd); | ||
3643 | err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, | ||
3644 | MGMT_STATUS_FAILED, &mgmt_cp->type, | ||
3645 | sizeof(mgmt_cp->type)); | ||
3646 | goto unlock; | 3651 | goto unlock; |
3647 | } | 3652 | } |
3648 | 3653 | ||
3649 | err = hci_req_run(&req, stop_discovery_complete); | 3654 | mgmt_pending_remove(cmd); |
3650 | if (err < 0) | 3655 | |
3651 | mgmt_pending_remove(cmd); | 3656 | /* If no HCI commands were sent we're done */ |
3652 | else | 3657 | if (err == -ENODATA) { |
3653 | hci_discovery_set_state(hdev, DISCOVERY_STOPPING); | 3658 | err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0, |
3659 | &mgmt_cp->type, sizeof(mgmt_cp->type)); | ||
3660 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
3661 | } | ||
3654 | 3662 | ||
3655 | unlock: | 3663 | unlock: |
3656 | hci_dev_unlock(hdev); | 3664 | hci_dev_unlock(hdev); |