aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@openbossa.org>2013-04-30 14:29:32 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-06-22 19:23:50 -0400
commit4c87eaab01df271c81f6a68e3c28dbd44d348004 (patch)
tree825b77d8f5d384889cb5fa41430913758c76957d /net
parent0d8cc935e01c0fd1312a10881f4c0f1c4b4d05ab (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')
-rw-r--r--net/bluetooth/hci_core.c65
-rw-r--r--net/bluetooth/hci_event.c10
-rw-r--r--net/bluetooth/mgmt.c17
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
2070static 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
2082static 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
2070static void le_scan_disable_work(struct work_struct *work) 2125static 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
2083static void le_scan_work(struct work_struct *work) 2146static 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
2624int 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
2641static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) 2624static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
2642{ 2625{
2643 struct pending_cmd *cmd; 2626 struct pending_cmd *cmd;