From 273d2fd5ec595b0ebd42d26e2092905c32f050a4 Mon Sep 17 00:00:00 2001 From: zwj Date: Fri, 18 Dec 2020 12:00:17 +0800 Subject: [PATCH] fix multi-connection crash (smp-08003) --- .../bluedroid/stack/l2cap/include/l2c_int.h | 1 + .../bt/host/bluedroid/stack/l2cap/l2c_main.c | 18 +++++++- .../bt/host/bluedroid/stack/l2cap/l2c_utils.c | 43 ++++++++++++------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index e50b593a06..66e221dd53 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -609,6 +609,7 @@ extern void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY prior extern tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid); extern void l2cu_release_ccb (tL2C_CCB *p_ccb); extern tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid); +extern tL2C_CCB *l2cu_find_free_ccb(void); extern tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid); extern void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask); extern BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb); diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index 0f77844106..1f4847bd94 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -904,12 +904,28 @@ void l2c_free_p_lcb_pool(void) list_free(l2cb.p_lcb_pool); } +void l2c_free_p_ccb_pool(void) +{ + list_node_t *p_node = NULL; + tL2C_CCB *p_ccb = NULL; + for (p_node = list_begin(l2cb.p_ccb_pool); p_node; p_node = list_next(p_node)) { + p_ccb = list_node(p_node); + if (p_ccb) { + l2cu_release_ccb (p_ccb); + list_remove(l2cb.p_ccb_pool, p_ccb); + osi_free(p_ccb); + } + } + + list_free(l2cb.p_ccb_pool); +} + void l2c_free(void) { list_free(l2cb.rcv_pending_q); l2cb.rcv_pending_q = NULL; l2c_free_p_lcb_pool(); - list_free(l2cb.p_ccb_pool); + l2c_free_p_ccb_pool(); #if L2C_DYNAMIC_MEMORY FREE_AND_RESET(l2c_cb_ptr); #endif diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 8484f0d9ab..882f59b5b1 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -1450,14 +1450,17 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid) tL2C_CCB *p_ccb = NULL; L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x", cid); + p_ccb = l2cu_find_free_ccb (); + if(p_ccb == NULL) { + if (list_length(l2cb.p_ccb_pool) < MAX_L2CAP_CHANNELS) { + p_ccb = (tL2C_CCB *)osi_malloc(sizeof(tL2C_CCB)); - if (list_length(l2cb.p_ccb_pool) < MAX_L2CAP_CHANNELS) { - p_ccb = (tL2C_CCB *)osi_malloc(sizeof(tL2C_CCB)); - if (p_ccb) { - memset (p_ccb, 0, sizeof(tL2C_CCB)); - list_append(l2cb.p_ccb_pool, p_ccb); - } - } + if (p_ccb) { + memset (p_ccb, 0, sizeof(tL2C_CCB)); + list_append(l2cb.p_ccb_pool, p_ccb); + } + } + } if (p_ccb == NULL) { return (NULL); } @@ -1686,14 +1689,7 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb) /* Flag as not in use */ p_ccb->in_use = FALSE; - { - if (list_remove(l2cb.p_ccb_pool, p_ccb)) { - p_ccb = NULL; - } - else { - L2CAP_TRACE_ERROR("Error in removing L2CAP Channel Control Block"); - } - } + /* If no channels on the connection, start idle timeout */ if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED)) { if (!p_lcb->ccb_queue.p_first_ccb) { @@ -3268,6 +3264,23 @@ tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid) return (p_ccb); } +tL2C_CCB *l2cu_find_free_ccb (void) +{ + tL2C_CCB *p_ccb = NULL; + + list_node_t *p_node = NULL; + + for (p_node = list_begin(l2cb.p_ccb_pool); p_node; p_node = list_next(p_node)) + { + p_ccb = list_node(p_node); + if(p_ccb && !p_ccb->in_use ) { + return p_ccb; + } + } + + return (NULL); +} + #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE && CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************