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