Re: [PATCH v4] Bluetooth: hci_event: Fix parsing of CIS Established Event

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Luiz,

to, 2023-06-22 kello 12:27 -0700, Luiz Augusto von Dentz kirjoitti:
> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
> 
> The ISO Interval on CIS Established Event uses 1.25 ms slots:
> 
>     BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
>     page 2304:
> 
>       Time = N * 1.25 ms
> 
> In addition to that this always update the QoS settings based on CIS
> Established Event.
> 
> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
> ---
>  net/bluetooth/hci_event.c | 36 +++++++++++++++++++++++-------------
>  1 file changed, 23 insertions(+), 13 deletions(-)
> 
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index b1aefe4bb751..049aa7f6a7c5 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -6822,6 +6822,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
>  {
>  	struct hci_evt_le_cis_established *ev = data;
>  	struct hci_conn *conn;
> +	struct bt_iso_qos *qos;
>  	bool pending = false;
>  	u16 handle = __le16_to_cpu(ev->handle);
>  
> @@ -6846,21 +6847,30 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
>  
>  	pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags);
>  
> -	if (conn->role == HCI_ROLE_SLAVE) {
> -		__le32 interval;
> +	qos = &conn->iso_qos;
>  
> -		memset(&interval, 0, sizeof(interval));
> +	/* Convert ISO Interval (1.25 ms slots) to latency (ms) */
> +	qos->ucast.in.latency = DIV_ROUND_CLOSEST(le16_to_cpu(ev->interval) *
> +						  125, 100);
> +	qos->ucast.out.latency = qos->ucast.in.latency;

In Set CIG Parameters:
u16 ucast.latency = Max_Transport_Latency (ms)
u32 ucast.interval = SDU_Interval (us)

Here:
u16 ucast.latency = ISO_Interval (ms)
u32 ucast.interval = Transport_Latency (us)

Currently BlueZ seems to not account for this swapping of the meanings
of the QoS fields, eg. in client/player.c it has

    num = (qos.ucast.out.latency * 1000 / qos.ucast.out.interval);
    ...
    ts.it_value.tv_nsec = qos->ucast.out.latency * 1000000

and writes num packets in each interval. In the AX210 example it seems
this would give num == 0. I guess this and other places that use these
need to be updated.

Since field meanings anyway change, would 1.25ms unit for the
ISO_Interval be better than 1ms so user side doesn't need to know how
kernel rounds the number and undo that to get the actual value?
 
> -		memcpy(&interval, ev->c_latency, sizeof(ev->c_latency));
> -		conn->iso_qos.ucast.in.interval = le32_to_cpu(interval);
> -		memcpy(&interval, ev->p_latency, sizeof(ev->p_latency));
> -		conn->iso_qos.ucast.out.interval = le32_to_cpu(interval);
> -		conn->iso_qos.ucast.in.latency = le16_to_cpu(ev->interval);
> -		conn->iso_qos.ucast.out.latency = le16_to_cpu(ev->interval);
> -		conn->iso_qos.ucast.in.sdu = le16_to_cpu(ev->c_mtu);
> -		conn->iso_qos.ucast.out.sdu = le16_to_cpu(ev->p_mtu);
> -		conn->iso_qos.ucast.in.phy = ev->c_phy;
> -		conn->iso_qos.ucast.out.phy = ev->p_phy;
> +	switch (conn->role) {
> +	case HCI_ROLE_SLAVE:
> +		qos->ucast.in.interval = get_unaligned_le24(ev->c_latency);
> +		qos->ucast.out.interval = get_unaligned_le24(ev->p_latency);
> +		qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu);
> +		qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu);
> +		qos->ucast.in.phy = ev->c_phy;
> +		qos->ucast.out.phy = ev->p_phy;
> +		break;
> +	case HCI_ROLE_MASTER:
> +		qos->ucast.out.interval = get_unaligned_le24(ev->c_latency);
> +		qos->ucast.in.interval = get_unaligned_le24(ev->p_latency);
> +		qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu);
> +		qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu);
> +		qos->ucast.out.phy = ev->c_phy;
> +		qos->ucast.in.phy = ev->p_phy;
> +		break;
>  	}
>  
>  	if (!ev->status) {





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux