Skip to content

Commit

Permalink
Bluetooth: hci_event: Fix parsing of CIS Established Event
Browse files Browse the repository at this point in the history
[ Upstream commit 2be22f1 ]

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 <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
Stable-dep-of: 7f74563 ("Bluetooth: ISO: do not emit new LE Create CIS if previous is pending")
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
Vudentz authored and gregkh committed Sep 13, 2023
1 parent 867a146 commit 3e740c8
Showing 1 changed file with 34 additions and 15 deletions.
49 changes: 34 additions & 15 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -6788,6 +6788,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;
u16 handle = __le16_to_cpu(ev->handle);

bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
Expand All @@ -6809,21 +6810,39 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
goto unlock;
}

if (conn->role == HCI_ROLE_SLAVE) {
__le32 interval;

memset(&interval, 0, sizeof(interval));

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;
qos = &conn->iso_qos;

/* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
qos->ucast.out.interval = qos->ucast.in.interval;

switch (conn->role) {
case HCI_ROLE_SLAVE:
/* Convert Transport Latency (us) to Latency (msec) */
qos->ucast.in.latency =
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
1000);
qos->ucast.out.latency =
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
1000);
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:
/* Convert Transport Latency (us) to Latency (msec) */
qos->ucast.out.latency =
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
1000);
qos->ucast.in.latency =
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
1000);
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) {
Expand Down

0 comments on commit 3e740c8

Please sign in to comment.