Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+85 −65
Original line number Diff line number Diff line
@@ -3921,55 +3921,50 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
	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_le_set_scan_param param_cp;
	struct hci_cp_le_set_scan_enable enable_cp;
	struct hci_cp_inquiry inq_cp;
	struct hci_cp_inquiry 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;

		if (test_bit(HCI_INQUIRY, &hdev->flags)) {
	if (hci_dev_test_flag(hdev, HCI_INQUIRY)) {
		*status = MGMT_STATUS_BUSY;
		return false;
	}

	hci_inquiry_cache_flush(hdev);

		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);
		break;
	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;
	u8 own_addr_type;
	int err;

	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)) {
			*status = MGMT_STATUS_NOT_SUPPORTED;
			return false;
		}

	if (hci_dev_test_flag(hdev, HCI_LE_ADV)) {
			/* Don't let discovery abort an outgoing
			 * connection attempt that's using directed
			 * advertising.
		/* 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)) {
		if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
			*status = MGMT_STATUS_REJECTED;
			return false;
		}
@@ -3977,18 +3972,16 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
		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 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(&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 private address.
	/* 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) {
@@ -3996,18 +3989,45 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
		return false;
	}

	memset(&param_cp, 0, sizeof(param_cp));
	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.own_address_type = own_addr_type;

	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
		    &param_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_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;

	default: