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