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

Commit ce4671a9 authored by Yamei Du's avatar Yamei Du Committed by android-build-merger
Browse files

Merge "Ensure we don't send more packets than firmware allows"

am: 76db9426

Change-Id: I6084a7edf6a878b1294099ff76e300fee95bea1e
parents 6614903d 76db9426
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -546,6 +546,14 @@ typedef struct {

typedef void(tL2C_FCR_MGMT_EVT_HDLR)(uint8_t, tL2C_CCB*);

/* Necessary info for postponed TX completion callback
*/
typedef struct {
  uint16_t local_cid;
  uint16_t num_sdu;
  tL2CA_TX_COMPLETE_CB* cb;
} tL2C_TX_COMPLETE_CB_INFO;

/* The offset in a buffer that L2CAP will use when building commands.
*/
#define L2CAP_SEND_CMD_OFFSET 0
@@ -631,6 +639,8 @@ extern void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb);
extern void l2cu_check_channel_congestion(tL2C_CCB* p_ccb);
extern void l2cu_disconnect_chnl(tL2C_CCB* p_ccb);

extern void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi);

#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
extern void l2cu_set_non_flushable_pbf(bool);
#endif
@@ -701,7 +711,8 @@ extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport);
extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport,
                             uint8_t initiating_phys);
extern bool l2cu_create_conn_after_switch(tL2C_LCB* p_lcb);
extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb);
extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb,
                                            tL2C_TX_COMPLETE_CB_INFO* p_cbi);
extern void l2cu_resubmit_pending_sec_req(BD_ADDR p_bda);
extern void l2cu_initialize_amp_ccb(tL2C_LCB* p_lcb);
extern void l2cu_adjust_out_mps(tL2C_CCB* p_ccb);
+17 −11
Original line number Diff line number Diff line
@@ -45,7 +45,8 @@

extern fixed_queue_t* btu_general_alarm_queue;

static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf);
static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
                                   tL2C_TX_COMPLETE_CB_INFO* p_cbi);

/*******************************************************************************
 *
@@ -992,6 +993,9 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) {

    /* Loop through, starting at the next */
    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
      /* Check for wraparound */
      if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) p_lcb = &l2cb.lcb_pool[0];

      /* If controller window is full, nothing to do */
      if (((l2cb.controller_xmit_window == 0 ||
            (l2cb.round_robin_unacked >= l2cb.round_robin_quota)) &&
@@ -1001,9 +1005,6 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) {
            l2cb.controller_le_xmit_window == 0)))
        continue;

      /* Check for wraparound */
      if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) p_lcb = &l2cb.lcb_pool[0];

      if ((!p_lcb->in_use) || (p_lcb->partial_segment_being_sent) ||
          (p_lcb->link_state != LST_CONNECTED) ||
          (p_lcb->link_xmit_quota != 0) || (L2C_LINK_CHECK_POWER_MODE(p_lcb)))
@@ -1013,16 +1014,17 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) {
      if (!list_is_empty(p_lcb->link_xmit_data_q)) {
        p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q);
        list_remove(p_lcb->link_xmit_data_q, p_buf);
        l2c_link_send_to_lower(p_lcb, p_buf);
        l2c_link_send_to_lower(p_lcb, p_buf, NULL);
      } else if (single_write) {
        /* If only doing one write, break out */
        break;
      }
      /* If nothing on the link queue, check the channel queue */
      else {
        p_buf = l2cu_get_next_buffer_to_send(p_lcb);
        tL2C_TX_COMPLETE_CB_INFO cbi;
        p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi);
        if (p_buf != NULL) {
          l2c_link_send_to_lower(p_lcb, p_buf);
          l2c_link_send_to_lower(p_lcb, p_buf, &cbi);
        }
      }
    }
@@ -1055,7 +1057,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) {

      p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q);
      list_remove(p_lcb->link_xmit_data_q, p_buf);
      if (!l2c_link_send_to_lower(p_lcb, p_buf)) break;
      if (!l2c_link_send_to_lower(p_lcb, p_buf, NULL)) break;
    }

    if (!single_write) {
@@ -1065,10 +1067,11 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) {
              (l2cb.controller_le_xmit_window != 0 &&
               (p_lcb->transport == BT_TRANSPORT_LE))) &&
             (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
        p_buf = l2cu_get_next_buffer_to_send(p_lcb);
        tL2C_TX_COMPLETE_CB_INFO cbi;
        p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi);
        if (p_buf == NULL) break;

        if (!l2c_link_send_to_lower(p_lcb, p_buf)) break;
        if (!l2c_link_send_to_lower(p_lcb, p_buf, &cbi)) break;
      }
    }

@@ -1093,7 +1096,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) {
 * Returns          true for success, false for fail
 *
 ******************************************************************************/
static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf) {
static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
  uint16_t num_segs;
  uint16_t xmit_window, acl_data_size;
  const controller_t* controller = controller_get_interface();
@@ -1183,6 +1186,9 @@ static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf) {
  }
#endif

  if (p_cbi)
    l2cu_tx_complete(p_cbi);

  return true;
}

+14 −5
Original line number Diff line number Diff line
@@ -3241,6 +3241,11 @@ static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) {
}
#endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */

void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
  if (p_cbi->cb != NULL)
      p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu);
}

/******************************************************************************
 *
 * Function         l2cu_get_next_buffer_to_send
@@ -3251,7 +3256,7 @@ static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) {
 * Returns          pointer to buffer or NULL
 *
 ******************************************************************************/
BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) {
BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
  tL2C_CCB* p_ccb;
  BT_HDR* p_buf;

@@ -3259,6 +3264,8 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) {
#if (L2CAP_NUM_FIXED_CHNLS > 0)
  int xx;

  p_cbi->cb = NULL;

  for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
    p_ccb = p_lcb->p_fixed_ccbs[xx];
    if (p_ccb == NULL) continue;
@@ -3287,12 +3294,14 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) {
      if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
        p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
        if (NULL == p_buf) {
          L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
          L2CAP_TRACE_ERROR("%s: No data to be sent", __func__);
          return (NULL);
        }
        /* send tx complete */
        if (l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)
          (*l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)(p_ccb->local_cid, 1);

        /* Prepare callback info for TX completion */
        p_cbi->cb = l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb;
        p_cbi->local_cid = p_ccb->local_cid;
        p_cbi->num_sdu = 1;

        l2cu_check_channel_congestion(p_ccb);
        l2cu_set_acl_hci_header(p_buf, p_ccb);