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 1 tag in Reader/Writer
23 *  mode.
24 *
25 ******************************************************************************/
26#include <string.h>
27#include "nfc_target.h"
28
29#if (NFC_INCLUDED == TRUE)
30#include "nfc_api.h"
31#include "nci_hmsgs.h"
32#include "rw_api.h"
33#include "rw_int.h"
34#include "nfc_int.h"
35#include "gki.h"
36
37/* Local Functions */
38static tRW_EVENT rw_t1t_handle_rid_rsp (BT_HDR *p_pkt);
39static void rw_t1t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
40static void rw_t1t_process_frame_error (void);
41static void rw_t1t_process_error (void);
42static void rw_t1t_handle_presence_check_rsp (tNFC_STATUS status);
43#if (BT_TRACE_VERBOSE == TRUE)
44static char *rw_t1t_get_state_name (UINT8 state);
45static char *rw_t1t_get_sub_state_name (UINT8 sub_state);
46static char *rw_t1t_get_event_name (UINT8 event);
47#endif
48
49/*******************************************************************************
50**
51** Function         rw_t1t_data_cback
52**
53** Description      This callback function handles data from NFCC.
54**
55** Returns          none
56**
57*******************************************************************************/
58static void rw_t1t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
59{
60    tRW_T1T_CB              *p_t1t      = &rw_cb.tcb.t1t;
61    tRW_EVENT               rw_event    = RW_RAW_FRAME_EVT;
62    BOOLEAN                 b_notify    = TRUE;
63    tRW_DATA                evt_data;
64    BT_HDR                  *p_pkt;
65    UINT8                   *p;
66    tT1T_CMD_RSP_INFO       *p_cmd_rsp_info     = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
67#if (BT_TRACE_VERBOSE == TRUE)
68    UINT8                   begin_state         = p_t1t->state;
69#endif
70
71    p_pkt = (BT_HDR *) (p_data->data.p_data);
72    if (p_pkt == NULL)
73        return;
74    /* Assume the data is just the response byte sequence */
75    p = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
76
77#if (BT_TRACE_VERBOSE == TRUE)
78    RW_TRACE_DEBUG2 ("rw_t1t_data_cback (): state:%s (%d)", rw_t1t_get_state_name (p_t1t->state), p_t1t->state);
79#else
80    RW_TRACE_DEBUG1 ("rw_t1t_data_cback (): state=%d", p_t1t->state);
81#endif
82
83    evt_data.status = NFC_STATUS_OK;
84
85    if(  (p_t1t->state == RW_T1T_STATE_IDLE)
86       ||(!p_cmd_rsp_info)  )
87    {
88        /* If previous command was retransmitted and if response is pending to previous command retransmission,
89         * check if lenght and ADD/ADD8/ADDS field matches the expected value of previous
90         * retransmited command response. However, ignore ADD field if the command was RALL/RID
91         */
92        if (  (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
93            &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len)
94            &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p))  )
95        {
96            /* Response to previous command retransmission */
97            RW_TRACE_ERROR2 ("T1T Response to previous command in Idle state. command=0x%02x, Remaining max retx rsp:0x%02x ", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
98            p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
99            GKI_freebuf (p_pkt);
100        }
101        else
102        {
103            /* Raw frame event */
104            evt_data.data.p_data = p_pkt;
105            (*rw_cb.p_cback) (RW_T1T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
106        }
107        return;
108    }
109
110#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
111    /* Update rx stats */
112    rw_main_update_rx_stats (p_pkt->len);
113#endif  /* RW_STATS_INCLUDED */
114
115
116    if (  (p_pkt->len != p_cmd_rsp_info->rsp_len)
117        ||((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID) && (*p != p_t1t->addr))  )
118
119    {
120        /* If previous command was retransmitted and if response is pending to previous command retransmission,
121         * then check if lenght and ADD/ADD8/ADDS field matches the expected value of previous
122         * retransmited command response. However, ignore ADD field if the command was RALL/RID
123         */
124        if (  (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
125            &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len)
126            &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p))  )
127        {
128            RW_TRACE_ERROR2 ("T1T Response to previous command. command=0x%02x, Remaining max retx rsp:0x%02x", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
129            p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
130        }
131        else
132        {
133            /* Stop timer as some response to current command is received */
134            nfc_stop_quick_timer (&p_t1t->timer);
135            /* Retrasmit the last sent command if retry-count < max retry */
136#if (BT_TRACE_VERBOSE == TRUE)
137            RW_TRACE_ERROR2 ("T1T Frame error. state=%s command (opcode) = 0x%02x", rw_t1t_get_state_name (p_t1t->state), p_cmd_rsp_info->opcode);
138#else
139            RW_TRACE_ERROR2 ("T1T Frame error. state=0x%02x command = 0x%02x ", p_t1t->state, p_cmd_rsp_info->opcode);
140#endif
141            rw_t1t_process_frame_error ();
142        }
143        GKI_freebuf (p_pkt);
144        return;
145    }
146
147    /* Stop timer as response to current command is received */
148    nfc_stop_quick_timer (&p_t1t->timer);
149
150    RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
151
152    /* If we did not receive response to all retransmitted previous command,
153     * dont expect that as response have come for the current command itself.
154     */
155    if (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
156        memset (&(p_t1t->prev_cmd_rsp_info), 0, sizeof (tRW_T1T_PREV_CMD_RSP_INFO));
157
158    if (rw_cb.cur_retry)
159    {
160    /* If the current command was retransmitted to get this response, we might get
161       response later to all or some of the retrasnmission of the current command
162     */
163        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;
164        p_t1t->prev_cmd_rsp_info.rsp_len       = p_cmd_rsp_info->rsp_len;
165        p_t1t->prev_cmd_rsp_info.op_code       = p_cmd_rsp_info->opcode;
166        p_t1t->prev_cmd_rsp_info.pend_retx_rsp = (UINT8) rw_cb.cur_retry;
167    }
168
169    rw_cb.cur_retry = 0;
170
171    if (p_cmd_rsp_info->opcode == T1T_CMD_RID)
172    {
173        rw_event = rw_t1t_handle_rid_rsp (p_pkt);
174    }
175    else
176    {
177        rw_event = rw_t1t_handle_rsp (p_cmd_rsp_info, &b_notify, p, &evt_data.status);
178    }
179
180    if (b_notify)
181    {
182        if(  (p_t1t->state != RW_T1T_STATE_READ)
183           &&(p_t1t->state != RW_T1T_STATE_WRITE)  )
184        {
185            GKI_freebuf (p_pkt);
186            evt_data.data.p_data = NULL;
187        }
188        else
189        {
190            evt_data.data.p_data = p_pkt;
191        }
192        rw_t1t_handle_op_complete ();
193        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
194    }
195    else
196        GKI_freebuf (p_pkt);
197
198#if (BT_TRACE_VERBOSE == TRUE)
199    if (begin_state != p_t1t->state)
200    {
201        RW_TRACE_DEBUG2 ("RW T1T state changed:<%s> -> <%s>",
202                          rw_t1t_get_state_name (begin_state),
203                          rw_t1t_get_state_name (p_t1t->state));
204    }
205#endif
206}
207
208/*******************************************************************************
209**
210** Function         rw_t1t_conn_cback
211**
212** Description      This callback function receives the events/data from NFCC.
213**
214** Returns          none
215**
216*******************************************************************************/
217void rw_t1t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
218{
219    tRW_T1T_CB          *p_t1t  = &rw_cb.tcb.t1t;
220    tRW_READ_DATA       evt_data;
221
222    RW_TRACE_DEBUG2 ("rw_t1t_conn_cback: conn_id=%i, evt=0x%x", conn_id, event);
223    /* Only handle static conn_id */
224    if (conn_id != NFC_RF_CONN_ID)
225    {
226        RW_TRACE_WARNING1 ("rw_t1t_conn_cback - Not static connection id: =%i", conn_id);
227        return;
228    }
229
230    switch (event)
231    {
232    case NFC_CONN_CREATE_CEVT:
233    case NFC_CONN_CLOSE_CEVT:
234        break;
235
236    case NFC_DEACTIVATE_CEVT:
237#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
238        /* Display stats */
239        rw_main_log_stats ();
240#endif  /* RW_STATS_INCLUDED */
241
242        /* Stop t1t timer (if started) */
243        nfc_stop_quick_timer (&p_t1t->timer);
244
245        /* Free cmd buf for retransmissions */
246        if (p_t1t->p_cur_cmd_buf)
247        {
248            GKI_freebuf (p_t1t->p_cur_cmd_buf);
249            p_t1t->p_cur_cmd_buf = NULL;
250        }
251
252        p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
253        NFC_SetStaticRfCback (NULL);
254        break;
255
256    case NFC_DATA_CEVT:
257        if (  (p_data != NULL)
258            &&(p_data->data.status == NFC_STATUS_OK)  )
259        {
260            rw_t1t_data_cback (conn_id, event, p_data);
261            break;
262        }
263        /* Data event with error status...fall through to NFC_ERROR_CEVT case */
264
265    case NFC_ERROR_CEVT:
266        if (  (p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED)
267            ||(p_t1t->state == RW_T1T_STATE_IDLE)  )
268        {
269#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
270            rw_main_update_trans_error_stats ();
271#endif  /* RW_STATS_INCLUDED */
272
273            if (event == NFC_ERROR_CEVT)
274                evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
275            else if (p_data)
276                evt_data.status = p_data->status;
277            else
278                evt_data.status = NFC_STATUS_FAILED;
279
280            evt_data.p_data = NULL;
281            (*rw_cb.p_cback) (RW_T1T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data);
282            break;
283        }
284        nfc_stop_quick_timer (&p_t1t->timer);
285
286#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
287        rw_main_update_trans_error_stats ();
288#endif  /* RW_STATS_INCLUDED */
289
290        if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
291        {
292            rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
293        }
294        else
295        {
296            rw_t1t_process_error ();
297        }
298        break;
299
300    default:
301        break;
302
303    }
304}
305
306/*******************************************************************************
307**
308** Function         rw_t1t_send_static_cmd
309**
310** Description      This function composes a Type 1 Tag command for static
311**                  memory and send through NCI to NFCC.
312**
313** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
314**                  otherwise, error status
315**
316*******************************************************************************/
317tNFC_STATUS rw_t1t_send_static_cmd (UINT8 opcode, UINT8 add, UINT8 dat)
318{
319    tNFC_STATUS             status  = NFC_STATUS_FAILED;
320    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
321    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
322    BT_HDR                  *p_data;
323    UINT8                   *p;
324
325    if (p_cmd_rsp_info)
326    {
327        /* a valid opcode for RW */
328        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
329        if (p_data)
330        {
331            p_t1t->p_cmd_rsp_info   = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
332            p_t1t->addr             = add;
333            p_data->offset          = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
334            p                       = (UINT8 *) (p_data + 1) + p_data->offset;
335            UINT8_TO_BE_STREAM (p, opcode);
336            UINT8_TO_BE_STREAM (p, add);
337            UINT8_TO_BE_STREAM (p, dat);
338
339            ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
340            p_data->len     = p_cmd_rsp_info->cmd_len;
341
342            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
343            rw_cb.cur_retry = 0;
344            memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
345
346#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
347            /* Update stats */
348            rw_main_update_tx_stats (p_data->len, FALSE);
349#endif  /* RW_STATS_INCLUDED */
350
351            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
352            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
353            {
354                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
355                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
356            }
357        }
358        else
359        {
360            status = NFC_STATUS_NO_BUFFERS;
361        }
362    }
363    return status;
364}
365
366/*******************************************************************************
367**
368** Function         rw_t1t_send_dyn_cmd
369**
370** Description      This function composes a Type 1 Tag command for dynamic memory
371**                  and send through NCI to NFCC.
372**
373** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
374**                  otherwise, error status
375**
376*******************************************************************************/
377tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat)
378{
379    tNFC_STATUS             status  = NFC_STATUS_FAILED;
380    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
381    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
382    BT_HDR                  *p_data;
383    UINT8                   *p;
384
385    if (p_cmd_rsp_info)
386    {
387        /* a valid opcode for RW */
388        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
389        if (p_data)
390        {
391            p_t1t->p_cmd_rsp_info   = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
392            p_t1t->addr             = add;
393            p_data->offset          = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
394            p                       = (UINT8 *) (p_data + 1) + p_data->offset;
395            UINT8_TO_BE_STREAM (p, opcode);
396            UINT8_TO_BE_STREAM (p, add);
397
398            if (p_dat)
399            {
400                ARRAY_TO_STREAM (p, p_dat, 8);
401            }
402            else
403            {
404                memset (p, 0, 8);
405                p += 8;
406            }
407            ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
408            p_data->len     = p_cmd_rsp_info->cmd_len;
409
410            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
411            rw_cb.cur_retry = 0;
412            memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
413
414#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
415            /* Update stats */
416            rw_main_update_tx_stats (p_data->len, FALSE);
417#endif  /* RW_STATS_INCLUDED */
418
419            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
420
421            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
422            {
423                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
424                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
425            }
426        }
427        else
428        {
429            status = NFC_STATUS_NO_BUFFERS;
430        }
431    }
432    return status;
433}
434
435/*****************************************************************************
436**
437** Function         rw_t1t_handle_rid_rsp
438**
439** Description      Handles response to RID: Collects HR, UID, notify up the
440**                  stack
441**
442** Returns          event to notify application
443**
444*****************************************************************************/
445static tRW_EVENT rw_t1t_handle_rid_rsp (BT_HDR *p_pkt)
446{
447    tRW_T1T_CB  *p_t1t   = &rw_cb.tcb.t1t;
448    tRW_DATA    evt_data;
449    UINT8       *p_rid_rsp;
450
451    evt_data.status      = NFC_STATUS_OK;
452    evt_data.data.p_data = p_pkt;
453
454    /* Assume the data is just the response byte sequence */
455    p_rid_rsp = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
456
457    /* Response indicates tag is present */
458    if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
459    {
460        /* If checking for the presence of the tag then just notify */
461        return RW_T1T_PRESENCE_CHECK_EVT;
462    }
463
464    /* Extract HR and UID from response */
465    STREAM_TO_ARRAY (p_t1t->hr,  p_rid_rsp, T1T_HR_LEN);
466
467#if (BT_TRACE_VERBOSE == TRUE)
468    RW_TRACE_DEBUG2 ("hr0:0x%x, hr1:0x%x", p_t1t->hr[0], p_t1t->hr[1]);
469    RW_TRACE_DEBUG4 ("rw_t1t_handle_rid_rsp (): UID0-3=%02x%02x%02x%02x", p_rid_rsp[0], p_rid_rsp[1], p_rid_rsp[2], p_rid_rsp[3]);
470#else
471    RW_TRACE_DEBUG0 ("rw_t1t_handle_rid_rsp ()");
472#endif
473
474    /* Fetch UID0-3 from RID response message */
475    STREAM_TO_ARRAY (p_t1t->mem,  p_rid_rsp, T1T_CMD_UID_LEN);
476
477    /* Notify RID response Event */
478    return RW_T1T_RID_EVT;
479}
480
481/*******************************************************************************
482**
483** Function         rw_t1t_select
484**
485** Description      This function will set the callback function to
486**                  receive data from lower layers and also send rid command
487**
488** Returns          none
489**
490*******************************************************************************/
491tNFC_STATUS rw_t1t_select (UINT8 hr[T1T_HR_LEN], UINT8 uid[T1T_CMD_UID_LEN])
492{
493    tNFC_STATUS status  = NFC_STATUS_FAILED;
494    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
495
496    p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
497
498    /* Alloc cmd buf for retransmissions */
499    if (p_t1t->p_cur_cmd_buf ==  NULL)
500    {
501        if ((p_t1t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
502        {
503            RW_TRACE_ERROR0 ("rw_t1t_select: unable to allocate buffer for retransmission");
504            return status;
505        }
506    }
507
508    memcpy (p_t1t->hr, hr, T1T_HR_LEN);
509    memcpy (p_t1t->mem, uid, T1T_CMD_UID_LEN);
510
511    NFC_SetStaticRfCback (rw_t1t_conn_cback);
512
513    p_t1t->state    = RW_T1T_STATE_IDLE;
514
515    return NFC_STATUS_OK;
516}
517
518/*******************************************************************************
519**
520** Function         rw_t1t_process_timeout
521**
522** Description      process timeout event
523**
524** Returns          none
525**
526*******************************************************************************/
527void rw_t1t_process_timeout (TIMER_LIST_ENT *p_tle)
528{
529    tRW_T1T_CB        *p_t1t  = &rw_cb.tcb.t1t;
530
531#if (BT_TRACE_VERBOSE == TRUE)
532    RW_TRACE_ERROR2 ("T1T timeout. state=%s command (opcode)=0x%02x ", rw_t1t_get_state_name (p_t1t->state), (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
533#else
534    RW_TRACE_ERROR2 ("T1T timeout. state=0x%02x command=0x%02x ", p_t1t->state, (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
535#endif
536
537    if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
538    {
539        /* Tag has moved from range */
540        rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
541    }
542    else if (p_t1t->state != RW_T1T_STATE_IDLE)
543    {
544        rw_t1t_process_error ();
545    }
546}
547
548
549/*******************************************************************************
550**
551** Function         rw_t1t_process_frame_error
552**
553** Description      Process frame crc error
554**
555** Returns          none
556**
557*******************************************************************************/
558static void rw_t1t_process_frame_error (void)
559{
560#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
561    /* Update stats */
562    rw_main_update_crc_error_stats ();
563#endif  /* RW_STATS_INCLUDED */
564
565    /* Process the error */
566    rw_t1t_process_error ();
567}
568
569/*******************************************************************************
570**
571** Function         rw_t1t_process_error
572**
573** Description      process timeout event
574**
575** Returns          none
576**
577*******************************************************************************/
578static void rw_t1t_process_error (void)
579{
580    tRW_READ_DATA           evt_data;
581    tRW_EVENT               rw_event;
582    BT_HDR                  *p_cmd_buf;
583    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
584    tT1T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
585    tRW_DETECT_NDEF_DATA    ndef_data;
586
587    RW_TRACE_DEBUG1 ("rw_t1t_process_error () State: %u", p_t1t->state);
588
589    /* Retry sending command if retry-count < max */
590    if (rw_cb.cur_retry < RW_MAX_RETRIES)
591    {
592        /* retry sending the command */
593        rw_cb.cur_retry++;
594
595        RW_TRACE_DEBUG2 ("T1T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
596
597        /* allocate a new buffer for message */
598        if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
599        {
600            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);
601
602#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
603            /* Update stats */
604            rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
605#endif  /* RW_STATS_INCLUDED */
606
607            if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
608            {
609                /* Start timer for waiting for response */
610                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
611                                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC)/1000);
612
613                return;
614            }
615        }
616    }
617    else
618    {
619    /* we might get response later to all or some of the retrasnmission
620     * of the current command, update previous command response information */
621        RW_TRACE_DEBUG1 ("T1T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
622        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;
623        p_t1t->prev_cmd_rsp_info.rsp_len       = p_cmd_rsp_info->rsp_len;
624        p_t1t->prev_cmd_rsp_info.op_code       = p_cmd_rsp_info->opcode;
625        p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
626    }
627
628#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
629    /* update failure count */
630    rw_main_update_fail_stats ();
631#endif  /* RW_STATS_INCLUDED */
632
633    rw_event        = rw_t1t_info_to_event (p_cmd_rsp_info);
634    if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED)
635        rw_t1t_handle_op_complete ();
636
637    evt_data.status = NFC_STATUS_TIMEOUT;
638    if (rw_event == RW_T2T_NDEF_DETECT_EVT)
639    {
640        ndef_data.status    = evt_data.status;
641        ndef_data.protocol  = NFC_PROTOCOL_T1T;
642        ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
643        ndef_data.max_size  = 0;
644        ndef_data.cur_size  = 0;
645        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
646    }
647    else
648    {
649        evt_data.p_data = NULL;
650        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
651    }
652}
653
654/*****************************************************************************
655**
656** Function         rw_t1t_handle_presence_check_rsp
657**
658** Description      Handle response to presence check
659**
660** Returns          Nothing
661**
662*****************************************************************************/
663void rw_t1t_handle_presence_check_rsp (tNFC_STATUS status)
664{
665    tRW_READ_DATA   evt_data;
666
667    /* Notify, Tag is present or not */
668    evt_data.status = status;
669    rw_t1t_handle_op_complete ();
670
671    (*(rw_cb.p_cback)) (RW_T1T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
672}
673
674/*****************************************************************************
675**
676** Function         rw_t1t_handle_op_complete
677**
678** Description      Reset to IDLE state
679**
680** Returns          Nothing
681**
682*****************************************************************************/
683void rw_t1t_handle_op_complete (void)
684{
685    tRW_T1T_CB      *p_t1t  = &rw_cb.tcb.t1t;
686
687    p_t1t->state    = RW_T1T_STATE_IDLE;
688#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
689    if (p_t1t->state != RW_T1T_STATE_READ_NDEF)
690    {
691        p_t1t->b_update = FALSE;
692        p_t1t->b_rseg   = FALSE;
693    }
694    p_t1t->substate = RW_T1T_SUBSTATE_NONE;
695#endif
696    return;
697}
698
699/*****************************************************************************
700**
701** Function         RW_T1tPresenceCheck
702**
703** Description
704**      Check if the tag is still in the field.
705**
706**      The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
707**      or non-presence.
708**
709** Returns
710**      NFC_STATUS_OK, if raw data frame sent
711**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
712**      NFC_STATUS_FAILED: other error
713**
714*****************************************************************************/
715tNFC_STATUS RW_T1tPresenceCheck (void)
716{
717    tNFC_STATUS retval = NFC_STATUS_OK;
718    tRW_DATA evt_data;
719    tRW_CB *p_rw_cb = &rw_cb;
720
721    RW_TRACE_API0 ("RW_T1tPresenceCheck");
722
723    /* If RW_SelectTagType was not called (no conn_callback) return failure */
724    if (!p_rw_cb->p_cback)
725    {
726        retval = NFC_STATUS_FAILED;
727    }
728    /* If we are not activated, then RW_T1T_PRESENCE_CHECK_EVT status=FAIL */
729    else if (p_rw_cb->tcb.t1t.state == RW_T1T_STATE_NOT_ACTIVATED)
730    {
731        evt_data.status = NFC_STATUS_FAILED;
732        (*p_rw_cb->p_cback) (RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
733    }
734    /* If command is pending, assume tag is still present */
735    else if (p_rw_cb->tcb.t1t.state != RW_T1T_STATE_IDLE)
736    {
737        evt_data.status = NFC_STATUS_OK;
738        (*p_rw_cb->p_cback) (RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
739    }
740    else
741    {
742        /* IDLE state: send a RID command to the tag to see if it responds */
743        if((retval = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
744        {
745            p_rw_cb->tcb.t1t.state = RW_T1T_STATE_CHECK_PRESENCE;
746        }
747    }
748
749    return (retval);
750}
751
752/*****************************************************************************
753**
754** Function         RW_T1tRid
755**
756** Description
757**      This function sends a RID command for Reader/Writer mode.
758**
759** Returns
760**      NFC_STATUS_OK, if raw data frame sent
761**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
762**      NFC_STATUS_FAILED: other error
763**
764*****************************************************************************/
765tNFC_STATUS RW_T1tRid (void)
766{
767    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
768    tNFC_STATUS status  = NFC_STATUS_FAILED;
769
770    RW_TRACE_API0 ("RW_T1tRid");
771
772    if (p_t1t->state != RW_T1T_STATE_IDLE)
773    {
774        RW_TRACE_WARNING1 ("RW_T1tRid - Busy - State: %u", p_t1t->state);
775        return (NFC_STATUS_BUSY);
776    }
777
778    /* send a RID command */
779    if((status = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
780    {
781        p_t1t->state = RW_T1T_STATE_READ;
782    }
783
784    return (status);
785}
786
787/*******************************************************************************
788**
789** Function         RW_T1tReadAll
790**
791** Description      This function sends a RALL command for Reader/Writer mode.
792**
793** Returns          tNFC_STATUS
794**
795*******************************************************************************/
796tNFC_STATUS RW_T1tReadAll (void)
797{
798    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
799    tNFC_STATUS status  = NFC_STATUS_FAILED;
800
801    RW_TRACE_API0 ("RW_T1tReadAll");
802
803    if (p_t1t->state != RW_T1T_STATE_IDLE)
804    {
805        RW_TRACE_WARNING1 ("RW_T1tReadAll - Busy - State: %u", p_t1t->state);
806        return (NFC_STATUS_BUSY);
807    }
808
809    /* send RALL command */
810    if ((status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0)) == NFC_STATUS_OK)
811    {
812        p_t1t->state = RW_T1T_STATE_READ;
813    }
814
815    return status;
816}
817
818/*******************************************************************************
819**
820** Function         RW_T1tRead
821**
822** Description      This function sends a READ command for Reader/Writer mode.
823**
824** Returns          tNFC_STATUS
825**
826*******************************************************************************/
827tNFC_STATUS RW_T1tRead (UINT8 block, UINT8 byte)
828{
829    tNFC_STATUS status  = NFC_STATUS_FAILED;
830    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
831    UINT8       addr;
832
833    if (p_t1t->state != RW_T1T_STATE_IDLE)
834    {
835        RW_TRACE_WARNING1 ("RW_T1tRead - Busy - State: %u", p_t1t->state);
836        return (NFC_STATUS_BUSY);
837    }
838
839    /* send READ command */
840    RW_T1T_BLD_ADD ((addr), (block), (byte));
841    if ((status = rw_t1t_send_static_cmd (T1T_CMD_READ, addr, 0)) == NFC_STATUS_OK)
842    {
843        p_t1t->state = RW_T1T_STATE_READ;
844    }
845    return status;
846}
847
848/*******************************************************************************
849**
850** Function         RW_T1tWriteErase
851**
852** Description      This function sends a WRITE-E command for Reader/Writer mode.
853**
854** Returns          tNFC_STATUS
855**
856*******************************************************************************/
857tNFC_STATUS RW_T1tWriteErase (UINT8 block, UINT8 byte, UINT8 new_byte)
858{
859    tNFC_STATUS status  = NFC_STATUS_FAILED;
860    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
861    UINT8       addr;
862
863    if (p_t1t->state != RW_T1T_STATE_IDLE)
864    {
865        RW_TRACE_WARNING1 ("RW_T1tWriteErase - Busy - State: %u", p_t1t->state);
866        return (NFC_STATUS_BUSY);
867    }
868    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
869        &&(block != T1T_CC_BLOCK)
870        &&(byte  != T1T_CC_RWA_OFFSET)  )
871    {
872        RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
873        return (NFC_STATUS_REFUSED);
874    }
875    if (  (block >= T1T_STATIC_BLOCKS)
876        ||(byte  >= T1T_BLOCK_SIZE   )  )
877    {
878        RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
879        return (NFC_STATUS_REFUSED);
880    }
881    if(  (block == T1T_UID_BLOCK)
882       ||(block == T1T_RES_BLOCK)  )
883    {
884        RW_TRACE_WARNING1 ("RW_T1tWriteErase - Cannot write to Locked block: %u", block);
885        return (NFC_STATUS_REFUSED);
886    }
887    /* send WRITE-E command */
888    RW_T1T_BLD_ADD ((addr), (block), (byte));
889    if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, new_byte)) == NFC_STATUS_OK)
890    {
891        p_t1t->state = RW_T1T_STATE_WRITE;
892        if (block < T1T_BLOCKS_PER_SEGMENT)
893        {
894            p_t1t->b_update = FALSE;
895            p_t1t->b_rseg   = FALSE;
896        }
897    }
898    return status;
899}
900
901/*******************************************************************************
902**
903** Function         RW_T1tWriteNoErase
904**
905** Description      This function sends a WRITE-NE command for Reader/Writer mode.
906**
907** Returns          tNFC_STATUS
908**
909*******************************************************************************/
910tNFC_STATUS RW_T1tWriteNoErase (UINT8 block, UINT8 byte, UINT8 new_byte)
911{
912    tNFC_STATUS status  = NFC_STATUS_FAILED;
913    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
914    UINT8       addr;
915
916    if (p_t1t->state != RW_T1T_STATE_IDLE)
917    {
918        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Busy - State: %u", p_t1t->state);
919        return (NFC_STATUS_BUSY);
920    }
921    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
922        &&(block != T1T_CC_BLOCK)
923        &&(byte  != T1T_CC_RWA_OFFSET)  )
924    {
925        RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
926        return (NFC_STATUS_REFUSED);
927    }
928    if (  (block >= T1T_STATIC_BLOCKS)
929        ||(byte  >= T1T_BLOCK_SIZE   )  )
930    {
931        RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
932        return (NFC_STATUS_REFUSED);
933    }
934    if(  (block == T1T_UID_BLOCK)
935       ||(block == T1T_RES_BLOCK)  )
936    {
937        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Cannot write to Locked block: %u", block);
938        return (NFC_STATUS_REFUSED);
939    }
940    /* send WRITE-NE command */
941    RW_T1T_BLD_ADD ((addr), (block), (byte));
942    if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, new_byte)) == NFC_STATUS_OK)
943    {
944        p_t1t->state = RW_T1T_STATE_WRITE;
945        if (block < T1T_BLOCKS_PER_SEGMENT)
946        {
947            p_t1t->b_update = FALSE;
948            p_t1t->b_rseg   = FALSE;
949        }
950    }
951    return status;
952}
953
954/*******************************************************************************
955**
956** Function         RW_T1tReadSeg
957**
958** Description      This function sends a RSEG command for Reader/Writer mode.
959**
960** Returns          tNFC_STATUS
961**
962*******************************************************************************/
963tNFC_STATUS RW_T1tReadSeg (UINT8 segment)
964{
965    tNFC_STATUS status  = NFC_STATUS_FAILED;
966    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
967    UINT8       adds;
968
969    if (p_t1t->state != RW_T1T_STATE_IDLE)
970    {
971        RW_TRACE_WARNING1 ("RW_T1tReadSeg - Busy - State: %u", p_t1t->state);
972        return (NFC_STATUS_BUSY);
973    }
974    if (segment >=  T1T_MAX_SEGMENTS)
975    {
976        RW_TRACE_ERROR1 ("RW_T1tReadSeg - Invalid Segment: %u", segment);
977        return (NFC_STATUS_REFUSED);
978    }
979    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0)
980    {
981        /* send RSEG command */
982        RW_T1T_BLD_ADDS ((adds), (segment));
983        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
984        {
985            p_t1t->state = RW_T1T_STATE_READ;
986        }
987    }
988    return status;
989}
990
991/*******************************************************************************
992**
993** Function         RW_T1tRead8
994**
995** Description      This function sends a READ8 command for Reader/Writer mode.
996**
997** Returns          tNFC_STATUS
998**
999*******************************************************************************/
1000tNFC_STATUS RW_T1tRead8 (UINT8 block)
1001{
1002    tNFC_STATUS status = NFC_STATUS_FAILED;
1003    tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
1004
1005    if (p_t1t->state != RW_T1T_STATE_IDLE)
1006    {
1007        RW_TRACE_WARNING1 ("RW_T1tRead8 - Busy - State: %u", p_t1t->state);
1008        return (NFC_STATUS_BUSY);
1009    }
1010
1011    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
1012    {
1013        /* send READ8 command */
1014        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, block, NULL)) == NFC_STATUS_OK)
1015        {
1016            p_t1t->state = RW_T1T_STATE_READ;
1017        }
1018    }
1019    return status;
1020}
1021
1022/*******************************************************************************
1023**
1024** Function         RW_T1tWriteErase8
1025**
1026** Description      This function sends a WRITE-E8 command for Reader/Writer mode.
1027**
1028** Returns          tNFC_STATUS
1029**
1030*******************************************************************************/
1031tNFC_STATUS RW_T1tWriteErase8 (UINT8 block, UINT8 *p_new_dat)
1032{
1033    tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
1034    tNFC_STATUS status = NFC_STATUS_FAILED;
1035
1036    if (p_t1t->state != RW_T1T_STATE_IDLE)
1037    {
1038        RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Busy - State: %u", p_t1t->state);
1039        return (NFC_STATUS_BUSY);
1040    }
1041
1042    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
1043        &&(block != T1T_CC_BLOCK)  )
1044    {
1045        RW_TRACE_ERROR0 ("RW_T1tWriteErase8 - Tag is in Read only state");
1046        return (NFC_STATUS_REFUSED);
1047    }
1048
1049    if(  (block == T1T_UID_BLOCK)
1050       ||(block == T1T_RES_BLOCK)  )
1051    {
1052        RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Cannot write to Locked block: %u", block);
1053        return (NFC_STATUS_REFUSED);
1054    }
1055
1056    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
1057    {
1058        /* send WRITE-E8 command */
1059        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_new_dat)) == NFC_STATUS_OK)
1060        {
1061            p_t1t->state = RW_T1T_STATE_WRITE;
1062            if (block < T1T_BLOCKS_PER_SEGMENT)
1063            {
1064                p_t1t->b_update = FALSE;
1065                p_t1t->b_rseg   = FALSE;
1066            }
1067        }
1068    }
1069    return status;
1070}
1071
1072/*******************************************************************************
1073**
1074** Function         RW_T1tWriteNoErase8
1075**
1076** Description      This function sends a WRITE-NE8 command for Reader/Writer mode.
1077**
1078** Returns          tNFC_STATUS
1079**
1080*******************************************************************************/
1081tNFC_STATUS RW_T1tWriteNoErase8 (UINT8 block, UINT8 *p_new_dat)
1082{
1083    tNFC_STATUS status = NFC_STATUS_FAILED;
1084    tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
1085
1086    if (p_t1t->state != RW_T1T_STATE_IDLE)
1087    {
1088        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Busy - State: %u", p_t1t->state);
1089        return (NFC_STATUS_BUSY);
1090    }
1091
1092    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
1093        &&(block != T1T_CC_BLOCK)  )
1094    {
1095        RW_TRACE_ERROR0 ("RW_T1tWriteNoErase8 - Tag is in Read only state");
1096        return (NFC_STATUS_REFUSED);
1097    }
1098
1099    if(  (block == T1T_UID_BLOCK)
1100       ||(block == T1T_RES_BLOCK)  )
1101    {
1102        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Cannot write to Locked block: %u", block);
1103        return (NFC_STATUS_REFUSED);
1104    }
1105
1106    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
1107    {
1108        /* send WRITE-NE command */
1109        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, block, p_new_dat)) == NFC_STATUS_OK)
1110        {
1111            p_t1t->state    = RW_T1T_STATE_WRITE;
1112            if (block < T1T_BLOCKS_PER_SEGMENT)
1113            {
1114                p_t1t->b_update = FALSE;
1115                p_t1t->b_rseg   = FALSE;
1116            }
1117        }
1118    }
1119    return status;
1120}
1121
1122#if (BT_TRACE_VERBOSE == TRUE)
1123/*******************************************************************************
1124**
1125** Function         rw_t1t_get_state_name
1126**
1127** Description      This function returns the state name.
1128**
1129** NOTE             conditionally compiled to save memory.
1130**
1131** Returns          pointer to the name
1132**
1133*******************************************************************************/
1134static char *rw_t1t_get_state_name (UINT8 state)
1135{
1136    switch (state)
1137    {
1138    case RW_T1T_STATE_IDLE:
1139        return ("IDLE");
1140    case RW_T1T_STATE_NOT_ACTIVATED:
1141        return ("NOT_ACTIVATED");
1142    case RW_T1T_STATE_READ:
1143        return ("APP_READ");
1144    case RW_T1T_STATE_WRITE:
1145        return ("APP_WRITE");
1146    case RW_T1T_STATE_TLV_DETECT:
1147        return ("TLV_DETECTION");
1148    case RW_T1T_STATE_READ_NDEF:
1149        return ("READING_NDEF");
1150    case RW_T1T_STATE_WRITE_NDEF:
1151        return ("WRITING_NDEF");
1152    case RW_T1T_STATE_SET_TAG_RO:
1153        return ("SET_TAG_RO");
1154    case RW_T1T_STATE_CHECK_PRESENCE:
1155        return ("CHECK_PRESENCE");
1156    case RW_T1T_STATE_FORMAT_TAG:
1157        return ("FORMAT_TAG");
1158    default:
1159        return ("???? UNKNOWN STATE");
1160    }
1161}
1162
1163#endif /* (BT_TRACE_VERBOSE == TRUE) */
1164
1165#endif /* (NFC_INCLUDED == TRUE) */
1166