Bluetooth: hci_sync: Use QoS to determine which PHY to scan

This used the hci_conn QoS to determine which PHY to scan when creating
a PA Sync.
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent bba71ef1
...@@ -2754,6 +2754,14 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) ...@@ -2754,6 +2754,14 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
return filter_policy; return filter_policy;
} }
static void hci_le_scan_phy_params(struct hci_cp_le_scan_phy_params *cp,
u8 type, u16 interval, u16 window)
{
cp->type = type;
cp->interval = cpu_to_le16(interval);
cp->window = cpu_to_le16(window);
}
static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type, static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
u16 interval, u16 window, u16 interval, u16 window,
u8 own_addr_type, u8 filter_policy) u8 own_addr_type, u8 filter_policy)
...@@ -2761,7 +2769,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type, ...@@ -2761,7 +2769,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
struct hci_cp_le_set_ext_scan_params *cp; struct hci_cp_le_set_ext_scan_params *cp;
struct hci_cp_le_scan_phy_params *phy; struct hci_cp_le_scan_phy_params *phy;
u8 data[sizeof(*cp) + sizeof(*phy) * 2]; u8 data[sizeof(*cp) + sizeof(*phy) * 2];
u8 num_phy = 0; u8 num_phy = 0x00;
cp = (void *)data; cp = (void *)data;
phy = (void *)cp->data; phy = (void *)cp->data;
...@@ -2771,28 +2779,64 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type, ...@@ -2771,28 +2779,64 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
cp->own_addr_type = own_addr_type; cp->own_addr_type = own_addr_type;
cp->filter_policy = filter_policy; cp->filter_policy = filter_policy;
if (scan_1m(hdev) || scan_2m(hdev)) { /* Check if PA Sync is in progress then select the PHY based on the
cp->scanning_phys |= LE_SCAN_PHY_1M; * hci_conn.iso_qos.
*/
if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
struct hci_cp_le_add_to_accept_list *sent;
phy->type = type; sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
phy->interval = cpu_to_le16(interval); if (sent) {
phy->window = cpu_to_le16(window); struct hci_conn *conn;
conn = hci_conn_hash_lookup_ba(hdev, ISO_LINK,
&sent->bdaddr);
if (conn) {
struct bt_iso_qos *qos = &conn->iso_qos;
if (qos->bcast.in.phy & BT_ISO_PHY_1M ||
qos->bcast.in.phy & BT_ISO_PHY_2M) {
cp->scanning_phys |= LE_SCAN_PHY_1M;
hci_le_scan_phy_params(phy, type,
interval,
window);
num_phy++; num_phy++;
phy++; phy++;
} }
if (scan_coded(hdev)) { if (qos->bcast.in.phy & BT_ISO_PHY_CODED) {
cp->scanning_phys |= LE_SCAN_PHY_CODED; cp->scanning_phys |= LE_SCAN_PHY_CODED;
hci_le_scan_phy_params(phy, type,
interval,
window);
num_phy++;
phy++;
}
phy->type = type; if (num_phy)
phy->interval = cpu_to_le16(interval); goto done;
phy->window = cpu_to_le16(window); }
}
}
if (scan_1m(hdev) || scan_2m(hdev)) {
cp->scanning_phys |= LE_SCAN_PHY_1M;
hci_le_scan_phy_params(phy, type, interval, window);
num_phy++; num_phy++;
phy++; phy++;
} }
if (scan_coded(hdev)) {
cp->scanning_phys |= LE_SCAN_PHY_CODED;
hci_le_scan_phy_params(phy, type, interval, window);
num_phy++;
phy++;
}
done:
if (!num_phy)
return -EINVAL;
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS, return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS,
sizeof(*cp) + sizeof(*phy) * num_phy, sizeof(*cp) + sizeof(*phy) * num_phy,
data, HCI_CMD_TIMEOUT); data, HCI_CMD_TIMEOUT);
......
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