• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the implementation for Type 1 tag in Reader/Writer
22  *  mode.
23  *
24  ******************************************************************************/
25 #include <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