Loading system/stack/gatt/att_protocol.cc +6 −5 Original line number Diff line number Diff line Loading @@ -434,8 +434,7 @@ tGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, uint16_t clcb_idx, uint8_t cmd_code, BT_HDR* p_cmd) { cmd_code &= ~GATT_AUTH_SIGN_MASK; if (tcb.pending_cl_req != tcb.next_slot_inq && cmd_code != GATT_HANDLE_VALUE_CONF) { if (!tcb.cl_cmd_q.empty() && cmd_code != GATT_HANDLE_VALUE_CONF) { gatt_cmd_enq(tcb, clcb_idx, true, cmd_code, p_cmd); return GATT_CMD_STARTED; } Loading @@ -447,10 +446,12 @@ tGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, uint16_t clcb_idx, } /* do not enq cmd if handle value confirmation or set request */ if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE) { if (cmd_code == GATT_HANDLE_VALUE_CONF || cmd_code == GATT_CMD_WRITE) { return att_ret; } gatt_start_rsp_timer(clcb_idx); gatt_cmd_enq(tcb, clcb_idx, false, cmd_code, NULL); } return att_ret; } Loading system/stack/gatt/gatt_cl.cc +28 −40 Original line number Diff line number Diff line Loading @@ -998,54 +998,42 @@ uint8_t gatt_cmd_to_rsp_code(uint8_t cmd_code) { } return rsp_code; } /******************************************************************************* * * Function gatt_cl_send_next_cmd_inq * * Description Find next command in queue and sent to server * * Returns true if command sent, otherwise false. * ******************************************************************************/ /** Find next command in queue and sent to server */ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) { tGATT_CMD_Q* p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; bool sent = false; uint8_t rsp_code; tGATT_CLCB* p_clcb = NULL; tGATT_STATUS att_ret = GATT_SUCCESS; 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; while (!sent && tcb.pending_cl_req != tcb.next_slot_inq && p_cmd->to_send && p_cmd->p_cmd != NULL) { att_ret = attp_send_msg_to_l2cap(tcb, p_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) { GATT_TRACE_ERROR("%s: L2CAP sent error", __func__); tcb.cl_cmd_q.pop(); continue; } if (att_ret == GATT_SUCCESS || att_ret == GATT_CONGESTED) { sent = true; p_cmd->to_send = false; p_cmd->p_cmd = NULL; cmd.to_send = false; cmd.p_cmd = NULL; if (cmd.op_code == GATT_CMD_WRITE || cmd.op_code == GATT_SIGN_CMD_WRITE) { /* dequeue the request if is write command or sign write */ if (p_cmd->op_code != GATT_CMD_WRITE && p_cmd->op_code != GATT_SIGN_CMD_WRITE) { gatt_start_rsp_timer(p_cmd->clcb_idx); } else { p_clcb = gatt_cmd_dequeue(tcb, &rsp_code); /* if no ack needed, keep sending */ if (att_ret == GATT_SUCCESS) sent = false; uint8_t rsp_code; tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &rsp_code); p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; /* send command complete callback here */ gatt_end_operation(p_clcb, att_ret, NULL); } } else { GATT_TRACE_ERROR("gatt_cl_send_next_cmd_inq: L2CAP sent error"); memset(p_cmd, 0, sizeof(tGATT_CMD_Q)); tcb.pending_cl_req++; p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; /* if no ack needed, keep sending */ if (att_ret == GATT_SUCCESS) continue; return true; } gatt_start_rsp_timer(cmd.clcb_idx); return true; } return sent; return false; } /******************************************************************************* Loading @@ -1062,9 +1050,9 @@ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) { void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code, uint16_t len, uint8_t* p_data) { tGATT_CLCB* p_clcb = NULL; uint8_t rsp_code; if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF) { uint8_t rsp_code; p_clcb = gatt_cmd_dequeue(tcb, &rsp_code); rsp_code = gatt_cmd_to_rsp_code(rsp_code); Loading system/stack/gatt/gatt_int.h +3 −5 Original line number Diff line number Diff line Loading @@ -289,10 +289,8 @@ typedef struct { uint8_t prep_cnt[GATT_MAX_APPS]; uint8_t ind_count; tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB]; std::queue<tGATT_CMD_Q> cl_cmd_q; alarm_t* ind_ack_timer; /* local app confirm to indication timer */ uint8_t pending_cl_req; uint8_t next_slot_inq; /* index of next available slot in queue */ bool in_use; uint8_t tcb_idx; Loading Loading @@ -546,9 +544,9 @@ extern void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, 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 bool gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, bool to_send, uint8_t op_code, BT_HDR* p_buf); extern tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint8_t* p_opcode); extern void gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, 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_send_queue_write_cancel(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, Loading system/stack/gatt/gatt_utils.cc +16 −40 Original line number Diff line number Diff line Loading @@ -1307,55 +1307,31 @@ bool gatt_find_app_hold_link(tGATT_TCB* p_tcb, uint8_t start_idx, return found; } /******************************************************************************* * * Function gatt_cmd_enq * * Description Enqueue this command. * * Returns None. * ******************************************************************************/ bool gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, bool to_send, /** Enqueue this command */ void gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, bool to_send, uint8_t op_code, BT_HDR* p_buf) { tGATT_CMD_Q* p_cmd = &tcb.cl_cmd_q[tcb.next_slot_inq]; p_cmd->to_send = to_send; /* waiting to be sent */ p_cmd->op_code = op_code; p_cmd->p_cmd = p_buf; p_cmd->clcb_idx = clcb_idx; tGATT_CMD_Q cmd; cmd.to_send = to_send; /* waiting to be sent */ cmd.op_code = op_code; cmd.p_cmd = p_buf; cmd.clcb_idx = clcb_idx; if (!to_send) { tcb.pending_cl_req = tcb.next_slot_inq; // TODO: WTF why do we clear the queue here ?! tcb.cl_cmd_q = std::queue<tGATT_CMD_Q>(); } tcb.next_slot_inq++; tcb.next_slot_inq %= GATT_CL_MAX_LCB; return true; tcb.cl_cmd_q.push(cmd); } /******************************************************************************* * * Function gatt_cmd_dequeue * * Description dequeue the command in the client CCB command queue. * * Returns total number of clcb found. * ******************************************************************************/ /** dequeue the command in the client CCB command queue */ tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint8_t* p_op_code) { tGATT_CMD_Q* p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; tGATT_CLCB* p_clcb = NULL; if (tcb.pending_cl_req != tcb.next_slot_inq) { p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx]; if (tcb.cl_cmd_q.empty()) return nullptr; *p_op_code = p_cmd->op_code; tcb.pending_cl_req++; tcb.pending_cl_req %= GATT_CL_MAX_LCB; } tGATT_CMD_Q cmd = tcb.cl_cmd_q.front(); tGATT_CLCB* p_clcb = &gatt_cb.clcb[cmd.clcb_idx]; *p_op_code = cmd.op_code; tcb.cl_cmd_q.pop(); return p_clcb; } Loading Loading
system/stack/gatt/att_protocol.cc +6 −5 Original line number Diff line number Diff line Loading @@ -434,8 +434,7 @@ tGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, uint16_t clcb_idx, uint8_t cmd_code, BT_HDR* p_cmd) { cmd_code &= ~GATT_AUTH_SIGN_MASK; if (tcb.pending_cl_req != tcb.next_slot_inq && cmd_code != GATT_HANDLE_VALUE_CONF) { if (!tcb.cl_cmd_q.empty() && cmd_code != GATT_HANDLE_VALUE_CONF) { gatt_cmd_enq(tcb, clcb_idx, true, cmd_code, p_cmd); return GATT_CMD_STARTED; } Loading @@ -447,10 +446,12 @@ tGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, uint16_t clcb_idx, } /* do not enq cmd if handle value confirmation or set request */ if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE) { if (cmd_code == GATT_HANDLE_VALUE_CONF || cmd_code == GATT_CMD_WRITE) { return att_ret; } gatt_start_rsp_timer(clcb_idx); gatt_cmd_enq(tcb, clcb_idx, false, cmd_code, NULL); } return att_ret; } Loading
system/stack/gatt/gatt_cl.cc +28 −40 Original line number Diff line number Diff line Loading @@ -998,54 +998,42 @@ uint8_t gatt_cmd_to_rsp_code(uint8_t cmd_code) { } return rsp_code; } /******************************************************************************* * * Function gatt_cl_send_next_cmd_inq * * Description Find next command in queue and sent to server * * Returns true if command sent, otherwise false. * ******************************************************************************/ /** Find next command in queue and sent to server */ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) { tGATT_CMD_Q* p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; bool sent = false; uint8_t rsp_code; tGATT_CLCB* p_clcb = NULL; tGATT_STATUS att_ret = GATT_SUCCESS; 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; while (!sent && tcb.pending_cl_req != tcb.next_slot_inq && p_cmd->to_send && p_cmd->p_cmd != NULL) { att_ret = attp_send_msg_to_l2cap(tcb, p_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) { GATT_TRACE_ERROR("%s: L2CAP sent error", __func__); tcb.cl_cmd_q.pop(); continue; } if (att_ret == GATT_SUCCESS || att_ret == GATT_CONGESTED) { sent = true; p_cmd->to_send = false; p_cmd->p_cmd = NULL; cmd.to_send = false; cmd.p_cmd = NULL; if (cmd.op_code == GATT_CMD_WRITE || cmd.op_code == GATT_SIGN_CMD_WRITE) { /* dequeue the request if is write command or sign write */ if (p_cmd->op_code != GATT_CMD_WRITE && p_cmd->op_code != GATT_SIGN_CMD_WRITE) { gatt_start_rsp_timer(p_cmd->clcb_idx); } else { p_clcb = gatt_cmd_dequeue(tcb, &rsp_code); /* if no ack needed, keep sending */ if (att_ret == GATT_SUCCESS) sent = false; uint8_t rsp_code; tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &rsp_code); p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; /* send command complete callback here */ gatt_end_operation(p_clcb, att_ret, NULL); } } else { GATT_TRACE_ERROR("gatt_cl_send_next_cmd_inq: L2CAP sent error"); memset(p_cmd, 0, sizeof(tGATT_CMD_Q)); tcb.pending_cl_req++; p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; /* if no ack needed, keep sending */ if (att_ret == GATT_SUCCESS) continue; return true; } gatt_start_rsp_timer(cmd.clcb_idx); return true; } return sent; return false; } /******************************************************************************* Loading @@ -1062,9 +1050,9 @@ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) { void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code, uint16_t len, uint8_t* p_data) { tGATT_CLCB* p_clcb = NULL; uint8_t rsp_code; if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF) { uint8_t rsp_code; p_clcb = gatt_cmd_dequeue(tcb, &rsp_code); rsp_code = gatt_cmd_to_rsp_code(rsp_code); Loading
system/stack/gatt/gatt_int.h +3 −5 Original line number Diff line number Diff line Loading @@ -289,10 +289,8 @@ typedef struct { uint8_t prep_cnt[GATT_MAX_APPS]; uint8_t ind_count; tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB]; std::queue<tGATT_CMD_Q> cl_cmd_q; alarm_t* ind_ack_timer; /* local app confirm to indication timer */ uint8_t pending_cl_req; uint8_t next_slot_inq; /* index of next available slot in queue */ bool in_use; uint8_t tcb_idx; Loading Loading @@ -546,9 +544,9 @@ extern void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, 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 bool gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, bool to_send, uint8_t op_code, BT_HDR* p_buf); extern tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint8_t* p_opcode); extern void gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, 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_send_queue_write_cancel(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, Loading
system/stack/gatt/gatt_utils.cc +16 −40 Original line number Diff line number Diff line Loading @@ -1307,55 +1307,31 @@ bool gatt_find_app_hold_link(tGATT_TCB* p_tcb, uint8_t start_idx, return found; } /******************************************************************************* * * Function gatt_cmd_enq * * Description Enqueue this command. * * Returns None. * ******************************************************************************/ bool gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, bool to_send, /** Enqueue this command */ void gatt_cmd_enq(tGATT_TCB& tcb, uint16_t clcb_idx, bool to_send, uint8_t op_code, BT_HDR* p_buf) { tGATT_CMD_Q* p_cmd = &tcb.cl_cmd_q[tcb.next_slot_inq]; p_cmd->to_send = to_send; /* waiting to be sent */ p_cmd->op_code = op_code; p_cmd->p_cmd = p_buf; p_cmd->clcb_idx = clcb_idx; tGATT_CMD_Q cmd; cmd.to_send = to_send; /* waiting to be sent */ cmd.op_code = op_code; cmd.p_cmd = p_buf; cmd.clcb_idx = clcb_idx; if (!to_send) { tcb.pending_cl_req = tcb.next_slot_inq; // TODO: WTF why do we clear the queue here ?! tcb.cl_cmd_q = std::queue<tGATT_CMD_Q>(); } tcb.next_slot_inq++; tcb.next_slot_inq %= GATT_CL_MAX_LCB; return true; tcb.cl_cmd_q.push(cmd); } /******************************************************************************* * * Function gatt_cmd_dequeue * * Description dequeue the command in the client CCB command queue. * * Returns total number of clcb found. * ******************************************************************************/ /** dequeue the command in the client CCB command queue */ tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint8_t* p_op_code) { tGATT_CMD_Q* p_cmd = &tcb.cl_cmd_q[tcb.pending_cl_req]; tGATT_CLCB* p_clcb = NULL; if (tcb.pending_cl_req != tcb.next_slot_inq) { p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx]; if (tcb.cl_cmd_q.empty()) return nullptr; *p_op_code = p_cmd->op_code; tcb.pending_cl_req++; tcb.pending_cl_req %= GATT_CL_MAX_LCB; } tGATT_CMD_Q cmd = tcb.cl_cmd_q.front(); tGATT_CLCB* p_clcb = &gatt_cb.clcb[cmd.clcb_idx]; *p_op_code = cmd.op_code; tcb.cl_cmd_q.pop(); return p_clcb; } Loading