Skip to content

Commit ac65ecc

Browse files
committed
Bluetooth: hci_event: Fix setting of unicast qos interval
qos->ucast interval reffers to the SDU interval, and should not be set to the interval value reported by the LE CIS Established event since the latter reffers to the ISO interval. These two interval are not the same thing: BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 6, Part G Isochronous interval: The time between two consecutive BIS or CIS events (designated ISO_Interval in the Link Layer) SDU interval: The nominal time between two consecutive SDUs that are sent or received by the upper layer. So this instead uses the following formula from the spec to calculate the resulting SDU interface: BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 6, Part G page 3075: Transport_Latency_C_To_P = CIG_Sync_Delay + (FT_C_To_P) × ISO_Interval + SDU_Interval_C_To_P Transport_Latency_P_To_C = CIG_Sync_Delay + (FT_P_To_C) × ISO_Interval + SDU_Interval_P_To_C Link: bluez/bluez#823 Fixes: 2be22f1 ("Bluetooth: hci_event: Fix parsing of CIS Established Event") Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 3f35d9b commit ac65ecc

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

net/bluetooth/hci_event.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6667,6 +6667,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
66676667
struct bt_iso_qos *qos;
66686668
bool pending = false;
66696669
u16 handle = __le16_to_cpu(ev->handle);
6670+
u32 c_sdu_interval, p_sdu_interval;
66706671

66716672
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
66726673

@@ -6691,12 +6692,25 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
66916692

66926693
pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags);
66936694

6694-
/* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
6695-
qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
6696-
qos->ucast.out.interval = qos->ucast.in.interval;
6695+
/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 6, Part G
6696+
* page 3075:
6697+
* Transport_Latency_C_To_P = CIG_Sync_Delay + (FT_C_To_P) ×
6698+
* ISO_Interval + SDU_Interval_C_To_P
6699+
* ...
6700+
* SDU_Interval = (CIG_Sync_Delay + (FT) x ISO_Interval) -
6701+
* Transport_Latency
6702+
*/
6703+
c_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) +
6704+
(ev->c_ft * le16_to_cpu(ev->interval) * 1250)) -
6705+
get_unaligned_le24(ev->c_latency);
6706+
p_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) +
6707+
(ev->p_ft * le16_to_cpu(ev->interval) * 1250)) -
6708+
get_unaligned_le24(ev->p_latency);
66976709

66986710
switch (conn->role) {
66996711
case HCI_ROLE_SLAVE:
6712+
qos->ucast.in.interval = c_sdu_interval;
6713+
qos->ucast.out.interval = p_sdu_interval;
67006714
/* Convert Transport Latency (us) to Latency (msec) */
67016715
qos->ucast.in.latency =
67026716
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
@@ -6710,6 +6724,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
67106724
qos->ucast.out.phy = ev->p_phy;
67116725
break;
67126726
case HCI_ROLE_MASTER:
6727+
qos->ucast.in.interval = p_sdu_interval;
6728+
qos->ucast.out.interval = c_sdu_interval;
67136729
/* Convert Transport Latency (us) to Latency (msec) */
67146730
qos->ucast.out.latency =
67156731
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),

0 commit comments

Comments
 (0)