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