mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-19 08:05:27 +08:00
Bluetooth: Interleaved discovery support
This patch adds interleaved discovery support to MGMT Start Discovery command. In case interleaved discovery is not supported (not a dual mode device), we perform BR/EDR or LE-only discovery according to the device capabilities. Signed-off-by: Andre Guedes <andre.guedes@openbossa.org> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
343f935bfa
commit
5e0452c00a
@ -716,6 +716,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
|
||||
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
|
||||
#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
|
||||
#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
|
||||
#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR))
|
||||
|
||||
/* ----- Extended LMP capabilities ----- */
|
||||
#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE)
|
||||
@ -1019,6 +1020,7 @@ int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
||||
int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
|
||||
int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
|
||||
int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
|
||||
int mgmt_interleaved_discovery(struct hci_dev *hdev);
|
||||
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
|
||||
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
|
||||
|
||||
|
@ -1090,11 +1090,16 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
|
||||
|
||||
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
|
||||
|
||||
if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
|
||||
mgmt_interleaved_discovery(hdev);
|
||||
} else {
|
||||
hci_dev_lock(hdev);
|
||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -108,8 +108,10 @@ static const u16 mgmt_events[] = {
|
||||
#define LE_SCAN_WIN 0x12
|
||||
#define LE_SCAN_INT 0x12
|
||||
#define LE_SCAN_TIMEOUT_LE_ONLY 10240 /* TGAP(gen_disc_scan_min) */
|
||||
#define LE_SCAN_TIMEOUT_BREDR_LE 5120 /* TGAP(100)/2 */
|
||||
|
||||
#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */
|
||||
#define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */
|
||||
|
||||
#define SERVICE_CACHE_TIMEOUT (5 * 1000)
|
||||
|
||||
@ -2153,6 +2155,46 @@ static int remove_remote_oob_data(struct sock *sk, u16 index,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int discovery(struct hci_dev *hdev)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (lmp_host_le_capable(hdev)) {
|
||||
if (lmp_bredr_capable(hdev)) {
|
||||
err = hci_le_scan(hdev, LE_SCAN_TYPE,
|
||||
LE_SCAN_INT, LE_SCAN_WIN,
|
||||
LE_SCAN_TIMEOUT_BREDR_LE);
|
||||
} else {
|
||||
hdev->discovery.type = DISCOV_TYPE_LE;
|
||||
err = hci_le_scan(hdev, LE_SCAN_TYPE,
|
||||
LE_SCAN_INT, LE_SCAN_WIN,
|
||||
LE_SCAN_TIMEOUT_LE_ONLY);
|
||||
}
|
||||
} else {
|
||||
hdev->discovery.type = DISCOV_TYPE_BREDR;
|
||||
err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mgmt_interleaved_discovery(struct hci_dev *hdev)
|
||||
{
|
||||
int err;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR_LE);
|
||||
if (err < 0)
|
||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int start_discovery(struct sock *sk, u16 index,
|
||||
void *data, u16 len)
|
||||
{
|
||||
@ -2196,7 +2238,6 @@ static int start_discovery(struct sock *sk, u16 index,
|
||||
|
||||
switch (hdev->discovery.type) {
|
||||
case DISCOV_TYPE_BREDR:
|
||||
case DISCOV_TYPE_INTERLEAVED:
|
||||
err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
|
||||
break;
|
||||
|
||||
@ -2205,6 +2246,10 @@ static int start_discovery(struct sock *sk, u16 index,
|
||||
LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
|
||||
break;
|
||||
|
||||
case DISCOV_TYPE_INTERLEAVED:
|
||||
err = discovery(hdev);
|
||||
break;
|
||||
|
||||
default:
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user