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

Commit 5bc6955b authored by Yamei Du's avatar Yamei Du Committed by Zach Johnson
Browse files

DO NOT MERGE ANYWHERE HOGP mouse connect failed during OPP TX

FW ACL buffer overflow.
One more ACL packet was sent to FW which is unexpected.

fix l2cap TX control defect.
Call fixed channel TX complete cb after packets is send to lower.

Bug: 26763700
Tested: manual
Change-Id: Iaba14a11c1583da2a72769ebd096e0baedf857c3
CR-Id: ALPS02404396
parent 423fe03b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -683,7 +683,7 @@ extern BOOLEAN l2cu_lcb_disconnecting (void);

extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport);
extern BOOLEAN 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, UINT16 *fixed_cid);
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);
+22 −12
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@

extern fixed_queue_t *btu_general_alarm_queue;

static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf);
static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf, UINT16 fixed_cid);

/*******************************************************************************
**
@@ -1065,6 +1065,7 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
{
    int         xx;
    BOOLEAN     single_write = FALSE;
    UINT16    fixed_cid;

    /* Save the channel ID for faster counting */
    if (p_buf)
@@ -1110,6 +1111,10 @@ 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 (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
                (l2cb.controller_xmit_window == 0 ||
@@ -1132,10 +1137,6 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
            }
#endif

            /* 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)
@@ -1147,7 +1148,7 @@ 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, 0);
            }
            else if (single_write)
            {
@@ -1155,9 +1156,9 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
                break;
            }
            /* If nothing on the link queue, check the channel queue */
            else if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) != NULL)
            else if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb, &fixed_cid)) != NULL)
            {
                l2c_link_send_to_lower (p_lcb, p_buf);
                l2c_link_send_to_lower (p_lcb, p_buf, fixed_cid);
            }
        }

@@ -1200,7 +1201,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))
            if (!l2c_link_send_to_lower (p_lcb, p_buf, 0))
                break;
        }

@@ -1215,10 +1216,10 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
            while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
#endif
            {
                if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) == NULL)
                if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb, &fixed_cid)) == NULL)
                    break;

                if (!l2c_link_send_to_lower (p_lcb, p_buf))
                if (!l2c_link_send_to_lower (p_lcb, p_buf, fixed_cid))
                    break;
            }
        }
@@ -1244,7 +1245,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 BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf, UINT16 fixed_cid)
{
    UINT16      num_segs;
    UINT16      xmit_window, acl_data_size;
@@ -1375,6 +1376,15 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
    }
#endif

    if (fixed_cid != 0)
    {
        L2CAP_TRACE_DEBUG("%s: fixed_cid = %d, send tx complete", __func__, fixed_cid);
        /* send tx complete */
        if (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedTxComplete_Cb)
        {
            (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedTxComplete_Cb)(fixed_cid, 1);
        }
    }
    return TRUE;
}

+7 −4
Original line number Diff line number Diff line
@@ -3538,7 +3538,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, UINT16 *fixed_cid)
{
    tL2C_CCB    *p_ccb;
    BT_HDR      *p_buf;
@@ -3547,6 +3547,7 @@ BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
#if (L2CAP_NUM_FIXED_CHNLS > 0)
    int         xx;

    *fixed_cid = 0;
    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
    {
        if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL)
@@ -3586,9 +3587,11 @@ BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
                    L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
                    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);
                if (fixed_cid != NULL)
                {
                    *fixed_cid = p_ccb->local_cid;
                    L2CAP_TRACE_DEBUG("l2cu_get_buffer_to_send: fixed_cid = %d", *fixed_cid);
                }

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