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