* Description Send message to L2CAP.
*
******************************************************************************/
-tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, BT_HDR* p_toL2CAP) {
+tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t lcid,
+ BT_HDR* p_toL2CAP) {
uint16_t l2cap_ret;
- if (tcb.att_lcid == L2CAP_ATT_CID)
- l2cap_ret = L2CA_SendFixedChnlData(L2CAP_ATT_CID, tcb.peer_bda, p_toL2CAP);
+ if (lcid == L2CAP_ATT_CID)
+ l2cap_ret = L2CA_SendFixedChnlData(lcid, tcb.peer_bda, p_toL2CAP);
else
- l2cap_ret = (uint16_t)L2CA_DataWrite(tcb.att_lcid, p_toL2CAP);
+ l2cap_ret = (uint16_t)L2CA_DataWrite(lcid, p_toL2CAP);
if (l2cap_ret == L2CAP_DW_FAILED) {
LOG(ERROR) << __func__ << ": failed to write data to L2CAP";
*
*
******************************************************************************/
-tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, BT_HDR* p_msg) {
+tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_msg) {
if (p_msg == NULL) return GATT_NO_RESOURCES;
p_msg->offset = L2CAP_MIN_OFFSET;
- return attp_send_msg_to_l2cap(tcb, p_msg);
+ return attp_send_msg_to_l2cap(tcb, cid, p_msg);
}
/*******************************************************************************
uint8_t cmd_code, BT_HDR* p_cmd) {
cmd_code &= ~GATT_AUTH_SIGN_MASK;
- if (!tcb.cl_cmd_q.empty() && cmd_code != GATT_HANDLE_VALUE_CONF) {
+ if (gatt_tcb_is_cid_busy(tcb, p_clcb->cid) &&
+ cmd_code != GATT_HANDLE_VALUE_CONF) {
gatt_cmd_enq(tcb, p_clcb, true, cmd_code, p_cmd);
return GATT_CMD_STARTED;
}
/* no pending request or value confirmation */
- tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, p_cmd);
+ tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, p_clcb->cid, p_cmd);
if (att_ret != GATT_CONGESTED && att_ret != GATT_SUCCESS) {
return GATT_INTERNAL_ERROR;
}
uint8_t op_code, tGATT_CL_MSG* p_msg) {
BT_HDR* p_cmd = NULL;
uint16_t offset = 0, handle;
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);
+
switch (op_code) {
case GATT_REQ_MTU:
if (p_msg->mtu > GATT_MAX_MTU_SIZE) return GATT_ILLEGAL_PARAMETER;
return GATT_ILLEGAL_PARAMETER;
p_cmd = attp_build_value_cmd(
- tcb.payload_size, op_code, p_msg->attr_value.handle, offset,
+ payload_size, op_code, p_msg->attr_value.handle, offset,
p_msg->attr_value.len, p_msg->attr_value.value);
break;
break;
case GATT_REQ_FIND_TYPE_VALUE:
- p_cmd = attp_build_read_by_type_value_cmd(tcb.payload_size,
+ p_cmd = attp_build_read_by_type_value_cmd(payload_size,
&p_msg->find_type_value);
break;
case GATT_REQ_READ_MULTI:
- p_cmd = attp_build_read_multi_cmd(tcb.payload_size,
- p_msg->read_multi.num_handles,
- p_msg->read_multi.handles);
+ p_cmd =
+ attp_build_read_multi_cmd(payload_size, p_msg->read_multi.num_handles,
+ p_msg->read_multi.handles);
break;
default:
memcpy(indication.value, p_val, val_len);
indication.auth_req = GATT_AUTH_REQ_NONE;
- if (GATT_HANDLE_IS_VALID(p_tcb->indicate_handle)) {
+ uint16_t* indicate_handle_p = NULL;
+ uint16_t cid;
+
+ if (!gatt_tcb_get_cid_available_for_indication(p_tcb, p_reg->eatt_support,
+ &indicate_handle_p, &cid)) {
VLOG(1) << "Add a pending indication";
gatt_add_pending_ind(p_tcb, &indication);
return GATT_SUCCESS;
attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_IND, &gatt_sr_msg);
if (!p_msg) return GATT_NO_RESOURCES;
- tGATT_STATUS cmd_status = attp_send_sr_msg(*p_tcb, p_msg);
+ tGATT_STATUS cmd_status = attp_send_sr_msg(*p_tcb, cid, p_msg);
if (cmd_status == GATT_SUCCESS || cmd_status == GATT_CONGESTED) {
- p_tcb->indicate_handle = indication.handle;
+ *indicate_handle_p = indication.handle;
gatt_start_conf_timer(p_tcb);
}
return cmd_status;
tGATT_STATUS cmd_sent;
tGATT_SR_MSG gatt_sr_msg;
gatt_sr_msg.attr_value = notif;
+
+ uint16_t cid = gatt_tcb_get_att_cid(*p_tcb);
+
BT_HDR* p_buf =
attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_NOTIF, &gatt_sr_msg);
if (p_buf != NULL) {
- cmd_sent = attp_send_sr_msg(*p_tcb, p_buf);
+ cmd_sent = attp_send_sr_msg(*p_tcb, cid, p_buf);
} else
cmd_sent = GATT_NO_RESOURCES;
return cmd_sent;
******************************************************************************/
tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id,
tGATT_STATUS status, tGATTS_RSP* p_msg) {
- tGATT_STATUS cmd_sent = GATT_ILLEGAL_PARAMETER;
tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
return (tGATT_STATUS)GATT_INVALID_CONN_ID;
}
- if (p_tcb->sr_cmd.trans_id != trans_id) {
+ tGATT_SR_CMD* sr_res_p = gatt_sr_get_cmd_by_trans_id(p_tcb, trans_id);
+
+ if (!sr_res_p) {
LOG(ERROR) << "conn_id=" << loghex(conn_id)
- << " waiting for op_code=" << loghex(p_tcb->sr_cmd.op_code);
+ << " waiting for other op_code ";
return (GATT_WRONG_STATE);
}
- /* Process App response */
- cmd_sent = gatt_sr_process_app_rsp(*p_tcb, gatt_if, trans_id,
- p_tcb->sr_cmd.op_code, status, p_msg);
- return cmd_sent;
+ /* Process App response */
+ return gatt_sr_process_app_rsp(*p_tcb, gatt_if, trans_id, sr_res_p->op_code,
+ status, p_msg, sr_res_p);
}
/******************************************************************************/
tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
if (!p_clcb) return GATT_NO_RESOURCES;
+ /* For this request only ATT CID is valid */
+ p_clcb->cid = L2CAP_ATT_CID;
p_clcb->p_tcb->payload_size = mtu;
p_clcb->operation = GATTC_OPTYPE_CONFIG;
tGATT_CL_MSG gatt_cl_msg;
p_clcb->op_subtype = type;
p_clcb->auth_req = p_read->by_handle.auth_req;
p_clcb->counter = 0;
- p_clcb->read_req_current_mtu = p_tcb->payload_size;
+ p_clcb->read_req_current_mtu =
+ gatt_tcb_get_payload_size_tx(*p_tcb, p_clcb->cid);
switch (type) {
case GATT_READ_BY_TYPE:
* Returns
*
******************************************************************************/
-void gatt_verify_signature(tGATT_TCB& tcb, BT_HDR* p_buf) {
+void gatt_verify_signature(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) {
uint16_t cmd_len;
uint8_t op_code;
uint8_t *p, *p_orig = (uint8_t*)(p_buf + 1) + p_buf->offset;
}
STREAM_TO_UINT8(op_code, p_orig);
- gatt_server_handle_client_req(tcb, op_code, (uint16_t)(p_buf->len - 1),
+ gatt_server_handle_client_req(tcb, cid, op_code, (uint16_t)(p_buf->len - 1),
p_orig);
}
/*******************************************************************************
*
******************************************************************************/
-#include "bt_target.h"
-
#include <string.h>
+
#include "bt_common.h"
+#include "bt_target.h"
#include "bt_utils.h"
#include "gatt_int.h"
#include "l2c_api.h"
CHECK(p_clcb->p_attr_buf);
tGATT_VALUE& attr = *((tGATT_VALUE*)p_clcb->p_attr_buf);
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);
+
switch (p_clcb->op_subtype) {
case GATT_WRITE_NO_RSP: {
p_clcb->s_handle = attr.handle;
}
case GATT_WRITE: {
- if (attr.len <= (tcb.payload_size - GATT_HDR_SIZE)) {
+ if (attr.len <= (payload_size - GATT_HDR_SIZE)) {
p_clcb->s_handle = attr.handle;
uint8_t rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_WRITE,
VLOG(1) << __func__ << StringPrintf(" type=0x%x", type);
uint16_t to_send = p_attr->len - p_attr->offset;
- if (to_send > (tcb.payload_size -
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);
+ if (to_send > (payload_size -
GATT_WRITE_LONG_HDR_SIZE)) /* 2 = uint16_t offset bytes */
- to_send = tcb.payload_size - GATT_WRITE_LONG_HDR_SIZE;
+ to_send = payload_size - GATT_WRITE_LONG_HDR_SIZE;
p_clcb->s_handle = p_attr->handle;
}
STREAM_TO_UINT8(value_len, p);
-
- if ((value_len > (tcb.payload_size - 2)) || (value_len > (len - 1))) {
+ uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, p_clcb->cid);
+ if ((value_len > (payload_size - 2)) || (value_len > (len - 1))) {
/* this is an error case that server's response containing a value length
which is larger than MTU-2
or value_len > message total length -1 */
<< StringPrintf(
": Discard response op_code=%d "
"vale_len=%d > (MTU-2=%d or msg_len-1=%d)",
- op_code, value_len, (tcb.payload_size - 2), (len - 1));
+ op_code, value_len, (payload_size - 2), (len - 1));
gatt_end_operation(p_clcb, GATT_ERROR, NULL);
return;
}
p_clcb->op_subtype == GATT_READ_BY_TYPE) {
p_clcb->counter = len - 2;
p_clcb->s_handle = handle;
- if (p_clcb->counter == (p_clcb->p_tcb->payload_size - 4)) {
+ if (p_clcb->counter == (payload_size - 4)) {
p_clcb->op_subtype = GATT_READ_BY_HANDLE;
if (!p_clcb->p_attr_buf)
p_clcb->p_attr_buf = (uint8_t*)osi_malloc(GATT_MAX_ATTR_LEN);
uint16_t offset = p_clcb->counter;
uint8_t* p = p_data;
+ uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, p_clcb->cid);
+
if (p_clcb->operation == GATTC_OPTYPE_READ) {
if (p_clcb->op_subtype != GATT_READ_BY_HANDLE) {
p_clcb->counter = len;
/* full packet for read or read blob rsp */
bool packet_is_full;
- if (tcb.payload_size == p_clcb->read_req_current_mtu) {
- packet_is_full = (len == (tcb.payload_size - 1));
+ if (payload_size == p_clcb->read_req_current_mtu) {
+ packet_is_full = (len == (payload_size - 1));
} else {
packet_is_full = (len == (p_clcb->read_req_current_mtu - 1) ||
- len == (tcb.payload_size - 1));
- p_clcb->read_req_current_mtu = tcb.payload_size;
+ len == (payload_size - 1));
+ p_clcb->read_req_current_mtu = payload_size;
}
/* send next request if needed */
/** Find next command in queue and sent to server */
bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) {
+ std::queue<tGATT_CMD_Q>* cl_cmd_q;
+
while (!tcb.cl_cmd_q.empty()) {
- tGATT_CMD_Q& cmd = tcb.cl_cmd_q.front();
- if (!cmd.to_send || cmd.p_cmd == NULL) return false;
+ if (!tcb.cl_cmd_q.empty()) {
+ cl_cmd_q = &tcb.cl_cmd_q;
+ }
+
+ tGATT_CMD_Q& cmd = cl_cmd_q->front();
+ if (!cmd.to_send || cmd.p_cmd == NULL) {
+ return false;
+ }
+
+ tGATT_STATUS att_ret;
+ att_ret = attp_send_msg_to_l2cap(tcb, cmd.cid, cmd.p_cmd);
- tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, cmd.p_cmd);
if (att_ret != GATT_SUCCESS && att_ret != GATT_CONGESTED) {
LOG(ERROR) << __func__ << ": L2CAP sent error";
- tcb.cl_cmd_q.pop();
+ cl_cmd_q->pop();
continue;
}
if (cmd.op_code == GATT_CMD_WRITE || cmd.op_code == GATT_SIGN_CMD_WRITE) {
/* dequeue the request if is write command or sign write */
uint8_t rsp_code;
- tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &rsp_code);
+ tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, cmd.cid, &rsp_code);
/* send command complete callback here */
gatt_end_operation(p_clcb, att_ret, NULL);
}
/** This function is called to handle the server response to client */
-void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code,
- uint16_t len, uint8_t* p_data) {
+void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data) {
+ VLOG(1) << __func__ << " opcode: " << loghex(op_code);
+
+ uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, cid);
+
if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF) {
- if (len >= tcb.payload_size) {
+ if (len >= payload_size) {
LOG(ERROR) << StringPrintf(
"%s: invalid indicate pkt size: %d, PDU size: %d", __func__, len + 1,
- tcb.payload_size);
+ payload_size);
return;
}
}
uint8_t cmd_code = 0;
- tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &cmd_code);
+ tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, cid, &cmd_code);
uint8_t rsp_code = gatt_cmd_to_rsp_code(cmd_code);
if (!p_clcb || (rsp_code != op_code && op_code != GATT_RSP_ERROR)) {
LOG(WARNING) << StringPrintf(
return;
}
- alarm_cancel(p_clcb->gatt_rsp_timer_ent);
+ gatt_stop_rsp_timer(p_clcb);
p_clcb->retry_count = 0;
/* the size of the message may not be bigger than the local max PDU size*/
/* The message has to be smaller than the agreed MTU, len does not count
* op_code */
- if (len >= tcb.payload_size) {
+ if (len >= payload_size) {
LOG(ERROR) << StringPrintf(
"%s: invalid response pkt size: %d, PDU size: %d", __func__, len + 1,
- tcb.payload_size);
+ payload_size);
gatt_end_operation(p_clcb, GATT_ERROR, NULL);
} else {
switch (op_code) {
static tGATT_ATTR& allocate_attr_in_db(tGATT_SVC_DB& db, const Uuid& uuid,
tGATT_PERM perm);
static tGATT_STATUS gatts_send_app_read_request(
- tGATT_TCB& tcb, uint8_t op_code, uint16_t handle, uint16_t offset,
- uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type);
+ tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t handle,
+ uint16_t offset, uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type);
/**
* Initialize a memory space to be a service database.
*
******************************************************************************/
tGATT_STATUS gatts_db_read_attr_value_by_type(
- tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, BT_HDR* p_rsp,
- uint16_t s_handle, uint16_t e_handle, const Uuid& type, uint16_t* p_len,
- tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id,
- uint16_t* p_cur_handle) {
+ tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
+ BT_HDR* p_rsp, uint16_t s_handle, uint16_t e_handle, const Uuid& type,
+ uint16_t* p_len, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
+ uint32_t trans_id, uint16_t* p_cur_handle) {
tGATT_STATUS status = GATT_NOT_FOUND;
uint16_t len = 0;
uint8_t* p = (uint8_t*)(p_rsp + 1) + p_rsp->len + L2CAP_MIN_OFFSET;
&len, sec_flag, key_size);
if (status == GATT_PENDING) {
- status = gatts_send_app_read_request(tcb, op_code, attr.handle, 0,
- trans_id, attr.gatt_type);
+ status = gatts_send_app_read_request(tcb, cid, op_code, attr.handle,
+ 0, trans_id, attr.gatt_type);
/* one callback at a time */
break;
*
******************************************************************************/
tGATT_STATUS gatts_read_attr_value_by_handle(
- tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, uint16_t handle,
- uint16_t offset, uint8_t* p_value, uint16_t* p_len, uint16_t mtu,
- tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id) {
+ tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
+ uint16_t handle, uint16_t offset, uint8_t* p_value, uint16_t* p_len,
+ uint16_t mtu, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
+ uint32_t trans_id) {
tGATT_ATTR* p_attr = find_attr_by_handle(p_db, handle);
if (!p_attr) return GATT_NOT_FOUND;
mtu, p_len, sec_flag, key_size);
if (status == GATT_PENDING) {
- status = gatts_send_app_read_request(tcb, op_code, p_attr->handle, offset,
- trans_id, p_attr->gatt_type);
+ status = gatts_send_app_read_request(tcb, cid, op_code, p_attr->handle,
+ offset, trans_id, p_attr->gatt_type);
}
return status;
}
*
******************************************************************************/
static tGATT_STATUS gatts_send_app_read_request(
- tGATT_TCB& tcb, uint8_t op_code, uint16_t handle, uint16_t offset,
- uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type) {
+ tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t handle,
+ uint16_t offset, uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type) {
tGATT_SRV_LIST_ELEM& el = *gatt_sr_find_i_rcb_by_handle(handle);
uint16_t conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, el.gatt_if);
if (trans_id == 0) {
- trans_id = gatt_sr_enqueue_cmd(tcb, op_code, handle);
- gatt_sr_update_cback_cnt(tcb, el.gatt_if, true, true);
+ trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, handle);
+ gatt_sr_update_cback_cnt(tcb, cid, el.gatt_if, true, true);
}
if (trans_id != 0) {
tGATT_CLCB* p_clcb;
uint8_t op_code;
bool to_send;
+ uint16_t cid;
} tGATT_CMD_Q;
#if GATT_MAX_SR_PROFILES <= 8
uint8_t op_code;
uint8_t status;
uint8_t cback_cnt[GATT_MAX_APPS];
+ uint16_t cid;
} tGATT_SR_CMD;
#define GATT_CH_CLOSE 0
uint8_t retry_count;
uint16_t read_req_current_mtu; /* This is the MTU value that the read was
initiated with */
+ uint16_t cid;
};
typedef struct {
extern bool gatt_connect(const RawAddress& rem_bda, tGATT_TCB* p_tcb,
tBT_TRANSPORT transport, uint8_t initiating_phys,
tGATT_IF gatt_if);
-extern void gatt_data_process(tGATT_TCB& p_tcb, BT_HDR* p_buf);
+extern void gatt_data_process(tGATT_TCB& p_tcb, uint16_t cid, BT_HDR* p_buf);
extern void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
bool is_add, bool check_acl_link);
uint8_t op_code, tGATT_CL_MSG* p_msg);
extern BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code,
tGATT_SR_MSG* p_msg);
-extern tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, BT_HDR* p_msg);
-extern tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, BT_HDR* p_toL2CAP);
+extern tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid,
+ BT_HDR* p_msg);
+extern tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t cid,
+ BT_HDR* p_toL2CAP);
/* utility functions */
extern uint8_t* gatt_dbg_op_name(uint8_t op_code);
tBT_TRANSPORT transport, uint8_t* p_sec_flag,
uint8_t* p_key_size);
extern void gatt_start_rsp_timer(tGATT_CLCB* p_clcb);
+extern void gatt_stop_rsp_timer(tGATT_CLCB* p_clcb);
extern void gatt_start_conf_timer(tGATT_TCB* p_tcb);
extern void gatt_rsp_timeout(void* data);
extern void gatt_indication_confirmation_timeout(void* data);
extern void gatt_ind_ack_timeout(void* data);
extern void gatt_start_ind_ack_timer(tGATT_TCB& tcb);
-extern tGATT_STATUS gatt_send_error_rsp(tGATT_TCB& tcb, uint8_t err_code,
- uint8_t op_code, uint16_t handle,
- bool deq);
+extern tGATT_STATUS gatt_send_error_rsp(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t err_code, uint8_t op_code,
+ uint16_t handle, bool deq);
extern bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb);
extern tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(
extern tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if,
uint32_t trans_id, uint8_t op_code,
tGATT_STATUS status,
- tGATTS_RSP* p_msg);
-extern void gatt_server_handle_client_req(tGATT_TCB& p_tcb, uint8_t op_code,
- uint16_t len, uint8_t* p_data);
+ tGATTS_RSP* p_msg,
+ tGATT_SR_CMD* sr_res_p);
+extern void gatt_server_handle_client_req(tGATT_TCB& p_tcb, uint16_t cid,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data);
extern void gatt_sr_send_req_callback(uint16_t conn_id, uint32_t trans_id,
uint8_t op_code, tGATTS_DATA* p_req_data);
-extern uint32_t gatt_sr_enqueue_cmd(tGATT_TCB& tcb, uint8_t op_code,
- uint16_t handle);
+extern uint32_t gatt_sr_enqueue_cmd(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t op_code, uint16_t handle);
extern bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda);
extern void gatt_notify_phy_updated(uint8_t status, uint16_t handle,
uint8_t tx_phy, uint8_t rx_phy);
/* */
+extern bool gatt_tcb_is_cid_busy(tGATT_TCB& tcb, uint16_t cid);
+
extern tGATT_REG* gatt_get_regcb(tGATT_IF gatt_if);
extern bool gatt_is_clcb_allocated(uint16_t conn_id);
extern tGATT_CLCB* gatt_clcb_alloc(uint16_t conn_id);
+
+extern bool gatt_tcb_get_cid_available_for_indication(
+ tGATT_TCB* p_tcb, bool eatt_support, uint16_t** indicate_handle_p,
+ uint16_t* cid_p);
+extern bool gatt_tcb_find_indicate_handle(tGATT_TCB& tcb, uint16_t cid,
+ uint16_t* indicated_handle_p);
+extern uint16_t gatt_tcb_get_att_cid(tGATT_TCB& tcb);
+extern uint16_t gatt_tcb_get_payload_size_tx(tGATT_TCB& tcb, uint16_t cid);
+extern uint16_t gatt_tcb_get_payload_size_rx(tGATT_TCB& tcb, uint16_t cid);
extern void gatt_clcb_dealloc(tGATT_CLCB* p_clcb);
extern void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB& p_tcb);
extern bool gatt_sr_is_cback_cnt_zero(tGATT_TCB& p_tcb);
extern bool gatt_sr_is_prep_cnt_zero(tGATT_TCB& p_tcb);
-extern void gatt_sr_reset_cback_cnt(tGATT_TCB& p_tcb);
+extern void gatt_sr_reset_cback_cnt(tGATT_TCB& p_tcb, uint16_t cid);
extern void gatt_sr_reset_prep_cnt(tGATT_TCB& tcb);
-extern void gatt_sr_update_cback_cnt(tGATT_TCB& p_tcb, tGATT_IF gatt_if,
- bool is_inc, bool is_reset_first);
+extern tGATT_SR_CMD* gatt_sr_get_cmd_by_trans_id(tGATT_TCB* p_tcb,
+ uint32_t trans_id);
+extern tGATT_SR_CMD* gatt_sr_get_cmd_by_cid(tGATT_TCB& tcb, uint16_t cid);
+extern void gatt_sr_update_cback_cnt(tGATT_TCB& p_tcb, uint16_t cid,
+ tGATT_IF gatt_if, bool is_inc,
+ bool is_reset_first);
extern void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if,
bool is_inc, bool is_reset_first);
extern void gatt_act_discovery(tGATT_CLCB* p_clcb);
extern void gatt_act_read(tGATT_CLCB* p_clcb, uint16_t offset);
extern void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act);
-extern tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint8_t* p_opcode);
+extern tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t* p_opcode);
extern void gatt_cmd_enq(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, bool to_send,
uint8_t op_code, BT_HDR* p_buf);
-extern void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code,
- uint16_t len, uint8_t* p_data);
+extern void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data);
extern void gatt_send_queue_write_cancel(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
tGATT_EXEC_FLAG flag);
/* gatt_auth.cc */
extern bool gatt_security_check_start(tGATT_CLCB* p_clcb);
-extern void gatt_verify_signature(tGATT_TCB& tcb, BT_HDR* p_buf);
+extern void gatt_verify_signature(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf);
extern tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB& tcb);
extern tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB* p_tcb);
extern void gatt_set_sec_act(tGATT_TCB* p_tcb, tGATT_SEC_ACTION sec_act);
extern uint16_t gatts_add_char_descr(tGATT_SVC_DB& db, tGATT_PERM perm,
const bluetooth::Uuid& dscp_uuid);
extern tGATT_STATUS gatts_db_read_attr_value_by_type(
- tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, BT_HDR* p_rsp,
- uint16_t s_handle, uint16_t e_handle, const bluetooth::Uuid& type,
- uint16_t* p_len, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
- uint32_t trans_id, uint16_t* p_cur_handle);
+ tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
+ BT_HDR* p_rsp, uint16_t s_handle, uint16_t e_handle,
+ const bluetooth::Uuid& type, uint16_t* p_len, tGATT_SEC_FLAG sec_flag,
+ uint8_t key_size, uint32_t trans_id, uint16_t* p_cur_handle);
extern tGATT_STATUS gatts_read_attr_value_by_handle(
- tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, uint16_t handle,
- uint16_t offset, uint8_t* p_value, uint16_t* p_len, uint16_t mtu,
- tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id);
+ tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
+ uint16_t handle, uint16_t offset, uint8_t* p_value, uint16_t* p_len,
+ uint16_t mtu, tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id);
extern tGATT_STATUS gatts_write_attr_perm_check(
tGATT_SVC_DB* p_db, uint8_t op_code, uint16_t handle, uint16_t offset,
uint8_t* p_data, uint16_t len, tGATT_SEC_FLAG sec_flag, uint8_t key_size);
LOG(WARNING) << "ATT - Ignored L2CAP data while in state: "
<< +gatt_get_ch_state(p_tcb);
} else
- gatt_data_process(*p_tcb, p_buf);
+ gatt_data_process(*p_tcb, L2CAP_ATT_CID, p_buf);
}
osi_free(p_buf);
tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
if (p_tcb && gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
/* process the data */
- gatt_data_process(*p_tcb, p_buf);
+ gatt_data_process(*p_tcb, lcid, p_buf);
}
osi_free(p_buf);
* Returns void
*
******************************************************************************/
-void gatt_data_process(tGATT_TCB& tcb, BT_HDR* p_buf) {
+void gatt_data_process(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) {
uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
uint8_t op_code, pseudo_op_code;
*/
LOG(ERROR) << __func__
<< ": ATT - Rcvd L2CAP data, unknown cmd: " << loghex(op_code);
- gatt_send_error_rsp(tcb, GATT_REQ_NOT_SUPPORTED, op_code, 0, false);
+ gatt_send_error_rsp(tcb, cid, GATT_REQ_NOT_SUPPORTED, op_code, 0, false);
return;
}
if (op_code == GATT_SIGN_CMD_WRITE) {
- gatt_verify_signature(tcb, p_buf);
+ gatt_verify_signature(tcb, cid, p_buf);
} else {
/* message from client */
if ((op_code % 2) == 0)
- gatt_server_handle_client_req(tcb, op_code, msg_len, p);
+ gatt_server_handle_client_req(tcb, cid, op_code, msg_len, p);
else
- gatt_client_handle_server_rsp(tcb, op_code, msg_len, p);
+ gatt_client_handle_server_rsp(tcb, cid, op_code, msg_len, p);
}
}
* this file contains the GATT server functions
*
******************************************************************************/
-
#include "bt_target.h"
#include "osi/include/osi.h"
* Returns void
*
******************************************************************************/
-uint32_t gatt_sr_enqueue_cmd(tGATT_TCB& tcb, uint8_t op_code, uint16_t handle) {
+uint32_t gatt_sr_enqueue_cmd(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
+ uint16_t handle) {
tGATT_SR_CMD* p_cmd = &tcb.sr_cmd;
+
uint32_t trans_id = 0;
+ p_cmd->cid = cid;
+
if ((p_cmd->op_code == 0) ||
(op_code == GATT_HANDLE_VALUE_CONF)) /* no pending request */
{
tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if,
UNUSED_ATTR uint32_t trans_id,
uint8_t op_code, tGATT_STATUS status,
- tGATTS_RSP* p_msg) {
+ tGATTS_RSP* p_msg,
+ tGATT_SR_CMD* sr_res_p) {
tGATT_STATUS ret_code = GATT_SUCCESS;
+ uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, sr_res_p->cid);
VLOG(1) << __func__ << " gatt_if=" << +gatt_if;
- gatt_sr_update_cback_cnt(tcb, gatt_if, false, false);
+ gatt_sr_update_cback_cnt(tcb, sr_res_p->cid, gatt_if, false, false);
if (op_code == GATT_REQ_READ_MULTI) {
/* If no error and still waiting, just return */
- if (!process_read_multi_rsp(&tcb.sr_cmd, status, p_msg, tcb.payload_size))
+ if (!process_read_multi_rsp(sr_res_p, status, p_msg, payload_size))
return (GATT_SUCCESS);
} else {
if (op_code == GATT_REQ_PREPARE_WRITE && status == GATT_SUCCESS)
gatt_sr_update_prep_cnt(tcb, gatt_if, true, false);
if (op_code == GATT_REQ_EXEC_WRITE && status != GATT_SUCCESS)
- gatt_sr_reset_cback_cnt(tcb);
+ gatt_sr_reset_cback_cnt(tcb, sr_res_p->cid);
- tcb.sr_cmd.status = status;
+ sr_res_p->status = status;
if (gatt_sr_is_cback_cnt_zero(tcb) && status == GATT_SUCCESS) {
- if (tcb.sr_cmd.p_rsp_msg == NULL) {
- tcb.sr_cmd.p_rsp_msg = attp_build_sr_msg(tcb, (uint8_t)(op_code + 1),
- (tGATT_SR_MSG*)p_msg);
+ if (sr_res_p->p_rsp_msg == NULL) {
+ sr_res_p->p_rsp_msg = attp_build_sr_msg(tcb, (uint8_t)(op_code + 1),
+ (tGATT_SR_MSG*)p_msg);
} else {
LOG(ERROR) << "Exception!!! already has respond message";
}
}
}
if (gatt_sr_is_cback_cnt_zero(tcb)) {
- if ((tcb.sr_cmd.status == GATT_SUCCESS) && (tcb.sr_cmd.p_rsp_msg)) {
- ret_code = attp_send_sr_msg(tcb, tcb.sr_cmd.p_rsp_msg);
- tcb.sr_cmd.p_rsp_msg = NULL;
+ if ((sr_res_p->status == GATT_SUCCESS) && (sr_res_p->p_rsp_msg)) {
+ ret_code = attp_send_sr_msg(tcb, sr_res_p->cid, sr_res_p->p_rsp_msg);
+ sr_res_p->p_rsp_msg = NULL;
} else {
- ret_code =
- gatt_send_error_rsp(tcb, status, op_code, tcb.sr_cmd.handle, false);
+ ret_code = gatt_send_error_rsp(tcb, sr_res_p->cid, status, op_code,
+ sr_res_p->handle, false);
}
gatt_dequeue_sr_cmd(tcb);
* Returns void
*
******************************************************************************/
-void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code, uint16_t len,
- uint8_t* p_data) {
+void gatt_process_exec_write_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
+ uint16_t len, uint8_t* p_data) {
uint8_t *p = p_data, flag, i = 0;
uint32_t trans_id = 0;
tGATT_IF gatt_if;
<< "Conformance tst: forced err rspv for Execute Write: error status="
<< +gatt_cb.err_status;
- gatt_send_error_rsp(tcb, gatt_cb.err_status, gatt_cb.req_op_code,
+ gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code,
gatt_cb.handle, false);
return;
if (len < sizeof(flag)) {
android_errorWriteLog(0x534e4554, "73172115");
LOG(ERROR) << __func__ << "invalid length";
- gatt_send_error_rsp(tcb, GATT_INVALID_PDU, GATT_REQ_EXEC_WRITE, 0, false);
+ gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, GATT_REQ_EXEC_WRITE, 0,
+ false);
return;
}
/* no prep write is queued */
if (!gatt_sr_is_prep_cnt_zero(tcb)) {
- trans_id = gatt_sr_enqueue_cmd(tcb, op_code, 0);
+ trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, 0);
gatt_sr_copy_prep_cnt_to_cback_cnt(tcb);
for (i = 0; i < GATT_MAX_APPS; i++) {
} else /* nothing needs to be executed , send response now */
{
LOG(ERROR) << "gatt_process_exec_write_req: no prepare write pending";
- gatt_send_error_rsp(tcb, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, false);
+ gatt_send_error_rsp(tcb, cid, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, false);
}
}
* Returns void
*
******************************************************************************/
-void gatt_process_read_multi_req(tGATT_TCB& tcb, uint8_t op_code, uint16_t len,
- uint8_t* p_data) {
+void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
+ uint16_t len, uint8_t* p_data) {
uint32_t trans_id;
uint16_t handle = 0, ll = len;
uint8_t* p = p_data;
STREAM_TO_UINT16(handle, p);
- gatt_send_error_rsp(tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle,
- false);
+ gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code,
+ handle, false);
return;
}
if (err == GATT_SUCCESS) {
trans_id =
- gatt_sr_enqueue_cmd(tcb, op_code, tcb.sr_cmd.multi_req.handles[0]);
+ gatt_sr_enqueue_cmd(tcb, cid, op_code, tcb.sr_cmd.multi_req.handles[0]);
if (trans_id != 0) {
- gatt_sr_reset_cback_cnt(tcb); /* read multiple use multi_rsp_q's count*/
+ tGATT_SR_CMD* sr_cmd_p = gatt_sr_get_cmd_by_cid(tcb, cid);
+
+ gatt_sr_reset_cback_cnt(tcb,
+ cid); /* read multiple use multi_rsp_q's count*/
for (ll = 0; ll < tcb.sr_cmd.multi_req.num_handles; ll++) {
tGATTS_RSP* p_msg = (tGATTS_RSP*)osi_calloc(sizeof(tGATTS_RSP));
p_msg->attr_value.handle = handle;
err = gatts_read_attr_value_by_handle(
- tcb, it->p_db, op_code, handle, 0, p_msg->attr_value.value,
+ tcb, cid, it->p_db, op_code, handle, 0, p_msg->attr_value.value,
&p_msg->attr_value.len, GATT_MAX_ATTR_LEN, sec_flag, key_size,
trans_id);
if (err == GATT_SUCCESS) {
gatt_sr_process_app_rsp(tcb, it->gatt_if, trans_id, op_code,
- GATT_SUCCESS, p_msg);
+ GATT_SUCCESS, p_msg, sr_cmd_p);
}
/* either not using or done using the buffer, release it now */
osi_free(p_msg);
/* in theroy BUSY is not possible(should already been checked), protected
* check */
if (err != GATT_SUCCESS && err != GATT_PENDING && err != GATT_BUSY)
- gatt_send_error_rsp(tcb, err, op_code, handle, false);
+ gatt_send_error_rsp(tcb, cid, err, op_code, handle, false);
}
/*******************************************************************************
*
******************************************************************************/
static tGATT_STATUS gatt_build_primary_service_rsp(
- BT_HDR* p_msg, tGATT_TCB& tcb, uint8_t op_code, uint16_t s_hdl,
- uint16_t e_hdl, UNUSED_ATTR uint8_t* p_data, const Uuid& value) {
+ BT_HDR* p_msg, tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
+ uint16_t s_hdl, uint16_t e_hdl, UNUSED_ATTR uint8_t* p_data,
+ const Uuid& value) {
tGATT_STATUS status = GATT_NOT_FOUND;
uint8_t handle_len = 4;
uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
+
for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
if (el.s_hdl < s_hdl || el.s_hdl > e_hdl ||
el.type != GATT_UUID_PRI_SERVICE) {
}
}
- if (p_msg->len + p_msg->offset > tcb.payload_size ||
+ if (p_msg->len + p_msg->offset > payload_size ||
handle_len != p_msg->offset) {
break;
}
* Returns void
*
******************************************************************************/
-void gatts_process_primary_service_req(tGATT_TCB& tcb, uint8_t op_code,
- uint16_t len, uint8_t* p_data) {
+void gatts_process_primary_service_req(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data) {
uint16_t s_hdl = 0, e_hdl = 0;
Uuid uuid = Uuid::kEmpty;
uint8_t reason =
gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
if (reason != GATT_SUCCESS) {
- gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
return;
}
if (uuid != Uuid::From16Bit(GATT_UUID_PRI_SERVICE)) {
if (op_code == GATT_REQ_READ_BY_GRP_TYPE) {
- gatt_send_error_rsp(tcb, GATT_UNSUPPORT_GRP_TYPE, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, GATT_UNSUPPORT_GRP_TYPE, op_code, s_hdl,
+ false);
VLOG(1) << StringPrintf("unexpected ReadByGrpType Group: %s",
uuid.ToString().c_str());
return;
}
// we do not support ReadByTypeValue with any non-primamry_service type
- gatt_send_error_rsp(tcb, GATT_NOT_FOUND, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, GATT_NOT_FOUND, op_code, s_hdl, false);
VLOG(1) << StringPrintf("unexpected ReadByTypeValue type: %s",
uuid.ToString().c_str());
return;
Uuid value = Uuid::kEmpty;
if (op_code == GATT_REQ_FIND_TYPE_VALUE) {
if (!gatt_parse_uuid_from_cmd(&value, len, &p_data)) {
- gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, s_hdl, false);
}
}
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
+
uint16_t msg_len =
- (uint16_t)(sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET);
+ (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
- reason = gatt_build_primary_service_rsp(p_msg, tcb, op_code, s_hdl, e_hdl,
- p_data, value);
+ reason = gatt_build_primary_service_rsp(p_msg, tcb, cid, op_code, s_hdl,
+ e_hdl, p_data, value);
if (reason != GATT_SUCCESS) {
osi_free(p_msg);
- gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
return;
}
- attp_send_sr_msg(tcb, p_msg);
+ attp_send_sr_msg(tcb, cid, p_msg);
}
/*******************************************************************************
* Returns void
*
******************************************************************************/
-static void gatts_process_find_info(tGATT_TCB& tcb, uint8_t op_code,
- uint16_t len, uint8_t* p_data) {
+static void gatts_process_find_info(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data) {
uint16_t s_hdl = 0, e_hdl = 0;
uint8_t reason = read_handles(len, p_data, s_hdl, e_hdl);
if (reason != GATT_SUCCESS) {
- gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
return;
}
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
uint16_t buf_len =
- (uint16_t)(sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET);
+ (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
BT_HDR* p_msg = (BT_HDR*)osi_calloc(buf_len);
reason = GATT_NOT_FOUND;
*p++ = op_code + 1;
p_msg->len = 2;
- buf_len = tcb.payload_size - 2;
+ buf_len = payload_size - 2;
for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
if (el.s_hdl <= e_hdl && el.e_hdl >= s_hdl) {
if (reason != GATT_SUCCESS) {
osi_free(p_msg);
- gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
} else
- attp_send_sr_msg(tcb, p_msg);
+ attp_send_sr_msg(tcb, cid, p_msg);
}
/*******************************************************************************
* Returns void
*
******************************************************************************/
-static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t len,
+static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t cid, uint16_t len,
uint8_t* p_data) {
/* BR/EDR conenction, send error response */
- if (tcb.att_lcid != L2CAP_ATT_CID) {
- gatt_send_error_rsp(tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, false);
+ if (cid != L2CAP_ATT_CID) {
+ gatt_send_error_rsp(tcb, cid, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0,
+ false);
return;
}
if (len < GATT_MTU_REQ_MIN_LEN) {
LOG(ERROR) << "invalid MTU request PDU received.";
- gatt_send_error_rsp(tcb, GATT_INVALID_PDU, GATT_REQ_MTU, 0, false);
+ gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, GATT_REQ_MTU, 0, false);
return;
}
tGATT_SR_MSG gatt_sr_msg;
gatt_sr_msg.mtu = tcb.payload_size;
BT_HDR* p_buf = attp_build_sr_msg(tcb, GATT_RSP_MTU, &gatt_sr_msg);
- attp_send_sr_msg(tcb, p_buf);
+ attp_send_sr_msg(tcb, cid, p_buf);
tGATTS_DATA gatts_data;
gatts_data.mtu = tcb.payload_size;
* Returns void
*
******************************************************************************/
-void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint8_t op_code,
- uint16_t len, uint8_t* p_data) {
+void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data) {
Uuid uuid = Uuid::kEmpty;
uint16_t s_hdl = 0, e_hdl = 0, err_hdl = 0;
tGATT_STATUS reason =
VLOG(1) << "Conformance tst: forced err rsp for ReadByType: error status="
<< +gatt_cb.err_status;
- gatt_send_error_rsp(tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl,
- false);
+ gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code,
+ s_hdl, false);
return;
}
#endif
if (reason != GATT_SUCCESS) {
- gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
return;
}
- size_t msg_len = sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET;
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
+
+ size_t msg_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
*p++ = op_code + 1;
/* reserve length byte */
p_msg->len = 2;
- uint16_t buf_len = tcb.payload_size - 2;
+ uint16_t buf_len = payload_size - 2;
reason = GATT_NOT_FOUND;
for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
tGATT_STATUS ret = gatts_db_read_attr_value_by_type(
- tcb, el.p_db, op_code, p_msg, s_hdl, e_hdl, uuid, &buf_len, sec_flag,
- key_size, 0, &err_hdl);
+ tcb, cid, el.p_db, op_code, p_msg, s_hdl, e_hdl, uuid, &buf_len,
+ sec_flag, key_size, 0, &err_hdl);
if (ret != GATT_NOT_FOUND) {
reason = ret;
if (ret == GATT_NO_RESOURCES) reason = GATT_SUCCESS;
/* in theroy BUSY is not possible(should already been checked), protected
* check */
if (reason != GATT_PENDING && reason != GATT_BUSY)
- gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+ gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
return;
}
- attp_send_sr_msg(tcb, p_msg);
+ attp_send_sr_msg(tcb, cid, p_msg);
}
/**
* This function is called to process the write request from client.
*/
-static void gatts_process_write_req(tGATT_TCB& tcb, tGATT_SRV_LIST_ELEM& el,
- uint16_t handle, uint8_t op_code,
- uint16_t len, uint8_t* p_data,
+static void gatts_process_write_req(tGATT_TCB& tcb, uint16_t cid,
+ tGATT_SRV_LIST_ELEM& el, uint16_t handle,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data,
bt_gatt_db_attribute_type_t gatt_type) {
tGATTS_DATA sr_data;
uint32_t trans_id;
LOG(ERROR) << __func__
<< ": Prepare write request was invalid - missing offset, "
"sending error response";
- gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, handle, false);
+ gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, handle, false);
return;
}
sr_data.write_req.is_prep = true;
sec_flag, key_size);
if (status == GATT_SUCCESS) {
- trans_id = gatt_sr_enqueue_cmd(tcb, op_code, handle);
+ trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, handle);
if (trans_id != 0) {
conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, el.gatt_if);
* check */
if (status != GATT_PENDING && status != GATT_BUSY &&
(op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) {
- gatt_send_error_rsp(tcb, status, op_code, handle, false);
+ gatt_send_error_rsp(tcb, cid, status, op_code, handle, false);
}
return;
}
/**
* This function is called to process the read request from client.
*/
-static void gatts_process_read_req(tGATT_TCB& tcb, tGATT_SRV_LIST_ELEM& el,
- uint8_t op_code, uint16_t handle,
- uint16_t len, uint8_t* p_data) {
- size_t buf_len = sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET;
+static void gatts_process_read_req(tGATT_TCB& tcb, uint16_t cid,
+ tGATT_SRV_LIST_ELEM& el, uint8_t op_code,
+ uint16_t handle, uint16_t len,
+ uint8_t* p_data) {
+ uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
+
+ size_t buf_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
uint16_t offset = 0;
if (op_code == GATT_REQ_READ_BLOB && len < sizeof(uint16_t)) {
LOG(ERROR) << __func__ << ": packet length=" << len
<< " too short. min=" << sizeof(uint16_t);
android_errorWriteWithInfoLog(0x534e4554, "73172115", -1, NULL, 0);
- gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, 0, false);
+ gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, 0, false);
return;
}
uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
*p++ = op_code + 1;
p_msg->len = 1;
- buf_len = tcb.payload_size - 1;
+ buf_len = payload_size - 1;
uint8_t sec_flag, key_size;
gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
uint16_t value_len = 0;
tGATT_STATUS reason = gatts_read_attr_value_by_handle(
- tcb, el.p_db, op_code, handle, offset, p, &value_len, (uint16_t)buf_len,
- sec_flag, key_size, 0);
+ tcb, cid, el.p_db, op_code, handle, offset, p, &value_len,
+ (uint16_t)buf_len, sec_flag, key_size, 0);
p_msg->len += value_len;
if (reason != GATT_SUCCESS) {
/* in theory BUSY is not possible(should already been checked), protected
* check */
if (reason != GATT_PENDING && reason != GATT_BUSY)
- gatt_send_error_rsp(tcb, reason, op_code, handle, false);
+ gatt_send_error_rsp(tcb, cid, reason, op_code, handle, false);
return;
}
- attp_send_sr_msg(tcb, p_msg);
+ attp_send_sr_msg(tcb, cid, p_msg);
}
/*******************************************************************************
* Returns void
*
******************************************************************************/
-void gatts_process_attribute_req(tGATT_TCB& tcb, uint8_t op_code, uint16_t len,
- uint8_t* p_data) {
+void gatts_process_attribute_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
+ uint16_t len, uint8_t* p_data) {
uint16_t handle = 0;
uint8_t* p = p_data;
tGATT_STATUS status = GATT_INVALID_HANDLE;
VLOG(1) << "Conformance tst: forced err rsp: error status="
<< +gatt_cb.err_status;
- gatt_send_error_rsp(tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle,
- false);
+ gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, cid, gatt_cb.req_op_code,
+ handle, false);
return;
}
switch (op_code) {
case GATT_REQ_READ: /* read char/char descriptor value */
case GATT_REQ_READ_BLOB:
- gatts_process_read_req(tcb, el, op_code, handle, len, p);
+ gatts_process_read_req(tcb, cid, el, op_code, handle, len, p);
break;
case GATT_REQ_WRITE: /* write char/char descriptor value */
case GATT_CMD_WRITE:
case GATT_SIGN_CMD_WRITE:
case GATT_REQ_PREPARE_WRITE:
- gatts_process_write_req(tcb, el, handle, op_code, len, p,
+ gatts_process_write_req(tcb, cid, el, handle, op_code, len, p,
attr.gatt_type);
break;
default:
if (status != GATT_SUCCESS && op_code != GATT_CMD_WRITE &&
op_code != GATT_SIGN_CMD_WRITE)
- gatt_send_error_rsp(tcb, status, op_code, handle, false);
+ gatt_send_error_rsp(tcb, cid, status, op_code, handle, false);
}
/*******************************************************************************
* Returns void
*
******************************************************************************/
-void gatts_process_value_conf(tGATT_TCB& tcb, uint8_t op_code) {
- uint16_t handle = tcb.indicate_handle;
+void gatts_process_value_conf(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code) {
+ uint16_t handle;
- alarm_cancel(tcb.conf_timer);
- if (!GATT_HANDLE_IS_VALID(handle)) {
+ if (gatt_tcb_find_indicate_handle(tcb, cid, &handle)) {
LOG(ERROR) << "unexpected handle value confirmation";
return;
}
- tcb.indicate_handle = 0;
+ alarm_cancel(tcb.conf_timer);
+
bool continue_processing = gatts_proc_ind_ack(tcb, handle);
if (continue_processing) {
gatts_data.handle = handle;
for (auto& el : *gatt_cb.srv_list_info) {
if (el.s_hdl <= handle && el.e_hdl >= handle) {
- uint32_t trans_id = gatt_sr_enqueue_cmd(tcb, op_code, handle);
+ uint32_t trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, handle);
uint16_t conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, el.gatt_if);
gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_CONF,
&gatts_data);
}
/** This function is called to handle the client requests to server */
-void gatt_server_handle_client_req(tGATT_TCB& tcb, uint8_t op_code,
- uint16_t len, uint8_t* p_data) {
+void gatt_server_handle_client_req(tGATT_TCB& tcb, uint16_t cid,
+ uint8_t op_code, uint16_t len,
+ uint8_t* p_data) {
/* there is pending command, discard this one */
if (!gatt_sr_cmd_empty(tcb) && op_code != GATT_HANDLE_VALUE_CONF) return;
/* the size of the message may not be bigger than the local max PDU size*/
/* The message has to be smaller than the agreed MTU, len does not include op
* code */
- if (len >= tcb.payload_size) {
+
+ uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, cid);
+ if (len >= payload_size) {
LOG(ERROR) << StringPrintf("server receive invalid PDU size:%d pdu size:%d",
- len + 1, tcb.payload_size);
+ len + 1, payload_size);
/* for invalid request expecting response, send it now */
if (op_code != GATT_CMD_WRITE && op_code != GATT_SIGN_CMD_WRITE &&
op_code != GATT_HANDLE_VALUE_CONF) {
- gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, 0, false);
+ gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, 0, false);
}
/* 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 */
- gatts_process_primary_service_req(tcb, op_code, len, p_data);
+ gatts_process_primary_service_req(tcb, cid, op_code, len, p_data);
break;
case GATT_REQ_FIND_INFO: /* discover char descrptor */
- gatts_process_find_info(tcb, op_code, len, p_data);
+ gatts_process_find_info(tcb, cid, op_code, len, p_data);
break;
case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor
value */
/* discover characteristic, discover char by UUID */
- gatts_process_read_by_type_req(tcb, op_code, len, p_data);
+ gatts_process_read_by_type_req(tcb, cid, op_code, len, p_data);
break;
case GATT_REQ_READ: /* read char/char descriptor value */
case GATT_CMD_WRITE:
case GATT_SIGN_CMD_WRITE:
case GATT_REQ_PREPARE_WRITE:
- gatts_process_attribute_req(tcb, op_code, len, p_data);
+ gatts_process_attribute_req(tcb, cid, op_code, len, p_data);
break;
case GATT_HANDLE_VALUE_CONF:
- gatts_process_value_conf(tcb, op_code);
+ gatts_process_value_conf(tcb, cid, op_code);
break;
case GATT_REQ_MTU:
- gatts_process_mtu_req(tcb, len, p_data);
+ gatts_process_mtu_req(tcb, cid, len, p_data);
break;
case GATT_REQ_EXEC_WRITE:
- gatt_process_exec_write_req(tcb, op_code, len, p_data);
+ gatt_process_exec_write_req(tcb, cid, op_code, len, p_data);
break;
case GATT_REQ_READ_MULTI:
- gatt_process_read_multi_req(tcb, op_code, len, p_data);
+ gatt_process_read_multi_req(tcb, cid, op_code, len, p_data);
break;
default:
/*******************************************************************************
*
+ * Function gatt_stop_rsp_timer
+ *
+ * Description Stops a GATT response timer.
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void gatt_stop_rsp_timer(tGATT_CLCB* p_clcb) {
+ alarm_cancel(p_clcb->gatt_rsp_timer_ent);
+}
+
+/*******************************************************************************
+ *
* Function gatt_start_conf_timer
*
* Description Start a wait_for_confirmation timer.
p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) {
uint8_t rsp_code;
LOG(WARNING) << __func__ << " retry discovery primary service";
- if (p_clcb != gatt_cmd_dequeue(*p_clcb->p_tcb, &rsp_code)) {
+ if (p_clcb != gatt_cmd_dequeue(*p_clcb->p_tcb, p_clcb->cid, &rsp_code)) {
LOG(ERROR) << __func__ << " command queue out of sync, disconnect";
} else {
p_clcb->retry_count++;
* Returns void
*
******************************************************************************/
-tGATT_STATUS gatt_send_error_rsp(tGATT_TCB& tcb, uint8_t err_code,
+tGATT_STATUS gatt_send_error_rsp(tGATT_TCB& tcb, uint16_t cid, uint8_t err_code,
uint8_t op_code, uint16_t handle, bool deq) {
tGATT_STATUS status;
BT_HDR* p_buf;
p_buf = attp_build_sr_msg(tcb, GATT_RSP_ERROR, &msg);
if (p_buf != NULL) {
- status = attp_send_sr_msg(tcb, p_buf);
+ status = attp_send_sr_msg(tcb, cid, p_buf);
} else
status = GATT_INSUF_RESOURCE;
/*******************************************************************************
*
+ * Function gatt_tcb_is_cid_busy
+ *
+ * Description The function check if channel with given cid is busy
+ *
+ * Returns True when busy
+ *
+ ******************************************************************************/
+
+bool gatt_tcb_is_cid_busy(tGATT_TCB& tcb, uint16_t cid) {
+ return !tcb.cl_cmd_q.empty();
+}
+/*******************************************************************************
+ *
* Function gatt_clcb_alloc
*
* Description The function allocates a GATT connection link control block
p_clcb->conn_id = conn_id;
p_clcb->p_reg = p_reg;
p_clcb->p_tcb = p_tcb;
+ p_clcb->cid = gatt_tcb_get_att_cid(*p_tcb);
break;
}
}
/*******************************************************************************
*
+ * Function gatt_tcb_get_cid_available_for_indication
+ *
+ * Description This function checks if indication can be send
+ *
+ * Returns None
+ *
+ ******************************************************************************/
+bool gatt_tcb_get_cid_available_for_indication(tGATT_TCB* p_tcb,
+ bool eatt_support,
+ uint16_t** indicated_handle_p,
+ uint16_t* cid_p) {
+ if (GATT_HANDLE_IS_VALID(p_tcb->indicate_handle)) {
+ return false;
+ }
+
+ *indicated_handle_p = &p_tcb->indicate_handle;
+ *cid_p = p_tcb->att_lcid;
+ return true;
+}
+
+/*******************************************************************************
+ *
+ * Function gatt_tcb_find_indicate_handle
+ *
+ * Description This function checks if indication can be send
+ *
+ * Returns true when indication handle found, false otherwise
+ *
+ ******************************************************************************/
+bool gatt_tcb_find_indicate_handle(tGATT_TCB& tcb, uint16_t cid,
+ uint16_t* indicated_handle_p) {
+ if (cid == tcb.att_lcid) {
+ *indicated_handle_p = tcb.indicate_handle;
+ tcb.indicate_handle = 0;
+ return true;
+ }
+
+ return false;
+}
+
+/*******************************************************************************
+ *
+ * Function gatt_tcb_get_att_cid
+ *
+ * Description This function gets cid for the GATT operation
+ *
+ * Returns Available CID
+ *
+ ******************************************************************************/
+
+uint16_t gatt_tcb_get_att_cid(tGATT_TCB& tcb) { return tcb.att_lcid; }
+
+/*******************************************************************************
+ *
+ * Function gatt_tcb_get_payload_size_tx
+ *
+ * Description This function gets payload size for the GATT operation
+ *
+ * Returns Payload size for sending data
+ *
+ ******************************************************************************/
+uint16_t gatt_tcb_get_payload_size_tx(tGATT_TCB& tcb, uint16_t cid) {
+ return tcb.payload_size;
+}
+
+/*******************************************************************************
+ *
+ * Function gatt_tcb_get_payload_size_rx
+ *
+ * Description This function gets payload size for the GATT operation
+ *
+ * Returns Payload size for receiving data
+ *
+ ******************************************************************************/
+
+uint16_t gatt_tcb_get_payload_size_rx(tGATT_TCB& tcb, uint16_t cid) {
+ return tcb.payload_size;
+}
+
+/*******************************************************************************
+ *
* Function gatt_clcb_dealloc
*
* Description The function de-allocates a GATT connection link control
}
}
+/* Get outstanding server command pointer by the transaction id */
+tGATT_SR_CMD* gatt_sr_get_cmd_by_trans_id(tGATT_TCB* p_tcb, uint32_t trans_id) {
+ if (p_tcb->sr_cmd.trans_id == trans_id) return &p_tcb->sr_cmd;
+
+ return nullptr;
+}
/*******************************************************************************
*
* Function gatt_sr_is_cback_cnt_zero
* Returns None
*
******************************************************************************/
-void gatt_sr_reset_cback_cnt(tGATT_TCB& tcb) {
+void gatt_sr_reset_cback_cnt(tGATT_TCB& tcb, uint16_t cid) {
for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
- tcb.sr_cmd.cback_cnt[i] = 0;
+ if (cid == tcb.att_lcid) {
+ tcb.sr_cmd.cback_cnt[i] = 0;
+ }
}
}
}
}
+/* Get pointer to server command on given cid */
+tGATT_SR_CMD* gatt_sr_get_cmd_by_cid(tGATT_TCB& tcb, uint16_t cid) {
+ return &tcb.sr_cmd;
+}
/*******************************************************************************
*
* Function gatt_sr_update_cback_cnt
* Returns None
*
******************************************************************************/
-void gatt_sr_update_cback_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc,
- bool is_reset_first) {
+void gatt_sr_update_cback_cnt(tGATT_TCB& tcb, uint16_t cid, tGATT_IF gatt_if,
+ bool is_inc, bool is_reset_first) {
uint8_t idx = ((uint8_t)gatt_if) - 1;
+ tGATT_SR_CMD* sr_cmd_p = &tcb.sr_cmd;
if (is_reset_first) {
- gatt_sr_reset_cback_cnt(tcb);
+ gatt_sr_reset_cback_cnt(tcb, cid);
}
if (is_inc) {
- tcb.sr_cmd.cback_cnt[idx]++;
+ sr_cmd_p->cback_cnt[idx]++;
} else {
- if (tcb.sr_cmd.cback_cnt[idx]) {
- tcb.sr_cmd.cback_cnt[idx]--;
+ if (sr_cmd_p->cback_cnt[idx]) {
+ sr_cmd_p->cback_cnt[idx]--;
}
}
}
cmd.op_code = op_code;
cmd.p_cmd = p_buf;
cmd.p_clcb = p_clcb;
-
- if (!to_send) {
- // TODO: WTF why do we clear the queue here ?!
- tcb.cl_cmd_q = std::queue<tGATT_CMD_Q>();
- }
+ cmd.cid = p_clcb->cid;
tcb.cl_cmd_q.push(cmd);
}
/** dequeue the command in the client CCB command queue */
-tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint8_t* p_op_code) {
- if (tcb.cl_cmd_q.empty()) return nullptr;
+tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint16_t cid, uint8_t* p_op_code) {
+ std::queue<tGATT_CMD_Q>* cl_cmd_q_p = &tcb.cl_cmd_q;
- tGATT_CMD_Q cmd = tcb.cl_cmd_q.front();
+ if (cl_cmd_q_p->empty()) return nullptr;
+
+ tGATT_CMD_Q cmd = cl_cmd_q_p->front();
tGATT_CLCB* p_clcb = cmd.p_clcb;
*p_op_code = cmd.op_code;
- tcb.cl_cmd_q.pop();
+ p_clcb->cid = cid;
+ cl_cmd_q_p->pop();
return p_clcb;
}
operation = p_clcb->operation;
conn_id = p_clcb->conn_id;
- alarm_cancel(p_clcb->gatt_rsp_timer_ent);
+ gatt_stop_rsp_timer(p_clcb);
gatt_clcb_dealloc(p_clcb);
tGATT_CLCB* p_clcb = &gatt_cb.clcb[i];
if (!p_clcb->in_use || p_clcb->p_tcb != p_tcb) continue;
- alarm_cancel(p_clcb->gatt_rsp_timer_ent);
+ gatt_stop_rsp_timer(p_clcb);
VLOG(1) << "found p_clcb conn_id=" << +p_clcb->conn_id;
if (p_clcb->operation == GATTC_OPTYPE_NONE) {
gatt_clcb_dealloc(p_clcb);
uint8_t op_code, tGATT_CL_MSG* p_msg) {
return 0;
}
-tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, BT_HDR* p_msg) { return 0; }
+tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_msg) {
+ return 0;
+}
uint8_t btm_ble_read_sec_key_size(const RawAddress& bd_addr) { return 0; }
bool BTM_GetSecurityFlagsByTransport(const RawAddress& bd_addr,
uint8_t* p_sec_flags,
bool gatt_disconnect(tGATT_TCB* p_tcb) { return false; }
tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) { return 0; }
tGATT_STATUS gatts_db_read_attr_value_by_type(
- tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, BT_HDR* p_rsp,
- uint16_t s_handle, uint16_t e_handle, const Uuid& type, uint16_t* p_len,
- tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id,
- uint16_t* p_cur_handle) {
+ tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
+ BT_HDR* p_rsp, uint16_t s_handle, uint16_t e_handle, const Uuid& type,
+ uint16_t* p_len, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
+ uint32_t trans_id, uint16_t* p_cur_handle) {
return 0;
}
void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {}
return GATT_SUCCESS;
}
tGATT_STATUS gatts_read_attr_value_by_handle(
- tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, uint16_t handle,
- uint16_t offset, uint8_t* p_value, uint16_t* p_len, uint16_t mtu,
- tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id) {
+ tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
+ uint16_t handle, uint16_t offset, uint8_t* p_value, uint16_t* p_len,
+ uint16_t mtu, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
+ uint32_t trans_id) {
return GATT_SUCCESS;
}
tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code,
};
TEST_F(GattSrTest, gatts_process_write_req_request_prepare_write_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE, 0,
- nullptr, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_REQ_PREPARE_WRITE, 0, nullptr,
+ kGattCharacteristicType);
}
TEST_F(GattSrTest,
gatts_process_write_req_request_prepare_write_max_len_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE,
- MAX_UINT16, nullptr, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_REQ_PREPARE_WRITE, MAX_UINT16, nullptr,
+ kGattCharacteristicType);
}
TEST_F(GattSrTest,
gatts_process_write_req_request_prepare_write_zero_len_max_data) {
uint8_t max_mem[MAX_UINT16];
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE, 0,
- max_mem, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_REQ_PREPARE_WRITE, 0, max_mem,
+ kGattCharacteristicType);
}
TEST_F(GattSrTest, gatts_process_write_req_request_prepare_write_typical) {
uint8_t p_data[2] = {0x34, 0x12};
uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE, length,
- p_data, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_REQ_PREPARE_WRITE, length, p_data,
+ kGattCharacteristicType);
CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
}
TEST_F(GattSrTest, gatts_process_write_req_signed_command_write_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, 0, nullptr,
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_SIGN_CMD_WRITE, 0, nullptr,
kGattCharacteristicType);
}
TEST_F(GattSrTest,
gatts_process_write_req_signed_command_write_max_len_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, MAX_UINT16,
- nullptr, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_SIGN_CMD_WRITE, MAX_UINT16, nullptr,
+ kGattCharacteristicType);
}
TEST_F(GattSrTest,
gatts_process_write_req_signed_command_write_zero_len_max_data) {
uint8_t max_mem[MAX_UINT16];
- gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, 0, max_mem,
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_SIGN_CMD_WRITE, 0, max_mem,
kGattCharacteristicType);
}
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
- gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, length,
- p_data, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
+ GATT_SIGN_CMD_WRITE, length, p_data,
+ kGattCharacteristicType);
CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
}
TEST_F(GattSrTest, gatts_process_write_req_command_write_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, 0, nullptr,
- kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE, 0,
+ nullptr, kGattCharacteristicType);
}
TEST_F(GattSrTest, gatts_process_write_req_command_write_max_len_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, MAX_UINT16,
- nullptr, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE,
+ MAX_UINT16, nullptr, kGattCharacteristicType);
}
TEST_F(GattSrTest, gatts_process_write_req_command_write_zero_len_max_data) {
uint8_t max_mem[MAX_UINT16];
- gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, 0, max_mem,
- kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE, 0,
+ max_mem, kGattCharacteristicType);
}
TEST_F(GattSrTest, gatts_process_write_req_command_write_typical) {
uint8_t p_data[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
- gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, length, p_data,
- kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE,
+ length, p_data, kGattCharacteristicType);
CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
}
TEST_F(GattSrTest, gatts_process_write_req_request_write_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, 0, nullptr,
- kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE, 0,
+ nullptr, kGattCharacteristicType);
}
TEST_F(GattSrTest, gatts_process_write_req_request_write_max_len_no_data) {
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, MAX_UINT16,
- nullptr, kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE,
+ MAX_UINT16, nullptr, kGattCharacteristicType);
}
TEST_F(GattSrTest, gatts_process_write_req_request_write_zero_len_max_data) {
uint8_t max_mem[MAX_UINT16];
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, 0, max_mem,
- kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE, 0,
+ max_mem, kGattCharacteristicType);
}
TEST_F(GattSrTest, gatts_process_write_req_request_write_typical) {
0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
- gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, length, p_data,
- kGattCharacteristicType);
+ gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE,
+ length, p_data, kGattCharacteristicType);
CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);