From f688309b3a09dd4b55c2ba66f6888dca8dfca8ff Mon Sep 17 00:00:00 2001 From: island Date: Wed, 12 Apr 2017 11:09:55 +0800 Subject: [PATCH] bt component: Fix memory leak while using gatt server - fix memory leak while creating attribute table - fix memory leak while deleting service --- .../btc/profile/std/gatt/btc_gatts.c | 26 ++++++++++++++++ components/bt/bluedroid/osi/future.c | 4 +-- components/bt/bluedroid/osi/include/future.h | 2 ++ 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 +++ 8 files changed, 78 insertions(+), 4 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 da8d4d5f6..d2d658393 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,31 @@ 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); + } + } + break; + default: LOG_DEBUG("%s Unhandled deep free %d\n", __func__, msg->act); break; @@ -320,6 +345,7 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db, break; } default: + future_free(future_p); break; } diff --git a/components/bt/bluedroid/osi/future.c b/components/bt/bluedroid/osi/future.c index 23c207f4d..1ee113db1 100644 --- a/components/bt/bluedroid/osi/future.c +++ b/components/bt/bluedroid/osi/future.c @@ -23,7 +23,7 @@ #include "osi.h" #include "osi_arch.h" -static void future_free(future_t *future); +void future_free(future_t *future); future_t *future_new(void) { @@ -85,7 +85,7 @@ void *future_await(future_t *future) return result; } -static void future_free(future_t *future) +void future_free(future_t *future) { if (!future) { return; diff --git a/components/bt/bluedroid/osi/include/future.h b/components/bt/bluedroid/osi/include/future.h index d54f23785..a89640c27 100644 --- a/components/bt/bluedroid/osi/include/future.h +++ b/components/bt/bluedroid/osi/include/future.h @@ -49,4 +49,6 @@ void future_ready(future_t *future, void *value); // Frees the future before return. |future| may not be NULL. void *future_await(future_t *async_result); +//Free the future if this "future" is not used +void future_free(future_t *future); #endif /* __FUTURE_H__ */ diff --git a/components/bt/bluedroid/stack/gatt/gatt_api.c b/components/bt/bluedroid/stack/gatt/gatt_api.c index 7a9d125a9..e0f633709 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 ae4f6430f..bb7c7ac97 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 60f99966b..fb8d51aec 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 9aca0c5df..5004f5bbf 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 42812a5be..0017d0fa0 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 {