• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the implementation for Type 1 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 "gki.h"
31 #include "nci_hmsgs.h"
32 #include "nfc_api.h"
33 #include "nfc_int.h"
34 #include "nfc_target.h"
35 #include "rw_api.h"
36 #include "rw_int.h"
37 
38 using android::base::StringPrintf;
39 
40 extern unsigned char appl_dta_mode_flag;
41 
42 /* Local Functions */
43 static tRW_EVENT rw_t1t_handle_rid_rsp(NFC_HDR* p_pkt);
44 static void rw_t1t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
45                               tNFC_CONN* p_data);
46 static void rw_t1t_process_frame_error(void);
47 static void rw_t1t_process_error(void);
48 static void rw_t1t_handle_presence_check_rsp(tNFC_STATUS status);
49 static std::string rw_t1t_get_state_name(uint8_t state);
50 
51 /*******************************************************************************
52 **
53 ** Function         rw_t1t_data_cback
54 **
55 ** Description      This callback function handles data from NFCC.
56 **
57 ** Returns          none
58 **
59 *******************************************************************************/
rw_t1t_data_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)60 static void rw_t1t_data_cback(__attribute__((unused)) uint8_t conn_id,
61                               __attribute__((unused)) tNFC_CONN_EVT event,
62                               tNFC_CONN* p_data) {
63   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
64   tRW_EVENT rw_event = RW_RAW_FRAME_EVT;
65   bool b_notify = true;
66   tRW_DATA evt_data;
67   NFC_HDR* p_pkt;
68   uint8_t* p;
69   tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
70       (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
71   uint8_t begin_state = p_t1t->state;
72 
73   p_pkt = (NFC_HDR*)(p_data->data.p_data);
74   if (p_pkt == nullptr) return;
75   /* Assume the data is just the response byte sequence */
76   p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
77 
78   LOG(VERBOSE) << StringPrintf("%s: state=%s (%d)", __func__,
79                                rw_t1t_get_state_name(p_t1t->state).c_str(),
80                                p_t1t->state);
81 
82   evt_data.status = NFC_STATUS_OK;
83 
84   if ((p_t1t->state == RW_T1T_STATE_IDLE) || (!p_cmd_rsp_info)) {
85     /* If previous command was retransmitted and if response is pending to
86      * previous command retransmission,
87      * check if lenght and ADD/ADD8/ADDS field matches the expected value of
88      * previous
89      * retransmited command response. However, ignore ADD field if the command
90      * was RALL/RID
91      */
92     if ((p_t1t->prev_cmd_rsp_info.pend_retx_rsp) &&
93         (p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len) &&
94         ((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) ||
95          (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) ||
96          (p_t1t->prev_cmd_rsp_info.addr == *p))) {
97       /* Response to previous command retransmission */
98       LOG(ERROR) << StringPrintf(
99           "%s: T1T Response to previous command in Idle state. command=0x%02x, "
100           "Remaining max retx rsp=0x%02x ",
101           __func__, p_t1t->prev_cmd_rsp_info.op_code,
102           p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
103       p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
104       GKI_freebuf(p_pkt);
105     } else {
106       /* Raw frame event */
107       evt_data.data.p_data = p_pkt;
108       (*rw_cb.p_cback)(RW_T1T_RAW_FRAME_EVT, &evt_data);
109     }
110     return;
111   }
112 
113 #if (RW_STATS_INCLUDED == TRUE)
114   /* Update rx stats */
115   rw_main_update_rx_stats(p_pkt->len);
116 #endif /* RW_STATS_INCLUDED */
117 
118   if ((p_pkt->len != p_cmd_rsp_info->rsp_len) ||
119       ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
120        (p_cmd_rsp_info->opcode != T1T_CMD_RID) && (*p != p_t1t->addr)))
121 
122   {
123     /* If previous command was retransmitted and if response is pending to
124      * previous command retransmission,
125      * then check if lenght and ADD/ADD8/ADDS field matches the expected value
126      * of previous
127      * retransmited command response. However, ignore ADD field if the command
128      * was RALL/RID
129      */
130     if ((p_t1t->prev_cmd_rsp_info.pend_retx_rsp) &&
131         (p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len) &&
132         ((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) ||
133          (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) ||
134          (p_t1t->prev_cmd_rsp_info.addr == *p))) {
135       LOG(ERROR) << StringPrintf(
136           "%s: T1T Response to previous command. command=0x%02x, Remaining max "
137           "retx rsp=0x%02x",
138           __func__, p_t1t->prev_cmd_rsp_info.op_code,
139           p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
140       p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
141     } else {
142       /* Stop timer as some response to current command is received */
143       nfc_stop_quick_timer(&p_t1t->timer);
144       /* Retrasmit the last sent command if retry-count < max retry */
145       LOG(ERROR) << StringPrintf(
146           "%s: T1T Frame error. state=%s command (opcode) = 0x%02x", __func__,
147           rw_t1t_get_state_name(p_t1t->state).c_str(), p_cmd_rsp_info->opcode);
148       rw_t1t_process_frame_error();
149     }
150     GKI_freebuf(p_pkt);
151     return;
152   }
153 
154   /* Stop timer as response to current command is received */
155   nfc_stop_quick_timer(&p_t1t->timer);
156 
157   LOG(VERBOSE) << StringPrintf("%s: RW RECV [%s]=0x%x RSP", __func__,
158                                t1t_info_to_str(p_cmd_rsp_info),
159                                p_cmd_rsp_info->opcode);
160 
161   /* If we did not receive response to all retransmitted previous command,
162    * dont expect that as response have come for the current command itself.
163    */
164   if (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
165     memset(&(p_t1t->prev_cmd_rsp_info), 0, sizeof(tRW_T1T_PREV_CMD_RSP_INFO));
166 
167   if (rw_cb.cur_retry) {
168     /* If the current command was retransmitted to get this response, we might
169        get
170        response later to all or some of the retrasnmission of the current
171        command
172      */
173     p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
174                                      (p_cmd_rsp_info->opcode != T1T_CMD_RID))
175                                         ? p_t1t->addr
176                                         : 0;
177     p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
178     p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
179     p_t1t->prev_cmd_rsp_info.pend_retx_rsp = (uint8_t)rw_cb.cur_retry;
180   }
181 
182   rw_cb.cur_retry = 0;
183 
184   if (p_cmd_rsp_info->opcode == T1T_CMD_RID) {
185     rw_event = rw_t1t_handle_rid_rsp(p_pkt);
186   } else {
187     rw_event =
188         rw_t1t_handle_rsp(p_cmd_rsp_info, &b_notify, p, &evt_data.status);
189   }
190 
191   if (b_notify) {
192     if ((p_t1t->state != RW_T1T_STATE_READ) &&
193         (p_t1t->state != RW_T1T_STATE_WRITE)) {
194       GKI_freebuf(p_pkt);
195       evt_data.data.p_data = nullptr;
196     } else {
197       evt_data.data.p_data = p_pkt;
198     }
199     rw_t1t_handle_op_complete();
200     (*rw_cb.p_cback)(rw_event, &evt_data);
201   } else
202     GKI_freebuf(p_pkt);
203 
204   if (begin_state != p_t1t->state) {
205     LOG(VERBOSE) << StringPrintf("%s: RW T1T state changed:<%s> -> <%s>",
206                                  __func__,
207                                  rw_t1t_get_state_name(begin_state).c_str(),
208                                  rw_t1t_get_state_name(p_t1t->state).c_str());
209   }
210 }
211 
212 /*******************************************************************************
213 **
214 ** Function         rw_t1t_conn_cback
215 **
216 ** Description      This callback function receives the events/data from NFCC.
217 **
218 ** Returns          none
219 **
220 *******************************************************************************/
rw_t1t_conn_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)221 void rw_t1t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
222                        tNFC_CONN* p_data) {
223   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
224 
225   LOG(VERBOSE) << StringPrintf("%s: conn_id=%i, evt=0x%x", __func__, conn_id,
226                                event);
227   /* Only handle static conn_id */
228   if (conn_id != NFC_RF_CONN_ID) {
229     LOG(WARNING) << StringPrintf("%s: Not static connection id: =%i", __func__,
230                                  conn_id);
231     return;
232   }
233 
234   switch (event) {
235     case NFC_CONN_CREATE_CEVT:
236     case NFC_CONN_CLOSE_CEVT:
237       break;
238 
239     case NFC_DEACTIVATE_CEVT:
240 #if (RW_STATS_INCLUDED == TRUE)
241       /* Display stats */
242       rw_main_log_stats();
243 #endif /* RW_STATS_INCLUDED */
244 
245       /* Stop t1t timer (if started) */
246       nfc_stop_quick_timer(&p_t1t->timer);
247 
248       /* Free cmd buf for retransmissions */
249       if (p_t1t->p_cur_cmd_buf) {
250         GKI_freebuf(p_t1t->p_cur_cmd_buf);
251         p_t1t->p_cur_cmd_buf = nullptr;
252       }
253 
254       p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
255       NFC_SetStaticRfCback(nullptr);
256       break;
257 
258     case NFC_DATA_CEVT:
259       if (p_data != nullptr) {
260         if (p_data->data.status == NFC_STATUS_OK) {
261           rw_t1t_data_cback(conn_id, event, p_data);
262           break;
263         } else if (p_data->data.p_data != nullptr) {
264           /* Free the response buffer in case of error response */
265           GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
266           p_data->data.p_data = nullptr;
267         }
268       }
269       /* Data event with error status...fall through to NFC_ERROR_CEVT case */
270       FALLTHROUGH_INTENDED;
271 
272     case NFC_ERROR_CEVT:
273       if ((p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED) ||
274           (p_t1t->state == RW_T1T_STATE_IDLE)) {
275 #if (RW_STATS_INCLUDED == TRUE)
276         rw_main_update_trans_error_stats();
277 #endif /* RW_STATS_INCLUDED */
278 
279         tRW_READ_DATA evt_data;
280         if (event == NFC_ERROR_CEVT)
281           evt_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
282         else if (p_data)
283           evt_data.status = p_data->status;
284         else
285           evt_data.status = NFC_STATUS_FAILED;
286 
287         evt_data.p_data = nullptr;
288         tRW_DATA rw_data;
289         rw_data.data = evt_data;
290         (*rw_cb.p_cback)(RW_T1T_INTF_ERROR_EVT, &rw_data);
291         break;
292       }
293       nfc_stop_quick_timer(&p_t1t->timer);
294 
295 #if (RW_STATS_INCLUDED == TRUE)
296       rw_main_update_trans_error_stats();
297 #endif /* RW_STATS_INCLUDED */
298 
299       if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
300         rw_t1t_handle_presence_check_rsp(NFC_STATUS_RF_FRAME_CORRUPTED);
301       } else {
302         rw_t1t_process_error();
303       }
304       break;
305 
306     default:
307       break;
308   }
309 }
310 
311 /*******************************************************************************
312 **
313 ** Function         rw_t1t_send_static_cmd
314 **
315 ** Description      This function composes a Type 1 Tag command for static
316 **                  memory and send through NCI to NFCC.
317 **
318 ** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
319 **                  otherwise, error status
320 **
321 *******************************************************************************/
rw_t1t_send_static_cmd(uint8_t opcode,uint8_t add,uint8_t dat)322 tNFC_STATUS rw_t1t_send_static_cmd(uint8_t opcode, uint8_t add, uint8_t dat) {
323   tNFC_STATUS status = NFC_STATUS_FAILED;
324   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
325   const tT1T_CMD_RSP_INFO* p_cmd_rsp_info = t1t_cmd_to_rsp_info(opcode);
326   NFC_HDR* p_data;
327   uint8_t* p;
328 
329   if (p_cmd_rsp_info) {
330     /* a valid opcode for RW */
331     p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
332     if (p_data) {
333       p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info;
334       p_t1t->addr = add;
335       p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
336       p = (uint8_t*)(p_data + 1) + p_data->offset;
337       UINT8_TO_BE_STREAM(p, opcode);
338       UINT8_TO_BE_STREAM(p, add);
339       UINT8_TO_BE_STREAM(p, dat);
340 
341       ARRAY_TO_STREAM(p, p_t1t->mem, T1T_CMD_UID_LEN);
342       p_data->len = p_cmd_rsp_info->cmd_len;
343 
344       /* Indicate first attempt to send command, back up cmd buffer in case
345        * needed for retransmission */
346       rw_cb.cur_retry = 0;
347       memcpy(p_t1t->p_cur_cmd_buf, p_data,
348              sizeof(NFC_HDR) + p_data->offset + p_data->len);
349 
350 #if (RW_STATS_INCLUDED == TRUE)
351       /* Update stats */
352       rw_main_update_tx_stats(p_data->len, false);
353 #endif /* RW_STATS_INCLUDED */
354 
355       LOG(VERBOSE) << StringPrintf("%s: RW SENT [%s]=0x%x CMD", __func__,
356                                    t1t_info_to_str(p_cmd_rsp_info),
357                                    p_cmd_rsp_info->opcode);
358       status = NFC_SendData(NFC_RF_CONN_ID, p_data);
359       if (status == NFC_STATUS_OK) {
360         nfc_start_quick_timer(
361             &p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
362             (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
363       }
364     } else {
365       status = NFC_STATUS_NO_BUFFERS;
366     }
367   }
368   return status;
369 }
370 
371 /*******************************************************************************
372 **
373 ** Function         rw_t1t_send_dyn_cmd
374 **
375 ** Description      This function composes a Type 1 Tag command for dynamic
376 **                  memory and send through NCI to NFCC.
377 **
378 ** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
379 **                  otherwise, error status
380 **
381 *******************************************************************************/
rw_t1t_send_dyn_cmd(uint8_t opcode,uint8_t add,uint8_t * p_dat)382 tNFC_STATUS rw_t1t_send_dyn_cmd(uint8_t opcode, uint8_t add, uint8_t* p_dat) {
383   tNFC_STATUS status = NFC_STATUS_FAILED;
384   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
385   const tT1T_CMD_RSP_INFO* p_cmd_rsp_info = t1t_cmd_to_rsp_info(opcode);
386   NFC_HDR* p_data;
387   uint8_t* p;
388 
389   if (p_cmd_rsp_info) {
390     /* a valid opcode for RW */
391     p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
392     if (p_data) {
393       p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info;
394       p_t1t->addr = add;
395       p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
396       p = (uint8_t*)(p_data + 1) + p_data->offset;
397       UINT8_TO_BE_STREAM(p, opcode);
398       UINT8_TO_BE_STREAM(p, add);
399 
400       if (p_dat) {
401         ARRAY_TO_STREAM(p, p_dat, 8);
402       } else {
403         memset(p, 0, 8);
404         p += 8;
405       }
406       ARRAY_TO_STREAM(p, p_t1t->mem, T1T_CMD_UID_LEN);
407       p_data->len = p_cmd_rsp_info->cmd_len;
408 
409       /* Indicate first attempt to send command, back up cmd buffer in case
410        * needed for retransmission */
411       rw_cb.cur_retry = 0;
412       memcpy(p_t1t->p_cur_cmd_buf, p_data,
413              sizeof(NFC_HDR) + p_data->offset + p_data->len);
414 
415 #if (RW_STATS_INCLUDED == TRUE)
416       /* Update stats */
417       rw_main_update_tx_stats(p_data->len, false);
418 #endif /* RW_STATS_INCLUDED */
419 
420       LOG(VERBOSE) << StringPrintf("%s: RW SENT [%s]=0x%x CMD", __func__,
421                                    t1t_info_to_str(p_cmd_rsp_info),
422                                    p_cmd_rsp_info->opcode);
423 
424       status = NFC_SendData(NFC_RF_CONN_ID, p_data);
425       if (status == NFC_STATUS_OK) {
426         nfc_start_quick_timer(
427             &p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
428             (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
429       }
430     } else {
431       status = NFC_STATUS_NO_BUFFERS;
432     }
433   }
434   return status;
435 }
436 
437 /*****************************************************************************
438 **
439 ** Function         rw_t1t_handle_rid_rsp
440 **
441 ** Description      Handles response to RID: Collects HR, UID, notify up the
442 **                  stack
443 **
444 ** Returns          event to notify application
445 **
446 *****************************************************************************/
rw_t1t_handle_rid_rsp(NFC_HDR * p_pkt)447 static tRW_EVENT rw_t1t_handle_rid_rsp(NFC_HDR* p_pkt) {
448   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
449   tRW_DATA evt_data;
450   uint8_t* p_rid_rsp;
451 
452   evt_data.status = NFC_STATUS_OK;
453   evt_data.data.p_data = p_pkt;
454 
455   /* Assume the data is just the response byte sequence */
456   p_rid_rsp = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
457 
458   /* Response indicates tag is present */
459   if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
460     /* If checking for the presence of the tag then just notify */
461     return RW_T1T_PRESENCE_CHECK_EVT;
462   }
463 
464   /* Extract HR and UID from response */
465   STREAM_TO_ARRAY(p_t1t->hr, p_rid_rsp, T1T_HR_LEN);
466 
467   LOG(VERBOSE) << StringPrintf("%s: hr0=0x%x, hr1=0x%x", __func__, p_t1t->hr[0],
468                                p_t1t->hr[1]);
469   LOG(VERBOSE) << StringPrintf("%s: UID0-3=%02x%02x%02x%02x", __func__,
470                                p_rid_rsp[0], p_rid_rsp[1], p_rid_rsp[2],
471                                p_rid_rsp[3]);
472 
473   /* Fetch UID0-3 from RID response message */
474   STREAM_TO_ARRAY(p_t1t->mem, p_rid_rsp, T1T_CMD_UID_LEN);
475 
476   /* Notify RID response Event */
477   return RW_T1T_RID_EVT;
478 }
479 
480 /*******************************************************************************
481 **
482 ** Function         rw_t1t_select
483 **
484 ** Description      This function will set the callback function to
485 **                  receive data from lower layers and also send rid command
486 **
487 ** Returns          none
488 **
489 *******************************************************************************/
rw_t1t_select(uint8_t hr[T1T_HR_LEN],uint8_t uid[T1T_CMD_UID_LEN])490 tNFC_STATUS rw_t1t_select(uint8_t hr[T1T_HR_LEN],
491                           uint8_t uid[T1T_CMD_UID_LEN]) {
492   tNFC_STATUS status = NFC_STATUS_FAILED;
493   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
494 
495   p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
496 
497   /* Alloc cmd buf for retransmissions */
498   if (p_t1t->p_cur_cmd_buf == nullptr) {
499     p_t1t->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
500     if (p_t1t->p_cur_cmd_buf == nullptr) {
501       LOG(ERROR) << StringPrintf(
502           "%s: unable to allocate buffer for retransmission", __func__);
503       return status;
504     }
505   }
506 
507   memcpy(p_t1t->hr, hr, T1T_HR_LEN);
508   memcpy(p_t1t->mem, uid, T1T_CMD_UID_LEN);
509 
510   NFC_SetStaticRfCback(rw_t1t_conn_cback);
511 
512   p_t1t->state = RW_T1T_STATE_IDLE;
513 
514   return NFC_STATUS_OK;
515 }
516 
517 /*******************************************************************************
518 **
519 ** Function         rw_t1t_process_timeout
520 **
521 ** Description      process timeout event
522 **
523 ** Returns          none
524 **
525 *******************************************************************************/
rw_t1t_process_timeout(TIMER_LIST_ENT * p_tle)526 void rw_t1t_process_timeout(__attribute__((unused)) TIMER_LIST_ENT* p_tle) {
527   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
528 
529   LOG(ERROR) << StringPrintf("%s: state=%s command (opcode)=0x%02x ", __func__,
530                              rw_t1t_get_state_name(p_t1t->state).c_str(),
531                              (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
532 
533   if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
534     /* Tag has moved from range */
535     rw_t1t_handle_presence_check_rsp(NFC_STATUS_RF_FRAME_CORRUPTED);
536   } else if (p_t1t->state != RW_T1T_STATE_IDLE) {
537     rw_t1t_process_error();
538   }
539 }
540 
541 /*******************************************************************************
542 **
543 ** Function         rw_t1t_process_frame_error
544 **
545 ** Description      Process frame crc error
546 **
547 ** Returns          none
548 **
549 *******************************************************************************/
rw_t1t_process_frame_error(void)550 static void rw_t1t_process_frame_error(void) {
551 #if (RW_STATS_INCLUDED == TRUE)
552   /* Update stats */
553   rw_main_update_crc_error_stats();
554 #endif /* RW_STATS_INCLUDED */
555 
556   /* Process the error */
557   rw_t1t_process_error();
558 }
559 
560 /*******************************************************************************
561 **
562 ** Function         rw_t1t_process_error
563 **
564 ** Description      process timeout event
565 **
566 ** Returns          none
567 **
568 *******************************************************************************/
rw_t1t_process_error(void)569 static void rw_t1t_process_error(void) {
570   tRW_EVENT rw_event;
571   NFC_HDR* p_cmd_buf;
572   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
573   tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
574       (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
575 
576   LOG(VERBOSE) << StringPrintf("%s: State=%u", __func__, p_t1t->state);
577 
578   /* Retry sending command if retry-count < max */
579   if (rw_cb.cur_retry < RW_MAX_RETRIES) {
580     /* retry sending the command */
581     rw_cb.cur_retry++;
582 
583     LOG(VERBOSE) << StringPrintf("%s: T1T retransmission attempt %i of %i",
584                                  __func__, rw_cb.cur_retry, RW_MAX_RETRIES);
585 
586     /* allocate a new buffer for message */
587     p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
588     if (p_cmd_buf != nullptr) {
589       memcpy(p_cmd_buf, p_t1t->p_cur_cmd_buf,
590              sizeof(NFC_HDR) + p_t1t->p_cur_cmd_buf->offset +
591                  p_t1t->p_cur_cmd_buf->len);
592 
593 #if (RW_STATS_INCLUDED == TRUE)
594       /* Update stats */
595       rw_main_update_tx_stats(p_cmd_buf->len, true);
596 #endif /* RW_STATS_INCLUDED */
597 
598       if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) {
599         /* Start timer for waiting for response */
600         nfc_start_quick_timer(
601             &p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
602             (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
603 
604         return;
605       }
606     }
607   } else {
608     /* we might get response later to all or some of the retrasnmission
609      * of the current command, update previous command response information */
610     LOG(VERBOSE) << StringPrintf(
611         "%s: T1T maximum retransmission attempts reached (%i)", __func__,
612         RW_MAX_RETRIES);
613     p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
614                                      (p_cmd_rsp_info->opcode != T1T_CMD_RID))
615                                         ? p_t1t->addr
616                                         : 0;
617     p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
618     p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
619     p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
620   }
621 
622 #if (RW_STATS_INCLUDED == TRUE)
623   /* update failure count */
624   rw_main_update_fail_stats();
625 #endif /* RW_STATS_INCLUDED */
626 
627   rw_event = rw_t1t_info_to_event(p_cmd_rsp_info);
628   if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED) rw_t1t_handle_op_complete();
629 
630   if (rw_event == RW_T1T_NDEF_DETECT_EVT) {
631     tRW_DETECT_NDEF_DATA ndef_data;
632     ndef_data.status = NFC_STATUS_TIMEOUT;
633     ndef_data.protocol = NFC_PROTOCOL_T1T;
634     ndef_data.flags = RW_NDEF_FL_UNKNOWN;
635     ndef_data.max_size = 0;
636     ndef_data.cur_size = 0;
637     tRW_DATA rw_data;
638     rw_data.ndef = ndef_data;
639     (*rw_cb.p_cback)(rw_event, &rw_data);
640   } else {
641     tRW_READ_DATA evt_data;
642     evt_data.status = NFC_STATUS_TIMEOUT;
643     evt_data.p_data = nullptr;
644     tRW_DATA rw_data;
645     rw_data.data = evt_data;
646     (*rw_cb.p_cback)(rw_event, &rw_data);
647   }
648 }
649 
650 /*****************************************************************************
651 **
652 ** Function         rw_t1t_handle_presence_check_rsp
653 **
654 ** Description      Handle response to presence check
655 **
656 ** Returns          Nothing
657 **
658 *****************************************************************************/
rw_t1t_handle_presence_check_rsp(tNFC_STATUS status)659 void rw_t1t_handle_presence_check_rsp(tNFC_STATUS status) {
660   tRW_DATA rw_data;
661 
662   /* Notify, Tag is present or not */
663   rw_data.data.status = status;
664   LOG(VERBOSE) << StringPrintf("%s: T1T rsp status = %d ", __func__, status);
665   rw_t1t_handle_op_complete();
666 
667   (*(rw_cb.p_cback))(RW_T1T_PRESENCE_CHECK_EVT, &rw_data);
668 }
669 
670 /*****************************************************************************
671 **
672 ** Function         rw_t1t_handle_op_complete
673 **
674 ** Description      Reset to IDLE state
675 **
676 ** Returns          Nothing
677 **
678 *****************************************************************************/
rw_t1t_handle_op_complete(void)679 void rw_t1t_handle_op_complete(void) {
680   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
681 
682   p_t1t->state = RW_T1T_STATE_IDLE;
683 #if (RW_NDEF_INCLUDED == TRUE)
684   if (appl_dta_mode_flag == 0 && (p_t1t->state != RW_T1T_STATE_READ_NDEF)) {
685     p_t1t->b_update = false;
686     p_t1t->b_rseg = false;
687   }
688   p_t1t->substate = RW_T1T_SUBSTATE_NONE;
689 #endif
690   return;
691 }
692 
693 /*****************************************************************************
694 **
695 ** Function         RW_T1tPresenceCheck
696 **
697 ** Description
698 **      Check if the tag is still in the field.
699 **
700 **      The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
701 **      or non-presence.
702 **
703 ** Returns
704 **      NFC_STATUS_OK, if raw data frame sent
705 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
706 **      NFC_STATUS_FAILED: other error
707 **
708 *****************************************************************************/
RW_T1tPresenceCheck(void)709 tNFC_STATUS RW_T1tPresenceCheck(void) {
710   tNFC_STATUS retval = NFC_STATUS_OK;
711   tRW_DATA evt_data;
712   tRW_CB* p_rw_cb = &rw_cb;
713 
714   LOG(VERBOSE) << __func__;
715 
716   /* If RW_SelectTagType was not called (no conn_callback) return failure */
717   if (!p_rw_cb->p_cback) {
718     retval = NFC_STATUS_FAILED;
719   }
720   /* If we are not activated, then RW_T1T_PRESENCE_CHECK_EVT status=FAIL */
721   else if (p_rw_cb->tcb.t1t.state == RW_T1T_STATE_NOT_ACTIVATED) {
722     evt_data.status = NFC_STATUS_FAILED;
723     (*p_rw_cb->p_cback)(RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
724   }
725   /* If command is pending, assume tag is still present */
726   else if (p_rw_cb->tcb.t1t.state != RW_T1T_STATE_IDLE) {
727     evt_data.status = NFC_STATUS_OK;
728     (*p_rw_cb->p_cback)(RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
729   } else {
730     /* IDLE state: send a RID command to the tag to see if it responds */
731     retval = rw_t1t_send_static_cmd(T1T_CMD_RID, 0, 0);
732     if (retval == NFC_STATUS_OK) {
733       p_rw_cb->tcb.t1t.state = RW_T1T_STATE_CHECK_PRESENCE;
734     }
735   }
736 
737   return (retval);
738 }
739 
740 /*****************************************************************************
741 **
742 ** Function         RW_T1tRid
743 **
744 ** Description
745 **      This function sends a RID command for Reader/Writer mode.
746 **
747 ** Returns
748 **      NFC_STATUS_OK, if raw data frame sent
749 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
750 **      NFC_STATUS_FAILED: other error
751 **
752 *****************************************************************************/
RW_T1tRid(void)753 tNFC_STATUS RW_T1tRid(void) {
754   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
755   tNFC_STATUS status = NFC_STATUS_FAILED;
756 
757   LOG(VERBOSE) << __func__;
758 
759   if (p_t1t->state != RW_T1T_STATE_IDLE) {
760     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
761     return (NFC_STATUS_BUSY);
762   }
763 
764   /* send a RID command */
765   status = rw_t1t_send_static_cmd(T1T_CMD_RID, 0, 0);
766   if (status == NFC_STATUS_OK) {
767     p_t1t->state = RW_T1T_STATE_READ;
768   }
769 
770   return (status);
771 }
772 
773 /*******************************************************************************
774 **
775 ** Function         RW_T1tReadAll
776 **
777 ** Description      This function sends a RALL command for Reader/Writer mode.
778 **
779 ** Returns          tNFC_STATUS
780 **
781 *******************************************************************************/
RW_T1tReadAll(void)782 tNFC_STATUS RW_T1tReadAll(void) {
783   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
784   tNFC_STATUS status = NFC_STATUS_FAILED;
785 
786   LOG(VERBOSE) << __func__;
787 
788   if (p_t1t->state != RW_T1T_STATE_IDLE) {
789     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
790     return (NFC_STATUS_BUSY);
791   }
792 
793   /* send RALL command */
794   status = rw_t1t_send_static_cmd(T1T_CMD_RALL, 0, 0);
795   if (status == NFC_STATUS_OK) {
796     p_t1t->state = RW_T1T_STATE_READ;
797   }
798 
799   return status;
800 }
801 
802 /*******************************************************************************
803 **
804 ** Function         RW_T1tRead
805 **
806 ** Description      This function sends a READ command for Reader/Writer mode.
807 **
808 ** Returns          tNFC_STATUS
809 **
810 *******************************************************************************/
RW_T1tRead(uint8_t block,uint8_t byte)811 tNFC_STATUS RW_T1tRead(uint8_t block, uint8_t byte) {
812   tNFC_STATUS status = NFC_STATUS_FAILED;
813   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
814   uint8_t addr;
815 
816   if (p_t1t->state != RW_T1T_STATE_IDLE) {
817     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
818     return (NFC_STATUS_BUSY);
819   }
820 
821   /* send READ command */
822   RW_T1T_BLD_ADD((addr), (block), (byte));
823   status = rw_t1t_send_static_cmd(T1T_CMD_READ, addr, 0);
824   if (status == NFC_STATUS_OK) {
825     p_t1t->state = RW_T1T_STATE_READ;
826   }
827   return status;
828 }
829 
830 /*******************************************************************************
831 **
832 ** Function         RW_T1tWriteErase
833 **
834 ** Description      This function sends a WRITE-E command for Reader/Writer
835 **                  mode.
836 **
837 ** Returns          tNFC_STATUS
838 **
839 *******************************************************************************/
RW_T1tWriteErase(uint8_t block,uint8_t byte,uint8_t new_byte)840 tNFC_STATUS RW_T1tWriteErase(uint8_t block, uint8_t byte, uint8_t new_byte) {
841   tNFC_STATUS status = NFC_STATUS_FAILED;
842   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
843   uint8_t addr;
844 
845   if (p_t1t->state != RW_T1T_STATE_IDLE) {
846     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
847     return (NFC_STATUS_BUSY);
848   }
849   if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
850       (block != T1T_CC_BLOCK) && (byte != T1T_CC_RWA_OFFSET)) {
851     LOG(ERROR) << StringPrintf("%s: Tag is in Read only state", __func__);
852     return (NFC_STATUS_REFUSED);
853   }
854   if ((block >= T1T_STATIC_BLOCKS) || (byte >= T1T_BLOCK_SIZE)) {
855     LOG(ERROR) << StringPrintf("%s: Invalid Block/byte=%u / %u", __func__,
856                                block, byte);
857     return (NFC_STATUS_REFUSED);
858   }
859   if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
860     LOG(WARNING) << StringPrintf("%s: Cannot write to Locked block=%u",
861                                  __func__, block);
862     return (NFC_STATUS_REFUSED);
863   }
864   /* send WRITE-E command */
865   RW_T1T_BLD_ADD((addr), (block), (byte));
866   status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, new_byte);
867   if (status == NFC_STATUS_OK) {
868     p_t1t->state = RW_T1T_STATE_WRITE;
869     if (block < T1T_BLOCKS_PER_SEGMENT) {
870       p_t1t->b_update = false;
871       p_t1t->b_rseg = false;
872     }
873   }
874   return status;
875 }
876 
877 /*******************************************************************************
878 **
879 ** Function         RW_T1tWriteNoErase
880 **
881 ** Description      This function sends a WRITE-NE command for Reader/Writer
882 **                  mode.
883 **
884 ** Returns          tNFC_STATUS
885 **
886 *******************************************************************************/
RW_T1tWriteNoErase(uint8_t block,uint8_t byte,uint8_t new_byte)887 tNFC_STATUS RW_T1tWriteNoErase(uint8_t block, uint8_t byte, uint8_t new_byte) {
888   tNFC_STATUS status = NFC_STATUS_FAILED;
889   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
890   uint8_t addr;
891 
892   if (p_t1t->state != RW_T1T_STATE_IDLE) {
893     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
894     return (NFC_STATUS_BUSY);
895   }
896   if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
897       (block != T1T_CC_BLOCK) && (byte != T1T_CC_RWA_OFFSET)) {
898     LOG(ERROR) << StringPrintf("%s: Tag is in Read only state", __func__);
899     return (NFC_STATUS_REFUSED);
900   }
901   if ((block >= T1T_STATIC_BLOCKS) || (byte >= T1T_BLOCK_SIZE)) {
902     LOG(ERROR) << StringPrintf("%s: Invalid Block/byte=%u / %u", __func__,
903                                block, byte);
904     return (NFC_STATUS_REFUSED);
905   }
906   if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
907     LOG(WARNING) << StringPrintf("%s: Cannot write to Locked block=%u",
908                                  __func__, block);
909     return (NFC_STATUS_REFUSED);
910   }
911   /* send WRITE-NE command */
912   RW_T1T_BLD_ADD((addr), (block), (byte));
913   status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, new_byte);
914   if (status == NFC_STATUS_OK) {
915     p_t1t->state = RW_T1T_STATE_WRITE;
916     if (block < T1T_BLOCKS_PER_SEGMENT) {
917       p_t1t->b_update = false;
918       p_t1t->b_rseg = false;
919     }
920   }
921   return status;
922 }
923 
924 /*******************************************************************************
925 **
926 ** Function         RW_T1tReadSeg
927 **
928 ** Description      This function sends a RSEG command for Reader/Writer mode.
929 **
930 ** Returns          tNFC_STATUS
931 **
932 *******************************************************************************/
RW_T1tReadSeg(uint8_t segment)933 tNFC_STATUS RW_T1tReadSeg(uint8_t segment) {
934   tNFC_STATUS status = NFC_STATUS_FAILED;
935   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
936   uint8_t adds;
937 
938   if (p_t1t->state != RW_T1T_STATE_IDLE) {
939     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
940     return (NFC_STATUS_BUSY);
941   }
942   if (segment >= T1T_MAX_SEGMENTS) {
943     LOG(ERROR) << StringPrintf("%s: Invalid Segment=%u", __func__, segment);
944     return (NFC_STATUS_REFUSED);
945   }
946   if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0) {
947     /* send RSEG command */
948     RW_T1T_BLD_ADDS((adds), (segment));
949     status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, nullptr);
950     if (status == NFC_STATUS_OK) {
951       p_t1t->state = RW_T1T_STATE_READ;
952     }
953   }
954   return status;
955 }
956 
957 /*******************************************************************************
958 **
959 ** Function         RW_T1tRead8
960 **
961 ** Description      This function sends a READ8 command for Reader/Writer mode.
962 **
963 ** Returns          tNFC_STATUS
964 **
965 *******************************************************************************/
RW_T1tRead8(uint8_t block)966 tNFC_STATUS RW_T1tRead8(uint8_t block) {
967   tNFC_STATUS status = NFC_STATUS_FAILED;
968   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
969 
970   if (p_t1t->state != RW_T1T_STATE_IDLE) {
971     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
972     return (NFC_STATUS_BUSY);
973   }
974 
975   if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
976       rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
977     /* send READ8 command */
978     status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, block, nullptr);
979     if (status == NFC_STATUS_OK) {
980       p_t1t->state = RW_T1T_STATE_READ;
981     }
982   }
983   return status;
984 }
985 
986 /*******************************************************************************
987 **
988 ** Function         RW_T1tWriteErase8
989 **
990 ** Description      This function sends a WRITE-E8 command for Reader/Writer
991 **                  mode.
992 **
993 ** Returns          tNFC_STATUS
994 **
995 *******************************************************************************/
RW_T1tWriteErase8(uint8_t block,uint8_t * p_new_dat)996 tNFC_STATUS RW_T1tWriteErase8(uint8_t block, uint8_t* p_new_dat) {
997   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
998   tNFC_STATUS status = NFC_STATUS_FAILED;
999 
1000   if (p_t1t->state != RW_T1T_STATE_IDLE) {
1001     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
1002     return (NFC_STATUS_BUSY);
1003   }
1004 
1005   if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
1006       (block != T1T_CC_BLOCK)) {
1007     LOG(ERROR) << StringPrintf("%s: Tag is in Read only state", __func__);
1008     return (NFC_STATUS_REFUSED);
1009   }
1010 
1011   if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
1012     LOG(WARNING) << StringPrintf("%s: Cannot write to Locked block=%u",
1013                                  __func__, block);
1014     return (NFC_STATUS_REFUSED);
1015   }
1016 
1017   if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
1018       rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
1019     /* send WRITE-E8 command */
1020     status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, block, p_new_dat);
1021     if (status == NFC_STATUS_OK) {
1022       p_t1t->state = RW_T1T_STATE_WRITE;
1023       if (block < T1T_BLOCKS_PER_SEGMENT) {
1024         p_t1t->b_update = false;
1025         p_t1t->b_rseg = false;
1026       }
1027     }
1028   }
1029   return status;
1030 }
1031 
1032 /*******************************************************************************
1033 **
1034 ** Function         RW_T1tWriteNoErase8
1035 **
1036 ** Description      This function sends a WRITE-NE8 command for Reader/Writer
1037 **                  mode.
1038 **
1039 ** Returns          tNFC_STATUS
1040 **
1041 *******************************************************************************/
RW_T1tWriteNoErase8(uint8_t block,uint8_t * p_new_dat)1042 tNFC_STATUS RW_T1tWriteNoErase8(uint8_t block, uint8_t* p_new_dat) {
1043   tNFC_STATUS status = NFC_STATUS_FAILED;
1044   tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1045 
1046   if (p_t1t->state != RW_T1T_STATE_IDLE) {
1047     LOG(WARNING) << StringPrintf("%s: Busy - State=%u", __func__, p_t1t->state);
1048     return (NFC_STATUS_BUSY);
1049   }
1050 
1051   if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
1052       (block != T1T_CC_BLOCK)) {
1053     LOG(ERROR) << StringPrintf("%s: Tag is in Read only state", __func__);
1054     return (NFC_STATUS_REFUSED);
1055   }
1056 
1057   if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
1058     LOG(WARNING) << StringPrintf("%s: Cannot write to Locked block=%u",
1059                                  __func__, block);
1060     return (NFC_STATUS_REFUSED);
1061   }
1062 
1063   if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
1064       rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
1065     /* send WRITE-NE command */
1066     status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_NE8, block, p_new_dat);
1067     if (status == NFC_STATUS_OK) {
1068       p_t1t->state = RW_T1T_STATE_WRITE;
1069       if (block < T1T_BLOCKS_PER_SEGMENT) {
1070         p_t1t->b_update = false;
1071         p_t1t->b_rseg = false;
1072       }
1073     }
1074   }
1075   return status;
1076 }
1077 
1078 /*******************************************************************************
1079 **
1080 ** Function         rw_t1t_get_state_name
1081 **
1082 ** Description      This function returns the state name.
1083 **
1084 ** NOTE             conditionally compiled to save memory.
1085 **
1086 ** Returns          pointer to the name
1087 **
1088 *******************************************************************************/
rw_t1t_get_state_name(uint8_t state)1089 static std::string rw_t1t_get_state_name(uint8_t state) {
1090   switch (state) {
1091     case RW_T1T_STATE_IDLE:
1092       return "IDLE";
1093     case RW_T1T_STATE_NOT_ACTIVATED:
1094       return "NOT_ACTIVATED";
1095     case RW_T1T_STATE_READ:
1096       return "APP_READ";
1097     case RW_T1T_STATE_WRITE:
1098       return "APP_WRITE";
1099     case RW_T1T_STATE_TLV_DETECT:
1100       return "TLV_DETECTION";
1101     case RW_T1T_STATE_READ_NDEF:
1102       return "READING_NDEF";
1103     case RW_T1T_STATE_WRITE_NDEF:
1104       return "WRITING_NDEF";
1105     case RW_T1T_STATE_SET_TAG_RO:
1106       return "SET_TAG_RO";
1107     case RW_T1T_STATE_CHECK_PRESENCE:
1108       return "CHECK_PRESENCE";
1109     case RW_T1T_STATE_FORMAT_TAG:
1110       return "FORMAT_TAG";
1111     default:
1112       return "???? UNKNOWN STATE";
1113   }
1114 }
1115