/*******************************************************************************
**
** Function         rw_t2t_process_error
**
** Description      Process error including Timeout, Frame error. This function
**                  will retry atleast till RW_MAX_RETRIES before give up and
**                  sending negative notification to upper layer
**
** Returns          none
**
*******************************************************************************/
static void rw_t2t_process_error (void)
{
    tRW_READ_DATA           evt_data;
    tRW_EVENT               rw_event;
    BT_HDR                  *p_cmd_buf;
    tRW_T2T_CB              *p_t2t          = &rw_cb.tcb.t2t;
    tT2T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
    tRW_DETECT_NDEF_DATA    ndef_data;

    RW_TRACE_DEBUG1 ("rw_t2t_process_error () State: %u", p_t2t->state);

    /* Retry sending command if retry-count < max */
    if (  (!p_t2t->check_tag_halt)
        &&(rw_cb.cur_retry < RW_MAX_RETRIES)  )
    {
        /* retry sending the command */
        rw_cb.cur_retry++;

        RW_TRACE_DEBUG2 ("T2T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);

        /* allocate a new buffer for message */
        if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
        {
            memcpy (p_cmd_buf, p_t2t->p_cur_cmd_buf, sizeof (BT_HDR) + p_t2t->p_cur_cmd_buf->offset + p_t2t->p_cur_cmd_buf->len);
#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
            /* Update stats */
            rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
#endif
            if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
            {
                /* Start timer for waiting for response */
                nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
                                       (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);

                return;
            }
        }
    }
    else
    {
        if (p_t2t->check_tag_halt)
        {
            RW_TRACE_DEBUG0 ("T2T Went to HALT State!");
        }
        else
        {
            RW_TRACE_DEBUG1 ("T2T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
        }
    }
    rw_event = rw_t2t_info_to_event (p_cmd_rsp_info);
#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
    /* update failure count */
    rw_main_update_fail_stats ();
#endif
    if (p_t2t->check_tag_halt)
    {
        evt_data.status = NFC_STATUS_REJECTED;
        p_t2t->state    = RW_T2T_STATE_HALT;
    }
    else
    {
        evt_data.status = NFC_STATUS_TIMEOUT;
    }

    if (rw_event == RW_T2T_NDEF_DETECT_EVT)
    {
        ndef_data.status    = evt_data.status;
        ndef_data.protocol  = NFC_PROTOCOL_T2T;
        ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
        if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
            ndef_data.flags = RW_NDEF_FL_FORMATED;
        ndef_data.max_size  = 0;
        ndef_data.cur_size  = 0;
        /* If not Halt move to idle state */
        rw_t2t_handle_op_complete ();

        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
    }
    else
    {
        evt_data.p_data = NULL;
        /* If activated and not Halt move to idle state */
        if (p_t2t->state != RW_T2T_STATE_NOT_ACTIVATED)
            rw_t2t_handle_op_complete ();

        p_t2t->substate = RW_T2T_SUBSTATE_NONE;
        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
    }
}
/*******************************************************************************
**
** Function         rw_t1t_process_error
**
** Description      process timeout event
**
** Returns          none
**
*******************************************************************************/
static void rw_t1t_process_error (void)
{
    tRW_READ_DATA           evt_data;
    tRW_EVENT               rw_event;
    BT_HDR                  *p_cmd_buf;
    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
    tT1T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
    tRW_DETECT_NDEF_DATA    ndef_data;

    RW_TRACE_DEBUG1 ("rw_t1t_process_error () State: %u", p_t1t->state);

    /* Retry sending command if retry-count < max */
    if (rw_cb.cur_retry < RW_MAX_RETRIES)
    {
        /* retry sending the command */
        rw_cb.cur_retry++;

        RW_TRACE_DEBUG2 ("T1T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);

        /* allocate a new buffer for message */
        if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
        {
            memcpy (p_cmd_buf, p_t1t->p_cur_cmd_buf, sizeof (BT_HDR) + p_t1t->p_cur_cmd_buf->offset + p_t1t->p_cur_cmd_buf->len);

#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
            /* Update stats */
            rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
#endif  /* RW_STATS_INCLUDED */

            if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
            {
                /* Start timer for waiting for response */
                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
                                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC)/1000);

                return;
            }
        }
    }
    else
    {
    /* we might get response later to all or some of the retrasnmission
     * of the current command, update previous command response information */
        RW_TRACE_DEBUG1 ("T1T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
        p_t1t->prev_cmd_rsp_info.addr          = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID))? p_t1t->addr:0;
        p_t1t->prev_cmd_rsp_info.rsp_len       = p_cmd_rsp_info->rsp_len;
        p_t1t->prev_cmd_rsp_info.op_code       = p_cmd_rsp_info->opcode;
        p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
    }

#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
    /* update failure count */
    rw_main_update_fail_stats ();
#endif  /* RW_STATS_INCLUDED */

    rw_event        = rw_t1t_info_to_event (p_cmd_rsp_info);
    if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED)
        rw_t1t_handle_op_complete ();

    evt_data.status = NFC_STATUS_TIMEOUT;
    if (rw_event == RW_T2T_NDEF_DETECT_EVT)
    {
        ndef_data.status    = evt_data.status;
        ndef_data.protocol  = NFC_PROTOCOL_T1T;
        ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
        ndef_data.max_size  = 0;
        ndef_data.cur_size  = 0;
        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
    }
    else
    {
        evt_data.p_data = NULL;
        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
    }
}