]> granicus.if.org Git - esp-idf/commitdiff
Component/bt: fix memory leak
authorzhiweijian <zhiweijian@espressif.com>
Tue, 22 May 2018 08:27:01 +0000 (16:27 +0800)
committerbot <bot@espressif.com>
Wed, 6 Jun 2018 02:17:06 +0000 (02:17 +0000)
components/bt/Kconfig
components/bt/bluedroid/bta/dm/bta_dm_act.c
components/bt/bluedroid/bta/gatt/bta_gattc_act.c
components/bt/bluedroid/bta/gatt/bta_gattc_api.c
components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
components/bt/bluedroid/bta/gatt/bta_gattc_co.c
components/bt/bluedroid/bta/include/bta/bta_gatt_api.h
components/bt/bluedroid/bta/include/bta/bta_gattc_co.h
components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c
components/bt/bluedroid/common/include/common/bt_target.h

index 33bd87112131f2fed3b8282c07df8ffcb90829c1..7f5c0b3a7dafa06a83a92ca014dfa8e9256f6a28 100644 (file)
@@ -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
index caa4943145e9504dea81a206792672c4741042f0..5e84d7daa041d44b25fa9772b9ec0f571f63ed9a 100644 (file)
@@ -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
     }
 }
index e836003dd4f54af98ad7773fcfa66ede3e328435..d91b1c1c830e8fdc421552d6f240f90d812aaf52 100644 (file)
@@ -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)
index b7c292a51e396cb8ff58675565ea630f82224573..45a155e1e6c38cf758641bbb9abc5727f248f7aa 100644 (file)
@@ -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) {
index 8a5625356ca2a97ccc4785a102c2ff77d0103830..66d3bb8becf87cdc449047c6d687910e9129d244 100644 (file)
@@ -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);
 }
 /*******************************************************************************
index 6c6fc460d3f74350a6d02843334bd1d2220383bb..1a1599af55f03743598ba9ad4a5c4062d3cfe678 100644 (file)
@@ -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;
index 72eb3643b6637583d3c3ce298f207a05224cf888..723c7fe26b9c7b6d739426f858ac24168cf3289a 100644 (file)
@@ -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);
 
index a902a2edf2eb1af725324b92018345406b689258..44a0e18ef204313ba841a49178d5be46b3269eba 100644 (file)
@@ -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);
index 0694b990f00524895e7e2c2052cd6dc1ece54f1a..d48cd0b40b21ef31f1a290dd965b97316664e637 100644 (file)
@@ -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,
index fc12bde071770d3755a553e135685bac92c1e7d1..ef45566867b7266eb847e0de02ede60bc92a86e7 100644 (file)
 #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
 #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