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