component/bt : Optimize Gatt attr table and fix some bugs
1. Optimize GATT attribute table structure 2. fix read/write bugs 3. add docs
This commit is contained in:
parent
d512d6100c
commit
9f151d745e
|
@ -287,12 +287,13 @@ typedef enum {
|
|||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bt_uuid_t uuid; /*!< Element UUID */
|
||||
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;
|
||||
uint8_t *value; /*!< Element value array*/
|
||||
} esp_attr_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -303,7 +304,7 @@ typedef struct
|
|||
#define ESP_GATT_RSP_BY_APP 0
|
||||
#define ESP_GATT_AUTO_RSP 1
|
||||
uint8_t auto_rsp; /*!< need the app response to the client if need_rsp set to 1*/
|
||||
}esp_attr_control_t;
|
||||
} esp_attr_control_t;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -312,8 +313,8 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
esp_attr_control_t attr_control; /*!< The attribue control type*/
|
||||
esp_attr_desc_t att_desc; /*!< The attribue type*/
|
||||
}esp_gatts_attr_db_t;
|
||||
esp_attr_desc_t att_desc; /*!< The attribue type*/
|
||||
} esp_gatts_attr_db_t;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -323,8 +324,8 @@ 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 */
|
||||
}esp_attr_value_t;
|
||||
uint8_t *attr_value; /*!< the pointer to attribute value */
|
||||
} esp_attr_value_t;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -335,7 +336,7 @@ 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 */
|
||||
} esp_gatts_incl_svc_desc_t; /*!< Gatt include service entry element */
|
||||
|
||||
/**
|
||||
* @brief Gatt include 128 bit service entry element
|
||||
|
@ -344,18 +345,9 @@ 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 */
|
||||
} esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gatt characteristic entry element
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t prop; /*!< Gatt attribute properties */
|
||||
uint16_t attr_hdl; /*!< Gatt attribute handle */
|
||||
esp_bt_uuid_t attr_uuid; /*!< Gatt attribute uuid typedle */
|
||||
}esp_gatts_char_desc_t; /*!< Gatt characteristic value descriptor */
|
||||
|
||||
|
||||
/// Gatt attribute value
|
||||
|
|
|
@ -74,8 +74,10 @@ typedef union {
|
|||
uint16_t handle; /*!< The attribute handle */
|
||||
uint16_t offset; /*!< Offset of the value, if the value is too long */
|
||||
bool is_long; /*!< The value is too long or not */
|
||||
bool need_rsp; /*!< The read operation need to do response */
|
||||
} read; /*!< Gatt server callback param of ESP_GATTS_READ_EVT */
|
||||
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_WRITE_EVT
|
||||
*/
|
||||
|
@ -227,7 +229,7 @@ typedef union {
|
|||
* @brief ESP_GATTS_RESPONSE_EVT
|
||||
*/
|
||||
struct gatts_rsp_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t handle; /*!< Attribute handle which send response */
|
||||
} rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
|
||||
|
||||
|
|
|
@ -406,13 +406,15 @@ void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
|||
tGATT_ATTR_VAL *p_attr_val = NULL;
|
||||
tGATTS_ATTR_CONTROL *p_control = NULL;
|
||||
|
||||
if (p_msg->api_add_char_descr.attr_val.attr_max_len != 0) {
|
||||
p_attr_val = &p_msg->api_add_char_descr.attr_val;
|
||||
if(p_msg->api_add_char.attr_val.attr_max_len != 0){
|
||||
p_attr_val = &p_msg->api_add_char.attr_val;
|
||||
}
|
||||
|
||||
if (p_msg->api_add_char_descr.control.auto_rsp != 0) {
|
||||
p_control = &p_msg->api_add_char_descr.control;
|
||||
if(p_msg->api_add_char.control.auto_rsp != 0){
|
||||
p_control = &p_msg->api_add_char.control;
|
||||
}
|
||||
|
||||
|
||||
attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
|
||||
&p_msg->api_add_char.char_uuid,
|
||||
p_msg->api_add_char.perm,
|
||||
|
@ -429,6 +431,9 @@ void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
|||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
if((p_attr_val != NULL) && (p_attr_val->attr_val != NULL)){
|
||||
GKI_freebuf(p_attr_val->attr_val);
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
|
||||
|
@ -476,6 +481,9 @@ void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_
|
|||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
if((p_attr_val != NULL) && (p_attr_val->attr_val != NULL)){
|
||||
GKI_freebuf(p_attr_val->attr_val);
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
|
||||
|
|
|
@ -274,47 +274,54 @@ void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
|
|||
tBTA_GATTS_ATTR_CONTROL *control)
|
||||
{
|
||||
tBTA_GATTS_API_ADD_DESCR *p_buf;
|
||||
UINT16 len = 0;
|
||||
if(attr_val != NULL) {
|
||||
len = sizeof(tBTA_GATTS_API_ADD_DESCR) + attr_val->attr_len;
|
||||
} else {
|
||||
len = sizeof(tBTA_GATTS_API_ADD_DESCR);
|
||||
}
|
||||
UINT16 value_len = 0;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, len);
|
||||
if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_DESCR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_DESCR));
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_ADD_DESCR_EVT;
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->perm = perm;
|
||||
|
||||
if(control != NULL){
|
||||
p_buf->control.auto_rsp = control->auto_rsp;
|
||||
}
|
||||
|
||||
if (p_descr_uuid) {
|
||||
memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
|
||||
}
|
||||
|
||||
if(attr_val->attr_len != 0) {
|
||||
if(attr_val != NULL){
|
||||
p_buf->attr_val.attr_len = attr_val->attr_len;
|
||||
p_buf->attr_val.attr_max_len= attr_val->attr_max_len;
|
||||
memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
|
||||
p_buf->attr_val.attr_max_len = attr_val->attr_max_len;
|
||||
value_len = attr_val->attr_len;
|
||||
if (value_len != 0){
|
||||
p_buf->attr_val.attr_val = (uint8_t*)GKI_getbuf(value_len);
|
||||
if(p_buf->attr_val.attr_val != NULL){
|
||||
memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, value_len);
|
||||
}
|
||||
else{
|
||||
APPL_TRACE_ERROR("Allocate fail for %s\n", __func__);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(control != NULL) {
|
||||
p_buf->control.auto_rsp = control->auto_rsp;
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_DeleteService
|
||||
**
|
||||
** Description This function is called to delete a service. When this is done,
|
||||
** a callback event BTA_GATTS_DELETE_EVT is report with the status.
|
||||
**
|
||||
** Parameters service_id: service_id to be deleted.
|
||||
**
|
||||
**
|
||||
** Function BTA_GATTS_DeleteService
|
||||
**
|
||||
** Description This function is called to delete a service. When this is done,
|
||||
** a callback event BTA_GATTS_DELETE_EVT is report with the status.
|
||||
**
|
||||
** Parameters service_id: service_id to be deleted.
|
||||
**
|
||||
** Returns returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
|
|
@ -47,6 +47,25 @@ static inline void btc_gatts_cb_to_app(esp_gatts_cb_event_t event, esp_gatt_if_t
|
|||
}
|
||||
}
|
||||
|
||||
static inline void btc_gatts_uuid_format_convert(esp_bt_uuid_t* dest_uuid, uint16_t src_uuid_len, uint8_t* src_uuid_p)
|
||||
{
|
||||
dest_uuid->len = src_uuid_len;
|
||||
if(src_uuid_len == ESP_UUID_LEN_16){
|
||||
dest_uuid->uuid.uuid16 = src_uuid_p[0] + (src_uuid_p[1]<<8);
|
||||
}
|
||||
else if(src_uuid_len == ESP_UUID_LEN_32){
|
||||
dest_uuid->uuid.uuid32 = src_uuid_p[0] + (src_uuid_p[1]<<8) + (src_uuid_p[2]<<16) + (src_uuid_p[3]<<24);
|
||||
}
|
||||
else if(src_uuid_len == ESP_UUID_LEN_128){
|
||||
memcpy(dest_uuid->uuid.uuid128, src_uuid_p, src_uuid_len);
|
||||
}
|
||||
else{
|
||||
LOG_ERROR("%s wrong uuid length %d\n", __func__, src_uuid_len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
btc_ble_gatts_args_t *dst = (btc_ble_gatts_args_t *) p_dest;
|
||||
|
@ -167,8 +186,8 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
|
|||
btc_creat_tab_env.is_tab_creat_svc = true;
|
||||
btc_creat_tab_env.num_handle = max_nb_attr;
|
||||
for(int i = 0; i < max_nb_attr; i++){
|
||||
if(gatts_attr_db[i].att_desc.uuid.len == ESP_UUID_LEN_16){
|
||||
uuid = gatts_attr_db[i].att_desc.uuid.uuid.uuid16;
|
||||
if(gatts_attr_db[i].att_desc.uuid_length== ESP_UUID_LEN_16){
|
||||
uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
|
||||
}
|
||||
future_p = future_new();
|
||||
if (future_p == NULL) {
|
||||
|
@ -184,8 +203,10 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
|
|||
esp_gatt_srvc_id_t esp_srvc_id;
|
||||
|
||||
esp_srvc_id.id.inst_id = srvc_inst_id;
|
||||
memcpy(&esp_srvc_id.id.uuid, &gatts_attr_db[i].att_desc.uuid, sizeof(esp_bt_uuid_t));
|
||||
btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
|
||||
btc_gatts_uuid_format_convert(&esp_srvc_id.id.uuid,gatts_attr_db[i].att_desc.uuid_length,
|
||||
gatts_attr_db[i].att_desc.uuid_p);
|
||||
|
||||
btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
|
||||
BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
|
||||
srvc_inst_id, max_nb_attr, true);
|
||||
|
||||
|
@ -200,8 +221,9 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
|
|||
esp_gatt_srvc_id_t esp_srvc_id;
|
||||
|
||||
esp_srvc_id.id.inst_id = srvc_inst_id;
|
||||
memcpy(&esp_srvc_id.id.uuid, &gatts_attr_db[i].att_desc.uuid, sizeof(esp_bt_uuid_t));
|
||||
btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
|
||||
btc_gatts_uuid_format_convert(&esp_srvc_id.id.uuid,gatts_attr_db[i].att_desc.uuid_length,
|
||||
gatts_attr_db[i].att_desc.uuid_p);
|
||||
btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
|
||||
BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
|
||||
srvc_inst_id, max_nb_attr, false);
|
||||
if (future_await(future_p) == FUTURE_FAIL) {
|
||||
|
@ -230,27 +252,33 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
|
|||
uint16_t svc_hal = 0;
|
||||
tBT_UUID bta_char_uuid;
|
||||
tGATT_ATTR_VAL attr_val;
|
||||
esp_bt_uuid_t uuid_temp;
|
||||
tBTA_GATT_PERM perm;
|
||||
tBTA_GATTS_ATTR_CONTROL control;
|
||||
uint8_t char_property;
|
||||
|
||||
if(btc_creat_tab_env.svc_start_hdl != 0){
|
||||
svc_hal = btc_creat_tab_env.svc_start_hdl;
|
||||
esp_gatts_char_desc_t *char_desc = (esp_gatts_char_desc_t *)gatts_attr_db[i].att_desc.value;
|
||||
if(char_desc != NULL){
|
||||
if((gatts_attr_db[i].att_desc.value) == NULL){
|
||||
LOG_ERROR("%s Characteristic declaration should not be NULL\n", __func__);
|
||||
}
|
||||
else{
|
||||
char_property = (uint8_t)(*(uint8_t*)(gatts_attr_db[i].att_desc.value));
|
||||
perm = gatts_attr_db[i+1].att_desc.perm;
|
||||
attr_val.attr_len = gatts_attr_db[i+1].att_desc.length;
|
||||
attr_val.attr_max_len = gatts_attr_db[i+1].att_desc.max_length;
|
||||
btc_to_bta_uuid(&bta_char_uuid, &char_desc->attr_uuid);
|
||||
btc_gatts_uuid_format_convert(&uuid_temp, gatts_attr_db[i+1].att_desc.uuid_length,gatts_attr_db[i+1].att_desc.uuid_p);
|
||||
btc_to_bta_uuid(&bta_char_uuid, &uuid_temp);
|
||||
attr_val.attr_val = gatts_attr_db[i+1].att_desc.value;
|
||||
control.auto_rsp = gatts_attr_db[i+1].attr_control.auto_rsp;
|
||||
BTA_GATTS_AddCharacteristic (svc_hal, &bta_char_uuid,
|
||||
perm, char_desc->prop, &attr_val, &control);
|
||||
perm, char_property, &attr_val, &control);
|
||||
|
||||
if (future_await(future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("%s failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -266,6 +294,7 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
|
|||
case ESP_GATT_UUID_RPT_REF_DESCR:{
|
||||
uint16_t svc_hal = btc_creat_tab_env.svc_start_hdl;
|
||||
tBT_UUID bta_char_uuid;
|
||||
esp_bt_uuid_t uuid_temp;
|
||||
tGATT_ATTR_VAL attr_val;
|
||||
tBTA_GATT_PERM perm = gatts_attr_db[i].att_desc.perm;
|
||||
tBTA_GATTS_ATTR_CONTROL control;
|
||||
|
@ -274,7 +303,9 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
|
|||
attr_val.attr_len = gatts_attr_db[i].att_desc.length;
|
||||
attr_val.attr_max_len = gatts_attr_db[i].att_desc.max_length;
|
||||
attr_val.attr_val = gatts_attr_db[i].att_desc.value;
|
||||
btc_to_bta_uuid(&bta_char_uuid, &gatts_attr_db[i].att_desc.uuid);
|
||||
btc_gatts_uuid_format_convert(&uuid_temp, gatts_attr_db[i].att_desc.uuid_length,
|
||||
gatts_attr_db[i].att_desc.uuid_p);
|
||||
btc_to_bta_uuid(&bta_char_uuid, &uuid_temp);
|
||||
control.auto_rsp = gatts_attr_db[i].attr_control.auto_rsp;
|
||||
BTA_GATTS_AddCharDescriptor(svc_hal, perm, &bta_char_uuid, &attr_val, &control);
|
||||
|
||||
|
@ -573,6 +604,7 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
|
|||
param.read.offset = p_data->req_data.p_data->read_req.offset;
|
||||
param.read.is_long = p_data->req_data.p_data->read_req.is_long;
|
||||
|
||||
param.read.need_rsp = p_data->req_data.p_data->read_req.need_rsp;
|
||||
btc_gatts_cb_to_app(ESP_GATTS_READ_EVT, gatts_if, ¶m);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 le
|
|||
|
||||
static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri);
|
||||
static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id);
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id, BOOLEAN need_rsp);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -268,16 +268,12 @@ static tGATT_STATUS read_attr_value (void *p_attr,
|
|||
status = GATT_SUCCESS;
|
||||
}
|
||||
} else { /* characteristic description or characteristic value */
|
||||
|
||||
if (p_attr16->control.auto_rsp == GATT_RSP_BY_STACK) {
|
||||
GATT_TRACE_DEBUG("before characteristic description or characteristic value\n");
|
||||
if (p_attr16->p_value != NULL && p_attr16->p_value->attr_val.attr_val != NULL) {
|
||||
uint8_t *value = p_attr16->p_value->attr_val.attr_val + offset;
|
||||
GATT_TRACE_DEBUG("after characteristic description or characteristic value\n");
|
||||
if (mtu >= p_attr16->p_value->attr_val.attr_len) {
|
||||
ARRAY_TO_STREAM(p, value, p_attr16->p_value->attr_val.attr_len);
|
||||
} else {
|
||||
ARRAY_TO_STREAM(p, value, mtu);
|
||||
}
|
||||
len = (mtu >= p_attr16->p_value->attr_val.attr_len) ? (p_attr16->p_value->attr_val.attr_len) : mtu;
|
||||
ARRAY_TO_STREAM(p, value, len);
|
||||
}
|
||||
status = GATT_STACK_RSP;
|
||||
|
||||
|
@ -357,7 +353,8 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb,
|
|||
status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len - 2), &len, sec_flag, key_size);
|
||||
|
||||
if (status == GATT_PENDING || status == GATT_STACK_RSP) {
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id);
|
||||
BOOLEAN need_rsp = (status != GATT_STACK_RSP);
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id, need_rsp);
|
||||
|
||||
/* one callback at a time */
|
||||
break;
|
||||
|
@ -630,7 +627,7 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
|
|||
tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
UINT16 length, UINT8 *value)
|
||||
{
|
||||
tGATT_ATTR16 *p_cur, *p_next;
|
||||
tGATT_ATTR16 *p_cur;
|
||||
|
||||
if (p_db == NULL) {
|
||||
GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db is NULL.\n");
|
||||
|
@ -642,19 +639,21 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
|||
}
|
||||
|
||||
p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
|
||||
p_next = (tGATT_ATTR16 *) p_cur->p_next;
|
||||
|
||||
|
||||
for (; p_cur != NULL; p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
|
||||
while (p_cur != NULL) {
|
||||
if (p_cur->handle == attr_handle) {
|
||||
|
||||
if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
|
||||
switch (p_cur->uuid) {
|
||||
case GATT_UUID_PRI_SERVICE:
|
||||
case GATT_UUID_SEC_SERVICE:
|
||||
case GATT_UUID_CHAR_DECLARE:
|
||||
case GATT_UUID_INCLUDE_SERVICE:
|
||||
return GATT_NOT_FOUND;
|
||||
default:
|
||||
if (p_cur->p_value->attr_val.attr_max_len < length) {
|
||||
GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
|
||||
return GATT_INVALID_ATTR_LEN;
|
||||
} else {
|
||||
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
|
||||
p_cur->p_value->attr_val.attr_len = length;
|
||||
|
@ -668,9 +667,14 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
|||
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
|
||||
p_cur->p_value->attr_val.attr_len = length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
p_cur = p_cur->p_next;
|
||||
}
|
||||
|
||||
return GATT_SUCCESS;
|
||||
|
@ -694,7 +698,7 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
|||
tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
UINT16 *length, UINT8 **value)
|
||||
{
|
||||
tGATT_ATTR16 *p_cur, *p_next;
|
||||
tGATT_ATTR16 *p_cur;
|
||||
GATT_TRACE_DEBUG("***********%s*************\n", __func__);
|
||||
GATT_TRACE_DEBUG("attr_handle = %x\n", attr_handle);
|
||||
if (p_db == NULL) {
|
||||
|
@ -707,10 +711,8 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
|||
}
|
||||
|
||||
p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
|
||||
p_next = (tGATT_ATTR16 *) p_cur->p_next;
|
||||
|
||||
|
||||
for (; p_cur != NULL; p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
|
||||
while (p_cur != NULL) {
|
||||
LOG_ERROR("p_ur->handle = %x\n", p_cur->handle);
|
||||
if (p_cur->handle == attr_handle) {
|
||||
|
||||
|
@ -736,7 +738,7 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
|||
*value = p_cur->p_value->attr_val.attr_val;
|
||||
return GATT_SUCCESS;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("gatts_get_attribute_vaule failt:the value length is 0");
|
||||
GATT_TRACE_ERROR("gatts_get_attribute_vaule failed:the value length is 0");
|
||||
return GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
|
||||
|
@ -747,9 +749,10 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
|||
}
|
||||
|
||||
|
||||
p_cur = p_cur->p_next;
|
||||
}
|
||||
|
||||
return GATT_SUCCESS;
|
||||
return GATT_NOT_FOUND;
|
||||
}
|
||||
|
||||
BOOLEAN gatts_is_auto_response(UINT16 attr_handle)
|
||||
|
@ -839,8 +842,9 @@ tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
|
|||
(BOOLEAN)(op_code == GATT_REQ_READ_BLOB),
|
||||
mtu, p_len, sec_flag, key_size);
|
||||
|
||||
if (status == GATT_PENDING) {
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, offset, trans_id);
|
||||
if ((status == GATT_PENDING) || (status == GATT_STACK_RSP)) {
|
||||
BOOLEAN need_rsp = (status != GATT_STACK_RSP);
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, offset, trans_id, need_rsp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -848,6 +852,7 @@ tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -867,7 +872,7 @@ tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
|
|||
return GATT_APP_RSP;
|
||||
}
|
||||
|
||||
if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >
|
||||
if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >=
|
||||
offset + len)) {
|
||||
memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len);
|
||||
p_attr->p_value->attr_val.attr_len = len + offset;
|
||||
|
@ -1301,7 +1306,7 @@ static BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db)
|
|||
**
|
||||
*******************************************************************************/
|
||||
static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id)
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id, BOOLEAN need_rsp)
|
||||
{
|
||||
tGATTS_DATA sr_data;
|
||||
UINT8 i_rcb;
|
||||
|
@ -1323,6 +1328,7 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
|
|||
sr_data.read_req.handle = handle;
|
||||
sr_data.read_req.is_long = (BOOLEAN)(op_code == GATT_REQ_READ_BLOB);
|
||||
sr_data.read_req.offset = offset;
|
||||
sr_data.read_req.need_rsp = need_rsp;
|
||||
|
||||
gatt_sr_send_req_callback(conn_id,
|
||||
trans_id, GATTS_REQ_TYPE_READ, &sr_data);
|
||||
|
|
|
@ -987,14 +987,14 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
|
|||
void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
||||
UINT8 op_code, UINT16 len, UINT8 *p_data)
|
||||
{
|
||||
UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
|
||||
tGATTS_DATA sr_data;
|
||||
UINT32 trans_id;
|
||||
tGATT_STATUS status;
|
||||
UINT8 sec_flag, key_size, *p = p_data, *p_m;
|
||||
tGATT_SR_REG *p_sreg;
|
||||
UINT16 conn_id, offset = 0;
|
||||
BT_HDR *p_msg = NULL;
|
||||
UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
|
||||
tGATTS_DATA sr_data;
|
||||
UINT32 trans_id;
|
||||
tGATT_STATUS status;
|
||||
UINT8 sec_flag, key_size, *p = p_data, *p_m;
|
||||
tGATT_SR_REG *p_sreg;
|
||||
UINT16 conn_id, offset = 0;
|
||||
BT_HDR *p_msg = NULL;
|
||||
memset(&sr_data, 0, sizeof(tGATTS_DATA));
|
||||
|
||||
if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
|
||||
|
@ -1011,10 +1011,10 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
|||
case GATT_REQ_PREPARE_WRITE:
|
||||
sr_data.write_req.is_prep = TRUE;
|
||||
STREAM_TO_UINT16(sr_data.write_req.offset, p);
|
||||
UINT16_TO_STREAM(p_m, sr_data.write_req.is_prep);
|
||||
offset = sr_data.write_req.offset;
|
||||
UINT16_TO_STREAM(p_m, sr_data.write_req.is_prep);
|
||||
offset = sr_data.write_req.offset;
|
||||
len -= 2;
|
||||
/* fall through */
|
||||
/* fall through */
|
||||
case GATT_SIGN_CMD_WRITE:
|
||||
if (op_code == GATT_SIGN_CMD_WRITE) {
|
||||
GATT_TRACE_DEBUG("Write CMD with data sigining" );
|
||||
|
@ -1025,10 +1025,10 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
|||
case GATT_REQ_WRITE:
|
||||
if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
|
||||
sr_data.write_req.need_rsp = TRUE;
|
||||
if(op_code == GATT_REQ_PREPARE_WRITE){
|
||||
memcpy(p_m, p, len);
|
||||
p_msg->len += len;
|
||||
}
|
||||
if(op_code == GATT_REQ_PREPARE_WRITE){
|
||||
memcpy(p_m, p, len);
|
||||
p_msg->len += len;
|
||||
}
|
||||
}
|
||||
sr_data.write_req.handle = handle;
|
||||
sr_data.write_req.len = len;
|
||||
|
@ -1053,24 +1053,31 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
|||
sec_flag,
|
||||
key_size);
|
||||
|
||||
p_msg->len += len;
|
||||
if (status == GATT_SUCCESS) {
|
||||
if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) {
|
||||
p_sreg = &gatt_cb.sr_reg[i_rcb];
|
||||
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
|
||||
status = gatts_write_attr_value_by_handle(gatt_cb.sr_reg[i_rcb].p_db,
|
||||
handle, offset, p, len);
|
||||
gatt_sr_send_req_callback(conn_id,
|
||||
trans_id,
|
||||
GATTS_REQ_TYPE_WRITE,
|
||||
&sr_data);
|
||||
status = gatts_write_attr_value_by_handle(gatt_cb.sr_reg[i_rcb].p_db,
|
||||
handle, offset, p, len);
|
||||
if((sr_data.write_req.need_rsp == TRUE) && (status == GATT_APP_RSP)){
|
||||
sr_data.write_req.need_rsp = TRUE;
|
||||
status = GATT_PENDING;
|
||||
}
|
||||
|
||||
else{
|
||||
sr_data.write_req.need_rsp = FALSE;
|
||||
}
|
||||
|
||||
gatt_sr_send_req_callback(conn_id,
|
||||
trans_id,
|
||||
GATTS_REQ_TYPE_WRITE,
|
||||
&sr_data);
|
||||
|
||||
if(status == GATT_SUCCESS){
|
||||
attp_send_sr_msg(p_tcb, p_msg);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
|
||||
if(status == GATT_SUCCESS){
|
||||
attp_send_sr_msg(p_tcb, p_msg);
|
||||
}else if(status == GATT_NOT_LONG){
|
||||
gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE);
|
||||
}
|
||||
status = GATT_PENDING;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("max pending command, send error\n");
|
||||
status = GATT_BUSY; /* max pending command, application error */
|
||||
|
@ -1078,23 +1085,24 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
|||
}
|
||||
|
||||
/* in theroy BUSY is not possible(should already been checked), protected check */
|
||||
if (status != GATT_PENDING && status != GATT_BUSY &&
|
||||
if (status != GATT_PENDING && status != GATT_BUSY && status != GATT_SUCCESS &&
|
||||
(op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) {
|
||||
gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatts_process_read_req
|
||||
**
|
||||
** Description This function is called to process the read request
|
||||
** from client.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
**
|
||||
** Function gatts_process_read_req
|
||||
**
|
||||
** Description This function is called to process the read request
|
||||
** from client.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code,
|
||||
UINT16 handle, UINT16 len, UINT8 *p_data)
|
||||
{
|
||||
|
@ -1140,7 +1148,8 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8
|
|||
p_msg->len += value_len;
|
||||
}
|
||||
|
||||
if (reason != GATT_SUCCESS && reason != GATT_PENDING) {
|
||||
|
||||
if (reason != GATT_SUCCESS && reason != GATT_PENDING && reason != GATT_STACK_RSP) {
|
||||
if (p_msg) {
|
||||
GKI_freebuf(p_msg);
|
||||
}
|
||||
|
@ -1148,9 +1157,11 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8
|
|||
/* in theroy BUSY is not possible(should already been checked), protected check */
|
||||
if (reason != GATT_BUSY) {
|
||||
gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
} else {
|
||||
attp_send_sr_msg(p_tcb, p_msg);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1376,24 +1387,24 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
|
|||
/* otherwise, ignore the pkt */
|
||||
} else {
|
||||
switch (op_code) {
|
||||
case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
|
||||
case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
|
||||
case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
|
||||
case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
|
||||
gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
|
||||
break;
|
||||
|
||||
case GATT_REQ_FIND_INFO: /* discover char descrptor */
|
||||
case GATT_REQ_FIND_INFO: /* discover char descrptor */
|
||||
gatts_process_find_info(p_tcb, op_code, len, p_data);
|
||||
break;
|
||||
|
||||
case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */
|
||||
case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */
|
||||
/* discover characteristic, discover char by UUID */
|
||||
gatts_process_read_by_type_req(p_tcb, op_code, len, p_data);
|
||||
break;
|
||||
|
||||
|
||||
case GATT_REQ_READ: /* read char/char descriptor value */
|
||||
case GATT_REQ_READ: /* read char/char descriptor value */
|
||||
case GATT_REQ_READ_BLOB:
|
||||
case GATT_REQ_WRITE: /* write char/char descriptor value */
|
||||
case GATT_REQ_WRITE: /* write char/char descriptor value */
|
||||
case GATT_CMD_WRITE:
|
||||
case GATT_SIGN_CMD_WRITE:
|
||||
case GATT_REQ_PREPARE_WRITE:
|
||||
|
|
|
@ -349,6 +349,7 @@ typedef struct {
|
|||
UINT16 handle;
|
||||
UINT16 offset;
|
||||
BOOLEAN is_long;
|
||||
BOOLEAN need_rsp;
|
||||
} tGATT_READ_REQ;
|
||||
|
||||
/* write request data */
|
||||
|
|
|
@ -25,6 +25,29 @@ Header Files
|
|||
|
||||
Macros
|
||||
^^^^^^
|
||||
|
||||
.. doxygendefine:: ESP_GATT_UUID_IMMEDIATE_ALERT_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_LINK_LOSS_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_TX_POWER_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_CURRENT_TIME_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_REF_TIME_UPDATE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_NEXT_DST_CHANGE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_GLUCOSE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_HEALTH_THERMOM_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_DEVICE_INFO_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_HEART_RATE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_PHONE_ALERT_STATUS_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_BATTERY_SERVICE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_BLOOD_PRESSURE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_ALERT_NTF_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_HID_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_SCAN_PARAMETERS_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_RUNNING_SPEED_CADENCE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_CYCLING_SPEED_CADENCE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_CYCLING_POWER_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_USER_DATA_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_WEIGHT_SCALE_SVC
|
||||
.. doxygendefine:: ESP_GATT_UUID_PRI_SERVICE
|
||||
.. doxygendefine:: ESP_GATT_UUID_SEC_SERVICE
|
||||
.. doxygendefine:: ESP_GATT_UUID_INCLUDE_SERVICE
|
||||
|
@ -74,6 +97,9 @@ Macros
|
|||
.. doxygendefine:: ESP_GATT_UUID_HID_BT_KB_INPUT
|
||||
.. doxygendefine:: ESP_GATT_UUID_HID_BT_KB_OUTPUT
|
||||
.. doxygendefine:: ESP_GATT_UUID_HID_BT_MOUSE_INPUT
|
||||
.. doxygendefine:: ESP_GATT_HEART_RATE_MEAS
|
||||
.. doxygendefine:: ESP_GATT_BODY_SENSOR_LOCATION
|
||||
.. doxygendefine:: ESP_GATT_HEART_RATE_CNTL_POINT
|
||||
.. doxygendefine:: ESP_GATT_UUID_BATTERY_LEVEL
|
||||
.. doxygendefine:: ESP_GATT_UUID_SC_CONTROL_POINT
|
||||
.. doxygendefine:: ESP_GATT_UUID_SENSOR_LOCATION
|
||||
|
@ -87,6 +113,8 @@ Macros
|
|||
.. doxygendefine:: ESP_GATT_ILLEGAL_HANDLE
|
||||
.. doxygendefine:: ESP_GATT_ATTR_HANDLE_MAX
|
||||
.. doxygendefine:: ESP_GATT_MAX_ATTR_LEN
|
||||
.. doxygendefine:: ESP_GATT_RSP_BY_APP
|
||||
.. doxygendefine:: ESP_GATT_AUTO_RSP
|
||||
.. doxygendefine:: ESP_GATT_IF_NONE
|
||||
|
||||
Type Definitions
|
||||
|
@ -126,9 +154,6 @@ Structures
|
|||
.. doxygenstruct:: esp_gatts_incl128_svc_desc_t
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: esp_gatts_char_desc_t
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: esp_gatt_value_t
|
||||
:members:
|
||||
|
||||
|
|
|
@ -80,9 +80,6 @@ Structures
|
|||
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_char_descr_evt_param
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_attr_tab_evt_param
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_delete_evt_param
|
||||
:members:
|
||||
|
||||
|
@ -104,6 +101,9 @@ Structures
|
|||
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_rsp_evt_param
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_attr_tab_evt_param
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_set_attr_val_evt_param
|
||||
:members:
|
||||
|
||||
|
|
|
@ -117,64 +117,6 @@ static struct gatts_profile_inst heart_rate_profile_tab[HEART_PROFILE_NUM] = {
|
|||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Full HRS Database Description - Used to add attributes into the database
|
||||
const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB] =
|
||||
{
|
||||
// Heart Rate Service Declaration
|
||||
[HRS_IDX_SVC] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_UUID_PRI_SERVICE}},
|
||||
ESP_GATT_PERM_READ,
|
||||
sizeof(heart_rate_svc),
|
||||
sizeof(heart_rate_svc), (uint8_t *)&heart_rate_svc}},
|
||||
|
||||
// Heart Rate Measurement Characteristic Declaration
|
||||
[HRS_IDX_HR_MEAS_CHAR] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}},
|
||||
ESP_GATT_PERM_READ,
|
||||
sizeof(heart_rate_meas_char),
|
||||
sizeof(heart_rate_meas_char), (uint8_t *)&heart_rate_meas_char}},
|
||||
// Heart Rate Measurement Characteristic Value
|
||||
[HRS_IDX_HR_MEAS_VAL] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_MEAS}},
|
||||
ESP_GATT_PERM_READ,
|
||||
HRPS_HT_MEAS_MAX_LEN,
|
||||
0, NULL}},
|
||||
|
||||
// Heart Rate Measurement Characteristic - Client Characteristic Configuration Descriptor
|
||||
[HRS_IDX_HR_MEAS_NTF_CFG] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_SRVR_CONFIG}},
|
||||
ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
|
||||
sizeof(uint16_t),
|
||||
0, NULL}},
|
||||
|
||||
// Body Sensor Location Characteristic Declaration
|
||||
[HRS_IDX_BOBY_SENSOR_LOC_CHAR] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}},
|
||||
ESP_GATT_PERM_READ,
|
||||
sizeof(heart_rate_body_sensor_loc_char),
|
||||
sizeof(heart_rate_body_sensor_loc_char), (uint8_t *)&heart_rate_body_sensor_loc_char}},
|
||||
|
||||
// Body Sensor Location Characteristic Value
|
||||
[HRS_IDX_BOBY_SENSOR_LOC_VAL] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_BODY_SENSOR_LOCATION}},
|
||||
ESP_GATT_PERM_READ,
|
||||
sizeof(uint8_t),
|
||||
0, NULL}},
|
||||
|
||||
// Heart Rate Control Point Characteristic Declaration
|
||||
[HRS_IDX_HR_CTNL_PT_CHAR] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}},
|
||||
ESP_GATT_PERM_READ,
|
||||
sizeof(heart_rate_cntl_point_char),
|
||||
sizeof(heart_rate_cntl_point_char), (uint8_t *)&heart_rate_cntl_point_char}},
|
||||
|
||||
// Heart Rate Control Point Characteristic Value
|
||||
[HRS_IDX_HR_CTNL_PT_VAL] = {{ESP_GATT_AUTO_RSP}, {
|
||||
{ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_CNTL_POINT}},
|
||||
ESP_GATT_PERM_WRITE,
|
||||
sizeof(uint8_t),
|
||||
0, NULL}},
|
||||
};
|
||||
|
||||
/*
|
||||
* Heart Rate PROFILE ATTRIBUTES
|
||||
|
@ -182,31 +124,75 @@ const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB] =
|
|||
*/
|
||||
|
||||
/// Heart Rate Sensor Service
|
||||
const uint16_t heart_rate_svc = ESP_GATT_UUID_HEART_RATE_SVC;
|
||||
static const uint16_t heart_rate_svc = ESP_GATT_UUID_HEART_RATE_SVC;
|
||||
|
||||
/// Heart Rate Sensor Service - Heart Rate Measurement Characteristic
|
||||
const esp_gatts_char_desc_t heart_rate_meas_char =
|
||||
#define CHAR_DECLARATION_SIZE (sizeof(uint8_t))
|
||||
static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
|
||||
static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
|
||||
static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
|
||||
static const uint8_t char_prop_notify = ESP_GATT_CHAR_PROP_BIT_NOTIFY;
|
||||
static const uint8_t char_prop_read = ESP_GATT_CHAR_PROP_BIT_READ;
|
||||
static const uint8_t char_prop_read_write = ESP_GATT_CHAR_PROP_BIT_WRITE|ESP_GATT_CHAR_PROP_BIT_READ;
|
||||
|
||||
/// Heart Rate Sensor Service - Heart Rate Measurement Characteristic, notify
|
||||
static const uint16_t heart_rate_meas_uuid = ESP_GATT_HEART_RATE_MEAS;
|
||||
static const uint8_t heart_measurement_ccc[2] ={ 0x00, 0x00};
|
||||
|
||||
|
||||
/// Heart Rate Sensor Service -Body Sensor Location characteristic, read
|
||||
static const uint16_t body_sensor_location_uuid = ESP_GATT_BODY_SENSOR_LOCATION;
|
||||
static const uint8_t body_sensor_loc_val[1] = {0x00};
|
||||
|
||||
|
||||
/// Heart Rate Sensor Service - Heart Rate Control Point characteristic, write&read
|
||||
static const uint16_t heart_rate_ctrl_point = ESP_GATT_HEART_RATE_CNTL_POINT;
|
||||
static const uint8_t heart_ctrl_point[1] = {0x00};
|
||||
|
||||
/// Full HRS Database Description - Used to add attributes into the database
|
||||
static const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB] =
|
||||
{
|
||||
.prop = ESP_GATT_CHAR_PROP_BIT_NOTIFY,
|
||||
.attr_hdl = 0,
|
||||
.attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_MEAS}},
|
||||
// Heart Rate Service Declaration
|
||||
[HRS_IDX_SVC] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
|
||||
sizeof(uint16_t), sizeof(heart_rate_svc), (uint8_t *)&heart_rate_svc}},
|
||||
|
||||
// Heart Rate Measurement Characteristic Declaration
|
||||
[HRS_IDX_HR_MEAS_CHAR] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
|
||||
CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_notify}},
|
||||
|
||||
// Heart Rate Measurement Characteristic Value
|
||||
[HRS_IDX_HR_MEAS_VAL] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&heart_rate_meas_uuid, ESP_GATT_PERM_READ,
|
||||
HRPS_HT_MEAS_MAX_LEN,0, NULL}},
|
||||
|
||||
// Heart Rate Measurement Characteristic - Client Characteristic Configuration Descriptor
|
||||
[HRS_IDX_HR_MEAS_NTF_CFG] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
|
||||
sizeof(uint16_t),sizeof(heart_measurement_ccc), (uint8_t *)heart_measurement_ccc}},
|
||||
|
||||
// Body Sensor Location Characteristic Declaration
|
||||
[HRS_IDX_BOBY_SENSOR_LOC_CHAR] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
|
||||
CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read}},
|
||||
|
||||
// Body Sensor Location Characteristic Value
|
||||
[HRS_IDX_BOBY_SENSOR_LOC_VAL] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&body_sensor_location_uuid, ESP_GATT_PERM_READ,
|
||||
sizeof(uint8_t), sizeof(body_sensor_loc_val), (uint8_t *)body_sensor_loc_val}},
|
||||
|
||||
// Heart Rate Control Point Characteristic Declaration
|
||||
[HRS_IDX_HR_CTNL_PT_CHAR] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
|
||||
CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write}},
|
||||
|
||||
// Heart Rate Control Point Characteristic Value
|
||||
[HRS_IDX_HR_CTNL_PT_VAL] =
|
||||
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&heart_rate_ctrl_point, ESP_GATT_PERM_WRITE|ESP_GATT_PERM_READ,
|
||||
sizeof(uint8_t), sizeof(heart_ctrl_point), (uint8_t *)heart_ctrl_point}},
|
||||
};
|
||||
|
||||
/// Heart Rate Sensor Service -Body Sensor Location characteristic
|
||||
const esp_gatts_char_desc_t heart_rate_body_sensor_loc_char =
|
||||
{
|
||||
.prop = ESP_GATT_CHAR_PROP_BIT_READ,
|
||||
.attr_hdl = 0,
|
||||
.attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_BODY_SENSOR_LOCATION}},
|
||||
};
|
||||
|
||||
/// Heart Rate Sensor Service - Heart Rate Control Point characteristic
|
||||
const esp_gatts_char_desc_t heart_rate_cntl_point_char =
|
||||
{
|
||||
.prop = ESP_GATT_CHAR_PROP_BIT_WRITE,
|
||||
.attr_hdl = 0,
|
||||
.attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_CNTL_POINT}},
|
||||
};
|
||||
|
||||
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||||
{
|
||||
|
|
|
@ -46,12 +46,3 @@ enum
|
|||
|
||||
HRS_IDX_NB,
|
||||
};
|
||||
|
||||
|
||||
extern const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB];
|
||||
/// Heart Rate Sensor Service - only one instance for now
|
||||
extern const uint16_t heart_rate_svc;
|
||||
|
||||
extern const esp_gatts_char_desc_t heart_rate_meas_char;
|
||||
extern const esp_gatts_char_desc_t heart_rate_body_sensor_loc_char;
|
||||
extern const esp_gatts_char_desc_t heart_rate_cntl_point_char;
|
||||
|
|
Loading…
Reference in a new issue