Commit 5842c01a authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz
Browse files

Bluetooth: ISO: Fix not using bc_sid as advertisement SID



Currently bc_sid is being ignore when acting as Broadcast Source role,
so this fix it by passing the bc_sid and then use it when programming
the PA:

< HCI Command: LE Set Exte.. (0x08|0x0036) plen 25
        Handle: 0x01
        Properties: 0x0000
        Min advertising interval: 140.000 msec (0x00e0)
        Max advertising interval: 140.000 msec (0x00e0)
        Channel map: 37, 38, 39 (0x07)
        Own address type: Random (0x01)
        Peer address type: Public (0x00)
        Peer address: 00:00:00:00:00:00 (OUI 00-00-00)
        Filter policy: Allow Scan Request from Any, Allow Connect Request from Any (0x00)
        TX power: Host has no preference (0x7f)
        Primary PHY: LE 1M (0x01)
        Secondary max skip: 0x00
        Secondary PHY: LE 2M (0x02)
        SID: 0x01
        Scan request notifications: Disabled (0x00)

Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 2df108c2
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -242,6 +242,7 @@ struct adv_info {
	__u8	mesh;
	__u8	instance;
	__u8	handle;
	__u8	sid;
	__u32	flags;
	__u16	timeout;
	__u16	remaining_time;
@@ -1551,13 +1552,14 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
				 u16 timeout);
struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
			      __u8 dst_type, struct bt_iso_qos *qos);
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
			      struct bt_iso_qos *qos,
			      __u8 base_len, __u8 *base);
struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
				 __u8 dst_type, struct bt_iso_qos *qos);
struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
				 __u8 dst_type, struct bt_iso_qos *qos,
				 __u8 dst_type, __u8 sid,
				 struct bt_iso_qos *qos,
				 __u8 data_len, __u8 *data);
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
		       __u8 dst_type, __u8 sid, struct bt_iso_qos *qos);
@@ -1832,6 +1834,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,

void hci_adv_instances_clear(struct hci_dev *hdev);
struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance);
struct adv_info *hci_find_adv_sid(struct hci_dev *hdev, u8 sid);
struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance);
struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
				      u32 flags, u16 adv_data_len, u8 *adv_data,
@@ -1839,7 +1842,7 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
				      u16 timeout, u16 duration, s8 tx_power,
				      u32 min_interval, u32 max_interval,
				      u8 mesh_handle);
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance, u8 sid,
				      u32 flags, u8 data_len, u8 *data,
				      u32 min_interval, u32 max_interval);
int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
+2 −2
Original line number Diff line number Diff line
@@ -115,8 +115,8 @@ int hci_enable_ext_advertising_sync(struct hci_dev *hdev, u8 instance);
int hci_enable_advertising_sync(struct hci_dev *hdev);
int hci_enable_advertising(struct hci_dev *hdev);

int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
			   u8 *data, u32 flags, u16 min_interval,
int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 sid,
			   u8 data_len, u8 *data, u32 flags, u16 min_interval,
			   u16 max_interval, u16 sync_interval);

int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance);
+24 −7
Original line number Diff line number Diff line
@@ -1501,8 +1501,8 @@ static int qos_set_bis(struct hci_dev *hdev, struct bt_iso_qos *qos)

/* This function requires the caller holds hdev->lock */
static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
				    struct bt_iso_qos *qos, __u8 base_len,
				    __u8 *base)
				    __u8 sid, struct bt_iso_qos *qos,
				    __u8 base_len, __u8 *base)
{
	struct hci_conn *conn;
	int err;
@@ -1543,6 +1543,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
		return conn;

	conn->state = BT_CONNECT;
	conn->sid = sid;

	hci_conn_hold(conn);
	return conn;
@@ -2062,7 +2063,8 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
	if (qos->bcast.bis)
		sync_interval = interval * 4;

	err = hci_start_per_adv_sync(hdev, qos->bcast.bis, conn->le_per_adv_data_len,
	err = hci_start_per_adv_sync(hdev, qos->bcast.bis, conn->sid,
				     conn->le_per_adv_data_len,
				     conn->le_per_adv_data, flags, interval,
				     interval, sync_interval);
	if (err)
@@ -2134,7 +2136,7 @@ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
	}
}

struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
			      struct bt_iso_qos *qos,
			      __u8 base_len, __u8 *base)
{
@@ -2156,7 +2158,7 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
						   base, base_len);

	/* We need hci_conn object using the BDADDR_ANY as dst */
	conn = hci_add_bis(hdev, dst, qos, base_len, eir);
	conn = hci_add_bis(hdev, dst, sid, qos, base_len, eir);
	if (IS_ERR(conn))
		return conn;

@@ -2207,20 +2209,35 @@ static void bis_mark_per_adv(struct hci_conn *conn, void *data)
}

struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
				 __u8 dst_type, struct bt_iso_qos *qos,
				 __u8 dst_type, __u8 sid,
				 struct bt_iso_qos *qos,
				 __u8 base_len, __u8 *base)
{
	struct hci_conn *conn;
	int err;
	struct iso_list_data data;

	conn = hci_bind_bis(hdev, dst, qos, base_len, base);
	conn = hci_bind_bis(hdev, dst, sid, qos, base_len, base);
	if (IS_ERR(conn))
		return conn;

	if (conn->state == BT_CONNECTED)
		return conn;

	/* Check if SID needs to be allocated then search for the first
	 * available.
	 */
	if (conn->sid == HCI_SID_INVALID) {
		u8 sid;

		for (sid = 0; sid <= 0x0f; sid++) {
			if (!hci_find_adv_sid(hdev, sid)) {
				conn->sid = sid;
				break;
			}
		}
	}

	data.big = qos->bcast.big;
	data.bis = qos->bcast.bis;

+15 −1
Original line number Diff line number Diff line
@@ -1584,6 +1584,19 @@ struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
	return NULL;
}

/* This function requires the caller holds hdev->lock */
struct adv_info *hci_find_adv_sid(struct hci_dev *hdev, u8 sid)
{
	struct adv_info *adv;

	list_for_each_entry(adv, &hdev->adv_instances, list) {
		if (adv->sid == sid)
			return adv;
	}

	return NULL;
}

/* This function requires the caller holds hdev->lock */
struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
{
@@ -1736,7 +1749,7 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
}

/* This function requires the caller holds hdev->lock */
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance, u8 sid,
				      u32 flags, u8 data_len, u8 *data,
				      u32 min_interval, u32 max_interval)
{
@@ -1748,6 +1761,7 @@ struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
	if (IS_ERR(adv))
		return adv;

	adv->sid = sid;
	adv->periodic = true;
	adv->per_adv_data_len = data_len;

+17 −3
Original line number Diff line number Diff line
@@ -1261,10 +1261,12 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
		hci_cpu_to_le24(adv->min_interval, cp.min_interval);
		hci_cpu_to_le24(adv->max_interval, cp.max_interval);
		cp.tx_power = adv->tx_power;
		cp.sid = adv->sid;
	} else {
		hci_cpu_to_le24(hdev->le_adv_min_interval, cp.min_interval);
		hci_cpu_to_le24(hdev->le_adv_max_interval, cp.max_interval);
		cp.tx_power = HCI_ADV_TX_POWER_NO_PREFERENCE;
		cp.sid = 0x00;
	}

	secondary_adv = (flags & MGMT_ADV_FLAG_SEC_MASK);
@@ -1594,8 +1596,8 @@ static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
	return hci_update_adv_data_sync(hdev, adv->instance);
}

int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
			   u8 *data, u32 flags, u16 min_interval,
int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 sid,
			   u8 data_len, u8 *data, u32 flags, u16 min_interval,
			   u16 max_interval, u16 sync_interval)
{
	struct adv_info *adv = NULL;
@@ -1607,6 +1609,18 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
	if (instance) {
		adv = hci_find_adv_instance(hdev, instance);
		if (adv) {
			if (sid != HCI_SID_INVALID && adv->sid != sid) {
				/* If the SID don't match attempt to find by
				 * SID.
				 */
				adv = hci_find_adv_sid(hdev, sid);
				if (!adv) {
					bt_dev_err(hdev,
						   "Unable to find adv_info");
					return -EINVAL;
				}
			}

			/* Turn it into periodic advertising */
			adv->periodic = true;
			adv->per_adv_data_len = data_len;
@@ -1615,7 +1629,7 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
			adv->flags = flags;
		} else if (!adv) {
			/* Create an instance if that could not be found */
			adv = hci_add_per_instance(hdev, instance, flags,
			adv = hci_add_per_instance(hdev, instance, sid, flags,
						   data_len, data,
						   sync_interval,
						   sync_interval);
Loading