mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
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: Jakub Pawlowski <jpawlowski@google.com> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
695c4cb619
commit
812abb13a9
@ -3921,93 +3921,113 @@ done:
|
||||
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_cp_inquiry cp;
|
||||
/* General inquiry access code (GIAC) */
|
||||
u8 lap[3] = { 0x33, 0x8b, 0x9e };
|
||||
|
||||
*status = mgmt_bredr_support(hdev);
|
||||
if (*status)
|
||||
return false;
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_INQUIRY)) {
|
||||
*status = MGMT_STATUS_BUSY;
|
||||
return false;
|
||||
}
|
||||
|
||||
hci_inquiry_cache_flush(hdev);
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
memcpy(&cp.lap, lap, sizeof(cp.lap));
|
||||
cp.length = DISCOV_BREDR_INQUIRY_LEN;
|
||||
|
||||
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;
|
||||
struct hci_cp_inquiry inq_cp;
|
||||
/* General inquiry access code (GIAC) */
|
||||
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);
|
||||
if (*status)
|
||||
return false;
|
||||
*status = mgmt_le_support(hdev);
|
||||
if (*status)
|
||||
return false;
|
||||
|
||||
if (test_bit(HCI_INQUIRY, &hdev->flags)) {
|
||||
*status = MGMT_STATUS_BUSY;
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_ADV)) {
|
||||
/* Don't let discovery abort an outgoing connection attempt
|
||||
* that's using directed advertising.
|
||||
*/
|
||||
if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
|
||||
*status = MGMT_STATUS_REJECTED;
|
||||
return false;
|
||||
}
|
||||
|
||||
hci_inquiry_cache_flush(hdev);
|
||||
disable_advertising(req);
|
||||
}
|
||||
|
||||
memset(&inq_cp, 0, sizeof(inq_cp));
|
||||
memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap));
|
||||
inq_cp.length = DISCOV_BREDR_INQUIRY_LEN;
|
||||
hci_req_add(req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp);
|
||||
/* If controller is scanning, it means the background scanning is
|
||||
* running. Thus, we should temporarily stop it in order to set the
|
||||
* discovery scanning parameters.
|
||||
*/
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
|
||||
hci_req_add_le_scan_disable(req);
|
||||
|
||||
/* All active scans will be done with either a resolvable private
|
||||
* address (when privacy feature has been enabled) or non-resolvable
|
||||
* private address.
|
||||
*/
|
||||
err = hci_update_random_address(req, true, &own_addr_type);
|
||||
if (err < 0) {
|
||||
*status = MGMT_STATUS_FAILED;
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(¶m_cp, 0, sizeof(param_cp));
|
||||
param_cp.type = LE_SCAN_ACTIVE;
|
||||
param_cp.interval = cpu_to_le16(interval);
|
||||
param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
|
||||
param_cp.own_address_type = own_addr_type;
|
||||
|
||||
hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
|
||||
¶m_cp);
|
||||
|
||||
memset(&enable_cp, 0, sizeof(enable_cp));
|
||||
enable_cp.enable = LE_SCAN_ENABLE;
|
||||
enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
|
||||
|
||||
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(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_LE:
|
||||
case DISCOV_TYPE_INTERLEAVED:
|
||||
*status = mgmt_le_support(hdev);
|
||||
if (*status)
|
||||
return false;
|
||||
|
||||
if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
|
||||
!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
|
||||
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
|
||||
*status = MGMT_STATUS_NOT_SUPPORTED;
|
||||
return false;
|
||||
}
|
||||
/* fall through */
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_ADV)) {
|
||||
/* Don't let discovery abort an outgoing
|
||||
* connection attempt that's using directed
|
||||
* advertising.
|
||||
*/
|
||||
if (hci_conn_hash_lookup_state(hdev, LE_LINK,
|
||||
BT_CONNECT)) {
|
||||
*status = MGMT_STATUS_REJECTED;
|
||||
return false;
|
||||
}
|
||||
|
||||
disable_advertising(req);
|
||||
}
|
||||
|
||||
/* If controller is scanning, it means the background scanning
|
||||
* is running. Thus, we should temporarily stop it in order to
|
||||
* set the discovery scanning parameters.
|
||||
*/
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
|
||||
hci_req_add_le_scan_disable(req);
|
||||
|
||||
memset(¶m_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 private address.
|
||||
*/
|
||||
err = hci_update_random_address(req, true, &own_addr_type);
|
||||
if (err < 0) {
|
||||
*status = MGMT_STATUS_FAILED;
|
||||
case DISCOV_TYPE_LE:
|
||||
if (!trigger_le_scan(req, DISCOV_LE_SCAN_INT, status))
|
||||
return false;
|
||||
}
|
||||
|
||||
param_cp.type = LE_SCAN_ACTIVE;
|
||||
param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
|
||||
param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
|
||||
param_cp.own_address_type = own_addr_type;
|
||||
hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
|
||||
¶m_cp);
|
||||
|
||||
memset(&enable_cp, 0, sizeof(enable_cp));
|
||||
enable_cp.enable = LE_SCAN_ENABLE;
|
||||
enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
|
||||
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
|
||||
&enable_cp);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user