コード例 #1
0
/*******************************************************************************
**
** Function         rw_t2t_send_cmd
**
** Description      This function composes a Type 2 Tag command and send it via
**                  NCI to NFCC.
**
** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
**                  otherwise, error status
**
*******************************************************************************/
tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat)
{
    tNFC_STATUS             status  = NFC_STATUS_FAILED;
    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
    const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = t2t_cmd_to_rsp_info (opcode);
    BT_HDR                  *p_data;
    UINT8                   *p;

    if (p_cmd_rsp_info)
    {
        /* a valid opcode for RW */
        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
        if (p_data)
        {
            p_t2t->p_cmd_rsp_info   = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;
            p_data->offset  = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
            p               = (UINT8 *) (p_data + 1) + p_data->offset;

            UINT8_TO_STREAM (p, opcode);

            if (p_dat)
            {
                ARRAY_TO_STREAM (p, p_dat, (p_cmd_rsp_info->cmd_len - 1));
            }

            p_data->len     = p_cmd_rsp_info->cmd_len;

            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
            rw_cb.cur_retry = 0;
            memcpy (p_t2t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);

#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
            /* Update stats */
            rw_main_update_tx_stats (p_data->len, FALSE);
#endif
            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);

            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
            {
                nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
                       (RW_T2T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000);
            }
            else
            {
#if (BT_TRACE_VERBOSE == TRUE)
                RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=%s substate=%s ", rw_t2t_get_state_name (p_t2t->state), rw_t2t_get_substate_name (p_t2t->substate));
#else
                RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=0x%02X substate=0x%02X ", p_t2t->state, p_t2t->substate);
#endif
            }
        }
        else
        {
            status = NFC_STATUS_NO_BUFFERS;
        }
    }
    return status;
}
コード例 #2
0
/*******************************************************************************
**
** Function         rw_t1t_send_dyn_cmd
**
** Description      This function composes a Type 1 Tag command for dynamic memory
**                  and send through NCI to NFCC.
**
** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
**                  otherwise, error status
**
*******************************************************************************/
tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat)
{
    tNFC_STATUS             status  = NFC_STATUS_FAILED;
    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
    BT_HDR                  *p_data;
    UINT8                   *p;

    if (p_cmd_rsp_info)
    {
        /* a valid opcode for RW */
        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
        if (p_data)
        {
            p_t1t->p_cmd_rsp_info   = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
            p_t1t->addr             = add;
            p_data->offset          = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
            p                       = (UINT8 *) (p_data + 1) + p_data->offset;
            UINT8_TO_BE_STREAM (p, opcode);
            UINT8_TO_BE_STREAM (p, add);

            if (p_dat)
            {
                ARRAY_TO_STREAM (p, p_dat, 8);
            }
            else
            {
                memset (p, 0, 8);
                p += 8;
            }
            ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
            p_data->len     = p_cmd_rsp_info->cmd_len;

            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
            rw_cb.cur_retry = 0;
            memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);

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

            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);

            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
            {
                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
            }
        }
        else
        {
            status = NFC_STATUS_NO_BUFFERS;
        }
    }
    return status;
}
コード例 #3
0
ファイル: rw_t4t.c プロジェクト: Abocer/android-4.2_r1
/*******************************************************************************
**
** Function         rw_t4t_send_to_lower
**
** Description      Send C-APDU to lower layer
**
** Returns          TRUE if success
**
*******************************************************************************/
static BOOLEAN rw_t4t_send_to_lower (BT_HDR *p_c_apdu)
{
#if (BT_TRACE_PROTOCOL == TRUE)
    DispRWT4Tags (p_c_apdu, FALSE);
#endif

    if (NFC_SendData (NFC_RF_CONN_ID, p_c_apdu) != NFC_STATUS_OK)
    {
        RW_TRACE_ERROR0 ("rw_t4t_send_to_lower (): NFC_SendData () failed");
        return FALSE;
    }

    nfc_start_quick_timer (&rw_cb.tcb.t4t.timer, NFC_TTYPE_RW_T4T_RESPONSE,
                           (RW_T4T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);

    return TRUE;
}
コード例 #4
0
/*******************************************************************************
**
** Function         rw_t2t_resume_op
**
** Description      This function will continue operation after moving to new
**                  sector
**
** Returns          tNFC_STATUS
**
*******************************************************************************/
static void rw_t2t_resume_op (void)
{
    tRW_T2T_CB          *p_t2t = &rw_cb.tcb.t2t;
    tRW_READ_DATA       evt_data;
    BT_HDR              *p_cmd_buf;
    tRW_EVENT           event;
    const tT2T_CMD_RSP_INFO   *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
    UINT8               *p;

    /* Move back to the substate where we were before changing sector */
    p_t2t->substate = p_t2t->prev_substate;

    p              = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
    p_cmd_rsp_info = t2t_cmd_to_rsp_info ((UINT8) *p);
    p_t2t->p_cmd_rsp_info   = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;

    /* 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_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len);
        memcpy (p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_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);
        }
        else
        {
            /* failure - could not send buffer */
            evt_data.p_data = NULL;
            evt_data.status = NFC_STATUS_FAILED;
            event = rw_t2t_info_to_event (p_cmd_rsp_info);
            rw_t2t_handle_op_complete ();
            (*rw_cb.p_cback) (event, (tRW_DATA *) &evt_data);
        }
    }
}
コード例 #5
0
/*******************************************************************************
**
** Function         rw_t2t_sector_change
**
** Description      This function issues Type 2 Tag SECTOR-SELECT command
**                  packet 1.
**
** Returns          tNFC_STATUS
**
*******************************************************************************/
tNFC_STATUS rw_t2t_sector_change (UINT8 sector)
{
    tNFC_STATUS status;
    BT_HDR      *p_data;
    UINT8       *p;
    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;

    if ((p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
    {
        RW_TRACE_ERROR0 ("rw_t2t_sector_change - No buffer");
         return (NFC_STATUS_NO_BUFFERS);
    }

    p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    p = (UINT8 *) (p_data + 1) + p_data->offset;

    UINT8_TO_BE_STREAM (p, sector);
    UINT8_TO_BE_STREAM (p, 0x00);
    UINT8_TO_BE_STREAM (p, 0x00);
    UINT8_TO_BE_STREAM (p, 0x00);

    p_data->len = 4;

    if ((status = NFC_SendData (NFC_RF_CONN_ID , p_data)) == NFC_STATUS_OK)
    {
        /* Passive rsp command and suppose not to get response to this command */
        p_t2t->p_cmd_rsp_info = NULL;
        p_t2t->substate       = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR;

        RW_TRACE_EVENT0 ("rw_t2t_sector_change Sent Second Command");
        nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
                               (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
    }
    else
    {
        RW_TRACE_ERROR1 ("rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u", status);
    }

    return status;
}
コード例 #6
0
ファイル: ce_t4t.c プロジェクト: NXPNFCLinux/linux_libnfc-nci
/*******************************************************************************
**
** Function         ce_t4t_update_binary
**
** Description      Update file and send R-APDU to peer
**
** Returns          TRUE if success
**
*******************************************************************************/
static BOOLEAN ce_t4t_update_binary (UINT16 offset, UINT8 length, UINT8 *p_data)
{
    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
    UINT8       *p;
    UINT8        file_length[2];
    UINT16       starting_offset;
    tCE_DATA     ce_data;

    CE_TRACE_DEBUG3 ("ce_t4t_update_binary (): Offset:0x%04X, Length:0x%04X, selected status = 0x%02X",
                      offset, length, p_t4t->status);

    starting_offset = offset;

    /* update file size (NLEN) */
    if ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0))
    {
        p = file_length;
        UINT16_TO_BE_STREAM (p, p_t4t->nlen);

        while ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0))
        {
            *(file_length + offset++) = *(p_data++);
            length--;
        }

        p = file_length;
        BE_STREAM_TO_UINT16 (p_t4t->nlen, p);
    }

    if (length > 0)
        memcpy (p_t4t->p_scratch_buf + offset - T4T_FILE_LENGTH_SIZE, p_data, length);

    /* if this is the last step: writing non-zero length in NLEN */
    if ((starting_offset == 0) && (p_t4t->nlen > 0))
    {
        nfc_stop_quick_timer (&p_t4t->timer);

        if (ce_cb.p_cback)
        {
            ce_data.update_info.status = NFC_STATUS_OK;
            ce_data.update_info.length = p_t4t->nlen;
            ce_data.update_info.p_data = p_t4t->p_scratch_buf;

            (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_CPLT_EVT, &ce_data);
            CE_TRACE_DEBUG0 ("ce_t4t_update_binary (): Sent CE_T4T_NDEF_UPDATE_CPLT_EVT");
        }

        p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_FILE_UPDATING);
    }
    else if (!(p_t4t->status & CE_T4T_STATUS_NDEF_FILE_UPDATING))
    {
        /* starting of updating */
        p_t4t->status |= CE_T4T_STATUS_NDEF_FILE_UPDATING;

        nfc_start_quick_timer (&p_t4t->timer, NFC_TTYPE_CE_T4T_UPDATE,
                               (CE_T4T_TOUT_UPDATE * QUICK_TIMER_TICKS_PER_SEC) / 1000);

        if (ce_cb.p_cback)
            (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_START_EVT, NULL);
    }

    if (!ce_t4t_send_status (T4T_RSP_CMD_CMPLTED))
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
コード例 #7
0
/*******************************************************************************
**
** 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);
    }
}
コード例 #8
0
/*******************************************************************************
**
** 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);
    }
}