Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57494231 authored by Antoine SOULIER's avatar Antoine SOULIER
Browse files

LE Audio: Fix ISO packets sequence numbers

Bug: 310743536
Flag: EXEMPT Change only information for the BT controller, and by the way seems not read by any controller.
Tag: #bug
Test: atest --host net_test_btm_iso
Change-Id: I2a660d1316998e3736ab8eb96a54b24d03c5b4b9
parent 5b373155
Loading
Loading
Loading
Loading
+19 −44
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@
namespace bluetooth {
namespace hci {
namespace iso_manager {
static constexpr uint8_t kIsoDataInTsBtHdrOffset = 0x0C;
static constexpr uint8_t kIsoHeaderWithTsLen = 12;
static constexpr uint8_t kIsoHeaderWithoutTsLen = 8;

@@ -58,7 +57,6 @@ static constexpr uint8_t kStateFlagIsBroadcast = 0x10;
constexpr char kBtmLogTag[] = "ISO";

struct iso_sync_info {
  uint32_t first_sync_ts;
  uint16_t seq_nb;
};

@@ -165,7 +163,7 @@ struct iso_impl {
        auto cis = std::unique_ptr<iso_cis>(new iso_cis());
        cis->cig_id = cig_id;
        cis->sdu_itv = sdu_itv_mtos;
        cis->sync_info = {.first_sync_ts = 0, .seq_nb = 0};
        cis->sync_info = {.seq_nb = 0};
        cis->used_credits = 0;
        cis->state_flags = kStateFlagsNone;
        conn_hdl_to_cis_map_[conn_handle] = std::move(cis);
@@ -510,10 +508,10 @@ struct iso_impl {
                                   weak_factory_.GetWeakPtr()));
  }

  BT_HDR* prepare_ts_hci_packet(uint16_t iso_handle, uint32_t ts,
                                uint16_t seq_nb, uint16_t data_len) {
    /* Add 2 for packet seq., 2 for length, 4 for the timestamp */
    uint16_t iso_data_load_len = data_len + 8;
  BT_HDR* prepare_hci_packet(uint16_t iso_handle, uint16_t seq_nb,
                             uint16_t data_len) {
    /* Add 2 for packet seq., 2 for length */
    uint16_t iso_data_load_len = data_len + 4;

    /* Add 2 for handle, 2 for length */
    uint16_t iso_full_len = iso_data_load_len + 4;
@@ -527,9 +525,6 @@ struct iso_impl {
    UINT16_TO_STREAM(packet_data, iso_handle);
    UINT16_TO_STREAM(packet_data, iso_data_load_len);

    packet->layer_specific |= BT_ISO_HDR_CONTAINS_TS;
    UINT32_TO_STREAM(packet_data, ts);

    UINT16_TO_STREAM(packet_data, seq_nb);
    UINT16_TO_STREAM(packet_data, data_len);

@@ -558,8 +553,8 @@ struct iso_impl {
    /* Calculate sequence number for the ISO data packet.
     * It should be incremented by 1 every SDU Interval.
     */
    uint32_t ts = bluetooth::common::time_get_os_boottime_us();
    iso->sync_info.seq_nb = (ts - iso->sync_info.first_sync_ts) / iso->sdu_itv;
    uint16_t seq_nb = iso->sync_info.seq_nb;
    iso->sync_info.seq_nb = (seq_nb + 1) & 0xffff;

    if (iso_credits_ == 0 || data_len > iso_buffer_size_) {
      iso->cr_stats.credits_underflow_bytes += data_len;
@@ -577,9 +572,8 @@ struct iso_impl {
    iso_credits_--;
    iso->used_credits++;

    BT_HDR* packet =
        prepare_ts_hci_packet(iso_handle, ts, iso->sync_info.seq_nb, data_len);
    memcpy(packet->data + kIsoDataInTsBtHdrOffset, data, data_len);
    BT_HDR* packet = prepare_hci_packet(iso_handle, seq_nb, data_len);
    memcpy(packet->data + kIsoHeaderWithoutTsLen, data, data_len);
    auto hci = bluetooth::shim::hci_layer_get_interface();
    packet->event = MSG_STACK_TO_HC_HCI_ISO | 0x0001;
    hci->transmit_downward(packet->event, packet);
@@ -603,8 +597,6 @@ struct iso_impl {
                       "cis_handle:0x%04x status:%s", evt.cis_conn_hdl,
                       hci_error_code_text((tHCI_STATUS)(evt.status)).c_str()));

    cis->sync_info.first_sync_ts = bluetooth::common::time_get_os_boottime_us();

    STREAM_TO_UINT24(evt.cig_sync_delay, data);
    STREAM_TO_UINT24(evt.cis_sync_delay, data);
    STREAM_TO_UINT24(evt.trans_lat_mtos, data);
@@ -736,7 +728,6 @@ struct iso_impl {
    LOG_ASSERT(len == (18 + num_bis * sizeof(uint16_t)))
        << "Invalid packet length: " << len << ". Number of bis: " << +num_bis;

    uint32_t ts = bluetooth::common::time_get_os_boottime_us();
    for (auto i = 0; i < num_bis; ++i) {
      uint16_t conn_handle;
      STREAM_TO_UINT16(conn_handle, data);
@@ -747,7 +738,7 @@ struct iso_impl {
        auto bis = std::unique_ptr<iso_bis>(new iso_bis());
        bis->big_handle = evt.big_id;
        bis->sdu_itv = last_big_create_req_sdu_itv_;
        bis->sync_info = {.first_sync_ts = ts, .seq_nb = 0};
        bis->sync_info = {.seq_nb = 0};
        bis->used_credits = 0;
        bis->state_flags = kStateFlagIsBroadcast;
        conn_hdl_to_bis_map_[conn_handle] = std::move(bis);
@@ -876,34 +867,18 @@ struct iso_impl {

    STREAM_TO_UINT16(seq_nb, stream);

    uint32_t ts = bluetooth::common::time_get_os_boottime_us();
    uint32_t new_calc_seq_nb =
        (ts - iso->sync_info.first_sync_ts) / iso->sdu_itv;
    if (new_calc_seq_nb <= iso->sync_info.seq_nb)
      new_calc_seq_nb = iso->sync_info.seq_nb + 1;
    uint16_t expected_seq_nb = iso->sync_info.seq_nb;
    iso->sync_info.seq_nb = (seq_nb + 1) & 0xffff;

    if (iso->sync_info.seq_nb == 0) {
      evt.evt_lost = 0;
    } else {
      evt.evt_lost = new_calc_seq_nb - iso->sync_info.seq_nb - 1;
    evt.evt_lost = ((1 << 16) + seq_nb - expected_seq_nb) & 0xffff;
    if (evt.evt_lost > 0) {
      iso->evt_stats.evt_lost_count += evt.evt_lost;
      iso->evt_stats.evt_last_lost_us =
          bluetooth::common::time_get_os_boottime_us();

        LOG(WARNING) << evt.evt_lost << " packets possibly lost.";
      }

      if (new_calc_seq_nb != seq_nb) {
        LOG(WARNING) << "Sequence number mismatch. "
                        "Adjusting own time reference point.";
        iso->sync_info.first_sync_ts = ts - (seq_nb * iso->sdu_itv);
        new_calc_seq_nb = seq_nb;

      LOG(WARNING) << evt.evt_lost << " packets lost.";
      iso->evt_stats.seq_nb_mismatch_count++;
    }
    }
    iso->sync_info.seq_nb = new_calc_seq_nb;

    evt.p_msg = p_msg;
    evt.cig_id = iso->cig_id;