Commit 812abb13 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Johan Hedberg

Bluetooth: Refactor BR/EDR inquiry and LE scan triggering.

This patch refactor BR/EDR inquiry and LE scan triggering logic into
separate methods.
Signed-off-by: default avatarJakub Pawlowski <jpawlowski@google.com>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
parent 695c4cb6
...@@ -3921,55 +3921,50 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, ...@@ -3921,55 +3921,50 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
return err; return err;
} }
static bool trigger_discovery(struct hci_request *req, u8 *status) static bool trigger_bredr_inquiry(struct hci_request *req, u8 *status)
{ {
struct hci_dev *hdev = req->hdev; struct hci_dev *hdev = req->hdev;
struct hci_cp_le_set_scan_param param_cp; struct hci_cp_inquiry cp;
struct hci_cp_le_set_scan_enable enable_cp;
struct hci_cp_inquiry inq_cp;
/* General inquiry access code (GIAC) */ /* General inquiry access code (GIAC) */
u8 lap[3] = { 0x33, 0x8b, 0x9e }; u8 lap[3] = { 0x33, 0x8b, 0x9e };
u8 own_addr_type;
int err;
switch (hdev->discovery.type) {
case DISCOV_TYPE_BREDR:
*status = mgmt_bredr_support(hdev); *status = mgmt_bredr_support(hdev);
if (*status) if (*status)
return false; return false;
if (test_bit(HCI_INQUIRY, &hdev->flags)) { if (hci_dev_test_flag(hdev, HCI_INQUIRY)) {
*status = MGMT_STATUS_BUSY; *status = MGMT_STATUS_BUSY;
return false; return false;
} }
hci_inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev);
memset(&inq_cp, 0, sizeof(inq_cp)); memset(&cp, 0, sizeof(cp));
memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap)); memcpy(&cp.lap, lap, sizeof(cp.lap));
inq_cp.length = DISCOV_BREDR_INQUIRY_LEN; cp.length = DISCOV_BREDR_INQUIRY_LEN;
hci_req_add(req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp);
break; hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
return true;
}
static bool trigger_le_scan(struct hci_request *req, u16 interval, u8 *status)
{
struct hci_dev *hdev = req->hdev;
struct hci_cp_le_set_scan_param param_cp;
struct hci_cp_le_set_scan_enable enable_cp;
u8 own_addr_type;
int err;
case DISCOV_TYPE_LE:
case DISCOV_TYPE_INTERLEAVED:
*status = mgmt_le_support(hdev); *status = mgmt_le_support(hdev);
if (*status) if (*status)
return false; return false;
if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
*status = MGMT_STATUS_NOT_SUPPORTED;
return false;
}
if (hci_dev_test_flag(hdev, HCI_LE_ADV)) { if (hci_dev_test_flag(hdev, HCI_LE_ADV)) {
/* Don't let discovery abort an outgoing /* Don't let discovery abort an outgoing connection attempt
* connection attempt that's using directed * that's using directed advertising.
* advertising.
*/ */
if (hci_conn_hash_lookup_state(hdev, LE_LINK, if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
BT_CONNECT)) {
*status = MGMT_STATUS_REJECTED; *status = MGMT_STATUS_REJECTED;
return false; return false;
} }
...@@ -3977,18 +3972,16 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) ...@@ -3977,18 +3972,16 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
disable_advertising(req); disable_advertising(req);
} }
/* If controller is scanning, it means the background scanning /* If controller is scanning, it means the background scanning is
* is running. Thus, we should temporarily stop it in order to * running. Thus, we should temporarily stop it in order to set the
* set the discovery scanning parameters. * discovery scanning parameters.
*/ */
if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
hci_req_add_le_scan_disable(req); hci_req_add_le_scan_disable(req);
memset(&param_cp, 0, sizeof(param_cp)); /* All active scans will be done with either a resolvable private
* address (when privacy feature has been enabled) or non-resolvable
/* All active scans will be done with either a resolvable * private address.
* private address (when privacy feature has been enabled)
* or non-resolvable private address.
*/ */
err = hci_update_random_address(req, true, &own_addr_type); err = hci_update_random_address(req, true, &own_addr_type);
if (err < 0) { if (err < 0) {
...@@ -3996,18 +3989,45 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) ...@@ -3996,18 +3989,45 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
return false; return false;
} }
memset(&param_cp, 0, sizeof(param_cp));
param_cp.type = LE_SCAN_ACTIVE; param_cp.type = LE_SCAN_ACTIVE;
param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); param_cp.interval = cpu_to_le16(interval);
param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
param_cp.own_address_type = own_addr_type; param_cp.own_address_type = own_addr_type;
hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
&param_cp); &param_cp);
memset(&enable_cp, 0, sizeof(enable_cp)); memset(&enable_cp, 0, sizeof(enable_cp));
enable_cp.enable = LE_SCAN_ENABLE; enable_cp.enable = LE_SCAN_ENABLE;
enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
&enable_cp); &enable_cp);
return true;
}
static bool trigger_discovery(struct hci_request *req, u8 *status)
{
struct hci_dev *hdev = req->hdev;
switch (hdev->discovery.type) {
case DISCOV_TYPE_BREDR:
if (!trigger_bredr_inquiry(req, status))
return false;
break;
case DISCOV_TYPE_INTERLEAVED:
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
*status = MGMT_STATUS_NOT_SUPPORTED;
return false;
}
/* fall through */
case DISCOV_TYPE_LE:
if (!trigger_le_scan(req, DISCOV_LE_SCAN_INT, status))
return false;
break; break;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment