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.h>
26 #include "nfc_target.h"
27
28 #include "gki.h"
29 #include "nci_hmsgs.h"
30 #include "nfc_api.h"
31 #include "nfc_int.h"
32 #include "rw_api.h"
33 #include "rw_int.h"
34
35 extern unsigned char appl_dta_mode_flag;
36 /* Local Functions */
37 static tRW_EVENT rw_t1t_handle_rid_rsp(NFC_HDR* p_pkt);
38 static void rw_t1t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
39 tNFC_CONN* p_data);
40 static void rw_t1t_process_frame_error(void);
41 static void rw_t1t_process_error(void);
42 static void rw_t1t_handle_presence_check_rsp(tNFC_STATUS status);
43 #if (BT_TRACE_VERBOSE == TRUE)
44 static char* rw_t1t_get_state_name(uint8_t state);
45 static char* rw_t1t_get_sub_state_name(uint8_t sub_state);
46 static char* rw_t1t_get_event_name(uint8_t event);
47 #endif
48
49 /*******************************************************************************
50 **
51 ** Function rw_t1t_data_cback
52 **
53 ** Description This callback function handles data from NFCC.
54 **
55 ** Returns none
56 **
57 *******************************************************************************/
rw_t1t_data_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)58 static void rw_t1t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
59 tNFC_CONN* p_data) {
60 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
61 tRW_EVENT rw_event = RW_RAW_FRAME_EVT;
62 bool b_notify = true;
63 tRW_DATA evt_data;
64 NFC_HDR* p_pkt;
65 uint8_t* p;
66 tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
67 (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
68 #if (BT_TRACE_VERBOSE == TRUE)
69 uint8_t begin_state = p_t1t->state;
70 #endif
71
72 p_pkt = (NFC_HDR*)(p_data->data.p_data);
73 if (p_pkt == NULL) return;
74 /* Assume the data is just the response byte sequence */
75 p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
76
77 #if (BT_TRACE_VERBOSE == TRUE)
78 RW_TRACE_DEBUG2("rw_t1t_data_cback (): state:%s (%d)",
79 rw_t1t_get_state_name(p_t1t->state), p_t1t->state);
80 #else
81 RW_TRACE_DEBUG1("rw_t1t_data_cback (): state=%d", p_t1t->state);
82 #endif
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 RW_TRACE_ERROR2(
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, (tRW_DATA*)&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 RW_TRACE_ERROR2(
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 #if (BT_TRACE_VERBOSE == TRUE)
148 RW_TRACE_ERROR2("T1T Frame error. state=%s command (opcode) = 0x%02x",
149 rw_t1t_get_state_name(p_t1t->state),
150 p_cmd_rsp_info->opcode);
151 #else
152 RW_TRACE_ERROR2("T1T Frame error. state=0x%02x command = 0x%02x ",
153 p_t1t->state, p_cmd_rsp_info->opcode);
154 #endif
155 rw_t1t_process_frame_error();
156 }
157 GKI_freebuf(p_pkt);
158 return;
159 }
160
161 /* Stop timer as response to current command is received */
162 nfc_stop_quick_timer(&p_t1t->timer);
163
164 RW_TRACE_EVENT2("RW RECV [%s]:0x%x RSP", t1t_info_to_str(p_cmd_rsp_info),
165 p_cmd_rsp_info->opcode);
166
167 /* If we did not receive response to all retransmitted previous command,
168 * dont expect that as response have come for the current command itself.
169 */
170 if (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
171 memset(&(p_t1t->prev_cmd_rsp_info), 0, sizeof(tRW_T1T_PREV_CMD_RSP_INFO));
172
173 if (rw_cb.cur_retry) {
174 /* If the current command was retransmitted to get this response, we might
175 get
176 response later to all or some of the retrasnmission of the current
177 command
178 */
179 p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
180 (p_cmd_rsp_info->opcode != T1T_CMD_RID))
181 ? p_t1t->addr
182 : 0;
183 p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
184 p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
185 p_t1t->prev_cmd_rsp_info.pend_retx_rsp = (uint8_t)rw_cb.cur_retry;
186 }
187
188 rw_cb.cur_retry = 0;
189
190 if (p_cmd_rsp_info->opcode == T1T_CMD_RID) {
191 rw_event = rw_t1t_handle_rid_rsp(p_pkt);
192 } else {
193 rw_event =
194 rw_t1t_handle_rsp(p_cmd_rsp_info, &b_notify, p, &evt_data.status);
195 }
196
197 if (b_notify) {
198 if ((p_t1t->state != RW_T1T_STATE_READ) &&
199 (p_t1t->state != RW_T1T_STATE_WRITE)) {
200 GKI_freebuf(p_pkt);
201 evt_data.data.p_data = NULL;
202 } else {
203 evt_data.data.p_data = p_pkt;
204 }
205 rw_t1t_handle_op_complete();
206 (*rw_cb.p_cback)(rw_event, (tRW_DATA*)&evt_data);
207 } else
208 GKI_freebuf(p_pkt);
209
210 #if (BT_TRACE_VERBOSE == TRUE)
211 if (begin_state != p_t1t->state) {
212 RW_TRACE_DEBUG2("RW T1T state changed:<%s> -> <%s>",
213 rw_t1t_get_state_name(begin_state),
214 rw_t1t_get_state_name(p_t1t->state));
215 }
216 #endif
217 }
218
219 /*******************************************************************************
220 **
221 ** Function rw_t1t_conn_cback
222 **
223 ** Description This callback function receives the events/data from NFCC.
224 **
225 ** Returns none
226 **
227 *******************************************************************************/
rw_t1t_conn_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)228 void rw_t1t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
229 tNFC_CONN* p_data) {
230 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
231 tRW_READ_DATA evt_data;
232
233 RW_TRACE_DEBUG2("rw_t1t_conn_cback: conn_id=%i, evt=0x%x", conn_id, event);
234 /* Only handle static conn_id */
235 if (conn_id != NFC_RF_CONN_ID) {
236 RW_TRACE_WARNING1("rw_t1t_conn_cback - Not static connection id: =%i",
237 conn_id);
238 return;
239 }
240
241 switch (event) {
242 case NFC_CONN_CREATE_CEVT:
243 case NFC_CONN_CLOSE_CEVT:
244 break;
245
246 case NFC_DEACTIVATE_CEVT:
247 #if (RW_STATS_INCLUDED == TRUE)
248 /* Display stats */
249 rw_main_log_stats();
250 #endif /* RW_STATS_INCLUDED */
251
252 /* Stop t1t timer (if started) */
253 nfc_stop_quick_timer(&p_t1t->timer);
254
255 /* Free cmd buf for retransmissions */
256 if (p_t1t->p_cur_cmd_buf) {
257 GKI_freebuf(p_t1t->p_cur_cmd_buf);
258 p_t1t->p_cur_cmd_buf = NULL;
259 }
260
261 p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
262 NFC_SetStaticRfCback(NULL);
263 break;
264
265 case NFC_DATA_CEVT:
266 if (p_data != NULL) {
267 if (p_data->data.status == NFC_STATUS_OK) {
268 rw_t1t_data_cback(conn_id, event, p_data);
269 break;
270 } else if (p_data->data.p_data != NULL) {
271 /* Free the response buffer in case of error response */
272 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
273 p_data->data.p_data = NULL;
274 }
275 }
276 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
277
278 case NFC_ERROR_CEVT:
279 if ((p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED) ||
280 (p_t1t->state == RW_T1T_STATE_IDLE)) {
281 #if (RW_STATS_INCLUDED == TRUE)
282 rw_main_update_trans_error_stats();
283 #endif /* RW_STATS_INCLUDED */
284
285 if (event == NFC_ERROR_CEVT)
286 evt_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
287 else if (p_data)
288 evt_data.status = p_data->status;
289 else
290 evt_data.status = NFC_STATUS_FAILED;
291
292 evt_data.p_data = NULL;
293 (*rw_cb.p_cback)(RW_T1T_INTF_ERROR_EVT, (tRW_DATA*)&evt_data);
294 break;
295 }
296 nfc_stop_quick_timer(&p_t1t->timer);
297
298 #if (RW_STATS_INCLUDED == TRUE)
299 rw_main_update_trans_error_stats();
300 #endif /* RW_STATS_INCLUDED */
301
302 if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
303 rw_t1t_handle_presence_check_rsp(NFC_STATUS_FAILED);
304 } else {
305 rw_t1t_process_error();
306 }
307 break;
308
309 default:
310 break;
311 }
312 }
313
314 /*******************************************************************************
315 **
316 ** Function rw_t1t_send_static_cmd
317 **
318 ** Description This function composes a Type 1 Tag command for static
319 ** memory and send through NCI to NFCC.
320 **
321 ** Returns NFC_STATUS_OK if the command is successfuly sent to NCI
322 ** otherwise, error status
323 **
324 *******************************************************************************/
rw_t1t_send_static_cmd(uint8_t opcode,uint8_t add,uint8_t dat)325 tNFC_STATUS rw_t1t_send_static_cmd(uint8_t opcode, uint8_t add, uint8_t dat) {
326 tNFC_STATUS status = NFC_STATUS_FAILED;
327 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
328 const tT1T_CMD_RSP_INFO* p_cmd_rsp_info = t1t_cmd_to_rsp_info(opcode);
329 NFC_HDR* p_data;
330 uint8_t* p;
331
332 if (p_cmd_rsp_info) {
333 /* a valid opcode for RW */
334 p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
335 if (p_data) {
336 p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info;
337 p_t1t->addr = add;
338 p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
339 p = (uint8_t*)(p_data + 1) + p_data->offset;
340 UINT8_TO_BE_STREAM(p, opcode);
341 UINT8_TO_BE_STREAM(p, add);
342 UINT8_TO_BE_STREAM(p, dat);
343
344 ARRAY_TO_STREAM(p, p_t1t->mem, T1T_CMD_UID_LEN);
345 p_data->len = p_cmd_rsp_info->cmd_len;
346
347 /* Indicate first attempt to send command, back up cmd buffer in case
348 * needed for retransmission */
349 rw_cb.cur_retry = 0;
350 memcpy(p_t1t->p_cur_cmd_buf, p_data,
351 sizeof(NFC_HDR) + p_data->offset + p_data->len);
352
353 #if (RW_STATS_INCLUDED == TRUE)
354 /* Update stats */
355 rw_main_update_tx_stats(p_data->len, false);
356 #endif /* RW_STATS_INCLUDED */
357
358 RW_TRACE_EVENT2("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 RW_TRACE_EVENT2("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 #if (BT_TRACE_VERBOSE == TRUE)
469 RW_TRACE_DEBUG2("hr0:0x%x, hr1:0x%x", p_t1t->hr[0], p_t1t->hr[1]);
470 RW_TRACE_DEBUG4("rw_t1t_handle_rid_rsp (): UID0-3=%02x%02x%02x%02x",
471 p_rid_rsp[0], p_rid_rsp[1], p_rid_rsp[2], p_rid_rsp[3]);
472 #else
473 RW_TRACE_DEBUG0("rw_t1t_handle_rid_rsp ()");
474 #endif
475
476 /* Fetch UID0-3 from RID response message */
477 STREAM_TO_ARRAY(p_t1t->mem, p_rid_rsp, T1T_CMD_UID_LEN);
478
479 /* Notify RID response Event */
480 return RW_T1T_RID_EVT;
481 }
482
483 /*******************************************************************************
484 **
485 ** Function rw_t1t_select
486 **
487 ** Description This function will set the callback function to
488 ** receive data from lower layers and also send rid command
489 **
490 ** Returns none
491 **
492 *******************************************************************************/
rw_t1t_select(uint8_t hr[T1T_HR_LEN],uint8_t uid[T1T_CMD_UID_LEN])493 tNFC_STATUS rw_t1t_select(uint8_t hr[T1T_HR_LEN],
494 uint8_t uid[T1T_CMD_UID_LEN]) {
495 tNFC_STATUS status = NFC_STATUS_FAILED;
496 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
497
498 p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
499
500 /* Alloc cmd buf for retransmissions */
501 if (p_t1t->p_cur_cmd_buf == NULL) {
502 p_t1t->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
503 if (p_t1t->p_cur_cmd_buf == NULL) {
504 RW_TRACE_ERROR0(
505 "rw_t1t_select: unable to allocate buffer for retransmission");
506 return status;
507 }
508 }
509
510 memcpy(p_t1t->hr, hr, T1T_HR_LEN);
511 memcpy(p_t1t->mem, uid, T1T_CMD_UID_LEN);
512
513 NFC_SetStaticRfCback(rw_t1t_conn_cback);
514
515 p_t1t->state = RW_T1T_STATE_IDLE;
516
517 return NFC_STATUS_OK;
518 }
519
520 /*******************************************************************************
521 **
522 ** Function rw_t1t_process_timeout
523 **
524 ** Description process timeout event
525 **
526 ** Returns none
527 **
528 *******************************************************************************/
rw_t1t_process_timeout(TIMER_LIST_ENT * p_tle)529 void rw_t1t_process_timeout(TIMER_LIST_ENT* p_tle) {
530 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
531
532 #if (BT_TRACE_VERBOSE == TRUE)
533 RW_TRACE_ERROR2("T1T timeout. state=%s command (opcode)=0x%02x ",
534 rw_t1t_get_state_name(p_t1t->state),
535 (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
536 #else
537 RW_TRACE_ERROR2("T1T timeout. state=0x%02x command=0x%02x ", p_t1t->state,
538 (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
539 #endif
540
541 if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
542 /* Tag has moved from range */
543 rw_t1t_handle_presence_check_rsp(NFC_STATUS_FAILED);
544 } else if (p_t1t->state != RW_T1T_STATE_IDLE) {
545 rw_t1t_process_error();
546 }
547 }
548
549 /*******************************************************************************
550 **
551 ** Function rw_t1t_process_frame_error
552 **
553 ** Description Process frame crc error
554 **
555 ** Returns none
556 **
557 *******************************************************************************/
rw_t1t_process_frame_error(void)558 static void rw_t1t_process_frame_error(void) {
559 #if (RW_STATS_INCLUDED == TRUE)
560 /* Update stats */
561 rw_main_update_crc_error_stats();
562 #endif /* RW_STATS_INCLUDED */
563
564 /* Process the error */
565 rw_t1t_process_error();
566 }
567
568 /*******************************************************************************
569 **
570 ** Function rw_t1t_process_error
571 **
572 ** Description process timeout event
573 **
574 ** Returns none
575 **
576 *******************************************************************************/
rw_t1t_process_error(void)577 static void rw_t1t_process_error(void) {
578 tRW_READ_DATA evt_data;
579 tRW_EVENT rw_event;
580 NFC_HDR* p_cmd_buf;
581 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
582 tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
583 (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
584 tRW_DETECT_NDEF_DATA ndef_data;
585
586 RW_TRACE_DEBUG1("rw_t1t_process_error () State: %u", p_t1t->state);
587
588 /* Retry sending command if retry-count < max */
589 if (rw_cb.cur_retry < RW_MAX_RETRIES) {
590 /* retry sending the command */
591 rw_cb.cur_retry++;
592
593 RW_TRACE_DEBUG2("T1T retransmission attempt %i of %i", rw_cb.cur_retry,
594 RW_MAX_RETRIES);
595
596 /* allocate a new buffer for message */
597 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
598 if (p_cmd_buf != NULL) {
599 memcpy(p_cmd_buf, p_t1t->p_cur_cmd_buf,
600 sizeof(NFC_HDR) + p_t1t->p_cur_cmd_buf->offset +
601 p_t1t->p_cur_cmd_buf->len);
602
603 #if (RW_STATS_INCLUDED == TRUE)
604 /* Update stats */
605 rw_main_update_tx_stats(p_cmd_buf->len, true);
606 #endif /* RW_STATS_INCLUDED */
607
608 if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) {
609 /* Start timer for waiting for response */
610 nfc_start_quick_timer(
611 &p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
612 (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
613
614 return;
615 }
616 }
617 } else {
618 /* we might get response later to all or some of the retrasnmission
619 * of the current command, update previous command response information */
620 RW_TRACE_DEBUG1("T1T maximum retransmission attempts reached (%i)",
621 RW_MAX_RETRIES);
622 p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
623 (p_cmd_rsp_info->opcode != T1T_CMD_RID))
624 ? p_t1t->addr
625 : 0;
626 p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
627 p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
628 p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
629 }
630
631 #if (RW_STATS_INCLUDED == TRUE)
632 /* update failure count */
633 rw_main_update_fail_stats();
634 #endif /* RW_STATS_INCLUDED */
635
636 rw_event = rw_t1t_info_to_event(p_cmd_rsp_info);
637 if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED) rw_t1t_handle_op_complete();
638
639 evt_data.status = NFC_STATUS_TIMEOUT;
640 if (rw_event == RW_T2T_NDEF_DETECT_EVT) {
641 ndef_data.status = evt_data.status;
642 ndef_data.protocol = NFC_PROTOCOL_T1T;
643 ndef_data.flags = RW_NDEF_FL_UNKNOWN;
644 ndef_data.max_size = 0;
645 ndef_data.cur_size = 0;
646 (*rw_cb.p_cback)(rw_event, (tRW_DATA*)&ndef_data);
647 } else {
648 evt_data.p_data = NULL;
649 (*rw_cb.p_cback)(rw_event, (tRW_DATA*)&evt_data);
650 }
651 }
652
653 /*****************************************************************************
654 **
655 ** Function rw_t1t_handle_presence_check_rsp
656 **
657 ** Description Handle response to presence check
658 **
659 ** Returns Nothing
660 **
661 *****************************************************************************/
rw_t1t_handle_presence_check_rsp(tNFC_STATUS status)662 void rw_t1t_handle_presence_check_rsp(tNFC_STATUS status) {
663 tRW_READ_DATA evt_data;
664
665 /* Notify, Tag is present or not */
666 evt_data.status = status;
667 rw_t1t_handle_op_complete();
668
669 (*(rw_cb.p_cback))(RW_T1T_PRESENCE_CHECK_EVT, (tRW_DATA*)&evt_data);
670 }
671
672 /*****************************************************************************
673 **
674 ** Function rw_t1t_handle_op_complete
675 **
676 ** Description Reset to IDLE state
677 **
678 ** Returns Nothing
679 **
680 *****************************************************************************/
rw_t1t_handle_op_complete(void)681 void rw_t1t_handle_op_complete(void) {
682 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
683
684 p_t1t->state = RW_T1T_STATE_IDLE;
685 #if (RW_NDEF_INCLUDED == TRUE)
686 if (appl_dta_mode_flag == 0 && (p_t1t->state != RW_T1T_STATE_READ_NDEF)) {
687 p_t1t->b_update = false;
688 p_t1t->b_rseg = false;
689 }
690 p_t1t->substate = RW_T1T_SUBSTATE_NONE;
691 #endif
692 return;
693 }
694
695 /*****************************************************************************
696 **
697 ** Function RW_T1tPresenceCheck
698 **
699 ** Description
700 ** Check if the tag is still in the field.
701 **
702 ** The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
703 ** or non-presence.
704 **
705 ** Returns
706 ** NFC_STATUS_OK, if raw data frame sent
707 ** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
708 ** NFC_STATUS_FAILED: other error
709 **
710 *****************************************************************************/
RW_T1tPresenceCheck(void)711 tNFC_STATUS RW_T1tPresenceCheck(void) {
712 tNFC_STATUS retval = NFC_STATUS_OK;
713 tRW_DATA evt_data;
714 tRW_CB* p_rw_cb = &rw_cb;
715
716 RW_TRACE_API0("RW_T1tPresenceCheck");
717
718 /* If RW_SelectTagType was not called (no conn_callback) return failure */
719 if (!p_rw_cb->p_cback) {
720 retval = NFC_STATUS_FAILED;
721 }
722 /* If we are not activated, then RW_T1T_PRESENCE_CHECK_EVT status=FAIL */
723 else if (p_rw_cb->tcb.t1t.state == RW_T1T_STATE_NOT_ACTIVATED) {
724 evt_data.status = NFC_STATUS_FAILED;
725 (*p_rw_cb->p_cback)(RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
726 }
727 /* If command is pending, assume tag is still present */
728 else if (p_rw_cb->tcb.t1t.state != RW_T1T_STATE_IDLE) {
729 evt_data.status = NFC_STATUS_OK;
730 (*p_rw_cb->p_cback)(RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
731 } else {
732 /* IDLE state: send a RID command to the tag to see if it responds */
733 retval = rw_t1t_send_static_cmd(T1T_CMD_RID, 0, 0);
734 if (retval == NFC_STATUS_OK) {
735 p_rw_cb->tcb.t1t.state = RW_T1T_STATE_CHECK_PRESENCE;
736 }
737 }
738
739 return (retval);
740 }
741
742 /*****************************************************************************
743 **
744 ** Function RW_T1tRid
745 **
746 ** Description
747 ** This function sends a RID command for Reader/Writer mode.
748 **
749 ** Returns
750 ** NFC_STATUS_OK, if raw data frame sent
751 ** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
752 ** NFC_STATUS_FAILED: other error
753 **
754 *****************************************************************************/
RW_T1tRid(void)755 tNFC_STATUS RW_T1tRid(void) {
756 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
757 tNFC_STATUS status = NFC_STATUS_FAILED;
758
759 RW_TRACE_API0("RW_T1tRid");
760
761 if (p_t1t->state != RW_T1T_STATE_IDLE) {
762 RW_TRACE_WARNING1("RW_T1tRid - Busy - State: %u", p_t1t->state);
763 return (NFC_STATUS_BUSY);
764 }
765
766 /* send a RID command */
767 status = rw_t1t_send_static_cmd(T1T_CMD_RID, 0, 0);
768 if (status == NFC_STATUS_OK) {
769 p_t1t->state = RW_T1T_STATE_READ;
770 }
771
772 return (status);
773 }
774
775 /*******************************************************************************
776 **
777 ** Function RW_T1tReadAll
778 **
779 ** Description This function sends a RALL command for Reader/Writer mode.
780 **
781 ** Returns tNFC_STATUS
782 **
783 *******************************************************************************/
RW_T1tReadAll(void)784 tNFC_STATUS RW_T1tReadAll(void) {
785 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
786 tNFC_STATUS status = NFC_STATUS_FAILED;
787
788 RW_TRACE_API0("RW_T1tReadAll");
789
790 if (p_t1t->state != RW_T1T_STATE_IDLE) {
791 RW_TRACE_WARNING1("RW_T1tReadAll - Busy - State: %u", 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 RW_TRACE_WARNING1("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 RW_TRACE_WARNING1("RW_T1tWriteErase - Busy - State: %u", 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 RW_TRACE_ERROR0("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 RW_TRACE_ERROR2("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block,
858 byte);
859 return (NFC_STATUS_REFUSED);
860 }
861 if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
862 RW_TRACE_WARNING1("RW_T1tWriteErase - Cannot write to Locked block: %u",
863 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 RW_TRACE_WARNING1("RW_T1tWriteNoErase - Busy - State: %u", p_t1t->state);
896 return (NFC_STATUS_BUSY);
897 }
898 if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
899 (block != T1T_CC_BLOCK) && (byte != T1T_CC_RWA_OFFSET)) {
900 RW_TRACE_ERROR0("RW_T1tWriteErase - Tag is in Read only state");
901 return (NFC_STATUS_REFUSED);
902 }
903 if ((block >= T1T_STATIC_BLOCKS) || (byte >= T1T_BLOCK_SIZE)) {
904 RW_TRACE_ERROR2("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block,
905 byte);
906 return (NFC_STATUS_REFUSED);
907 }
908 if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
909 RW_TRACE_WARNING1("RW_T1tWriteNoErase - Cannot write to Locked block: %u",
910 block);
911 return (NFC_STATUS_REFUSED);
912 }
913 /* send WRITE-NE command */
914 RW_T1T_BLD_ADD((addr), (block), (byte));
915 status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, new_byte);
916 if (status == NFC_STATUS_OK) {
917 p_t1t->state = RW_T1T_STATE_WRITE;
918 if (block < T1T_BLOCKS_PER_SEGMENT) {
919 p_t1t->b_update = false;
920 p_t1t->b_rseg = false;
921 }
922 }
923 return status;
924 }
925
926 /*******************************************************************************
927 **
928 ** Function RW_T1tReadSeg
929 **
930 ** Description This function sends a RSEG command for Reader/Writer mode.
931 **
932 ** Returns tNFC_STATUS
933 **
934 *******************************************************************************/
RW_T1tReadSeg(uint8_t segment)935 tNFC_STATUS RW_T1tReadSeg(uint8_t segment) {
936 tNFC_STATUS status = NFC_STATUS_FAILED;
937 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
938 uint8_t adds;
939
940 if (p_t1t->state != RW_T1T_STATE_IDLE) {
941 RW_TRACE_WARNING1("RW_T1tReadSeg - Busy - State: %u", p_t1t->state);
942 return (NFC_STATUS_BUSY);
943 }
944 if (segment >= T1T_MAX_SEGMENTS) {
945 RW_TRACE_ERROR1("RW_T1tReadSeg - Invalid Segment: %u", segment);
946 return (NFC_STATUS_REFUSED);
947 }
948 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0) {
949 /* send RSEG command */
950 RW_T1T_BLD_ADDS((adds), (segment));
951 status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
952 if (status == NFC_STATUS_OK) {
953 p_t1t->state = RW_T1T_STATE_READ;
954 }
955 }
956 return status;
957 }
958
959 /*******************************************************************************
960 **
961 ** Function RW_T1tRead8
962 **
963 ** Description This function sends a READ8 command for Reader/Writer mode.
964 **
965 ** Returns tNFC_STATUS
966 **
967 *******************************************************************************/
RW_T1tRead8(uint8_t block)968 tNFC_STATUS RW_T1tRead8(uint8_t block) {
969 tNFC_STATUS status = NFC_STATUS_FAILED;
970 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
971
972 if (p_t1t->state != RW_T1T_STATE_IDLE) {
973 RW_TRACE_WARNING1("RW_T1tRead8 - Busy - State: %u", p_t1t->state);
974 return (NFC_STATUS_BUSY);
975 }
976
977 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
978 rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
979 /* send READ8 command */
980 status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, block, NULL);
981 if (status == NFC_STATUS_OK) {
982 p_t1t->state = RW_T1T_STATE_READ;
983 }
984 }
985 return status;
986 }
987
988 /*******************************************************************************
989 **
990 ** Function RW_T1tWriteErase8
991 **
992 ** Description This function sends a WRITE-E8 command for Reader/Writer
993 ** mode.
994 **
995 ** Returns tNFC_STATUS
996 **
997 *******************************************************************************/
RW_T1tWriteErase8(uint8_t block,uint8_t * p_new_dat)998 tNFC_STATUS RW_T1tWriteErase8(uint8_t block, uint8_t* p_new_dat) {
999 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1000 tNFC_STATUS status = NFC_STATUS_FAILED;
1001
1002 if (p_t1t->state != RW_T1T_STATE_IDLE) {
1003 RW_TRACE_WARNING1("RW_T1tWriteErase8 - Busy - State: %u", p_t1t->state);
1004 return (NFC_STATUS_BUSY);
1005 }
1006
1007 if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
1008 (block != T1T_CC_BLOCK)) {
1009 RW_TRACE_ERROR0("RW_T1tWriteErase8 - Tag is in Read only state");
1010 return (NFC_STATUS_REFUSED);
1011 }
1012
1013 if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
1014 RW_TRACE_WARNING1("RW_T1tWriteErase8 - Cannot write to Locked block: %u",
1015 block);
1016 return (NFC_STATUS_REFUSED);
1017 }
1018
1019 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
1020 rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
1021 /* send WRITE-E8 command */
1022 status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, block, p_new_dat);
1023 if (status == NFC_STATUS_OK) {
1024 p_t1t->state = RW_T1T_STATE_WRITE;
1025 if (block < T1T_BLOCKS_PER_SEGMENT) {
1026 p_t1t->b_update = false;
1027 p_t1t->b_rseg = false;
1028 }
1029 }
1030 }
1031 return status;
1032 }
1033
1034 /*******************************************************************************
1035 **
1036 ** Function RW_T1tWriteNoErase8
1037 **
1038 ** Description This function sends a WRITE-NE8 command for Reader/Writer
1039 ** mode.
1040 **
1041 ** Returns tNFC_STATUS
1042 **
1043 *******************************************************************************/
RW_T1tWriteNoErase8(uint8_t block,uint8_t * p_new_dat)1044 tNFC_STATUS RW_T1tWriteNoErase8(uint8_t block, uint8_t* p_new_dat) {
1045 tNFC_STATUS status = NFC_STATUS_FAILED;
1046 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1047
1048 if (p_t1t->state != RW_T1T_STATE_IDLE) {
1049 RW_TRACE_WARNING1("RW_T1tWriteNoErase8 - Busy - State: %u", p_t1t->state);
1050 return (NFC_STATUS_BUSY);
1051 }
1052
1053 if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
1054 (block != T1T_CC_BLOCK)) {
1055 RW_TRACE_ERROR0("RW_T1tWriteNoErase8 - Tag is in Read only state");
1056 return (NFC_STATUS_REFUSED);
1057 }
1058
1059 if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
1060 RW_TRACE_WARNING1("RW_T1tWriteNoErase8 - Cannot write to Locked block: %u",
1061 block);
1062 return (NFC_STATUS_REFUSED);
1063 }
1064
1065 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
1066 rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
1067 /* send WRITE-NE command */
1068 status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_NE8, block, p_new_dat);
1069 if (status == NFC_STATUS_OK) {
1070 p_t1t->state = RW_T1T_STATE_WRITE;
1071 if (block < T1T_BLOCKS_PER_SEGMENT) {
1072 p_t1t->b_update = false;
1073 p_t1t->b_rseg = false;
1074 }
1075 }
1076 }
1077 return status;
1078 }
1079
1080 #if (BT_TRACE_VERBOSE == TRUE)
1081 /*******************************************************************************
1082 **
1083 ** Function rw_t1t_get_state_name
1084 **
1085 ** Description This function returns the state name.
1086 **
1087 ** NOTE conditionally compiled to save memory.
1088 **
1089 ** Returns pointer to the name
1090 **
1091 *******************************************************************************/
rw_t1t_get_state_name(uint8_t state)1092 static char* rw_t1t_get_state_name(uint8_t state) {
1093 switch (state) {
1094 case RW_T1T_STATE_IDLE:
1095 return ("IDLE");
1096 case RW_T1T_STATE_NOT_ACTIVATED:
1097 return ("NOT_ACTIVATED");
1098 case RW_T1T_STATE_READ:
1099 return ("APP_READ");
1100 case RW_T1T_STATE_WRITE:
1101 return ("APP_WRITE");
1102 case RW_T1T_STATE_TLV_DETECT:
1103 return ("TLV_DETECTION");
1104 case RW_T1T_STATE_READ_NDEF:
1105 return ("READING_NDEF");
1106 case RW_T1T_STATE_WRITE_NDEF:
1107 return ("WRITING_NDEF");
1108 case RW_T1T_STATE_SET_TAG_RO:
1109 return ("SET_TAG_RO");
1110 case RW_T1T_STATE_CHECK_PRESENCE:
1111 return ("CHECK_PRESENCE");
1112 case RW_T1T_STATE_FORMAT_TAG:
1113 return ("FORMAT_TAG");
1114 default:
1115 return ("???? UNKNOWN STATE");
1116 }
1117 }
1118
1119 #endif /* (BT_TRACE_VERBOSE == TRUE) */
1120