]> granicus.if.org Git - esp-idf/commitdiff
Component/bt: fix gatt cache error
authorzhiweijian <zhiweijian@espressif.com>
Tue, 20 Mar 2018 11:27:50 +0000 (19:27 +0800)
committerzhiweijian <zhiweijian@espressif.com>
Mon, 23 Apr 2018 07:43:10 +0000 (15:43 +0800)
- fix sev == NULL error
- fix start_handle == end_handle

components/bt/bluedroid/api/include/esp_gattc_api.h
components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
components/bt/bluedroid/bta/gatt/bta_gatts_act.c
components/bt/bluedroid/bta/include/bta_gatt_api.h
components/bt/bluedroid/bta/include/bta_gattc_int.h
components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c
components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
examples/bluetooth/gatt_client/main/gattc_demo.c
examples/bluetooth/gatt_security_client/main/example_ble_sec_gattc_demo.c
examples/bluetooth/gattc_multi_connect/main/gattc_multi_connect.c

index 025cc4472f498412efb89144b96d55b4c58eab8e..44c013d5ee34912ac422d0a495e138530fb00644 100644 (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 */
 
     /**
index 2108fbcd05c7cc33d0d6a2d8b7e0b0d8ce181d82..c43a2d49119b3dc271c13d645aa493a18232d5df 100644 (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) {
index 923803b83c62206db65313b28f41e31d59c70917..c93fbe0e0576d60635ea0f03840c92a5aaece351 100644 (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);
index 226a9e6d6f307c9877899bfaa0e9aa6a0e8dce3a..936cb3b420962841a2d8c1043f9cf7a7127f8136 100644 (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 {
index ad52ada53d47f80e5385087019bd2bab940e90bb..6df2529f7700e914c3e3479e82b59f98839e4b68 100644 (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
index 32f5e39ffc22481dce4aad0ff7e9dcfb1d3e95ce..24017aece10ae339b71bb2da365f04304073a18b 100644 (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;
index ca11213823e8699b0086c5cddd1896d4f401758c..ae74c5ad3885acb5016e918e62060b7cfbf1aeb1 100644 (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,
index a2f8899f4f24f637a2aa6faf06009488234a51dd..31704c0948b60176c1b97626d1c4ac88836c41f6 100644 (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,
index 5294c344da9a2bd8dd4dc623abc23fca0666e1a7..2090c8bc00601ebd240d2039ccaf442673f91b46 100644 (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;
index 2eca1a8f1c2e9d4a8a54f642ce8a0f0fb666f226..e5b44868e6948dd4a582c0145aa1f1f578d51729 100644 (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;