From d4619584d767d826c1ea7f48ecee8383aba1daf8 Mon Sep 17 00:00:00 2001 From: "zhiweijian@espressif.com" Date: Fri, 27 Nov 2020 16:38:21 +0800 Subject: [PATCH] fix ble connect crash --- .../bt/host/bluedroid/stack/l2cap/l2c_main.c | 17 +++++++- .../bt/host/bluedroid/stack/l2cap/l2c_utils.c | 40 ++++++++++++------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index 7ef00f884f..0f77844106 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -888,12 +888,27 @@ void l2c_init (void) l2ble_update_att_acl_pkt_num(L2CA_BUFF_INI, NULL); #endif } +void l2c_free_p_lcb_pool(void) +{ + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); + if (p_lcb) { + l2cu_release_lcb (p_lcb); + list_remove(l2cb.p_lcb_pool, p_lcb); + osi_free(p_lcb); + } + } + + list_free(l2cb.p_lcb_pool); +} void l2c_free(void) { list_free(l2cb.rcv_pending_q); l2cb.rcv_pending_q = NULL; - list_free(l2cb.p_lcb_pool); + l2c_free_p_lcb_pool(); list_free(l2cb.p_ccb_pool); #if L2C_DYNAMIC_MEMORY FREE_AND_RESET(l2c_cb_ptr); diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index c46c03b1b1..8484f0d9ab 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -52,14 +52,20 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR { tL2C_LCB *p_lcb = NULL; bool list_ret = false; - if (list_length(l2cb.p_lcb_pool) < MAX_L2CAP_LINKS) { + extern tL2C_LCB *l2cu_find_free_lcb (void); + // temp solution + p_lcb = l2cu_find_free_lcb(); + if(p_lcb != NULL) { + list_ret = true; + } + if(p_lcb == NULL && list_length(l2cb.p_lcb_pool) < MAX_L2CAP_LINKS) { p_lcb = (tL2C_LCB *)osi_malloc(sizeof(tL2C_LCB)); - if (p_lcb) { - memset (p_lcb, 0, sizeof(tL2C_LCB)); + if (p_lcb) { + memset (p_lcb, 0, sizeof(tL2C_LCB)); list_ret = list_append(l2cb.p_lcb_pool, p_lcb); - }else { - L2CAP_TRACE_ERROR("Error in allocating L2CAP Link Control Block"); - } + }else { + L2CAP_TRACE_ERROR("Error in allocating L2CAP Link Control Block"); + } } if (list_ret) { if (p_lcb) { @@ -272,14 +278,6 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) #if (C2H_FLOW_CONTROL_INCLUDED == TRUE) p_lcb->completed_packets = 0; #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE - { - if (list_remove(l2cb.p_lcb_pool, p_lcb)) { - p_lcb = NULL; - } - else { - L2CAP_TRACE_ERROR("Error in removing L2CAP Link Control Block"); - } - } } @@ -312,6 +310,20 @@ tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport) return (NULL); } +tL2C_LCB *l2cu_find_free_lcb (void) +{ + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); + if (!p_lcb->in_use) { + return (p_lcb); + } + } + /* If here, no match found */ + return (NULL); +} + /******************************************************************************* ** ** Function l2cu_get_conn_role