This is a combination of 4 commits.

squash again all the commit.

component/bt: Change all the gattc API && bta gattc layer.

component/bt: Debug the code and change the btc_ble_gattc_get_db method.

component/bt: Change the gatt read API interface.

component/bt: Reconstruction the BTA_gattc_cache code.

component/bt: Change back the bluedroid_get_status to marco.

component/bt: Added the serch service res start_handle & end_handle to the result.

component/bt: Change the gattc docs format.

component/bt: Change the docs format.

component/bt: fix the read char value bug.

component/bt: change the gattc_get_attr_count method.

component/bt: Change back the bta_gattc write ccc code.

component/bt: Change the gattc api docs format

component/bt: Change the gattc API docs.

component/bt: Change the prepare write descriptor method to avoid the exection.

Component/bt: modify gatt clinet demo with new API

component/bt: Change the p_src_data->read.p_value to avoid exection.

compoent/bt: Change the bugfix of gattc unreg for the notify.

Modify gattc security demo

component/bt: Change the log error.

Component/bt: modify gattc_multi_connect demo

componnet/bt: Change the bta_gattc_cache sdp include.

component/bt: Change the start_handle & end_handle not from the service.

component/bt: Change the gattc API docs.

component/bt: Change the return issues.

component/bt: Fixed the include service bug.

component/bt: Modify gattc_multi_connect demo , add scan log

component/bt: Fixed the BTA_GATTC_GetIncludeService start handle & end handle error bug.

component/bt: Fix the invalid handle of the get all char issues.

component/bt: Fix the bug with get_db_size_with_type of the start handle & end_handle not correted issue.

component/bt: Fixed the get secondly service num not correct issue.

component/bt: Fixed the last service handle not correted issue.
This commit is contained in:
Yulong 2017-08-24 02:24:04 -04:00
parent b6d82eeceb
commit 1759a47060
20 changed files with 3609 additions and 2813 deletions

View file

@ -24,7 +24,7 @@
esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (callback == NULL) {
return ESP_FAIL;
}
@ -39,7 +39,7 @@ esp_err_t esp_ble_gattc_app_register(uint16_t app_id)
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (app_id > ESP_APP_ID_MAX) {
return ESP_ERR_INVALID_ARG;
}
@ -57,8 +57,8 @@ esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if)
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_APP_UNREGISTER;
@ -73,7 +73,7 @@ esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, b
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_OPEN;
@ -90,7 +90,7 @@ esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id)
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_CLOSE;
@ -120,7 +120,7 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_SEARCH_SERVICE;
@ -136,155 +136,264 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_get_characteristic(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *start_char_id)
esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *svc_uuid,
esp_gattc_service_elem_t *result, uint16_t *count, uint16_t offset)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
if (start_char_id) {
arg.get_next_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.get_next_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.get_next_char.char_id, start_char_id, sizeof(esp_gatt_id_t));
msg.act = BTC_GATTC_ACT_GET_NEXT_CHAR;
} else {
arg.get_first_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.get_first_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
msg.act = BTC_GATTC_ACT_GET_FIRST_CHAR;
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_service(conn_hdl, svc_uuid, result, count, offset);
}
esp_err_t esp_ble_gattc_get_descriptor(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *start_descr_id)
esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_gattc_char_elem_t *result,
uint16_t *count, uint16_t offset)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
if (start_descr_id) {
arg.get_next_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.get_next_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.get_next_descr.char_id, char_id, sizeof(esp_gatt_id_t));
memcpy(&arg.get_next_descr.descr_id, start_descr_id, sizeof(esp_gatt_id_t));
msg.act = BTC_GATTC_ACT_GET_NEXT_DESCR;
} else {
arg.get_first_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.get_first_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.get_first_descr.char_id, char_id, sizeof(esp_gatt_id_t));
msg.act = BTC_GATTC_ACT_GET_FIRST_DESCR;
if ((start_handle == 0) && (end_handle == 0)) {
return ESP_GATT_INVALID_HANDLE;
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_get_included_service(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_srvc_id_t *start_incl_srvc_id)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
if (start_incl_srvc_id) {
arg.get_next_incl_srvc.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.get_next_incl_srvc.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.get_next_incl_srvc.start_service_id, start_incl_srvc_id, sizeof(esp_gatt_srvc_id_t));
msg.act = BTC_GATTC_ACT_GET_NEXT_INCL_SERVICE;
} else {
arg.get_first_incl_srvc.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.get_first_incl_srvc.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
msg.act = BTC_GATTC_ACT_GET_FIRST_INCL_SERVICE;
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_all_char(conn_hdl, start_handle, end_handle, result, count, offset);
}
esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t char_handle,
esp_gattc_descr_elem_t *result,
uint16_t *count, uint16_t offset)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (char_handle == 0) {
return ESP_GATT_INVALID_HANDLE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_all_descr(conn_hdl, char_handle, result, count, offset);
}
esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_gattc_char_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) {
return ESP_GATT_INVALID_HANDLE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if,conn_id);
return btc_ble_gattc_get_char_by_uuid(conn_hdl, start_handle, end_handle, char_uuid, result, count);
}
esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_descr_by_uuid(conn_hdl, start_handle, end_handle, char_uuid, descr_uuid, result, count);
}
esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t char_handle,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (char_handle == 0) {
return ESP_GATT_INVALID_HANDLE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_descr_by_char_handle(conn_hdl, char_handle, descr_uuid, result, count);
}
esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t *incl_uuid,
esp_gattc_incl_svc_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) {
return ESP_GATT_INVALID_HANDLE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_include_service(conn_hdl, start_handle, end_handle, incl_uuid, result, count);
}
esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_db_attr_type_t type,
uint16_t start_handle,
uint16_t end_handle,
uint16_t char_handle,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((start_handle == 0 && end_handle == 0) && (type != ESP_GATT_DB_DESCRIPTOR)) {
return ESP_GATT_INVALID_HANDLE;
}
if (count == NULL) {
return ESP_GATT_INVALID_PDU;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_attr_count(conn_hdl, type, start_handle, end_handle, char_handle, count);
}
esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
esp_gattc_db_elem_t *db, uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) {
return ESP_GATT_INVALID_HANDLE;
}
if (db == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_db(conn_hdl, start_handle, end_handle, db, count);
}
esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_auth_req_t auth_req)
uint16_t conn_id, uint16_t handle,
esp_gatt_auth_req_t auth_req)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_CHAR;
arg.read_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.read_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.read_char.char_id, char_id, sizeof(esp_gatt_id_t));
arg.read_char.handle = handle;
arg.read_char.auth_req = auth_req;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *descr_id,
esp_gatt_auth_req_t auth_req)
esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
uint16_t conn_id, esp_gattc_multi_t *read_multi,
esp_gatt_auth_req_t auth_req)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_MULTIPLE_CHAR;
arg.read_multiple.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
if (read_multi->num_attr > 0) {
memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t)*read_multi->num_attr);
} else {
LOG_ERROR("%s(), the num_attr should not be 0.", __func__);
return ESP_FAIL;
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
uint16_t conn_id, uint16_t handle,
esp_gatt_auth_req_t auth_req)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_CHAR_DESCR;
arg.read_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.read_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.read_descr.char_id, char_id, sizeof(esp_gatt_id_t));
memcpy(&arg.read_descr.descr_id, descr_id, sizeof(esp_gatt_id_t));
arg.read_descr.handle = handle;
arg.read_descr.auth_req = auth_req;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
uint16_t value_len,
uint8_t *value,
esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req)
esp_err_t esp_ble_gattc_write_char(esp_gatt_if_t gattc_if,
uint16_t conn_id, uint16_t handle,
uint16_t value_len,
uint8_t *value,
esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_WRITE_CHAR;
arg.write_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.write_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.write_char.char_id, char_id, sizeof(esp_gatt_id_t));
arg.write_char.handle = handle;
arg.write_char.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len;
arg.write_char.value = value;
arg.write_char.write_type = write_type;
@ -294,14 +403,11 @@ esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
}
esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *descr_id,
uint16_t value_len,
uint8_t *value,
esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req)
uint16_t conn_id, uint16_t handle,
uint16_t value_len,
uint8_t *value,
esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
@ -312,9 +418,7 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
arg.write_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.write_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.write_descr.char_id, char_id, sizeof(esp_gatt_id_t));
memcpy(&arg.write_descr.descr_id, descr_id, sizeof(esp_gatt_id_t));
arg.write_descr.handle = handle;
arg.write_descr.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len;
arg.write_descr.value = value;
arg.write_descr.write_type = write_type;
@ -324,9 +428,7 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
}
esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
uint16_t conn_id, uint16_t handle,
uint16_t offset,
uint16_t value_len,
uint8_t *value,
@ -341,8 +443,7 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_PREPARE_WRITE;
arg.prep_write.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.prep_write.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.prep_write.char_id, char_id, sizeof(esp_gatt_id_t));
arg.prep_write.handle = handle;
arg.prep_write.offset = offset;
arg.prep_write.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; // length check ?
arg.prep_write.value = value;
@ -352,10 +453,7 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
}
esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *descr_id,
uint16_t conn_id, uint16_t handle,
uint16_t offset,
uint16_t value_len,
uint8_t *value,
@ -370,9 +468,7 @@ esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR;
arg.prep_write_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
memcpy(&arg.prep_write_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.prep_write_descr.char_id, char_id, sizeof(esp_gatt_id_t));
memcpy(&arg.prep_write_descr.descr_id, descr_id, sizeof(esp_gatt_id_t));
arg.prep_write_descr.handle = handle;
arg.prep_write_descr.offset = offset;
arg.prep_write_descr.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; // length check ?
arg.prep_write_descr.value = value;
@ -387,7 +483,7 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id,
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_EXECUTE_WRITE;
@ -398,44 +494,37 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id,
}
esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
esp_bd_addr_t server_bda,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id)
esp_bd_addr_t server_bda, uint16_t handle)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_REG_FOR_NOTIFY;
arg.reg_for_notify.gattc_if = gattc_if;
memcpy(arg.reg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t));
memcpy(&arg.reg_for_notify.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.reg_for_notify.char_id, char_id, sizeof(esp_gatt_id_t));
arg.reg_for_notify.handle = handle;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
esp_bd_addr_t server_bda,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id)
esp_bd_addr_t server_bda, uint16_t handle)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_UNREG_FOR_NOTIFY;
arg.unreg_for_notify.gattc_if = gattc_if;
arg.unreg_for_notify.handle = handle;
memcpy(arg.unreg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t));
memcpy(&arg.unreg_for_notify.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&arg.unreg_for_notify.char_id, char_id, sizeof(esp_gatt_id_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View file

@ -27,6 +27,7 @@ extern "C" {
#define ESP_GATT_ILLEGAL_HANDLE 0
/// GATT attribute max handle
#define ESP_GATT_ATTR_HANDLE_MAX 100
#define ESP_GATT_MAX_READ_MULTI_HANDLES 10 /* Max attributes to read in one request */
/**@{
@ -294,12 +295,12 @@ typedef uint8_t esp_gatt_char_prop_t;
*/
typedef struct
{
uint16_t uuid_length; /*!< UUID length */
uint8_t *uuid_p; /*!< UUID value */
uint16_t perm; /*!< Attribute permission */
uint16_t max_length; /*!< Maximum length of the element*/
uint16_t length; /*!< Current length of the element*/
uint8_t *value; /*!< Element value array*/
uint16_t uuid_length; /*!< UUID length */
uint8_t *uuid_p; /*!< UUID value */
uint16_t perm; /*!< Attribute permission */
uint16_t max_length; /*!< Maximum length of the element*/
uint16_t length; /*!< Current length of the element*/
uint8_t *value; /*!< Element value array*/
} esp_attr_desc_t;
@ -313,8 +314,8 @@ typedef struct
/**
* @brief if auto_rsp set to ESP_GATT_RSP_BY_APP, means the response of Write/Read operation will by replied by application.
if auto_rsp set to ESP_GATT_AUTO_RSP, means the response of Write/Read operation will be replied by GATT stack automatically.
*/
uint8_t auto_rsp;
*/
uint8_t auto_rsp;
} esp_attr_control_t;
@ -323,8 +324,8 @@ typedef struct
*/
typedef struct
{
esp_attr_control_t attr_control; /*!< The attribute control type*/
esp_attr_desc_t att_desc; /*!< The attribute type*/
esp_attr_control_t attr_control; /*!< The attribute control type */
esp_attr_desc_t att_desc; /*!< The attribute type */
} esp_gatts_attr_db_t;
@ -333,9 +334,9 @@ typedef struct
*/
typedef struct
{
uint16_t attr_max_len; /*!< attribute max value length */
uint16_t attr_len; /*!< attribute current value length */
uint8_t *attr_value; /*!< the pointer to attribute value */
uint16_t attr_max_len; /*!< attribute max value length */
uint16_t attr_len; /*!< attribute current value length */
uint8_t *attr_value; /*!< the pointer to attribute value */
} esp_attr_value_t;
@ -344,22 +345,19 @@ typedef struct
*/
typedef struct
{
uint16_t start_hdl; /*!< Gatt start handle value of included service */
uint16_t end_hdl; /*!< Gatt end handle value of included service */
uint16_t uuid; /*!< Gatt attribute value UUID of included service */
} esp_gatts_incl_svc_desc_t; /*!< Gatt include service entry element */
uint16_t start_hdl; /*!< Gatt start handle value of included service */
uint16_t end_hdl; /*!< Gatt end handle value of included service */
uint16_t uuid; /*!< Gatt attribute value UUID of included service */
} esp_gatts_incl_svc_desc_t; /*!< Gatt include service entry element */
/**
* @brief Gatt include 128 bit service entry element
*/
typedef struct
{
uint16_t start_hdl; /*!< Gatt start handle value of included 128 bit service */
uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */
} esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */
uint16_t start_hdl; /*!< Gatt start handle value of included 128 bit service */
uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */
} esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */
/// Gatt attribute value
typedef struct {
@ -388,6 +386,75 @@ typedef enum {
typedef uint8_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */
/**
* @brief the type of attribute element
*/
typedef enum {
ESP_GATT_DB_PRIMARY_SERVICE, /*!< Gattc primary service attribute type in the cache */
ESP_GATT_DB_SECONDARY_SERVICE, /*!< Gattc secondary service attribute type in the cache */
ESP_GATT_DB_CHARACTERISTIC, /*!< Gattc characteristic attribute type in the cache */
ESP_GATT_DB_DESCRIPTOR, /*!< Gattc characteristic descriptor attribute type in the cache */
ESP_GATT_DB_INCLUDED_SERVICE, /*!< Gattc include service attribute type in the cache */
ESP_GATT_DB_ALL, /*!< Gattc all the attribute (primary service & secondary service & include service & char & descriptor) type in the cache */
} esp_gatt_db_attr_type_t; /*!< Gattc attribute type element */
/**
* @brief read multiple attribute
*/
typedef struct {
uint8_t num_attr; /*!< The number of the attribute */
uint16_t handles[ESP_GATT_MAX_READ_MULTI_HANDLES]; /*!< The handles list */
} esp_gattc_multi_t; /*!< The gattc multiple read element */
/**
* @brief data base attribute element
*/
typedef struct {
esp_gatt_db_attr_type_t type; /*!< The attribute type */
uint16_t attribute_handle; /*!< The attribute handle, it's valid for all of the type */
uint16_t start_handle; /*!< The service start handle, it's valid only when the type = ESP_GATT_DB_PRIMARY_SERVICE or ESP_GATT_DB_SECONDARY_SERVICE */
uint16_t end_handle; /*!< The service end handle, it's valid only when the type = ESP_GATT_DB_PRIMARY_SERVICE or ESP_GATT_DB_SECONDARY_SERVICE */
esp_gatt_char_prop_t properties; /*!< The characteristic properties, it's valid only when the type = ESP_GATT_DB_CHARACTERISTIC */
esp_bt_uuid_t uuid; /*!< The attribute uuid, it's valid for all of the type */
} esp_gattc_db_elem_t; /*!< The gattc service data base element in the cache */
/**
* @brief service element
*/
typedef struct {
bool is_primary; /*!< The service flag, ture if the service is primary service, else is secondly service */
uint16_t start_handle; /*!< The start handle of the service */
uint16_t end_handle; /*!< The end handle of the service */
esp_bt_uuid_t uuid; /*!< The uuid of the service */
} esp_gattc_service_elem_t; /*!< The gattc service element */
/**
* @brief characteristic element
*/
typedef struct {
uint16_t char_handle; /*!< The characteristic handle */
esp_gatt_char_prop_t properties; /*!< The characteristic properties */
esp_bt_uuid_t uuid; /*!< The characteristic uuid */
} esp_gattc_char_elem_t; /*!< The gattc characteristic element */
/**
* @brief descriptor element
*/
typedef struct {
uint16_t handle; /*!< The characteristic descriptor handle */
esp_bt_uuid_t uuid; /*!< The characteristic descriptor uuid */
} esp_gattc_descr_elem_t; /*!< The gattc descriptor type element */
/**
* @brief include service element
*/
typedef struct {
uint16_t handle; /*!< The include service current attribute handle */
uint16_t incl_srvc_s_handle; /*!< The start hanlde of the service which has been included */
esp_bt_uuid_t uuid; /*!< The include service uuid */
} esp_gattc_incl_svc_elem_t; /*!< The gattc inclue service element */
#ifdef __cplusplus
}
#endif

View file

@ -59,9 +59,6 @@ typedef enum {
ESP_GATTC_SCAN_FLT_PARAM_EVT = 32, /*!< When Scan filter parameters are set, the event comes */
ESP_GATTC_SCAN_FLT_STATUS_EVT = 33, /*!< When Scan filter status is reported, the event comes */
ESP_GATTC_ADV_VSC_EVT = 34, /*!< When advertising vendor spec content event is reported, the event comes */
ESP_GATTC_GET_CHAR_EVT = 35, /*!< When characteristic is got from GATT server, the event comes */
ESP_GATTC_GET_DESCR_EVT = 36, /*!< When characteristic descriptor is got from GATT server, the event comes */
ESP_GATTC_GET_INCL_SRVC_EVT = 37, /*!< When included service is got from GATT server, the event comes */
ESP_GATTC_REG_FOR_NOTIFY_EVT = 38, /*!< When register for notification of a service completes, the event comes */
ESP_GATTC_UNREG_FOR_NOTIFY_EVT = 39, /*!< When unregister for notification of a service completes, the event comes */
ESP_GATTC_CONNECT_EVT = 40, /*!< When the ble physical connection is set up, the event comes */
@ -74,57 +71,59 @@ typedef enum {
*/
typedef union {
/**
* @brief ESP_GATTC_REG_EVT
*/
struct gattc_reg_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t app_id; /*!< Application id which input in register API */
} reg; /*!< Gatt client callback param of ESP_GATTC_REG_EVT */
* @brief ESP_GATTC_REG_EVT
*/
struct gattc_reg_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t app_id; /*!< Application id which input in register API */
} reg; /*!< Gatt client callback param of ESP_GATTC_REG_EVT */
/**
* @brief ESP_GATTC_OPEN_EVT
*/
struct gattc_open_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
uint16_t mtu; /*!< MTU size */
} open; /*!< Gatt client callback param of ESP_GATTC_OPEN_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
uint16_t mtu; /*!< MTU size */
} open; /*!< Gatt client callback param of ESP_GATTC_OPEN_EVT */
/**
* @brief ESP_GATTC_CLOSE_EVT
*/
struct gattc_close_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
esp_gatt_conn_reason_t reason; /*!< The reason of gatt connection close */
} close; /*!< Gatt client callback param of ESP_GATTC_CLOSE_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
esp_gatt_conn_reason_t reason; /*!< The reason of gatt connection close */
} close; /*!< Gatt client callback param of ESP_GATTC_CLOSE_EVT */
/**
* @brief ESP_GATTC_CFG_MTU_EVT
*/
struct gattc_cfg_mtu_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
uint16_t mtu; /*!< MTU size */
} cfg_mtu; /*!< Gatt client callback param of ESP_GATTC_CFG_MTU_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
uint16_t mtu; /*!< MTU size */
} cfg_mtu; /*!< Gatt client callback param of ESP_GATTC_CFG_MTU_EVT */
/**
* @brief ESP_GATTC_SEARCH_CMPL_EVT
*/
struct gattc_search_cmpl_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
} search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
} search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */
/**
* @brief ESP_GATTC_SEARCH_RES_EVT
*/
struct gattc_search_res_evt_param {
uint16_t conn_id; /*!< Connection id */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
} search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */
uint16_t conn_id; /*!< Connection id */
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 */
} search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */
/**
* @brief ESP_GATTC_READ_CHAR_EVT, ESP_GATTC_READ_DESCR_EVT
@ -133,17 +132,8 @@ typedef union {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
uint16_t handle; /*!< Characteristic handle */
uint8_t *value; /*!< Characteristic value */
uint16_t value_type; /*!< Characteristic value type, there is two value for this type:
ESP_GATTC_READ_VALUE_TYPE_VALUE(0x0000) and
ESP_GATTC_READ_VALUE_TYPE_AGG_FORMAT(0x2905).
If the value is ESP_GATTC_READ_VALUE_TYPE_VALUE means it is a generally
value type, and if is the type of ESP_GATTC_READ_VALUE_TYPE_AGG_FORMAT,
the unit of the value will indicate in the Characteristic
aggregate format descriptor */
uint16_t value_len; /*!< Characteristic value length */
} read; /*!< Gatt client callback param of ESP_GATTC_READ_CHAR_EVT */
@ -151,99 +141,60 @@ typedef union {
* @brief ESP_GATTC_WRITE_CHAR_EVT, ESP_GATTC_PREP_WRITE_EVT, ESP_GATTC_WRITE_DESCR_EVT
*/
struct gattc_write_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
} write; /*!< Gatt client callback param of ESP_GATTC_WRITE_DESCR_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
uint16_t handle; /*!< The Characteristic or descriptor handle */
} write; /*!< Gatt client callback param of ESP_GATTC_WRITE_DESCR_EVT */
/**
* @brief ESP_GATTC_EXEC_EVT
*/
struct gattc_exec_cmpl_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
} exec_cmpl; /*!< Gatt client callback param of ESP_GATTC_EXEC_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
} exec_cmpl; /*!< Gatt client callback param of ESP_GATTC_EXEC_EVT */
/**
* @brief ESP_GATTC_NOTIFY_EVT
*/
struct gattc_notify_evt_param {
uint16_t conn_id; /*!< Connection id */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
uint16_t value_len; /*!< Notify attribute value */
uint8_t *value; /*!< Notify attribute value */
bool is_notify; /*!< True means notify, false means indicate */
} notify; /*!< Gatt client callback param of ESP_GATTC_NOTIFY_EVT */
uint16_t conn_id; /*!< Connection id */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
uint16_t handle; /*!< The Characteristic or descriptor handle */
uint16_t value_len; /*!< Notify attribute value */
uint8_t *value; /*!< Notify attribute value */
bool is_notify; /*!< True means notify, false means indicate */
} notify; /*!< Gatt client callback param of ESP_GATTC_NOTIFY_EVT */
/**
* @brief ESP_GATTC_SRVC_CHG_EVT
*/
struct gattc_srvc_chg_evt_param {
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
} srvc_chg; /*!< Gatt client callback param of ESP_GATTC_SRVC_CHG_EVT */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
} srvc_chg; /*!< Gatt client callback param of ESP_GATTC_SRVC_CHG_EVT */
/**
* @brief ESP_GATTC_CONGEST_EVT
*/
struct gattc_congest_evt_param {
uint16_t conn_id; /*!< Connection id */
bool congested; /*!< Congested or not */
} congest; /*!< Gatt client callback param of ESP_GATTC_CONGEST_EVT */
/**
* @brief ESP_GATTC_GET_CHAR_EVT
*/
struct gattc_get_char_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
esp_gatt_char_prop_t char_prop; /*!< Characteristic property */
} get_char; /*!< Gatt client callback param of ESP_GATTC_GET_CHAR_EVT */
/**
* @brief ESP_GATTC_GET_DESCR_EVT
*/
struct gattc_get_descr_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
} get_descr; /*!< Gatt client callback param of ESP_GATTC_GET_DESCR_EVT */
/**
* @brief ESP_GATTC_GET_INCL_SRVC_EVT
*/
struct gattc_get_incl_srvc_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t conn_id; /*!< Connection id */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_srvc_id_t incl_srvc_id;/*!< Included service id, include service uuid and other information */
} get_incl_srvc; /*!< Gatt client callback param of ESP_GATTC_GET_INCL_SRVC_EVT */
uint16_t conn_id; /*!< Connection id */
bool congested; /*!< Congested or not */
} congest; /*!< Gatt client callback param of ESP_GATTC_CONGEST_EVT */
/**
* @brief ESP_GATTC_REG_FOR_NOTIFY_EVT
*/
struct gattc_reg_for_notify_evt_param {
esp_gatt_status_t status; /*!< Operation status */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
} reg_for_notify; /*!< Gatt client callback param of ESP_GATTC_REG_FOR_NOTIFY_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t handle; /*!< The characteristic or descriptor handle */
} reg_for_notify; /*!< Gatt client callback param of ESP_GATTC_REG_FOR_NOTIFY_EVT */
/**
/**
* @brief ESP_GATTC_UNREG_FOR_NOTIFY_EVT
*/
struct gattc_unreg_for_notify_evt_param {
esp_gatt_status_t status; /*!< Operation status */
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
} unreg_for_notify; /*!< Gatt client callback param of ESP_GATTC_UNREG_FOR_NOTIFY_EVT */
esp_gatt_status_t status; /*!< Operation status */
uint16_t handle; /*!< The characteristic or descriptor handle */
} unreg_for_notify; /*!< Gatt client callback param of ESP_GATTC_UNREG_FOR_NOTIFY_EVT */
/**
* @brief ESP_GATTC_CONNECT_EVT
@ -263,7 +214,7 @@ typedef union {
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
} disconnect; /*!< Gatt client callback param of ESP_GATTC_DISCONNECT_EVT */
} esp_ble_gattc_cb_param_t; /*!< GATT client callback parameter union type */
} esp_ble_gattc_cb_param_t; /*!< GATT client callback parameter union type */
/**
* @brief GATT Client callback function type
@ -383,76 +334,233 @@ esp_err_t esp_ble_gattc_send_mtu_req (esp_gatt_if_t gattc_if, uint16_t conn_id);
*/
esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *filter_uuid);
/**
* @brief This function is called to find the first characteristic of the
* service on the given server.
* @brief Find all the service with the given service uuid in the gattc cache, if the svc_uuid is NULL, find all the service.
* Note: It just get service from local cache, won't get from remote devices. If want to get it from remote device, need
* to used the esp_ble_gattc_search_service.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] srvc_id: service ID
* @param[in] start_char_id: the start characteristic ID
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_err_t esp_ble_gattc_get_characteristic(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *start_char_id);
/**
* @brief This function is called to find the descriptor of the
* service on the given server.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] srvc_id: the service ID of which the characteristic is belonged to.
* @param[in] char_id: Characteristic ID, if NULL find the first available
* characteristic.
* @param[in] start_descr_id: the start descriptor id
* @param[in] svc_uuid: the pointer to the service uuid.
* @param[out] result: The pointer to the service whith has been found in the gattc cache.
* @param[inout] count: input the number of service want to find,
* it will output the number of service has been found in the gattc cache with the given service uuid.
* @param[in] offset: Offset of the service position to get.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_err_t esp_ble_gattc_get_descriptor(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *start_descr_id);
esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *svc_uuid,
esp_gattc_service_elem_t *result, uint16_t *count, uint16_t offset);
/**
* @brief This function is called to find the first characteristic of the
* service on the given server.
* @brief Find all the characteristic with the given service in the gattc cache
* Note: It just get characteristic from local cache, won't get from remote devices.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] srvc_id: the service ID of which the characteristic is belonged to.
* @param[in] start_incl_srvc_id: the start include service id
* @param[in] start_handle: the attribute start handle.
* @param[in] end_handle: the attribute end handle
* @param[out] result: The pointer to the charateristic in the service.
* @param[inout] count: input the number of characteristic want to find,
* it will output the number of characteristic has been found in the gattc cache with the given service.
* @param[in] offset: Offset of the characteristic position to get.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_err_t esp_ble_gattc_get_included_service(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_srvc_id_t *start_incl_srvc_id);
esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_gattc_char_elem_t *result,
uint16_t *count, uint16_t offset);
/**
* @brief Find all the descriptor with the given characteristic in the gattc cache
* Note: It just get descriptor from local cache, won't get from remote devices.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] char_handle: the given characteristic handle
* @param[out] result: The pointer to the descriptor in the characteristic.
* @param[inout] count: input the number of descriptor want to find,
* it will output the number of descriptor has been found in the gattc cache with the given characteristic.
* @param[in] offset: Offset of the descriptor position to get.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t char_handle,
esp_gattc_descr_elem_t *result,
uint16_t *count, uint16_t offset);
/**
* @brief Find the characteristic with the given characteristic uuid in the gattc cache
* Note: It just get characteristic from local cache, won't get from remote devices.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] start_handle: the attribute start handle
* @param[in] end_handle: the attribute end handle
* @param[in] char_uuid: the characteristic uuid
* @param[out] result: The pointer to the characteristic in the service.
* @param[inout] count: input the number of characteristic want to find,
* it will output the number of characteristic has been found in the gattc cache with the given service.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_gattc_char_elem_t *result,
uint16_t *count);
/**
* @brief Find the descriptor with the given characteristic uuid in the gattc cache
* Note: It just get descriptor from local cache, won't get from remote devices.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] start_handle: the attribute start handle
* @param[in] end_handle: the attribute end handle
* @param[in] char_uuid: the characteristic uuid.
* @param[in] descr_uuid: the descriptor uuid.
* @param[out] result: The pointer to the descriptor in the given characteristic.
* @param[inout] count: input the number of descriptor want to find,
* it will output the number of descriptor has been found in the gattc cache with the given characteristic.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count);
/**
* @brief Find the descriptor with the given characteristic handle in the gattc cache
* Note: It just get descriptor from local cache, won't get from remote devices.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] char_handle: the characteristic handle.
* @param[in] descr_uuid: the descriptor uuid.
* @param[out] result: The pointer to the descriptor in the given characteristic.
* @param[inout] count: input the number of descriptor want to find,
* it will output the number of descriptor has been found in the gattc cache with the given characteristic.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t char_handle,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count);
/**
* @brief Find the include service with the given service handle in the gattc cache
* Note: It just get include service from local cache, won't get from remote devices.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] start_handle: the attribute start handle
* @param[in] end_handle: the attribute end handle
* @param[in] incl_uuid: the include service uuid
* @param[out] result: The pointer to the include service in the given service.
* @param[inout] count: input the number of include service want to find,
* it will output the number of include service has been found in the gattc cache with the given service.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t *incl_uuid,
esp_gattc_incl_svc_elem_t *result,
uint16_t *count);
/**
* @brief Find the attribute count with the given service or characteristic in the gattc cache
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] type: the attribute type.
* @param[in] start_handle: the attribute start handle, if the type is ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore
* @param[in] end_handle: the attribute end handle, if the type is ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore
* @param[in] char_handle: the characteristic handle, this parameter valid when the type is ESP_GATT_DB_DESCRIPTOR. If the type
* isn't ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore.
* @param[out] count: output the number of attribute has been found in the gattc cache with the given attribute type.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_db_attr_type_t type,
uint16_t start_handle,
uint16_t end_handle,
uint16_t char_handle,
uint16_t *count);
/**
* @brief This function is called to get the GATT database.
* Note: It just get attribute data base from local cache, won't get from remote devices.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] start_handle: the attribute start handle
* @param[in] end_handle: the attribute end handle
* @param[in] conn_id: connection ID which identify the server.
* @param[in] db: output parameter which will contain the GATT database copy.
* Caller is responsible for freeing it.
* @param[in] count: number of elements in database.
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
esp_gattc_db_elem_t *db, uint16_t *count);
/**
* @brief This function is called to read a service's characteristics of
* the given characteristic ID
* the given characteristic handle
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] srvc_id : service ID.
* @param[in] char_id : characteristic ID to read.
* @param[in] handle : characteritic handle to read.
* @param[in] auth_req : authenticate request type
*
* @return
@ -460,11 +568,28 @@ esp_err_t esp_ble_gattc_get_included_service(esp_gatt_if_t gattc_if,
* - other: failed
*
*/
esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_auth_req_t auth_req);
esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t handle,
esp_gatt_auth_req_t auth_req);
/**
* @brief This function is called to read multiple characteristic or
* characteristic descriptors.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] read_multi : pointer to the read multiple parameter.
* @param[in] auth_req : authenticate request type
*
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
uint16_t conn_id, esp_gattc_multi_t *read_multi,
esp_gatt_auth_req_t auth_req);
/**
@ -472,9 +597,7 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] srvc_id : service ID.
* @param[in] char_id : characteristic ID to read.
* @param[in] descr_id : characteristic descriptor ID to read.
* @param[in] handle : descriptor handle to read.
* @param[in] auth_req : authenticate request type
*
* @return
@ -483,11 +606,9 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
*
*/
esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *descr_id,
esp_gatt_auth_req_t auth_req);
uint16_t conn_id,
uint16_t handle,
esp_gatt_auth_req_t auth_req);
/**
@ -495,8 +616,7 @@ esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] srvc_id : service ID.
* @param[in] char_id : characteristic ID to write.
* @param[in] handle : characteristic handle to write.
* @param[in] value_len: length of the value to be written.
* @param[in] value : the value to be written.
* @param[in] write_type : the type of attribute write operation.
@ -509,11 +629,10 @@ esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
*/
esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
uint16_t handle,
uint16_t value_len,
uint8_t *value,
esp_gatt_write_type_t write_type,
esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req);
@ -522,9 +641,7 @@ esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID
* @param[in] srvc_id : service ID.
* @param[in] char_id : characteristic ID.
* @param[in] descr_id : characteristic descriptor ID to write.
* @param[in] handle : descriptor hadle to write.
* @param[in] value_len: length of the value to be written.
* @param[in] value : the value to be written.
* @param[in] write_type : the type of attribute write operation.
@ -537,9 +654,7 @@ esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
*/
esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *descr_id,
uint16_t handle,
uint16_t value_len,
uint8_t *value,
esp_gatt_write_type_t write_type,
@ -551,8 +666,7 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] srvc_id : service ID.
* @param[in] char_id : GATT characteristic ID of the service.
* @param[in] handle : charateristic handle to prepare write.
* @param[in] offset : offset of the write value.
* @param[in] value_len: length of the value to be written.
* @param[in] value : the value to be written.
@ -563,10 +677,9 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
* - other: failed
*
*/
esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
uint16_t handle,
uint16_t offset,
uint16_t value_len,
uint8_t *value,
@ -578,9 +691,7 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] srvc_id : service ID.
* @param[in] char_id : GATT characteristic ID of the service.
* @param[in] descr_id : characteristic descriptor ID to write.
* @param[in] handle : characteristic descriptor hanlde to prepare write.
* @param[in] offset : offset of the write value.
* @param[in] value_len: length of the value to be written.
* @param[in] value : the value to be written.
@ -593,9 +704,7 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
*/
esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
uint16_t conn_id,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id,
esp_gatt_id_t *descr_id,
uint16_t handle,
uint16_t offset,
uint16_t value_len,
uint8_t *value,
@ -622,8 +731,7 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] server_bda : target GATT server.
* @param[in] srvc_id : pointer to GATT service ID.
* @param[in] char_id : pointer to GATT characteristic ID.
* @param[in] handle : GATT characteristic handle.
*
* @return
* - ESP_OK: registration succeeds
@ -631,9 +739,8 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id,
*
*/
esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
esp_bd_addr_t server_bda,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id);
esp_bd_addr_t server_bda,
uint16_t handle);
/**
@ -641,8 +748,7 @@ esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] server_bda : target GATT server.
* @param[in] srvc_id : pointer to GATT service ID.
* @param[in] char_id : pointer to GATT characteristic ID.
* @param[in] handle : GATT characteristic handle.
*
* @return
* - ESP_OK: unregister succeeds
@ -650,9 +756,8 @@ esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
*
*/
esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
esp_bd_addr_t server_bda,
esp_gatt_srvc_id_t *srvc_id,
esp_gatt_id_t *char_id);
esp_bd_addr_t server_bda,
uint16_t handle);
/**

View file

@ -5608,7 +5608,7 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
break;
case BTA_GATTC_SEARCH_RES_EVT:
bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid.id);
bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
break;
case BTA_GATTC_SEARCH_CMPL_EVT:

View file

@ -102,6 +102,9 @@ static const char *bta_gattc_op_code_name[] = {
** Action Functions
*****************************************************************************/
void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status);
/*******************************************************************************
**
** Function bta_gattc_enable
@ -659,13 +662,18 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, NULL);
if (bta_gattc_cache_load(p_clcb)) {
p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
} else { /* cache is building */
p_clcb->state = BTA_GATTC_DISCOVER_ST;
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
/* cache load failure, start discovery */
bta_gattc_start_discover(p_clcb, NULL);
}
} else { /* cache is building */
p_clcb->state = BTA_GATTC_DISCOVER_ST;
}
else {
} else {
/* a pending service handle change indication */
if (p_clcb->p_srcb->srvc_hdl_chg) {
p_clcb->p_srcb->srvc_hdl_chg = FALSE;
@ -932,9 +940,8 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC)
p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC) {
/* no pending operation, start discovery right away */
{
p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
if (p_clcb->p_srcb != NULL) {
@ -988,7 +995,7 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
UNUSED(p_data);
APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d", p_clcb->bta_conn_id);
APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d, status = %d", p_clcb->bta_conn_id, p_clcb->status);
p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
p_clcb->disc_active = FALSE;
@ -996,30 +1003,30 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
if (p_clcb->status != GATT_SUCCESS) {
/* clean up cache */
if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
while (!fixed_queue_is_empty(p_clcb->p_srcb->cache_buffer)) {
osi_free(fixed_queue_try_dequeue(p_clcb->p_srcb->cache_buffer));
}
//fixed_queue_free(p_clcb->p_srcb->cache_buffer, NULL);
list_free(p_clcb->p_srcb->p_srvc_cache);
p_clcb->p_srcb->p_srvc_cache = NULL;
}
/* used to reset cache in application */
bta_gattc_co_cache_reset(p_clcb->p_srcb->server_bda);
bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
}
if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
/* release pending attribute list buffer */
APPL_TRACE_DEBUG("+++++++++++++++++++++++++++++++++++++++++++++++++++++++= %p", p_clcb->p_srcb->p_srvc_list);
osi_free(p_clcb->p_srcb->p_srvc_list);
p_clcb->p_srcb->p_srvc_list = NULL;
//osi_free_and_reset((void **)&p_clcb->p_srcb->p_srvc_list);
}
/* release pending attribute list buffer */
utl_freebuf((void **)&p_clcb->p_srcb->p_srvc_list);
if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
/* start discovery again */
p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
}
/* get any queued command to proceed */
else if (p_q_cmd != NULL) {
p_clcb->p_q_cmd = NULL;
/* execute pending operation of link block still present */
if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda,
BT_TRANSPORT_LE) != NULL) {
/* execute pending operation of link block still present */
if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
}
/* if the command executed requeued the cmd, we don't
@ -1027,8 +1034,11 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
* referenced by p_clcb->p_q_cmd
*/
if (p_q_cmd != p_clcb->p_q_cmd) {
utl_freebuf((void **)&p_q_cmd);
APPL_TRACE_DEBUG("====================================================================");
osi_free(p_q_cmd);
p_q_cmd = NULL;
}
//osi_free_and_reset((void **)&p_q_cmd);
}
}
/*******************************************************************************
@ -1042,24 +1052,15 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
*******************************************************************************/
void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
UINT16 handle = 0;
if (!bta_gattc_enqueue(p_clcb, p_data))
return;
tGATT_READ_PARAM read_param;
tBTA_GATT_STATUS status;
memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
read_param.by_handle.handle = p_data->api_read.handle;
read_param.by_handle.auth_req = p_data->api_read.auth_req;
memset (&read_param, 0 , sizeof(tGATT_READ_PARAM));
if (bta_gattc_enqueue(p_clcb, p_data)) {
if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_data->api_read.srvc_id,
&p_data->api_read.char_id,
p_data->api_read.p_descr_type)) == 0) {
status = BTA_GATT_ERROR;
} else {
read_param.by_handle.handle = handle;
read_param.by_handle.auth_req = p_data->api_read.auth_req;
status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
}
tBTA_GATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
/* read fail */
if (status != BTA_GATT_OK) {
@ -1070,7 +1071,6 @@ void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
}
}
}
/*******************************************************************************
**
@ -1082,41 +1082,17 @@ void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
*********************************************************************************/
void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
UINT16 i, handle;
tBTA_GATT_STATUS status = BTA_GATT_OK;
tGATT_READ_PARAM read_param;
tBTA_GATTC_ATTR_ID *p_id;
if (bta_gattc_enqueue(p_clcb, p_data)) {
memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
p_id = p_data->api_read_multi.p_id_list;
for (i = 0; i < p_data->api_read_multi.num_attr && p_id; i ++, p_id ++) {
handle = 0;
if (p_id->id_type == BTA_GATT_TYPE_CHAR) {
handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_id->id_value.char_id.srvc_id,
&p_id->id_value.char_id.char_id,
NULL);
} else if (p_id->id_type == BTA_GATT_TYPE_CHAR_DESCR) {
handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_id->id_value.char_descr_id.char_id.srvc_id,
&p_id->id_value.char_descr_id.char_id.char_id,
&p_id->id_value.char_descr_id.descr_id);
} else {
APPL_TRACE_ERROR("invalud ID type: %d", p_id->id_type);
}
if (handle == 0) {
status = BTA_GATT_ERROR;
break;
}
}
if (status == BTA_GATT_OK) {
read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
sizeof(UINT16) * p_data->api_read_multi.num_attr);
status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
}
@ -1143,38 +1119,32 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
*******************************************************************************/
void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
UINT16 handle = 0;
tGATT_VALUE attr = {0};
if (!bta_gattc_enqueue(p_clcb, p_data))
return;
tBTA_GATT_STATUS status = BTA_GATT_OK;
tGATT_VALUE attr;
if (bta_gattc_enqueue(p_clcb, p_data)) {
if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_data->api_write.srvc_id,
&p_data->api_write.char_id,
p_data->api_write.p_descr_type)) == 0) {
status = BTA_GATT_ERROR;
} else {
attr.handle = handle;
attr.offset = p_data->api_write.offset;
attr.len = p_data->api_write.len;
attr.auth_req = p_data->api_write.auth_req;
attr.conn_id = p_clcb->bta_conn_id;
attr.handle = p_data->api_write.handle;
attr.offset = p_data->api_write.offset;
attr.len = p_data->api_write.len;
attr.auth_req = p_data->api_write.auth_req;
if (p_data->api_write.p_value) {
memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
}
if (p_data->api_write.p_value) {
memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
}
status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
/* write fail */
if (status != BTA_GATT_OK) {
/* Dequeue the data, if it was enqueued */
if (p_clcb->p_q_cmd == p_data) {
p_clcb->p_q_cmd = NULL;
}
/* write fail */
if (status != BTA_GATT_OK) {
/* Dequeue the data, if it was enqueued */
if (p_clcb->p_q_cmd == p_data) {
p_clcb->p_q_cmd = NULL;
}
bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
}
bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
}
}
/*******************************************************************************
@ -1213,23 +1183,16 @@ void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
*******************************************************************************/
void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
UINT16 handle;
UINT16 handle = p_data->api_confirm.handle;
if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_data->api_confirm.srvc_id,
&p_data->api_confirm.char_id,
NULL)) == 0) {
APPL_TRACE_ERROR("Can not map service/char ID into valid handle");
} else {
if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
!= GATT_SUCCESS) {
if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
!= GATT_SUCCESS) {
APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
} else {
/* if over BR_EDR, inform PM for mode change */
if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
}
} else {
/* if over BR_EDR, inform PM for mode change */
if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
}
}
}
@ -1246,42 +1209,28 @@ void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
{
UINT8 event;
tBTA_GATTC cb_data;
tBTA_GATT_READ_VAL read_value;
tBTA_GATT_UNFMT read_value;
memset(&cb_data, 0, sizeof(tBTA_GATTC));
memset(&read_value, 0, sizeof(tBTA_GATT_READ_VAL));
memset(&read_value, 0, sizeof(tBTA_GATT_UNFMT));
cb_data.read.status = p_data->status;
if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) {
if (bta_gattc_handle2id(p_clcb->p_srcb,
p_data->p_cmpl->att_value.handle,
&cb_data.read.srvc_id,
&cb_data.read.char_id,
&cb_data.read.descr_type) == FALSE) {
cb_data.read.status = BTA_GATT_INTERNAL_ERROR;
APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x",
p_data->p_cmpl->att_value.handle);
} else {
cb_data.read.status = bta_gattc_pack_read_cb_data(p_clcb->p_srcb,
&cb_data.read.descr_type.uuid,
&p_data->p_cmpl->att_value,
&read_value);
cb_data.read.p_value = &read_value;
}
cb_data.read.handle = p_data->p_cmpl->att_value.handle;
read_value.len = p_data->p_cmpl->att_value.len;
read_value.p_value = p_data->p_cmpl->att_value.value;
cb_data.read.p_value = &read_value;
} else {
cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id;
cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id;
if (p_clcb->p_q_cmd->api_read.p_descr_type)
memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type,
sizeof(tBTA_GATT_ID));
cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle;
}
event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ?
BTA_GATTC_READ_CHAR_EVT : BTA_GATTC_READ_DESCR_EVT;
event = p_clcb->p_q_cmd->api_read.cmpl_evt;
cb_data.read.conn_id = p_clcb->bta_conn_id;
utl_freebuf((void **)&p_clcb->p_q_cmd);
osi_free(p_clcb->p_q_cmd);
p_clcb->p_q_cmd = NULL;
//osi_free_and_reset((void **)&p_clcb->p_q_cmd);
/* read complete, callback */
( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
@ -1303,39 +1252,18 @@ void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
memset(&cb_data, 0, sizeof(tBTA_GATTC));
cb_data.write.status = p_data->status;
if (p_data->p_cmpl != NULL) {
bta_gattc_handle2id(p_clcb->p_srcb, p_data->p_cmpl->att_value.handle,
&cb_data.write.srvc_id, &cb_data.write.char_id,
&cb_data.write.descr_type);
} else {
memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id,
sizeof(tBTA_GATT_SRVC_ID));
memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id,
sizeof(tBTA_GATT_ID));
if (p_clcb->p_q_cmd->api_write.p_descr_type)
memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type,
sizeof(tBTA_GATT_ID));
}
cb_data.write.handle = p_data->p_cmpl->att_value.handle;
if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE)
p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) {
{
event = BTA_GATTC_PREP_WRITE_EVT;
}
else if (p_clcb->p_q_cmd->api_write.p_descr_type == NULL)
{
event = BTA_GATTC_WRITE_CHAR_EVT;
}
else {
event = BTA_GATTC_WRITE_DESCR_EVT;
}
utl_freebuf((void **)&p_clcb->p_q_cmd);
} else {
event = p_clcb->p_q_cmd->api_write.cmpl_evt;
}
osi_free(p_clcb->p_q_cmd);
p_clcb->p_q_cmd = NULL;
//osi_free_and_reset((void **)&p_clcb->p_q_cmd);
cb_data.write.conn_id = p_clcb->bta_conn_id;
/* write complete, callback */
( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
@ -1353,9 +1281,9 @@ void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
{
tBTA_GATTC cb_data;
utl_freebuf((void **)&p_clcb->p_q_cmd);
osi_free(p_clcb->p_q_cmd);
p_clcb->p_q_cmd = NULL;
//osi_free_and_reset((void **)&p_clcb->p_q_cmd);
p_clcb->status = BTA_GATT_OK;
/* execute complete, callback */
@ -1378,8 +1306,9 @@ void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
{
tBTA_GATTC cb_data;
utl_freebuf((void **)&p_clcb->p_q_cmd);
osi_free(p_clcb->p_q_cmd);
p_clcb->p_q_cmd = NULL;
//osi_free_and_reset((void **)&p_clcb->p_q_cmd);
if (p_data->p_cmpl && p_data->status == BTA_GATT_OK) {
@ -1521,128 +1450,7 @@ void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
bta_gattc_enqueue(p_clcb, p_data);
}
/*******************************************************************************
**
** Function bta_gattc_cache_open
**
** Description open a NV cache for loading
**
** Returns void
**
*******************************************************************************/
void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
UNUSED(p_data);
bta_gattc_set_discover_st(p_clcb->p_srcb);
APPL_TRACE_DEBUG("bta_gattc_cache_open conn_id=%d", p_clcb->bta_conn_id);
bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT,
p_clcb->bta_conn_id, FALSE);
}
/*******************************************************************************
**
** Function bta_gattc_start_load
**
** Description start cache loading by sending callout open cache
**
** Returns None.
**
*******************************************************************************/
void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
APPL_TRACE_DEBUG("bta_gattc_ci_open conn_id=%d server state=%d" ,
p_clcb->bta_conn_id, p_clcb->p_srcb->state);
if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD) {
if (p_data->ci_open.status == BTA_GATT_OK) {
p_clcb->p_srcb->attr_index = 0;
bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
BTA_GATTC_CI_CACHE_LOAD_EVT,
p_clcb->p_srcb->attr_index,
p_clcb->bta_conn_id);
} else {
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
/* cache open failure, start discovery */
bta_gattc_start_discover(p_clcb, NULL);
}
}
if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE) {
if (p_data->ci_open.status == BTA_GATT_OK) {
if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) {
p_data->ci_open.status = BTA_GATT_ERROR;
}
}
if (p_data->ci_open.status != BTA_GATT_OK) {
p_clcb->p_srcb->attr_index = 0;
bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id);
bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
}
}
}
/*******************************************************************************
**
** Function bta_gattc_ci_load
**
** Description cache loading received.
**
** Returns None.
**
*******************************************************************************/
void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
APPL_TRACE_DEBUG("bta_gattc_ci_load conn_id=%d load status=%d",
p_clcb->bta_conn_id, p_data->ci_load.status);
if (p_data->ci_load.status == BTA_GATT_OK ||
p_data->ci_load.status == BTA_GATT_MORE) {
if (p_data->ci_load.num_attr != 0)
bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr,
p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
if (p_data->ci_load.status == BTA_GATT_OK) {
p_clcb->p_srcb->attr_index = 0;
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
} else { /* load more */
p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr;
bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
BTA_GATTC_CI_CACHE_LOAD_EVT,
p_clcb->p_srcb->attr_index,
p_clcb->bta_conn_id);
}
} else {
bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
p_clcb->p_srcb->attr_index = 0;
/* cache load failure, start discovery */
bta_gattc_start_discover(p_clcb, NULL);
}
}
/*******************************************************************************
**
** Function bta_gattc_ci_save
**
** Description cache loading received.
**
** Returns None.
**
*******************************************************************************/
void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
UNUSED(p_data);
APPL_TRACE_DEBUG("bta_gattc_ci_save conn_id=%d " ,
p_clcb->bta_conn_id );
if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) {
p_clcb->p_srcb->attr_index = 0;
bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
}
}
/*******************************************************************************
**
** Function bta_gattc_fail
@ -1731,9 +1539,9 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
}
if ((transport == BT_TRANSPORT_LE) && (connected == TRUE) && (p_conn != NULL) \
&& (p_conn->service_change_ccc_written == FALSE) && (p_conn->ccc_timer_used == FALSE)){
&& (p_conn->service_change_ccc_written == FALSE) && (p_conn->ccc_timer_used == FALSE)) {
result = bta_gattc_register_service_change_notify(conn_id, bda, &start_ccc_timer);
if (start_ccc_timer == TRUE){
if (start_ccc_timer == TRUE) {
TIMER_LIST_ENT *ccc_timer = &(p_conn->service_change_ccc_timer);
/* start a 1000ms timer to wait for service discovery finished */
bta_gattc_start_service_change_ccc_timer(conn_id, bda, 1000, 0, result, ccc_timer);
@ -1804,6 +1612,8 @@ static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
if ((p_buf = (tBTA_GATTC_DATA *) osi_calloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
p_buf->enc_cmpl.client_if = gattc_if;
@ -1847,15 +1657,12 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
}
/* in all other cases, mark it and delete the cache */
if (p_srvc_cb->p_srvc_cache != NULL) {
while (!fixed_queue_is_empty(p_clcb->p_srcb->cache_buffer)) {
osi_free(fixed_queue_try_dequeue(p_clcb->p_srcb->cache_buffer));
}
//fixed_queue_free(p_clcb->p_srcb->cache_buffer, NULL);
list_free(p_srvc_cb->p_srvc_cache);
p_srvc_cb->p_srvc_cache = NULL;
}
}
/* used to reset cache in application */
bta_gattc_co_cache_reset(p_msg->api_conn.remote_bda);
bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
}
/*******************************************************************************
@ -1872,7 +1679,7 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
tBTA_GATTC_SERV *p_srcb,
tBTA_GATTC_CLCB *p_clcb,
tBTA_GATTC_NOTIFY *p_notify,
UINT16 handle)
tGATT_VALUE *att_value)
{
tBT_UUID gattp_uuid, srvc_chg_uuid;
BOOLEAN processed = FALSE;
@ -1884,13 +1691,26 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
srvc_chg_uuid.len = 2;
srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
if (bta_gattc_uuid_compare(&p_notify->char_id.srvc_id.id.uuid, &gattp_uuid, TRUE) &&
bta_gattc_uuid_compare(&p_notify->char_id.char_id.uuid, &srvc_chg_uuid, TRUE)) {
const tBTA_GATTC_CHARACTERISTIC *p_char = bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
if (p_char && bta_gattc_uuid_compare(&p_char->service->uuid, &gattp_uuid, TRUE) &&
bta_gattc_uuid_compare(&p_char->uuid, &srvc_chg_uuid, TRUE)) {
if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
return FALSE;
}
UINT8 *p = att_value->value;
UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
APPL_TRACE_ERROR("%s: service changed s_handle:0x%04x e_handle:0x%04x",
__func__, s_handle, e_handle);
processed = TRUE;
/* mark service handle change pending */
p_srcb->srvc_hdl_chg = TRUE;
/* clear up all notification/indication registration */
bta_gattc_clear_notif_registration(conn_id);
bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
/* service change indication all received, do discovery update */
if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) {
/* not an opened connection; or connection busy */
@ -1906,7 +1726,7 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
}
}
/* send confirmation here if this is an indication, it should always be */
GATTC_SendHandleValueConfirm(conn_id, handle);
GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
/* if connection available, refresh cache by doing discovery now */
if (p_clcb != NULL) {
@ -1936,9 +1756,8 @@ void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
tGATT_CL_COMPLETE *p_data,
tBTA_GATTC_NOTIFY *p_notify)
{
APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check \
p_data->att_value.handle=%d p_data->handle=%d",
p_data->att_value.handle, p_data->handle);
APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check p_data->att_value.handle=%d p_data->handle=%d",
p_data->att_value.handle, p_data->handle);
APPL_TRACE_DEBUG("is_notify %d", p_notify->is_notify);
p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
@ -1998,40 +1817,32 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL
p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
if (bta_gattc_handle2id(p_srcb, handle,
&notify.char_id.srvc_id,
&notify.char_id.char_id,
&notify.descr_type)) {
/* if non-service change indication/notification, forward to application */
if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, &notify, handle)) {
/* if app registered for the notification */
if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, &notify)) {
/* connection not open yet */
notify.handle = handle;
/* if non-service change indication/notification, forward to application */
if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, &notify, &p_data->att_value)) {
/* if app registered for the notification */
if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, &notify)) {
/* connection not open yet */
if (p_clcb == NULL) {
p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
if (p_clcb == NULL) {
if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL) {
p_clcb->bta_conn_id = conn_id;
p_clcb->transport = transport;
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
} else {
APPL_TRACE_ERROR("No resources");
}
APPL_TRACE_ERROR("No resources");
return;
}
if (p_clcb != NULL) {
bta_gattc_proc_other_indication(p_clcb, op, p_data, &notify);
}
p_clcb->bta_conn_id = conn_id;
p_clcb->transport = transport;
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
}
if (p_clcb != NULL) {
bta_gattc_proc_other_indication(p_clcb, op, p_data, &notify);
}
} else if (op == GATTC_OPTYPE_INDICATION) {
/* no one intersted and need ack? */
else if (op == GATTC_OPTYPE_INDICATION) {
APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
GATTC_SendHandleValueConfirm(conn_id, handle);
}
}
} else {
APPL_TRACE_ERROR("%s Indi/Notif for Unknown handle[0x%04x], can not find in local cache.",
__func__, handle);
if (op == GATTC_OPTYPE_INDICATION) {
APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
GATTC_SendHandleValueConfirm(conn_id, handle);
}
}
@ -2287,7 +2098,7 @@ void bta_gattc_start_service_change_ccc_timer(UINT16 conn_id, BD_ADDR bda,UINT32
UINT8 timer_cnt, UINT8 last_status, TIMER_LIST_ENT *ccc_timer)
{
tBTA_GATTC_WAIT_CCC_TIMER *p_timer_param = (tBTA_GATTC_WAIT_CCC_TIMER*) osi_malloc(sizeof(tBTA_GATTC_WAIT_CCC_TIMER));
if (p_timer_param != NULL){
if (p_timer_param != NULL) {
p_timer_param->conn_id = conn_id;
memcpy(p_timer_param->remote_bda, bda, sizeof(BD_ADDR));
p_timer_param->count = timer_cnt;
@ -2311,12 +2122,13 @@ void bta_gattc_start_service_change_ccc_timer(UINT16 conn_id, BD_ADDR bda,UINT32
** Returns Return result of service change ccc service discovery result result and written operate result
**
*******************************************************************************/
tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda, BOOLEAN *need_timer){
tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda, BOOLEAN *need_timer)
{
tBTA_GATTC_SERV *p_srcb = NULL;
tBTA_GATTC_CACHE *p_cache = NULL;
tBTA_GATT_ID result_id;
tBTA_GATT_ID *p_result = &result_id;
tBTA_GATTC_CACHE_ATTR *p_attr = NULL;
list_t *p_cache = NULL;
tBTA_GATTC_SERVICE *p_service = NULL;
tBTA_GATTC_CHARACTERISTIC *p_char = NULL;
tBTA_GATTC_DESCRIPTOR *p_desc = NULL;
tGATT_STATUS write_status;
tGATT_VALUE ccc_value;
tBTA_GATTC_FIND_SERVICE_CB result;
@ -2331,7 +2143,7 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
p_srcb = bta_gattc_find_srcb(remote_bda);
if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)){
if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
p_cache = p_srcb->p_srvc_cache;
gatt_cache_found = TRUE;
}
@ -2339,15 +2151,15 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
start_find_ccc_timer = TRUE;
result = SERVICE_CHANGE_CACHE_NOT_FOUND;
}
/* start to find gatt service */
if (gatt_cache_found == TRUE){
while (p_cache) {
if (bta_gattc_uuid_compare(&gatt_service_uuid, &p_cache->service_uuid.id.uuid, TRUE)) {
if (gatt_cache_found == TRUE) {
for (list_node_t *sn = list_begin(p_cache);
sn != list_end(p_cache); sn = list_next(sn)) {
p_service = list_node(sn);
if (bta_gattc_uuid_compare(&gatt_service_uuid, &p_service->uuid, TRUE)) {
gatt_service_found = TRUE;
break;
}
p_cache = p_cache->p_next;
}
}
else {
@ -2356,38 +2168,37 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
}
/* start to find gatt service change characteristic */
if (gatt_service_found == TRUE){
p_attr = p_cache->p_attr;
while(p_attr){
bta_gattc_pack_attr_uuid(p_attr, &p_result->uuid);
if (bta_gattc_uuid_compare(&gatt_service_change_uuid, &p_result->uuid, TRUE)){
gatt_service_change_found = TRUE;
break;
if (gatt_service_found == TRUE) {
if (p_service->characteristics) {
for (list_node_t *cn = list_begin(p_service->characteristics);
cn != list_end(p_service->characteristics); cn = list_next(cn)) {
p_char = list_node(cn);
if (bta_gattc_uuid_compare(&gatt_service_change_uuid, &p_char->uuid, TRUE)) {
gatt_service_change_found = TRUE;
break;
}
}
p_attr = p_attr->p_next;
}
}
else if (gatt_cache_found == TRUE){
else if (gatt_cache_found == TRUE) {
/* Gatt service not found, start a timer to wait for service discovery */
start_find_ccc_timer = TRUE;
result = SERVICE_CHANGE_SERVICE_NOT_FOUND;
}
/* start to find gatt service change characteristic ccc */
if (gatt_service_change_found == TRUE){
p_attr = p_attr->p_next;
while(p_attr && p_attr->attr_type != BTA_GATTC_ATTR_TYPE_CHAR){
bta_gattc_pack_attr_uuid(p_attr, &p_result->uuid);
if (bta_gattc_uuid_compare(&gatt_ccc_uuid, &p_result->uuid, TRUE)){
gatt_ccc_found = TRUE;
break;
if (gatt_service_change_found == TRUE) {
if (p_char->descriptors) {
for (list_node_t *dn = list_begin(p_char->descriptors);
dn != list_end(p_char->descriptors); dn = list_next(dn)) {
p_desc = list_node(dn);
if (bta_gattc_uuid_compare(&gatt_ccc_uuid, &p_desc->uuid, TRUE)) {
gatt_ccc_found = TRUE;
break;
}
}
p_attr = p_attr->p_next;
}
}
else if (gatt_service_found ==TRUE){
else if (gatt_service_found ==TRUE) {
/* Gatt service found, but service change char not found,
* Case1: remote device doesn't have service change char, we don't need to start a timer here to
* wait for service discovery
@ -2398,7 +2209,7 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
}
if (gatt_ccc_found == TRUE){
ccc_value.handle = p_attr->attr_handle;
ccc_value.handle = p_desc->handle;
ccc_value.len = 2;
ccc_value.value[0] = GATT_CLT_CONFIG_INDICATION;
ccc_value.auth_req = GATT_AUTH_REQ_NONE;
@ -2417,17 +2228,17 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
}
}
else if (gatt_service_change_found == TRUE){
else if (gatt_service_change_found == TRUE) {
/* Gatt service char found, but service change char ccc not found,
* Case1: remote device doesn't have service change char ccc, we don't need to start a timer here to
* wait for service discovery
* Case2: remote device exist service change char ccc, we have found gatt service change char, but have not found
* service change char ccc, we need to start a timer here*/
* service change char ccc, we need to start a timer here */
start_find_ccc_timer = TRUE;
result = SERVICE_CHANGE_CCC_NOT_FOUND;
}
if (need_timer != NULL){
if (need_timer != NULL) {
*need_timer = start_find_ccc_timer;
}

View file

@ -282,272 +282,194 @@ void BTA_GATTC_ServiceSearchRequest (UINT16 conn_id, tBT_UUID *p_srvc_uuid)
/*******************************************************************************
**
** Function BTA_GATTC_GetFirstChar
** Function BTA_GATTC_GetServices
**
** Description This function is called to find the first characteristic of the
** service on the given server.
** Description This function is called to find the services on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_srvc_id: the service ID of which the characteristic is belonged to.
** p_char_uuid_cond: Characteristic UUID, if NULL find the first available
** characteristic.
** p_char_result: output parameter which will store the GATT
** characteristic ID.
** p_property: output parameter to carry the characteristic property.
**
** Returns returns status.
** Returns returns list_t of tBTA_GATTC_SERVICE or NULL.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_GetFirstChar (UINT16 conn_id, tBTA_GATT_SRVC_ID *p_srvc_id,
tBT_UUID *p_char_uuid_cond,
tBTA_GATTC_CHAR_ID *p_char_result,
tBTA_GATT_CHAR_PROP *p_property)
const list_t* BTA_GATTC_GetServices(UINT16 conn_id)
{
tBTA_GATT_STATUS status;
if (!p_srvc_id || !p_char_result) {
return BTA_GATT_ILLEGAL_PARAMETER;
}
if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR, p_srvc_id, NULL,
p_char_uuid_cond, &p_char_result->char_id, (void *)p_property))
== BTA_GATT_OK) {
memcpy(&p_char_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
}
return status;
}
/*******************************************************************************
**
** Function BTA_GATTC_GetNextChar
**
** Description This function is called to find the next characteristic of the
** service on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_start_char_id: start the characteristic search from the next record
** after the one identified by char_id.
** p_char_uuid_cond: Characteristic UUID, if NULL find the first available
** characteristic.
** p_char_result: output parameter which will store the GATT
** characteristic ID.
** p_property: output parameter to carry the characteristic property.
**
** Returns returns status.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_GetNextChar (UINT16 conn_id,
tBTA_GATTC_CHAR_ID *p_start_char_id,
tBT_UUID *p_char_uuid_cond,
tBTA_GATTC_CHAR_ID *p_char_result,
tBTA_GATT_CHAR_PROP *p_property)
{
tBTA_GATT_STATUS status;
if (!p_start_char_id || !p_char_result) {
return BTA_GATT_ILLEGAL_PARAMETER;
}
if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR,
&p_start_char_id->srvc_id,
&p_start_char_id->char_id,
p_char_uuid_cond,
&p_char_result->char_id,
(void *) p_property))
== BTA_GATT_OK) {
memcpy(&p_char_result->srvc_id, &p_start_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
}
return status;
return bta_gattc_get_services(conn_id);
}
/*******************************************************************************
**
** Function BTA_GATTC_GetFirstCharDescr
** Function BTA_GATTC_GetCharacteristic
**
** Description This function is called to find the first characteristic descriptor of the
** characteristic on the given server.
** Description This function is called to find the characteristic on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_char_id: the characteristic ID of which the descriptor is belonged to.
** p_descr_uuid_cond: Characteristic Descr UUID, if NULL find the first available
** characteristic.
** p_descr_result: output parameter which will store the GATT
** characteristic descriptor ID.
** Parameters conn_id - connection ID which identify the server.
** handle - characteristic handle
**
** Returns returns status.
** Returns returns pointer to tBTA_GATTC_CHARACTERISTIC or NULL.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_GetFirstCharDescr (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
tBT_UUID *p_descr_uuid_cond,
tBTA_GATTC_CHAR_DESCR_ID *p_descr_result)
const tBTA_GATTC_CHARACTERISTIC* BTA_GATTC_GetCharacteristic(UINT16 conn_id, UINT16 handle)
{
tBTA_GATT_STATUS status;
if (!p_char_id || !p_descr_result) {
return BTA_GATT_ILLEGAL_PARAMETER;
}
memset(p_descr_result, 0, sizeof(tBTA_GATTC_CHAR_DESCR_ID));
if ((status = bta_gattc_query_cache(conn_id,
BTA_GATTC_ATTR_TYPE_CHAR_DESCR,
&p_char_id->srvc_id,
&p_char_id->char_id,
p_descr_uuid_cond,
&p_descr_result->char_id.char_id,
NULL))
== BTA_GATT_OK) {
memcpy(&p_descr_result->descr_id, &p_descr_result->char_id.char_id, sizeof(tBTA_GATT_ID));
memcpy(&p_descr_result->char_id, p_char_id, sizeof(tBTA_GATTC_CHAR_ID));
}
return status;
return bta_gattc_get_characteristic(conn_id, handle);
}
/*******************************************************************************
**
** Function BTA_GATTC_GetNextCharDescr
** Function BTA_GATTC_GetDescriptor
**
** Description This function is called to find the next characteristic descriptor
** of the characterisctic.
** Description This function is called to find the characteristic on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_start_descr_id: start the descriptor search from the next record
** after the one identified by p_start_descr_id.
** p_descr_uuid_cond: Characteristic descriptor UUID, if NULL find
** the first available characteristic descriptor.
** p_descr_result: output parameter which will store the GATT
** characteristic descriptor ID.
** Parameters conn_id - connection ID which identify the server.
** handle - descriptor handle
**
** Returns returns status.
** Returns returns pointer to tBTA_GATTC_DESCRIPTOR or NULL.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_GetNextCharDescr (UINT16 conn_id,
tBTA_GATTC_CHAR_DESCR_ID *p_start_descr_id,
tBT_UUID *p_descr_uuid_cond,
tBTA_GATTC_CHAR_DESCR_ID *p_descr_result)
const tBTA_GATTC_DESCRIPTOR* BTA_GATTC_GetDescriptor(UINT16 conn_id, UINT16 handle)
{
tBTA_GATT_STATUS status;
return bta_gattc_get_descriptor(conn_id, handle);
}
if (!p_start_descr_id || !p_descr_result) {
return BTA_GATT_ILLEGAL_PARAMETER;
}
void BTA_GATTC_GetServiceWithUUID(UINT16 conn_id, tBT_UUID *svc_uuid,
btgatt_db_element_t **db, int *count)
{
bta_gattc_get_service_with_uuid(conn_id, svc_uuid, db, count);
}
memset(p_descr_result, 0, sizeof(tBTA_GATTC_CHAR_DESCR_ID));
void BTA_GATTC_GetAllChar(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
btgatt_db_element_t **db, int *count)
{
bta_gattc_get_db_with_opration(conn_id,
GATT_OP_GET_ALL_CHAR,
0,
NULL,
NULL,
NULL,
start_handle,
end_handle,
db,
count);
}
if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR_DESCR,
&p_start_descr_id->char_id.srvc_id,
&p_start_descr_id->char_id.char_id,
p_descr_uuid_cond,
&p_descr_result->char_id.char_id,
(void *)&p_start_descr_id->descr_id))
== BTA_GATT_OK) {
memcpy(&p_descr_result->descr_id, &p_descr_result->char_id.char_id, sizeof(tBTA_GATT_ID));
memcpy(&p_descr_result->char_id, p_start_descr_id, sizeof(tBTA_GATTC_CHAR_ID));
}
void BTA_GATTC_GetAllDescriptor(UINT16 conn_id, UINT16 char_handle,
btgatt_db_element_t **db, int *count)
{
bta_gattc_get_db_with_opration(conn_id,
GATT_OP_GET_ALL_DESCRI,
char_handle,
NULL,
NULL,
NULL,
0,
0xFFFF,
db,
count);
}
return status;
void BTA_GATTC_GetCharByUUID(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, tBT_UUID char_uuid,
btgatt_db_element_t **db, int *count)
{
bta_gattc_get_db_with_opration(conn_id,
GATT_OP_GET_CHAR_BY_UUID,
0,
NULL,
&char_uuid,
NULL,
start_handle,
end_handle,
db,
count);
}
void BTA_GATTC_GetDescrByUUID(UINT16 conn_id, uint16_t start_handle, uint16_t end_handle,
tBT_UUID char_uuid, tBT_UUID descr_uuid,
btgatt_db_element_t **db, int *count)
{
bta_gattc_get_db_with_opration(conn_id,
GATT_OP_GET_DESCRI_BY_UUID,
0,
NULL,
&char_uuid,
&descr_uuid,
start_handle,
end_handle,
db,
count);
}
void BTA_GATTC_GetDescrByCharHandle(UINT16 conn_id, UINT16 char_handle, tBT_UUID descr_uuid,
btgatt_db_element_t **db, int *count)
{
bta_gattc_get_db_with_opration(conn_id,
GATT_OP_GET_DESCRI_BY_HANDLE,
char_handle,
NULL,
NULL,
&descr_uuid,
0,
0xFFFF,
db,
count);
}
void BTA_GATTC_GetIncludeService(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
tBT_UUID *incl_uuid, btgatt_db_element_t **db, int *count)
{
bta_gattc_get_db_with_opration(conn_id,
GATT_OP_GET_INCLUDE_SVC,
0,
incl_uuid,
NULL,
NULL,
start_handle,
end_handle,
db,
count);
}
void BTA_GATTC_GetDBSize(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, int *count)
{
bta_gattc_get_db_size_handle(conn_id, start_handle, end_handle, count);
}
void BTA_GATTC_GetDBSizeByType(UINT16 conn_id, bt_gatt_db_attribute_type_t type,
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, int *count)
{
bta_gattc_get_db_size_with_type_handle(conn_id, type, start_handle, end_handle, char_handle, count);
}
/*******************************************************************************
**
** Function BTA_GATTC_GetFirstIncludedService
** Function BTA_GATTC_GetGattDb
**
** Description This function is called to find the first included service of the
** service on the given server.
** Description This function is called to get the GATT database.
**
** Parameters conn_id: connection ID which identify the server.
** p_srvc_id: the service ID of which the characteristic is belonged to.
** p_uuid_cond: Characteristic UUID, if NULL find the first available
** characteristic.
** p_result: output parameter which will store the GATT ID
** of the included service found.
**
** Returns returns status.
** db: output parameter which will contain the GATT database copy.
** Caller is responsible for freeing it.
** count: number of elements in database.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_GetFirstIncludedService(UINT16 conn_id, tBTA_GATT_SRVC_ID *p_srvc_id,
tBT_UUID *p_uuid_cond, tBTA_GATTC_INCL_SVC_ID *p_result)
void BTA_GATTC_GetGattDb(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
btgatt_db_element_t **db, int *count)
{
tBTA_GATT_STATUS status;
if (!p_srvc_id || !p_result) {
return BTA_GATT_ILLEGAL_PARAMETER;
}
if ((status = bta_gattc_query_cache(conn_id,
BTA_GATTC_ATTR_TYPE_INCL_SRVC,
p_srvc_id,
NULL,
p_uuid_cond,
&p_result->incl_svc_id.id,
(void *)&p_result->incl_svc_id.is_primary))
== BTA_GATT_OK) {
memcpy(&p_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
}
return status;
}
/*******************************************************************************
**
** Function BTA_GATTC_GetNextIncludedService
**
** Description This function is called to find the next included service of the
** service on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_start_id: start the search from the next record
** after the one identified by p_start_id.
** p_uuid_cond: Included service UUID, if NULL find the first available
** included service.
** p_result: output parameter which will store the GATT ID
** of the included service found.
**
** Returns returns status.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_GetNextIncludedService(UINT16 conn_id,
tBTA_GATTC_INCL_SVC_ID *p_start_id,
tBT_UUID *p_uuid_cond,
tBTA_GATTC_INCL_SVC_ID *p_result)
{
tBTA_GATT_STATUS status;
if (!p_start_id || !p_result) {
return BTA_GATT_ILLEGAL_PARAMETER;
}
if ((status = bta_gattc_query_cache(conn_id,
BTA_GATTC_ATTR_TYPE_INCL_SRVC,
&p_start_id->srvc_id,
&p_start_id->incl_svc_id.id,
p_uuid_cond,
&p_result->incl_svc_id.id,
(void *)&p_result->incl_svc_id.is_primary))
== BTA_GATT_OK) {
memcpy(&p_result->srvc_id, &p_start_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
}
return status;
bta_gattc_get_gatt_db(conn_id, start_handle, end_handle, db, count);
}
/*******************************************************************************
**
** Function BTA_GATTC_ReadCharacteristic
**
** Description This function is called to read a service's characteristics of
** the given characteritisc ID.
** Description This function is called to read a characteristics value
**
** Parameters conn_id - connection ID.
** p_char_id - characteritic ID to read.
** handle - characteritic handle to read.
**
** Returns None
**
*******************************************************************************/
void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
tBTA_GATT_AUTH_REQ auth_req)
void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, UINT16 handle, tBTA_GATT_AUTH_REQ auth_req)
{
tBTA_GATTC_API_READ *p_buf;
@ -557,10 +479,8 @@ void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
p_buf->hdr.layer_specific = conn_id;
p_buf->auth_req = auth_req;
memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
p_buf->p_descr_type = NULL;
p_buf->handle = handle;
p_buf->cmpl_evt = BTA_GATTC_READ_CHAR_EVT;
bta_sys_sendmsg(p_buf);
}
@ -571,17 +491,15 @@ void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
**
** Function BTA_GATTC_ReadCharDescr
**
** Description This function is called to read a characteristics descriptor.
** Description This function is called to read a descriptor value.
**
** Parameters conn_id - connection ID.
** p_char_descr_id - characteritic descriptor ID to read.
** handle - descriptor handle to read.
**
** Returns None
**
*******************************************************************************/
void BTA_GATTC_ReadCharDescr (UINT16 conn_id,
tBTA_GATTC_CHAR_DESCR_ID *p_descr_id,
tBTA_GATT_AUTH_REQ auth_req)
void BTA_GATTC_ReadCharDescr (UINT16 conn_id, UINT16 handle, tBTA_GATT_AUTH_REQ auth_req)
{
tBTA_GATTC_API_READ *p_buf;
UINT16 len = (UINT16)(sizeof(tBTA_GATT_ID) + sizeof(tBTA_GATTC_API_READ));
@ -592,12 +510,8 @@ void BTA_GATTC_ReadCharDescr (UINT16 conn_id,
p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
p_buf->hdr.layer_specific = conn_id;
p_buf->auth_req = auth_req;
memcpy(&p_buf->srvc_id, &p_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
memcpy(p_buf->p_descr_type, &p_descr_id->descr_id, sizeof(tBTA_GATT_ID));
p_buf->handle = handle;
p_buf->cmpl_evt = BTA_GATTC_READ_DESCR_EVT;
bta_sys_sendmsg(p_buf);
}
@ -621,10 +535,8 @@ void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi,
tBTA_GATT_AUTH_REQ auth_req)
{
tBTA_GATTC_API_READ_MULTI *p_buf;
tBTA_GATTC_ATTR_ID *p_value;
UINT16 len = (UINT16)(sizeof(tBTA_GATTC_API_READ_MULTI) +
p_read_multi->num_attr * sizeof(tBTA_GATTC_ATTR_ID));
UINT8 i;
//tBTA_GATTC_API_READ_MULTI *p_value;
UINT16 len = (UINT16)(sizeof(tBTA_GATTC_API_READ_MULTI));
if ((p_buf = (tBTA_GATTC_API_READ_MULTI *) osi_malloc(len)) != NULL) {
memset(p_buf, 0, len);
@ -632,16 +544,12 @@ void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi,
p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_EVT;
p_buf->hdr.layer_specific = conn_id;
p_buf->auth_req = auth_req;
p_buf->num_attr = p_read_multi->num_attr;
if (p_buf->num_attr > 0) {
p_buf->p_id_list = p_value = (tBTA_GATTC_ATTR_ID *)(p_buf + 1);
memcpy(p_buf->handles, p_read_multi->handles, sizeof(UINT16) * p_read_multi->num_attr);
}
for (i = 0; i < p_buf->num_attr; i ++, p_value ++) {
memcpy(p_value, &p_read_multi->id_list[i], sizeof(tBTA_GATTC_ATTR_ID));
}
}
bta_sys_sendmsg(p_buf);
}
return;
@ -655,8 +563,8 @@ void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi,
** Description This function is called to write characteristic value.
**
** Parameters conn_id - connection ID.
** p_char_id - characteristic ID to write.
** write_type - type of write.
** handle - characteristic handle to write.
** write_type - type of write.
** len: length of the data to be written.
** p_value - the value to be written.
**
@ -664,7 +572,7 @@ void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi,
**
*******************************************************************************/
void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
tBTA_GATTC_CHAR_ID *p_char_id,
UINT16 handle,
tBTA_GATTC_WRITE_TYPE write_type,
UINT16 len,
UINT8 *p_value,
@ -678,10 +586,8 @@ void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
p_buf->hdr.layer_specific = conn_id;
p_buf->auth_req = auth_req;
memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
p_buf->handle = handle;
p_buf->cmpl_evt = BTA_GATTC_WRITE_CHAR_EVT;
p_buf->write_type = write_type;
p_buf->len = len;
@ -698,10 +604,10 @@ void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
**
** Function BTA_GATTC_WriteCharDescr
**
** Description This function is called to write characteristic descriptor value.
** Description This function is called to write descriptor value.
**
** Parameters conn_id - connection ID
** p_char_descr_id - characteristic descriptor ID to write.
** handle - descriptor hadle to write.
** write_type - write type.
** p_value - the value to be written.
**
@ -709,14 +615,13 @@ void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
**
*******************************************************************************/
void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
tBTA_GATTC_CHAR_DESCR_ID *p_char_descr_id,
UINT16 handle,
tBTA_GATTC_WRITE_TYPE write_type,
tBTA_GATT_UNFMT *p_data,
tBTA_GATT_AUTH_REQ auth_req)
{
tBTA_GATTC_API_WRITE *p_buf;
UINT16 len = sizeof(tBTA_GATTC_API_WRITE) + sizeof(tBTA_GATT_ID);
size_t len = sizeof(tBTA_GATTC_API_WRITE);
tBTA_GATTC_API_WRITE *p_buf;
if (p_data != NULL) {
len += p_data->len;
}
@ -727,15 +632,12 @@ void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
p_buf->hdr.layer_specific = conn_id;
p_buf->auth_req = auth_req;
memcpy(&p_buf->srvc_id, &p_char_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
memcpy(p_buf->p_descr_type, &p_char_descr_id->descr_id, sizeof(tBTA_GATT_ID));
p_buf->handle = handle;
p_buf->cmpl_evt = BTA_GATTC_WRITE_DESCR_EVT;
p_buf->write_type = write_type;
if (p_data && p_data->len != 0) {
p_buf->p_value = (UINT8 *)(p_buf->p_descr_type + 1);
p_buf->p_value = (UINT8 *)(p_buf + 1);
p_buf->len = p_data->len;
/* pack the descr data */
memcpy(p_buf->p_value, p_data->p_value, p_data->len);
@ -761,7 +663,7 @@ void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
** Returns None
**
*******************************************************************************/
void BTA_GATTC_PrepareWrite (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
void BTA_GATTC_PrepareWrite (UINT16 conn_id, UINT16 handle,
UINT16 offset, UINT16 len, UINT8 *p_value,
tBTA_GATT_AUTH_REQ auth_req)
{
@ -773,9 +675,7 @@ void BTA_GATTC_PrepareWrite (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
p_buf->hdr.layer_specific = conn_id;
p_buf->auth_req = auth_req;
memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
p_buf->handle = handle;
p_buf->write_type = BTA_GATTC_WRITE_PREPARE;
p_buf->offset = offset;
@ -806,12 +706,12 @@ void BTA_GATTC_PrepareWrite (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
** Returns None
**
*******************************************************************************/
void BTA_GATTC_PrepareWriteCharDescr (UINT16 conn_id, tBTA_GATTC_CHAR_DESCR_ID *p_char_descr_id,
void BTA_GATTC_PrepareWriteCharDescr (UINT16 conn_id, UINT16 handle,
UINT16 offset,tBTA_GATT_UNFMT *p_data,
tBTA_GATT_AUTH_REQ auth_req)
{
tBTA_GATTC_API_WRITE *p_buf;
UINT16 len = sizeof(tBTA_GATTC_API_WRITE) + sizeof(tBTA_GATT_ID);
UINT16 len = sizeof(tBTA_GATTC_API_WRITE) + p_data->len;
if (p_data != NULL) {
len += p_data->len;
@ -823,17 +723,13 @@ void BTA_GATTC_PrepareWriteCharDescr (UINT16 conn_id, tBTA_GATTC_CHAR_DESCR_ID
p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
p_buf->hdr.layer_specific = conn_id;
p_buf->auth_req = auth_req;
memcpy(&p_buf->srvc_id, &p_char_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
memcpy(p_buf->p_descr_type, &p_char_descr_id->descr_id, sizeof(tBTA_GATT_ID));
p_buf->handle = handle;
p_buf->write_type = BTA_GATTC_WRITE_PREPARE;
p_buf->offset = offset;
if (p_data && p_data->len != 0) {
p_buf->p_value = (UINT8 *)(p_buf->p_descr_type + 1);
p_buf->len = p_data->len;
p_buf->p_value = (UINT8 *)(p_buf + 1);
/* pack the descr data */
memcpy(p_buf->p_value, p_data->p_value, p_data->len);
}
@ -861,7 +757,6 @@ void BTA_GATTC_ExecuteWrite (UINT16 conn_id, BOOLEAN is_execute)
if ((p_buf = (tBTA_GATTC_API_EXEC *) osi_malloc((UINT16)sizeof(tBTA_GATTC_API_EXEC))) != NULL) {
memset(p_buf, 0, sizeof(tBTA_GATTC_API_EXEC));
p_buf->hdr.event = BTA_GATTC_API_EXEC_EVT;
p_buf->hdr.layer_specific = conn_id;
@ -884,21 +779,18 @@ void BTA_GATTC_ExecuteWrite (UINT16 conn_id, BOOLEAN is_execute)
** Returns None
**
*******************************************************************************/
void BTA_GATTC_SendIndConfirm (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id)
void BTA_GATTC_SendIndConfirm (UINT16 conn_id, UINT16 handle)
{
tBTA_GATTC_API_CONFIRM *p_buf;
APPL_TRACE_API("BTA_GATTC_SendIndConfirm conn_id=%d service uuid1=0x%x char uuid=0x%x",
conn_id, p_char_id->srvc_id.id.uuid.uu.uuid16, p_char_id->char_id.uuid.uu.uuid16);
APPL_TRACE_API("BTA_GATTC_SendIndConfirm conn_id=%d handle =0x%x",
conn_id, handle);
if ((p_buf = (tBTA_GATTC_API_CONFIRM *) osi_malloc(sizeof(tBTA_GATTC_API_CONFIRM))) != NULL) {
memset(p_buf, 0, sizeof(tBTA_GATTC_API_CONFIRM));
p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT;
p_buf->hdr.layer_specific = conn_id;
memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
p_buf->handle = handle;
bta_sys_sendmsg(p_buf);
}
@ -914,21 +806,21 @@ void BTA_GATTC_SendIndConfirm (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id)
**
** Parameters client_if - client interface.
** bda - target GATT server.
** p_char_id - pointer to GATT characteristic ID.
** handle - GATT characteristic handle.
**
** Returns OK if registration succeed, otherwise failed.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
BD_ADDR bda,
tBTA_GATTC_CHAR_ID *p_char_id)
BD_ADDR bda, UINT16 handle)
{
tBTA_GATTC_RCB *p_clreg;
tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
UINT8 i;
if (!p_char_id) {
APPL_TRACE_ERROR("deregistration failed, unknow char id");
if (!handle)
{
APPL_TRACE_ERROR("deregistration failed, handle is 0");
return status;
}
@ -936,7 +828,7 @@ tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
if ( p_clreg->notif_reg[i].in_use &&
!memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id)) {
p_clreg->notif_reg[i].handle == handle) {
APPL_TRACE_WARNING("notification already registered");
status = BTA_GATT_OK;
break;
@ -950,10 +842,7 @@ tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
p_clreg->notif_reg[i].in_use = TRUE;
memcpy(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN);
p_clreg->notif_reg[i].char_id.srvc_id.is_primary = p_char_id->srvc_id.is_primary;
bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.srvc_id.id, &p_char_id->srvc_id.id);
bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.char_id, &p_char_id->char_id);
p_clreg->notif_reg[i].handle = handle;
status = BTA_GATT_OK;
break;
}
@ -977,48 +866,41 @@ tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
** Description This function is called to de-register for notification of a service.
**
** Parameters client_if - client interface.
** bda - target GATT server.
** p_char_id - pointer to GATT characteristic ID.
** remote_bda - target GATT server.
** handle - GATT characteristic handle.
**
** Returns OK if deregistration succeed, otherwise failed.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if,
BD_ADDR bda,
tBTA_GATTC_CHAR_ID *p_char_id)
BD_ADDR bda, UINT16 handle)
{
tBTA_GATTC_RCB *p_clreg;
tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
UINT8 i;
if (!p_char_id) {
APPL_TRACE_ERROR("%s deregistration failed, unknown char id", __func__);
return status;
if (!handle) {
APPL_TRACE_ERROR("%s: deregistration failed, handle is 0", __func__);
return BTA_GATT_ILLEGAL_PARAMETER;
}
if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL) {
for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
if (p_clreg->notif_reg[i].in_use &&
!memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id)) {
APPL_TRACE_DEBUG("%s deregistered bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
__func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
status = BTA_GATT_OK;
break;
}
}
if (i == BTA_GATTC_NOTIF_REG_MAX) {
status = BTA_GATT_ERROR;
APPL_TRACE_ERROR("%s registration not found bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
__func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
}
} else {
tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(client_if);
if (p_clreg == NULL) {
APPL_TRACE_ERROR("%s client_if: %d not registered bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
__func__, client_if, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
__func__, client_if, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
return BTA_GATT_ILLEGAL_PARAMETER;
}
return status;
for (int i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
if (p_clreg->notif_reg[i].in_use &&
!memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
p_clreg->notif_reg[i].handle == handle) {
APPL_TRACE_DEBUG("%s deregistered bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
__func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
return BTA_GATT_OK;
}
}
APPL_TRACE_ERROR("%s registration not found bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
__func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
return BTA_GATT_ERROR;
}
/*******************************************************************************
@ -1038,10 +920,8 @@ void BTA_GATTC_Refresh(BD_ADDR remote_bda)
if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) {
p_buf->hdr.event = BTA_GATTC_API_REFRESH_EVT;
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
bta_sys_sendmsg(p_buf);
}
return;
@ -1108,5 +988,5 @@ void BTA_GATTC_Broadcast(tBTA_GATTC_IF client_if, BOOLEAN start)
return;
}
#endif /* BTA_GATT_INCLUDED */
#endif /* defined(GATTC_INCLUDED) && (GATTC_INCLUDED == TRUE) */

File diff suppressed because it is too large Load diff

View file

@ -60,10 +60,6 @@ enum {
BTA_GATTC_CONFIRM,
BTA_GATTC_EXEC,
BTA_GATTC_READ_MULTI,
BTA_GATTC_CI_OPEN,
BTA_GATTC_CI_LOAD,
BTA_GATTC_CI_SAVE,
BTA_GATTC_CACHE_OPEN,
BTA_GATTC_IGNORE_OP_CMPL,
BTA_GATTC_DISC_CLOSE,
BTA_GATTC_RESTART_DISCOVER,
@ -98,10 +94,6 @@ const tBTA_GATTC_ACTION bta_gattc_action[] = {
bta_gattc_confirm,
bta_gattc_execute,
bta_gattc_read_multi,
bta_gattc_ci_open,
bta_gattc_ci_load,
bta_gattc_ci_save,
bta_gattc_cache_open,
bta_gattc_ignore_op_cmpl,
bta_gattc_disc_close,
bta_gattc_restart_discover,
@ -140,12 +132,6 @@ static const UINT8 bta_gattc_st_idle[][BTA_GATTC_NUM_COLS] = {
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
/* ===> for cache loading, saving */
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST}
};
/* state table for wait for open state */
@ -174,11 +160,6 @@ static const UINT8 bta_gattc_st_w4_conn[][BTA_GATTC_NUM_COLS] = {
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST},
/* ===> for cache loading, saving */
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST}
};
/* state table for open state */
@ -208,11 +189,6 @@ static const UINT8 bta_gattc_st_connected[][BTA_GATTC_NUM_COLS] = {
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
/* ===> for cache loading, saving */
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_CACHE_OPEN, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST}
};
/* state table for discover state */
@ -241,11 +217,6 @@ static const UINT8 bta_gattc_st_discover[][BTA_GATTC_NUM_COLS] = {
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE_OP_CMPL, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
/* ===> for cache loading, saving */
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_CI_OPEN, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_CI_LOAD, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_CI_SAVE, BTA_GATTC_DISCOVER_ST}
};
/* type for state table */
@ -477,14 +448,6 @@ static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code)
return "BTA_GATTC_OP_CMPL_EVT";
case BTA_GATTC_INT_DISCONN_EVT:
return "BTA_GATTC_INT_DISCONN_EVT";
case BTA_GATTC_START_CACHE_EVT:
return "BTA_GATTC_START_CACHE_EVT";
case BTA_GATTC_CI_CACHE_OPEN_EVT:
return "BTA_GATTC_CI_CACHE_OPEN_EVT";
case BTA_GATTC_CI_CACHE_LOAD_EVT:
return "BTA_GATTC_CI_CACHE_LOAD_EVT";
case BTA_GATTC_CI_CACHE_SAVE_EVT:
return "BTA_GATTC_CI_CACHE_SAVE_EVT";
case BTA_GATTC_INT_START_IF_EVT:
return "BTA_GATTC_INT_START_IF_EVT";
case BTA_GATTC_API_REG_EVT:

View file

@ -74,10 +74,10 @@ void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uui
** Returns TRUE if two uuid match; FALSE otherwise.
**
*******************************************************************************/
BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise)
BOOLEAN bta_gattc_uuid_compare (const tBT_UUID *p_src, const tBT_UUID *p_tar, BOOLEAN is_precise)
{
UINT8 su[LEN_UUID_128], tu[LEN_UUID_128];
UINT8 *ps, *pt;
const UINT8 *ps, *pt;
/* any of the UUID is unspecified */
if (p_src == 0 || p_tar == 0) {
@ -296,10 +296,16 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
p_srcb->connected = FALSE;
p_srcb->state = BTA_GATTC_SERV_IDLE;
p_srcb->mtu = 0;
/* clean up cache */
if (p_srcb->p_srvc_cache) {
list_free(p_srcb->p_srvc_cache);
p_srcb->p_srvc_cache = NULL;
}
}
utl_freebuf((void **)&p_clcb->p_q_cmd);
osi_free(p_clcb->p_q_cmd);
p_clcb->p_q_cmd = NULL;
//osi_free_and_reset((void **)&p_clcb->p_q_cmd);
memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
} else {
APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
@ -396,25 +402,22 @@ tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda)
/* if not found, try to recycle one known device */
if (!found && !p_recycle) {
p_tcb = NULL;
} else if (!found && p_recycle) {
}
else if (!found && p_recycle) {
p_tcb = p_recycle;
}
}
if (p_tcb != NULL) {
if (p_tcb->cache_buffer) {
while (!fixed_queue_is_empty(p_tcb->cache_buffer)) {
osi_free(fixed_queue_dequeue(p_tcb->cache_buffer));
}
fixed_queue_free(p_tcb->cache_buffer, NULL);
}
utl_freebuf((void **)&p_tcb->p_srvc_list);
if (p_tcb != NULL)
{
if (p_tcb->p_srvc_cache != NULL)
list_free(p_tcb->p_srvc_cache);
osi_free(p_tcb->p_srvc_list);
p_tcb->p_srvc_list = NULL;
//osi_free_and_reset((void **)&p_tcb->p_srvc_list);
memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));
p_tcb->in_use = TRUE;
bdcpy(p_tcb->server_bda, bda);
p_tcb->cache_buffer = fixed_queue_new(SIZE_MAX); //by Snake
}
return p_tcb;
}
@ -430,118 +433,15 @@ tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda)
BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
if (p_clcb->p_q_cmd == NULL) {
if (p_clcb->p_q_cmd == NULL)
{
p_clcb->p_q_cmd = p_data;
} else {
APPL_TRACE_ERROR("already has a pending command!!");
/* skip the callback now. ----- need to send callback ? */
}
return (p_clcb->p_q_cmd != NULL) ? TRUE : FALSE;
}
/*******************************************************************************
**
** Function bta_gattc_pack_attr_uuid
**
** Description pack UUID into a stream.
**
** Returns
**
*******************************************************************************/
void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid)
{
UINT8 *pp = (UINT8 *)p_attr->p_uuid;
memset(p_uuid, 0, sizeof(tBT_UUID));
p_uuid->len = p_attr->uuid_len;
if (p_attr->uuid_len == LEN_UUID_16) {
STREAM_TO_UINT16(p_uuid->uu.uuid16, pp);
} else {
memcpy(p_uuid->uu.uuid128, pp, LEN_UUID_128);
}
return;
}
/*******************************************************************************
**
** Function bta_gattc_cpygattid
**
** Description copy two tBTA_GATT_ID value
**
** Returns
**
*******************************************************************************/
void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src)
{
memset ((void *)p_des, 0, sizeof(tBTA_GATT_ID));
p_des->inst_id = p_src->inst_id;
p_des->uuid.len = p_src->uuid.len;
if (p_des->uuid.len == LEN_UUID_16) {
p_des->uuid.uu.uuid16 = p_src->uuid.uu.uuid16;
} else if (p_des->uuid.len == LEN_UUID_128) {
memcpy(p_des->uuid.uu.uuid128, p_src->uuid.uu.uuid128, LEN_UUID_128);
}
}
/*******************************************************************************
**
** Function bta_gattc_gattid_compare
**
** Description compare two tBTA_GATT_ID type of pointer
**
** Returns
**
*******************************************************************************/
BOOLEAN bta_gattc_gattid_compare(tBTA_GATT_ID *p_src, tBTA_GATT_ID *p_tar)
{
if (p_src->inst_id == p_tar->inst_id &&
bta_gattc_uuid_compare (&p_src->uuid, &p_tar->uuid, TRUE )) {
return TRUE;
} else {
return FALSE;
}
}
/*******************************************************************************
**
** Function bta_gattc_srvcid_compare
**
** Description compare two tBTA_GATT_SRVC_ID type of pointer
**
** Returns
**
*******************************************************************************/
BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar)
{
if (p_src->is_primary == p_tar->is_primary &&
bta_gattc_gattid_compare (&p_src->id, &p_tar->id)) {
return TRUE;
} else {
return FALSE;
}
}
/*******************************************************************************
**
** Function bta_gattc_charid_compare
**
** Description compare two tBTA_GATTC_CHAR_ID type of pointer
**
** Returns
**
*******************************************************************************/
BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar)
{
if (bta_gattc_gattid_compare (&p_src->char_id, &p_tar->char_id) &&
bta_gattc_srvcid_compare (&p_src->srvc_id, &p_tar->srvc_id)) {
return TRUE;
} else {
return FALSE;
}
APPL_TRACE_ERROR ("%s: already has a pending command!!", __func__);
/* skip the callback now. ----- need to send callback ? */
return FALSE;
}
/*******************************************************************************
@ -558,10 +458,12 @@ BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV
{
UINT8 i;
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
{
if (p_clreg->notif_reg[i].in_use &&
bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
bta_gattc_charid_compare (&p_clreg->notif_reg[i].char_id, &p_notify->char_id)) {
bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
p_clreg->notif_reg[i].handle == p_notify->handle)
{
APPL_TRACE_DEBUG("Notification registered!");
return TRUE;
}
@ -573,26 +475,36 @@ BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV
**
** Function bta_gattc_clear_notif_registration
**
** Description clear up the notification registration information by BD_ADDR.
** Description Clear up the notification registration information by BD_ADDR.
** Where handle is between start_handle and end_handle, and
** start_handle and end_handle are boundaries of service
** containing characteristic.
**
** Returns None.
**
*******************************************************************************/
void bta_gattc_clear_notif_registration(UINT16 conn_id)
void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id,
UINT16 start_handle, UINT16 end_handle)
{
BD_ADDR remote_bda;
tBTA_GATTC_IF gatt_if;
tBTA_GATTC_RCB *p_clrcb ;
UINT8 i;
tGATT_TRANSPORT transport;
UINT16 handle = 0;
if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) {
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
if (p_clrcb->notif_reg[i].in_use &&
!bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda)) {
memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
}
!bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
/* It's enough to get service or characteristic handle, as
* clear boundaries are always around service.
*/
handle = p_clrcb->notif_reg[i].handle;
if (handle >= start_handle && handle <= end_handle)
memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
}
}
} else {
@ -601,50 +513,6 @@ void bta_gattc_clear_notif_registration(UINT16 conn_id)
return;
}
/*******************************************************************************
**
** Function bta_gattc_pack_cb_data
**
** Description pack the data from read response into callback data structure.
**
** Returns
**
*******************************************************************************/
tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb,
tBT_UUID *p_descr_uuid,
tGATT_VALUE *p_attr,
tBTA_GATT_READ_VAL *p_value)
{
UINT8 i = 0, *pp = p_attr->value;
tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_AGG_FORMAT}};
UINT16 handle;
tBTA_GATT_STATUS status = BTA_GATT_OK;
/* GATT_UUID_CHAR_AGG_FORMAT */
if (bta_gattc_uuid_compare (&uuid, p_descr_uuid, TRUE)) {
while (p_attr->len >= 2 && i < BTA_GATTC_MULTI_MAX) {
STREAM_TO_UINT16(handle, pp);
if (bta_gattc_handle2id(p_srcb,
handle,
&p_value->aggre_value.pre_format[i].char_id.srvc_id,
&p_value->aggre_value.pre_format[i].char_id.char_id,
&p_value->aggre_value.pre_format[i].descr_id) == FALSE) {
status = BTA_GATT_INTERNAL_ERROR;
APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x", handle);
break;
}
i ++;
p_attr->len -= 2;
}
p_value->aggre_value.num_pres_fmt = i;
} else {
/* all others, take as raw format */
p_value->unformat.len = p_attr->len;
p_value->unformat.p_value = p_attr->value;
}
return status;
}
/*******************************************************************************
**
** Function bta_gattc_mark_bg_conn
@ -982,4 +850,43 @@ tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
return p_clcb;
}
void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src)
{
int i = 0;
if (p_src->len == LEN_UUID_16 || p_src->len == LEN_UUID_32)
{
for(i=0; i != 16; ++i)
p_dest->uu[i] = base_uuid[i];
}
switch (p_src->len)
{
case 0:
break;
case LEN_UUID_16:
p_dest->uu[12] = p_src->uu.uuid16 & 0xff;
p_dest->uu[13] = (p_src->uu.uuid16 >> 8) & 0xff;
break;
case LEN_UUID_32:
p_dest->uu[12] = p_src->uu.uuid16 & 0xff;
p_dest->uu[13] = (p_src->uu.uuid16 >> 8) & 0xff;
p_dest->uu[14] = (p_src->uu.uuid32 >> 16) & 0xff;
p_dest->uu[15] = (p_src->uu.uuid32 >> 24) & 0xff;
break;
case LEN_UUID_128:
for(i=0; i != 16; ++i)
p_dest->uu[i] = p_src->uu.uuid128[i];
break;
default:
LOG_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_src->len);
break;
}
}
#endif /* BTA_GATT_INCLUDED */

View file

@ -27,6 +27,7 @@
#include "bta_api.h"
#include "gatt_api.h"
#include "list.h"
#ifndef BTA_GATT_INCLUDED
#warning BTA_GATT_INCLUDED not defined
@ -43,6 +44,34 @@
#define BTA_GATT_DEBUG FALSE
#endif
typedef enum {
BTGATT_DB_PRIMARY_SERVICE,
BTGATT_DB_SECONDARY_SERVICE,
BTGATT_DB_CHARACTERISTIC,
BTGATT_DB_DESCRIPTOR,
BTGATT_DB_INCLUDED_SERVICE,
}bt_gatt_db_attribute_type_t;
typedef enum {
GATT_OP_GET_SVC_BY_UUID,
GATT_OP_GET_ALL_CHAR,
GATT_OP_GET_ALL_DESCRI,
GATT_OP_GET_CHAR_BY_UUID,
GATT_OP_GET_DESCRI_BY_UUID,
GATT_OP_GET_DESCRI_BY_HANDLE,
GATT_OP_GET_INCLUDE_SVC,
}bt_gatt_get_db_op_t;
typedef struct {
bt_gatt_db_attribute_type_t type;
UINT16 attribute_handle;
UINT16 start_handle;
UINT16 end_handle;
UINT16 id;
UINT8 properties;
bt_uuid_t uuid;
}btgatt_db_element_t;
/*****************************************************************************
** Constants and data types
*****************************************************************************/
@ -104,7 +133,7 @@ typedef struct {
#define BTA_GATT_APP_RSP GATT_APP_RSP /* 0xE1 */
//Error caused by customer application or stack bug
#define BTA_GATT_UNKNOWN_ERROR GATT_UNKNOWN_ERROR /* 0XEF */
/* 0xE0 ~ 0xFC reserved for future use */
#define BTA_GATT_CCC_CFG_ERR GATT_CCC_CFG_ERR /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */
#define BTA_GATT_PRC_IN_PROGRESS GATT_PRC_IN_PROGRESS /* 0xFE Procedure Already in progress */
#define BTA_GATT_OUT_OF_RANGE GATT_OUT_OF_RANGE /* 0xFFAttribute value out of range */
@ -213,41 +242,13 @@ typedef struct {
BOOLEAN is_primary;
} tBTA_GATT_SRVC_ID;
typedef struct {
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
} tBTA_GATTC_CHAR_ID;
typedef struct {
tBTA_GATTC_CHAR_ID char_id;
tBTA_GATT_ID descr_id;
} tBTA_GATTC_CHAR_DESCR_ID;
typedef struct {
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_SRVC_ID incl_svc_id;
} tBTA_GATTC_INCL_SVC_ID;
#define BTA_GATT_TYPE_CHAR 0
#define BTA_GATT_TYPE_CHAR_DESCR 1
typedef UINT8 tBTA_GATT_ID_TYPE;
typedef struct {
tBTA_GATT_ID_TYPE id_type;
union {
tBTA_GATTC_CHAR_ID char_id;
tBTA_GATTC_CHAR_DESCR_ID char_descr_id;
} id_value;
} tBTA_GATTC_ATTR_ID;
#define BTA_GATTC_MULTI_MAX GATT_MAX_READ_MULTI_HANDLES
typedef struct {
UINT8 num_attr;
tBTA_GATTC_ATTR_ID id_list[BTA_GATTC_MULTI_MAX];
} tBTA_GATTC_MULTI;
UINT16 handles[BTA_GATTC_MULTI_MAX];
}tBTA_GATTC_MULTI;
/* relate to ESP_GATT_xxx in esp_gatt_def.h */
#define BTA_GATT_AUTH_REQ_NONE GATT_AUTH_REQ_NONE
@ -275,44 +276,28 @@ typedef struct {
UINT8 id;
UINT8 prop; /* used when attribute type is characteristic */
BOOLEAN is_primary; /* used when attribute type is service */
} tBTA_GATTC_NV_ATTR;
UINT16 incl_srvc_handle; /* used when attribute type is included service */
}tBTA_GATTC_NV_ATTR;
/* callback data structure */
typedef struct {
tBTA_GATT_STATUS status;
tBTA_GATTC_IF client_if;
// btla-specific ++
tBT_UUID app_uuid;
// btla-specific --
} tBTA_GATTC_REG;
typedef struct {
UINT8 num_pres_fmt; /* number of presentation format aggregated*/
tBTA_GATTC_CHAR_DESCR_ID pre_format[BTA_GATTC_MULTI_MAX];
} tBTA_GATT_CHAR_AGGRE_VALUE;
typedef union {
tBTA_GATT_CHAR_AGGRE_VALUE aggre_value;
tBTA_GATT_UNFMT unformat;
} tBTA_GATT_READ_VAL;
}tBTA_GATTC_REG;
typedef struct {
UINT16 conn_id;
tBTA_GATT_STATUS status;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
tBTA_GATT_ID descr_type;
tBTA_GATT_READ_VAL *p_value;
} tBTA_GATTC_READ;
UINT16 handle;
tBTA_GATT_UNFMT *p_value;
}tBTA_GATTC_READ;
typedef struct {
UINT16 conn_id;
tBTA_GATT_STATUS status;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
tBTA_GATT_ID descr_type;
} tBTA_GATTC_WRITE;
UINT16 handle;
}tBTA_GATTC_WRITE;
typedef struct {
UINT16 conn_id;
@ -326,8 +311,10 @@ typedef struct {
typedef struct {
UINT16 conn_id;
tBTA_GATT_SRVC_ID service_uuid;
} tBTA_GATTC_SRVC_RES;
UINT16 start_handle;
UINT16 end_handle;
tBTA_GATT_ID service_uuid;
}tBTA_GATTC_SRVC_RES;
typedef struct {
UINT16 conn_id;
@ -355,8 +342,7 @@ typedef struct {
typedef struct {
UINT16 conn_id;
BD_ADDR bda;
tBTA_GATTC_CHAR_ID char_id;
tBTA_GATT_ID descr_type;
UINT16 handle;
UINT16 len;
UINT8 value[BTA_GATT_MAX_ATTR_LEN];
BOOLEAN is_notify;
@ -367,14 +353,12 @@ typedef struct {
BOOLEAN congested; /* congestion indicator */
} tBTA_GATTC_CONGEST;
// btla-specific ++
typedef struct {
tBTA_GATT_STATUS status;
tBTA_GATTC_IF client_if;
UINT16 conn_id;
BD_ADDR remote_bda;
} tBTA_GATTC_OPEN_CLOSE;
// btla-specific --
}tBTA_GATTC_OPEN_CLOSE;
typedef struct {
tBTA_GATTC_IF client_if;
@ -395,6 +379,8 @@ typedef struct {
BD_ADDR remote_bda;
} tBTA_GATTC_DISCONNECT;
typedef union {
tBTA_GATT_STATUS status;
@ -541,33 +527,26 @@ typedef struct {
typedef struct {
tBTA_GATTS_IF server_if;
tBTA_GATT_STATUS status;
// btla-specific ++
tBT_UUID uuid;
// btla-specific --
} tBTA_GATTS_REG_OPER;
}tBTA_GATTS_REG_OPER;
typedef struct {
tBTA_GATTS_IF server_if;
UINT16 service_id;
// btla-specific ++
UINT16 svc_instance;
BOOLEAN is_primary;
tBTA_GATT_STATUS status;
tBT_UUID uuid;
// btla-specific --
} tBTA_GATTS_CREATE;
}tBTA_GATTS_CREATE;
typedef struct {
tBTA_GATTS_IF server_if;
UINT16 service_id;
UINT16 attr_id;
tBTA_GATT_STATUS status;
// btla-specific ++
tBT_UUID char_uuid;
// btla-specific --
} tBTA_GATTS_ADD_RESULT;
}tBTA_GATTS_ADD_RESULT;
typedef struct{
tBTA_GATTS_IF server_if;
UINT16 service_id;
@ -614,7 +593,6 @@ typedef struct {
tBTA_GATT_STATUS status;
tBTA_GATTS_IF server_if;
} tBTA_GATTS_CANCEL_OPEN;
/* GATTS callback data */
typedef union {
tBTA_GATTS_REG_OPER reg_oper;
@ -648,6 +626,41 @@ typedef void (tBTA_GATTS_ENB_CBACK)(tBTA_GATT_STATUS status);
/* Server callback function */
typedef void (tBTA_GATTS_CBACK)(tBTA_GATTS_EVT event, tBTA_GATTS *p_data);
typedef struct
{
tBT_UUID uuid;
BOOLEAN is_primary;
UINT16 handle;
UINT16 s_handle;
UINT16 e_handle;
list_t *characteristics; /* list of tBTA_GATTC_CHARACTERISTIC */
list_t *included_svc; /* list of tBTA_GATTC_INCLUDED_SVC */
} __attribute__((packed)) tBTA_GATTC_SERVICE;
typedef struct
{
tBT_UUID uuid;
UINT16 handle;
tBTA_GATT_CHAR_PROP properties;
tBTA_GATTC_SERVICE *service; /* owning service*/
list_t *descriptors; /* list of tBTA_GATTC_DESCRIPTOR */
} __attribute__((packed)) tBTA_GATTC_CHARACTERISTIC;
typedef struct
{
tBT_UUID uuid;
UINT16 handle;
tBTA_GATTC_CHARACTERISTIC *characteristic; /* owning characteristic */
} __attribute__((packed)) tBTA_GATTC_DESCRIPTOR;
typedef struct
{
tBT_UUID uuid;
UINT16 handle;
UINT16 incl_srvc_s_handle;
tBTA_GATTC_SERVICE *owning_service; /* owning service*/
tBTA_GATTC_SERVICE *included_service;
} __attribute__((packed)) tBTA_GATTC_INCLUDED_SVC;
/*****************************************************************************
** External Function Declarations
@ -770,175 +783,114 @@ extern void BTA_GATTC_ServiceSearchRequest(UINT16 conn_id, tBT_UUID *p_srvc_uuid
/*******************************************************************************
**
** Function BTA_GATTC_GetFirstChar
** Function BTA_GATTC_GetServices
**
** Description This function is called to find the first charatceristic of the
** service on the given server.
** Description This function is called to find the services on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_srvc_id: the service ID of which the characteristic is belonged to.
** p_char_uuid_cond: Characteristic UUID, if NULL find the first available
** characteristic.
** p_char_result: output parameter which will store the GATT
** characteristic ID.
** p_property: output parameter to carry the characteristic property.
**
** Returns returns status.
** Returns returns list_t of tBTA_GATTC_SERVICE or NULL.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_GetFirstChar (UINT16 conn_id,
tBTA_GATT_SRVC_ID *p_srvc_id,
tBT_UUID *p_char_uuid_cond,
tBTA_GATTC_CHAR_ID *p_char_result,
tBTA_GATT_CHAR_PROP *p_property);
extern const list_t* BTA_GATTC_GetServices(UINT16 conn_id);
/*******************************************************************************
**
** Function BTA_GATTC_GetNextChar
** Function BTA_GATTC_GetCharacteristic
**
** Description This function is called to find the next charatceristic of the
** service on the given server.
** Description This function is called to find the characteristic on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_start_char_id: start the characteristic search from the next record
** after the one identified by char_id.
** p_char_uuid_cond: Characteristic UUID, if NULL find the first available
** characteristic.
** p_char_result: output parameter which will store the GATT
** characteristic ID.
** p_property: output parameter, characteristic property.
** handle: characteristic handle
**
** Returns returns status.
** Returns returns pointer to tBTA_GATTC_CHARACTERISTIC or NULL.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_GetNextChar (UINT16 conn_id,
tBTA_GATTC_CHAR_ID *p_start_char_id,
tBT_UUID *p_char_uuid_cond,
tBTA_GATTC_CHAR_ID *p_char_result,
tBTA_GATT_CHAR_PROP *p_property);
extern const tBTA_GATTC_CHARACTERISTIC* BTA_GATTC_GetCharacteristic(UINT16 conn_id, UINT16 handle);
/*******************************************************************************
**
** Function BTA_GATTC_GetFirstCharDescr
** Function BTA_GATTC_GetDescriptor
**
** Description This function is called to find the first charatceristic descriptor of the
** charatceristic on the given server.
** Description This function is called to find the characteristic on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_char_id: the characteristic ID of which the descriptor is belonged to.
** p_descr_uuid_cond: Characteristic Descr UUID, if NULL find the first available
** characteristic.
** p_descr_result: output parameter which will store the GATT
** characteristic descriptor ID.
** handle: descriptor handle
**
** Returns returns status.
** Returns returns pointer to tBTA_GATTC_DESCRIPTOR or NULL.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_GetFirstCharDescr (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
tBT_UUID *p_descr_uuid_cond,
tBTA_GATTC_CHAR_DESCR_ID *p_descr_result);
extern const tBTA_GATTC_DESCRIPTOR* BTA_GATTC_GetDescriptor(UINT16 conn_id, UINT16 handle);
extern void BTA_GATTC_GetServiceWithUUID(UINT16 conn_id, tBT_UUID *svc_uuid,
btgatt_db_element_t **db, int *count);
extern void BTA_GATTC_GetAllChar(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
btgatt_db_element_t **db, int *count);
extern void BTA_GATTC_GetAllDescriptor(UINT16 conn_id, UINT16 char_handle,
btgatt_db_element_t **db, int *count);
extern void BTA_GATTC_GetCharByUUID(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, tBT_UUID char_uuid,
btgatt_db_element_t **db, int *count);
extern void BTA_GATTC_GetDescrByUUID(UINT16 conn_id, uint16_t start_handle, uint16_t end_handle,
tBT_UUID char_uuid, tBT_UUID descr_uuid,
btgatt_db_element_t **db, int *count);
extern void BTA_GATTC_GetDescrByCharHandle(UINT16 conn_id, UINT16 char_handle, tBT_UUID descr_uuid,
btgatt_db_element_t **db, int *count);
extern void BTA_GATTC_GetIncludeService(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
tBT_UUID *incl_uuid, btgatt_db_element_t **db, int *count);
extern void BTA_GATTC_GetDBSize(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, int *count);
extern void BTA_GATTC_GetDBSizeByType(UINT16 conn_id, bt_gatt_db_attribute_type_t type,
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, int *count);
/*******************************************************************************
**
** Function BTA_GATTC_GetNextCharDescr
** Function BTA_GATTC_GetGattDb
**
** Description This function is called to find the next charatceristic of the
** service on the given server.
** Description This function is called to get gatt db.
**
** Parameters conn_id: connection ID which identify the server.
** p_start_descr_id: start the characteristic search from the next record
** after the one identified by p_start_descr_id.
** p_descr_uuid_cond: Characteristic descriptor UUID, if NULL find
** the first available characteristic descriptor.
** p_descr_result: output parameter which will store the GATT
** characteristic descriptor ID.
**
** Returns returns status.
** db: output parameter which will contain gatt db copy.
** Caller is responsible for freeing it.
** count: number of elements in db.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_GetNextCharDescr (UINT16 conn_id,
tBTA_GATTC_CHAR_DESCR_ID *p_start_descr_id,
tBT_UUID *p_descr_uuid_cond,
tBTA_GATTC_CHAR_DESCR_ID *p_descr_result);
/*******************************************************************************
**
** Function BTA_GATTC_GetFirstIncludedService
**
** Description This function is called to find the first included service of the
** service on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_srvc_id: the service ID of which the included service is belonged to.
** p_uuid_cond: include service UUID, if NULL find the first available
** included service.
** p_result: output parameter which will store the GATT ID
** of the included service found.
**
** Returns returns status.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_GetFirstIncludedService(UINT16 conn_id,
tBTA_GATT_SRVC_ID *p_srvc_id,
tBT_UUID *p_uuid_cond,
tBTA_GATTC_INCL_SVC_ID *p_result);
/*******************************************************************************
**
** Function BTA_GATTC_GetNextIncludedService
**
** Description This function is called to find the next included service of the
** service on the given server.
**
** Parameters conn_id: connection ID which identify the server.
** p_start_id: start the search from the next record
** after the one identified by p_start_id.
** p_uuid_cond: Included service UUID, if NULL find the first available
** included service.
** p_result: output parameter which will store the GATT ID
** of the included service found.
**
** Returns returns status.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_GetNextIncludedService(UINT16 conn_id,
tBTA_GATTC_INCL_SVC_ID *p_start_id,
tBT_UUID *p_uuid_cond,
tBTA_GATTC_INCL_SVC_ID *p_result);
extern void BTA_GATTC_GetGattDb(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
btgatt_db_element_t **db, int *count);
/*******************************************************************************
**
** Function BTA_GATTC_ReadCharacteristic
**
** Description This function is called to read a service's characteristics of
** the given characteritisc ID.
** Description This function is called to read a characteristics value
**
** Parameters conn_id - connection ID.
** p_char_id - characteritic ID to read.
** Parameters conn_id - connectino ID.
** handle - characteritic handle to read.
**
** Returns None
**
*******************************************************************************/
extern void BTA_GATTC_ReadCharacteristic (UINT16 conn_id,
tBTA_GATTC_CHAR_ID *p_char_id,
tBTA_GATT_AUTH_REQ auth_req);
void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, UINT16 handle, tBTA_GATT_AUTH_REQ auth_req);
/*******************************************************************************
**
** Function BTA_GATTC_ReadCharDescr
**
** Description This function is called to read a characteristics descriptor.
** Description This function is called to read a descriptor value.
**
** Parameters conn_id - connection ID.
** p_char_descr_id - characteritic descriptor ID to read.
** handle - descriptor handle to read.
**
** Returns None
**
*******************************************************************************/
extern void BTA_GATTC_ReadCharDescr (UINT16 conn_id,
tBTA_GATTC_CHAR_DESCR_ID *p_char_descr_id,
tBTA_GATT_AUTH_REQ auth_req);
void BTA_GATTC_ReadCharDescr (UINT16 conn_id, UINT16 handle, tBTA_GATT_AUTH_REQ auth_req);
/*******************************************************************************
**
@ -947,40 +899,40 @@ extern void BTA_GATTC_ReadCharDescr (UINT16 conn_id,
** Description This function is called to write characteristic value.
**
** Parameters conn_id - connection ID.
** p_char_id - characteristic ID to write.
** write_type - type of write.
** handle - characteristic handle to write.
** write_type - type of write.
** len: length of the data to be written.
** p_value - the value to be written.
**
** Returns None
**
*******************************************************************************/
extern void BTA_GATTC_WriteCharValue (UINT16 conn_id,
tBTA_GATTC_CHAR_ID *p_char_id,
tBTA_GATTC_WRITE_TYPE write_type,
UINT16 len,
UINT8 *p_value,
tBTA_GATT_AUTH_REQ auth_req);
void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
UINT16 handle,
tBTA_GATTC_WRITE_TYPE write_type,
UINT16 len,
UINT8 *p_value,
tBTA_GATT_AUTH_REQ auth_req);
/*******************************************************************************
**
** Function BTA_GATTC_WriteCharDescr
**
** Description This function is called to write characteristic descriptor value.
** Description This function is called to write descriptor value.
**
** Parameters conn_id - connection ID
** p_char_descr_id - characteristic descriptor ID to write.
** write_type - type of write.
** handle - descriptor handle to write.
** write_type - type of write.
** p_value - the value to be written.
**
** Returns None
**
*******************************************************************************/
extern void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
tBTA_GATTC_CHAR_DESCR_ID *p_char_descr_id,
tBTA_GATTC_WRITE_TYPE write_type,
tBTA_GATT_UNFMT *p_data,
tBTA_GATT_AUTH_REQ auth_req);
void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
UINT16 handle,
tBTA_GATTC_WRITE_TYPE write_type,
tBTA_GATT_UNFMT *p_data,
tBTA_GATT_AUTH_REQ auth_req);
/*******************************************************************************
**
@ -989,12 +941,12 @@ extern void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
** Description This function is called to send handle value confirmation.
**
** Parameters conn_id - connection ID.
** p_char_id - characteristic ID to confrim.
** handle - characteristic handle to confirm.
**
** Returns None
**
*******************************************************************************/
extern void BTA_GATTC_SendIndConfirm (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id);
extern void BTA_GATTC_SendIndConfirm (UINT16 conn_id, UINT16 handle);
/*******************************************************************************
**
@ -1002,17 +954,16 @@ extern void BTA_GATTC_SendIndConfirm (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char
**
** Description This function is called to register for notification of a service.
**
** Parameters client_if - client interface.
** remote_bda - target GATT server.
** p_char_id - pointer to GATT characteristic ID.
** Parameters client_if - client interface.
** remote_bda - target GATT server.
** handle - GATT characteristic handle.
**
** Returns OK if registration succeed, otherwise failed.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
BD_ADDR remote_bda,
tBTA_GATTC_CHAR_ID *p_char_id);
BD_ADDR remote_bda,
UINT16 handle);
/*******************************************************************************
**
@ -1022,14 +973,14 @@ extern tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF c
**
** Parameters client_if - client interface.
** remote_bda - target GATT server.
** p_char_id - pointer to a GATT characteristic ID.
** handle - GATT characteristic handle.
**
** Returns OK if deregistration succeed, otherwise failed.
**
*******************************************************************************/
extern tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if,
BD_ADDR remote_bda,
tBTA_GATTC_CHAR_ID *p_char_id);
BD_ADDR remote_bda,
UINT16 handle);
/*******************************************************************************
**
@ -1038,16 +989,16 @@ extern tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF
** Description This function is called to prepare write a characteristic value.
**
** Parameters conn_id - connection ID.
** p_char_id - GATT characteritic ID of the service.
** handle - GATT characteritic handle.
** offset - offset of the write value.
** len: length of the data to be written.
** len - length of the data to be written.
** p_value - the value to be written.
**
** Returns None
**
*******************************************************************************/
extern void BTA_GATTC_PrepareWrite (UINT16 conn_id,
tBTA_GATTC_CHAR_ID *p_char_id,
UINT16 handle,
UINT16 offset,
UINT16 len,
UINT8 *p_value,
@ -1069,7 +1020,7 @@ extern void BTA_GATTC_PrepareWrite (UINT16 conn_id,
**
*******************************************************************************/
extern void BTA_GATTC_PrepareWriteCharDescr (UINT16 conn_id,
tBTA_GATTC_CHAR_DESCR_ID *p_char_descr_id,
UINT16 handle,
UINT16 offset,
tBTA_GATT_UNFMT *p_data,
tBTA_GATT_AUTH_REQ auth_req);
@ -1360,9 +1311,9 @@ extern void BTA_GATTS_StopService(UINT16 service_id);
**
*******************************************************************************/
extern void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id,
UINT16 data_len,
UINT8 *p_data,
BOOLEAN need_confirm);
UINT16 data_len,
UINT8 *p_data,
BOOLEAN need_confirm);
/*******************************************************************************
**

View file

@ -58,12 +58,6 @@ enum {
BTA_GATTC_OP_CMPL_EVT,
BTA_GATTC_INT_DISCONN_EVT,
/* for cache loading/saving */
BTA_GATTC_START_CACHE_EVT,
BTA_GATTC_CI_CACHE_OPEN_EVT,
BTA_GATTC_CI_CACHE_LOAD_EVT,
BTA_GATTC_CI_CACHE_SAVE_EVT,
BTA_GATTC_INT_START_IF_EVT,
BTA_GATTC_API_REG_EVT,
BTA_GATTC_API_DEREG_EVT,
@ -74,6 +68,8 @@ enum {
};
typedef UINT16 tBTA_GATTC_INT_EVT;
#define BTA_GATTC_SERVICE_CHANGED_LEN 4
/* max client application GATTC can support */
#ifndef BTA_GATTC_CL_MAX
#define BTA_GATTC_CL_MAX 3 // 32
@ -95,7 +91,7 @@ typedef UINT16 tBTA_GATTC_INT_EVT;
#endif
#define BTA_GATTC_WRITE_PREPARE GATT_WRITE_PREPARE
#define BTA_GATTC_INVALID_HANDLE 0
/* internal strucutre for GATTC register API */
typedef struct {
@ -125,17 +121,15 @@ typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
typedef struct {
BT_HDR hdr;
tBTA_GATT_AUTH_REQ auth_req;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
tBTA_GATT_ID *p_descr_type;
UINT16 handle;
tBTA_GATTC_EVT cmpl_evt;
} tBTA_GATTC_API_READ;
typedef struct {
BT_HDR hdr;
tBTA_GATT_AUTH_REQ auth_req;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
tBTA_GATT_ID *p_descr_type;
UINT16 handle;
tBTA_GATTC_EVT cmpl_evt;
tBTA_GATTC_WRITE_TYPE write_type;
UINT16 offset;
UINT16 len;
@ -149,8 +143,7 @@ typedef struct {
typedef struct {
BT_HDR hdr;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
UINT16 handle;
} tBTA_GATTC_API_CONFIRM;
typedef tGATT_CL_COMPLETE tBTA_GATTC_CMPL;
@ -171,8 +164,8 @@ typedef struct {
BT_HDR hdr;
tBTA_GATT_AUTH_REQ auth_req;
UINT8 num_attr;
tBTA_GATTC_ATTR_ID *p_id_list;
} tBTA_GATTC_API_READ_MULTI;
UINT16 handles[GATT_MAX_READ_MULTI_HANDLES];
}tBTA_GATTC_API_READ_MULTI;
typedef struct {
BT_HDR hdr;
@ -215,9 +208,6 @@ typedef union {
tBTA_GATTC_API_READ_MULTI api_read_multi;
tBTA_GATTC_API_CFG_MTU api_mtu;
tBTA_GATTC_OP_CMPL op_cmpl;
tBTA_GATTC_CI_EVT ci_open;
tBTA_GATTC_CI_EVT ci_save;
tBTA_GATTC_CI_LOAD ci_load;
tBTA_GATTC_INT_CONN int_conn;
tBTA_GATTC_ENC_CMPL enc_cmpl;
@ -230,43 +220,13 @@ typedef union {
/* GATT server cache on the client */
typedef union {
UINT8 uuid128[LEN_UUID_128];
UINT16 uuid16;
} tBTA_GATTC_UUID;
typedef struct gattc_attr_cache {
tBTA_GATTC_UUID *p_uuid;
struct gattc_attr_cache *p_next;
UINT16 uuid_len;
UINT16 attr_handle;
UINT8 inst_id;
tBTA_GATT_CHAR_PROP property; /* if characteristic, it is char property;
if included service, flag primary,
if descriptor, not used */
tBTA_GATTC_ATTR_TYPE attr_type;
// btla-specific ++
} __attribute__((packed)) tBTA_GATTC_CACHE_ATTR;
// btla-specific --
typedef struct gattc_svc_cache {
tBTA_GATT_SRVC_ID service_uuid;
tBTA_GATTC_CACHE_ATTR *p_attr;
tBTA_GATTC_CACHE_ATTR *p_last_attr;
UINT16 s_handle;
UINT16 e_handle;
struct gattc_svc_cache *p_next;
tBTA_GATTC_CACHE_ATTR *p_cur_char;
// btla-specific ++
} __attribute__((packed)) tBTA_GATTC_CACHE;
// btla-specific --
typedef struct {
tBT_UUID uuid;
UINT16 s_handle;
UINT16 e_handle;
// this field is set only for characteristic
UINT16 char_decl_handle;
BOOLEAN is_primary;
UINT8 srvc_inst_id;
tBTA_GATT_CHAR_PROP property;
} tBTA_GATTC_ATTR_REC;
@ -299,11 +259,7 @@ typedef struct {
UINT8 state;
tBTA_GATTC_CACHE *p_srvc_cache;
tBTA_GATTC_CACHE *p_cur_srvc;
fixed_queue_t *cache_buffer; /* buffer queue used for storing the cache data */
UINT8 *p_free; /* starting point to next available byte */
UINT16 free_byte; /* number of available bytes in server cache buffer */
list_t *p_srvc_cache; /* list of tBTA_GATTC_SERVICE */
UINT8 update_count; /* indication received */
UINT8 num_clcb; /* number of associated CLCB */
@ -314,7 +270,7 @@ typedef struct {
UINT8 next_avail_idx;
UINT8 total_srvc;
UINT8 total_char;
UINT16 total_attr;
UINT8 srvc_hdl_chg; /* service handle change indication pending */
UINT16 attr_index; /* cahce NV saving/loading attribute index */
@ -328,8 +284,8 @@ typedef struct {
typedef struct {
BOOLEAN in_use;
BD_ADDR remote_bda;
tBTA_GATTC_CHAR_ID char_id;
} tBTA_GATTC_NOTIF_REG;
UINT16 handle;
}tBTA_GATTC_NOTIF_REG;
typedef struct {
tBTA_GATTC_CBACK *p_cback;
@ -403,11 +359,7 @@ typedef struct {
tBTA_GATTC_CLCB clcb[BTA_GATTC_CLCB_MAX];
tBTA_GATTC_SERV known_server[BTA_GATTC_KNOWN_SR_MAX];
#if (SDP_INCLUDED == TRUE)
tSDP_DISCOVERY_DB *p_sdp_db;
#endif ///SDP_INCLUDED == TRUE
UINT16 sdp_conn_id;
} tBTA_GATTC_CB;
}tBTA_GATTC_CB;
typedef enum {
SERVICE_CHANGE_CCC_WRITTEN_SUCCESS = 0,
@ -474,10 +426,7 @@ extern void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_ci_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_msg);
extern void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg);
@ -509,20 +458,13 @@ extern tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg);
extern BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
extern UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service_id, tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_uuid);
extern BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SRVC_ID *service_id, tBTA_GATT_ID *char_id, tBTA_GATT_ID *p_type);
extern BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise);
extern void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid);
extern BOOLEAN bta_gattc_uuid_compare (const tBT_UUID *p_src, const tBT_UUID *p_tar, BOOLEAN is_precise);
extern BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb, tBTA_GATTC_NOTIFY *p_notify);
extern tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID *p_descr_uuid, tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value);
extern BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda, BOOLEAN add, BOOLEAN is_listen);
extern BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role);
extern UINT8 bta_gattc_num_reg_app(void);
extern void bta_gattc_clear_notif_registration(UINT16 conn_id);
extern tBTA_GATTC_SERV *bta_gattc_find_srvr_cache(BD_ADDR bda);
extern BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar);
extern BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar);
extern void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src);
extern void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id, UINT16 start_handle, UINT16 end_handle);
extern tBTA_GATTC_SERV * bta_gattc_find_srvr_cache(BD_ADDR bda);
/* discovery functions */
extern void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data);
@ -530,17 +472,41 @@ extern void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type
extern tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
extern tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
extern void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid);
extern tBTA_GATT_STATUS bta_gattc_query_cache(UINT16 conn_id, UINT8 query_type, tBTA_GATT_SRVC_ID *p_srvc_id,
tBTA_GATT_ID *p_start_rec, tBT_UUID *p_uuid_cond,
tBTA_GATT_ID *p_output, void *p_param);
extern tBTA_GATT_STATUS bta_gattc_init_cache(tBTA_GATTC_SERV *p_srvc_cb);
extern void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srcv, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index);
extern BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id);
extern const list_t* bta_gattc_get_services(UINT16 conn_id);
extern const tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle(UINT16 conn_id, UINT16 handle);
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle);
extern tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic(UINT16 conn_id, UINT16 handle);
extern tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor(UINT16 conn_id, UINT16 handle);
extern void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, int *count);
extern void bta_gattc_get_db_size_with_type_handle(UINT16 conn_id, bt_gatt_db_attribute_type_t type,
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, int *count);
extern void bta_gattc_get_service_with_uuid(UINT16 conn_id, tBT_UUID *svc_uuid,
btgatt_db_element_t **svc_db,
int *count);
extern void bta_gattc_get_db_with_opration(UINT16 conn_id,
bt_gatt_get_db_op_t op,
UINT16 char_handle,
tBT_UUID *incl_uuid,
tBT_UUID *char_uuid,
tBT_UUID *descr_uuid,
UINT16 start_handle, UINT16 end_handle,
btgatt_db_element_t **char_db,
int *count);
extern void bta_gattc_get_gatt_db(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, btgatt_db_element_t **db, int *count);
extern tBTA_GATT_STATUS bta_gattc_init_cache(tBTA_GATTC_SERV *p_srvc_cb);
extern void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srcv, UINT16 num_attr, tBTA_GATTC_NV_ATTR *attr);
extern void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id);
extern void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status);
extern tBTA_GATTC_CONN *bta_gattc_conn_alloc(BD_ADDR remote_bda);
extern tBTA_GATTC_CONN *bta_gattc_conn_find(BD_ADDR remote_bda);
extern tBTA_GATTC_CONN *bta_gattc_conn_find_alloc(BD_ADDR remote_bda);
extern BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda);
extern bool bta_gattc_cache_load(tBTA_GATTC_CLCB *p_clcb);
extern void bta_gattc_cache_reset(BD_ADDR server_bda);
#endif /* BTA_GATTC_INT_H */

View file

@ -33,7 +33,7 @@
#include "blufi_int.h"
#include "esp_wifi.h"
//#include "esp_wifi.h"
#if (GATTS_INCLUDED == TRUE)
extern tBLUFI_ENV blufi_env;

View file

@ -174,42 +174,28 @@ uint16_t get_uuid16(tBT_UUID *p_uuid)
return (UINT16) p_uuid->uu.uuid32;
}
}
uint16_t set_read_value(uint8_t *gattc_if, esp_ble_gattc_cb_param_t *p_dest, tBTA_GATTC_READ *p_src)
{
uint16_t descr_type = 0;
uint16_t len = 0;
p_dest->read.status = p_src->status;
p_dest->read.conn_id = BTC_GATT_GET_CONN_ID(p_src->conn_id);
*gattc_if = BTC_GATT_GET_GATT_IF(p_src->conn_id);
bta_to_btc_srvc_id(&p_dest->read.srvc_id, &p_src->srvc_id);
bta_to_btc_gatt_id(&p_dest->read.char_id, &p_src->char_id);
bta_to_btc_gatt_id(&p_dest->read.descr_id, &p_src->descr_type);
p_dest->read.status = p_src->status;
p_dest->read.handle = p_src->handle;
descr_type = get_uuid16(&p_src->descr_type.uuid);
switch (descr_type) {
case GATT_UUID_CHAR_AGG_FORMAT:
/* not supported */
p_dest->read.value_type = GATTC_READ_VALUE_TYPE_AGG_FORMAT;
p_dest->read.value_len = 0;
break;
default:
if (( p_src->status == BTA_GATT_OK ) && (p_src->p_value != NULL)) {
LOG_INFO("%s unformat.len = %d ", __FUNCTION__, p_src->p_value->unformat.len);
p_dest->read.value_len = p_src->p_value->unformat.len;
if ( p_src->p_value->unformat.len > 0 && p_src->p_value->unformat.p_value != NULL ) {
p_dest->read.value = p_src->p_value->unformat.p_value;
}
len += p_src->p_value->unformat.len;
} else {
p_dest->read.value_len = 0;
if (( p_src->status == BTA_GATT_OK ) && (p_src->p_value != NULL))
{
LOG_DEBUG("%s len = %d ", __func__, p_src->p_value->len);
p_dest->read.value_len = p_src->p_value->len;
if ( p_src->p_value->len > 0 && p_src->p_value->p_value != NULL ) {
p_dest->read.value = p_src->p_value->p_value;
}
p_dest->read.value_type = GATTC_READ_VALUE_TYPE_VALUE;
break;
len += p_src->p_value->len;
} else {
p_dest->read.value_len = 0;
}
return len;
}
}

View file

@ -116,7 +116,6 @@ void btc_gattc_arg_deep_free(btc_msg_t *msg)
}
// TODO: to be finished, used in deep-copying data from lower layer
static void btc_gattc_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
tBTA_GATTC *p_dest_data = (tBTA_GATTC *) p_dest;
@ -128,14 +127,39 @@ static void btc_gattc_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
// Allocate buffer for request data if necessary
switch (msg->act) {
default:
break;
case BTA_GATTC_READ_DESCR_EVT:
case BTA_GATTC_READ_CHAR_EVT: {
if (p_src_data->read.p_value && p_src_data->read.p_value->p_value) {
p_dest_data->read.p_value = (tBTA_GATT_UNFMT *)osi_malloc(sizeof(tBTA_GATT_UNFMT) + p_src_data->read.p_value->len);
p_dest_data->read.p_value->p_value = (uint8_t *)(p_dest_data->read.p_value + 1);
if (p_dest_data->read.p_value && p_dest_data->read.p_value->p_value) {
p_dest_data->read.p_value->len = p_src_data->read.p_value->len;
memcpy(p_dest_data->read.p_value->p_value, p_src_data->read.p_value->p_value, p_src_data->read.p_value->len);
} else {
LOG_ERROR("%s %d no mem\n", __func__, msg->act);
}
}
break;
}
default:
break;
}
}
// TODO: to be finished, used to free deep-copied data allocated using btc_gattc_copy_req_data()
static void btc_gattc_free_req_data(btc_msg_t *msg)
{
tBTA_GATTC *arg = (tBTA_GATTC *)(msg->arg);
switch (msg->act) {
case BTA_GATTC_READ_DESCR_EVT:
case BTA_GATTC_READ_CHAR_EVT: {
if (arg->read.p_value) {
osi_free(arg->read.p_value);
}
break;
}
default:
break;
}
return;
}
@ -184,6 +208,74 @@ static void btc_gattc_cfg_mtu(btc_ble_gattc_args_t *arg)
BTA_GATTC_ConfigureMTU (arg->cfg_mtu.conn_id);
}
static esp_gatt_status_t btc_gattc_check_valid_param(int num, uint16_t offset)
{
if (num == 0) {
return ESP_GATT_NOT_FOUND;
} else if (offset >= num) {
return ESP_GATT_INVALID_OFFSET;
}
return ESP_GATT_OK;
}
static void btc_gattc_fill_gatt_db_conversion(uint16_t count, uint16_t num, esp_gatt_db_attr_type_t type,
uint16_t offset, void *result, btgatt_db_element_t *db)
{
tBT_UUID bta_uuid = {0};
uint16_t db_size = (count + offset > num) ? (num - offset) : count;
switch(type) {
case ESP_GATT_DB_PRIMARY_SERVICE:
case ESP_GATT_DB_SECONDARY_SERVICE: {
esp_gattc_service_elem_t *svc_result = (esp_gattc_service_elem_t *)result;
for (int i = 0; i < db_size; i++) {
svc_result->is_primary = (db[offset + i].type == BTGATT_DB_PRIMARY_SERVICE) ? true : false;
svc_result->start_handle = db[offset + i].start_handle;
svc_result->end_handle = db[offset + i].end_handle;
btc128_to_bta_uuid(&bta_uuid, db[offset + i].uuid.uu);
bta_to_btc_uuid(&svc_result->uuid, &bta_uuid);
svc_result++;
}
break;
}
case ESP_GATT_DB_CHARACTERISTIC: {
esp_gattc_char_elem_t *char_result = (esp_gattc_char_elem_t *)result;
for (int i = 0; i < db_size; i++) {
char_result->char_handle = db[offset + i].attribute_handle;
char_result->properties = db[offset + i].properties;
btc128_to_bta_uuid(&bta_uuid, db[offset + i].uuid.uu);
bta_to_btc_uuid(&char_result->uuid, &bta_uuid);
char_result++;
}
break;
}
case ESP_GATT_DB_DESCRIPTOR: {
esp_gattc_descr_elem_t *descr_result = (esp_gattc_descr_elem_t *)result;
for (int i = 0; i < (num - offset); i++) {
descr_result->handle = db[offset + i].attribute_handle;
btc128_to_bta_uuid(&bta_uuid, db[offset + i].uuid.uu);
bta_to_btc_uuid(&descr_result->uuid, &bta_uuid);
descr_result++;
}
break;
}
case ESP_GATT_DB_INCLUDED_SERVICE: {
esp_gattc_incl_svc_elem_t *incl_result = (esp_gattc_incl_svc_elem_t *)result;
for (int i = 0; i < db_size; i++) {
incl_result->handle = db[offset + i].attribute_handle;
incl_result->incl_srvc_s_handle = db[offset + i].start_handle;
btc128_to_bta_uuid(&bta_uuid, db[offset + i].uuid.uu);
bta_to_btc_uuid(&incl_result->uuid, &bta_uuid);
incl_result++;
}
break;
}
default:
LOG_WARN("%s(), Not support type(%d)", __func__, type);
break;
}
}
static void btc_gattc_search_service(btc_ble_gattc_args_t *arg)
{
tBT_UUID srvc_uuid;
@ -196,198 +288,305 @@ static void btc_gattc_search_service(btc_ble_gattc_args_t *arg)
}
}
static void btc_gattc_get_first_char(btc_ble_gattc_args_t *arg)
esp_gatt_status_t btc_ble_gattc_get_service(uint16_t conn_id, esp_bt_uuid_t *svc_uuid,
esp_gattc_service_elem_t *result,
uint16_t *count, uint16_t offset)
{
esp_gatt_id_t char_id;
tBTA_GATT_STATUS status;
tBTA_GATTC_CHAR_ID out_char_id;
tBTA_GATT_CHAR_PROP out_char_prop;
tBTA_GATT_SRVC_ID srvc_id;
esp_ble_gattc_cb_param_t param;
esp_gatt_if_t gattc_if;
esp_gatt_status_t status;
btgatt_db_element_t *db = NULL;
int svc_num = 0;
tBT_UUID *bta_uuid = NULL;
if (svc_uuid) {
bta_uuid = osi_malloc(sizeof(tBT_UUID));
btc_to_bta_uuid(bta_uuid, svc_uuid);
}
BTA_GATTC_GetServiceWithUUID(conn_id, bta_uuid, &db, &svc_num);
btc_to_bta_srvc_id(&srvc_id, &arg->get_first_char.service_id);
status = BTA_GATTC_GetFirstChar(arg->get_first_char.conn_id, &srvc_id, NULL,
&out_char_id, &out_char_prop);
if (status == 0) {
bta_to_btc_gatt_id(&char_id, &out_char_id.char_id);
if ((status = btc_gattc_check_valid_param(svc_num, offset)) != ESP_GATT_OK) {
if (db) {
osi_free(db);
}
if (bta_uuid) {
osi_free(bta_uuid);
}
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)svc_num, ESP_GATT_DB_PRIMARY_SERVICE, offset, (void *)result, db);
}
gattc_if = BTC_GATT_GET_GATT_IF(arg->get_first_char.conn_id);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.get_char.conn_id = BTC_GATT_GET_CONN_ID(arg->get_first_char.conn_id);
param.get_char.status = status;
memcpy(&param.get_char.srvc_id, &arg->get_first_char.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.get_char.char_id, &char_id, sizeof(esp_gatt_id_t));
param.get_char.char_prop = out_char_prop;
btc_gattc_cb_to_app(ESP_GATTC_GET_CHAR_EVT, gattc_if, &param);
*count = svc_num;
//don't forget to free the db buffer after used.
if (db) {
osi_free(db);
}
if (bta_uuid) {
osi_free(bta_uuid);
}
return ESP_GATT_OK;
}
static void btc_gattc_get_next_char(btc_ble_gattc_args_t *arg)
esp_gatt_status_t btc_ble_gattc_get_all_char(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_gattc_char_elem_t *result,
uint16_t *count, uint16_t offset)
{
esp_gatt_id_t char_id;
tBTA_GATT_STATUS status;
tBTA_GATTC_CHAR_ID in_char_id;
tBTA_GATTC_CHAR_ID out_char_id;
tBTA_GATT_CHAR_PROP out_char_prop;
esp_ble_gattc_cb_param_t param;
esp_gatt_if_t gattc_if;
esp_gatt_status_t status;
btgatt_db_element_t *db = NULL;
int char_num = 0;
BTA_GATTC_GetAllChar(conn_id, start_handle, end_handle, &db, &char_num);
btc_to_bta_srvc_id(&in_char_id.srvc_id, &arg->get_next_char.service_id);
btc_to_bta_gatt_id(&in_char_id.char_id, &arg->get_next_char.char_id);
status = BTA_GATTC_GetNextChar(arg->get_next_char.conn_id, &in_char_id, NULL,
&out_char_id, &out_char_prop);
if (status == 0) {
bta_to_btc_gatt_id(&char_id, &out_char_id.char_id);
if ((status = btc_gattc_check_valid_param(char_num, offset)) != ESP_GATT_OK) {
if (db) {
osi_free(db);
}
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, offset, (void *)result, db);
}
gattc_if = BTC_GATT_GET_GATT_IF(arg->get_next_char.conn_id);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.get_char.conn_id = BTC_GATT_GET_CONN_ID(arg->get_next_char.conn_id);
param.get_char.status = status;
memcpy(&param.get_char.srvc_id, &arg->get_next_char.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.get_char.char_id, &char_id, sizeof(esp_gatt_id_t));
param.get_char.char_prop = out_char_prop;
btc_gattc_cb_to_app(ESP_GATTC_GET_CHAR_EVT, gattc_if, &param);
*count = char_num;
//don't forget to free the db buffer after used.
if (db) {
osi_free(db);
}
return ESP_GATT_OK;
}
static void btc_gattc_get_first_descr(btc_ble_gattc_args_t *arg)
esp_gatt_status_t btc_ble_gattc_get_all_descr(uint16_t conn_id,
uint16_t char_handle,
esp_gattc_descr_elem_t *result,
uint16_t *count, uint16_t offset)
{
esp_gatt_id_t descr_id;
tBTA_GATT_STATUS status;
tBTA_GATTC_CHAR_ID in_char_id;
tBTA_GATTC_CHAR_DESCR_ID out_char_descr_id;
esp_ble_gattc_cb_param_t param;
esp_gatt_if_t gattc_if;
esp_gatt_status_t status;
btgatt_db_element_t *db = NULL;
int descr_num = 0;
BTA_GATTC_GetAllDescriptor(conn_id, char_handle, &db, &descr_num);
btc_to_bta_srvc_id(&in_char_id.srvc_id, &arg->get_first_descr.service_id);
btc_to_bta_gatt_id(&in_char_id.char_id, &arg->get_first_descr.char_id);
status = BTA_GATTC_GetFirstCharDescr(arg->get_first_descr.conn_id, &in_char_id, NULL,
&out_char_descr_id);
if (status == 0) {
bta_to_btc_gatt_id(&descr_id, &out_char_descr_id.descr_id);
if ((status = btc_gattc_check_valid_param(descr_num, offset)) != ESP_GATT_OK) {
if (db) {
osi_free(db);
}
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, offset, (void *)result, db);
}
gattc_if = BTC_GATT_GET_GATT_IF(arg->get_first_descr.conn_id);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.get_descr.conn_id = BTC_GATT_GET_CONN_ID(arg->get_first_descr.conn_id);
param.get_descr.status = status;
memcpy(&param.get_descr.srvc_id, &arg->get_first_descr.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.get_descr.char_id, &arg->get_first_descr.char_id, sizeof(esp_gatt_id_t));
memcpy(&param.get_descr.descr_id, &descr_id, sizeof(esp_gatt_id_t));
btc_gattc_cb_to_app(ESP_GATTC_GET_DESCR_EVT, gattc_if, &param);
*count = descr_num;
//don't forget to free the db buffer after used.
if (db) {
osi_free(db);
}
return ESP_GATT_OK;
}
static void btc_gattc_get_next_descr(btc_ble_gattc_args_t *arg)
esp_gatt_status_t btc_ble_gattc_get_char_by_uuid(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_gattc_char_elem_t *result,
uint16_t *count)
{
esp_gatt_id_t descr_id;
tBTA_GATT_STATUS status;
tBTA_GATTC_CHAR_DESCR_ID in_char_descr_id;
tBTA_GATTC_CHAR_DESCR_ID out_char_descr_id;
esp_ble_gattc_cb_param_t param;
esp_gatt_if_t gattc_if;
esp_gatt_status_t status;
btgatt_db_element_t *db = NULL;
int char_num = 0;
tBT_UUID bta_uuid = {0};
btc_to_bta_uuid(&bta_uuid, &char_uuid);
BTA_GATTC_GetCharByUUID(conn_id, start_handle, end_handle, bta_uuid, &db, &char_num);
btc_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &arg->get_next_descr.service_id);
btc_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &arg->get_next_descr.char_id);
btc_to_bta_gatt_id(&in_char_descr_id.descr_id, &arg->get_next_descr.descr_id);
status = BTA_GATTC_GetNextCharDescr(arg->get_next_descr.conn_id, &in_char_descr_id
, NULL, &out_char_descr_id);
if (status == 0) {
bta_to_btc_gatt_id(&descr_id, &out_char_descr_id.descr_id);
if ((status = btc_gattc_check_valid_param(char_num, 0)) != ESP_GATT_OK) {
if (db) {
osi_free(db);
}
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, 0, (void *)result, db);
}
gattc_if = BTC_GATT_GET_GATT_IF(arg->get_next_descr.conn_id);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.get_descr.conn_id = BTC_GATT_GET_CONN_ID(arg->get_next_descr.conn_id);
param.get_descr.status = status;
memcpy(&param.get_descr.srvc_id, &arg->get_next_descr.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.get_descr.char_id, &arg->get_next_descr.char_id, sizeof(esp_gatt_id_t));
memcpy(&param.get_descr.descr_id, &descr_id, sizeof(esp_gatt_id_t));
btc_gattc_cb_to_app(ESP_GATTC_GET_DESCR_EVT, gattc_if, &param);
*count = char_num;
//don't forget to free the db buffer after used.
if (db) {
osi_free(db);
}
return ESP_GATT_OK;
}
static void btc_gattc_get_first_incl_service(btc_ble_gattc_args_t *arg)
esp_gatt_status_t btc_ble_gattc_get_descr_by_uuid(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count)
{
esp_gatt_srvc_id_t incl_srvc_id;
tBTA_GATT_STATUS status;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATTC_INCL_SVC_ID out_incl_svc_id;
esp_ble_gattc_cb_param_t param;
esp_gatt_if_t gattc_if;
esp_gatt_status_t status;
btgatt_db_element_t *db = NULL;
int descr_num = 0;
tBT_UUID bta_char_uuid = {0};
tBT_UUID bta_descr_uuid = {0};
btc_to_bta_uuid(&bta_char_uuid, &char_uuid);
btc_to_bta_uuid(&bta_descr_uuid, &descr_uuid);
BTA_GATTC_GetDescrByUUID(conn_id, start_handle, end_handle,
bta_char_uuid, bta_descr_uuid, &db, &descr_num);
btc_to_bta_srvc_id(&srvc_id, &arg->get_first_incl_srvc.service_id);
status = BTA_GATTC_GetFirstIncludedService(arg->get_first_incl_srvc.conn_id, &srvc_id,
NULL, &out_incl_svc_id);
bta_to_btc_srvc_id(&incl_srvc_id, &out_incl_svc_id.incl_svc_id);
gattc_if = BTC_GATT_GET_GATT_IF(arg->get_first_incl_srvc.conn_id);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.get_incl_srvc.conn_id = BTC_GATT_GET_CONN_ID(arg->get_first_incl_srvc.conn_id);
param.get_incl_srvc.status = status;
memcpy(&param.get_incl_srvc.srvc_id, &arg->get_first_incl_srvc.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.get_incl_srvc.incl_srvc_id, &incl_srvc_id, sizeof(esp_gatt_srvc_id_t));
btc_gattc_cb_to_app(ESP_GATTC_GET_INCL_SRVC_EVT, gattc_if, &param);
if ((status = btc_gattc_check_valid_param(descr_num, 0)) != ESP_GATT_OK) {
if (db) {
osi_free(db);
}
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db);
}
*count = descr_num;
//don't forget to free the db buffer after used.
if (db) {
osi_free(db);
}
return ESP_GATT_OK;
}
static void btc_gattc_get_next_incl_service(btc_ble_gattc_args_t *arg)
esp_gatt_status_t btc_ble_gattc_get_descr_by_char_handle(uint16_t conn_id,
uint16_t char_handle,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count)
{
esp_gatt_srvc_id_t incl_srvc_id;
tBTA_GATT_STATUS status;
tBTA_GATTC_INCL_SVC_ID in_incl_svc_id;
tBTA_GATTC_INCL_SVC_ID out_incl_svc_id;
esp_ble_gattc_cb_param_t param;
esp_gatt_if_t gattc_if;
esp_gatt_status_t status;
btgatt_db_element_t *db = NULL;
int descr_num = 0;
tBT_UUID bta_descr_uuid = {0};
btc_to_bta_uuid(&bta_descr_uuid, &descr_uuid);
BTA_GATTC_GetDescrByCharHandle(conn_id, char_handle, bta_descr_uuid, &db, &descr_num);
btc_to_bta_srvc_id(&in_incl_svc_id.srvc_id, &arg->get_next_incl_srvc.service_id);
btc_to_bta_srvc_id(&in_incl_svc_id.incl_svc_id, &arg->get_next_incl_srvc.start_service_id);
if ((status = btc_gattc_check_valid_param(descr_num, 0)) != ESP_GATT_OK) {
if (db) {
osi_free(db);
}
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db);
}
status = BTA_GATTC_GetNextIncludedService(arg->get_next_incl_srvc.conn_id, &in_incl_svc_id,
NULL, &out_incl_svc_id);
*count = descr_num;
//don't forget to free the db buffer after used.
if (db) {
osi_free(db);
}
return ESP_GATT_OK;
}
bta_to_btc_srvc_id(&incl_srvc_id, &out_incl_svc_id.incl_svc_id);
esp_gatt_status_t btc_ble_gattc_get_include_service(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t *incl_uuid,
esp_gattc_incl_svc_elem_t *result,
uint16_t *count)
{
esp_gatt_status_t status;
btgatt_db_element_t *db = NULL;
int incl_num = 0;
tBT_UUID bta_uuid = {0};
gattc_if = BTC_GATT_GET_GATT_IF(arg->get_next_incl_srvc.conn_id);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.get_incl_srvc.conn_id = BTC_GATT_GET_CONN_ID(arg->get_next_incl_srvc.conn_id);
param.get_incl_srvc.status = status;
memcpy(&param.get_incl_srvc.srvc_id, &arg->get_next_incl_srvc.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.get_incl_srvc.incl_srvc_id, &incl_srvc_id, sizeof(esp_gatt_srvc_id_t));
btc_gattc_cb_to_app(ESP_GATTC_GET_INCL_SRVC_EVT, gattc_if, &param);
if (incl_uuid != NULL) {
btc_to_bta_uuid(&bta_uuid, incl_uuid);
BTA_GATTC_GetIncludeService(conn_id, start_handle, end_handle, &bta_uuid, &db, &incl_num);
} else {
BTA_GATTC_GetIncludeService(conn_id, start_handle, end_handle, NULL, &db, &incl_num);
}
if ((status = btc_gattc_check_valid_param(incl_num, 0)) != ESP_GATT_OK) {
if (db) {
osi_free(db);
}
return status;
}else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)incl_num, ESP_GATT_DB_INCLUDED_SERVICE, 0, (void *)result, db);
}
*count = incl_num;
//don't forget to free the db buffer after used.
if (db) {
osi_free(db);
}
return ESP_GATT_OK;
}
esp_gatt_status_t btc_ble_gattc_get_attr_count(uint16_t conn_id,
esp_gatt_db_attr_type_t type,
uint16_t start_handle,
uint16_t end_handle,
uint16_t char_handle,
uint16_t *count)
{
if (type == ESP_GATT_DB_ALL) {
BTA_GATTC_GetDBSize(conn_id, start_handle, end_handle, (int *)count);
} else {
BTA_GATTC_GetDBSizeByType(conn_id, type, start_handle, end_handle, char_handle, (int *)count);
}
return ESP_GATT_OK;
}
esp_gatt_status_t btc_ble_gattc_get_db(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
esp_gattc_db_elem_t *db, uint16_t *count)
{
btgatt_db_element_t *get_db = NULL;
int num = 0;
tBT_UUID bta_uuid;
uint16_t db_size = 0;
BTA_GATTC_GetGattDb(conn_id, start_handle, end_handle, &get_db, &num);
if (num == 0) {
if (get_db) {
osi_free(get_db);
}
return ESP_GATT_NOT_FOUND;
}
db_size = (*count > num) ? num : (*count);
for (int i = 0; i < db_size; i++) {
db[i].type = get_db[i].type;
db[i].attribute_handle = get_db[i].id;
db[i].start_handle = get_db[i].start_handle;
db[i].end_handle = get_db[i].end_handle;
btc128_to_bta_uuid(&bta_uuid, get_db[i].uuid.uu);
bta_to_btc_uuid(&db[i].uuid, &bta_uuid);
}
*count = num;
//don't forget to free the db buffer after used.
if (get_db) {
osi_free(get_db);
}
return ESP_GATT_OK;
}
static void btc_gattc_read_char(btc_ble_gattc_args_t *arg)
{
tBTA_GATTC_CHAR_ID in_char_id;
btc_to_bta_srvc_id(&in_char_id.srvc_id, &arg->read_char.service_id);
btc_to_bta_gatt_id(&in_char_id.char_id, &arg->read_char.char_id);
BTA_GATTC_ReadCharacteristic(arg->read_char.conn_id, &in_char_id, arg->read_char.auth_req);
BTA_GATTC_ReadCharacteristic(arg->read_char.conn_id, arg->read_char.handle, arg->read_char.auth_req);
}
static void btc_gattc_read_multiple_char(btc_ble_gattc_args_t *arg)
{
tBTA_GATTC_MULTI bta_multi;
bta_multi.num_attr = arg->read_multiple.num_attr;
memcpy(bta_multi.handles, arg->read_multiple.handles, BTA_GATTC_MULTI_MAX);
BTA_GATTC_ReadMultiple(arg->read_multiple.conn_id, &bta_multi, arg->read_multiple.auth_req);
}
static void btc_gattc_read_char_descr(btc_ble_gattc_args_t *arg)
{
tBTA_GATTC_CHAR_DESCR_ID in_char_descr_id;
btc_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &arg->read_descr.service_id);
btc_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &arg->read_descr.char_id);
btc_to_bta_gatt_id(&in_char_descr_id.descr_id, &arg->read_descr.descr_id);
BTA_GATTC_ReadCharDescr(arg->read_descr.conn_id, &in_char_descr_id, arg->read_descr.auth_req);
BTA_GATTC_ReadCharDescr(arg->read_descr.conn_id, arg->read_descr.handle, arg->read_descr.auth_req);
}
static void btc_gattc_write_char(btc_ble_gattc_args_t *arg)
{
tBTA_GATTC_CHAR_ID in_char_id;
btc_to_bta_srvc_id(&in_char_id.srvc_id, &arg->write_char.service_id);
btc_to_bta_gatt_id(&in_char_id.char_id, &arg->write_char.char_id);
BTA_GATTC_WriteCharValue(arg->write_char.conn_id, &in_char_id,
BTA_GATTC_WriteCharValue(arg->write_char.conn_id,
arg->write_char.handle,
arg->write_char.write_type,
arg->write_char.value_len,
arg->write_char.value,
@ -396,28 +595,21 @@ static void btc_gattc_write_char(btc_ble_gattc_args_t *arg)
static void btc_gattc_write_char_descr(btc_ble_gattc_args_t *arg)
{
tBTA_GATTC_CHAR_DESCR_ID in_char_descr_id;
tBTA_GATT_UNFMT descr_val;
btc_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &arg->write_descr.service_id);
btc_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &arg->write_descr.char_id);
btc_to_bta_gatt_id(&in_char_descr_id.descr_id, &arg->write_descr.descr_id);
descr_val.len = arg->write_descr.value_len;
descr_val.p_value = arg->write_descr.value;
BTA_GATTC_WriteCharDescr(arg->write_descr.conn_id, &in_char_descr_id,
BTA_GATTC_WriteCharDescr(arg->write_descr.conn_id,
arg->write_descr.handle,
arg->write_descr.write_type, &descr_val,
arg->write_descr.auth_req);
}
static void btc_gattc_prepare_write(btc_ble_gattc_args_t *arg)
{
tBTA_GATTC_CHAR_ID in_char_id;
btc_to_bta_srvc_id(&in_char_id.srvc_id, &arg->prep_write.service_id);
btc_to_bta_gatt_id(&in_char_id.char_id, &arg->prep_write.char_id);
BTA_GATTC_PrepareWrite(arg->prep_write.conn_id,
&in_char_id,
arg->prep_write.handle,
arg->prep_write.offset,
arg->prep_write.value_len,
arg->prep_write.value,
@ -425,16 +617,12 @@ static void btc_gattc_prepare_write(btc_ble_gattc_args_t *arg)
}
static void btc_gattc_prepare_write_char_descr(btc_ble_gattc_args_t *arg)
{
tBTA_GATTC_CHAR_DESCR_ID in_char_descr_id;
tBTA_GATT_UNFMT descr_val;
btc_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &arg->prep_write_descr.service_id);
btc_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &arg->prep_write_descr.char_id);
btc_to_bta_gatt_id(&in_char_descr_id.descr_id, &arg->prep_write_descr.descr_id);
descr_val.len = arg->prep_write_descr.value_len;
descr_val.p_value = arg->prep_write_descr.value;
BTA_GATTC_PrepareWriteCharDescr(arg->prep_write_descr.conn_id,
&in_char_descr_id,
arg->prep_write_descr.handle,
arg->prep_write_descr.offset,
&descr_val,
arg->prep_write_descr.auth_req);
@ -448,40 +636,30 @@ static void btc_gattc_execute_wrtie(btc_ble_gattc_args_t *arg)
static void btc_gattc_reg_for_notify(btc_ble_gattc_args_t *arg)
{
tBTA_GATT_STATUS status;
tBTA_GATTC_CHAR_ID in_char_id;
esp_ble_gattc_cb_param_t param;
btc_to_bta_srvc_id(&in_char_id.srvc_id, &arg->reg_for_notify.service_id);
btc_to_bta_gatt_id(&in_char_id.char_id, &arg->reg_for_notify.char_id);
status = BTA_GATTC_RegisterForNotifications(arg->reg_for_notify.gattc_if,
arg->reg_for_notify.remote_bda,
&in_char_id);
arg->reg_for_notify.handle);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.reg_for_notify.status = status;
memcpy(&param.reg_for_notify.srvc_id, &arg->reg_for_notify.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.reg_for_notify.char_id, &arg->reg_for_notify.char_id, sizeof(esp_gatt_id_t));
param.reg_for_notify.handle = arg->reg_for_notify.handle;
btc_gattc_cb_to_app(ESP_GATTC_REG_FOR_NOTIFY_EVT, arg->reg_for_notify.gattc_if, &param);
}
static void btc_gattc_unreg_for_notify(btc_ble_gattc_args_t *arg)
{
tBTA_GATT_STATUS status;
tBTA_GATTC_CHAR_ID in_char_id;
esp_ble_gattc_cb_param_t param;
btc_to_bta_srvc_id(&in_char_id.srvc_id, &arg->unreg_for_notify.service_id);
btc_to_bta_gatt_id(&in_char_id.char_id, &arg->unreg_for_notify.char_id);
status = BTA_GATTC_DeregisterForNotifications(arg->unreg_for_notify.gattc_if,
arg->unreg_for_notify.remote_bda,
&in_char_id);
arg->unreg_for_notify.handle);
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
param.unreg_for_notify.status = status;
memcpy(&param.unreg_for_notify.srvc_id, &arg->unreg_for_notify.service_id, sizeof(esp_gatt_srvc_id_t));
memcpy(&param.unreg_for_notify.char_id, &arg->unreg_for_notify.char_id, sizeof(esp_gatt_id_t));
param.unreg_for_notify.handle = arg->unreg_for_notify.handle;
btc_gattc_cb_to_app(ESP_GATTC_UNREG_FOR_NOTIFY_EVT, arg->unreg_for_notify.gattc_if, &param);
}
@ -490,6 +668,7 @@ void btc_gattc_call_handler(btc_msg_t *msg)
btc_ble_gattc_args_t *arg = (btc_ble_gattc_args_t *)(msg->arg);
switch (msg->act) {
case BTC_GATTC_ACT_APP_REGISTER:
LOG_ERROR("%s()", __func__);
btc_gattc_app_register(arg);
break;
case BTC_GATTC_ACT_APP_UNREGISTER:
@ -507,27 +686,12 @@ void btc_gattc_call_handler(btc_msg_t *msg)
case BTC_GATTC_ACT_SEARCH_SERVICE:
btc_gattc_search_service(arg);
break;
case BTC_GATTC_ACT_GET_FIRST_CHAR:
btc_gattc_get_first_char(arg);
break;
case BTC_GATTC_ACT_GET_NEXT_CHAR:
btc_gattc_get_next_char(arg);
break;
case BTC_GATTC_ACT_GET_FIRST_DESCR:
btc_gattc_get_first_descr(arg);
break;
case BTC_GATTC_ACT_GET_NEXT_DESCR:
btc_gattc_get_next_descr(arg);
break;
case BTC_GATTC_ACT_GET_FIRST_INCL_SERVICE:
btc_gattc_get_first_incl_service(arg);
break;
case BTC_GATTC_ACT_GET_NEXT_INCL_SERVICE:
btc_gattc_get_next_incl_service(arg);
break;
case BTC_GATTC_ACT_READ_CHAR:
btc_gattc_read_char(arg);
break;
case BTC_GATTC_ACT_READ_MULTIPLE_CHAR:
btc_gattc_read_multiple_char(arg);
break;
case BTC_GATTC_ACT_READ_CHAR_DESCR:
btc_gattc_read_char_descr(arg);
break;
@ -566,8 +730,8 @@ void btc_gattc_call_handler(btc_msg_t *msg)
void btc_gattc_cb_handler(btc_msg_t *msg)
{
tBTA_GATTC *arg = (tBTA_GATTC *)(msg->arg);
esp_gatt_if_t gattc_if;
esp_ble_gattc_cb_param_t param;
esp_gatt_if_t gattc_if = 0;
esp_ble_gattc_cb_param_t param = {0};
memset(&param, 0, sizeof(esp_ble_gattc_cb_param_t));
@ -602,8 +766,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
gattc_if = BTC_GATT_GET_GATT_IF(write->conn_id);
param.write.conn_id = BTC_GATT_GET_CONN_ID(write->conn_id);
param.write.status = write->status;
bta_to_btc_srvc_id(&param.write.srvc_id, &write->srvc_id);
bta_to_btc_gatt_id(&param.write.char_id, &write->char_id);
param.write.handle = write->handle;
btc_gattc_cb_to_app(ret_evt, gattc_if, &param);
break;
}
@ -632,7 +795,9 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
gattc_if = BTC_GATT_GET_GATT_IF(srvc_res->conn_id);
param.search_res.conn_id = BTC_GATT_GET_CONN_ID(srvc_res->conn_id);
bta_to_btc_srvc_id(&param.search_res.srvc_id, &srvc_res->service_uuid);
param.search_res.start_handle = srvc_res->start_handle;
param.search_res.end_handle = srvc_res->end_handle;
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;
}
@ -647,9 +812,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
gattc_if = BTC_GATT_GET_GATT_IF(write->conn_id);
param.write.conn_id = BTC_GATT_GET_CONN_ID(write->conn_id);
param.write.status = write->status;
bta_to_btc_srvc_id(&param.write.srvc_id, &write->srvc_id);
bta_to_btc_gatt_id(&param.write.char_id, &write->char_id);
bta_to_btc_gatt_id(&param.write.descr_id, &write->descr_type);
param.write.handle = write->handle;
btc_gattc_cb_to_app(ESP_GATTC_WRITE_DESCR_EVT, gattc_if, &param);
break;
}
@ -659,16 +822,14 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
gattc_if = BTC_GATT_GET_GATT_IF(notify->conn_id);
param.notify.conn_id = BTC_GATT_GET_CONN_ID(notify->conn_id);
memcpy(param.notify.remote_bda, notify->bda, sizeof(esp_bd_addr_t));
bta_to_btc_srvc_id(&param.notify.srvc_id, &notify->char_id.srvc_id);
bta_to_btc_gatt_id(&param.notify.char_id, &notify->char_id.char_id);
bta_to_btc_gatt_id(&param.notify.descr_id, &notify->descr_type);
param.notify.handle = notify->handle;
param.notify.is_notify = (notify->is_notify == TRUE) ? true : false;
param.notify.value_len = (notify->len > ESP_GATT_MAX_ATTR_LEN) ? \
ESP_GATT_MAX_ATTR_LEN : notify->len;
param.notify.value = notify->value;
if (notify->is_notify == FALSE) {
BTA_GATTC_SendIndConfirm(notify->conn_id, &notify->char_id);
BTA_GATTC_SendIndConfirm(notify->conn_id, notify->handle);
}
btc_gattc_cb_to_app(ESP_GATTC_NOTIFY_EVT, gattc_if, &param);
@ -750,7 +911,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
break;
}
default:
LOG_ERROR("%s: Unhandled event (%d)!", __FUNCTION__, msg->act);
LOG_DEBUG("%s: Unhandled event (%d)!", __FUNCTION__, msg->act);
break;
}

View file

@ -27,13 +27,8 @@ typedef enum {
BTC_GATTC_ACT_CLOSE,
BTC_GATTC_ACT_CFG_MTU,
BTC_GATTC_ACT_SEARCH_SERVICE,
BTC_GATTC_ACT_GET_FIRST_CHAR,
BTC_GATTC_ACT_GET_NEXT_CHAR,
BTC_GATTC_ACT_GET_FIRST_DESCR,
BTC_GATTC_ACT_GET_NEXT_DESCR,
BTC_GATTC_ACT_GET_FIRST_INCL_SERVICE,
BTC_GATTC_ACT_GET_NEXT_INCL_SERVICE,
BTC_GATTC_ACT_READ_CHAR,
BTC_GATTC_ACT_READ_MULTIPLE_CHAR,
BTC_GATTC_ACT_READ_CHAR_DESCR,
BTC_GATTC_ACT_WRITE_CHAR,
BTC_GATTC_ACT_WRITE_CHAR_DESCR,
@ -75,82 +70,67 @@ typedef union {
bool filter_uuid_enable;
esp_bt_uuid_t filter_uuid;
} search_srvc;
//BTC_GATTC_ACT_GET_FIRST_CHAR,
struct get_first_char_arg {
//BTC_GATTC_ACT_GET_CHAR,
struct get_char_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
} get_first_char;
//BTC_GATTC_ACT_GET_NEXT_CHAR,
struct get_next_char_arg {
uint16_t handle;
} get_char;
//BTC_GATTC_ACT_GET_DESCR,
struct get_descr_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
} get_next_char;
//BTC_GATTC_ACT_GET_FIRST_DESCR,
struct get_first_descr_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
} get_first_descr;
//BTC_GATTC_ACT_GET_NEXT_DESCR,
struct get_next_descr_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
esp_gatt_id_t descr_id;
} get_next_descr;
uint16_t handle;
} get_descr;
//BTC_GATTC_ACT_GET_FIRST_INCL_SERVICE,
struct get_first_incl_srvc_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
uint16_t handle;
} get_first_incl_srvc;
//BTC_GATTC_ACT_GET_NEXT_INCL_SERVICE,
struct get_next_incl_srvc_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_srvc_id_t start_service_id;
uint16_t handle;
} get_next_incl_srvc;
//BTC_GATTC_ACT_READ_CHAR,
struct read_char_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
uint16_t handle;
esp_gatt_auth_req_t auth_req;
} read_char;
//BTC_GATTC_ACT_READ_MULTIPLE_CHAR
struct read_multiple_arg {
uint16_t conn_id;
uint8_t num_attr;
uint16_t handles[ESP_GATT_MAX_READ_MULTI_HANDLES];
esp_gatt_auth_req_t auth_req;
} read_multiple;
//BTC_GATTC_ACT_READ_CHAR_DESCR,
struct read_descr_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
esp_gatt_id_t descr_id;
uint16_t handle;
esp_gatt_auth_req_t auth_req;
} read_descr;
//BTC_GATTC_ACT_WRITE_CHAR,
struct write_char_arg {
uint16_t conn_id;
uint16_t value_len;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
uint16_t handle;
uint8_t *value;
esp_gatt_write_type_t write_type;
esp_gatt_write_type_t write_type;
esp_gatt_auth_req_t auth_req;
} write_char;
//BTC_GATTC_ACT_WRITE_CHAR_DESCR,
struct write_descr_arg {
uint16_t conn_id;
uint16_t value_len;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
esp_gatt_id_t descr_id;
uint16_t handle;
uint8_t *value;
esp_gatt_write_type_t write_type;
esp_gatt_write_type_t write_type;
esp_gatt_auth_req_t auth_req;
} write_descr;
//BTC_GATTC_ACT_PREPARE_WRITE,
struct prep_write_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
uint16_t handle;
uint16_t offset;
uint16_t value_len;
uint8_t *value;
@ -159,9 +139,7 @@ typedef union {
//BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR,
struct prep_write_descr_arg {
uint16_t conn_id;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
esp_gatt_id_t descr_id;
uint16_t handle;
uint16_t offset;
uint16_t value_len;
uint8_t *value;
@ -176,15 +154,13 @@ typedef union {
struct reg_for_notify_arg {
esp_gatt_if_t gattc_if;
esp_bd_addr_t remote_bda;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
uint16_t handle;
} reg_for_notify;
//BTC_GATTC_ACT_UNREG_FOR_NOTIFY
struct unreg_for_notify_arg {
esp_gatt_if_t gattc_if;
esp_bd_addr_t remote_bda;
esp_gatt_srvc_id_t service_id;
esp_gatt_id_t char_id;
uint16_t handle;
} unreg_for_notify;
//BTC_GATTC_ACT_CACHE_REFRESH,
struct cache_refresh_arg {
@ -195,5 +171,56 @@ typedef union {
void btc_gattc_call_handler(btc_msg_t *msg);
void btc_gattc_cb_handler(btc_msg_t *msg);
void btc_gattc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
esp_gatt_status_t btc_ble_gattc_get_service(uint16_t conn_id, esp_bt_uuid_t *svc_uuid,
esp_gattc_service_elem_t *result,
uint16_t *count, uint16_t offset);
esp_gatt_status_t btc_ble_gattc_get_all_char(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_gattc_char_elem_t *result,
uint16_t *count, uint16_t offset);
esp_gatt_status_t btc_ble_gattc_get_all_descr(uint16_t conn_id,
uint16_t char_handle,
esp_gattc_descr_elem_t *result,
uint16_t *count, uint16_t offset);
esp_gatt_status_t btc_ble_gattc_get_char_by_uuid(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_gattc_char_elem_t *result,
uint16_t *count);
esp_gatt_status_t btc_ble_gattc_get_descr_by_uuid(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t char_uuid,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count);
esp_gatt_status_t btc_ble_gattc_get_descr_by_char_handle(uint16_t conn_id,
uint16_t char_handle,
esp_bt_uuid_t descr_uuid,
esp_gattc_descr_elem_t *result,
uint16_t *count);
esp_gatt_status_t btc_ble_gattc_get_include_service(uint16_t conn_id,
uint16_t start_handle,
uint16_t end_handle,
esp_bt_uuid_t *incl_uuid,
esp_gattc_incl_svc_elem_t *result,
uint16_t *count);
esp_gatt_status_t btc_ble_gattc_get_attr_count(uint16_t conn_id,
esp_gatt_db_attr_type_t type,
uint16_t start_handle,
uint16_t end_handle,
uint16_t char_handle,
uint16_t *count);
esp_gatt_status_t btc_ble_gattc_get_db(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
esp_gattc_db_elem_t *db, uint16_t *count);
#endif /* __BTC_GATTC_H__ */

View file

@ -2216,10 +2216,10 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
gatt_free_pending_ind(p_tcb);
gatt_free_pending_enc_queue(p_tcb);
gatt_free_pending_prepare_write_queue(p_tcb);
#if (GATTS_INCLUDED == TRUE)
#if (GATTS_INCLUDED)
fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, osi_free_func);
p_tcb->sr_cmd.multi_rsp_q = NULL;
#endif ///GATTS_INCLUDED == TRUE
#endif /* #if (GATTS_INCLUDED) */
for (i = 0; i < GATT_MAX_APPS; i ++) {
p_reg = &gatt_cb.cl_rcb[i];
if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {

View file

@ -41,41 +41,36 @@
#define GATTC_TAG "GATTC_DEMO"
#define REMOTE_SERVICE_UUID 0x00FF
#define REMOTE_NOTIFY_CHAR_UUID 0xFF01
#define PROFILE_NUM 1
#define PROFILE_A_APP_ID 0
#define INVALID_HANDLE 0
///Declare static functions
static const char remote_device_name[] = "ESP_GATTS_DEMO";
static bool connect = false;
static bool get_server = false;
static esp_gattc_char_elem_t *char_elem_result = NULL;
static esp_gattc_descr_elem_t *descr_elem_result = NULL;
/* eclare static functions */
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static esp_gatt_srvc_id_t gatt_server_demo_service_id = {
.id = {
.uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
},
.inst_id = 0,
},
.is_primary = true,
};
static esp_bt_uuid_t remote_filter_service_uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
};
static esp_gatt_id_t notify_descr_id = {
.uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,},
},
.inst_id = 0,
static esp_bt_uuid_t remote_filter_char_uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_NOTIFY_CHAR_UUID,},
};
static bool connect = false;
static bool get_server = false;
static const char remote_device_name[] = "ESP_GATTS_DEMO";
static esp_bt_uuid_t notify_descr_uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,},
};
static esp_ble_scan_params_t ble_scan_params = {
.scan_type = BLE_SCAN_TYPE_ACTIVE,
@ -85,15 +80,14 @@ static esp_ble_scan_params_t ble_scan_params = {
.scan_window = 0x30
};
#define PROFILE_NUM 1
#define PROFILE_A_APP_ID 0
struct gattc_profile_inst {
esp_gattc_cb_t gattc_cb;
uint16_t gattc_if;
uint16_t app_id;
uint16_t conn_id;
uint16_t service_start_handle;
uint16_t service_end_handle;
uint16_t char_handle;
esp_bd_addr_t remote_bda;
};
@ -107,7 +101,6 @@ static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = {
static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
uint16_t conn_id = 0;
esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param;
switch (event) {
@ -120,13 +113,12 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
break;
case ESP_GATTC_CONNECT_EVT:{
//p_data->connect.status always be ESP_GATT_OK
ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d, status %d", conn_id, gattc_if, p_data->connect.status);
conn_id = p_data->connect.conn_id;
ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d, status %d", p_data->connect.conn_id, gattc_if, p_data->connect.status);
gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
ESP_LOGI(GATTC_TAG, "REMOTE BDA:");
esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t));
esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, conn_id);
esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, p_data->connect.conn_id);
if (mtu_ret){
ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret);
}
@ -147,10 +139,13 @@ 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 = &p_data->search_res.srvc_id;
conn_id = p_data->search_res.conn_id;
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, "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);
}
break;
@ -160,56 +155,110 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status);
break;
}
conn_id = p_data->search_cmpl.conn_id;
ESP_LOGI(GATTC_TAG, "ESP_GATTC_SEARCH_CMPL_EVT");
if (get_server){
esp_ble_gattc_get_characteristic(gattc_if, conn_id, &gatt_server_demo_service_id, NULL);
}
break;
case ESP_GATTC_GET_CHAR_EVT:
if (p_data->get_char.status != ESP_GATT_OK) {
ESP_LOGE(GATTC_TAG, "get char failed, error status = %x", p_data->get_char.status);
break;
}
ESP_LOGI(GATTC_TAG, "get char success");
ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16);
uint16_t count = 0;
esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if,
p_data->search_cmpl.conn_id,
ESP_GATT_DB_CHARACTERISTIC,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
INVALID_HANDLE,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_CHAR_UUID) {
esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &gatt_server_demo_service_id, &p_data->get_char.char_id);
}
if (count > 0){
char_elem_result = (esp_gattc_char_elem_t *)malloc(sizeof(char_elem_result) * count);
if (!char_elem_result){
ESP_LOGE(GATTC_TAG, "gattc no mem");
}else{
status = esp_ble_gattc_get_char_by_uuid( gattc_if,
p_data->search_cmpl.conn_id,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
remote_filter_char_uuid,
char_elem_result,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error");
}
esp_ble_gattc_get_characteristic(gattc_if, conn_id, &gatt_server_demo_service_id, &p_data->get_char.char_id);
break;
/* Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */
if (count > 0 && (char_elem_result[0].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY)){
gl_profile_tab[PROFILE_A_APP_ID].char_handle = char_elem_result[0].char_handle;
esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, char_elem_result[0].char_handle);
}
}
/* free char_elem_result */
free(char_elem_result);
}else{
ESP_LOGE(GATTC_TAG, "no char found");
}
}
break;
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
ESP_LOGI(GATTC_TAG, "ESP_GATTC_REG_FOR_NOTIFY_EVT");
if (p_data->reg_for_notify.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "REG FOR NOTIFY failed: error status = %d", p_data->reg_for_notify.status);
break;
}
}else{
uint16_t count = 0;
uint16_t notify_en = 1;
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count( gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
ESP_GATT_DB_DESCRIPTOR,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
gl_profile_tab[PROFILE_A_APP_ID].char_handle,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (count > 0){
descr_elem_result = malloc(sizeof(descr_elem_result) * count);
if (!descr_elem_result){
ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem");
}else{
ret_status = esp_ble_gattc_get_descr_by_char_handle( gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
p_data->reg_for_notify.handle,
notify_descr_uuid,
descr_elem_result,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error");
}
ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, p_data->reg_for_notify.char_id.uuid.uuid.uuid16);
uint16_t notify_en = 1;
esp_ble_gattc_write_char_descr( gattc_if,
conn_id,
&gatt_server_demo_service_id,
&p_data->reg_for_notify.char_id,
&notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
/* Erery char have 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,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
descr_elem_result[0].handle,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
}
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_write_char_descr error");
}
/* free descr_elem_result */
free(descr_elem_result);
}
}
else{
ESP_LOGE(GATTC_TAG, "decsr not found");
}
}
break;
}
case ESP_GATTC_NOTIFY_EVT:
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify value:");
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive notify value:");
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
//write back
esp_ble_gattc_write_char(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
&gatt_server_demo_service_id,
&p_data->notify.char_id,
p_data->notify.value_len,
p_data->notify.value,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_DESCR_EVT:
if (p_data->write.status != ESP_GATT_OK){
@ -217,6 +266,18 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
break;
}
ESP_LOGI(GATTC_TAG, "write descr success ");
uint8_t write_char_data[35];
for (int i = 0; i < sizeof(write_char_data); ++i)
{
write_char_data[i] = i % 256;
}
esp_ble_gattc_write_char( gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
gl_profile_tab[PROFILE_A_APP_ID].char_handle,
sizeof(write_char_data),
write_char_data,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_SRVC_CHG_EVT: {
esp_bd_addr_t bda;
@ -324,8 +385,6 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
ESP_LOGI(GATTC_TAG, "EVT %d, gattc if %d", event, gattc_if);
/* If event is register event, store the gattc_if for each profile */
if (event == ESP_GATTC_REG_EVT) {
if (param->reg.status == ESP_GATT_OK) {

View file

@ -41,38 +41,20 @@
#define REMOTE_SERVICE_UUID 0x1809
#define REMOTE_NOTIFY_UUID 0x2A37
static esp_gattc_char_elem_t *char_elem_result = NULL;
static esp_gattc_descr_elem_t *descr_elem_result = NULL;
///Declare static functions
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static esp_gatt_srvc_id_t heart_rate_service_id = {
.id = {
.uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
},
.inst_id = 0,
},
.is_primary = true,
};
static esp_bt_uuid_t remote_filter_service_uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
};
static esp_gatt_id_t remote_notify_descr_id = {
.uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,},
},
.inst_id = 0,
};
static bool connect = false;
static bool get_service = false;
static const char remote_device_name[] = "ESP_BLE_SECURITY";
@ -88,12 +70,16 @@ static esp_ble_scan_params_t ble_scan_params = {
#define PROFILE_NUM 1
#define PROFILE_A_APP_ID 0
#define INVALID_HANDLE 0
struct gattc_profile_inst {
esp_gattc_cb_t gattc_cb;
uint16_t gattc_if;
uint16_t app_id;
uint16_t conn_id;
uint16_t service_start_handle;
uint16_t service_end_handle;
uint16_t notify_char_handle;
esp_bd_addr_t remote_bda;
};
@ -146,7 +132,6 @@ static char *esp_key_type_to_str(esp_ble_key_type_t key_type)
static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
uint16_t conn_id = 0;
esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param;
switch (event) {
@ -160,12 +145,11 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
break;
}
ESP_LOGI(GATTC_TAG, "open success");
conn_id = p_data->open.conn_id;
gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->open.conn_id;
memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->open.remote_bda, sizeof(esp_bd_addr_t));
ESP_LOGI(GATTC_TAG, "REMOTE BDA:");
esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t));
esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, conn_id);
esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, p_data->open.conn_id);
if (mtu_ret){
ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret);
}
@ -178,12 +162,13 @@ 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 = &p_data->search_res.srvc_id;
conn_id = p_data->search_res.conn_id;
ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", conn_id);
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);
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;
}
break;
}
@ -192,26 +177,53 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status);
break;
}
conn_id = p_data->search_cmpl.conn_id;
if (get_service){
esp_ble_gattc_get_characteristic(gattc_if, conn_id, &heart_rate_service_id, NULL);
uint16_t count = 0;
uint16_t offset = 0;
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
ESP_GATT_DB_CHARACTERISTIC,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
INVALID_HANDLE,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error, %d", __LINE__);
}
if (count > 0){
char_elem_result = (esp_gattc_char_elem_t *)malloc(sizeof(char_elem_result) * count);
if (!char_elem_result){
ESP_LOGE(GATTC_TAG, "gattc no mem");
}else{
ret_status = esp_ble_gattc_get_all_char(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
char_elem_result,
&count,
offset);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_all_char error, %d", __LINE__);
}
if (count > 0){
for (int i = 0; i < count; ++i)
{
if (char_elem_result[i].uuid.len == ESP_UUID_LEN_16 && char_elem_result[i].uuid.uuid.uuid16 == REMOTE_NOTIFY_UUID && (char_elem_result[i].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY))
{
gl_profile_tab[PROFILE_A_APP_ID].notify_char_handle = char_elem_result[i].char_handle;
esp_ble_gattc_register_for_notify (gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].remote_bda,
char_elem_result[i].char_handle);
break;
}
}
}
}
free(char_elem_result);
}
}
break;
case ESP_GATTC_GET_CHAR_EVT:
if (p_data->get_char.status != ESP_GATT_OK) {
ESP_LOGE(GATTC_TAG, "get char failed, error status = %x", p_data->get_char.status);
break;
}
ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status);
ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16);
if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_UUID) {
ESP_LOGI(GATTC_TAG, "register notify");
esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &heart_rate_service_id, &p_data->get_char.char_id);
}
esp_ble_gattc_get_characteristic(gattc_if, conn_id, &heart_rate_service_id, &p_data->get_char.char_id);
break;
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
if (p_data->reg_for_notify.status != ESP_GATT_OK){
@ -219,31 +231,58 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
break;
}
ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, p_data->reg_for_notify.char_id.uuid.uuid.uuid16);
uint16_t notify_en = 1;
esp_ble_gattc_write_char_descr( gattc_if,
conn_id,
&heart_rate_service_id,
&p_data->reg_for_notify.char_id,
&remote_notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
uint16_t count = 0;
uint16_t offset = 0;
uint16_t notify_en = 1;
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
ESP_GATT_DB_DESCRIPTOR,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
p_data->reg_for_notify.handle,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error, %d", __LINE__);
}
if (count > 0){
descr_elem_result = malloc(sizeof(descr_elem_result) * count);
if (!descr_elem_result){
ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem");
}else{
ret_status = esp_ble_gattc_get_all_descr(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
p_data->reg_for_notify.handle,
descr_elem_result,
&count,
offset);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_all_descr error, %d", __LINE__);
}
for (int i = 0; i < count; ++i)
{
if (descr_elem_result[i].uuid.len == ESP_UUID_LEN_16 && descr_elem_result[i].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG)
{
esp_ble_gattc_write_char_descr (gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
descr_elem_result[i].handle,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
}
}
}
free(descr_elem_result);
}
break;
}
case ESP_GATTC_NOTIFY_EVT:
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive notify value:");
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
//write back
esp_ble_gattc_write_char(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
&heart_rate_service_id,
&p_data->notify.char_id,
p_data->notify.value_len,
p_data->notify.value,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_DESCR_EVT:
if (p_data->write.status != ESP_GATT_OK){

View file

@ -339,6 +339,8 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
case ESP_GATTS_READ_EVT:
break;
case ESP_GATTS_WRITE_EVT:
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_WRITE_EVT, write value:");
esp_log_buffer_hex(GATTS_TABLE_TAG, param->write.value, param->write.len);
break;
case ESP_GATTS_EXEC_WRITE_EVT:
break;
@ -356,12 +358,12 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
break;
case ESP_GATTS_CONNECT_EVT:
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONNECT_EVT");
//start security connect with peer device when receive the connect event sent by the master.
/* start security connect with peer device when receive the connect event sent by the master */
esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
break;
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT");
///start advertising again when missing the connect.
/* start advertising again when missing the connect */
esp_ble_gap_start_advertising(&heart_rate_adv_params);
break;
case ESP_GATTS_OPEN_EVT:

View file

@ -45,35 +45,34 @@
#define REMOTE_SERVICE_UUID 0x00FF
#define REMOTE_NOTIFY_CHAR_UUID 0xFF01
///Declare static functions
/* register three profiles, each profile corresponds to one connection,
which makes it easy to handle each connection event */
#define PROFILE_NUM 3
#define PROFILE_A_APP_ID 0
#define PROFILE_B_APP_ID 1
#define PROFILE_C_APP_ID 2
#define INVALID_HANDLE 0
/* Declare static functions */
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static void gattc_profile_c_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
static esp_gatt_srvc_id_t remote_service_id = {
.id = {
.uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
},
.inst_id = 0,
},
.is_primary = true,
};
static esp_bt_uuid_t remote_filter_service_uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
};
static esp_gatt_id_t notify_descr_id = {
.uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,},
},
.inst_id = 0,
static esp_bt_uuid_t remote_filter_char_uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = REMOTE_NOTIFY_CHAR_UUID,},
};
static esp_bt_uuid_t notify_descr_uuid = {
.len = ESP_UUID_LEN_16,
.uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,},
};
static bool conn_device_a = false;
@ -87,6 +86,13 @@ static bool get_service_c = false;
static bool Isconnecting = false;
static bool stop_scan_done = false;
static esp_gattc_char_elem_t *char_elem_result_a = NULL;
static esp_gattc_descr_elem_t *descr_elem_result_a = NULL;
static esp_gattc_char_elem_t *char_elem_result_b = NULL;
static esp_gattc_descr_elem_t *descr_elem_result_b = NULL;
static esp_gattc_char_elem_t *char_elem_result_c = NULL;
static esp_gattc_descr_elem_t *descr_elem_result_c = NULL;
static const char remote_device_name[3][20] = {"ESP_GATTS_DEMO_a", "ESP_GATTS_DEMO_b", "ESP_GATTS_DEMO_c"};
static esp_ble_scan_params_t ble_scan_params = {
@ -97,19 +103,14 @@ static esp_ble_scan_params_t ble_scan_params = {
.scan_window = 0x30
};
//register three profiles, each profile corresponds to one connection,
//which makes it easy to handle each connection event
#define PROFILE_NUM 3
#define PROFILE_A_APP_ID 0
#define PROFILE_B_APP_ID 1
#define PROFILE_C_APP_ID 2
struct gattc_profile_inst {
esp_gattc_cb_t gattc_cb;
uint16_t gattc_if;
uint16_t app_id;
uint16_t conn_id;
uint16_t service_start_handle;
uint16_t service_end_handle;
uint16_t char_handle;
esp_bd_addr_t remote_bda;
};
@ -159,7 +160,7 @@ static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
//open failed, ignore the first device, connect the second device
ESP_LOGE(GATTC_TAG, "connect device failed, status %d", p_data->open.status);
conn_device_a = false;
start_scan();
//start_scan();
break;
}
memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->open.remote_bda, 6);
@ -180,11 +181,13 @@ 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 = &p_data->search_res.srvc_id;
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);
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;
}
break;
}
@ -194,57 +197,105 @@ static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
if (get_service_a){
esp_ble_gattc_get_characteristic(gattc_if, p_data->search_cmpl.conn_id, &remote_service_id, NULL);
}
break;
case ESP_GATTC_GET_CHAR_EVT:
if (p_data->get_char.status != ESP_GATT_OK) {
break;
}
ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status);
ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16);
uint16_t count = 0;
esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if,
p_data->search_cmpl.conn_id,
ESP_GATT_DB_CHARACTERISTIC,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
INVALID_HANDLE,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (count > 0) {
char_elem_result_a = (esp_gattc_char_elem_t *)malloc(sizeof(char_elem_result_a) * count);
if (!char_elem_result_a){
ESP_LOGE(GATTC_TAG, "gattc no mem");
}else {
status = esp_ble_gattc_get_char_by_uuid( gattc_if,
p_data->search_cmpl.conn_id,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
remote_filter_char_uuid,
char_elem_result_a,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error");
}
if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_CHAR_UUID) {
ESP_LOGI(GATTC_TAG, "register notify");
esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &remote_service_id, &p_data->get_char.char_id);
/* Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */
if (count > 0 && (char_elem_result_a[0].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY)){
gl_profile_tab[PROFILE_A_APP_ID].char_handle = char_elem_result_a[0].char_handle;
esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, char_elem_result_a[0].char_handle);
}
}
/* free char_elem_result */
free(char_elem_result_a);
}else {
ESP_LOGE(GATTC_TAG, "no char found");
}
}
esp_ble_gattc_get_characteristic(gattc_if, p_data->get_char.conn_id, &remote_service_id, &p_data->get_char.char_id);
break;
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
if (p_data->reg_for_notify.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "reg notify failed, error status =%x", p_data->reg_for_notify.status);
break;
}
uint16_t count = 0;
uint16_t notify_en = 1;
ESP_LOGI(GATTC_TAG, "REG FOR NOTIFY: status %d, srvc_id = %04x, char_id = %04x",
p_data->reg_for_notify.status,
p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16,
p_data->reg_for_notify.char_id.uuid.uuid.uuid16);
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count( gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
ESP_GATT_DB_DESCRIPTOR,
gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
gl_profile_tab[PROFILE_A_APP_ID].char_handle,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (count > 0){
descr_elem_result_a = malloc(sizeof(descr_elem_result_a) * count);
if (!descr_elem_result_a){
ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem");
}else{
ret_status = esp_ble_gattc_get_descr_by_char_handle( gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
p_data->reg_for_notify.handle,
notify_descr_uuid,
descr_elem_result_a,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error");
}
esp_ble_gattc_write_char_descr(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
&remote_service_id,
&p_data->reg_for_notify.char_id,
&notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
/* Erery char have only one descriptor in our 'ESP_GATTS_DEMO' demo, so we used first 'descr_elem_result' */
if (count > 0 && descr_elem_result_a[0].uuid.len == ESP_UUID_LEN_16 && descr_elem_result_a[0].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG){
ret_status = esp_ble_gattc_write_char_descr( gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
descr_elem_result_a[0].handle,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
}
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_write_char_descr error");
}
/* free descr_elem_result */
free(descr_elem_result_a);
}
}
else{
ESP_LOGE(GATTC_TAG, "decsr not found");
}
break;
}
case ESP_GATTC_NOTIFY_EVT:
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify value:");
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
//write back
esp_ble_gattc_write_char(gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
&remote_service_id,
&p_data->notify.char_id,
p_data->notify.value_len,
p_data->notify.value,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_DESCR_EVT:
if (p_data->write.status != ESP_GATT_OK){
@ -252,6 +303,18 @@ static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
ESP_LOGI(GATTC_TAG, "write descr success");
uint8_t write_char_data[35];
for (int i = 0; i < sizeof(write_char_data); ++i)
{
write_char_data[i] = i % 256;
}
esp_ble_gattc_write_char( gattc_if,
gl_profile_tab[PROFILE_A_APP_ID].conn_id,
gl_profile_tab[PROFILE_A_APP_ID].char_handle,
sizeof(write_char_data),
write_char_data,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_CHAR_EVT:
if (p_data->write.status != ESP_GATT_OK){
@ -269,8 +332,6 @@ static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
case ESP_GATTC_DISCONNECT_EVT:
ESP_LOGI(GATTC_TAG,"ESP_GATTC_DISCONNECT_EVT");
ESP_LOGI(GATTC_TAG, "conn_id %d, if %d", p_data->disconnect.conn_id, gattc_if);
//Start scanning again
start_scan();
if (memcmp(p_data->disconnect.remote_bda, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, 6) == 0){
@ -299,7 +360,7 @@ static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
//open failed, ignore the second device, connect the third device
ESP_LOGE(GATTC_TAG, "connect device failed, status %d", p_data->open.status);
conn_device_b = false;
start_scan();
//start_scan();
break;
}
memcpy(gl_profile_tab[PROFILE_B_APP_ID].remote_bda, p_data->open.remote_bda, 6);
@ -320,11 +381,13 @@ 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 = &p_data->search_res.srvc_id;
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);
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;
}
break;
}
@ -334,53 +397,107 @@ static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
if (get_service_b){
esp_ble_gattc_get_characteristic(gattc_if, p_data->search_cmpl.conn_id, &remote_service_id, NULL);
}
break;
case ESP_GATTC_GET_CHAR_EVT:
if (p_data->get_char.status != ESP_GATT_OK) {
break;
}
ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status);
ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16);
uint16_t count = 0;
esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if,
p_data->search_cmpl.conn_id,
ESP_GATT_DB_CHARACTERISTIC,
gl_profile_tab[PROFILE_B_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_B_APP_ID].service_end_handle,
INVALID_HANDLE,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_CHAR_UUID) {
ESP_LOGI(GATTC_TAG, "register notify");
esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_B_APP_ID].remote_bda, &remote_service_id, &p_data->get_char.char_id);
}
if (count > 0){
char_elem_result_b = (esp_gattc_char_elem_t *)malloc(sizeof(char_elem_result_b) * count);
if (!char_elem_result_b){
ESP_LOGE(GATTC_TAG, "gattc no mem");
}else{
status = esp_ble_gattc_get_char_by_uuid( gattc_if,
p_data->search_cmpl.conn_id,
gl_profile_tab[PROFILE_B_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_B_APP_ID].service_end_handle,
remote_filter_char_uuid,
char_elem_result_b,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error");
}
esp_ble_gattc_get_characteristic(gattc_if, p_data->get_char.conn_id, &remote_service_id, &p_data->get_char.char_id);
/* Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */
if (count > 0 && (char_elem_result_b[0].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY)){
gl_profile_tab[PROFILE_B_APP_ID].char_handle = char_elem_result_b[0].char_handle;
esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_B_APP_ID].remote_bda, char_elem_result_b[0].char_handle);
}
}
/* free char_elem_result */
free(char_elem_result_b);
}else{
ESP_LOGE(GATTC_TAG, "no char found");
}
}
break;
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
ESP_LOGI(GATTC_TAG, "REG FOR NOTIFY: status %d, srvc_id = %04x, char_id = %04x",
p_data->reg_for_notify.status,
p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16,
p_data->reg_for_notify.char_id.uuid.uuid.uuid16);
if (p_data->reg_for_notify.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "reg notify failed, error status =%x", p_data->reg_for_notify.status);
break;
}
uint16_t count = 0;
uint16_t notify_en = 1;
esp_ble_gattc_write_char_descr(gattc_if,
gl_profile_tab[PROFILE_B_APP_ID].conn_id,
&remote_service_id,
&p_data->reg_for_notify.char_id,
&notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count( gattc_if,
gl_profile_tab[PROFILE_B_APP_ID].conn_id,
ESP_GATT_DB_DESCRIPTOR,
gl_profile_tab[PROFILE_B_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_B_APP_ID].service_end_handle,
gl_profile_tab[PROFILE_B_APP_ID].char_handle,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (count > 0){
descr_elem_result_b = malloc(sizeof(descr_elem_result_b) * count);
if (!descr_elem_result_b){
ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem");
}else{
ret_status = esp_ble_gattc_get_descr_by_char_handle( gattc_if,
gl_profile_tab[PROFILE_B_APP_ID].conn_id,
p_data->reg_for_notify.handle,
notify_descr_uuid,
descr_elem_result_b,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error");
}
/* Erery char have only one descriptor in our 'ESP_GATTS_DEMO' demo, so we used first 'descr_elem_result' */
if (count > 0 && descr_elem_result_b[0].uuid.len == ESP_UUID_LEN_16 && descr_elem_result_b[0].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG){
ret_status = esp_ble_gattc_write_char_descr( gattc_if,
gl_profile_tab[PROFILE_B_APP_ID].conn_id,
descr_elem_result_b[0].handle,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
}
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_write_char_descr error");
}
/* free descr_elem_result */
free(descr_elem_result_b);
}
}
else{
ESP_LOGE(GATTC_TAG, "decsr not found");
}
break;
}
case ESP_GATTC_NOTIFY_EVT:
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify value:");
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
//write back
esp_ble_gattc_write_char(gattc_if,
gl_profile_tab[PROFILE_B_APP_ID].conn_id,
&remote_service_id,
&p_data->notify.char_id,
p_data->notify.value_len,
p_data->notify.value,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_DESCR_EVT:
if (p_data->write.status != ESP_GATT_OK){
@ -388,6 +505,18 @@ static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
ESP_LOGI(GATTC_TAG, "write descr success");
uint8_t write_char_data[35];
for (int i = 0; i < sizeof(write_char_data); ++i)
{
write_char_data[i] = i % 256;
}
esp_ble_gattc_write_char( gattc_if,
gl_profile_tab[PROFILE_B_APP_ID].conn_id,
gl_profile_tab[PROFILE_B_APP_ID].char_handle,
sizeof(write_char_data),
write_char_data,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_CHAR_EVT:
if (p_data->write.status != ESP_GATT_OK){
@ -405,8 +534,6 @@ static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
case ESP_GATTC_DISCONNECT_EVT:
ESP_LOGI(GATTC_TAG,"ESP_GATTC_DISCONNECT_EVT");
ESP_LOGI(GATTC_TAG, "conn_id %d, if %d", p_data->disconnect.conn_id, gattc_if);
if (memcmp(p_data->disconnect.remote_bda, gl_profile_tab[PROFILE_B_APP_ID].remote_bda, 6) == 0){
ESP_LOGI(GATTC_TAG, "device b disconnect");
conn_device_b = false;
@ -432,7 +559,7 @@ static void gattc_profile_c_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
if (p_data->open.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "connect device failed, status %d", p_data->open.status);
conn_device_c = false;
start_scan();
//start_scan();
break;
}
memcpy(gl_profile_tab[PROFILE_C_APP_ID].remote_bda, p_data->open.remote_bda, 6);
@ -453,11 +580,13 @@ 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 = &p_data->search_res.srvc_id;
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);
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;
}
break;
}
@ -467,51 +596,106 @@ static void gattc_profile_c_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
if (get_service_c){
esp_ble_gattc_get_characteristic(gattc_if, p_data->search_cmpl.conn_id, &remote_service_id, NULL);
uint16_t count = 0;
esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if,
p_data->search_cmpl.conn_id,
ESP_GATT_DB_CHARACTERISTIC,
gl_profile_tab[PROFILE_C_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_C_APP_ID].service_end_handle,
INVALID_HANDLE,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (count > 0){
char_elem_result_c = (esp_gattc_char_elem_t *)malloc(sizeof(char_elem_result_c) * count);
if (!char_elem_result_c){
ESP_LOGE(GATTC_TAG, "gattc no mem");
}else{
status = esp_ble_gattc_get_char_by_uuid( gattc_if,
p_data->search_cmpl.conn_id,
gl_profile_tab[PROFILE_C_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_C_APP_ID].service_end_handle,
remote_filter_char_uuid,
char_elem_result_c,
&count);
if (status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error");
}
/* Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */
if (count > 0 && (char_elem_result_c[0].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY)){
gl_profile_tab[PROFILE_C_APP_ID].char_handle = char_elem_result_c[0].char_handle;
esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_C_APP_ID].remote_bda, char_elem_result_c[0].char_handle);
}
}
/* free char_elem_result */
free(char_elem_result_c);
}else{
ESP_LOGE(GATTC_TAG, "no char found");
}
}
break;
case ESP_GATTC_GET_CHAR_EVT:
if (p_data->get_char.status != ESP_GATT_OK) {
ESP_LOGE(GATTC_TAG, "GET CHAR failed, error status = %x", p_data->get_char.status);
break;
}
ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16);
if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_CHAR_UUID) {
ESP_LOGI(GATTC_TAG, "register notify");
esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_C_APP_ID].remote_bda, &remote_service_id, &p_data->get_char.char_id);
}
esp_ble_gattc_get_characteristic(gattc_if, p_data->get_char.conn_id, &remote_service_id, &p_data->get_char.char_id);
break;
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
if (p_data->reg_for_notify.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "reg notify failed, error status =%x", p_data->reg_for_notify.status);
break;
}
uint16_t count = 0;
uint16_t notify_en = 1;
ESP_LOGI(GATTC_TAG, "REG FOR NOTIFY: status %d, srvc_id = %04x, char_id = %04x",
p_data->reg_for_notify.status,
p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16,
p_data->reg_for_notify.char_id.uuid.uuid.uuid16);
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count( gattc_if,
gl_profile_tab[PROFILE_C_APP_ID].conn_id,
ESP_GATT_DB_DESCRIPTOR,
gl_profile_tab[PROFILE_C_APP_ID].service_start_handle,
gl_profile_tab[PROFILE_C_APP_ID].service_end_handle,
gl_profile_tab[PROFILE_C_APP_ID].char_handle,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
}
if (count > 0){
descr_elem_result_c = malloc(sizeof(descr_elem_result_c) * count);
if (!descr_elem_result_c){
ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem");
}else{
ret_status = esp_ble_gattc_get_descr_by_char_handle( gattc_if,
gl_profile_tab[PROFILE_C_APP_ID].conn_id,
p_data->reg_for_notify.handle,
notify_descr_uuid,
descr_elem_result_c,
&count);
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error");
}
esp_ble_gattc_write_char_descr(gattc_if,
gl_profile_tab[PROFILE_C_APP_ID].conn_id,
&remote_service_id,
&p_data->reg_for_notify.char_id,
&notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
/* Erery char have only one descriptor in our 'ESP_GATTS_DEMO' demo, so we used first 'descr_elem_result' */
if (count > 0 && descr_elem_result_c[0].uuid.len == ESP_UUID_LEN_16 && descr_elem_result_c[0].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG){
ret_status = esp_ble_gattc_write_char_descr( gattc_if,
gl_profile_tab[PROFILE_C_APP_ID].conn_id,
descr_elem_result_c[0].handle,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
}
if (ret_status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, "esp_ble_gattc_write_char_descr error");
}
/* free descr_elem_result */
free(descr_elem_result_c);
}
}
else{
ESP_LOGE(GATTC_TAG, "decsr not found");
}
break;
}
case ESP_GATTC_NOTIFY_EVT:
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify value:");
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
//write back
esp_ble_gattc_write_char(gattc_if,
gl_profile_tab[PROFILE_C_APP_ID].conn_id,
&remote_service_id,
&p_data->notify.char_id,
p_data->notify.value_len,
p_data->notify.value,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_DESCR_EVT:
if (p_data->write.status != ESP_GATT_OK){
@ -519,6 +703,18 @@ static void gattc_profile_c_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
ESP_LOGI(GATTC_TAG, "write descr success");
uint8_t write_char_data[35];
for (int i = 0; i < sizeof(write_char_data); ++i)
{
write_char_data[i] = i % 256;
}
esp_ble_gattc_write_char( gattc_if,
gl_profile_tab[PROFILE_C_APP_ID].conn_id,
gl_profile_tab[PROFILE_C_APP_ID].char_handle,
sizeof(write_char_data),
write_char_data,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
case ESP_GATTC_WRITE_CHAR_EVT:
if (p_data->write.status != ESP_GATT_OK){
@ -536,8 +732,6 @@ static void gattc_profile_c_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
case ESP_GATTC_DISCONNECT_EVT:
ESP_LOGI(GATTC_TAG,"ESP_GATTC_DISCONNECT_EVT");
ESP_LOGI(GATTC_TAG, "conn_id %d, if %d", p_data->disconnect.conn_id, gattc_if);
if (memcmp(p_data->disconnect.remote_bda, gl_profile_tab[PROFILE_C_APP_ID].remote_bda, 6) == 0){
ESP_LOGI(GATTC_TAG, "device c disconnect");
conn_device_c = false;
@ -554,6 +748,15 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
uint8_t *adv_name = NULL;
uint8_t adv_name_len = 0;
switch (event) {
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
ESP_LOGI(GATTC_TAG, "update connetion params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
param->update_conn_params.status,
param->update_conn_params.min_int,
param->update_conn_params.max_int,
param->update_conn_params.conn_int,
param->update_conn_params.latency,
param->update_conn_params.timeout);
break;
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
//the unit of the duration is second
uint32_t duration = 30;
@ -593,7 +796,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
if (strlen(remote_device_name[0]) == adv_name_len && strncmp((char *)adv_name, remote_device_name[0], adv_name_len) == 0) {
if (conn_device_a == false) {
conn_device_a = true;
ESP_LOGI(GATTC_TAG, "Searched device %s\n", remote_device_name[0]);
ESP_LOGI(GATTC_TAG, "Searched device %s", remote_device_name[0]);
esp_ble_gap_stop_scanning();
esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, true);
Isconnecting = true;
@ -603,7 +806,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
else if (strlen(remote_device_name[1]) == adv_name_len && strncmp((char *)adv_name, remote_device_name[1], adv_name_len) == 0) {
if (conn_device_b == false) {
conn_device_b = true;
ESP_LOGI(GATTC_TAG, "Searched device %s\n", remote_device_name[1]);
ESP_LOGI(GATTC_TAG, "Searched device %s", remote_device_name[1]);
esp_ble_gap_stop_scanning();
esp_ble_gattc_open(gl_profile_tab[PROFILE_B_APP_ID].gattc_if, scan_result->scan_rst.bda, true);
Isconnecting = true;
@ -613,7 +816,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
else if (strlen(remote_device_name[2]) == adv_name_len && strncmp((char *)adv_name, remote_device_name[2], adv_name_len) == 0) {
if (conn_device_c == false) {
conn_device_c = true;
ESP_LOGI(GATTC_TAG, "Searched device %s\n", remote_device_name[2]);
ESP_LOGI(GATTC_TAG, "Searched device %s", remote_device_name[2]);
esp_ble_gap_stop_scanning();
esp_ble_gattc_open(gl_profile_tab[PROFILE_C_APP_ID].gattc_if, scan_result->scan_rst.bda, true);
Isconnecting = true;