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

Commit dbf8fcd2 authored by Himanshu Rawat's avatar Himanshu Rawat Committed by Gerrit Code Review
Browse files

Merge "Transmit pending L2CAP fixed channel packets before closing" into main

parents 472ed9de f864dc75
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -364,9 +364,8 @@ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, B
 *
 *  Parameters:     Fixed CID
 *                  BD Address of remote
 *                  Idle timeout to use (or 0xFFFF if don't care)
 *
 *  Return value:   true if channel removed
 *  Return value:   true if channel removed or marked for removal
 *
 ******************************************************************************/
bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda);
+1 −2
Original line number Diff line number Diff line
@@ -794,9 +794,8 @@ struct tL2CAP_FIXED_CHNL_REG {
 *
 *  Parameters:     Fixed CID
 *                  BD Address of remote
 *                  Idle timeout to use (or 0xFFFF if don't care)
 *
 *  Return value:   true if channel removed
 *  Return value:   true if channel removed or marked for removal
 *
 ******************************************************************************/
[[nodiscard]] bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda);
+35 −17
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <base/location.h>
#include <base/strings/stringprintf.h>
#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>

#include <cstdint>
#include <string>
@@ -1214,6 +1215,9 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
      return true;
    }

    // Restore the fixed channel if it was suspended
    l2cu_fixed_channel_restore(p_lcb, fixed_cid);

    (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(
            fixed_cid, p_lcb->remote_bd_addr, true, 0, p_lcb->transport);
    return true;
@@ -1307,28 +1311,29 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& re
  p_buf->event = 0;
  p_buf->layer_specific = L2CAP_FLUSHABLE_CH_BASED;

  if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) {
  tL2C_CCB* p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];

  if (p_ccb == nullptr) {
    if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) {
      log::warn("No channel control block found for CID: 0x{:4x}", fixed_cid);
      osi_free(p_buf);
      return tL2CAP_DW_RESULT::FAILED;
    }
    p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
  }

  if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
    log::warn(
            "Unable to send data due to congestion CID: 0x{:04x} "
            "xmit_hold_q.count: {} buff_quota: {}",
            fixed_cid,
            fixed_queue_length(
                    p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q),
            p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota);
  // Sending packets over fixed channel reinstates them
  l2cu_fixed_channel_restore(p_lcb, fixed_cid);

  if (p_ccb->cong_sent) {
    log::warn("Link congestion CID: 0x{:04x} xmit_hold_q.count: {} buff_quota: {}", fixed_cid,
              fixed_queue_length(p_ccb->xmit_hold_q), p_ccb->buff_quota);
    osi_free(p_buf);
    return tL2CAP_DW_RESULT::FAILED;
  }

  log::debug("Enqueued data for CID: 0x{:04x} len:{}", fixed_cid, p_buf->len);
  l2c_enqueue_peer_data(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL], p_buf);
  l2c_enqueue_peer_data(p_ccb, p_buf);

  l2c_link_check_send_pkts(p_lcb, 0, NULL);

@@ -1338,7 +1343,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& re
    l2cu_no_dynamic_ccbs(p_lcb);
  }

  if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
  if (p_ccb->cong_sent) {
    log::debug("Link congested for CID: 0x{:04x}", fixed_cid);
    return tL2CAP_DW_RESULT::CONGESTED;
  }
@@ -1354,13 +1359,11 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& re
 *
 *  Parameters:     Fixed CID
 *                  BD Address of remote
 *                  Idle timeout to use (or 0xFFFF if don't care)
 *
 *  Return value:   true if channel removed
 *  Return value:   true if channel removed or marked for removal
 *
 ******************************************************************************/
bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
  tL2C_CCB* p_ccb;
  tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;

  /* Check CID is valid and registered */
@@ -1382,11 +1385,22 @@ bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
    return false;
  }

  log::verbose("BDA: {} CID: 0x{:04x}", rem_bda, fixed_cid);

  /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs
   * exist */
  p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
  tL2C_CCB* p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];

  if (com::android::bluetooth::flags::transmit_smp_packets_before_release() && p_ccb->in_use &&
      !fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
    if (l2cu_fixed_channel_suspended(p_lcb, fixed_cid)) {
      log::warn("Removal of BDA: {} CID: 0x{:04x} already pending", rem_bda, fixed_cid);
    } else {
      p_lcb->suspended.push_back(fixed_cid);
      log::info("Waiting for transmit queue to clear, BDA: {} CID: 0x{:04x}", rem_bda, fixed_cid);
    }
    return true;
  }

  log::verbose("BDA: {} CID: 0x{:04x}", rem_bda, fixed_cid);

  p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL;
  p_lcb->SetDisconnectReason(HCI_ERR_CONN_CAUSE_LOCAL_HOST);
@@ -1744,6 +1758,10 @@ void L2CA_Dumpsys(int fd) {
                  ccb->in_use ? "true" : "false");
      ccb = ccb->p_next_ccb;
    }

    for (auto fixed_cid : lcb.suspended) {
      LOG_DUMPSYS(fd, "  pending removal fixed CID: 0x%04x", fixed_cid);
    }
  }
}
#undef DUMPSYS_TAG
+1 −2
Original line number Diff line number Diff line
@@ -1137,8 +1137,7 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) {
          if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb !=
              nullptr) {
            p_ccb->metrics.rx(static_cast<BT_HDR*>(p_data)->len);
            (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(
                    p_ccb->local_cid, p_ccb->p_lcb->remote_bd_addr, (BT_HDR*)p_data);
            l2cu_fixed_channel_data_cb(p_lcb, p_ccb->local_cid, reinterpret_cast<BT_HDR*>(p_data));
          } else {
            if (p_data != nullptr) {
              osi_free_and_reset(&p_data);
+1 −2
Original line number Diff line number Diff line
@@ -1219,8 +1219,7 @@ static bool do_sar_reassembly(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word
    if (p_ccb->local_cid < L2CAP_BASE_APPL_CID &&
        (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL && p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL)) {
      if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb) {
        (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(
                p_ccb->local_cid, p_ccb->p_lcb->remote_bd_addr, p_buf);
        l2cu_fixed_channel_data_cb(p_ccb->p_lcb, p_ccb->local_cid, p_buf);
      }
    } else {
      l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_buf);
Loading