From 6ad86f0d67fcaf1e52fcf33e27fea4f4908776c0 Mon Sep 17 00:00:00 2001 From: island Date: Sat, 1 Apr 2017 11:08:39 +0800 Subject: [PATCH] bt component: fix gatt delete service memory leak problem --- .../btc/profile/std/gatt/btc_gatts.c | 24 ++++++++++++++ components/bt/bluedroid/stack/gatt/gatt_api.c | 3 ++ components/bt/bluedroid/stack/gatt/gatt_db.c | 8 +++++ .../bt/bluedroid/stack/gatt/gatt_utils.c | 31 +++++++++++++++++-- .../bluedroid/stack/gatt/include/gatt_int.h | 4 +++ .../bt/bluedroid/stack/include/gatt_api.h | 4 +++ 6 files changed, 72 insertions(+), 2 deletions(-) diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c index da8d4d5f68..4a631e868b 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c @@ -166,6 +166,30 @@ void btc_gatts_arg_deep_free(btc_msg_t *msg) } break; } + case BTC_GATTS_ACT_ADD_CHAR:{ + if (arg->add_char.char_val.attr_value != NULL) { + GKI_freebuf(arg->add_char.char_val.attr_value); + } + break; + } + case BTC_GATTS_ACT_ADD_CHAR_DESCR:{ + if (arg->add_descr.descr_val.attr_value != NULL){ + GKI_freebuf(arg->add_descr.descr_val.attr_value); + } + break; + } + case BTC_GATTS_ACT_CREATE_ATTR_TAB:{ + if (arg->create_attr_tab.gatts_attr_db != NULL){ + GKI_freebuf(arg->create_attr_tab.gatts_attr_db); + } + break; + } + case BTC_GATTS_ACT_SET_ATTR_VALUE:{ + if (arg->set_attr_val.value != NULL){ + GKI_freebuf(arg->set_attr_val.value); + } + } + default: LOG_DEBUG("%s Unhandled deep free %d\n", __func__, msg->act); break; diff --git a/components/bt/bluedroid/stack/gatt/gatt_api.c b/components/bt/bluedroid/stack/gatt/gatt_api.c index 7a9d125a97..e0f633709d 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/bluedroid/stack/gatt/gatt_api.c @@ -214,6 +214,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, if (p_list) { gatt_remove_an_item_from_list(p_list_info, p_list); + gatt_free_attr_value_buffer(p_list); gatt_free_hdl_buffer(p_list); } return (0); @@ -227,6 +228,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed\n"); if (p_list) { gatt_remove_an_item_from_list(p_list_info, p_list); + gatt_free_attr_value_buffer(p_list); gatt_free_hdl_buffer(p_list); } @@ -413,6 +415,7 @@ BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_ } gatt_remove_an_item_from_list(p_list_info, p_list); + gatt_free_attr_value_buffer(p_list); gatt_free_hdl_buffer(p_list); return (TRUE); diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index ae4f6430fa..bb7c7ac974 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -529,6 +529,10 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, GATT_TRACE_WARNING("Warning in %s, line=%d, insufficient resource to allocate for attribute value\n", __func__, __LINE__); return 0; } + else { + //add mask to indicate that p_value->attr_val.attr_val is dynamic allocated + p_char_val->mask |= GATT_ATTR_VALUE_ALLOCATED; + } //initiate characteristic attribute value part memset(p_char_val->p_value->attr_val.attr_val, 0, attr_val->attr_max_len); @@ -663,6 +667,10 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, GATT_TRACE_WARNING("Warning in %s, line=%d, insufficient resource to allocate for descriptor value\n", __func__, __LINE__); return 0; } + else { + //add mask to indicate that p_value->attr_val.attr_val is dynamic allocated + p_char_dscptr->mask |= GATT_ATTR_VALUE_ALLOCATED; + } //initiate characteristic attribute value part memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len); diff --git a/components/bt/bluedroid/stack/gatt/gatt_utils.c b/components/bt/bluedroid/stack/gatt/gatt_utils.c index 60f99966b2..fb8d51aec2 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/bluedroid/stack/gatt/gatt_utils.c @@ -397,11 +397,38 @@ tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, } /******************************************************************************* ** +** Function gatt_free_attr_value_buffer +** +** Description free characteristic attribute value buffer in a service +** +** Returns None +** +*******************************************************************************/ +void gatt_free_attr_value_buffer(tGATT_HDL_LIST_ELEM *p) +{ + if (p){ + tGATT_SVC_DB *p_db = &(p->svc_db); + tGATT_ATTR16 *p_attr = p_db->p_attr_list; + tGATT_ATTR_VALUE *p_value = NULL; + + while(p_attr){ + if (p_attr->mask & GATT_ATTR_VALUE_ALLOCATED){ + p_value = p_attr->p_value; + if ((p_value != NULL) && (p_value->attr_val.attr_val != NULL)){ + GKI_freebuf(p_value->attr_val.attr_val); + } + } + p_attr = p_attr->p_next; + } + } +} +/******************************************************************************* +** ** Function gatt_free_hdl_buffer ** -** Description free a handle buffer +** Description free a handle buffer ** -** Returns None +** Returns None ** *******************************************************************************/ void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p) diff --git a/components/bt/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/bluedroid/stack/gatt/include/gatt_int.h index 9aca0c5dfd..5004f5bbfc 100644 --- a/components/bt/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/bluedroid/stack/gatt/include/gatt_int.h @@ -185,6 +185,7 @@ typedef struct { tGATT_ATTR_UUID_TYPE uuid_type; tGATT_PERM permission; tGATTS_ATTR_CONTROL control; + tGATT_ATTR_MASK mask; UINT16 handle; UINT16 uuid; } tGATT_ATTR16; @@ -197,6 +198,7 @@ typedef struct { tGATT_ATTR_UUID_TYPE uuid_type; tGATT_PERM permission; tGATTS_ATTR_CONTROL control; + tGATT_ATTR_MASK mask; UINT16 handle; UINT32 uuid; } tGATT_ATTR32; @@ -210,6 +212,7 @@ typedef struct { tGATT_ATTR_UUID_TYPE uuid_type; tGATT_PERM permission; tGATTS_ATTR_CONTROL control; + tGATT_ATTR_MASK mask; UINT16 handle; UINT8 uuid[LEN_UUID_128]; } tGATT_ATTR128; @@ -621,6 +624,7 @@ extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle); extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle); extern tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void); extern void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p); +extern void gatt_free_attr_value_buffer(tGATT_HDL_LIST_ELEM *p); extern BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value); extern void gatt_update_last_pri_srv_info(tGATT_SRV_LIST_INFO *p_list); extern BOOLEAN gatt_add_a_srv_to_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_new); diff --git a/components/bt/bluedroid/stack/include/gatt_api.h b/components/bt/bluedroid/stack/include/gatt_api.h index 42812a5bee..0017d0fa08 100644 --- a/components/bt/bluedroid/stack/include/gatt_api.h +++ b/components/bt/bluedroid/stack/include/gatt_api.h @@ -326,6 +326,10 @@ typedef struct{ uint8_t auto_rsp; }tGATTS_ATTR_CONTROL; +/* Mask for gatt server attribute */ +#define GATT_ATTR_VALUE_ALLOCATED 0x01 +typedef UINT8 tGATT_ATTR_MASK; + /* Union of the event data which is used in the server respond API to carry the server response information */ typedef union {