• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2013 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             &&(p_data->data.status == NFC_STATUS_OK)  )
259         {
260             rw_t1t_data_cback (conn_id, event, p_data);
261             break;
262         }
263         /* Data event with error status...fall through to NFC_ERROR_CEVT case */
264 
265     case NFC_ERROR_CEVT:
266         if (  (p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED)
267             ||(p_t1t->state == RW_T1T_STATE_IDLE)  )
268         {
269 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
270             rw_main_update_trans_error_stats ();
271 #endif  /* RW_STATS_INCLUDED */
272 
273             if (event == NFC_ERROR_CEVT)
274                 evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
275             else if (p_data)
276                 evt_data.status = p_data->status;
277             else
278                 evt_data.status = NFC_STATUS_FAILED;
279 
280             evt_data.p_data = NULL;
281             (*rw_cb.p_cback) (RW_T1T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data);
282             break;
283         }
284         nfc_stop_quick_timer (&p_t1t->timer);
285 
286 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
287         rw_main_update_trans_error_stats ();
288 #endif  /* RW_STATS_INCLUDED */
289 
290         if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
291         {
292             rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
293         }
294         else
295         {
296             rw_t1t_process_error ();
297         }
298         break;
299 
300     default:
301         break;
302 
303     }
304 }
305 
306 /*******************************************************************************
307 **
308 ** Function         rw_t1t_send_static_cmd
309 **
310 ** Description      This function composes a Type 1 Tag command for static
311 **                  memory and send through NCI to NFCC.
312 **
313 ** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
314 **                  otherwise, error status
315 **
316 *******************************************************************************/
rw_t1t_send_static_cmd(UINT8 opcode,UINT8 add,UINT8 dat)317 tNFC_STATUS rw_t1t_send_static_cmd (UINT8 opcode, UINT8 add, UINT8 dat)
318 {
319     tNFC_STATUS             status  = NFC_STATUS_FAILED;
320     tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
321     const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
322     BT_HDR                  *p_data;
323     UINT8                   *p;
324 
325     if (p_cmd_rsp_info)
326     {
327         /* a valid opcode for RW */
328         p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
329         if (p_data)
330         {
331             p_t1t->p_cmd_rsp_info   = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
332             p_t1t->addr             = add;
333             p_data->offset          = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
334             p                       = (UINT8 *) (p_data + 1) + p_data->offset;
335             UINT8_TO_BE_STREAM (p, opcode);
336             UINT8_TO_BE_STREAM (p, add);
337             UINT8_TO_BE_STREAM (p, dat);
338 
339             ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
340             p_data->len     = p_cmd_rsp_info->cmd_len;
341 
342             /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
343             rw_cb.cur_retry = 0;
344             memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
345 
346 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
347             /* Update stats */
348             rw_main_update_tx_stats (p_data->len, FALSE);
349 #endif  /* RW_STATS_INCLUDED */
350 
351             RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
352             if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
353             {
354                 nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
355                        (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
356             }
357         }
358         else
359         {
360             status = NFC_STATUS_NO_BUFFERS;
361         }
362     }
363     return status;
364 }
365 
366 /*******************************************************************************
367 **
368 ** Function         rw_t1t_send_dyn_cmd
369 **
370 ** Description      This function composes a Type 1 Tag command for dynamic memory
371 **                  and send through NCI to NFCC.
372 **
373 ** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
374 **                  otherwise, error status
375 **
376 *******************************************************************************/
rw_t1t_send_dyn_cmd(UINT8 opcode,UINT8 add,UINT8 * p_dat)377 tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat)
378 {
379     tNFC_STATUS             status  = NFC_STATUS_FAILED;
380     tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
381     const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
382     BT_HDR                  *p_data;
383     UINT8                   *p;
384 
385     if (p_cmd_rsp_info)
386     {
387         /* a valid opcode for RW */
388         p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
389         if (p_data)
390         {
391             p_t1t->p_cmd_rsp_info   = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
392             p_t1t->addr             = add;
393             p_data->offset          = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
394             p                       = (UINT8 *) (p_data + 1) + p_data->offset;
395             UINT8_TO_BE_STREAM (p, opcode);
396             UINT8_TO_BE_STREAM (p, add);
397 
398             if (p_dat)
399             {
400                 ARRAY_TO_STREAM (p, p_dat, 8);
401             }
402             else
403             {
404                 memset (p, 0, 8);
405                 p += 8;
406             }
407             ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
408             p_data->len     = p_cmd_rsp_info->cmd_len;
409 
410             /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
411             rw_cb.cur_retry = 0;
412             memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
413 
414 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
415             /* Update stats */
416             rw_main_update_tx_stats (p_data->len, FALSE);
417 #endif  /* RW_STATS_INCLUDED */
418 
419             RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
420 
421             if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
422             {
423                 nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
424                        (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
425             }
426         }
427         else
428         {
429             status = NFC_STATUS_NO_BUFFERS;
430         }
431     }
432     return status;
433 }
434 
435 /*****************************************************************************
436 **
437 ** Function         rw_t1t_handle_rid_rsp
438 **
439 ** Description      Handles response to RID: Collects HR, UID, notify up the
440 **                  stack
441 **
442 ** Returns          event to notify application
443 **
444 *****************************************************************************/
rw_t1t_handle_rid_rsp(BT_HDR * p_pkt)445 static tRW_EVENT rw_t1t_handle_rid_rsp (BT_HDR *p_pkt)
446 {
447     tRW_T1T_CB  *p_t1t   = &rw_cb.tcb.t1t;
448     tRW_DATA    evt_data;
449     UINT8       *p_rid_rsp;
450 
451     evt_data.status      = NFC_STATUS_OK;
452     evt_data.data.p_data = p_pkt;
453 
454     /* Assume the data is just the response byte sequence */
455     p_rid_rsp = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
456 
457     /* Response indicates tag is present */
458     if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
459     {
460         /* If checking for the presence of the tag then just notify */
461         return RW_T1T_PRESENCE_CHECK_EVT;
462     }
463 
464     /* Extract HR and UID from response */
465     STREAM_TO_ARRAY (p_t1t->hr,  p_rid_rsp, T1T_HR_LEN);
466 
467 #if (BT_TRACE_VERBOSE == TRUE)
468     RW_TRACE_DEBUG2 ("hr0:0x%x, hr1:0x%x", p_t1t->hr[0], p_t1t->hr[1]);
469     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]);
470 #else
471     RW_TRACE_DEBUG0 ("rw_t1t_handle_rid_rsp ()");
472 #endif
473 
474     /* Fetch UID0-3 from RID response message */
475     STREAM_TO_ARRAY (p_t1t->mem,  p_rid_rsp, T1T_CMD_UID_LEN);
476 
477     /* Notify RID response Event */
478     return RW_T1T_RID_EVT;
479 }
480 
481 /*******************************************************************************
482 **
483 ** Function         rw_t1t_select
484 **
485 ** Description      This function will set the callback function to
486 **                  receive data from lower layers and also send rid command
487 **
488 ** Returns          none
489 **
490 *******************************************************************************/
rw_t1t_select(UINT8 hr[T1T_HR_LEN],UINT8 uid[T1T_CMD_UID_LEN])491 tNFC_STATUS rw_t1t_select (UINT8 hr[T1T_HR_LEN], UINT8 uid[T1T_CMD_UID_LEN])
492 {
493     tNFC_STATUS status  = NFC_STATUS_FAILED;
494     tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
495 
496     p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
497 
498     /* Alloc cmd buf for retransmissions */
499     if (p_t1t->p_cur_cmd_buf ==  NULL)
500     {
501         if ((p_t1t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
502         {
503             RW_TRACE_ERROR0 ("rw_t1t_select: unable to allocate buffer for retransmission");
504             return status;
505         }
506     }
507 
508     memcpy (p_t1t->hr, hr, T1T_HR_LEN);
509     memcpy (p_t1t->mem, uid, T1T_CMD_UID_LEN);
510 
511     NFC_SetStaticRfCback (rw_t1t_conn_cback);
512 
513     p_t1t->state    = RW_T1T_STATE_IDLE;
514 
515     return NFC_STATUS_OK;
516 }
517 
518 /*******************************************************************************
519 **
520 ** Function         rw_t1t_process_timeout
521 **
522 ** Description      process timeout event
523 **
524 ** Returns          none
525 **
526 *******************************************************************************/
rw_t1t_process_timeout(TIMER_LIST_ENT * p_tle)527 void rw_t1t_process_timeout (TIMER_LIST_ENT *p_tle)
528 {
529     tRW_T1T_CB        *p_t1t  = &rw_cb.tcb.t1t;
530 
531 #if (BT_TRACE_VERBOSE == TRUE)
532     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);
533 #else
534     RW_TRACE_ERROR2 ("T1T timeout. state=0x%02x command=0x%02x ", p_t1t->state, (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
535 #endif
536 
537     if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
538     {
539         /* Tag has moved from range */
540         rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
541     }
542     else if (p_t1t->state != RW_T1T_STATE_IDLE)
543     {
544         rw_t1t_process_error ();
545     }
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 {
560 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
561     /* Update stats */
562     rw_main_update_crc_error_stats ();
563 #endif  /* RW_STATS_INCLUDED */
564 
565     /* Process the error */
566     rw_t1t_process_error ();
567 }
568 
569 /*******************************************************************************
570 **
571 ** Function         rw_t1t_process_error
572 **
573 ** Description      process timeout event
574 **
575 ** Returns          none
576 **
577 *******************************************************************************/
rw_t1t_process_error(void)578 static void rw_t1t_process_error (void)
579 {
580     tRW_READ_DATA           evt_data;
581     tRW_EVENT               rw_event;
582     BT_HDR                  *p_cmd_buf;
583     tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
584     tT1T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
585     tRW_DETECT_NDEF_DATA    ndef_data;
586 
587     RW_TRACE_DEBUG1 ("rw_t1t_process_error () State: %u", p_t1t->state);
588 
589     /* Retry sending command if retry-count < max */
590     if (rw_cb.cur_retry < RW_MAX_RETRIES)
591     {
592         /* retry sending the command */
593         rw_cb.cur_retry++;
594 
595         RW_TRACE_DEBUG2 ("T1T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
596 
597         /* allocate a new buffer for message */
598         if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
599         {
600             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);
601 
602 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
603             /* Update stats */
604             rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
605 #endif  /* RW_STATS_INCLUDED */
606 
607             if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
608             {
609                 /* Start timer for waiting for response */
610                 nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
611                                        (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC)/1000);
612 
613                 return;
614             }
615         }
616     }
617     else
618     {
619     /* we might get response later to all or some of the retrasnmission
620      * of the current command, update previous command response information */
621         RW_TRACE_DEBUG1 ("T1T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
622         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;
623         p_t1t->prev_cmd_rsp_info.rsp_len       = p_cmd_rsp_info->rsp_len;
624         p_t1t->prev_cmd_rsp_info.op_code       = p_cmd_rsp_info->opcode;
625         p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
626     }
627 
628 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
629     /* update failure count */
630     rw_main_update_fail_stats ();
631 #endif  /* RW_STATS_INCLUDED */
632 
633     rw_event        = rw_t1t_info_to_event (p_cmd_rsp_info);
634     if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED)
635         rw_t1t_handle_op_complete ();
636 
637     evt_data.status = NFC_STATUS_TIMEOUT;
638     if (rw_event == RW_T2T_NDEF_DETECT_EVT)
639     {
640         ndef_data.status    = evt_data.status;
641         ndef_data.protocol  = NFC_PROTOCOL_T1T;
642         ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
643         ndef_data.max_size  = 0;
644         ndef_data.cur_size  = 0;
645         (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
646     }
647     else
648     {
649         evt_data.p_data = NULL;
650         (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
651     }
652 }
653 
654 /*****************************************************************************
655 **
656 ** Function         rw_t1t_handle_presence_check_rsp
657 **
658 ** Description      Handle response to presence check
659 **
660 ** Returns          Nothing
661 **
662 *****************************************************************************/
rw_t1t_handle_presence_check_rsp(tNFC_STATUS status)663 void rw_t1t_handle_presence_check_rsp (tNFC_STATUS status)
664 {
665     tRW_READ_DATA   evt_data;
666 
667     /* Notify, Tag is present or not */
668     evt_data.status = status;
669     rw_t1t_handle_op_complete ();
670 
671     (*(rw_cb.p_cback)) (RW_T1T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
672 }
673 
674 /*****************************************************************************
675 **
676 ** Function         rw_t1t_handle_op_complete
677 **
678 ** Description      Reset to IDLE state
679 **
680 ** Returns          Nothing
681 **
682 *****************************************************************************/
rw_t1t_handle_op_complete(void)683 void rw_t1t_handle_op_complete (void)
684 {
685     tRW_T1T_CB      *p_t1t  = &rw_cb.tcb.t1t;
686 
687     p_t1t->state    = RW_T1T_STATE_IDLE;
688 #if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
689     if (p_t1t->state != RW_T1T_STATE_READ_NDEF)
690     {
691         p_t1t->b_update = FALSE;
692         p_t1t->b_rseg   = FALSE;
693     }
694     p_t1t->substate = RW_T1T_SUBSTATE_NONE;
695 #endif
696     return;
697 }
698 
699 /*****************************************************************************
700 **
701 ** Function         RW_T1tPresenceCheck
702 **
703 ** Description
704 **      Check if the tag is still in the field.
705 **
706 **      The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
707 **      or non-presence.
708 **
709 ** Returns
710 **      NFC_STATUS_OK, if raw data frame sent
711 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
712 **      NFC_STATUS_FAILED: other error
713 **
714 *****************************************************************************/
RW_T1tPresenceCheck(void)715 tNFC_STATUS RW_T1tPresenceCheck (void)
716 {
717     tNFC_STATUS retval = NFC_STATUS_OK;
718     tRW_DATA evt_data;
719     tRW_CB *p_rw_cb = &rw_cb;
720 
721     RW_TRACE_API0 ("RW_T1tPresenceCheck");
722 
723     /* If RW_SelectTagType was not called (no conn_callback) return failure */
724     if (!p_rw_cb->p_cback)
725     {
726         retval = NFC_STATUS_FAILED;
727     }
728     /* If we are not activated, then RW_T1T_PRESENCE_CHECK_EVT status=FAIL */
729     else if (p_rw_cb->tcb.t1t.state == RW_T1T_STATE_NOT_ACTIVATED)
730     {
731         evt_data.status = NFC_STATUS_FAILED;
732         (*p_rw_cb->p_cback) (RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
733     }
734     /* If command is pending, assume tag is still present */
735     else if (p_rw_cb->tcb.t1t.state != RW_T1T_STATE_IDLE)
736     {
737         evt_data.status = NFC_STATUS_OK;
738         (*p_rw_cb->p_cback) (RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
739     }
740     else
741     {
742         /* IDLE state: send a RID command to the tag to see if it responds */
743         if((retval = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
744         {
745             p_rw_cb->tcb.t1t.state = RW_T1T_STATE_CHECK_PRESENCE;
746         }
747     }
748 
749     return (retval);
750 }
751 
752 /*****************************************************************************
753 **
754 ** Function         RW_T1tRid
755 **
756 ** Description
757 **      This function sends a RID command for Reader/Writer mode.
758 **
759 ** Returns
760 **      NFC_STATUS_OK, if raw data frame sent
761 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
762 **      NFC_STATUS_FAILED: other error
763 **
764 *****************************************************************************/
RW_T1tRid(void)765 tNFC_STATUS RW_T1tRid (void)
766 {
767     tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
768     tNFC_STATUS status  = NFC_STATUS_FAILED;
769 
770     RW_TRACE_API0 ("RW_T1tRid");
771 
772     if (p_t1t->state != RW_T1T_STATE_IDLE)
773     {
774         RW_TRACE_WARNING1 ("RW_T1tRid - Busy - State: %u", p_t1t->state);
775         return (NFC_STATUS_BUSY);
776     }
777 
778     /* send a RID command */
779     if((status = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
780     {
781         p_t1t->state = RW_T1T_STATE_READ;
782     }
783 
784     return (status);
785 }
786 
787 /*******************************************************************************
788 **
789 ** Function         RW_T1tReadAll
790 **
791 ** Description      This function sends a RALL command for Reader/Writer mode.
792 **
793 ** Returns          tNFC_STATUS
794 **
795 *******************************************************************************/
RW_T1tReadAll(void)796 tNFC_STATUS RW_T1tReadAll (void)
797 {
798     tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
799     tNFC_STATUS status  = NFC_STATUS_FAILED;
800 
801     RW_TRACE_API0 ("RW_T1tReadAll");
802 
803     if (p_t1t->state != RW_T1T_STATE_IDLE)
804     {
805         RW_TRACE_WARNING1 ("RW_T1tReadAll - Busy - State: %u", p_t1t->state);
806         return (NFC_STATUS_BUSY);
807     }
808 
809     /* send RALL command */
810     if ((status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0)) == NFC_STATUS_OK)
811     {
812         p_t1t->state = RW_T1T_STATE_READ;
813     }
814 
815     return status;
816 }
817 
818 /*******************************************************************************
819 **
820 ** Function         RW_T1tRead
821 **
822 ** Description      This function sends a READ command for Reader/Writer mode.
823 **
824 ** Returns          tNFC_STATUS
825 **
826 *******************************************************************************/
RW_T1tRead(UINT8 block,UINT8 byte)827 tNFC_STATUS RW_T1tRead (UINT8 block, UINT8 byte)
828 {
829     tNFC_STATUS status  = NFC_STATUS_FAILED;
830     tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
831     UINT8       addr;
832 
833     if (p_t1t->state != RW_T1T_STATE_IDLE)
834     {
835         RW_TRACE_WARNING1 ("RW_T1tRead - Busy - State: %u", p_t1t->state);
836         return (NFC_STATUS_BUSY);
837     }
838 
839     /* send READ command */
840     RW_T1T_BLD_ADD ((addr), (block), (byte));
841     if ((status = rw_t1t_send_static_cmd (T1T_CMD_READ, addr, 0)) == NFC_STATUS_OK)
842     {
843         p_t1t->state = RW_T1T_STATE_READ;
844     }
845     return status;
846 }
847 
848 /*******************************************************************************
849 **
850 ** Function         RW_T1tWriteErase
851 **
852 ** Description      This function sends a WRITE-E command for Reader/Writer mode.
853 **
854 ** Returns          tNFC_STATUS
855 **
856 *******************************************************************************/
RW_T1tWriteErase(UINT8 block,UINT8 byte,UINT8 new_byte)857 tNFC_STATUS RW_T1tWriteErase (UINT8 block, UINT8 byte, UINT8 new_byte)
858 {
859     tNFC_STATUS status  = NFC_STATUS_FAILED;
860     tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
861     UINT8       addr;
862 
863     if (p_t1t->state != RW_T1T_STATE_IDLE)
864     {
865         RW_TRACE_WARNING1 ("RW_T1tWriteErase - Busy - State: %u", p_t1t->state);
866         return (NFC_STATUS_BUSY);
867     }
868     if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
869         &&(block != T1T_CC_BLOCK)
870         &&(byte  != T1T_CC_RWA_OFFSET)  )
871     {
872         RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
873         return (NFC_STATUS_REFUSED);
874     }
875     if (  (block >= T1T_STATIC_BLOCKS)
876         ||(byte  >= T1T_BLOCK_SIZE   )  )
877     {
878         RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
879         return (NFC_STATUS_REFUSED);
880     }
881     if(  (block == T1T_UID_BLOCK)
882        ||(block == T1T_RES_BLOCK)  )
883     {
884         RW_TRACE_WARNING1 ("RW_T1tWriteErase - Cannot write to Locked block: %u", block);
885         return (NFC_STATUS_REFUSED);
886     }
887     /* send WRITE-E command */
888     RW_T1T_BLD_ADD ((addr), (block), (byte));
889     if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, new_byte)) == NFC_STATUS_OK)
890     {
891         p_t1t->state = RW_T1T_STATE_WRITE;
892         if (block < T1T_BLOCKS_PER_SEGMENT)
893         {
894             p_t1t->b_update = FALSE;
895             p_t1t->b_rseg   = FALSE;
896         }
897     }
898     return status;
899 }
900 
901 /*******************************************************************************
902 **
903 ** Function         RW_T1tWriteNoErase
904 **
905 ** Description      This function sends a WRITE-NE command for Reader/Writer mode.
906 **
907 ** Returns          tNFC_STATUS
908 **
909 *******************************************************************************/
RW_T1tWriteNoErase(UINT8 block,UINT8 byte,UINT8 new_byte)910 tNFC_STATUS RW_T1tWriteNoErase (UINT8 block, UINT8 byte, UINT8 new_byte)
911 {
912     tNFC_STATUS status  = NFC_STATUS_FAILED;
913     tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
914     UINT8       addr;
915 
916     if (p_t1t->state != RW_T1T_STATE_IDLE)
917     {
918         RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Busy - State: %u", p_t1t->state);
919         return (NFC_STATUS_BUSY);
920     }
921     if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
922         &&(block != T1T_CC_BLOCK)
923         &&(byte  != T1T_CC_RWA_OFFSET)  )
924     {
925         RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
926         return (NFC_STATUS_REFUSED);
927     }
928     if (  (block >= T1T_STATIC_BLOCKS)
929         ||(byte  >= T1T_BLOCK_SIZE   )  )
930     {
931         RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
932         return (NFC_STATUS_REFUSED);
933     }
934     if(  (block == T1T_UID_BLOCK)
935        ||(block == T1T_RES_BLOCK)  )
936     {
937         RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Cannot write to Locked block: %u", block);
938         return (NFC_STATUS_REFUSED);
939     }
940     /* send WRITE-NE command */
941     RW_T1T_BLD_ADD ((addr), (block), (byte));
942     if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, new_byte)) == NFC_STATUS_OK)
943     {
944         p_t1t->state = RW_T1T_STATE_WRITE;
945         if (block < T1T_BLOCKS_PER_SEGMENT)
946         {
947             p_t1t->b_update = FALSE;
948             p_t1t->b_rseg   = FALSE;
949         }
950     }
951     return status;
952 }
953 
954 /*******************************************************************************
955 **
956 ** Function         RW_T1tReadSeg
957 **
958 ** Description      This function sends a RSEG command for Reader/Writer mode.
959 **
960 ** Returns          tNFC_STATUS
961 **
962 *******************************************************************************/
RW_T1tReadSeg(UINT8 segment)963 tNFC_STATUS RW_T1tReadSeg (UINT8 segment)
964 {
965     tNFC_STATUS status  = NFC_STATUS_FAILED;
966     tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
967     UINT8       adds;
968 
969     if (p_t1t->state != RW_T1T_STATE_IDLE)
970     {
971         RW_TRACE_WARNING1 ("RW_T1tReadSeg - Busy - State: %u", p_t1t->state);
972         return (NFC_STATUS_BUSY);
973     }
974     if (segment >=  T1T_MAX_SEGMENTS)
975     {
976         RW_TRACE_ERROR1 ("RW_T1tReadSeg - Invalid Segment: %u", segment);
977         return (NFC_STATUS_REFUSED);
978     }
979     if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0)
980     {
981         /* send RSEG command */
982         RW_T1T_BLD_ADDS ((adds), (segment));
983         if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
984         {
985             p_t1t->state = RW_T1T_STATE_READ;
986         }
987     }
988     return status;
989 }
990 
991 /*******************************************************************************
992 **
993 ** Function         RW_T1tRead8
994 **
995 ** Description      This function sends a READ8 command for Reader/Writer mode.
996 **
997 ** Returns          tNFC_STATUS
998 **
999 *******************************************************************************/
RW_T1tRead8(UINT8 block)1000 tNFC_STATUS RW_T1tRead8 (UINT8 block)
1001 {
1002     tNFC_STATUS status = NFC_STATUS_FAILED;
1003     tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
1004 
1005     if (p_t1t->state != RW_T1T_STATE_IDLE)
1006     {
1007         RW_TRACE_WARNING1 ("RW_T1tRead8 - Busy - State: %u", p_t1t->state);
1008         return (NFC_STATUS_BUSY);
1009     }
1010 
1011     if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
1012     {
1013         /* send READ8 command */
1014         if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, block, NULL)) == NFC_STATUS_OK)
1015         {
1016             p_t1t->state = RW_T1T_STATE_READ;
1017         }
1018     }
1019     return status;
1020 }
1021 
1022 /*******************************************************************************
1023 **
1024 ** Function         RW_T1tWriteErase8
1025 **
1026 ** Description      This function sends a WRITE-E8 command for Reader/Writer mode.
1027 **
1028 ** Returns          tNFC_STATUS
1029 **
1030 *******************************************************************************/
RW_T1tWriteErase8(UINT8 block,UINT8 * p_new_dat)1031 tNFC_STATUS RW_T1tWriteErase8 (UINT8 block, UINT8 *p_new_dat)
1032 {
1033     tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
1034     tNFC_STATUS status = NFC_STATUS_FAILED;
1035 
1036     if (p_t1t->state != RW_T1T_STATE_IDLE)
1037     {
1038         RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Busy - State: %u", p_t1t->state);
1039         return (NFC_STATUS_BUSY);
1040     }
1041 
1042     if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
1043         &&(block != T1T_CC_BLOCK)  )
1044     {
1045         RW_TRACE_ERROR0 ("RW_T1tWriteErase8 - Tag is in Read only state");
1046         return (NFC_STATUS_REFUSED);
1047     }
1048 
1049     if(  (block == T1T_UID_BLOCK)
1050        ||(block == T1T_RES_BLOCK)  )
1051     {
1052         RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Cannot write to Locked block: %u", block);
1053         return (NFC_STATUS_REFUSED);
1054     }
1055 
1056     if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
1057     {
1058         /* send WRITE-E8 command */
1059         if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_new_dat)) == NFC_STATUS_OK)
1060         {
1061             p_t1t->state = RW_T1T_STATE_WRITE;
1062             if (block < T1T_BLOCKS_PER_SEGMENT)
1063             {
1064                 p_t1t->b_update = FALSE;
1065                 p_t1t->b_rseg   = FALSE;
1066             }
1067         }
1068     }
1069     return status;
1070 }
1071 
1072 /*******************************************************************************
1073 **
1074 ** Function         RW_T1tWriteNoErase8
1075 **
1076 ** Description      This function sends a WRITE-NE8 command for Reader/Writer mode.
1077 **
1078 ** Returns          tNFC_STATUS
1079 **
1080 *******************************************************************************/
RW_T1tWriteNoErase8(UINT8 block,UINT8 * p_new_dat)1081 tNFC_STATUS RW_T1tWriteNoErase8 (UINT8 block, UINT8 *p_new_dat)
1082 {
1083     tNFC_STATUS status = NFC_STATUS_FAILED;
1084     tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
1085 
1086     if (p_t1t->state != RW_T1T_STATE_IDLE)
1087     {
1088         RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Busy - State: %u", p_t1t->state);
1089         return (NFC_STATUS_BUSY);
1090     }
1091 
1092     if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
1093         &&(block != T1T_CC_BLOCK)  )
1094     {
1095         RW_TRACE_ERROR0 ("RW_T1tWriteNoErase8 - Tag is in Read only state");
1096         return (NFC_STATUS_REFUSED);
1097     }
1098 
1099     if(  (block == T1T_UID_BLOCK)
1100        ||(block == T1T_RES_BLOCK)  )
1101     {
1102         RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Cannot write to Locked block: %u", block);
1103         return (NFC_STATUS_REFUSED);
1104     }
1105 
1106     if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
1107     {
1108         /* send WRITE-NE command */
1109         if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, block, p_new_dat)) == NFC_STATUS_OK)
1110         {
1111             p_t1t->state    = RW_T1T_STATE_WRITE;
1112             if (block < T1T_BLOCKS_PER_SEGMENT)
1113             {
1114                 p_t1t->b_update = FALSE;
1115                 p_t1t->b_rseg   = FALSE;
1116             }
1117         }
1118     }
1119     return status;
1120 }
1121 
1122 #if (BT_TRACE_VERBOSE == TRUE)
1123 /*******************************************************************************
1124 **
1125 ** Function         rw_t1t_get_state_name
1126 **
1127 ** Description      This function returns the state name.
1128 **
1129 ** NOTE             conditionally compiled to save memory.
1130 **
1131 ** Returns          pointer to the name
1132 **
1133 *******************************************************************************/
rw_t1t_get_state_name(UINT8 state)1134 static char *rw_t1t_get_state_name (UINT8 state)
1135 {
1136     switch (state)
1137     {
1138     case RW_T1T_STATE_IDLE:
1139         return ("IDLE");
1140     case RW_T1T_STATE_NOT_ACTIVATED:
1141         return ("NOT_ACTIVATED");
1142     case RW_T1T_STATE_READ:
1143         return ("APP_READ");
1144     case RW_T1T_STATE_WRITE:
1145         return ("APP_WRITE");
1146     case RW_T1T_STATE_TLV_DETECT:
1147         return ("TLV_DETECTION");
1148     case RW_T1T_STATE_READ_NDEF:
1149         return ("READING_NDEF");
1150     case RW_T1T_STATE_WRITE_NDEF:
1151         return ("WRITING_NDEF");
1152     case RW_T1T_STATE_SET_TAG_RO:
1153         return ("SET_TAG_RO");
1154     case RW_T1T_STATE_CHECK_PRESENCE:
1155         return ("CHECK_PRESENCE");
1156     case RW_T1T_STATE_FORMAT_TAG:
1157         return ("FORMAT_TAG");
1158     default:
1159         return ("???? UNKNOWN STATE");
1160     }
1161 }
1162 
1163 #endif /* (BT_TRACE_VERBOSE == TRUE) */
1164 
1165 #endif /* (NFC_INCLUDED == TRUE) */
1166