]> granicus.if.org Git - esp-idf/commitdiff
component/bt: cherry-pick the btdm_hit_limit_github_#12259 branch to this branch.
authorYulong <huangyulong@espressif.com>
Wed, 14 Jun 2017 11:14:23 +0000 (07:14 -0400)
committerYulong <huangyulong@espressif.com>
Wed, 14 Jun 2017 11:14:23 +0000 (07:14 -0400)
components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c

index 9161ce8271c84f493fc3e7ccafd8d5db74eeec84..2ac15c19851d967c1289961bfa1fb78c60f66828 100644 (file)
@@ -34,6 +34,7 @@ typedef struct {
     uint16_t svc_start_hdl;
     esp_bt_uuid_t svc_uuid;
     bool        is_tab_creat_svc;
+    bool      is_use_svc;
     uint8_t   num_handle;
     uint8_t   handle_idx;
     uint16_t handles[ESP_GATT_ATTR_HANDLE_MAX];
@@ -41,6 +42,10 @@ typedef struct {
 
 static esp_btc_creat_tab_t btc_creat_tab_env;
 
+
+static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
+                                                                          uint8_t max_nb_attr);
+
 static inline void btc_gatts_cb_to_app(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
 {
     esp_gatts_cb_t btc_gatts_cb = (esp_gatts_cb_t)btc_profile_cb_get(BTC_PID_GATTS);
@@ -211,12 +216,16 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
     param.add_attr_tab.status = ESP_GATT_OK;
     param.add_attr_tab.num_handle = max_nb_attr;
 
-    // To add a large attribute table, need to enlarge BTC_TASK_QUEUE_NUM
-    if (max_nb_attr > BTC_TASK_QUEUE_NUM){
-        param.add_attr_tab.status = ESP_GATT_NO_RESOURCES;
+    if (param.add_attr_tab.status != ESP_GATT_OK) {
+        btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
+        //reset the env after sent the data to app
+        memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
+        return;
     }
 
-    if (param.add_attr_tab.status != ESP_GATT_OK){
+    // Check the attribute table is valid or not
+    if ((param.add_attr_tab.status = btc_gatts_check_valid_attr_tab(gatts_attr_db, max_nb_attr)) != ESP_GATT_OK) {
+        //sent the callback event to the application
         btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
         return;
     }
@@ -226,7 +235,7 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
     btc_creat_tab_env.is_tab_creat_svc = true;
     btc_creat_tab_env.num_handle = max_nb_attr;
     for(int i = 0; i < max_nb_attr; i++){
-        if(gatts_attr_db[i].att_desc.uuid_length== ESP_UUID_LEN_16){
+        if(gatts_attr_db[i].att_desc.uuid_length == ESP_UUID_LEN_16){
             uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
         }
         else{
@@ -250,8 +259,18 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
                                               gatts_attr_db[i].att_desc.value);
     
                 btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
-                BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid, 
-                                        srvc_inst_id, max_nb_attr, true);
+                if (btc_creat_tab_env.is_use_svc != true) {
+                    BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
+                                            srvc_inst_id, max_nb_attr, true);
+                    btc_creat_tab_env.is_use_svc = true;
+                } else {
+                    LOG_ERROR("Each service table can only created one primary service.");
+                    param.add_attr_tab.status = ESP_GATT_ERROR;
+                    btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
+                    //reset the env after sent the data to app
+                    memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
+                    return;
+                }
                 
                  if (future_await(future_p) == FUTURE_FAIL) {
                         LOG_ERROR("%s failed\n", __func__);
@@ -267,8 +286,18 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
                 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_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
-                BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid, 
-                                        srvc_inst_id, max_nb_attr, false);
+                if (btc_creat_tab_env.is_use_svc != true) {
+                    BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
+                                            srvc_inst_id, max_nb_attr, false);
+                    btc_creat_tab_env.is_use_svc = true;
+                } else {
+                    LOG_ERROR("Each service table can only created one secondary service.");
+                    param.add_attr_tab.status = ESP_GATT_ERROR;
+                    btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
+                    //reset the env after sent the data to app
+                    memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
+                    return;
+                }
                 if (future_await(future_p) == FUTURE_FAIL) {
                         LOG_ERROR("%s failed\n", __func__);
                         return;
@@ -378,6 +407,75 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
     btc_creat_tab_env.is_tab_creat_svc = false;
 }
 
+static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
+                                                                          uint8_t max_nb_attr)
+{
+    uint8_t svc_num = 0;
+    uint16_t uuid = 0;
+
+    for(int i = 0; i < max_nb_attr; i++) {
+        if(gatts_attr_db[i].att_desc.uuid_length== ESP_UUID_LEN_16) {
+            uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
+        } else {
+            continue;
+        }
+
+        switch(uuid) {
+            case ESP_GATT_UUID_PRI_SERVICE:
+            case ESP_GATT_UUID_SEC_SERVICE:
+                ++svc_num;
+                if (svc_num > 1) {
+                    LOG_ERROR("Each service table can only created one primary service or secondly service.");
+                    return ESP_GATT_ERROR;
+                }
+                break;
+            case ESP_GATT_UUID_INCLUDE_SERVICE: {
+                esp_gatts_incl_svc_desc_t *svc_desc = (esp_gatts_incl_svc_desc_t *)gatts_attr_db[i].att_desc.value;
+                if(svc_desc == NULL) {
+                    LOG_ERROR("%s, The include service attribute should not be NULL.", __func__);
+                    return ESP_GATT_INVALID_PDU;
+                } else if((svc_desc->start_hdl == 0) || (svc_desc->end_hdl == 0) ||
+                          (svc_desc->start_hdl == svc_desc->end_hdl)) {
+                    LOG_ERROR("%s, The include service attribute handle is invalid, start_hanlde = %d, end_handle = %d",\
+                              __func__, svc_desc->start_hdl, svc_desc->end_hdl);
+                    return ESP_GATT_INVALID_HANDLE;
+                }
+                break;
+            }
+            case ESP_GATT_UUID_CHAR_DECLARE:
+                if((gatts_attr_db[i].att_desc.value) == NULL) {
+                    LOG_ERROR("%s, Characteristic declaration should not be NULL.", __func__);
+                    return ESP_GATT_INVALID_PDU;
+                }
+
+                if(gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_16 &&
+                   gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_32 &&
+                   gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_128) {
+                    LOG_ERROR("%s, The Charateristic uuid length = %d is invalid", __func__,\
+                        gatts_attr_db[i+1].att_desc.uuid_length);
+                    return ESP_GATT_INVALID_ATTR_LEN;
+                }
+
+                if(gatts_attr_db[i+1].att_desc.uuid_length == ESP_UUID_LEN_16) {
+                    uuid = (gatts_attr_db[i+1].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i+1].att_desc.uuid_p[0]);
+                    if(uuid == ESP_GATT_UUID_CHAR_DECLARE || uuid == ESP_GATT_UUID_CHAR_EXT_PROP ||
+                        uuid == ESP_GATT_UUID_CHAR_DESCRIPTION || uuid == ESP_GATT_UUID_CHAR_CLIENT_CONFIG ||
+                        uuid == ESP_GATT_UUID_CHAR_SRVR_CONFIG || uuid == ESP_GATT_UUID_CHAR_PRESENT_FORMAT ||
+                        uuid == ESP_GATT_UUID_CHAR_AGG_FORMAT || uuid == ESP_GATT_UUID_CHAR_VALID_RANGE ||
+                        uuid == ESP_GATT_UUID_EXT_RPT_REF_DESCR || uuid == ESP_GATT_UUID_RPT_REF_DESCR) {
+                        LOG_ERROR("%s, The charateristic value uuid = %d is invalid", __func__, uuid);
+                        return ESP_GATT_INVALID_PDU;
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    return ESP_GATT_OK;
+}
+
 void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value)
 {
     
@@ -474,6 +572,8 @@ static void btc_gatts_inter_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
             default:
                 break;
 
+          return;
+
         }
         future_ready(btc_creat_tab_env.complete_future, FUTURE_SUCCESS);
     }