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