From: zhiweijian Date: Tue, 22 May 2018 08:27:01 +0000 (+0800) Subject: Component/bt: fix memory leak X-Git-Tag: v3.1-beta1~52^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=822dac5659e2c22bb9a011cafa8835cbbd603332;p=esp-idf Component/bt: fix memory leak --- diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 33bd871121..7f5c0b3a7d 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -220,6 +220,13 @@ config GATTC_ENABLE help This option can be close when the app work only on gatt server mode +config GATTC_CACHE_NVS_FLASH + bool "Save gattc cache data to nvs flash" + depends on GATTC_ENABLE + default n + help + This select can save gattc cache data to nvs flash + config BLE_SMP_ENABLE bool "Include BLE security module(SMP)" depends on BLUEDROID_ENABLED diff --git a/components/bt/bluedroid/bta/dm/bta_dm_act.c b/components/bt/bluedroid/bta/dm/bta_dm_act.c index caa4943145..5e84d7daa0 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c @@ -374,6 +374,12 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH ); /* notify BTA DM is now unactive */ bta_dm_cb.is_bta_dm_active = FALSE; +#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) +#if (GATTC_INCLUDED == TRUE && GATTC_CACHE_NVS == TRUE) + /* clear the gattc cache address list */ + bta_gattc_co_cache_addr_deinit(); +#endif +#endif } else if ( status == BTA_SYS_HW_ON_EVT ) { /* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error. * We need to revisit when this platform has more than one BLuetooth H/W chip */ @@ -403,7 +409,7 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) BTM_SetDeviceClass (dev_class); #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) -#if (GATTC_INCLUDED == TRUE) +#if (GATTC_INCLUDED == TRUE && GATTC_CACHE_NVS == TRUE) // load the gattc cache address list bta_gattc_co_cache_addr_init(); #endif /* #if (GATTC_INCLUDED = TRUE) */ @@ -703,7 +709,7 @@ void bta_dm_process_remove_device(BD_ADDR bd_addr) #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE) /* remove all cached GATT information */ - BTA_GATTC_Refresh(bd_addr); + BTA_GATTC_Refresh(bd_addr, false); #endif if (bta_dm_cb.p_sec_cback) { @@ -887,7 +893,7 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data) /* need to remove all pending background connection if any */ BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE); /* remove all cached GATT information */ - BTA_GATTC_Refresh(p_remove_acl->bd_addr); + BTA_GATTC_Refresh(p_remove_acl->bd_addr, false); #endif } /* otherwise, no action needed */ @@ -3336,7 +3342,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) /* need to remove all pending background connection */ BTA_GATTC_CancelOpen(0, p_bda, FALSE); /* remove all cached GATT information */ - BTA_GATTC_Refresh(p_bda); + BTA_GATTC_Refresh(p_bda, false); #endif } @@ -3510,7 +3516,7 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr) /* need to remove all pending background connection */ BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE); /* remove all cached GATT information */ - BTA_GATTC_Refresh(remote_bd_addr); + BTA_GATTC_Refresh(remote_bd_addr, false); #endif } } diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c index e836003dd4..d91b1c1c83 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c @@ -666,11 +666,14 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) if (p_clcb->p_srcb->p_srvc_cache == NULL || p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) { if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) { +#if (GATTC_CACHE_NVS == TRUE) p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD; if (bta_gattc_cache_load(p_clcb)) { p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); - } else { /* cache is building */ + } else +#endif + { /* cache is building */ p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; /* cache load failure, start discovery */ bta_gattc_start_discover(p_clcb, NULL); @@ -1016,9 +1019,10 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) list_free(p_clcb->p_srcb->p_srvc_cache); p_clcb->p_srcb->p_srvc_cache = NULL; } - +#if(GATTC_CACHE_NVS == TRUE) /* used to reset cache in application */ bta_gattc_cache_reset(p_clcb->p_srcb->server_bda); +#endif } if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) { /* release pending attribute list buffer */ @@ -1716,7 +1720,6 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) } if (found) { bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); - bta_gattc_cache_reset(p_msg->api_conn.remote_bda); return; } } @@ -1726,8 +1729,6 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) p_srvc_cb->p_srvc_cache = NULL; } } - /* used to reset cache in application */ - bta_gattc_cache_reset(p_msg->api_conn.remote_bda); } void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_api.c b/components/bt/bluedroid/bta/gatt/bta_gattc_api.c index b7c292a51e..45a155e1e6 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/bluedroid/bta/gatt/bta_gattc_api.c @@ -912,12 +912,20 @@ tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if, ** Description Refresh the server cache of the remote device ** ** Parameters remote_bda: remote device BD address. +** erase_flash: delete cache from nvs flash ** ** Returns void ** *******************************************************************************/ -void BTA_GATTC_Refresh(BD_ADDR remote_bda) +void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash) { +#if(GATTC_CACHE_NVS == TRUE) + if(erase_flash) { + /* used to reset cache in application */ + bta_gattc_cache_reset(remote_bda); + } +#endif + tBTA_GATTC_API_OPEN *p_buf; if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) { diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c b/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c index 8a5625356c..66d3bb8bec 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c +++ b/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c @@ -622,10 +622,11 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb) L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); } #endif +#if(GATTC_CACHE_NVS == TRUE) /* save cache to NV */ p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE; - bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id); +#endif bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); } /******************************************************************************* diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_co.c b/components/bt/bluedroid/bta/gatt/bta_gattc_co.c index 6c6fc460d3..1a1599af55 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gattc_co.c +++ b/components/bt/bluedroid/bta/gatt/bta_gattc_co.c @@ -75,7 +75,7 @@ static void cacheReset(BD_ADDR bda) #else -static const char *cache_key = "gattc_cahe_key"; +static const char *cache_key = "gattc_cache_key"; static const char *cache_addr = "cache_addr_tab"; nvs_handle nvs_fp; @@ -144,7 +144,7 @@ static void cacheReset(BD_ADDR bda) char fname[255] = {0}; getFilename(fname, bda); UINT8 index = 0; - //cache_env.cache_addr + //cache_env.cache_addr if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) { //clear the association address pending in the source address. bta_gattc_co_cache_clear_assoc_addr(bda); @@ -152,7 +152,22 @@ static void cacheReset(BD_ADDR bda) nvs_erase_all(cache_env.cache_addr[index].cache_fp); nvs_close(cache_env.cache_addr[index].cache_fp); cache_env.cache_addr[index].is_open = FALSE; + } else { + cacheOpen(bda, false, &index); + if (cache_env.cache_addr[index].is_open) { + nvs_erase_all(cache_env.cache_addr[index].cache_fp); + nvs_close(cache_env.cache_addr[index].cache_fp); + cache_env.cache_addr[index].is_open = FALSE; + } else { + APPL_TRACE_ERROR("%s cacheOpen failed", __func__); + return; + } + } + if(cache_env.num_addr == 0) { + APPL_TRACE_ERROR("%s cache addr list error", __func__); + return; } + UINT8 num = cache_env.num_addr; //delete the server_bda in the addr_info list. for(UINT8 i = index; i < (num - 1); i++) { @@ -160,6 +175,40 @@ static void cacheReset(BD_ADDR bda) } //reduced the number address counter also cache_env.num_addr--; + + //update addr list to nvs flash + if(cache_env.num_addr > 0) { + //update + UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF); + if(!p_buf) { + APPL_TRACE_ERROR("%s malloc error", __func__); + return; + } + UINT16 length = cache_env.num_addr*(sizeof(BD_ADDR) + sizeof(hash_key_t)); + for (UINT8 i = 0; i < cache_env.num_addr; i++) { + //copy the address to the buffer. + memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), cache_env.cache_addr[i].addr, sizeof(BD_ADDR)); + //copy the hash key to the buffer. + memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR), + cache_env.cache_addr[i].hash_key, sizeof(hash_key_t)); + } + if (cache_env.is_open) { + if (nvs_set_blob(cache_env.addr_fp, cache_key, p_buf, length) != ESP_OK) { + APPL_TRACE_WARNING("%s, nvs set blob failed", __func__); + } + } + osi_free(p_buf); + + } else { + //erase + if (cache_env.is_open) { + nvs_erase_all(cache_env.addr_fp); + nvs_close(cache_env.addr_fp); + cache_env.is_open = FALSE; + } else { + APPL_TRACE_WARNING("cache_env status is error"); + } + } } } @@ -325,10 +374,11 @@ void bta_gattc_co_cache_addr_init(void) esp_err_t err_code; UINT8 num_addr; UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF); - size_t length = 0; + size_t length = MAX_ADDR_LIST_CACHE_BUF; if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) { cache_env.addr_fp = fp; + cache_env.is_open = TRUE; // Read previously saved blob if available if ((err_code = nvs_get_blob(fp, cache_key, p_buf, &length)) != ESP_OK) { if(err_code != ESP_ERR_NVS_NOT_FOUND) { @@ -361,6 +411,26 @@ void bta_gattc_co_cache_addr_init(void) return; } +void bta_gattc_co_cache_addr_deinit(void) +{ + if(!cache_env.is_open) { + return; + } + nvs_close(cache_env.addr_fp); + cache_env.is_open = false; + + for(UINT8 i = 0; i< cache_env.num_addr; i++) { + cache_addr_info_t *addr_info = &cache_env.cache_addr[i]; + if(addr_info) { + nvs_close(addr_info->cache_fp); + addr_info->is_open = false; + if(addr_info->assoc_addr) { + list_free(addr_info->assoc_addr); + } + } + } +} + BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda) { UINT8 addr_index = 0; diff --git a/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h index 72eb3643b6..723c7fe26b 100644 --- a/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h +++ b/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h @@ -1096,11 +1096,12 @@ extern void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_mult ** Description Refresh the server cache of the remote device ** ** Parameters remote_bda: remote device BD address. +** erase_flash: delete cache from nvs flash ** ** Returns void ** *******************************************************************************/ -extern void BTA_GATTC_Refresh(BD_ADDR remote_bda); +extern void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash); extern void BTA_GATTC_CacheAssoc(tBTA_GATTC_IF client_if, BD_ADDR src_addr, BD_ADDR assoc_addr, BOOLEAN is_assoc); diff --git a/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h b/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h index a902a2edf2..44a0e18ef2 100644 --- a/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h +++ b/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h @@ -113,6 +113,8 @@ extern size_t bta_gattc_get_cache_attr_length(UINT8 index); extern void bta_gattc_co_cache_addr_init(void); +extern void bta_gattc_co_cache_addr_deinit(void); + extern BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda); extern uint8_t bta_gattc_co_find_addr_in_cache(BD_ADDR bda); diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c index 0694b990f0..d48cd0b40b 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -738,7 +738,7 @@ void btc_gattc_call_handler(btc_msg_t *msg) btc_gattc_unreg_for_notify(arg); break; case BTC_GATTC_ACT_CACHE_REFRESH: - BTA_GATTC_Refresh(arg->cache_refresh.remote_bda); + BTA_GATTC_Refresh(arg->cache_refresh.remote_bda, true); break; case BTC_GATTC_ACT_CACHE_ASSOC: BTA_GATTC_CacheAssoc(arg->cache_assoc.gattc_if, diff --git a/components/bt/bluedroid/common/include/common/bt_target.h b/components/bt/bluedroid/common/include/common/bt_target.h index fc12bde071..ef45566867 100644 --- a/components/bt/bluedroid/common/include/common/bt_target.h +++ b/components/bt/bluedroid/common/include/common/bt_target.h @@ -94,6 +94,10 @@ #define CLASSIC_BT_INCLUDED FALSE #endif /* CLASSIC_BT_INCLUDED */ +#ifndef CONFIG_GATTC_CACHE_NVS_FLASH +#define CONFIG_GATTC_CACHE_NVS_FLASH FALSE +#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */ + /****************************************************************************** ** ** BLE features @@ -111,6 +115,12 @@ #define GATTC_INCLUDED FALSE #endif /* CONFIG_GATTC_ENABLE */ +#if (CONFIG_GATTC_ENABLE && CONFIG_GATTC_CACHE_NVS_FLASH) +#define GATTC_CACHE_NVS TRUE +#else +#define GATTC_CACHE_NVS FALSE +#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */ + #if (CONFIG_SMP_ENABLE) #define SMP_INCLUDED TRUE #define BLE_PRIVACY_SPT TRUE