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