/******************************************************************************* ** ** Function gatt_cl_send_next_cmd_inq ** ** Description Find next command in queue and sent to server ** ** Returns TRUE if command sent, otherwise FALSE. ** *******************************************************************************/ BOOLEAN gatt_cl_send_next_cmd_inq(tGATT_TCB *p_tcb) { tGATT_CMD_Q *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req]; BOOLEAN sent = FALSE; while (!sent && p_tcb->pending_cl_req != p_tcb->next_slot_inq && p_cmd->to_send && p_cmd->p_cmd != NULL) { sent = attp_send_msg_to_L2CAP(p_tcb, p_cmd->p_cmd); if (sent) { p_cmd->to_send = FALSE; p_cmd->p_cmd = NULL; gatt_start_rsp_timer (p_tcb); } else { GATT_TRACE_ERROR0("gatt_cl_send_next_cmd_inq: L2CAP sent error"); memset(p_cmd, 0, sizeof(tGATT_CMD_Q)); p_tcb->pending_cl_req ++; p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req]; } } return sent; }
/******************************************************************************* ** ** Function gatt_cl_send_next_cmd_inq ** ** Description Find next command in queue and sent to server ** ** Returns TRUE if command sent, otherwise FALSE. ** *******************************************************************************/ BOOLEAN gatt_cl_send_next_cmd_inq(tGATT_TCB *p_tcb) { tGATT_CMD_Q *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req]; BOOLEAN sent = FALSE; UINT8 rsp_code; tGATT_CLCB *p_clcb = NULL; tGATT_STATUS att_ret = GATT_SUCCESS; while (!sent && p_tcb->pending_cl_req != p_tcb->next_slot_inq && p_cmd->to_send && p_cmd->p_cmd != NULL) { att_ret = attp_send_msg_to_l2cap(p_tcb, p_cmd->p_cmd); if (att_ret == GATT_SUCCESS || att_ret == GATT_CONGESTED) { sent = TRUE; p_cmd->to_send = FALSE; p_cmd->p_cmd = NULL; /* 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(p_tcb, &rsp_code); /* if no ack needed, keep sending */ if (att_ret == GATT_SUCCESS) sent = FALSE; p_cmd = &p_tcb->cl_cmd_q[p_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)); p_tcb->pending_cl_req ++; p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req]; } } return sent; }
/******************************************************************************* ** ** Function attp_cl_send_cmd ** ** Description Send a ATT command or enqueue it. ** ** Returns GATT_SUCCESS if command sent ** GATT_CONGESTED if command sent but channel congested ** GATT_CMD_STARTED if command queue up in GATT ** GATT_ERROR if command sending failure ** *******************************************************************************/ tGATT_STATUS attp_cl_send_cmd(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 cmd_code, BT_HDR *p_cmd) { tGATT_STATUS att_ret = GATT_SUCCESS; if (p_tcb != NULL) { cmd_code &= ~GATT_AUTH_SIGN_MASK; /* no pending request or value confirmation */ if (p_tcb->pending_cl_req == p_tcb->next_slot_inq || cmd_code == GATT_HANDLE_VALUE_CONF) { att_ret = attp_send_msg_to_l2cap(p_tcb, p_cmd); if (att_ret == GATT_CONGESTED || att_ret == GATT_SUCCESS) { /* do not enq cmd if handle value confirmation or set request */ if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE) { gatt_start_rsp_timer (clcb_idx); gatt_cmd_enq(p_tcb, clcb_idx, FALSE, cmd_code, NULL); } } else att_ret = GATT_INTERNAL_ERROR; } else { att_ret = GATT_CMD_STARTED; gatt_cmd_enq(p_tcb, clcb_idx, TRUE, cmd_code, p_cmd); } } else att_ret = GATT_ERROR; return att_ret; }