diff options
Diffstat (limited to 'net/bluetooth/hci_core.c')
-rw-r--r-- | net/bluetooth/hci_core.c | 65 |
1 files changed, 64 insertions, 1 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) |