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