Loading system/bta/Android.mk +0 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ LOCAL_SRC_FILES:= \ ./gatt/bta_gatts_act.c \ ./gatt/bta_gatts_main.c \ ./gatt/bta_gattc_utils.c \ ./gatt/bta_gattc_ci.c \ ./gatt/bta_gatts_api.c \ ./gatt/bta_gattc_main.c \ ./gatt/bta_gattc_act.c \ Loading system/bta/BUILD.gn +0 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ static_library("bta") { "gatt/bta_gattc_act.c", "gatt/bta_gattc_api.c", "gatt/bta_gattc_cache.c", "gatt/bta_gattc_ci.c", "gatt/bta_gattc_main.c", "gatt/bta_gattc_utils.c", "gatt/bta_gatts_act.c", Loading system/bta/gatt/bta_gattc_act.c +12 −139 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ static const char *bta_gattc_op_code_name[] = ** Action Functions *****************************************************************************/ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status); /******************************************************************************* ** ** Function bta_gattc_enable Loading Loading @@ -711,7 +714,13 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) { p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD; bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, NULL); if (bta_gattc_cache_load(p_clcb)) { bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); } else { p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; /* cache load failure, start discovery */ bta_gattc_start_discover(p_clcb, NULL); } } else /* cache is building */ p_clcb->state = BTA_GATTC_DISCOVER_ST; Loading Loading @@ -1035,7 +1044,7 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) } /* used to reset cache in application */ bta_gattc_co_cache_reset(p_clcb->p_srcb->server_bda); bta_gattc_cache_reset(p_clcb->p_srcb->server_bda); } if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) { /* release pending attribute list buffer */ Loading Loading @@ -1582,143 +1591,7 @@ void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { bta_gattc_enqueue(p_clcb, p_data); } /******************************************************************************* ** ** Function bta_gattc_cache_open ** ** Description open a NV cache for loading ** ** Returns void ** *******************************************************************************/ void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { UNUSED(p_data); bta_gattc_set_discover_st(p_clcb->p_srcb); APPL_TRACE_DEBUG("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id); bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT, p_clcb->bta_conn_id, FALSE); } /******************************************************************************* ** ** Function bta_gattc_start_load ** ** Description start cache loading by sending callout open cache ** ** Returns None. ** *******************************************************************************/ void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { APPL_TRACE_DEBUG("bta_gattc_ci_open conn_id=%d server state=%d" , p_clcb->bta_conn_id, p_clcb->p_srcb->state); if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD) { if (p_data->ci_open.status == BTA_GATT_OK) { p_clcb->p_srcb->attr_index = 0; bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_LOAD_EVT, p_clcb->p_srcb->attr_index, p_clcb->bta_conn_id); } else { p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; /* cache open failure, start discovery */ bta_gattc_start_discover(p_clcb, NULL); } } if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE) { if (p_data->ci_open.status == BTA_GATT_OK) { if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) { p_data->ci_open.status = BTA_GATT_ERROR; } } if (p_data->ci_open.status != BTA_GATT_OK) { p_clcb->p_srcb->attr_index = 0; bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id); bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); } } } /******************************************************************************* ** ** Function bta_gattc_ci_load ** ** Description cache loading received. ** ** Returns None. ** *******************************************************************************/ void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { APPL_TRACE_DEBUG("bta_gattc_ci_load conn_id=%d load status=%d", p_clcb->bta_conn_id, p_data->ci_load.status); if (p_data->ci_load.status == BTA_GATT_OK || p_data->ci_load.status == BTA_GATT_MORE) { if (p_data->ci_load.num_attr != 0) bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index); if (p_data->ci_load.status == BTA_GATT_OK) { p_clcb->p_srcb->attr_index = 0; bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); } else /* load more */ { p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr; bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_LOAD_EVT, p_clcb->p_srcb->attr_index, p_clcb->bta_conn_id); } } else { bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; p_clcb->p_srcb->attr_index = 0; /* cache load failure, start discovery */ bta_gattc_start_discover(p_clcb, NULL); } } /******************************************************************************* ** ** Function bta_gattc_ci_save ** ** Description cache loading received. ** ** Returns None. ** *******************************************************************************/ void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { UNUSED(p_data); APPL_TRACE_DEBUG("bta_gattc_ci_save conn_id=%d " , p_clcb->bta_conn_id ); if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) { p_clcb->p_srcb->attr_index = 0; bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); } } /******************************************************************************* ** ** Function bta_gattc_fail Loading Loading @@ -1893,7 +1766,7 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) } } /* used to reset cache in application */ bta_gattc_co_cache_reset(p_msg->api_conn.remote_bda); bta_gattc_cache_reset(p_msg->api_conn.remote_bda); } /******************************************************************************* Loading system/bta/gatt/bta_gattc_cache.c +211 −71 Original line number Diff line number Diff line Loading @@ -29,24 +29,37 @@ #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) #include <errno.h> #include <stdio.h> #include <string.h> #include "bta_gattc_int.h" #include "bta_sys.h" #include "btm_api.h" #include "btm_ble_api.h" #include "btm_int.h" #include "bt_common.h" #include "osi/include/log.h" #include "sdp_api.h" #include "sdpdefs.h" #include "utl.h" static void bta_gattc_cache_write(BD_ADDR server_bda, UINT16 num_attr, tBTA_GATTC_NV_ATTR *attr); static void bta_gattc_char_dscpt_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb); static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb); extern void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src); #define BTA_GATT_SDP_DB_SIZE 4096 #define GATT_CACHE_PREFIX "/data/misc/bluetooth/gatt_cache_" #define GATT_CACHE_VERSION 1 static void bta_gattc_generate_cache_file_name(char *buffer, BD_ADDR bda) { sprintf(buffer, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); } /***************************************************************************** ** Constants and data types *****************************************************************************/ Loading Loading @@ -524,8 +537,12 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb) #endif /* save cache to NV */ p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE; bta_gattc_co_cache_open(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT, conn_id, TRUE); if (btm_sec_is_a_bonded_dev(p_srvc_cb->server_bda)) { bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id); } bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); } /******************************************************************************* ** Loading Loading @@ -1391,6 +1408,34 @@ void bta_gattc_fill_gatt_db_el(btgatt_db_element_t *p_attr, bta_to_btif_uuid(&p_attr->uuid, &uuid); } /******************************************************************************* ** Returns number of elements inside db from start_handle to end_handle *******************************************************************************/ static size_t bta_gattc_get_db_size(list_t *services, UINT16 start_handle, UINT16 end_handle) { if (!services || list_is_empty(services)) return 0; size_t db_size = 0; for (list_node_t *sn = list_begin(services); sn != list_end(services); sn = list_next(sn)) { tBTA_GATTC_CACHE *p_cur_srvc = list_node(sn); if (p_cur_srvc->s_handle < start_handle) continue; if (p_cur_srvc->e_handle > end_handle) break; db_size++; if (p_cur_srvc->p_attr) db_size += list_length(p_cur_srvc->p_attr); } return db_size; } /******************************************************************************* ** ** Function bta_gattc_get_gatt_db_impl Loading @@ -1413,28 +1458,13 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV *p_srvc_cb, { APPL_TRACE_DEBUG(LOG_TAG, "%s", __func__); int db_size = 0; if (!p_srvc_cb->p_srvc_cache || list_is_empty(p_srvc_cb->p_srvc_cache)) { *count = 0; *db = NULL; return; } for (list_node_t *sn = list_begin(p_srvc_cb->p_srvc_cache); sn != list_end(p_srvc_cb->p_srvc_cache); sn = list_next(sn)) { tBTA_GATTC_CACHE *p_cur_srvc = list_node(sn); if (p_cur_srvc->s_handle < start_handle) continue; if (p_cur_srvc->e_handle > end_handle) break; db_size++; if (p_cur_srvc->p_attr) db_size += list_length(p_cur_srvc->p_attr); } size_t db_size = bta_gattc_get_db_size(p_srvc_cb->p_srvc_cache, start_handle, end_handle); void* buffer = osi_malloc(db_size * sizeof(btgatt_db_element_t)); btgatt_db_element_t *curr_db_attr = buffer; Loading Loading @@ -1555,17 +1585,14 @@ void bta_gattc_get_gatt_db(UINT16 conn_id, UINT16 start_handle, UINT16 end_handl ** *******************************************************************************/ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index) tBTA_GATTC_NV_ATTR *p_attr) { /* first attribute loading, initialize buffer */ APPL_TRACE_ERROR("%s: bta_gattc_rebuild_cache", __func__); if (attr_index == 0) { if (p_srvc_cb->p_srvc_cache) list_free(p_srvc_cb->p_srvc_cache); p_srvc_cb->p_srvc_cache = NULL; p_srvc_cb->p_cur_srvc = NULL; } while (num_attr > 0 && p_attr != NULL) { Loading Loading @@ -1617,6 +1644,7 @@ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_han memcpy(&p_attr->uuid, &uuid, sizeof(tBT_UUID)); } /******************************************************************************* ** ** Function bta_gattc_cache_save Loading @@ -1626,21 +1654,19 @@ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_han ** Returns None. ** *******************************************************************************/ BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) { UINT8 i = 0; UINT16 offset = 0; tBTA_GATTC_NV_ATTR nv_attr[BTA_GATTC_NV_LOAD_MAX]; if (!p_srvc_cb->p_srvc_cache || list_is_empty(p_srvc_cb->p_srvc_cache)) return; int i = 0; size_t db_size = bta_gattc_get_db_size(p_srvc_cb->p_srvc_cache, 0x0000, 0xFFFF); tBTA_GATTC_NV_ATTR *nv_attr = osi_malloc(db_size * sizeof(tBTA_GATTC_NV_ATTR)); if (p_srvc_cb->p_srvc_cache && !list_is_empty(p_srvc_cb->p_srvc_cache)) { for (list_node_t *sn = list_begin(p_srvc_cb->p_srvc_cache); sn != list_end(p_srvc_cb->p_srvc_cache); sn = list_next(sn)) { tBTA_GATTC_CACHE *p_cur_srvc = list_node(sn); if (i >= BTA_GATTC_NV_LOAD_MAX) break; if (offset ++ >= p_srvc_cb->attr_index) bta_gattc_fill_nv_attr(&nv_attr[i++], BTA_GATTC_ATTR_TYPE_SRVC, p_cur_srvc->s_handle, Loading @@ -1657,10 +1683,6 @@ BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) an != list_end(p_cur_srvc->p_attr); an = list_next(an)) { tBTA_GATTC_CACHE_ATTR *p_attr = list_node(an); if (i >= BTA_GATTC_NV_LOAD_MAX) break; if (offset++ >= p_srvc_cb->attr_index) { bta_gattc_fill_nv_attr(&nv_attr[i++], p_attr->attr_type, p_attr->attr_handle, Loading @@ -1671,19 +1693,137 @@ BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) FALSE); } } bta_gattc_cache_write(p_srvc_cb->server_bda, db_size, nv_attr); osi_free(nv_attr); } /******************************************************************************* ** ** Function bta_gattc_cache_load ** ** Description Load GATT cache from storage for server. ** ** Parameter p_clcb: pointer to server clcb, that will ** be filled from storage ** Returns true on success, false otherwise ** *******************************************************************************/ bool bta_gattc_cache_load(tBTA_GATTC_CLCB *p_clcb) { char fname[255] = {0}; bta_gattc_generate_cache_file_name(fname, p_clcb->p_srcb->server_bda); FILE *fd = fopen(fname, "rb"); if (!fd) { APPL_TRACE_ERROR("%s: can't open GATT cache file %s for reading, error: %s", __func__, fname, strerror(errno)); return false; } UINT16 cache_ver = 0; tBTA_GATTC_NV_ATTR *attr = NULL; bool success = false; if (fread(&cache_ver, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't read GATT cache version from: %s", __func__, fname); goto done; } if (cache_ver != GATT_CACHE_VERSION) { APPL_TRACE_ERROR("%s: wrong GATT cache version: %s", __func__, fname); goto done; } if (i > 0) { bta_gattc_co_cache_save(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_SAVE_EVT, i, nv_attr, p_srvc_cb->attr_index, conn_id); UINT16 num_attr = 0; p_srvc_cb->attr_index += i; if (fread(&num_attr, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't read number of GATT attributes: %s", __func__, fname); goto done; } return TRUE; } else { return FALSE; attr = osi_malloc(sizeof(tBTA_GATTC_NV_ATTR) * num_attr); if (fread(attr, sizeof(tBTA_GATTC_NV_ATTR), 0xFF, fd) != num_attr) { APPL_TRACE_ERROR("%s: can't read GATT attributes: %s", __func__, fname); goto done; } bta_gattc_rebuild_cache(p_clcb->p_srcb, num_attr, attr); success = true; done: osi_free(attr); fclose(fd); return success; } /******************************************************************************* ** ** Function bta_gattc_cache_write ** ** Description This callout function is executed by GATT when a server cache ** is available to save. ** ** Parameter server_bda: server bd address of this cache belongs to ** num_attr: number of attribute to be save. ** attr: pointer to the list of attributes to save. ** Returns ** *******************************************************************************/ static void bta_gattc_cache_write(BD_ADDR server_bda, UINT16 num_attr, tBTA_GATTC_NV_ATTR *attr) { char fname[255] = {0}; bta_gattc_generate_cache_file_name(fname, server_bda); FILE *fd = fopen(fname, "wb"); if (!fd) { APPL_TRACE_ERROR("%s: can't open GATT cache file for writing: %s", __func__, fname); return; } UINT16 cache_ver = GATT_CACHE_VERSION; if (fwrite(&cache_ver, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't write GATT cache version: %s", __func__, fname); fclose(fd); return; } if (fwrite(&num_attr, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't write GATT cache attribute count: %s", __func__, fname); fclose(fd); return; } if (fwrite(attr, sizeof(tBTA_GATTC_NV_ATTR), num_attr, fd) != num_attr) { APPL_TRACE_ERROR("%s: can't write GATT cache attributes: %s", __func__, fname); fclose(fd); return; } fclose(fd); } /******************************************************************************* ** ** Function bta_gattc_cache_reset ** ** Description This callout function is executed by GATTC to reset cache in ** application ** ** Parameter server_bda: server bd address of this cache belongs to ** ** Returns void. ** *******************************************************************************/ void bta_gattc_cache_reset(BD_ADDR server_bda) { BTIF_TRACE_DEBUG("%s", __func__); char fname[255] = {0}; bta_gattc_generate_cache_file_name(fname, server_bda); unlink(fname); } #endif /* BTA_GATT_INCLUDED */ system/bta/gatt/bta_gattc_ci.cdeleted 100644 → 0 +0 −132 Original line number Diff line number Diff line /****************************************************************************** * * Copyright (C) 2010-2012 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ /****************************************************************************** * * This is the implementation file for the GATT call-in functions. * ******************************************************************************/ #include "bt_target.h" #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) #include <string.h> #include "bta_api.h" #include "bta_sys.h" #include "bta_gattc_ci.h" #include "bt_common.h" #include "utl.h" /******************************************************************************* ** ** Function bta_gattc_ci_cache_open ** ** Description This function sends an event to indicate server cache open ** completed. ** ** Parameters server_bda - server BDA of this cache. ** status - BTA_GATT_OK if full buffer of data, ** BTA_GATT_FAIL if an error has occurred. ** ** Returns void ** *******************************************************************************/ void bta_gattc_ci_cache_open(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status, UINT16 conn_id) { tBTA_GATTC_CI_EVT *p_evt = (tBTA_GATTC_CI_EVT *) osi_malloc(sizeof(tBTA_GATTC_CI_EVT)); UNUSED(server_bda); p_evt->hdr.event = evt; p_evt->hdr.layer_specific = conn_id; p_evt->status = status; bta_sys_sendmsg(p_evt); } /******************************************************************************* ** ** Function bta_gattc_ci_cache_load ** ** Description This function sends an event to BTA indicating the phone has ** load the servere cache and ready to send it to the stack. ** ** Parameters server_bda - server BDA of this cache. ** num_bytes_read - number of bytes read into the buffer ** specified in the read callout-function. ** status - BTA_GATT_OK if full buffer of data, ** BTA_GATT_FAIL if an error has occurred. ** ** Returns void ** *******************************************************************************/ void bta_gattc_ci_cache_load(BD_ADDR server_bda, UINT16 evt, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, tBTA_GATT_STATUS status, UINT16 conn_id) { tBTA_GATTC_CI_LOAD *p_evt = (tBTA_GATTC_CI_LOAD *)osi_calloc(sizeof(tBTA_GATTC_CI_LOAD)); UNUSED(server_bda); p_evt->hdr.event = evt; p_evt->hdr.layer_specific = conn_id; p_evt->status = status; p_evt->num_attr = (num_attr > BTA_GATTC_NV_LOAD_MAX) ? BTA_GATTC_NV_LOAD_MAX : num_attr; if (p_evt->num_attr > 0 && p_attr != NULL) { memcpy(p_evt->attr, p_attr, p_evt->num_attr * sizeof(tBTA_GATTC_NV_ATTR)); } bta_sys_sendmsg(p_evt); } /******************************************************************************* ** ** Function bta_gattc_ci_cache_save ** ** Description This function sends an event to BTA indicating the phone has ** save the servere cache. ** ** Parameters server_bda - server BDA of this cache. ** evt - callin event code. ** status - BTA_GATT_OK if full buffer of data, ** BTA_GATT_ERROR if an error has occurred. *8 conn_id - for this NV operation for. ** ** Returns void ** *******************************************************************************/ void bta_gattc_ci_cache_save(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status, UINT16 conn_id) { tBTA_GATTC_CI_EVT *p_evt = (tBTA_GATTC_CI_EVT *)osi_malloc(sizeof(tBTA_GATTC_CI_EVT)); UNUSED(server_bda); p_evt->hdr.event = evt; p_evt->hdr.layer_specific = conn_id; p_evt->status = status; bta_sys_sendmsg(p_evt); } #endif /* BTA_GATT_INCLUDED */ Loading
system/bta/Android.mk +0 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ LOCAL_SRC_FILES:= \ ./gatt/bta_gatts_act.c \ ./gatt/bta_gatts_main.c \ ./gatt/bta_gattc_utils.c \ ./gatt/bta_gattc_ci.c \ ./gatt/bta_gatts_api.c \ ./gatt/bta_gattc_main.c \ ./gatt/bta_gattc_act.c \ Loading
system/bta/BUILD.gn +0 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ static_library("bta") { "gatt/bta_gattc_act.c", "gatt/bta_gattc_api.c", "gatt/bta_gattc_cache.c", "gatt/bta_gattc_ci.c", "gatt/bta_gattc_main.c", "gatt/bta_gattc_utils.c", "gatt/bta_gatts_act.c", Loading
system/bta/gatt/bta_gattc_act.c +12 −139 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ static const char *bta_gattc_op_code_name[] = ** Action Functions *****************************************************************************/ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status); /******************************************************************************* ** ** Function bta_gattc_enable Loading Loading @@ -711,7 +714,13 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) { p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD; bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, NULL); if (bta_gattc_cache_load(p_clcb)) { bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); } else { p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; /* cache load failure, start discovery */ bta_gattc_start_discover(p_clcb, NULL); } } else /* cache is building */ p_clcb->state = BTA_GATTC_DISCOVER_ST; Loading Loading @@ -1035,7 +1044,7 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) } /* used to reset cache in application */ bta_gattc_co_cache_reset(p_clcb->p_srcb->server_bda); bta_gattc_cache_reset(p_clcb->p_srcb->server_bda); } if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) { /* release pending attribute list buffer */ Loading Loading @@ -1582,143 +1591,7 @@ void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { bta_gattc_enqueue(p_clcb, p_data); } /******************************************************************************* ** ** Function bta_gattc_cache_open ** ** Description open a NV cache for loading ** ** Returns void ** *******************************************************************************/ void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { UNUSED(p_data); bta_gattc_set_discover_st(p_clcb->p_srcb); APPL_TRACE_DEBUG("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id); bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT, p_clcb->bta_conn_id, FALSE); } /******************************************************************************* ** ** Function bta_gattc_start_load ** ** Description start cache loading by sending callout open cache ** ** Returns None. ** *******************************************************************************/ void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { APPL_TRACE_DEBUG("bta_gattc_ci_open conn_id=%d server state=%d" , p_clcb->bta_conn_id, p_clcb->p_srcb->state); if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD) { if (p_data->ci_open.status == BTA_GATT_OK) { p_clcb->p_srcb->attr_index = 0; bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_LOAD_EVT, p_clcb->p_srcb->attr_index, p_clcb->bta_conn_id); } else { p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; /* cache open failure, start discovery */ bta_gattc_start_discover(p_clcb, NULL); } } if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE) { if (p_data->ci_open.status == BTA_GATT_OK) { if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) { p_data->ci_open.status = BTA_GATT_ERROR; } } if (p_data->ci_open.status != BTA_GATT_OK) { p_clcb->p_srcb->attr_index = 0; bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id); bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); } } } /******************************************************************************* ** ** Function bta_gattc_ci_load ** ** Description cache loading received. ** ** Returns None. ** *******************************************************************************/ void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { APPL_TRACE_DEBUG("bta_gattc_ci_load conn_id=%d load status=%d", p_clcb->bta_conn_id, p_data->ci_load.status); if (p_data->ci_load.status == BTA_GATT_OK || p_data->ci_load.status == BTA_GATT_MORE) { if (p_data->ci_load.num_attr != 0) bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index); if (p_data->ci_load.status == BTA_GATT_OK) { p_clcb->p_srcb->attr_index = 0; bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); } else /* load more */ { p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr; bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_LOAD_EVT, p_clcb->p_srcb->attr_index, p_clcb->bta_conn_id); } } else { bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; p_clcb->p_srcb->attr_index = 0; /* cache load failure, start discovery */ bta_gattc_start_discover(p_clcb, NULL); } } /******************************************************************************* ** ** Function bta_gattc_ci_save ** ** Description cache loading received. ** ** Returns None. ** *******************************************************************************/ void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { UNUSED(p_data); APPL_TRACE_DEBUG("bta_gattc_ci_save conn_id=%d " , p_clcb->bta_conn_id ); if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) { p_clcb->p_srcb->attr_index = 0; bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); } } /******************************************************************************* ** ** Function bta_gattc_fail Loading Loading @@ -1893,7 +1766,7 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) } } /* used to reset cache in application */ bta_gattc_co_cache_reset(p_msg->api_conn.remote_bda); bta_gattc_cache_reset(p_msg->api_conn.remote_bda); } /******************************************************************************* Loading
system/bta/gatt/bta_gattc_cache.c +211 −71 Original line number Diff line number Diff line Loading @@ -29,24 +29,37 @@ #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) #include <errno.h> #include <stdio.h> #include <string.h> #include "bta_gattc_int.h" #include "bta_sys.h" #include "btm_api.h" #include "btm_ble_api.h" #include "btm_int.h" #include "bt_common.h" #include "osi/include/log.h" #include "sdp_api.h" #include "sdpdefs.h" #include "utl.h" static void bta_gattc_cache_write(BD_ADDR server_bda, UINT16 num_attr, tBTA_GATTC_NV_ATTR *attr); static void bta_gattc_char_dscpt_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb); static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb); extern void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src); #define BTA_GATT_SDP_DB_SIZE 4096 #define GATT_CACHE_PREFIX "/data/misc/bluetooth/gatt_cache_" #define GATT_CACHE_VERSION 1 static void bta_gattc_generate_cache_file_name(char *buffer, BD_ADDR bda) { sprintf(buffer, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); } /***************************************************************************** ** Constants and data types *****************************************************************************/ Loading Loading @@ -524,8 +537,12 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb) #endif /* save cache to NV */ p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE; bta_gattc_co_cache_open(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT, conn_id, TRUE); if (btm_sec_is_a_bonded_dev(p_srvc_cb->server_bda)) { bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id); } bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); } /******************************************************************************* ** Loading Loading @@ -1391,6 +1408,34 @@ void bta_gattc_fill_gatt_db_el(btgatt_db_element_t *p_attr, bta_to_btif_uuid(&p_attr->uuid, &uuid); } /******************************************************************************* ** Returns number of elements inside db from start_handle to end_handle *******************************************************************************/ static size_t bta_gattc_get_db_size(list_t *services, UINT16 start_handle, UINT16 end_handle) { if (!services || list_is_empty(services)) return 0; size_t db_size = 0; for (list_node_t *sn = list_begin(services); sn != list_end(services); sn = list_next(sn)) { tBTA_GATTC_CACHE *p_cur_srvc = list_node(sn); if (p_cur_srvc->s_handle < start_handle) continue; if (p_cur_srvc->e_handle > end_handle) break; db_size++; if (p_cur_srvc->p_attr) db_size += list_length(p_cur_srvc->p_attr); } return db_size; } /******************************************************************************* ** ** Function bta_gattc_get_gatt_db_impl Loading @@ -1413,28 +1458,13 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV *p_srvc_cb, { APPL_TRACE_DEBUG(LOG_TAG, "%s", __func__); int db_size = 0; if (!p_srvc_cb->p_srvc_cache || list_is_empty(p_srvc_cb->p_srvc_cache)) { *count = 0; *db = NULL; return; } for (list_node_t *sn = list_begin(p_srvc_cb->p_srvc_cache); sn != list_end(p_srvc_cb->p_srvc_cache); sn = list_next(sn)) { tBTA_GATTC_CACHE *p_cur_srvc = list_node(sn); if (p_cur_srvc->s_handle < start_handle) continue; if (p_cur_srvc->e_handle > end_handle) break; db_size++; if (p_cur_srvc->p_attr) db_size += list_length(p_cur_srvc->p_attr); } size_t db_size = bta_gattc_get_db_size(p_srvc_cb->p_srvc_cache, start_handle, end_handle); void* buffer = osi_malloc(db_size * sizeof(btgatt_db_element_t)); btgatt_db_element_t *curr_db_attr = buffer; Loading Loading @@ -1555,17 +1585,14 @@ void bta_gattc_get_gatt_db(UINT16 conn_id, UINT16 start_handle, UINT16 end_handl ** *******************************************************************************/ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index) tBTA_GATTC_NV_ATTR *p_attr) { /* first attribute loading, initialize buffer */ APPL_TRACE_ERROR("%s: bta_gattc_rebuild_cache", __func__); if (attr_index == 0) { if (p_srvc_cb->p_srvc_cache) list_free(p_srvc_cb->p_srvc_cache); p_srvc_cb->p_srvc_cache = NULL; p_srvc_cb->p_cur_srvc = NULL; } while (num_attr > 0 && p_attr != NULL) { Loading Loading @@ -1617,6 +1644,7 @@ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_han memcpy(&p_attr->uuid, &uuid, sizeof(tBT_UUID)); } /******************************************************************************* ** ** Function bta_gattc_cache_save Loading @@ -1626,21 +1654,19 @@ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_han ** Returns None. ** *******************************************************************************/ BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) { UINT8 i = 0; UINT16 offset = 0; tBTA_GATTC_NV_ATTR nv_attr[BTA_GATTC_NV_LOAD_MAX]; if (!p_srvc_cb->p_srvc_cache || list_is_empty(p_srvc_cb->p_srvc_cache)) return; int i = 0; size_t db_size = bta_gattc_get_db_size(p_srvc_cb->p_srvc_cache, 0x0000, 0xFFFF); tBTA_GATTC_NV_ATTR *nv_attr = osi_malloc(db_size * sizeof(tBTA_GATTC_NV_ATTR)); if (p_srvc_cb->p_srvc_cache && !list_is_empty(p_srvc_cb->p_srvc_cache)) { for (list_node_t *sn = list_begin(p_srvc_cb->p_srvc_cache); sn != list_end(p_srvc_cb->p_srvc_cache); sn = list_next(sn)) { tBTA_GATTC_CACHE *p_cur_srvc = list_node(sn); if (i >= BTA_GATTC_NV_LOAD_MAX) break; if (offset ++ >= p_srvc_cb->attr_index) bta_gattc_fill_nv_attr(&nv_attr[i++], BTA_GATTC_ATTR_TYPE_SRVC, p_cur_srvc->s_handle, Loading @@ -1657,10 +1683,6 @@ BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) an != list_end(p_cur_srvc->p_attr); an = list_next(an)) { tBTA_GATTC_CACHE_ATTR *p_attr = list_node(an); if (i >= BTA_GATTC_NV_LOAD_MAX) break; if (offset++ >= p_srvc_cb->attr_index) { bta_gattc_fill_nv_attr(&nv_attr[i++], p_attr->attr_type, p_attr->attr_handle, Loading @@ -1671,19 +1693,137 @@ BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id) FALSE); } } bta_gattc_cache_write(p_srvc_cb->server_bda, db_size, nv_attr); osi_free(nv_attr); } /******************************************************************************* ** ** Function bta_gattc_cache_load ** ** Description Load GATT cache from storage for server. ** ** Parameter p_clcb: pointer to server clcb, that will ** be filled from storage ** Returns true on success, false otherwise ** *******************************************************************************/ bool bta_gattc_cache_load(tBTA_GATTC_CLCB *p_clcb) { char fname[255] = {0}; bta_gattc_generate_cache_file_name(fname, p_clcb->p_srcb->server_bda); FILE *fd = fopen(fname, "rb"); if (!fd) { APPL_TRACE_ERROR("%s: can't open GATT cache file %s for reading, error: %s", __func__, fname, strerror(errno)); return false; } UINT16 cache_ver = 0; tBTA_GATTC_NV_ATTR *attr = NULL; bool success = false; if (fread(&cache_ver, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't read GATT cache version from: %s", __func__, fname); goto done; } if (cache_ver != GATT_CACHE_VERSION) { APPL_TRACE_ERROR("%s: wrong GATT cache version: %s", __func__, fname); goto done; } if (i > 0) { bta_gattc_co_cache_save(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_SAVE_EVT, i, nv_attr, p_srvc_cb->attr_index, conn_id); UINT16 num_attr = 0; p_srvc_cb->attr_index += i; if (fread(&num_attr, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't read number of GATT attributes: %s", __func__, fname); goto done; } return TRUE; } else { return FALSE; attr = osi_malloc(sizeof(tBTA_GATTC_NV_ATTR) * num_attr); if (fread(attr, sizeof(tBTA_GATTC_NV_ATTR), 0xFF, fd) != num_attr) { APPL_TRACE_ERROR("%s: can't read GATT attributes: %s", __func__, fname); goto done; } bta_gattc_rebuild_cache(p_clcb->p_srcb, num_attr, attr); success = true; done: osi_free(attr); fclose(fd); return success; } /******************************************************************************* ** ** Function bta_gattc_cache_write ** ** Description This callout function is executed by GATT when a server cache ** is available to save. ** ** Parameter server_bda: server bd address of this cache belongs to ** num_attr: number of attribute to be save. ** attr: pointer to the list of attributes to save. ** Returns ** *******************************************************************************/ static void bta_gattc_cache_write(BD_ADDR server_bda, UINT16 num_attr, tBTA_GATTC_NV_ATTR *attr) { char fname[255] = {0}; bta_gattc_generate_cache_file_name(fname, server_bda); FILE *fd = fopen(fname, "wb"); if (!fd) { APPL_TRACE_ERROR("%s: can't open GATT cache file for writing: %s", __func__, fname); return; } UINT16 cache_ver = GATT_CACHE_VERSION; if (fwrite(&cache_ver, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't write GATT cache version: %s", __func__, fname); fclose(fd); return; } if (fwrite(&num_attr, sizeof(UINT16), 1, fd) != 1) { APPL_TRACE_ERROR("%s: can't write GATT cache attribute count: %s", __func__, fname); fclose(fd); return; } if (fwrite(attr, sizeof(tBTA_GATTC_NV_ATTR), num_attr, fd) != num_attr) { APPL_TRACE_ERROR("%s: can't write GATT cache attributes: %s", __func__, fname); fclose(fd); return; } fclose(fd); } /******************************************************************************* ** ** Function bta_gattc_cache_reset ** ** Description This callout function is executed by GATTC to reset cache in ** application ** ** Parameter server_bda: server bd address of this cache belongs to ** ** Returns void. ** *******************************************************************************/ void bta_gattc_cache_reset(BD_ADDR server_bda) { BTIF_TRACE_DEBUG("%s", __func__); char fname[255] = {0}; bta_gattc_generate_cache_file_name(fname, server_bda); unlink(fname); } #endif /* BTA_GATT_INCLUDED */
system/bta/gatt/bta_gattc_ci.cdeleted 100644 → 0 +0 −132 Original line number Diff line number Diff line /****************************************************************************** * * Copyright (C) 2010-2012 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ /****************************************************************************** * * This is the implementation file for the GATT call-in functions. * ******************************************************************************/ #include "bt_target.h" #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) #include <string.h> #include "bta_api.h" #include "bta_sys.h" #include "bta_gattc_ci.h" #include "bt_common.h" #include "utl.h" /******************************************************************************* ** ** Function bta_gattc_ci_cache_open ** ** Description This function sends an event to indicate server cache open ** completed. ** ** Parameters server_bda - server BDA of this cache. ** status - BTA_GATT_OK if full buffer of data, ** BTA_GATT_FAIL if an error has occurred. ** ** Returns void ** *******************************************************************************/ void bta_gattc_ci_cache_open(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status, UINT16 conn_id) { tBTA_GATTC_CI_EVT *p_evt = (tBTA_GATTC_CI_EVT *) osi_malloc(sizeof(tBTA_GATTC_CI_EVT)); UNUSED(server_bda); p_evt->hdr.event = evt; p_evt->hdr.layer_specific = conn_id; p_evt->status = status; bta_sys_sendmsg(p_evt); } /******************************************************************************* ** ** Function bta_gattc_ci_cache_load ** ** Description This function sends an event to BTA indicating the phone has ** load the servere cache and ready to send it to the stack. ** ** Parameters server_bda - server BDA of this cache. ** num_bytes_read - number of bytes read into the buffer ** specified in the read callout-function. ** status - BTA_GATT_OK if full buffer of data, ** BTA_GATT_FAIL if an error has occurred. ** ** Returns void ** *******************************************************************************/ void bta_gattc_ci_cache_load(BD_ADDR server_bda, UINT16 evt, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, tBTA_GATT_STATUS status, UINT16 conn_id) { tBTA_GATTC_CI_LOAD *p_evt = (tBTA_GATTC_CI_LOAD *)osi_calloc(sizeof(tBTA_GATTC_CI_LOAD)); UNUSED(server_bda); p_evt->hdr.event = evt; p_evt->hdr.layer_specific = conn_id; p_evt->status = status; p_evt->num_attr = (num_attr > BTA_GATTC_NV_LOAD_MAX) ? BTA_GATTC_NV_LOAD_MAX : num_attr; if (p_evt->num_attr > 0 && p_attr != NULL) { memcpy(p_evt->attr, p_attr, p_evt->num_attr * sizeof(tBTA_GATTC_NV_ATTR)); } bta_sys_sendmsg(p_evt); } /******************************************************************************* ** ** Function bta_gattc_ci_cache_save ** ** Description This function sends an event to BTA indicating the phone has ** save the servere cache. ** ** Parameters server_bda - server BDA of this cache. ** evt - callin event code. ** status - BTA_GATT_OK if full buffer of data, ** BTA_GATT_ERROR if an error has occurred. *8 conn_id - for this NV operation for. ** ** Returns void ** *******************************************************************************/ void bta_gattc_ci_cache_save(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status, UINT16 conn_id) { tBTA_GATTC_CI_EVT *p_evt = (tBTA_GATTC_CI_EVT *)osi_malloc(sizeof(tBTA_GATTC_CI_EVT)); UNUSED(server_bda); p_evt->hdr.event = evt; p_evt->hdr.layer_specific = conn_id; p_evt->status = status; bta_sys_sendmsg(p_evt); } #endif /* BTA_GATT_INCLUDED */