From 3770c47387d3dfc6d2e2d32f4409a82119e726e3 Mon Sep 17 00:00:00 2001 From: Satya Calloji Date: Sun, 19 Oct 2014 21:28:46 -0700 Subject: [PATCH] Clean up SetADV and ScanResp data memory leak. Bug:18045480 Change-Id: Ic433f4aa26bd08e84c53c447be9d5278e16ebd55 --- btif/include/btif_gatt_multi_adv_util.h | 10 ++-- btif/src/btif_gatt_client.c | 7 ++- btif/src/btif_gatt_multi_adv_util.c | 98 ++++++++++++++++----------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/btif/include/btif_gatt_multi_adv_util.h b/btif/include/btif_gatt_multi_adv_util.h index 117595870..4b44a5110 100644 --- a/btif/include/btif_gatt_multi_adv_util.h +++ b/btif/include/btif_gatt_multi_adv_util.h @@ -52,7 +52,6 @@ typedef struct typedef struct { - UINT8 inst_id; BOOLEAN is_scan_rsp; UINT8 client_if; UINT16 service_uuid_len; @@ -78,9 +77,12 @@ extern int btif_multi_adv_add_instid_map(int client_if, int inst_id, BOOLEAN gen_temp_instid); extern int btif_multi_adv_instid_for_clientif(int client_if); extern int btif_gattc_obtain_idx_for_datacb(int value, int clnt_inst_index); -extern void btif_gattc_clear_clientif(int client_if); -extern void btif_gattc_cleanup_inst_cb(int inst_id); -extern void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_inst_cb); +extern void btif_gattc_clear_clientif(int client_if, BOOLEAN stop_timer); +extern void btif_gattc_cleanup_inst_cb(int inst_id, BOOLEAN stop_timer); +extern void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_inst_cb, + BOOLEAN stop_timer); +// Free a buffer and reset *buf to NULL. +extern void btif_gattc_cleanup(void** buf); extern BOOLEAN btif_gattc_copy_datacb(int arrindex, btif_adv_data_t *p_adv_data, BOOLEAN bInstData); extern void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp, diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c index 3e0107f07..084950d27 100644 --- a/btif/src/btif_gatt_client.c +++ b/btif/src/btif_gatt_client.c @@ -660,6 +660,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) case BTA_GATTC_MULT_ADV_DATA_EVT: { btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param; + btif_gattc_clear_clientif(p_btif_cb->client_if, FALSE); HAL_CBACK(bt_gatt_callbacks, client->multi_adv_data_cb , p_btif_cb->client_if , p_btif_cb->status @@ -670,7 +671,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) case BTA_GATTC_MULT_ADV_DIS_EVT: { btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param; - btif_gattc_clear_clientif(p_btif_cb->client_if); + btif_gattc_clear_clientif(p_btif_cb->client_if, TRUE); HAL_CBACK(bt_gatt_callbacks, client->multi_adv_disable_cb , p_btif_cb->client_if , p_btif_cb->status @@ -680,7 +681,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) case BTA_GATTC_ADV_DATA_EVT: { - btif_gattc_cleanup_inst_cb(STD_ADV_INSTID); + btif_gattc_cleanup_inst_cb(STD_ADV_INSTID, FALSE); /* No HAL callback available */ break; } @@ -1092,7 +1093,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param) break; case BTIF_GATTC_UNREGISTER_APP: - btif_gattc_clear_clientif(p_cb->client_if); + btif_gattc_clear_clientif(p_cb->client_if, TRUE); btif_gattc_decr_app_count(); BTA_GATTC_AppDeregister(p_cb->client_if); break; diff --git a/btif/src/btif_gatt_multi_adv_util.c b/btif/src/btif_gatt_multi_adv_util.c index 3d7d96cfd..e03f2f168 100644 --- a/btif/src/btif_gatt_multi_adv_util.c +++ b/btif/src/btif_gatt_multi_adv_util.c @@ -485,7 +485,7 @@ BOOLEAN btif_gattc_copy_datacb(int cbindex, btif_adv_data_t *p_adv_data, BOOLEAN return true; } -void btif_gattc_clear_clientif(int client_if) +void btif_gattc_clear_clientif(int client_if, BOOLEAN stop_timer) { btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb(); if (NULL == p_multi_adv_data_cb) @@ -496,18 +496,20 @@ void btif_gattc_clear_clientif(int client_if) { if (client_if == p_multi_adv_data_cb->clntif_map[i]) { - btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1]); - p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST; - p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST; - BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i/2, client_if); + btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1], stop_timer); + if (stop_timer) + { + p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST; + p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST; + BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i/2, client_if); + } break; } } } -void btif_gattc_cleanup_inst_cb(int inst_id) +void btif_gattc_cleanup_inst_cb(int inst_id, BOOLEAN stop_timer) { - int cbindex = 0; // Check for invalid instance id if (inst_id < 0 || inst_id >= BTM_BleMaxMultiAdvInstanceCount()) return; @@ -516,39 +518,33 @@ void btif_gattc_cleanup_inst_cb(int inst_id) if (NULL == p_multi_adv_data_cb) return; - if (inst_id > 0) - { - cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX); - if (cbindex < 0) - return; - } else { - if (STD_ADV_INSTID == inst_id) - cbindex = STD_ADV_INSTID; - } + int cbindex = (STD_ADV_INSTID == inst_id) ? + STD_ADV_INSTID : btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX); + if (cbindex < 0) return; - if (inst_id != INVALID_ADV_INST) - { - BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex); - btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex]); - p_multi_adv_data_cb->inst_cb[cbindex].inst_id = INVALID_ADV_INST; - } + BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex); + btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex], stop_timer); } -void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb) +void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb, + BOOLEAN stop_timer) { if (p_multi_inst_cb == NULL) return; // Discoverability timer cleanup - if (p_multi_inst_cb->tle_limited_timer.in_use) - btu_stop_timer_oneshot(&p_multi_inst_cb->tle_limited_timer); + if (stop_timer) + { + if (p_multi_inst_cb->tle_limited_timer.in_use) + btu_stop_timer_oneshot(&p_multi_inst_cb->tle_limited_timer); + p_multi_inst_cb->tle_limited_timer.in_use = 0; + } // Manufacturer data cleanup if (p_multi_inst_cb->data.p_manu != NULL) { - if (p_multi_inst_cb->data.p_manu->p_val != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_manu->p_val); - GKI_freebuf(p_multi_inst_cb->data.p_manu); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu->p_val); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu); } // Proprietary data cleanup @@ -559,58 +555,56 @@ void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb) while (i++ != p_multi_inst_cb->data.p_proprietary->num_elem && p_elem) { - if (p_elem->p_val != NULL) - GKI_freebuf(p_elem->p_val); + btif_gattc_cleanup((void**) &p_elem->p_val); ++p_elem; } - if (p_multi_inst_cb->data.p_proprietary->p_elem != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_proprietary->p_elem); - GKI_freebuf(p_multi_inst_cb->data.p_proprietary); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary->p_elem); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary); } // Service list cleanup if (p_multi_inst_cb->data.p_services != NULL) { - if (p_multi_inst_cb->data.p_services->p_uuid != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_services->p_uuid); - GKI_freebuf(p_multi_inst_cb->data.p_services); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services->p_uuid); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services); } // Service data cleanup if (p_multi_inst_cb->data.p_service_data != NULL) { - if (p_multi_inst_cb->data.p_service_data->p_val != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_service_data->p_val); - GKI_freebuf(p_multi_inst_cb->data.p_service_data); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data->p_val); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data); } - if (p_multi_inst_cb->data.p_services_128b != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_services_128b); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services_128b); if (p_multi_inst_cb->data.p_service_32b != NULL) { - if (p_multi_inst_cb->data.p_service_32b->p_uuid != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_service_32b->p_uuid); - GKI_freebuf(p_multi_inst_cb->data.p_service_32b); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b->p_uuid); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b); } if (p_multi_inst_cb->data.p_sol_services != NULL) { - if (p_multi_inst_cb->data.p_sol_services->p_uuid != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_sol_services->p_uuid); - GKI_freebuf(p_multi_inst_cb->data.p_sol_services); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services->p_uuid); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services); } if (p_multi_inst_cb->data.p_sol_service_32b != NULL) { - if (p_multi_inst_cb->data.p_sol_service_32b->p_uuid != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_sol_service_32b->p_uuid); - GKI_freebuf(p_multi_inst_cb->data.p_sol_service_32b); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b->p_uuid); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b); } - if (p_multi_inst_cb->data.p_sol_service_128b != NULL) - GKI_freebuf(p_multi_inst_cb->data.p_sol_service_128b); + btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_128b); +} + +void btif_gattc_cleanup(void** buf) +{ + if (NULL == *buf) return; + GKI_freebuf(*buf); + *buf = NULL; } void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb) -- 2.11.0