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