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