rw_t2t.c revision 5c65c3a0f42e174e47fecd4e569606003217ff4e
1/******************************************************************************
2 *
3 *  Copyright (C) 2010-2013 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19
20/******************************************************************************
21 *
22 *  This file contains the implementation for Type 2 tag in Reader/Writer
23 *  mode.
24 *
25 ******************************************************************************/
26#include <string.h>
27#include "nfc_target.h"
28#include "bt_types.h"
29
30#if (NFC_INCLUDED == TRUE)
31#include "nfc_api.h"
32#include "nci_hmsgs.h"
33#include "rw_api.h"
34#include "rw_int.h"
35#include "nfc_int.h"
36#include "gki.h"
37
38/* Static local functions */
39static void rw_t2t_proc_data (UINT8 conn_id, tNFC_CONN_EVT event, BT_HDR *p_pkt);
40static tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat);
41static void rw_t2t_process_error (void);
42static void rw_t2t_process_frame_error (void);
43static void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status);
44static void rw_t2t_resume_op (void);
45
46#if (BT_TRACE_VERBOSE == TRUE)
47static char *rw_t2t_get_state_name (UINT8 state);
48static char *rw_t2t_get_substate_name (UINT8 substate);
49#endif
50
51/*******************************************************************************
52**
53** Function         rw_t2t_proc_data
54**
55** Description      This function handles data evt received from NFC Controller.
56**
57** Returns          none
58**
59*******************************************************************************/
60static void rw_t2t_proc_data (UINT8 conn_id, tNFC_CONN_EVT event, BT_HDR *p_pkt)
61{
62    tRW_EVENT               rw_event    = RW_RAW_FRAME_EVT;
63    tRW_T2T_CB              *p_t2t      = &rw_cb.tcb.t2t;
64    BOOLEAN                 b_notify    = TRUE;
65    BOOLEAN                 b_release   = TRUE;
66    UINT8                   *p;
67    tRW_READ_DATA           evt_data = {0};
68    tT2T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
69    tRW_DETECT_NDEF_DATA    ndef_data;
70#if (BT_TRACE_VERBOSE == TRUE)
71    UINT8                   begin_state     = p_t2t->state;
72#endif
73
74    if (  (p_t2t->state == RW_T2T_STATE_IDLE)
75        ||(p_cmd_rsp_info == NULL)  )
76    {
77        RW_TRACE_DEBUG2 ("rw_t2t_proc_data - Raw frame event! state: IDLE, conn_id: %u  event: %u",
78                           conn_id, event);
79
80        evt_data.status = NFC_STATUS_OK;
81        evt_data.p_data = p_pkt;
82        (*rw_cb.p_cback) (RW_T2T_RAW_FRAME_EVT, (tRW_DATA *)&evt_data);
83        return;
84    }
85#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
86    /* Update rx stats */
87    rw_main_update_rx_stats (p_pkt->len);
88#endif
89    /* Stop timer as response is received */
90    nfc_stop_quick_timer (&p_t2t->t2_timer);
91
92    RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
93
94    if (  (p_pkt->len != p_cmd_rsp_info->rsp_len)
95        &&(p_pkt->len != p_cmd_rsp_info->nack_rsp_len)
96        &&(p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)  )
97    {
98#if (BT_TRACE_VERBOSE == TRUE)
99        RW_TRACE_ERROR1 ("T2T Frame error. state=%s ", rw_t2t_get_state_name (p_t2t->state));
100#else
101        RW_TRACE_ERROR1 ("T2T Frame error. state=0x%02X command=0x%02X ", p_t2t->state);
102#endif
103        /* Retrasmit the last sent command if retry-count < max retry */
104        rw_t2t_process_frame_error ();
105        GKI_freebuf (p_pkt);
106        return;
107    }
108    rw_cb.cur_retry = 0;
109
110    /* Assume the data is just the response byte sequence */
111    p = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
112
113
114    RW_TRACE_EVENT5 ("rw_t2t_proc_data State: %u  conn_id: %u  event: %u  len: %u  data[0]: 0x%02x",
115                      p_t2t->state, conn_id, event, p_pkt->len, *p);
116
117    evt_data.p_data     = NULL;
118
119    if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT)
120    {
121        /* The select process happens in two steps */
122        if ((*p & 0x0f) == T2T_RSP_ACK)
123        {
124            if (rw_t2t_sector_change (p_t2t->select_sector) == NFC_STATUS_OK)
125                b_notify = FALSE;
126            else
127                evt_data.status = NFC_STATUS_FAILED;
128        }
129        else
130        {
131            evt_data.status = NFC_STATUS_FAILED;
132        }
133    }
134    else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)
135    {
136        evt_data.status = NFC_STATUS_FAILED;
137    }
138    else if (p_pkt->len == p_cmd_rsp_info->rsp_len)
139    {
140        /* If the response length indicates positive response or cannot be known from length then assume success */
141        evt_data.status  = NFC_STATUS_OK;
142
143        /* The response data depends on what the current operation was */
144        switch (p_t2t->state)
145        {
146        case RW_T2T_STATE_CHECK_PRESENCE:
147            b_notify = FALSE;
148            rw_t2t_handle_presence_check_rsp (NFC_STATUS_OK);
149            break;
150
151        case RW_T2T_STATE_READ:
152            evt_data.p_data = p_pkt;
153            b_release = FALSE;
154            if (p_t2t->block_read == 0)
155            {
156                p_t2t->b_read_hdr = TRUE;
157                memcpy (p_t2t->tag_hdr,  p, T2T_READ_DATA_LEN);
158
159                /* On Ultralight - C tag, if CC is corrupt, correct it */
160                if (  (p_t2t->tag_hdr[0] == TAG_MIFARE_MID)
161                    &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0)
162                    &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1)  )
163                {
164                    p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC;
165                }
166            }
167            break;
168
169        case RW_T2T_STATE_WRITE:
170            /* Check positive or negative acknowledgment */
171            if ((*p & 0x0f) != T2T_RSP_ACK)
172                evt_data.status = NFC_STATUS_FAILED;
173            break;
174
175        default:
176            /* NDEF/other Tlv Operation/Format Tag/Config Tag as Read only
177             * Check if Positive response to previous write command */
178            if (  (p_cmd_rsp_info->opcode == T2T_CMD_WRITE)
179                &&((*p & 0x0f) != T2T_RSP_ACK)  )
180                evt_data.status = NFC_STATUS_FAILED;
181            else
182            {
183                b_notify = FALSE;
184                rw_t2t_handle_rsp (p);
185            }
186            break;
187        }
188    }
189    else
190    {
191        evt_data.p_data = p_pkt;
192        if (p_t2t->state == RW_T2T_STATE_READ)
193            b_release = FALSE;
194
195        /* Negative response to the command sent */
196        evt_data.status = NFC_STATUS_FAILED;
197    }
198
199    if (b_notify)
200    {
201        rw_event = rw_t2t_info_to_event (p_cmd_rsp_info);
202        /* Move back to idle state */
203        rw_t2t_handle_op_complete ();
204        if (rw_event == RW_T2T_NDEF_DETECT_EVT)
205        {
206            ndef_data.status    = evt_data.status;
207            ndef_data.protocol  = NFC_PROTOCOL_T2T;
208            ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
209            ndef_data.max_size  = 0;
210            ndef_data.cur_size  = 0;
211            (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
212        }
213        else
214            (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
215    }
216
217    if (b_release)
218        GKI_freebuf (p_pkt);
219#if (BT_TRACE_VERBOSE == TRUE)
220    if (begin_state != p_t2t->state)
221    {
222        RW_TRACE_DEBUG2 ("RW T2T state changed:<%s> -> <%s>",
223                          rw_t2t_get_state_name (begin_state),
224                          rw_t2t_get_state_name (p_t2t->state));
225    }
226#endif
227}
228
229/*******************************************************************************
230**
231** Function         rw_t2t_conn_cback
232**
233** Description      This callback function receives events/data from NFCC.
234**
235** Returns          none
236**
237*******************************************************************************/
238void rw_t2t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
239{
240    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
241    tRW_READ_DATA       evt_data;
242
243    RW_TRACE_DEBUG2 ("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
244    /* Only handle static conn_id */
245    if (conn_id != NFC_RF_CONN_ID)
246    {
247        return;
248    }
249
250    switch (event)
251    {
252    case NFC_CONN_CREATE_CEVT:
253    case NFC_CONN_CLOSE_CEVT:
254        break;
255
256    case NFC_DEACTIVATE_CEVT:
257#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
258        /* Display stats */
259        rw_main_log_stats ();
260#endif
261        /* Stop t2t timer (if started) */
262        nfc_stop_quick_timer (&p_t2t->t2_timer);
263
264        /* Free cmd buf for retransmissions */
265        if (p_t2t->p_cur_cmd_buf)
266        {
267            GKI_freebuf (p_t2t->p_cur_cmd_buf);
268            p_t2t->p_cur_cmd_buf = NULL;
269        }
270        /* Free cmd buf used to hold command before sector change */
271        if (p_t2t->p_sec_cmd_buf)
272        {
273            GKI_freebuf (p_t2t->p_sec_cmd_buf);
274            p_t2t->p_sec_cmd_buf = NULL;
275        }
276
277        p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED;
278        NFC_SetStaticRfCback (NULL);
279        break;
280
281    case NFC_DATA_CEVT:
282        if (  (p_data != NULL)
283            &&(p_data->data.status == NFC_STATUS_OK)  )
284        {
285            rw_t2t_proc_data (conn_id, event, (BT_HDR *) (p_data->data.p_data));
286            break;
287        }
288        /* Data event with error status...fall through to NFC_ERROR_CEVT case */
289
290    case NFC_ERROR_CEVT:
291        if (  (p_t2t->state == RW_T2T_STATE_NOT_ACTIVATED)
292            ||(p_t2t->state == RW_T2T_STATE_IDLE)  )
293        {
294#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
295            rw_main_update_trans_error_stats ();
296#endif  /* RW_STATS_INCLUDED */
297            if (event == NFC_ERROR_CEVT)
298                evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
299            else if (p_data)
300                evt_data.status = p_data->status;
301            else
302                evt_data.status = NFC_STATUS_FAILED;
303
304            evt_data.p_data = NULL;
305            (*rw_cb.p_cback) (RW_T2T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data);
306            break;
307        }
308        nfc_stop_quick_timer (&p_t2t->t2_timer);
309#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
310        rw_main_update_trans_error_stats ();
311#endif
312        if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE)
313        {
314            rw_t2t_handle_presence_check_rsp (NFC_STATUS_FAILED);
315        }
316        else
317        {
318            rw_t2t_process_error ();
319        }
320        break;
321
322    default:
323        break;
324
325    }
326}
327
328/*******************************************************************************
329**
330** Function         rw_t2t_send_cmd
331**
332** Description      This function composes a Type 2 Tag command and send it via
333**                  NCI to NFCC.
334**
335** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
336**                  otherwise, error status
337**
338*******************************************************************************/
339tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat)
340{
341    tNFC_STATUS             status  = NFC_STATUS_FAILED;
342    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
343    const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = t2t_cmd_to_rsp_info (opcode);
344    BT_HDR                  *p_data;
345    UINT8                   *p;
346
347    if (p_cmd_rsp_info)
348    {
349        /* a valid opcode for RW */
350        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
351        if (p_data)
352        {
353            p_t2t->p_cmd_rsp_info   = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;
354            p_data->offset  = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
355            p               = (UINT8 *) (p_data + 1) + p_data->offset;
356
357            UINT8_TO_STREAM (p, opcode);
358
359            if (p_dat)
360            {
361                ARRAY_TO_STREAM (p, p_dat, (p_cmd_rsp_info->cmd_len - 1));
362            }
363
364            p_data->len     = p_cmd_rsp_info->cmd_len;
365
366            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
367            rw_cb.cur_retry = 0;
368            memcpy (p_t2t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
369
370#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
371            /* Update stats */
372            rw_main_update_tx_stats (p_data->len, FALSE);
373#endif
374            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
375
376            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
377            {
378                nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
379                       (RW_T2T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000);
380            }
381            else
382            {
383#if (BT_TRACE_VERBOSE == TRUE)
384                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));
385#else
386                RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=0x%02X substate=0x%02X ", p_t2t->state, p_t2t->substate);
387#endif
388            }
389        }
390        else
391        {
392            status = NFC_STATUS_NO_BUFFERS;
393        }
394    }
395    return status;
396}
397
398/*******************************************************************************
399**
400** Function         rw_t2t_process_timeout
401**
402** Description      handles timeout event
403**
404** Returns          none
405**
406*******************************************************************************/
407void rw_t2t_process_timeout (TIMER_LIST_ENT *p_tle)
408{
409    tRW_READ_DATA       evt_data;
410    tRW_T2T_CB          *p_t2t          = &rw_cb.tcb.t2t;
411
412    if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE)
413    {
414        /* Move back to idle state */
415        rw_t2t_handle_presence_check_rsp (NFC_STATUS_FAILED);
416        return;
417    }
418
419    if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)
420    {
421        p_t2t->sector   = p_t2t->select_sector;
422        /* Here timeout is an acknowledgment for successfull sector change */
423        if (p_t2t->state == RW_T2T_STATE_SELECT_SECTOR)
424        {
425            /* Notify that select sector op is successfull */
426            rw_t2t_handle_op_complete ();
427            evt_data.status = NFC_STATUS_OK;
428            evt_data.p_data = NULL;
429            (*rw_cb.p_cback) (RW_T2T_SELECT_CPLT_EVT, (tRW_DATA *) &evt_data);
430        }
431        else
432        {
433            /* Resume operation from where we stopped before sector change */
434            rw_t2t_resume_op ();
435        }
436    }
437    else if (p_t2t->state != RW_T2T_STATE_IDLE)
438    {
439#if (BT_TRACE_VERBOSE == TRUE)
440        RW_TRACE_ERROR1 ("T2T timeout. state=%s ", rw_t2t_get_state_name (p_t2t->state));
441#else
442        RW_TRACE_ERROR1 ("T2T timeout. state=0x%02X ", p_t2t->state);
443#endif
444        /* Handle timeout error as no response to the command sent */
445        rw_t2t_process_error ();
446    }
447}
448
449/*******************************************************************************
450**
451** Function         rw_t2t_process_frame_error
452**
453** Description      handles frame crc error
454**
455** Returns          none
456**
457*******************************************************************************/
458static void rw_t2t_process_frame_error (void)
459{
460#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
461    /* Update stats */
462    rw_main_update_crc_error_stats ();
463#endif
464    /* Process the error */
465    rw_t2t_process_error ();
466}
467
468/*******************************************************************************
469**
470** Function         rw_t2t_process_error
471**
472** Description      Process error including Timeout, Frame error. This function
473**                  will retry atleast till RW_MAX_RETRIES before give up and
474**                  sending negative notification to upper layer
475**
476** Returns          none
477**
478*******************************************************************************/
479static void rw_t2t_process_error (void)
480{
481    tRW_READ_DATA           evt_data;
482    tRW_EVENT               rw_event;
483    BT_HDR                  *p_cmd_buf;
484    tRW_T2T_CB              *p_t2t          = &rw_cb.tcb.t2t;
485    tT2T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
486    tRW_DETECT_NDEF_DATA    ndef_data;
487
488    RW_TRACE_DEBUG1 ("rw_t2t_process_error () State: %u", p_t2t->state);
489
490    /* Retry sending command if retry-count < max */
491    if (rw_cb.cur_retry < RW_MAX_RETRIES)
492    {
493        /* retry sending the command */
494        rw_cb.cur_retry++;
495
496        RW_TRACE_DEBUG2 ("T2T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
497
498        /* allocate a new buffer for message */
499        if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
500        {
501            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);
502#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
503            /* Update stats */
504            rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
505#endif
506            if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
507            {
508                /* Start timer for waiting for response */
509                nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
510                                       (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
511
512                return;
513            }
514        }
515    }
516    else
517    {
518        RW_TRACE_DEBUG1 ("T2T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
519    }
520    rw_event = rw_t2t_info_to_event (p_cmd_rsp_info);
521#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
522    /* update failure count */
523    rw_main_update_fail_stats ();
524#endif
525    /* If not activated remain in non activated state, otherwise move to idle state */
526    if (p_t2t->state != RW_T2T_STATE_NOT_ACTIVATED)
527        rw_t2t_handle_op_complete ();
528
529    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
530    evt_data.status = NFC_STATUS_TIMEOUT;
531    if (rw_event == RW_T2T_NDEF_DETECT_EVT)
532    {
533        ndef_data.status    = evt_data.status;
534        ndef_data.protocol  = NFC_PROTOCOL_T2T;
535        ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
536        ndef_data.max_size  = 0;
537        ndef_data.cur_size  = 0;
538        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
539    }
540    else
541    {
542        evt_data.p_data = NULL;
543        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
544    }
545}
546
547/*****************************************************************************
548**
549** Function         rw_t2t_handle_presence_check_rsp
550**
551** Description      Handle response to presence check
552**
553** Returns          Nothing
554**
555*****************************************************************************/
556void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status)
557{
558    tRW_READ_DATA   evt_data;
559
560    /* Notify, Tag is present or not */
561    evt_data.status = status;
562    rw_t2t_handle_op_complete ();
563
564    (*rw_cb.p_cback) (RW_T2T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
565}
566
567/*******************************************************************************
568**
569** Function         rw_t2t_resume_op
570**
571** Description      This function will continue operation after moving to new
572**                  sector
573**
574** Returns          tNFC_STATUS
575**
576*******************************************************************************/
577static void rw_t2t_resume_op (void)
578{
579    tRW_T2T_CB          *p_t2t = &rw_cb.tcb.t2t;
580    tRW_READ_DATA       evt_data;
581    BT_HDR              *p_cmd_buf;
582    tRW_EVENT           event;
583    const tT2T_CMD_RSP_INFO   *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
584    UINT8               *p;
585
586    /* Move back to the substate where we were before changing sector */
587    p_t2t->substate = p_t2t->prev_substate;
588
589    p              = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
590    p_cmd_rsp_info = t2t_cmd_to_rsp_info ((UINT8) *p);
591    p_t2t->p_cmd_rsp_info   = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;
592
593    /* allocate a new buffer for message */
594    if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
595    {
596        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);
597        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);
598
599#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
600        /* Update stats */
601         rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
602#endif
603        if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
604        {
605            /* Start timer for waiting for response */
606            nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
607                                   (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
608        }
609        else
610        {
611            /* failure - could not send buffer */
612            evt_data.p_data = NULL;
613            evt_data.status = NFC_STATUS_FAILED;
614            event = rw_t2t_info_to_event (p_cmd_rsp_info);
615            rw_t2t_handle_op_complete ();
616            (*rw_cb.p_cback) (event, (tRW_DATA *) &evt_data);
617        }
618    }
619}
620
621/*******************************************************************************
622**
623** Function         rw_t2t_sector_change
624**
625** Description      This function issues Type 2 Tag SECTOR-SELECT command
626**                  packet 1.
627**
628** Returns          tNFC_STATUS
629**
630*******************************************************************************/
631tNFC_STATUS rw_t2t_sector_change (UINT8 sector)
632{
633    tNFC_STATUS status;
634    BT_HDR      *p_data;
635    UINT8       *p;
636    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
637
638    if ((p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
639    {
640        RW_TRACE_ERROR0 ("rw_t2t_sector_change - No buffer");
641         return (NFC_STATUS_NO_BUFFERS);
642    }
643
644    p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
645    p = (UINT8 *) (p_data + 1) + p_data->offset;
646
647    UINT8_TO_BE_STREAM (p, sector);
648    UINT8_TO_BE_STREAM (p, 0x00);
649    UINT8_TO_BE_STREAM (p, 0x00);
650    UINT8_TO_BE_STREAM (p, 0x00);
651
652    p_data->len = 4;
653
654    if ((status = NFC_SendData (NFC_RF_CONN_ID , p_data)) == NFC_STATUS_OK)
655    {
656        /* Passive rsp command and suppose not to get response to this command */
657        p_t2t->p_cmd_rsp_info = NULL;
658        p_t2t->substate       = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR;
659
660        RW_TRACE_EVENT0 ("rw_t2t_sector_change Sent Second Command");
661        nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
662                               (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
663    }
664    else
665    {
666        RW_TRACE_ERROR1 ("rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u", status);
667    }
668
669    return status;
670}
671
672/*******************************************************************************
673**
674** Function         rw_t2t_read
675**
676** Description      This function issues Type 2 Tag READ command for the
677**                  specified block. If the specified block is in different
678**                  sector then it first sends command to move to new sector
679**                  and after the tag moves to new sector it issues the read
680**                  command for the block.
681**
682** Returns          tNFC_STATUS
683**
684*******************************************************************************/
685tNFC_STATUS rw_t2t_read (UINT16 block)
686{
687    tNFC_STATUS status;
688    UINT8       *p;
689    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
690    UINT8       sector_byte2[1];
691    UINT8       read_cmd[1];
692
693
694    read_cmd[0] = block % T2T_BLOCKS_PER_SECTOR;
695    if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR)
696    {
697        sector_byte2[0] = 0xFF;
698        /* First Move to new sector before sending Read command */
699        if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL,sector_byte2)) == NFC_STATUS_OK)
700        {
701            /* Prepare command that needs to be sent after sector change op is completed */
702            p_t2t->select_sector         = (UINT8) (block/T2T_BLOCKS_PER_SECTOR);
703            p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
704
705            p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
706            UINT8_TO_BE_STREAM (p, T2T_CMD_READ);
707            UINT8_TO_BE_STREAM (p, read_cmd[0]);
708            p_t2t->p_sec_cmd_buf->len = 2;
709            p_t2t->block_read = block;
710
711            /* Backup the current substate to move back to this substate after changing sector */
712            p_t2t->prev_substate = p_t2t->substate;
713            p_t2t->substate      = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
714            return NFC_STATUS_OK;
715        }
716        return NFC_STATUS_FAILED;
717    }
718
719    /* Send Read command as sector change is not needed */
720    if ((status = rw_t2t_send_cmd (T2T_CMD_READ, (UINT8 *) read_cmd)) == NFC_STATUS_OK)
721    {
722        p_t2t->block_read = block;
723        RW_TRACE_EVENT1 ("rw_t2t_read Sent Command for Block: %u", block);
724    }
725
726    return status;
727}
728
729/*******************************************************************************
730**
731** Function         rw_t2t_write
732**
733** Description      This function issues Type 2 Tag WRITE command for the
734**                  specified block.  If the specified block is in different
735**                  sector then it first sends command to move to new sector
736**                  and after the tag moves to new sector it issues the write
737**                  command for the block.
738**
739** Returns          tNFC_STATUS
740**
741*******************************************************************************/
742tNFC_STATUS rw_t2t_write (UINT16 block, UINT8 *p_write_data)
743{
744    tNFC_STATUS status;
745    UINT8       *p;
746    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
747    UINT8       write_cmd[T2T_WRITE_DATA_LEN + 1];
748    UINT8       sector_byte2[1];
749
750    p_t2t->block_written = block;
751    write_cmd[0] = (UINT8) (block%T2T_BLOCKS_PER_SECTOR);
752    memcpy (&write_cmd[1], p_write_data, T2T_WRITE_DATA_LEN);
753
754    if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR)
755    {
756        sector_byte2[0] = 0xFF;
757        /* First Move to new sector before sending Write command */
758        if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK)
759        {
760            /* Prepare command that needs to be sent after sector change op is completed */
761            p_t2t->select_sector         = (UINT8) (block/T2T_BLOCKS_PER_SECTOR);
762            p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
763            p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
764            UINT8_TO_BE_STREAM (p, T2T_CMD_WRITE);
765            memcpy (p, write_cmd, T2T_WRITE_DATA_LEN + 1);
766            p_t2t->p_sec_cmd_buf->len   = 2 + T2T_WRITE_DATA_LEN;
767            p_t2t->block_written  = block;
768
769            /* Backup the current substate to move back to this substate after changing sector */
770            p_t2t->prev_substate        = p_t2t->substate;
771            p_t2t->substate             = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
772            return NFC_STATUS_OK;
773        }
774        return NFC_STATUS_FAILED;
775    }
776
777    /* Send Write command as sector change is not needed */
778    if ((status = rw_t2t_send_cmd (T2T_CMD_WRITE, write_cmd)) == NFC_STATUS_OK)
779    {
780        RW_TRACE_EVENT1 ("rw_t2t_write Sent Command for Block: %u", block);
781    }
782
783    return status;
784}
785
786/*******************************************************************************
787**
788** Function         rw_t2t_select
789**
790** Description      This function selects type 2 tag.
791**
792** Returns          Tag selection status
793**
794*******************************************************************************/
795tNFC_STATUS rw_t2t_select (void)
796{
797    tRW_T2T_CB    *p_t2t = &rw_cb.tcb.t2t;
798
799    p_t2t->state       = RW_T2T_STATE_IDLE;
800    p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
801
802
803    /* Alloc cmd buf for retransmissions */
804    if (p_t2t->p_cur_cmd_buf ==  NULL)
805    {
806        if ((p_t2t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
807        {
808            RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer for retransmission");
809            return (NFC_STATUS_FAILED);
810        }
811    }
812    /* Alloc cmd buf for holding a command untill sector changes */
813    if (p_t2t->p_sec_cmd_buf ==  NULL)
814    {
815        if ((p_t2t->p_sec_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
816        {
817            RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer used during sector change");
818            return (NFC_STATUS_FAILED);
819        }
820    }
821
822    NFC_SetStaticRfCback (rw_t2t_conn_cback);
823    rw_t2t_handle_op_complete ();
824
825    return NFC_STATUS_OK;
826}
827
828/*****************************************************************************
829**
830** Function         rw_t2t_handle_op_complete
831**
832** Description      Reset to IDLE state
833**
834** Returns          Nothing
835**
836*****************************************************************************/
837void rw_t2t_handle_op_complete (void)
838{
839    tRW_T2T_CB      *p_t2t  = &rw_cb.tcb.t2t;
840
841    if (  (p_t2t->state == RW_T2T_STATE_READ_NDEF)
842        ||(p_t2t->state == RW_T2T_STATE_WRITE_NDEF)  )
843    {
844        p_t2t->b_read_data = FALSE;
845    }
846
847    p_t2t->state    = RW_T2T_STATE_IDLE;
848    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
849    return;
850}
851
852/*****************************************************************************
853**
854** Function         RW_T2tPresenceCheck
855**
856** Description
857**      Check if the tag is still in the field.
858**
859**      The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
860**      or non-presence.
861**
862** Returns
863**      NFC_STATUS_OK, if raw data frame sent
864**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
865**      NFC_STATUS_FAILED: other error
866**
867*****************************************************************************/
868tNFC_STATUS RW_T2tPresenceCheck (void)
869{
870    tNFC_STATUS retval = NFC_STATUS_OK;
871    tRW_DATA evt_data;
872    tRW_CB *p_rw_cb = &rw_cb;
873    UINT8 sector_blk = 0;           /* block 0 of current sector */
874
875    RW_TRACE_API0 ("RW_T2tPresenceCheck");
876
877    /* If RW_SelectTagType was not called (no conn_callback) return failure */
878    if (!p_rw_cb->p_cback)
879    {
880        retval = NFC_STATUS_FAILED;
881    }
882    /* If we are not activated, then RW_T2T_PRESENCE_CHECK_EVT status=FAIL */
883    else if (p_rw_cb->tcb.t2t.state == RW_T2T_STATE_NOT_ACTIVATED)
884    {
885        evt_data.status = NFC_STATUS_FAILED;
886        (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
887    }
888    /* If command is pending, assume tag is still present */
889    else if (p_rw_cb->tcb.t2t.state != RW_T2T_STATE_IDLE)
890    {
891        evt_data.status = NFC_STATUS_OK;
892        (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
893    }
894    else
895    {
896        /* IDLE state: send a READ command to block 0 of the current sector */
897        if((retval = rw_t2t_send_cmd (T2T_CMD_READ, &sector_blk))== NFC_STATUS_OK)
898        {
899            p_rw_cb->tcb.t2t.state = RW_T2T_STATE_CHECK_PRESENCE;
900        }
901    }
902
903    return (retval);
904}
905
906/*******************************************************************************
907**
908** Function         RW_T2tRead
909**
910** Description      This function issues the Type 2 Tag READ command. When the
911**                  operation is complete the callback function will be called
912**                  with a RW_T2T_READ_EVT.
913**
914** Returns          tNFC_STATUS
915**
916*******************************************************************************/
917tNFC_STATUS RW_T2tRead (UINT16 block)
918{
919    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
920    tNFC_STATUS status;
921
922    if (p_t2t->state != RW_T2T_STATE_IDLE)
923    {
924        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
925        return (NFC_STATUS_FAILED);
926    }
927
928    if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
929    {
930        p_t2t->state    = RW_T2T_STATE_READ;
931        RW_TRACE_EVENT0 ("RW_T2tRead Sent Read command");
932    }
933
934    return status;
935
936}
937
938/*******************************************************************************
939**
940** Function         RW_T2tWrite
941**
942** Description      This function issues the Type 2 Tag WRITE command. When the
943**                  operation is complete the callback function will be called
944**                  with a RW_T2T_WRITE_EVT.
945**
946**                  p_new_bytes points to the array of 4 bytes to be written
947**
948** Returns          tNFC_STATUS
949**
950*******************************************************************************/
951tNFC_STATUS RW_T2tWrite (UINT16 block, UINT8 *p_write_data)
952{
953    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
954    tNFC_STATUS status;
955
956    if (p_t2t->state != RW_T2T_STATE_IDLE)
957    {
958        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
959        return (NFC_STATUS_FAILED);
960    }
961
962    if ((status = rw_t2t_write (block, p_write_data)) == NFC_STATUS_OK)
963    {
964        p_t2t->state    = RW_T2T_STATE_WRITE;
965        if (block < T2T_FIRST_DATA_BLOCK)
966            p_t2t->b_read_hdr = FALSE;
967        else if (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS))
968            p_t2t->b_read_data = FALSE;
969        RW_TRACE_EVENT0 ("RW_T2tWrite Sent Write command");
970    }
971
972    return status;
973}
974
975/*******************************************************************************
976**
977** Function         RW_T2tSectorSelect
978**
979** Description      This function issues the Type 2 Tag SECTOR-SELECT command
980**                  packet 1. If a NACK is received as the response, the callback
981**                  function will be called with a RW_T2T_SECTOR_SELECT_EVT. If
982**                  an ACK is received as the response, the command packet 2 with
983**                  the given sector number is sent to the peer device. When the
984**                  response for packet 2 is received, the callback function will
985**                  be called with a RW_T2T_SECTOR_SELECT_EVT.
986**
987**                  A sector is 256 contiguous blocks (1024 bytes).
988**
989** Returns          tNFC_STATUS
990**
991*******************************************************************************/
992tNFC_STATUS RW_T2tSectorSelect (UINT8 sector)
993{
994    tNFC_STATUS status;
995    tRW_T2T_CB  *p_t2t       = &rw_cb.tcb.t2t;
996    UINT8       sector_byte2[1];
997
998    if (p_t2t->state != RW_T2T_STATE_IDLE)
999    {
1000        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
1001        return (NFC_STATUS_FAILED);
1002    }
1003
1004    if (sector >= T2T_MAX_SECTOR)
1005    {
1006        RW_TRACE_ERROR2 ("RW_T2tSectorSelect - Invalid sector: %u, T2 Max supported sector value: %u", sector, T2T_MAX_SECTOR - 1);
1007        return (NFC_STATUS_FAILED);
1008    }
1009
1010    sector_byte2[0] = 0xFF;
1011
1012    if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK)
1013    {
1014        p_t2t->state         = RW_T2T_STATE_SELECT_SECTOR;
1015        p_t2t->select_sector = sector;
1016        p_t2t->substate      = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
1017
1018        RW_TRACE_EVENT0 ("RW_T2tSectorSelect Sent Sector select first command");
1019    }
1020
1021    return status;
1022}
1023
1024#if (BT_TRACE_VERBOSE == TRUE)
1025/*******************************************************************************
1026**
1027** Function         rw_t2t_get_state_name
1028**
1029** Description      This function returns the state name.
1030**
1031** NOTE             conditionally compiled to save memory.
1032**
1033** Returns          pointer to the name
1034**
1035*******************************************************************************/
1036static char *rw_t2t_get_state_name (UINT8 state)
1037{
1038    switch (state)
1039    {
1040    case RW_T2T_STATE_NOT_ACTIVATED:
1041        return ("NOT_ACTIVATED");
1042    case RW_T2T_STATE_IDLE:
1043        return ("IDLE");
1044    case RW_T2T_STATE_READ:
1045        return ("APP_READ");
1046    case RW_T2T_STATE_WRITE:
1047        return ("APP_WRITE");
1048    case RW_T2T_STATE_SELECT_SECTOR:
1049        return ("SECTOR_SELECT");
1050    case RW_T2T_STATE_DETECT_TLV:
1051        return ("TLV_DETECT");
1052    case RW_T2T_STATE_READ_NDEF:
1053        return ("READ_NDEF");
1054    case RW_T2T_STATE_WRITE_NDEF:
1055        return ("WRITE_NDEF");
1056    case RW_T2T_STATE_SET_TAG_RO:
1057        return ("SET_TAG_RO");
1058    case RW_T2T_STATE_CHECK_PRESENCE:
1059        return ("CHECK_PRESENCE");
1060    default:
1061        return ("???? UNKNOWN STATE");
1062    }
1063}
1064
1065/*******************************************************************************
1066**
1067** Function         rw_t2t_get_substate_name
1068**
1069** Description      This function returns the substate name.
1070**
1071** NOTE             conditionally compiled to save memory.
1072**
1073** Returns          pointer to the name
1074**
1075*******************************************************************************/
1076static char *rw_t2t_get_substate_name (UINT8 substate)
1077{
1078    switch (substate)
1079    {
1080    case RW_T2T_SUBSTATE_NONE:
1081        return ("RW_T2T_SUBSTATE_NONE");
1082    case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT:
1083        return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT");
1084    case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR:
1085        return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR");
1086    case RW_T2T_SUBSTATE_WAIT_READ_CC:
1087        return ("RW_T2T_SUBSTATE_WAIT_READ_CC");
1088    case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
1089        return ("RW_T2T_SUBSTATE_WAIT_TLV_DETECT");
1090    case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
1091        return ("RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN");
1092    case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
1093        return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0");
1094    case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
1095        return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1");
1096    case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
1097        return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE");
1098    case RW_T2T_SUBSTATE_WAIT_READ_LOCKS:
1099        return ("RW_T2T_SUBSTATE_WAIT_READ_LOCKS");
1100    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
1101        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK");
1102    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
1103        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK");
1104    case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
1105        return ("RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK");
1106    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
1107        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK");
1108    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
1109        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK");
1110    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
1111        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK");
1112    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
1113        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK");
1114    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
1115        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK");
1116    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
1117        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK");
1118    case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
1119        return ("RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT");
1120    default:
1121        return ("???? UNKNOWN SUBSTATE");
1122    }
1123}
1124
1125#endif /* (BT_TRACE_VERBOSE == TRUE) */
1126
1127#endif /* NFC_INCLUDED == TRUE*/
1128