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