diff options
author | Andre Guedes <andre.guedes@openbossa.org> | 2013-04-30 14:29:32 -0400 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-06-22 19:23:50 -0400 |
commit | 4c87eaab01df271c81f6a68e3c28dbd44d348004 (patch) | |
tree | 825b77d8f5d384889cb5fa41430913758c76957d /net/bluetooth | |
parent | 0d8cc935e01c0fd1312a10881f4c0f1c4b4d05ab (diff) |
Bluetooth: Use HCI request in interleaved discovery
In order to have a better HCI error handling in interleaved discovery
functionality, we should use the HCI request framework.
This patch updates le_scan_disable_work function so it uses the
HCI request framework instead of the hci_send_cmd helper. A complete
callback is registered (le_scan_disable_work_complete function) so we
are able to trigger the inquiry procedure (if we are running the
interleaved discovery) or to stop the discovery procedure (if we are
running LE-only discovery).
This patch also removes the extra logic in hci_cc_le_set_scan_enable
to trigger the inquiry procedure and the mgmt_interleaved_discovery
function since they become useless.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 65 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 10 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 17 |
3 files changed, 64 insertions, 28 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 43c63877c5b7..9270d7ee489d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -2067,17 +2067,80 @@ int hci_cancel_le_scan(struct hci_dev *hdev) | |||
2067 | return 0; | 2067 | return 0; |
2068 | } | 2068 | } |
2069 | 2069 | ||
2070 | static void inquiry_complete(struct hci_dev *hdev, u8 status) | ||
2071 | { | ||
2072 | if (status) { | ||
2073 | BT_ERR("Failed to start inquiry: status %d", status); | ||
2074 | |||
2075 | hci_dev_lock(hdev); | ||
2076 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2077 | hci_dev_unlock(hdev); | ||
2078 | return; | ||
2079 | } | ||
2080 | } | ||
2081 | |||
2082 | static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) | ||
2083 | { | ||
2084 | /* General inquiry access code (GIAC) */ | ||
2085 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
2086 | struct hci_request req; | ||
2087 | struct hci_cp_inquiry cp; | ||
2088 | int err; | ||
2089 | |||
2090 | if (status) { | ||
2091 | BT_ERR("Failed to disable LE scanning: status %d", status); | ||
2092 | return; | ||
2093 | } | ||
2094 | |||
2095 | switch (hdev->discovery.type) { | ||
2096 | case DISCOV_TYPE_LE: | ||
2097 | hci_dev_lock(hdev); | ||
2098 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2099 | hci_dev_unlock(hdev); | ||
2100 | break; | ||
2101 | |||
2102 | case DISCOV_TYPE_INTERLEAVED: | ||
2103 | hci_req_init(&req, hdev); | ||
2104 | |||
2105 | memset(&cp, 0, sizeof(cp)); | ||
2106 | memcpy(&cp.lap, lap, sizeof(cp.lap)); | ||
2107 | cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; | ||
2108 | hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
2109 | |||
2110 | hci_dev_lock(hdev); | ||
2111 | |||
2112 | hci_inquiry_cache_flush(hdev); | ||
2113 | |||
2114 | err = hci_req_run(&req, inquiry_complete); | ||
2115 | if (err) { | ||
2116 | BT_ERR("Inquiry request failed: err %d", err); | ||
2117 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2118 | } | ||
2119 | |||
2120 | hci_dev_unlock(hdev); | ||
2121 | break; | ||
2122 | } | ||
2123 | } | ||
2124 | |||
2070 | static void le_scan_disable_work(struct work_struct *work) | 2125 | static void le_scan_disable_work(struct work_struct *work) |
2071 | { | 2126 | { |
2072 | struct hci_dev *hdev = container_of(work, struct hci_dev, | 2127 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
2073 | le_scan_disable.work); | 2128 | le_scan_disable.work); |
2074 | struct hci_cp_le_set_scan_enable cp; | 2129 | struct hci_cp_le_set_scan_enable cp; |
2130 | struct hci_request req; | ||
2131 | int err; | ||
2075 | 2132 | ||
2076 | BT_DBG("%s", hdev->name); | 2133 | BT_DBG("%s", hdev->name); |
2077 | 2134 | ||
2135 | hci_req_init(&req, hdev); | ||
2136 | |||
2078 | memset(&cp, 0, sizeof(cp)); | 2137 | memset(&cp, 0, sizeof(cp)); |
2138 | cp.enable = LE_SCAN_DISABLE; | ||
2139 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2079 | 2140 | ||
2080 | hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | 2141 | err = hci_req_run(&req, le_scan_disable_work_complete); |
2142 | if (err) | ||
2143 | BT_ERR("Disable LE scanning request failed: err %d", err); | ||
2081 | } | 2144 | } |
2082 | 2145 | ||
2083 | static void le_scan_work(struct work_struct *work) | 2146 | static void le_scan_work(struct work_struct *work) |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0e71e6c47391..faaf1f31345d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -974,16 +974,6 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
974 | } | 974 | } |
975 | 975 | ||
976 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); | 976 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); |
977 | |||
978 | if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && | ||
979 | hdev->discovery.state == DISCOVERY_FINDING) { | ||
980 | mgmt_interleaved_discovery(hdev); | ||
981 | } else { | ||
982 | hci_dev_lock(hdev); | ||
983 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
984 | hci_dev_unlock(hdev); | ||
985 | } | ||
986 | |||
987 | break; | 977 | break; |
988 | 978 | ||
989 | default: | 979 | default: |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 6b31e93af761..743100f3ab9c 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2621,23 +2621,6 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
2621 | return err; | 2621 | return err; |
2622 | } | 2622 | } |
2623 | 2623 | ||
2624 | int mgmt_interleaved_discovery(struct hci_dev *hdev) | ||
2625 | { | ||
2626 | int err; | ||
2627 | |||
2628 | BT_DBG("%s", hdev->name); | ||
2629 | |||
2630 | hci_dev_lock(hdev); | ||
2631 | |||
2632 | err = hci_do_inquiry(hdev, DISCOV_INTERLEAVED_INQUIRY_LEN); | ||
2633 | if (err < 0) | ||
2634 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2635 | |||
2636 | hci_dev_unlock(hdev); | ||
2637 | |||
2638 | return err; | ||
2639 | } | ||
2640 | |||
2641 | static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) | 2624 | static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) |
2642 | { | 2625 | { |
2643 | struct pending_cmd *cmd; | 2626 | struct pending_cmd *cmd; |