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