|
@@ -34,6 +34,7 @@ typedef struct {
|
|
|
uint16_t svc_start_hdl;
|
|
uint16_t svc_start_hdl;
|
|
|
esp_bt_uuid_t svc_uuid;
|
|
esp_bt_uuid_t svc_uuid;
|
|
|
bool is_tab_creat_svc;
|
|
bool is_tab_creat_svc;
|
|
|
|
|
+ bool is_use_svc;
|
|
|
uint8_t num_handle;
|
|
uint8_t num_handle;
|
|
|
uint8_t handle_idx;
|
|
uint8_t handle_idx;
|
|
|
uint16_t handles[ESP_GATT_ATTR_HANDLE_MAX];
|
|
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_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)
|
|
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);
|
|
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.status = ESP_GATT_OK;
|
|
|
param.add_attr_tab.num_handle = max_nb_attr;
|
|
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);
|
|
btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, ¶m);
|
|
|
return;
|
|
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.is_tab_creat_svc = true;
|
|
|
btc_creat_tab_env.num_handle = max_nb_attr;
|
|
btc_creat_tab_env.num_handle = max_nb_attr;
|
|
|
for(int i = 0; i < max_nb_attr; i++){
|
|
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]);
|
|
uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
|
|
|
}
|
|
}
|
|
|
else{
|
|
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);
|
|
gatts_attr_db[i].att_desc.value);
|
|
|
|
|
|
|
|
btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
|
|
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) {
|
|
if (future_await(future_p) == FUTURE_FAIL) {
|
|
|
LOG_ERROR("%s failed\n", __func__);
|
|
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,
|
|
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);
|
|
gatts_attr_db[i].att_desc.uuid_p);
|
|
|
btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
|
|
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) {
|
|
if (future_await(future_p) == FUTURE_FAIL) {
|
|
|
LOG_ERROR("%s failed\n", __func__);
|
|
LOG_ERROR("%s failed\n", __func__);
|
|
|
return;
|
|
return;
|
|
@@ -378,6 +407,73 @@ 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;
|
|
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) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
|
|
|
|
|
+ switch(uuid) {
|
|
|
|
|
+ case ESP_GATT_UUID_PRI_SERVICE:
|
|
|
|
|
+ case ESP_GATT_UUID_SEC_SERVICE:
|
|
|
|
|
+ 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)
|
|
void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value)
|
|
|
{
|
|
{
|
|
|
|
|
|
|
@@ -444,9 +540,9 @@ static void btc_gatts_inter_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
|
|
msg.sig = BTC_SIG_API_CB;
|
|
msg.sig = BTC_SIG_API_CB;
|
|
|
msg.pid = BTC_PID_GATTS;
|
|
msg.pid = BTC_PID_GATTS;
|
|
|
msg.act = event;
|
|
msg.act = event;
|
|
|
- if(btc_creat_tab_env.is_tab_creat_svc && btc_creat_tab_env.complete_future){
|
|
|
|
|
- switch(event){
|
|
|
|
|
- case BTA_GATTS_CREATE_EVT:{
|
|
|
|
|
|
|
+ if(btc_creat_tab_env.is_tab_creat_svc && btc_creat_tab_env.complete_future) {
|
|
|
|
|
+ switch(event) {
|
|
|
|
|
+ case BTA_GATTS_CREATE_EVT: {
|
|
|
//save the service handle to the btc module after used
|
|
//save the service handle to the btc module after used
|
|
|
//the attribute table method to creat a service
|
|
//the attribute table method to creat a service
|
|
|
bta_to_btc_uuid(&btc_creat_tab_env.svc_uuid, &p_data->create.uuid);
|
|
bta_to_btc_uuid(&btc_creat_tab_env.svc_uuid, &p_data->create.uuid);
|
|
@@ -455,27 +551,28 @@ static void btc_gatts_inter_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
|
|
btc_creat_tab_env.handles[index] = p_data->create.service_id;
|
|
btc_creat_tab_env.handles[index] = p_data->create.service_id;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- case BTA_GATTS_ADD_INCL_SRVC_EVT:{
|
|
|
|
|
|
|
+ case BTA_GATTS_ADD_INCL_SRVC_EVT: {
|
|
|
uint8_t index = btc_creat_tab_env.handle_idx;
|
|
uint8_t index = btc_creat_tab_env.handle_idx;
|
|
|
btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
|
|
btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- case BTA_GATTS_ADD_CHAR_EVT:{
|
|
|
|
|
|
|
+ case BTA_GATTS_ADD_CHAR_EVT: {
|
|
|
uint8_t index = btc_creat_tab_env.handle_idx;
|
|
uint8_t index = btc_creat_tab_env.handle_idx;
|
|
|
btc_creat_tab_env.handles[index] = p_data->add_result.attr_id - 1;
|
|
btc_creat_tab_env.handles[index] = p_data->add_result.attr_id - 1;
|
|
|
btc_creat_tab_env.handles[index+1] = p_data->add_result.attr_id;
|
|
btc_creat_tab_env.handles[index+1] = p_data->add_result.attr_id;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- case BTA_GATTS_ADD_CHAR_DESCR_EVT:{
|
|
|
|
|
|
|
+ case BTA_GATTS_ADD_CHAR_DESCR_EVT: {
|
|
|
uint8_t index = btc_creat_tab_env.handle_idx;
|
|
uint8_t index = btc_creat_tab_env.handle_idx;
|
|
|
btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
|
|
btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
default:
|
|
default:
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
future_ready(btc_creat_tab_env.complete_future, FUTURE_SUCCESS);
|
|
future_ready(btc_creat_tab_env.complete_future, FUTURE_SUCCESS);
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
status = btc_transfer_context(&msg, p_data,
|
|
status = btc_transfer_context(&msg, p_data,
|
|
|
sizeof(tBTA_GATTS), btc_gatts_cb_param_copy_req);
|
|
sizeof(tBTA_GATTS), btc_gatts_cb_param_copy_req);
|