Component/bt: fix gatt cache error

- fix sev == NULL error
- fix start_handle == end_handle
This commit is contained in:
zhiweijian 2018-03-20 19:27:50 +08:00
parent 088c73bd22
commit be107320f7
10 changed files with 116 additions and 39 deletions

View File

@ -127,6 +127,7 @@ typedef union {
uint16_t start_handle; /*!< Service start handle */
uint16_t end_handle; /*!< Service end handle */
esp_gatt_id_t srvc_id; /*!< Service id, include service uuid and other information */
bool is_primary; /*!< True if this is the primary service */
} search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */
/**

View File

@ -214,6 +214,40 @@ static void bta_gattc_free(void *ptr)
osi_free(ptr);
}
void bta_gattc_insert_sec_service_to_cache(list_t *services, tBTA_GATTC_SERVICE *p_new_srvc)
{
// services/p_new_srvc is NULL
if (!services || !p_new_srvc) {
APPL_TRACE_ERROR("%s services/p_new_srvc is NULL", __func__);
return;
}
//list is empty
if (list_is_empty(services)) {
list_append(services, p_new_srvc);
} else {
//check the first service
list_node_t *sn = list_begin(services);
tBTA_GATTC_SERVICE *service = list_node(sn);
if(service && p_new_srvc->e_handle < service->s_handle) {
list_prepend(services, p_new_srvc);
} else {
for (list_node_t *sn = list_begin(services); sn != list_end(services); sn = list_next(sn)) {
list_node_t *next_sn = list_next(sn);
if(next_sn == list_end(services)) {
list_append(services, p_new_srvc);
return;
}
tBTA_GATTC_SERVICE *service = list_node(sn);
tBTA_GATTC_SERVICE *next_service = list_node(next_sn);
if (p_new_srvc->s_handle > service->e_handle && p_new_srvc->e_handle < next_service->s_handle) {
list_insert_after(services, sn, p_new_srvc);
return;
}
}
}
}
}
/*******************************************************************************
**
** Function bta_gattc_add_srvc_to_cache
@ -251,7 +285,12 @@ static tBTA_GATT_STATUS bta_gattc_add_srvc_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
p_srvc_cb->p_srvc_cache = list_new(service_free);
}
list_append(p_srvc_cb->p_srvc_cache, p_new_srvc);
if(is_primary) {
list_append(p_srvc_cb->p_srvc_cache, p_new_srvc);
} else {
//add secondary service into list
bta_gattc_insert_sec_service_to_cache(p_srvc_cb->p_srvc_cache, p_new_srvc);
}
return BTA_GATT_OK;
}
@ -336,9 +375,14 @@ static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
isvc->included_service = bta_gattc_find_matching_service(
p_srvc_cb->p_srvc_cache, incl_srvc_s_handle);
if (!isvc->included_service) {
APPL_TRACE_ERROR("%s: Illegal action to add non-existing included service!", __func__);
osi_free(isvc);
return GATT_WRONG_STATE;
// if it is a secondary service, wait to update later
if(property == 0){
p_srvc_cb->update_sec_sev = true;
} else {
APPL_TRACE_ERROR("%s: Illegal action to add non-existing included service!", __func__);
osi_free(isvc);
return GATT_WRONG_STATE;
}
}
list_append(service->included_svc, isvc);
@ -502,6 +546,30 @@ void bta_gattc_start_disc_char_dscp(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
}
}
void bta_gattc_update_include_service(const list_t *services) {
if (!services || list_is_empty(services)) {
return;
}
for (list_node_t *sn = list_begin(services); sn != list_end(services); sn = list_next(sn)) {
tBTA_GATTC_SERVICE *service = list_node(sn);
if(!service && list_is_empty(service->included_svc)) break;
for (list_node_t *sn = list_begin(service->included_svc); sn != list_end(service->included_svc); sn = list_next(sn)) {
tBTA_GATTC_INCLUDED_SVC *include_service = list_node(sn);
if(include_service && !include_service->included_service) {
//update
include_service->included_service = bta_gattc_find_matching_service(services, include_service->incl_srvc_s_handle);
if(!include_service->included_service) {
//not match, free it
list_remove(service->included_svc, include_service);
osi_free(include_service);
}
}
}
}
}
/*******************************************************************************
**
** Function bta_gattc_explore_srvc
@ -537,6 +605,11 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
return;
}
}
//update include service when have secondary service
if(p_srvc_cb->update_sec_sev) {
bta_gattc_update_include_service(p_srvc_cb->p_srvc_cache);
p_srvc_cb->update_sec_sev = false;
}
/* no service found at all, the end of server discovery*/
LOG_DEBUG("%s no more services found", __func__);
@ -1022,8 +1095,8 @@ void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid)
cb_data.srvc_res.service_uuid.inst_id = p_cache->handle;
cb_data.srvc_res.start_handle = p_cache->s_handle;
cb_data.srvc_res.end_handle = p_cache->e_handle;
memcpy(&cb_data.srvc_res.service_uuid.uuid, &p_cache->uuid, sizeof(tBTA_GATT_ID));
cb_data.srvc_res.is_primary = p_cache->is_primary;
memcpy(&cb_data.srvc_res.service_uuid.uuid, &p_cache->uuid, sizeof(tBT_UUID));
(* p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_RES_EVT, &cb_data);
}
}
@ -1141,7 +1214,8 @@ void bta_gattc_get_service_with_uuid(UINT16 conn_id, tBT_UUID *svc_uuid,
int *count)
{
const list_t* svc = bta_gattc_get_services(conn_id);
if (svc == NULL) {
if(!svc) {
APPL_TRACE_WARNING("%s(), no service.", __func__);
*svc_db = NULL;
*count = 0;
return;
@ -1227,8 +1301,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
return;
}
size_t db_size = ((end_handle - start_handle) < p_srcb->total_attr) ? (end_handle - start_handle) : p_srcb->total_attr;
size_t db_size = ((end_handle - start_handle + 1) < p_srcb->total_attr) ? (end_handle - start_handle + 1) : p_srcb->total_attr;
if (!db_size) {
APPL_TRACE_DEBUG("the db size is 0.");
*count = 0;
@ -1298,9 +1371,10 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
for (list_node_t *cn = list_begin(p_cur_srvc->characteristics);
cn != list_end(p_cur_srvc->characteristics); cn = list_next(cn)) {
tBTA_GATTC_CHARACTERISTIC *p_char = list_node(cn);
if (p_char->handle < start_handle) {
continue;
if(op == GATT_OP_GET_ALL_CHAR || op == GATT_OP_GET_CHAR_BY_UUID) {
if (p_char->handle < start_handle) {
continue;
}
}
if (p_char->handle > end_handle) {

View File

@ -335,19 +335,19 @@ void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
cb_data.create.status = BTA_GATT_OK;
cb_data.create.service_id = service_id;
// btla-specific ++
cb_data.create.is_primary = p_msg->api_create_svc.is_pri;
// btla-specific --
cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if;
} else {
cb_data.status = BTA_GATT_ERROR;
memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
APPL_TRACE_ERROR("service creation failed.");
}
// btla-specific ++
memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
cb_data.create.svc_instance = p_msg->api_create_svc.inst;
// btla-specific --
}
if (p_cb->rcb[rcb_idx].p_cback) {
(* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);

View File

@ -321,6 +321,7 @@ typedef struct {
UINT16 start_handle;
UINT16 end_handle;
tBTA_GATT_ID service_uuid;
bool is_primary;
}tBTA_GATTC_SRVC_RES;
typedef struct {

View File

@ -300,6 +300,7 @@ typedef struct {
UINT16 attr_index; /* cahce NV saving/loading attribute index */
UINT16 mtu;
bool update_sec_sev;
} tBTA_GATTC_SERV;
#ifndef BTA_GATTC_NOTIF_REG_MAX

View File

@ -827,6 +827,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
param.search_res.conn_id = BTC_GATT_GET_CONN_ID(srvc_res->conn_id);
param.search_res.start_handle = srvc_res->start_handle;
param.search_res.end_handle = srvc_res->end_handle;
param.search_res.is_primary = srvc_res->is_primary;
bta_to_btc_gatt_id(&param.search_res.srvc_id, &srvc_res->service_uuid);
btc_gattc_cb_to_app(ESP_GATTC_SEARCH_RES_EVT, gattc_if, &param);
break;

View File

@ -284,8 +284,8 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
esp_gatt_srvc_id_t esp_srvc_id;
esp_srvc_id.id.inst_id = srvc_inst_id;
btc_gatts_uuid_format_convert(&esp_srvc_id.id.uuid,gatts_attr_db[i].att_desc.uuid_length,
gatts_attr_db[i].att_desc.uuid_p);
btc_gatts_uuid_format_convert(&esp_srvc_id.id.uuid,gatts_attr_db[i].att_desc.length,
gatts_attr_db[i].att_desc.value);
btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
if (btc_creat_tab_env.is_use_svc != true) {
BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,

View File

@ -132,14 +132,14 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
break;
case ESP_GATTC_SEARCH_RES_EVT: {
ESP_LOGI(GATTC_TAG, "ESP_GATTC_SEARCH_RES_EVT");
esp_gatt_srvc_id_t *srvc_id =(esp_gatt_srvc_id_t *)&p_data->search_res.srvc_id;
if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary);
ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.start_handle, p_data->search_res.srvc_id.inst_id);
if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "service found");
get_server = true;
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle = p_data->search_res.start_handle;
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle = p_data->search_res.end_handle;
ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16);
ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
}
break;
}
@ -222,7 +222,6 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error");
}
/* Every char has only one descriptor in our 'ESP_GATTS_DEMO' demo, so we used first 'descr_elem_result' */
if (count > 0 && descr_elem_result[0].uuid.len == ESP_UUID_LEN_16 && descr_elem_result[0].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG){
ret_status = esp_ble_gattc_write_char_descr( gattc_if,

View File

@ -156,10 +156,10 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
break;
case ESP_GATTC_SEARCH_RES_EVT: {
esp_gatt_srvc_id_t *srvc_id =(esp_gatt_srvc_id_t *)&p_data->search_res.srvc_id;
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", p_data->search_res.conn_id);
if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16);
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary);
ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.start_handle, p_data->search_res.srvc_id.inst_id);
if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
get_service = true;
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle = p_data->search_res.start_handle;
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle = p_data->search_res.end_handle;

View File

@ -175,10 +175,10 @@ static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
break;
case ESP_GATTC_SEARCH_RES_EVT: {
esp_gatt_srvc_id_t *srvc_id = (esp_gatt_srvc_id_t *)&p_data->search_res.srvc_id;
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", p_data->search_res.conn_id);
if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16);
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary);
ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.start_handle, p_data->search_res.srvc_id.inst_id);
if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
get_service_a = true;
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle = p_data->search_res.start_handle;
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle = p_data->search_res.end_handle;
@ -375,10 +375,10 @@ static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
break;
case ESP_GATTC_SEARCH_RES_EVT: {
esp_gatt_srvc_id_t *srvc_id = (esp_gatt_srvc_id_t *)&p_data->search_res.srvc_id;
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", p_data->search_res.conn_id);
if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16);
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary);
ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.start_handle, p_data->search_res.srvc_id.inst_id);
if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
get_service_b = true;
gl_profile_tab[PROFILE_B_APP_ID].service_start_handle = p_data->search_res.start_handle;
gl_profile_tab[PROFILE_B_APP_ID].service_end_handle = p_data->search_res.end_handle;
@ -574,10 +574,10 @@ static void gattc_profile_c_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
break;
case ESP_GATTC_SEARCH_RES_EVT: {
esp_gatt_srvc_id_t *srvc_id = (esp_gatt_srvc_id_t *)&p_data->search_res.srvc_id;
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", p_data->search_res.conn_id);
if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16);
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary);
ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.start_handle, p_data->search_res.srvc_id.inst_id);
if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
get_service_c = true;
gl_profile_tab[PROFILE_C_APP_ID].service_start_handle = p_data->search_res.start_handle;
gl_profile_tab[PROFILE_C_APP_ID].service_end_handle = p_data->search_res.end_handle;