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