]> granicus.if.org Git - esp-idf/commitdiff
bt component: fix gatt delete service memory leak problem
authorisland <island@espressif.com>
Sat, 1 Apr 2017 03:08:39 +0000 (11:08 +0800)
committerisland <island@espressif.com>
Sat, 1 Apr 2017 07:34:38 +0000 (15:34 +0800)
components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
components/bt/bluedroid/stack/gatt/gatt_api.c
components/bt/bluedroid/stack/gatt/gatt_db.c
components/bt/bluedroid/stack/gatt/gatt_utils.c
components/bt/bluedroid/stack/gatt/include/gatt_int.h
components/bt/bluedroid/stack/include/gatt_api.h

index da8d4d5f68e5920157fdc7d85910e419ce1a74d5..4a631e868b735336b2c02af64e2f991c1de90f0b 100644 (file)
@@ -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;
index 7a9d125a97440ba7e4cdcb0631fe6f4afe939df1..e0f633709d4cadb13923d61667991f135810d7ea 100644 (file)
@@ -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);
index ae4f6430fa1b6c4bb9c39aeafb7dadec2aa3bc52..bb7c7ac9741488d96b906a00e985109d64ea942b 100644 (file)
@@ -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);
index 60f99966b2671b65aa52b68427b63e8f3495ffc1..fb8d51aec2258ee5856e0c0df6497d5f9c52f383 100644 (file)
@@ -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)
index 9aca0c5dfd519435a90318c8b322ee2389ad233b..5004f5bbfc2dbe84f446f10fb6d698eaca8e70ab 100644 (file)
@@ -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);
index 42812a5bee4474c395b136002aab915476f06e2a..0017d0fa08a7a7e248225b12dd5f697b65128949 100644 (file)
@@ -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 {