Bläddra i källkod

bt component: Fix memory leak while using gatt server

- fix memory leak while creating attribute table
- fix memory leak while deleting service
island 8 år sedan
förälder
incheckning
f688309b3a

+ 26 - 0
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;
         }
 

+ 2 - 2
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;

+ 2 - 0
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__ */

+ 3 - 0
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);

+ 8 - 0
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);

+ 29 - 2
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)

+ 4 - 0
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);

+ 4 - 0
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 {