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];
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);
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, ¶m);
+ //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, ¶m);
return;
}
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{
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, ¶m);
+ //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__);
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, ¶m);
+ //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;
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)
{
default:
break;
+ return;
+
}
future_ready(btc_creat_tab_env.complete_future, FUTURE_SUCCESS);
}