• 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 action functions the NFA_RW state machine.
23  *
24  ******************************************************************************/
25 #include <string.h>
26 #include "nfa_rw_int.h"
27 #include "nfa_dm_int.h"
28 #include "nfa_sys_int.h"
29 #include "nfa_mem_co.h"
30 #include "ndef_utils.h"
31 #include "rw_api.h"
32 
33 /* Local static function prototypes */
34 static tNFC_STATUS nfa_rw_start_ndef_read(void);
35 static tNFC_STATUS nfa_rw_start_ndef_write(void);
36 static tNFC_STATUS nfa_rw_start_ndef_detection(void);
37 static tNFC_STATUS nfa_rw_config_tag_ro(BOOLEAN b_hard_lock);
38 static BOOLEAN     nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data);
39 static void        nfa_rw_error_cleanup (UINT8 event);
40 static void        nfa_rw_presence_check (tNFA_RW_MSG *p_data);
41 static void        nfa_rw_handle_t2t_evt (tRW_EVENT event, tRW_DATA *p_rw_data);
42 static BOOLEAN     nfa_rw_detect_ndef(tNFA_RW_MSG *p_data);
43 static void        nfa_rw_cback (tRW_EVENT event, tRW_DATA *p_rw_data);
44 
45 /*******************************************************************************
46 **
47 ** Function         nfa_rw_free_ndef_rx_buf
48 **
49 ** Description      Free buffer allocated to hold incoming NDEF message
50 **
51 ** Returns          Nothing
52 **
53 *******************************************************************************/
nfa_rw_free_ndef_rx_buf(void)54 void nfa_rw_free_ndef_rx_buf(void)
55 {
56     if (nfa_rw_cb.p_ndef_buf)
57     {
58         nfa_mem_co_free(nfa_rw_cb.p_ndef_buf);
59         nfa_rw_cb.p_ndef_buf = NULL;
60     }
61 }
62 
63 /*******************************************************************************
64 **
65 ** Function         nfa_rw_store_ndef_rx_buf
66 **
67 ** Description      Store data into NDEF buffer
68 **
69 ** Returns          Nothing
70 **
71 *******************************************************************************/
nfa_rw_store_ndef_rx_buf(tRW_DATA * p_rw_data)72 static void nfa_rw_store_ndef_rx_buf (tRW_DATA *p_rw_data)
73 {
74     UINT8      *p;
75 
76     p = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
77 
78     /* Save data into buffer */
79     memcpy(&nfa_rw_cb.p_ndef_buf[nfa_rw_cb.ndef_rd_offset], p, p_rw_data->data.p_data->len);
80     nfa_rw_cb.ndef_rd_offset += p_rw_data->data.p_data->len;
81 
82     GKI_freebuf(p_rw_data->data.p_data);
83     p_rw_data->data.p_data = NULL;
84 }
85 
86 /*******************************************************************************
87 **
88 ** Function         nfa_rw_send_data_to_upper
89 **
90 ** Description      Send data to upper layer
91 **
92 ** Returns          Nothing
93 **
94 *******************************************************************************/
nfa_rw_send_data_to_upper(tRW_DATA * p_rw_data)95 static void nfa_rw_send_data_to_upper (tRW_DATA *p_rw_data)
96 {
97     tNFA_CONN_EVT_DATA conn_evt_data;
98 
99     if (  (p_rw_data->status == NFC_STATUS_TIMEOUT)
100         ||(p_rw_data->data.p_data == NULL) )
101         return;
102 
103     /* Notify conn cback of NFA_DATA_EVT */
104     conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
105     conn_evt_data.data.len    = p_rw_data->data.p_data->len;
106 
107     nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
108 
109     GKI_freebuf(p_rw_data->data.p_data);
110     p_rw_data->data.p_data = NULL;
111 }
112 
113 /*******************************************************************************
114 **
115 ** Function         nfa_rw_error_cleanup
116 **
117 ** Description      Handle failure - signal command complete and notify app
118 **
119 ** Returns          Nothing
120 **
121 *******************************************************************************/
nfa_rw_error_cleanup(UINT8 event)122 static void nfa_rw_error_cleanup (UINT8 event)
123 {
124     tNFA_CONN_EVT_DATA conn_evt_data;
125 
126     nfa_rw_command_complete();
127 
128     conn_evt_data.status = NFA_STATUS_FAILED;
129 
130     nfa_dm_act_conn_cback_notify (event, &conn_evt_data);
131 }
132 
133 /*******************************************************************************
134 **
135 ** Function         nfa_rw_check_start_presence_check_timer
136 **
137 ** Description      Start timer to wait for specified time before presence check
138 **
139 ** Returns          Nothing
140 **
141 *******************************************************************************/
nfa_rw_check_start_presence_check_timer(UINT16 presence_check_start_delay)142 static void nfa_rw_check_start_presence_check_timer (UINT16 presence_check_start_delay)
143 {
144 #if (defined (NFA_DM_AUTO_PRESENCE_CHECK) && (NFA_DM_AUTO_PRESENCE_CHECK == TRUE))
145     if (nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE)
146     {
147         if (presence_check_start_delay)
148         {
149             NFA_TRACE_DEBUG0("Starting presence check timer...");
150             nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TICK_EVT, presence_check_start_delay);
151         }
152         else
153         {
154             /* Presence check now */
155             nfa_rw_presence_check (NULL);
156         }
157     }
158 #endif   /* NFA_DM_AUTO_PRESENCE_CHECK  */
159 }
160 
161 /*******************************************************************************
162 **
163 ** Function         nfa_rw_stop_presence_check_timer
164 **
165 ** Description      Stop timer for presence check
166 **
167 ** Returns          Nothing
168 **
169 *******************************************************************************/
nfa_rw_stop_presence_check_timer(void)170 void nfa_rw_stop_presence_check_timer(void)
171 {
172     nfa_sys_stop_timer(&nfa_rw_cb.tle);
173     NFA_TRACE_DEBUG0("Stopped presence check timer (if started)");
174 }
175 
176 /*******************************************************************************
177 **
178 ** Function         nfa_rw_handle_ndef_detect
179 **
180 ** Description      Handler for NDEF detection reader/writer event
181 **
182 ** Returns          Nothing
183 **
184 *******************************************************************************/
nfa_rw_handle_ndef_detect(tRW_EVENT event,tRW_DATA * p_rw_data)185 static void nfa_rw_handle_ndef_detect(tRW_EVENT event, tRW_DATA *p_rw_data)
186 {
187     tNFA_CONN_EVT_DATA conn_evt_data;
188 
189     NFA_TRACE_DEBUG3("NDEF Detection completed: cur_size=%i, max_size=%i, flags=0x%x",
190         p_rw_data->ndef.cur_size, p_rw_data->ndef.max_size, p_rw_data->ndef.flags);
191 
192     /* Check if NDEF detection succeeded */
193     if (p_rw_data->ndef.status == NFC_STATUS_OK)
194     {
195         /* Set NDEF detection state */
196         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_TRUE;
197 
198         /* Store ndef properties */
199         conn_evt_data.ndef_detect.status = NFA_STATUS_OK;
200         conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
201         conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
202         conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
203         conn_evt_data.ndef_detect.flags    = p_rw_data->ndef.flags;
204 
205         if (p_rw_data->ndef.flags & RW_NDEF_FL_READ_ONLY)
206             nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
207         else
208             nfa_rw_cb.flags &= ~NFA_RW_FL_TAG_IS_READONLY;
209 
210         /* Determine what operation triggered the NDEF detection procedure */
211         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
212         {
213             /* if ndef detection was done as part of ndef-read operation, then perform ndef read now */
214             if ((conn_evt_data.status = nfa_rw_start_ndef_read()) != NFA_STATUS_OK)
215             {
216                 /* Failed to start NDEF Read */
217 
218                 /* Command complete - perform cleanup, notify app */
219                 nfa_rw_command_complete();
220                 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
221             }
222         }
223         else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
224         {
225             /* if ndef detection was done as part of ndef-write operation, then perform ndef write now */
226             if ((conn_evt_data.status = nfa_rw_start_ndef_write()) != NFA_STATUS_OK)
227             {
228                 /* Failed to start NDEF Write.  */
229 
230                 /* Command complete - perform cleanup, notify app */
231                 nfa_rw_command_complete();
232                 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
233             }
234         }
235         else
236         {
237             /* current op was stand-alone NFA_DetectNDef. Command complete - perform cleanup and notify app */
238             nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
239             nfa_rw_command_complete();
240 
241             nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
242         }
243     }
244     else
245     {
246         /* NDEF detection failed... */
247 
248         /* Command complete - perform cleanup, notify app */
249         nfa_rw_command_complete();
250         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
251 
252         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
253         {
254             /* if ndef detection was done as part of ndef-read operation, then notify NDEF handlers of failure */
255             nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
256 
257             /* Notify app of read status */
258             conn_evt_data.status = NFC_STATUS_FAILED;
259             nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
260         }
261         else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
262         {
263             /* if ndef detection was done as part of ndef-write operation, then notify app of failure */
264             conn_evt_data.status = NFA_STATUS_FAILED;
265             nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
266         }
267         else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF)
268         {
269             conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
270             /* current op was stand-alone NFA_DetectNDef. Notify app of failure */
271             conn_evt_data.ndef_detect.status = NFA_STATUS_FAILED;
272             if (p_rw_data->ndef.status == NFC_STATUS_TIMEOUT)
273             {
274                 /* Tag could have moved away */
275                 conn_evt_data.ndef_detect.cur_size = 0;
276                 conn_evt_data.ndef_detect.max_size = 0;
277                 conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
278             }
279             else
280             {
281                 /* NDEF Detection failed for other reasons */
282                 conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
283                 conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
284                 conn_evt_data.ndef_detect.flags    = p_rw_data->ndef.flags;
285             }
286             nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
287         }
288 
289         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
290     }
291 }
292 
293 /*******************************************************************************
294 **
295 ** Function         nfa_rw_handle_tlv_detect
296 **
297 ** Description      Handler for TLV detection reader/writer event
298 **
299 ** Returns          Nothing
300 **
301 *******************************************************************************/
nfa_rw_handle_tlv_detect(tRW_EVENT event,tRW_DATA * p_rw_data)302 static void nfa_rw_handle_tlv_detect(tRW_EVENT event, tRW_DATA *p_rw_data)
303 {
304     tNFA_CONN_EVT_DATA conn_evt_data;
305 
306     /* Set TLV detection state */
307     if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
308     {
309         if(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED)
310         {
311             nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
312         }
313         else
314         {
315             nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
316         }
317     }
318     else
319     {
320         if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV)
321         {
322             nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
323         }
324         else if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV)
325         {
326             nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE;
327         }
328     }
329 
330     /* Check if TLV detection succeeded */
331     if (p_rw_data->tlv.status == NFC_STATUS_OK)
332     {
333         NFA_TRACE_DEBUG1("TLV Detection succeeded: num_bytes=%i",p_rw_data->tlv.num_bytes);
334 
335         /* Store tlv properties */
336         conn_evt_data.tlv_detect.status     = NFA_STATUS_OK;
337         conn_evt_data.tlv_detect.protocol   = p_rw_data->tlv.protocol;
338         conn_evt_data.tlv_detect.num_bytes  = p_rw_data->tlv.num_bytes;
339 
340 
341         /* Determine what operation triggered the TLV detection procedure */
342         if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
343         {
344             if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK)
345             {
346                 /* Failed to set tag read only */
347                 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
348                 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
349             }
350         }
351         else
352         {
353             /* current op was stand-alone NFA_DetectTlv. Command complete - perform cleanup and notify app */
354             nfa_rw_command_complete();
355             nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
356         }
357     }
358 
359     /* Handle failures */
360     if (p_rw_data->tlv.status != NFC_STATUS_OK)
361     {
362         /* Command complete - perform cleanup, notify the app */
363         nfa_rw_command_complete();
364 
365         conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
366         if(  (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV)
367            ||(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) )
368         {
369             nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
370         }
371         else if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
372         {
373             if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK)
374             {
375                 /* Failed to set tag read only */
376                 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
377                 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
378             }
379         }
380     }
381 }
382 
383 /*******************************************************************************
384 **
385 ** Function         nfa_rw_handle_sleep_wakeup_rsp
386 **
387 ** Description      Handl sleep wakeup
388 **
389 ** Returns          Nothing
390 **
391 *******************************************************************************/
nfa_rw_handle_sleep_wakeup_rsp(tNFC_STATUS status)392 void nfa_rw_handle_sleep_wakeup_rsp (tNFC_STATUS status)
393 {
394     tNFC_ACTIVATE_DEVT activate_params;
395     tRW_EVENT event;
396 
397     if (nfa_rw_cb.halt_event != RW_T2T_MAX_EVT)
398     {
399         NFA_TRACE_DEBUG0("nfa_rw_handle_sleep_wakeup_rsp; Attempt to woke up tag from HALT State is complete");
400         /* Tag is wakeup from HALT state */
401         if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED)
402         {
403             NFA_TRACE_DEBUG0("nfa_rw_handle_sleep_wakeup_rsp; Handle the NACK rsp received now");
404             /* Initialize control block */
405             activate_params.protocol                        = nfa_rw_cb.protocol;
406             activate_params.rf_tech_param.param.pa.sel_rsp  = nfa_rw_cb.pa_sel_res;
407             activate_params.rf_tech_param.mode              = nfa_rw_cb.activated_tech_mode;
408 
409             if (  (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A)
410                 &&(nfa_rw_cb.protocol == NFC_PROTOCOL_T2T)
411                 &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)  )
412             {
413                 /* Initialize RW module */
414                 if ((RW_SetActivatedTagType (&activate_params, nfa_rw_cback)) != NFC_STATUS_OK)
415                 {
416                     /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
417                     NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
418                     if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT)
419                     {
420                         if (nfa_rw_cb.rw_data.data.p_data)
421                             GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
422                         nfa_rw_cb.rw_data.data.p_data = NULL;
423                     }
424                     return;
425                 }
426 
427                 nfa_rw_cb.rw_data.status = NFC_STATUS_FAILED;
428                 event = nfa_rw_cb.halt_event;
429 
430                 if (nfa_rw_cb.cur_op == NFA_RW_OP_PRESENCE_CHECK)
431                     nfa_rw_cb.rw_data.status = status;
432 
433                 if ((status == NFA_STATUS_FAILED) && (nfa_rw_cb.halt_event == RW_T2T_NDEF_DETECT_EVT))
434                     nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
435 
436                 nfa_rw_handle_t2t_evt (event, &nfa_rw_cb.rw_data);
437             }
438         }
439         else
440         {
441             NFA_TRACE_DEBUG0("nfa_rw_handle_sleep_wakeup_rsp; Tag is already deactivated, just drop the NACK from tag");
442             if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT)
443             {
444                 if (nfa_rw_cb.rw_data.data.p_data)
445                     GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
446                 nfa_rw_cb.rw_data.data.p_data = NULL;
447             }
448             nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
449             nfa_rw_cb.skip_dyn_locks = FALSE;
450         }
451     }
452     else
453     {
454         NFA_TRACE_DEBUG0("nfa_rw_handle_sleep_wakeup_rsp; Legacy presence check performed");
455         /* Legacy presence check performed */
456         nfa_rw_handle_presence_check_rsp (status);
457     }
458 }
459 
460 /*******************************************************************************
461 **
462 ** Function         nfa_rw_handle_presence_check_rsp
463 **
464 ** Description      Handler RW_T#t_PRESENCE_CHECK_EVT
465 **
466 ** Returns          Nothing
467 **
468 *******************************************************************************/
nfa_rw_handle_presence_check_rsp(tNFC_STATUS status)469 void nfa_rw_handle_presence_check_rsp (tNFC_STATUS status)
470 {
471     BT_HDR *p_pending_msg;
472 
473     if (status == NFA_STATUS_OK)
474     {
475         /* Clear the BUSY flag and restart the presence-check timer */
476         nfa_rw_command_complete();
477     }
478     else
479     {
480         /* If presence check failed just clear the BUSY flag */
481         nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
482     }
483 
484     /* Handle presence check due to auto-presence-check  */
485     if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY)
486     {
487         nfa_rw_cb.flags &= ~NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
488 
489         /* If an API was called during auto-presence-check, then handle it now */
490         if (nfa_rw_cb.p_pending_msg)
491         {
492             /* If NFA_RwPresenceCheck was called during auto-presence-check, notify app of result */
493             if (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_PRESENCE_CHECK)
494             {
495                 /* Notify app of presence check status */
496                 nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status);
497                 GKI_freebuf(nfa_rw_cb.p_pending_msg);
498                 nfa_rw_cb.p_pending_msg = NULL;
499             }
500             /* For all other APIs called during auto-presence check, perform the command now (if tag is still present) */
501             else if (status == NFC_STATUS_OK)
502             {
503                 NFA_TRACE_DEBUG0("Performing deferred operation after presence check...");
504                 p_pending_msg = (BT_HDR *)nfa_rw_cb.p_pending_msg;
505                 nfa_rw_cb.p_pending_msg = NULL;
506                 nfa_rw_handle_event(p_pending_msg);
507                 GKI_freebuf (p_pending_msg);
508             }
509             else
510             {
511                 /* Tag no longer present. Free command for pending API command */
512                 GKI_freebuf(nfa_rw_cb.p_pending_msg);
513                 nfa_rw_cb.p_pending_msg = NULL;
514             }
515         }
516 
517         /* Auto-presence check failed. Deactivate */
518         if (status != NFC_STATUS_OK)
519         {
520             NFA_TRACE_DEBUG0("Auto presence check failed. Deactivating...");
521             nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
522         }
523     }
524     /* Handle presence check due to NFA_RwPresenceCheck API call */
525     else
526     {
527         /* Notify app of presence check status */
528         nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status);
529 
530         /* If in normal mode (not-exclusive RF mode) then deactivate the link if presence check failed */
531         if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) && (status != NFC_STATUS_OK))
532         {
533             NFA_TRACE_DEBUG0("Presence check failed. Deactivating...");
534             nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
535         }
536     }
537 }
538 
539 /*******************************************************************************
540 **
541 ** Function         nfa_rw_handle_t1t_evt
542 **
543 ** Description      Handler for Type-1 tag reader/writer events
544 **
545 ** Returns          Nothing
546 **
547 *******************************************************************************/
nfa_rw_handle_t1t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)548 static void nfa_rw_handle_t1t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
549 {
550     tNFA_CONN_EVT_DATA conn_evt_data;
551 
552     conn_evt_data.status = p_rw_data->data.status;
553     switch (event)
554     {
555     case RW_T1T_RID_EVT:
556     case RW_T1T_RALL_CPLT_EVT:
557     case RW_T1T_READ_CPLT_EVT:
558     case RW_T1T_RSEG_CPLT_EVT:
559     case RW_T1T_READ8_CPLT_EVT:
560         nfa_rw_send_data_to_upper (p_rw_data);
561 
562         /* Command complete - perform cleanup, notify the app */
563         nfa_rw_command_complete();
564         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
565         break;
566 
567     case RW_T1T_WRITE_E_CPLT_EVT:
568     case RW_T1T_WRITE_NE_CPLT_EVT:
569     case RW_T1T_WRITE_E8_CPLT_EVT:
570     case RW_T1T_WRITE_NE8_CPLT_EVT:
571         nfa_rw_send_data_to_upper (p_rw_data);
572 
573         /* Command complete - perform cleanup, notify the app */
574         nfa_rw_command_complete();
575         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
576         break;
577 
578     case RW_T1T_TLV_DETECT_EVT:
579         nfa_rw_handle_tlv_detect(event, p_rw_data);
580         break;
581 
582     case RW_T1T_NDEF_DETECT_EVT:
583         nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
584 
585         if (  (p_rw_data->status != NFC_STATUS_OK)
586             &&(nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
587             &&(p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATABLE) && (!(p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATED)) && (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_SUPPORTED)  )
588         {
589             /* Tag is in Initialized state, Format the tag first and then Write NDEF */
590             if (RW_T1tFormatNDef() == NFC_STATUS_OK)
591                 break;
592         }
593 
594         nfa_rw_handle_ndef_detect(event, p_rw_data);
595 
596         break;
597 
598     case RW_T1T_NDEF_READ_EVT:
599         nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
600         if (p_rw_data->status == NFC_STATUS_OK)
601         {
602             /* Process the ndef record */
603             nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
604         }
605         else
606         {
607             /* Notify app of failure */
608             if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
609             {
610                 /* If current operation is READ_NDEF, then notify ndef handlers of failure */
611                 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
612             }
613         }
614 
615         /* Command complete - perform cleanup, notify the app */
616         nfa_rw_command_complete();
617         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
618 
619         /* Free ndef buffer */
620         nfa_rw_free_ndef_rx_buf();
621         break;
622 
623     case RW_T1T_NDEF_WRITE_EVT:
624         if (p_rw_data->data.status != NFA_STATUS_OK)
625             nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
626         nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
627 
628 
629         /* Command complete - perform cleanup, notify the app */
630         nfa_rw_command_complete();
631 
632         /* Notify app */
633         conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
634         if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
635         {
636             /* Update local cursize of ndef message */
637             nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
638         }
639 
640         /* Notify app of ndef write complete status */
641         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
642         break;
643 
644     case RW_T1T_SET_TAG_RO_EVT:
645         /* Command complete - perform cleanup, notify the app */
646         nfa_rw_command_complete();
647         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
648         break;
649 
650     case RW_T1T_RAW_FRAME_EVT:
651         nfa_rw_send_data_to_upper (p_rw_data);
652 
653         /* Command complete - perform cleanup */
654         nfa_rw_command_complete();
655         break;
656 
657     case RW_T1T_PRESENCE_CHECK_EVT:             /* Presence check completed */
658         nfa_rw_handle_presence_check_rsp(p_rw_data->status);
659         break;
660 
661     case RW_T1T_FORMAT_CPLT_EVT:
662 
663         if (p_rw_data->data.status == NFA_STATUS_OK)
664             nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
665 
666         if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
667         {
668             /* if format operation was done as part of ndef-write operation, now start NDEF Write */
669             if (  (p_rw_data->data.status != NFA_STATUS_OK)
670                 ||((conn_evt_data.status = RW_T1tDetectNDef ()) != NFC_STATUS_OK)  )
671             {
672                 /* Command complete - perform cleanup, notify app */
673                 nfa_rw_command_complete();
674                 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
675 
676 
677                 /* if format operation failed or ndef detection did not start, then notify app of ndef-write operation failure */
678                 conn_evt_data.status = NFA_STATUS_FAILED;
679                 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
680             }
681         }
682         else
683         {
684             /* Command complete - perform cleanup, notify the app */
685             nfa_rw_command_complete();
686             nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
687         }
688         break;
689 
690     case RW_T1T_INTF_ERROR_EVT:
691         nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
692         break;
693     }
694 }
695 
696 /*******************************************************************************
697 **
698 ** Function         nfa_rw_handle_t2t_evt
699 **
700 ** Description      Handler for Type-2 tag reader/writer events
701 **
702 ** Returns          Nothing
703 **
704 *******************************************************************************/
nfa_rw_handle_t2t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)705 static void nfa_rw_handle_t2t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
706 {
707     tNFA_CONN_EVT_DATA conn_evt_data;
708 
709     conn_evt_data.status = p_rw_data->status;
710 
711     if (p_rw_data->status == NFC_STATUS_REJECTED)
712     {
713         NFA_TRACE_DEBUG0("nfa_rw_handle_t2t_evt(); Waking the tag first before handling the response!");
714         /* Received NACK. Let DM wakeup the tag first (by putting tag to sleep and then waking it up) */
715         if ((p_rw_data->status = nfa_dm_disc_sleep_wakeup ()) == NFC_STATUS_OK)
716         {
717             nfa_rw_cb.halt_event    = event;
718             memcpy (&nfa_rw_cb.rw_data, p_rw_data, sizeof (tRW_DATA));
719             return;
720         }
721     }
722 
723     switch (event)
724     {
725     case RW_T2T_READ_CPLT_EVT:              /* Read completed          */
726         nfa_rw_send_data_to_upper (p_rw_data);
727         /* Command complete - perform cleanup, notify the app */
728         nfa_rw_command_complete();
729         nfa_dm_act_conn_cback_notify (NFA_READ_CPLT_EVT, &conn_evt_data);
730         break;
731 
732     case RW_T2T_WRITE_CPLT_EVT:             /* Write completed         */
733         /* Command complete - perform cleanup, notify the app */
734         nfa_rw_command_complete();
735         nfa_dm_act_conn_cback_notify (NFA_WRITE_CPLT_EVT, &conn_evt_data);
736         break;
737 
738     case RW_T2T_SELECT_CPLT_EVT:            /* Sector select completed */
739         /* Command complete - perform cleanup, notify the app */
740         nfa_rw_command_complete();
741         nfa_dm_act_conn_cback_notify (NFA_SELECT_CPLT_EVT, &conn_evt_data);
742         break;
743 
744     case RW_T2T_NDEF_DETECT_EVT:            /* NDEF detection complete */
745         if (  (p_rw_data->status == NFC_STATUS_OK)
746             ||((p_rw_data->status == NFC_STATUS_FAILED) && ((p_rw_data->ndef.flags == NFA_RW_NDEF_FL_UNKNOWN) || (nfa_rw_cb.halt_event == RW_T2T_MAX_EVT)))
747             ||(nfa_rw_cb.skip_dyn_locks == TRUE)  )
748         {
749             /* NDEF Detection is complete */
750             nfa_rw_cb.skip_dyn_locks = FALSE;
751             nfa_rw_handle_ndef_detect (event, p_rw_data);
752         }
753         else
754         {
755             /* Try to detect NDEF again, this time without reading dynamic lock bytes */
756             nfa_rw_cb.skip_dyn_locks = TRUE;
757             nfa_rw_detect_ndef (NULL);
758         }
759         break;
760 
761     case RW_T2T_TLV_DETECT_EVT:             /* Lock control/Mem/Prop tlv detection complete */
762         nfa_rw_handle_tlv_detect(event, p_rw_data);
763         break;
764 
765     case RW_T2T_NDEF_READ_EVT:              /* NDEF read completed     */
766         if (p_rw_data->status == NFC_STATUS_OK)
767         {
768             /* Process the ndef record */
769             nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
770         }
771         else
772         {
773             /* Notify app of failure */
774             if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
775             {
776                 /* If current operation is READ_NDEF, then notify ndef handlers of failure */
777                 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
778             }
779         }
780 
781         /* Notify app of read status */
782         conn_evt_data.status = p_rw_data->status;
783         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
784         /* Free ndef buffer */
785         nfa_rw_free_ndef_rx_buf();
786 
787         /* Command complete - perform cleanup */
788         nfa_rw_command_complete();
789         break;
790 
791     case RW_T2T_NDEF_WRITE_EVT:             /* NDEF write complete     */
792 
793         /* Command complete - perform cleanup, notify the app */
794         nfa_rw_command_complete();
795 
796         /* Notify app */
797         conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
798         if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
799         {
800             /* Update local cursize of ndef message */
801             nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
802         }
803 
804         /* Notify app of ndef write complete status */
805         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
806 
807         break;
808 
809     case RW_T2T_SET_TAG_RO_EVT:
810         /* Command complete - perform cleanup, notify the app */
811         nfa_rw_command_complete();
812         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
813         break;
814 
815     case RW_T2T_RAW_FRAME_EVT:
816         nfa_rw_send_data_to_upper (p_rw_data);
817 
818         /* Command complete - perform cleanup */
819         nfa_rw_command_complete();
820         break;
821 
822     case RW_T2T_PRESENCE_CHECK_EVT:             /* Presence check completed */
823         nfa_rw_handle_presence_check_rsp(p_rw_data->status);
824         break;
825 
826     case RW_T2T_FORMAT_CPLT_EVT:
827         if (p_rw_data->data.status == NFA_STATUS_OK)
828             nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
829 
830         /* Command complete - perform cleanup, notify the app */
831         nfa_rw_command_complete();
832         nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
833         break;
834 
835     case RW_T2T_INTF_ERROR_EVT:
836         nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
837         break;
838     }
839 
840     if (event != RW_T2T_INTF_ERROR_EVT)
841         nfa_rw_cb.halt_event     = RW_T2T_MAX_EVT;
842 }
843 
844 /*******************************************************************************
845 **
846 ** Function         nfa_rw_handle_t3t_evt
847 **
848 ** Description      Handler for Type-3 tag reader/writer events
849 **
850 ** Returns          Nothing
851 **
852 *******************************************************************************/
nfa_rw_handle_t3t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)853 static void nfa_rw_handle_t3t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
854 {
855     tNFA_CONN_EVT_DATA conn_evt_data;
856     tNFA_TAG_PARAMS tag_params;
857 
858     switch (event)
859     {
860     case RW_T3T_NDEF_DETECT_EVT:            /* NDEF detection complete */
861         nfa_rw_handle_ndef_detect(event, p_rw_data);
862         break;
863 
864     case RW_T3T_UPDATE_CPLT_EVT:        /* Write completed */
865         /* Command complete - perform cleanup, notify the app */
866         nfa_rw_command_complete();
867 
868         /* Notify app */
869         conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
870         if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
871         {
872             /* Update local cursize of ndef message */
873             nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
874         }
875 
876         /* Notify app of ndef write complete status */
877         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
878 
879         break;
880 
881     case RW_T3T_CHECK_CPLT_EVT:         /* Read completed */
882         if (p_rw_data->status == NFC_STATUS_OK)
883         {
884             /* Process the ndef record */
885             nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
886         }
887         else
888         {
889             /* Notify app of failure */
890             if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
891             {
892                 /* If current operation is READ_NDEF, then notify ndef handlers of failure */
893                 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
894             }
895         }
896 
897         /* Free ndef buffer */
898         nfa_rw_free_ndef_rx_buf();
899 
900         /* Command complete - perform cleanup, notify the app */
901         nfa_rw_command_complete();
902         conn_evt_data.status = p_rw_data->status;
903         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
904         break;
905 
906     case RW_T3T_CHECK_EVT:                  /* Segment of data received from type 3 tag */
907         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
908         {
909             nfa_rw_store_ndef_rx_buf (p_rw_data);
910         }
911         else
912         {
913             nfa_rw_send_data_to_upper (p_rw_data);
914         }
915         break;
916 
917     case RW_T3T_RAW_FRAME_EVT:              /* SendRawFrame response */
918         nfa_rw_send_data_to_upper (p_rw_data);
919 
920         /* Command complete - perform cleanup */
921         nfa_rw_command_complete();
922         break;
923 
924     case RW_T3T_PRESENCE_CHECK_EVT:             /* Presence check completed */
925         nfa_rw_handle_presence_check_rsp(p_rw_data->status);
926         break;
927 
928     case RW_T3T_GET_SYSTEM_CODES_EVT:           /* Presence check completed */
929         /* Command complete - perform cleanup */
930         nfa_rw_command_complete();
931 
932         /* System codes retrieved - notify app of ACTIVATION */
933         if (p_rw_data->status == NFC_STATUS_OK)
934         {
935             tag_params.t3t.num_system_codes = p_rw_data->t3t_sc.num_system_codes;
936             tag_params.t3t.p_system_codes = p_rw_data->t3t_sc.p_system_codes;
937         }
938         else
939         {
940             tag_params.t3t.num_system_codes = 0;
941             tag_params.t3t.p_system_codes = NULL;
942         }
943 
944         nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
945         break;
946 
947     case RW_T3T_FORMAT_CPLT_EVT:        /* Format completed */
948         /* Command complete - perform cleanup, notify the app */
949         nfa_rw_command_complete();
950 
951         /* Notify app */
952         conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
953 
954         /* Notify app of ndef write complete status */
955         nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
956         break;
957 
958 
959     case RW_T3T_INTF_ERROR_EVT:
960         conn_evt_data.status = p_rw_data->status;
961         nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
962         break;
963 
964     case RW_T3T_SET_READ_ONLY_CPLT_EVT:
965         /* Command complete - perform cleanup, notify the app */
966         nfa_rw_command_complete();
967 
968         conn_evt_data.status = p_rw_data->status;
969         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
970         break;
971 
972     default:
973         NFA_TRACE_DEBUG1("nfa_rw_handle_t3t_evt(); Unhandled RW event 0x%X", event);
974         break;
975     }
976 }
977 
978 
979 /*******************************************************************************
980 **
981 ** Function         nfa_rw_handle_t4t_evt
982 **
983 ** Description      Handler for Type-4 tag reader/writer events
984 **
985 ** Returns          Nothing
986 **
987 *******************************************************************************/
nfa_rw_handle_t4t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)988 static void nfa_rw_handle_t4t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
989 {
990     tNFA_CONN_EVT_DATA conn_evt_data;
991 
992     switch (event)
993     {
994     case RW_T4T_NDEF_DETECT_EVT :           /* Result of NDEF detection procedure */
995         nfa_rw_handle_ndef_detect(event, p_rw_data);
996         break;
997 
998     case RW_T4T_NDEF_READ_EVT:              /* Segment of data received from type 4 tag */
999         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
1000         {
1001             nfa_rw_store_ndef_rx_buf (p_rw_data);
1002         }
1003         else
1004         {
1005             nfa_rw_send_data_to_upper (p_rw_data);
1006         }
1007         break;
1008 
1009     case RW_T4T_NDEF_READ_CPLT_EVT:         /* Read operation completed           */
1010         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
1011         {
1012             nfa_rw_store_ndef_rx_buf (p_rw_data);
1013 
1014             /* Process the ndef record */
1015             nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
1016 
1017             /* Free ndef buffer */
1018             nfa_rw_free_ndef_rx_buf();
1019         }
1020         else
1021         {
1022             nfa_rw_send_data_to_upper (p_rw_data);
1023         }
1024 
1025         /* Command complete - perform cleanup, notify the app */
1026         nfa_rw_command_complete();
1027         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1028         conn_evt_data.status = NFC_STATUS_OK;
1029         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1030         break;
1031 
1032     case RW_T4T_NDEF_READ_FAIL_EVT:         /* Read operation failed              */
1033         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
1034         {
1035             /* If current operation is READ_NDEF, then notify ndef handlers of failure */
1036             nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
1037 
1038             /* Free ndef buffer */
1039             nfa_rw_free_ndef_rx_buf();
1040         }
1041 
1042         /* Command complete - perform cleanup, notify the app */
1043         nfa_rw_command_complete();
1044         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1045         conn_evt_data.status = NFA_STATUS_FAILED;
1046         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1047         break;
1048 
1049     case RW_T4T_NDEF_UPDATE_CPLT_EVT:       /* Update operation completed         */
1050     case RW_T4T_NDEF_UPDATE_FAIL_EVT:       /* Update operation failed            */
1051 
1052         if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
1053         {
1054             /* Update local cursize of ndef message */
1055             nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
1056         }
1057 
1058         /* Notify app */
1059         if (event == RW_T4T_NDEF_UPDATE_CPLT_EVT)
1060             conn_evt_data.status = NFA_STATUS_OK;
1061         else
1062             conn_evt_data.status = NFA_STATUS_FAILED;
1063 
1064         /* Command complete - perform cleanup, notify the app */
1065         nfa_rw_command_complete();
1066         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1067         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1068         break;
1069 
1070     case RW_T4T_RAW_FRAME_EVT:              /* Raw Frame data event         */
1071         nfa_rw_send_data_to_upper (p_rw_data);
1072 
1073         /* Command complete - perform cleanup */
1074         nfa_rw_command_complete();
1075         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1076         break;
1077 
1078     case RW_T4T_SET_TO_RO_EVT:              /* Tag is set as read only          */
1079         conn_evt_data.status = p_rw_data->status;
1080         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
1081 
1082         nfa_rw_command_complete();
1083         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1084         break;
1085 
1086     case RW_T4T_INTF_ERROR_EVT:             /* RF Interface error event         */
1087         conn_evt_data.status = p_rw_data->status;
1088         nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
1089 
1090         nfa_rw_command_complete();
1091         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1092         break;
1093 
1094     case RW_T4T_PRESENCE_CHECK_EVT:             /* Presence check completed */
1095         nfa_rw_handle_presence_check_rsp(p_rw_data->status);
1096         break;
1097 
1098     default:
1099         NFA_TRACE_DEBUG1("nfa_rw_handle_t4t_evt(); Unhandled RW event 0x%X", event);
1100         break;
1101     }
1102 }
1103 
1104 /*******************************************************************************
1105 **
1106 ** Function         nfa_rw_handle_i93_evt
1107 **
1108 ** Description      Handler for ISO 15693 tag reader/writer events
1109 **
1110 ** Returns          Nothing
1111 **
1112 *******************************************************************************/
nfa_rw_handle_i93_evt(tRW_EVENT event,tRW_DATA * p_rw_data)1113 static void nfa_rw_handle_i93_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
1114 {
1115     tNFA_CONN_EVT_DATA conn_evt_data;
1116     tNFA_TAG_PARAMS    i93_params;
1117 
1118     switch (event)
1119     {
1120     case RW_I93_NDEF_DETECT_EVT :           /* Result of NDEF detection procedure */
1121         nfa_rw_handle_ndef_detect(event, p_rw_data);
1122         break;
1123 
1124     case RW_I93_NDEF_READ_EVT:              /* Segment of data received from type 4 tag */
1125         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
1126         {
1127             nfa_rw_store_ndef_rx_buf (p_rw_data);
1128         }
1129         else
1130         {
1131             nfa_rw_send_data_to_upper (p_rw_data);
1132         }
1133         break;
1134 
1135     case RW_I93_NDEF_READ_CPLT_EVT:         /* Read operation completed           */
1136         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
1137         {
1138             nfa_rw_store_ndef_rx_buf (p_rw_data);
1139 
1140             /* Process the ndef record */
1141             nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
1142 
1143             /* Free ndef buffer */
1144             nfa_rw_free_ndef_rx_buf();
1145         }
1146         else
1147         {
1148             nfa_rw_send_data_to_upper (p_rw_data);
1149         }
1150 
1151         /* Command complete - perform cleanup, notify app */
1152         nfa_rw_command_complete();
1153         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1154         conn_evt_data.status = NFC_STATUS_OK;
1155         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1156         break;
1157 
1158     case RW_I93_NDEF_READ_FAIL_EVT:         /* Read operation failed              */
1159         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
1160         {
1161             /* If current operation is READ_NDEF, then notify ndef handlers of failure */
1162             nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
1163 
1164             /* Free ndef buffer */
1165             nfa_rw_free_ndef_rx_buf();
1166         }
1167 
1168         /* Command complete - perform cleanup, notify app */
1169         nfa_rw_command_complete();
1170         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1171         conn_evt_data.status = NFA_STATUS_FAILED;
1172         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1173         break;
1174 
1175     case RW_I93_NDEF_UPDATE_CPLT_EVT:       /* Update operation completed         */
1176     case RW_I93_NDEF_UPDATE_FAIL_EVT:       /* Update operation failed            */
1177 
1178         if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
1179         {
1180             /* Update local cursize of ndef message */
1181             nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
1182         }
1183 
1184         /* Command complete - perform cleanup, notify app */
1185         nfa_rw_command_complete();
1186         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1187 
1188         if (event == RW_I93_NDEF_UPDATE_CPLT_EVT)
1189             conn_evt_data.status = NFA_STATUS_OK;
1190         else
1191             conn_evt_data.status = NFA_STATUS_FAILED;
1192 
1193         /* Notify app of ndef write complete status */
1194         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1195         break;
1196 
1197     case RW_I93_RAW_FRAME_EVT:              /* Raw Frame data event         */
1198         nfa_rw_send_data_to_upper (p_rw_data);
1199 
1200         /* Command complete - perform cleanup */
1201         nfa_rw_command_complete();
1202         break;
1203 
1204     case RW_I93_INTF_ERROR_EVT:             /* RF Interface error event         */
1205         /* Command complete - perform cleanup, notify app */
1206         nfa_rw_command_complete();
1207 
1208         if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
1209         {
1210             nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1211 
1212             memset (&i93_params, 0x00, sizeof (tNFA_TAG_PARAMS));
1213             memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1214 
1215             nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
1216         }
1217         else
1218         {
1219             conn_evt_data.status = p_rw_data->status;
1220             nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
1221         }
1222 
1223         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1224         break;
1225 
1226 
1227     case RW_I93_PRESENCE_CHECK_EVT:             /* Presence check completed */
1228         nfa_rw_handle_presence_check_rsp(p_rw_data->status);
1229         break;
1230 
1231     case RW_I93_FORMAT_CPLT_EVT:                /* Format procedure complete          */
1232         if (p_rw_data->data.status == NFA_STATUS_OK)
1233             nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
1234 
1235         /* Command complete - perform cleanup, notify app */
1236         nfa_rw_command_complete();
1237         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1238         conn_evt_data.status = p_rw_data->status;
1239         nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
1240         break;
1241 
1242     case RW_I93_SET_TAG_RO_EVT:                 /* Set read-only procedure complete   */
1243         nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
1244 
1245         /* Command complete - perform cleanup, notify app */
1246         nfa_rw_command_complete();
1247         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1248         conn_evt_data.status = p_rw_data->status;
1249         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
1250         break;
1251 
1252     case RW_I93_INVENTORY_EVT:                  /* Response of Inventory              */
1253 
1254         /* Command complete - perform cleanup, notify app */
1255         nfa_rw_command_complete();
1256 
1257         conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_inventory.status;
1258         conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY;
1259 
1260         conn_evt_data.i93_cmd_cplt.params.inventory.dsfid = p_rw_data->i93_inventory.dsfid;
1261         memcpy (conn_evt_data.i93_cmd_cplt.params.inventory.uid,
1262                 p_rw_data->i93_inventory.uid,
1263                 I93_UID_BYTE_LEN);
1264 
1265         nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1266 
1267         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1268         break;
1269 
1270     case RW_I93_DATA_EVT:                       /* Response of Read, Get Multi Security */
1271 
1272         /* Command complete - perform cleanup, notify app */
1273         nfa_rw_command_complete();
1274 
1275         conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->i93_data.p_data + 1) + p_rw_data->i93_data.p_data->offset;
1276 
1277         if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
1278         {
1279             nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1280 
1281             i93_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE|I93_INFO_FLAG_AFI);
1282             i93_params.i93.afi        = *(conn_evt_data.data.p_data + nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size);
1283             i93_params.i93.dsfid      = nfa_rw_cb.i93_dsfid;
1284             i93_params.i93.block_size = nfa_rw_cb.i93_block_size;
1285             i93_params.i93.num_block  = nfa_rw_cb.i93_num_block;
1286             memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1287 
1288             nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
1289         }
1290         else
1291         {
1292             conn_evt_data.data.len    = p_rw_data->i93_data.p_data->len;
1293 
1294             nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
1295         }
1296 
1297         GKI_freebuf(p_rw_data->i93_data.p_data);
1298         p_rw_data->i93_data.p_data = NULL;
1299 
1300         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1301         break;
1302 
1303     case RW_I93_SYS_INFO_EVT:                   /* Response of System Information     */
1304 
1305         /* Command complete - perform cleanup, notify app */
1306         nfa_rw_command_complete();
1307 
1308         if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
1309         {
1310             nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1311 
1312             nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
1313             nfa_rw_cb.i93_num_block  = p_rw_data->i93_sys_info.num_block;
1314 
1315             i93_params.i93.info_flags   = p_rw_data->i93_sys_info.info_flags;
1316             i93_params.i93.dsfid        = p_rw_data->i93_sys_info.dsfid;
1317             i93_params.i93.afi          = p_rw_data->i93_sys_info.afi;
1318             i93_params.i93.num_block    = p_rw_data->i93_sys_info.num_block;
1319             i93_params.i93.block_size   = p_rw_data->i93_sys_info.block_size;
1320             i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference;
1321             memcpy (i93_params.i93.uid, p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN);
1322 
1323             nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
1324         }
1325         else
1326         {
1327             conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_sys_info.status;
1328             conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO;
1329 
1330             conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags = p_rw_data->i93_sys_info.info_flags;
1331             memcpy (conn_evt_data.i93_cmd_cplt.params.sys_info.uid,
1332                     p_rw_data->i93_sys_info.uid,
1333                     I93_UID_BYTE_LEN);
1334             conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid        = p_rw_data->i93_sys_info.dsfid;
1335             conn_evt_data.i93_cmd_cplt.params.sys_info.afi          = p_rw_data->i93_sys_info.afi;
1336             conn_evt_data.i93_cmd_cplt.params.sys_info.num_block    = p_rw_data->i93_sys_info.num_block;
1337             conn_evt_data.i93_cmd_cplt.params.sys_info.block_size   = p_rw_data->i93_sys_info.block_size;
1338             conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference = p_rw_data->i93_sys_info.IC_reference;
1339 
1340             /* store tag memory information for writing blocks */
1341             nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
1342             nfa_rw_cb.i93_num_block  = p_rw_data->i93_sys_info.num_block;
1343 
1344             nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1345         }
1346 
1347         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1348         break;
1349 
1350     case RW_I93_CMD_CMPL_EVT:                   /* Command complete                   */
1351         /* Command complete - perform cleanup, notify app */
1352         nfa_rw_command_complete();
1353 
1354         if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
1355         {
1356             /* Reader got error code from tag */
1357 
1358             nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1359 
1360             memset (&i93_params, 0x00, sizeof(i93_params));
1361             memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1362 
1363             nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
1364         }
1365         else
1366         {
1367             conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_cmd_cmpl.status;
1368             conn_evt_data.i93_cmd_cplt.sent_command = p_rw_data->i93_cmd_cmpl.command;
1369 
1370             if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK)
1371                 conn_evt_data.i93_cmd_cplt.params.error_code = p_rw_data->i93_cmd_cmpl.error_code;
1372 
1373             nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1374         }
1375 
1376         nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1377         break;
1378 
1379     default:
1380         NFA_TRACE_DEBUG1("nfa_rw_handle_i93_evt(); Unhandled RW event 0x%X", event);
1381         break;
1382     }
1383 }
1384 
1385 /*******************************************************************************
1386 **
1387 ** Function         nfa_rw_cback
1388 **
1389 ** Description      Callback for reader/writer event notification
1390 **
1391 ** Returns          Nothing
1392 **
1393 *******************************************************************************/
nfa_rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)1394 static void nfa_rw_cback (tRW_EVENT event, tRW_DATA *p_rw_data)
1395 {
1396     NFA_TRACE_DEBUG1("nfa_rw_cback: event=0x%02x", event);
1397 
1398     /* Call appropriate event handler for tag type */
1399     if (event < RW_T1T_MAX_EVT)
1400     {
1401         /* Handle Type-1 tag events */
1402         nfa_rw_handle_t1t_evt(event, p_rw_data);
1403     }
1404     else if (event < RW_T2T_MAX_EVT)
1405     {
1406         /* Handle Type-2 tag events */
1407         nfa_rw_handle_t2t_evt(event, p_rw_data);
1408     }
1409     else if (event < RW_T3T_MAX_EVT)
1410     {
1411         /* Handle Type-3 tag events */
1412         nfa_rw_handle_t3t_evt(event, p_rw_data);
1413     }
1414     else if (event < RW_T4T_MAX_EVT)
1415     {
1416         /* Handle Type-4 tag events */
1417         nfa_rw_handle_t4t_evt(event, p_rw_data);
1418     }
1419     else if (event < RW_I93_MAX_EVT)
1420     {
1421         /* Handle ISO 15693 tag events */
1422         nfa_rw_handle_i93_evt(event, p_rw_data);
1423     }
1424     else
1425     {
1426         NFA_TRACE_ERROR1("nfa_rw_cback: unhandled event=0x%02x", event);
1427     }
1428 }
1429 
1430 /*******************************************************************************
1431 **
1432 ** Function         nfa_rw_start_ndef_detection
1433 **
1434 ** Description      Start NDEF detection on activated tag
1435 **
1436 ** Returns          Nothing
1437 **
1438 *******************************************************************************/
nfa_rw_start_ndef_detection(void)1439 static tNFC_STATUS nfa_rw_start_ndef_detection(void)
1440 {
1441     tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1442     tNFC_STATUS status = NFC_STATUS_FAILED;
1443 
1444     switch (protocol)
1445     {
1446     case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1447         status = RW_T1tDetectNDef();
1448         break;
1449 
1450     case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1451         if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1452         {
1453             status = RW_T2tDetectNDef(nfa_rw_cb.skip_dyn_locks);
1454         }
1455         break;
1456 
1457     case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1458         status = RW_T3tDetectNDef();
1459         break;
1460 
1461     case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1462         status = RW_T4tDetectNDef();
1463         break;
1464 
1465     case NFC_PROTOCOL_15693:       /* ISO 15693 */
1466         status = RW_I93DetectNDef();
1467         break;
1468 
1469     default:
1470         break;
1471     }
1472 
1473     return(status);
1474 }
1475 
1476 /*******************************************************************************
1477 **
1478 ** Function         nfa_rw_start_ndef_read
1479 **
1480 ** Description      Start NDEF read on activated tag
1481 **
1482 ** Returns          Nothing
1483 **
1484 *******************************************************************************/
nfa_rw_start_ndef_read(void)1485 static tNFC_STATUS nfa_rw_start_ndef_read(void)
1486 {
1487     tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1488     tNFC_STATUS status = NFC_STATUS_FAILED;
1489     tNFA_CONN_EVT_DATA conn_evt_data;
1490 
1491     /* Handle zero length NDEF message */
1492     if (nfa_rw_cb.ndef_cur_size == 0)
1493     {
1494         NFA_TRACE_DEBUG0("NDEF message is zero-length");
1495 
1496         /* Send zero-lengh NDEF message to ndef callback */
1497         nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0);
1498 
1499         /* Command complete - perform cleanup, notify app */
1500         nfa_rw_command_complete();
1501         conn_evt_data.status = NFA_STATUS_OK;
1502         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1503         return NFC_STATUS_OK;
1504     }
1505 
1506     /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if needed) */
1507     nfa_rw_free_ndef_rx_buf ();
1508     if ((nfa_rw_cb.p_ndef_buf = (UINT8 *)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size)) == NULL)
1509     {
1510         NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)", nfa_rw_cb.ndef_cur_size);
1511 
1512         /* Command complete - perform cleanup, notify app */
1513         nfa_rw_command_complete();
1514         conn_evt_data.status = NFA_STATUS_FAILED;
1515         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1516         return NFC_STATUS_FAILED;
1517     }
1518     nfa_rw_cb.ndef_rd_offset = 0;
1519 
1520     switch (protocol)
1521     {
1522     case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1523         status = RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
1524         break;
1525 
1526     case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1527         if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1528         {
1529             status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
1530         }
1531         break;
1532 
1533     case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1534         status = RW_T3tCheckNDef();
1535         break;
1536 
1537     case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1538         status = RW_T4tReadNDef();
1539         break;
1540 
1541     case NFC_PROTOCOL_15693:       /* ISO 15693 */
1542         status = RW_I93ReadNDef();
1543         break;
1544 
1545     default:
1546         break;
1547     }
1548     return(status);
1549 }
1550 
1551 /*******************************************************************************
1552 **
1553 ** Function         nfa_rw_detect_ndef
1554 **
1555 ** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
1556 **
1557 ** Returns          TRUE (message buffer to be freed by caller)
1558 **
1559 *******************************************************************************/
nfa_rw_detect_ndef(tNFA_RW_MSG * p_data)1560 static BOOLEAN nfa_rw_detect_ndef(tNFA_RW_MSG *p_data)
1561 {
1562     tNFA_CONN_EVT_DATA conn_evt_data;
1563     NFA_TRACE_DEBUG0("nfa_rw_detect_ndef");
1564 
1565     if ((conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection()) != NFC_STATUS_OK)
1566     {
1567         /* Command complete - perform cleanup, notify app */
1568         nfa_rw_command_complete();
1569         conn_evt_data.ndef_detect.cur_size = 0;
1570         conn_evt_data.ndef_detect.max_size = 0;
1571         conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
1572         nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
1573     }
1574 
1575     return TRUE;
1576 }
1577 
1578 /*******************************************************************************
1579 **
1580 ** Function         nfa_rw_start_ndef_write
1581 **
1582 ** Description      Start NDEF write on activated tag
1583 **
1584 ** Returns          Nothing
1585 **
1586 *******************************************************************************/
nfa_rw_start_ndef_write(void)1587 static tNFC_STATUS nfa_rw_start_ndef_write(void)
1588 {
1589     tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1590     tNFC_STATUS status = NFC_STATUS_FAILED;
1591 
1592     if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY)
1593     {
1594         /* error: ndef tag is read-only */
1595         status = NFC_STATUS_FAILED;
1596         NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only")
1597     }
1598     else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len)
1599     {
1600         /* error: ndef tag size is too small */
1601         status = NFC_STATUS_BUFFER_FULL;
1602         NFA_TRACE_ERROR2("Unable to write NDEF. Tag maxsize=%i, request write size=%i", nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len)
1603     }
1604     else
1605     {
1606         switch (protocol)
1607         {
1608         case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1609             status = RW_T1tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1610             break;
1611 
1612         case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1613 
1614             if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1615             {
1616                 status = RW_T2tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1617             }
1618             break;
1619 
1620         case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1621             status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1622             break;
1623 
1624         case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1625             status = RW_T4tUpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1626             break;
1627 
1628         case NFC_PROTOCOL_15693:       /* ISO 15693 */
1629             status = RW_I93UpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1630             break;
1631 
1632         default:
1633             break;
1634         }
1635     }
1636 
1637     return(status);
1638 }
1639 
1640 /*******************************************************************************
1641 **
1642 ** Function         nfa_rw_read_ndef
1643 **
1644 ** Description      Handler for NFA_RW_API_READ_NDEF_EVT
1645 **
1646 ** Returns          TRUE (message buffer to be freed by caller)
1647 **
1648 *******************************************************************************/
nfa_rw_read_ndef(tNFA_RW_MSG * p_data)1649 static BOOLEAN nfa_rw_read_ndef(tNFA_RW_MSG *p_data)
1650 {
1651     tNFA_STATUS status = NFA_STATUS_OK;
1652     tNFA_CONN_EVT_DATA conn_evt_data;
1653 
1654     NFA_TRACE_DEBUG0("nfa_rw_read_ndef");
1655 
1656     /* Check if ndef detection has been performed yet */
1657     if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
1658     {
1659         /* Perform ndef detection first */
1660         status = nfa_rw_start_ndef_detection();
1661     }
1662     else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
1663     {
1664         /* Tag is not NDEF */
1665         status = NFA_STATUS_FAILED;
1666     }
1667     else
1668     {
1669         /* Perform the NDEF read operation */
1670         status = nfa_rw_start_ndef_read();
1671     }
1672 
1673     /* Handle failure */
1674     if (status != NFA_STATUS_OK)
1675     {
1676         /* Command complete - perform cleanup, notify app */
1677         nfa_rw_command_complete();
1678         conn_evt_data.status = status;
1679         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1680     }
1681 
1682 
1683     return TRUE;
1684 }
1685 
1686 /*******************************************************************************
1687 **
1688 ** Function         nfa_rw_write_ndef
1689 **
1690 ** Description      Handler for NFA_RW_API_WRITE_NDEF_EVT
1691 **
1692 ** Returns          TRUE (message buffer to be freed by caller)
1693 **
1694 *******************************************************************************/
nfa_rw_write_ndef(tNFA_RW_MSG * p_data)1695 static BOOLEAN nfa_rw_write_ndef(tNFA_RW_MSG *p_data)
1696 {
1697     tNDEF_STATUS ndef_status;
1698     tNFA_STATUS write_status = NFA_STATUS_OK;
1699     tNFA_CONN_EVT_DATA conn_evt_data;
1700     NFA_TRACE_DEBUG0("nfa_rw_write_ndef");
1701 
1702     /* Validate NDEF message */
1703     if ((ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data, p_data->op_req.params.write_ndef.len, FALSE)) != NDEF_OK)
1704     {
1705         NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i", ndef_status);
1706 
1707         /* Command complete - perform cleanup, notify app */
1708         nfa_rw_command_complete();
1709         conn_evt_data.status = NFA_STATUS_FAILED;
1710         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1711         return TRUE;
1712     }
1713 
1714     /* Store pointer to source NDEF */
1715     nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data;
1716     nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len;
1717 
1718     /* Check if ndef detection has been performed yet */
1719     if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
1720     {
1721         /* Perform ndef detection first */
1722         write_status = nfa_rw_start_ndef_detection();
1723     }
1724     else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
1725     {
1726         if (nfa_rw_cb.protocol == NFC_PROTOCOL_T1T)
1727         {
1728             /* For Type 1 tag, NDEF can be written on Initialized tag
1729             *  Perform ndef detection first to check if tag is in Initialized state to Write NDEF */
1730             write_status = nfa_rw_start_ndef_detection();
1731         }
1732         else
1733         {
1734             /* Tag is not NDEF */
1735             write_status = NFA_STATUS_FAILED;
1736         }
1737     }
1738     else
1739     {
1740         /* Perform the NDEF read operation */
1741         write_status = nfa_rw_start_ndef_write();
1742     }
1743 
1744     /* Handle failure */
1745     if (write_status != NFA_STATUS_OK)
1746     {
1747         /* Command complete - perform cleanup, notify app */
1748         nfa_rw_command_complete();
1749         conn_evt_data.status = write_status;
1750         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1751     }
1752 
1753     return TRUE;
1754 }
1755 
1756 /*******************************************************************************
1757 **
1758 ** Function         nfa_rw_presence_check
1759 **
1760 ** Description      Handler for NFA_RW_API_PRESENCE_CHECK
1761 **
1762 ** Returns          Nothing
1763 **
1764 *******************************************************************************/
nfa_rw_presence_check(tNFA_RW_MSG * p_data)1765 void nfa_rw_presence_check (tNFA_RW_MSG *p_data)
1766 {
1767     tNFC_PROTOCOL       protocol = nfa_rw_cb.protocol;
1768     UINT8               sel_res  = nfa_rw_cb.pa_sel_res;
1769     tNFC_STATUS         status   = NFC_STATUS_FAILED;
1770 
1771     switch (protocol)
1772     {
1773     case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1774         status = RW_T1tPresenceCheck();
1775         break;
1776 
1777     case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1778         status = RW_T3tPresenceCheck();
1779         break;
1780 
1781     case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1782         status = RW_T4tPresenceCheck();
1783         break;
1784 
1785     case NFC_PROTOCOL_15693:       /* ISO 15693 */
1786         status = RW_I93PresenceCheck();
1787         break;
1788 
1789     case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1790         /* If T2T NFC-Forum, then let RW handle presence check; otherwise fall through */
1791         if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1792         {
1793             /* Type 2 tag have not sent NACK after activation */
1794             status = RW_T2tPresenceCheck();
1795             break;
1796         }
1797 
1798     default:
1799         /* Protocol unsupported by RW module... */
1800 
1801         if (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_KOVIO)
1802         {
1803             /* start Kovio presence check (deactivate and wait for activation) */
1804             status = nfa_dm_disc_start_kovio_presence_check ();
1805         }
1806         else
1807         {
1808             /* Let DM perform presence check (by putting tag to sleep and then waking it up) */
1809             status = nfa_dm_disc_sleep_wakeup();
1810         }
1811         break;
1812     }
1813 
1814     /* Handle presence check failure */
1815     if (status != NFC_STATUS_OK)
1816         nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
1817 }
1818 
1819 
1820 /*******************************************************************************
1821 **
1822 ** Function         nfa_rw_presence_check_tick
1823 **
1824 ** Description      Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL
1825 **                  Initiate presence check
1826 **
1827 ** Returns          TRUE (caller frees message buffer)
1828 **
1829 *******************************************************************************/
nfa_rw_presence_check_tick(tNFA_RW_MSG * p_data)1830 BOOLEAN nfa_rw_presence_check_tick(tNFA_RW_MSG *p_data)
1831 {
1832     /* Store the current operation */
1833     nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK;
1834     nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
1835     NFA_TRACE_DEBUG0("Auto-presence check starting...");
1836 
1837     /* Perform presence check */
1838     nfa_rw_presence_check(NULL);
1839 
1840     return TRUE;
1841 }
1842 
1843 /*******************************************************************************
1844 **
1845 ** Function         nfa_rw_format_tag
1846 **
1847 ** Description      Handler for NFA_RW_API_FORMAT_TAG
1848 **
1849 ** Returns          Nothing
1850 **
1851 *******************************************************************************/
nfa_rw_format_tag(tNFA_RW_MSG * p_data)1852 static void nfa_rw_format_tag (tNFA_RW_MSG *p_data)
1853 {
1854     tNFC_PROTOCOL   protocol = nfa_rw_cb.protocol;
1855     tNFC_STATUS     status   = NFC_STATUS_FAILED;
1856 
1857     if (protocol == NFC_PROTOCOL_T1T)
1858     {
1859         status = RW_T1tFormatNDef();
1860     }
1861     else if (  (protocol  == NFC_PROTOCOL_T2T)
1862              &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)  )
1863     {
1864         status = RW_T2tFormatNDef();
1865     }
1866     else if (protocol == NFC_PROTOCOL_T3T)
1867     {
1868         status = RW_T3tFormatNDef();
1869     }
1870     else if (protocol == NFC_PROTOCOL_15693)
1871     {
1872         status = RW_I93FormatNDef();
1873     }
1874 
1875     /* If unable to format NDEF, notify the app */
1876     if (status != NFC_STATUS_OK)
1877         nfa_rw_error_cleanup (NFA_FORMAT_CPLT_EVT);
1878 }
1879 
1880 /*******************************************************************************
1881 **
1882 ** Function         nfa_rw_detect_tlv
1883 **
1884 ** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
1885 **
1886 ** Returns          TRUE (message buffer to be freed by caller)
1887 **
1888 *******************************************************************************/
nfa_rw_detect_tlv(tNFA_RW_MSG * p_data,UINT8 tlv)1889 static BOOLEAN nfa_rw_detect_tlv (tNFA_RW_MSG *p_data, UINT8 tlv)
1890 {
1891     NFA_TRACE_DEBUG0("nfa_rw_detect_tlv");
1892 
1893     switch (nfa_rw_cb.protocol)
1894     {
1895     case NFC_PROTOCOL_T1T:
1896         if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK)
1897             nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
1898         break;
1899 
1900     case NFC_PROTOCOL_T2T:
1901         if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1902         {
1903             if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK)
1904                 nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
1905         }
1906         break;
1907 
1908     default:
1909         break;
1910     }
1911 
1912     return TRUE;
1913 }
1914 
1915 /*******************************************************************************
1916 **
1917 ** Function         nfa_rw_config_tag_ro
1918 **
1919 ** Description      Handler for NFA_RW_OP_SET_TAG_RO
1920 **
1921 ** Returns          TRUE (message buffer to be freed by caller)
1922 **
1923 *******************************************************************************/
nfa_rw_config_tag_ro(BOOLEAN b_hard_lock)1924 static tNFC_STATUS nfa_rw_config_tag_ro (BOOLEAN b_hard_lock)
1925 {
1926     tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1927     tNFC_STATUS   status   = NFC_STATUS_FAILED;
1928 
1929     NFA_TRACE_DEBUG0 ("nfa_rw_config_tag_ro ()");
1930 
1931     switch (protocol)
1932     {
1933     case NFC_PROTOCOL_T1T:
1934         if(  (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED)
1935            ||(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE) )
1936         {
1937             status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV);
1938             return (status);
1939         }
1940         else
1941         {
1942             status = RW_T1tSetTagReadOnly(b_hard_lock);
1943         }
1944         break;
1945 
1946     case NFC_PROTOCOL_T2T:
1947         if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1948         {
1949             status = RW_T2tSetTagReadOnly(b_hard_lock);
1950         }
1951         break;
1952 
1953     case NFC_PROTOCOL_T3T:
1954         status = RW_T3tSetReadOnly(b_hard_lock);
1955         break;
1956 
1957     case NFC_PROTOCOL_ISO_DEP:
1958         status = RW_T4tSetNDefReadOnly();
1959         break;
1960 
1961     case NFC_PROTOCOL_15693:
1962         status = RW_I93SetTagReadOnly();
1963         break;
1964 
1965     default:
1966         break;
1967 
1968     }
1969 
1970     if (status == NFC_STATUS_OK)
1971     {
1972         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
1973     }
1974     else
1975     {
1976         nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT);
1977     }
1978 
1979     return (status);
1980 }
1981 
1982 /*******************************************************************************
1983 **
1984 ** Function         nfa_rw_t1t_rid
1985 **
1986 ** Description      Handler for T1T_RID API
1987 **
1988 ** Returns          TRUE (message buffer to be freed by caller)
1989 **
1990 *******************************************************************************/
nfa_rw_t1t_rid(tNFA_RW_MSG * p_data)1991 static BOOLEAN nfa_rw_t1t_rid(tNFA_RW_MSG *p_data)
1992 {
1993     if (RW_T1tRid () != NFC_STATUS_OK)
1994         nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
1995 
1996     return TRUE;
1997 }
1998 
1999 /*******************************************************************************
2000 **
2001 ** Function         nfa_rw_t1t_rall
2002 **
2003 ** Description      Handler for T1T_ReadAll API
2004 **
2005 ** Returns          TRUE (message buffer to be freed by caller)
2006 **
2007 *******************************************************************************/
nfa_rw_t1t_rall(tNFA_RW_MSG * p_data)2008 static BOOLEAN nfa_rw_t1t_rall(tNFA_RW_MSG *p_data)
2009 {
2010     if (RW_T1tReadAll() != NFC_STATUS_OK)
2011         nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2012 
2013     return TRUE;
2014 }
2015 
2016 /*******************************************************************************
2017 **
2018 ** Function         nfa_rw_t1t_read
2019 **
2020 ** Description      Handler for T1T_Read API
2021 **
2022 ** Returns          TRUE (message buffer to be freed by caller)
2023 **
2024 *******************************************************************************/
nfa_rw_t1t_read(tNFA_RW_MSG * p_data)2025 static BOOLEAN nfa_rw_t1t_read (tNFA_RW_MSG *p_data)
2026 {
2027     tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
2028 
2029     if (RW_T1tRead (p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK)
2030         nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2031 
2032     return TRUE;
2033 }
2034 
2035 /*******************************************************************************
2036 **
2037 ** Function         nfa_rw_t1t_write
2038 **
2039 ** Description      Handler for T1T_WriteErase/T1T_WriteNoErase API
2040 **
2041 ** Returns          TRUE (message buffer to be freed by caller)
2042 **
2043 *******************************************************************************/
nfa_rw_t1t_write(tNFA_RW_MSG * p_data)2044 static BOOLEAN nfa_rw_t1t_write (tNFA_RW_MSG *p_data)
2045 {
2046     tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
2047     tNFC_STATUS                 status;
2048 
2049     if (p_t1t_write->b_erase)
2050     {
2051         status = RW_T1tWriteErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
2052     }
2053     else
2054     {
2055         status = RW_T1tWriteNoErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
2056     }
2057 
2058     if (status != NFC_STATUS_OK)
2059     {
2060         nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
2061     }
2062     else
2063     {
2064         if (p_t1t_write->block_number == 0x01)
2065             nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2066     }
2067 
2068     return TRUE;
2069 }
2070 
2071 /*******************************************************************************
2072 **
2073 ** Function         nfa_rw_t1t_rseg
2074 **
2075 ** Description      Handler for T1t_ReadSeg API
2076 **
2077 ** Returns          TRUE (message buffer to be freed by caller)
2078 **
2079 *******************************************************************************/
nfa_rw_t1t_rseg(tNFA_RW_MSG * p_data)2080 static BOOLEAN nfa_rw_t1t_rseg (tNFA_RW_MSG *p_data)
2081 {
2082     tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
2083 
2084     if (RW_T1tReadSeg (p_t1t_read->segment_number) != NFC_STATUS_OK)
2085         nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2086 
2087     return TRUE;
2088 }
2089 
2090 /*******************************************************************************
2091 **
2092 ** Function         nfa_rw_t1t_read8
2093 **
2094 ** Description      Handler for T1T_Read8 API
2095 **
2096 ** Returns          TRUE (message buffer to be freed by caller)
2097 **
2098 *******************************************************************************/
nfa_rw_t1t_read8(tNFA_RW_MSG * p_data)2099 static BOOLEAN nfa_rw_t1t_read8 (tNFA_RW_MSG *p_data)
2100 {
2101     tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
2102 
2103     if (RW_T1tRead8 (p_t1t_read->block_number) != NFC_STATUS_OK)
2104         nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2105 
2106     return TRUE;
2107 }
2108 
2109 /*******************************************************************************
2110 **
2111 ** Function         nfa_rw_t1t_write8
2112 **
2113 ** Description      Handler for T1T_WriteErase8/T1T_WriteNoErase8 API
2114 **
2115 ** Returns          TRUE (message buffer to be freed by caller)
2116 **
2117 *******************************************************************************/
nfa_rw_t1t_write8(tNFA_RW_MSG * p_data)2118 static BOOLEAN nfa_rw_t1t_write8 (tNFA_RW_MSG *p_data)
2119 {
2120     tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
2121     tNFC_STATUS                 status;
2122 
2123     if (p_t1t_write->b_erase)
2124     {
2125         status = RW_T1tWriteErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
2126     }
2127     else
2128     {
2129         status = RW_T1tWriteNoErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
2130     }
2131 
2132     if (status != NFC_STATUS_OK)
2133     {
2134         nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
2135     }
2136     else
2137     {
2138         if (p_t1t_write->block_number == 0x01)
2139             nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2140     }
2141 
2142     return TRUE;
2143 }
2144 
2145 /*******************************************************************************
2146 **
2147 ** Function         nfa_rw_t2t_read
2148 **
2149 ** Description      Handler for T2T_Read API
2150 **
2151 ** Returns          TRUE (message buffer to be freed by caller)
2152 **
2153 *******************************************************************************/
nfa_rw_t2t_read(tNFA_RW_MSG * p_data)2154 static BOOLEAN nfa_rw_t2t_read (tNFA_RW_MSG *p_data)
2155 {
2156     tNFA_RW_OP_PARAMS_T2T_READ *p_t2t_read = (tNFA_RW_OP_PARAMS_T2T_READ *)&(p_data->op_req.params.t2t_read);
2157     tNFC_STATUS                status = NFC_STATUS_FAILED;
2158 
2159     if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
2160         status = RW_T2tRead (p_t2t_read->block_number);
2161 
2162     if (status != NFC_STATUS_OK)
2163         nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2164 
2165     return TRUE;
2166 }
2167 
2168 /*******************************************************************************
2169 **
2170 ** Function         nfa_rw_t2t_write
2171 **
2172 ** Description      Handler for T2T_Write API
2173 **
2174 ** Returns          TRUE (message buffer to be freed by caller)
2175 **
2176 *******************************************************************************/
nfa_rw_t2t_write(tNFA_RW_MSG * p_data)2177 static BOOLEAN nfa_rw_t2t_write (tNFA_RW_MSG *p_data)
2178 {
2179     tNFA_RW_OP_PARAMS_T2T_WRITE *p_t2t_write = (tNFA_RW_OP_PARAMS_T2T_WRITE *)&(p_data->op_req.params.t2t_write);
2180 
2181     if (RW_T2tWrite (p_t2t_write->block_number,p_t2t_write->p_block_data) != NFC_STATUS_OK)
2182     {
2183         nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
2184     }
2185     else
2186     {
2187         if (p_t2t_write->block_number == 0x03)
2188             nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2189     }
2190 
2191     return TRUE;
2192 }
2193 
2194 /*******************************************************************************
2195 **
2196 ** Function         nfa_rw_t2t_sector_select
2197 **
2198 ** Description      Handler for T2T_Sector_Select API
2199 **
2200 ** Returns          TRUE (message buffer to be freed by caller)
2201 **
2202 *******************************************************************************/
nfa_rw_t2t_sector_select(tNFA_RW_MSG * p_data)2203 static BOOLEAN nfa_rw_t2t_sector_select(tNFA_RW_MSG *p_data)
2204 {
2205     tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *p_t2t_sector_select = (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *)&(p_data->op_req.params.t2t_sector_select);
2206 
2207     if (RW_T2tSectorSelect (p_t2t_sector_select->sector_number) != NFC_STATUS_OK)
2208         nfa_rw_error_cleanup (NFA_SELECT_CPLT_EVT);
2209 
2210     return TRUE;
2211 }
2212 
2213 /*******************************************************************************
2214 **
2215 ** Function         nfa_rw_t3t_read
2216 **
2217 ** Description      Handler for T3T_Read API
2218 **
2219 ** Returns          TRUE (message buffer to be freed by caller)
2220 **
2221 *******************************************************************************/
nfa_rw_t3t_read(tNFA_RW_MSG * p_data)2222 static BOOLEAN nfa_rw_t3t_read (tNFA_RW_MSG *p_data)
2223 {
2224     tNFA_RW_OP_PARAMS_T3T_READ *p_t3t_read = (tNFA_RW_OP_PARAMS_T3T_READ *)&(p_data->op_req.params.t3t_read);
2225 
2226     if (RW_T3tCheck (p_t3t_read->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_read->p_block_desc) != NFC_STATUS_OK)
2227         nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2228 
2229     return TRUE;
2230 }
2231 
2232 /*******************************************************************************
2233 **
2234 ** Function         nfa_rw_t3t_write
2235 **
2236 ** Description      Handler for T3T_Write API
2237 **
2238 ** Returns          TRUE (message buffer to be freed by caller)
2239 **
2240 *******************************************************************************/
nfa_rw_t3t_write(tNFA_RW_MSG * p_data)2241 static BOOLEAN nfa_rw_t3t_write (tNFA_RW_MSG *p_data)
2242 {
2243     tNFA_RW_OP_PARAMS_T3T_WRITE *p_t3t_write = (tNFA_RW_OP_PARAMS_T3T_WRITE *)&(p_data->op_req.params.t3t_write);
2244 
2245     if (RW_T3tUpdate (p_t3t_write->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_write->p_block_desc, p_t3t_write->p_block_data) != NFC_STATUS_OK)
2246         nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
2247 
2248     return TRUE;
2249 }
2250 
2251 /*******************************************************************************
2252 **
2253 ** Function         nfa_rw_t3t_get_system_codes
2254 **
2255 ** Description      Get system codes (initiated by NFA after activation)
2256 **
2257 ** Returns          TRUE (message buffer to be freed by caller)
2258 **
2259 *******************************************************************************/
nfa_rw_t3t_get_system_codes(tNFA_RW_MSG * p_data)2260 static BOOLEAN nfa_rw_t3t_get_system_codes (tNFA_RW_MSG *p_data)
2261 {
2262     tNFC_STATUS     status;
2263     tNFA_TAG_PARAMS tag_params;
2264 
2265     status = RW_T3tGetSystemCodes();
2266 
2267     if (status != NFC_STATUS_OK)
2268     {
2269         /* Command complete - perform cleanup, notify app */
2270         nfa_rw_command_complete();
2271         tag_params.t3t.num_system_codes = 0;
2272         tag_params.t3t.p_system_codes   = NULL;
2273 
2274         nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
2275     }
2276 
2277     return TRUE;
2278 }
2279 
2280 /*******************************************************************************
2281 **
2282 ** Function         nfa_rw_i93_command
2283 **
2284 ** Description      Handler for ISO 15693 command
2285 **
2286 ** Returns          TRUE (message buffer to be freed by caller)
2287 **
2288 *******************************************************************************/
nfa_rw_i93_command(tNFA_RW_MSG * p_data)2289 static BOOLEAN nfa_rw_i93_command (tNFA_RW_MSG *p_data)
2290 {
2291     tNFA_CONN_EVT_DATA conn_evt_data;
2292     tNFC_STATUS        status = NFC_STATUS_OK;
2293     UINT8              i93_command = I93_CMD_STAY_QUIET;
2294 
2295     switch (p_data->op_req.op)
2296     {
2297     case NFA_RW_OP_I93_INVENTORY:
2298         i93_command = I93_CMD_INVENTORY;
2299         if (p_data->op_req.params.i93_cmd.uid_present)
2300         {
2301             status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi_present,
2302                                       p_data->op_req.params.i93_cmd.afi,
2303                                       p_data->op_req.params.i93_cmd.uid);
2304         }
2305         else
2306         {
2307             status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi_present,
2308                                       p_data->op_req.params.i93_cmd.afi,
2309                                       NULL);
2310         }
2311         break;
2312 
2313     case NFA_RW_OP_I93_STAY_QUIET:
2314         i93_command = I93_CMD_STAY_QUIET;
2315         status = RW_I93StayQuiet ();
2316         break;
2317 
2318     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2319         i93_command = I93_CMD_READ_SINGLE_BLOCK;
2320         status = RW_I93ReadSingleBlock (p_data->op_req.params.i93_cmd.first_block_number);
2321         break;
2322 
2323     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2324         i93_command = I93_CMD_WRITE_SINGLE_BLOCK;
2325         status = RW_I93WriteSingleBlock (p_data->op_req.params.i93_cmd.first_block_number,
2326                                          p_data->op_req.params.i93_cmd.p_data);
2327         break;
2328 
2329     case NFA_RW_OP_I93_LOCK_BLOCK:
2330         i93_command = I93_CMD_LOCK_BLOCK;
2331         status = RW_I93LockBlock ((UINT8)p_data->op_req.params.i93_cmd.first_block_number);
2332         break;
2333 
2334     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2335         i93_command = I93_CMD_READ_MULTI_BLOCK;
2336         status = RW_I93ReadMultipleBlocks (p_data->op_req.params.i93_cmd.first_block_number,
2337                                            p_data->op_req.params.i93_cmd.number_blocks);
2338         break;
2339 
2340     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2341         i93_command = I93_CMD_WRITE_MULTI_BLOCK;
2342         status = RW_I93WriteMultipleBlocks ((UINT8)p_data->op_req.params.i93_cmd.first_block_number,
2343                                             p_data->op_req.params.i93_cmd.number_blocks,
2344                                             p_data->op_req.params.i93_cmd.p_data);
2345         break;
2346 
2347     case NFA_RW_OP_I93_SELECT:
2348         i93_command = I93_CMD_SELECT;
2349         status = RW_I93Select (p_data->op_req.params.i93_cmd.p_data);
2350         break;
2351 
2352     case NFA_RW_OP_I93_RESET_TO_READY:
2353         i93_command = I93_CMD_RESET_TO_READY;
2354         status = RW_I93ResetToReady ();
2355         break;
2356 
2357     case NFA_RW_OP_I93_WRITE_AFI:
2358         i93_command = I93_CMD_WRITE_AFI;
2359         status = RW_I93WriteAFI (p_data->op_req.params.i93_cmd.afi);
2360         break;
2361 
2362     case NFA_RW_OP_I93_LOCK_AFI:
2363         i93_command = I93_CMD_LOCK_AFI;
2364         status = RW_I93LockAFI ();
2365         break;
2366 
2367     case NFA_RW_OP_I93_WRITE_DSFID:
2368         i93_command = I93_CMD_WRITE_DSFID;
2369         status = RW_I93WriteDSFID (p_data->op_req.params.i93_cmd.dsfid);
2370         break;
2371 
2372     case NFA_RW_OP_I93_LOCK_DSFID:
2373         i93_command = I93_CMD_LOCK_DSFID;
2374         status = RW_I93LockDSFID ();
2375         break;
2376 
2377     case NFA_RW_OP_I93_GET_SYS_INFO:
2378         i93_command = I93_CMD_GET_SYS_INFO;
2379         if (p_data->op_req.params.i93_cmd.uid_present)
2380         {
2381             status = RW_I93GetSysInfo (p_data->op_req.params.i93_cmd.uid);
2382         }
2383         else
2384         {
2385             status = RW_I93GetSysInfo (NULL);
2386         }
2387         break;
2388 
2389     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2390         i93_command = I93_CMD_GET_MULTI_BLK_SEC;
2391         status = RW_I93GetMultiBlockSecurityStatus (p_data->op_req.params.i93_cmd.first_block_number,
2392                                                     p_data->op_req.params.i93_cmd.number_blocks);
2393         break;
2394 
2395     default:
2396         break;
2397     }
2398 
2399     if (status != NFC_STATUS_OK)
2400     {
2401         /* Command complete - perform cleanup, notify app */
2402         nfa_rw_command_complete();
2403 
2404         conn_evt_data.i93_cmd_cplt.status       = NFA_STATUS_FAILED;
2405         conn_evt_data.i93_cmd_cplt.sent_command = i93_command;
2406 
2407         nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
2408     }
2409 
2410     return TRUE;
2411 }
2412 
2413 /*******************************************************************************
2414 **
2415 ** Function         nfa_rw_raw_mode_data_cback
2416 **
2417 ** Description      Handler for incoming tag data for unsupported tag protocols
2418 **                  (forward data to upper layer)
2419 **
2420 ** Returns          nothing
2421 **
2422 *******************************************************************************/
nfa_rw_raw_mode_data_cback(UINT8 conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)2423 static void nfa_rw_raw_mode_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
2424 {
2425     BT_HDR             *p_msg;
2426     tNFA_CONN_EVT_DATA evt_data;
2427 
2428     NFA_TRACE_DEBUG1 ("nfa_rw_raw_mode_data_cback(): event = 0x%X", event);
2429 
2430     if ((event == NFC_DATA_CEVT) && (p_data->data.status == NFC_STATUS_OK))
2431     {
2432         p_msg = (BT_HDR *)p_data->data.p_data;
2433 
2434         if (p_msg)
2435         {
2436             evt_data.data.p_data = (UINT8 *)(p_msg + 1) + p_msg->offset;
2437             evt_data.data.len    = p_msg->len;
2438 
2439             nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data);
2440 
2441             GKI_freebuf (p_msg);
2442         }
2443         else
2444         {
2445             NFA_TRACE_ERROR0 ("nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL data pointer");
2446         }
2447     }
2448     else if (event == NFC_DEACTIVATE_CEVT)
2449     {
2450         NFC_SetStaticRfCback (NULL);
2451     }
2452 }
2453 
2454 
2455 /*******************************************************************************
2456 **
2457 ** Function         nfa_rw_activate_ntf
2458 **
2459 ** Description      Handler for NFA_RW_ACTIVATE_NTF
2460 **
2461 ** Returns          TRUE (message buffer to be freed by caller)
2462 **
2463 *******************************************************************************/
nfa_rw_activate_ntf(tNFA_RW_MSG * p_data)2464 BOOLEAN nfa_rw_activate_ntf(tNFA_RW_MSG *p_data)
2465 {
2466     tNFC_ACTIVATE_DEVT *p_activate_params = p_data->activate_ntf.p_activate_params;
2467     tNFA_TAG_PARAMS    tag_params;
2468     tNFA_RW_OPERATION  msg;
2469     BOOLEAN            activate_notify = TRUE;
2470     UINT8              *p;
2471 
2472     NFA_TRACE_DEBUG0("nfa_rw_activate_ntf");
2473 
2474     /* Initialize control block */
2475     nfa_rw_cb.protocol   = p_activate_params->protocol;
2476     nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp;
2477     nfa_rw_cb.activated_tech_mode = p_activate_params->rf_tech_param.mode;
2478     nfa_rw_cb.flags      = NFA_RW_FL_ACTIVATED;
2479     nfa_rw_cb.cur_op     = NFA_RW_OP_MAX;
2480     nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
2481     nfa_rw_cb.skip_dyn_locks = FALSE;
2482     nfa_rw_cb.ndef_st    = NFA_RW_NDEF_ST_UNKNOWN;
2483     nfa_rw_cb.tlv_st     = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED;
2484 
2485     memset (&tag_params, 0, sizeof(tNFA_TAG_PARAMS));
2486 
2487     /* Check if we are in exclusive RF mode */
2488     if (p_data->activate_ntf.excl_rf_not_active)
2489     {
2490         /* Not in exclusive RF mode */
2491         nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE;
2492     }
2493 
2494     /* check if the protocol is activated with supported interface */
2495     if (p_activate_params->intf_param.type == NCI_INTERFACE_FRAME)
2496     {
2497         if (  (p_activate_params->protocol != NFA_PROTOCOL_T1T)
2498             &&(p_activate_params->protocol != NFA_PROTOCOL_T2T)
2499             &&(p_activate_params->protocol != NFA_PROTOCOL_T3T)
2500             &&(p_activate_params->protocol != NFC_PROTOCOL_15693)  )
2501         {
2502             nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
2503         }
2504     }
2505     else if (p_activate_params->intf_param.type == NCI_INTERFACE_ISO_DEP)
2506     {
2507         if (p_activate_params->protocol != NFA_PROTOCOL_ISO_DEP)
2508         {
2509             nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
2510         }
2511     }
2512 
2513     if (nfa_rw_cb.protocol == NFA_PROTOCOL_INVALID)
2514     {
2515         /* Only sending raw frame and presence check are supported in this state */
2516 
2517         NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
2518 
2519         /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
2520         nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
2521         nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL);
2522         return TRUE;
2523     }
2524 
2525     /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and start presence check if needed */
2526     if (!nfa_dm_is_protocol_supported(p_activate_params->protocol, p_activate_params->rf_tech_param.param.pa.sel_rsp))
2527     {
2528         /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */
2529         /* Set data callback (pass all incoming data to upper layer using NFA_DATA_EVT) */
2530         NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
2531 
2532         /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
2533         nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
2534         nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL);
2535         return TRUE;
2536     }
2537 
2538     /* Initialize RW module */
2539     if ((RW_SetActivatedTagType (p_activate_params, nfa_rw_cback)) != NFC_STATUS_OK)
2540     {
2541         /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
2542         NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
2543         return TRUE;
2544     }
2545 
2546     /* Perform protocol-specific actions */
2547     switch (nfa_rw_cb.protocol)
2548     {
2549     case NFC_PROTOCOL_T1T:
2550         /* Retrieve HR and UID fields from activation notification */
2551         memcpy (tag_params.t1t.hr, p_activate_params->intf_param.intf_param.frame.param, NFA_T1T_HR_LEN);
2552         memcpy (tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
2553         break;
2554 
2555     case NFC_PROTOCOL_T2T:
2556         /* Retrieve UID fields from activation notification */
2557         memcpy (tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
2558         break;
2559 
2560     case NFC_PROTOCOL_T3T:
2561         /* Issue command to get Felica system codes */
2562         activate_notify = FALSE;                    /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system codes are retrieved */
2563         msg.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES;
2564         nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg);
2565         break;
2566 
2567     case NFC_PROTOCOL_15693:
2568         /* Delay notifying upper layer of NFA_ACTIVATED_EVT to retrieve additional tag infomation */
2569         nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING;
2570         activate_notify = FALSE;
2571 
2572         /* store DSFID and UID from activation NTF */
2573         nfa_rw_cb.i93_dsfid = p_activate_params->rf_tech_param.param.pi93.dsfid;
2574 
2575         p = nfa_rw_cb.i93_uid;
2576         ARRAY8_TO_STREAM (p, p_activate_params->rf_tech_param.param.pi93.uid);
2577 
2578         if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI)
2579           &&(((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
2580            ||((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)))
2581         {
2582             /* these don't support Get System Information Command */
2583             nfa_rw_cb.i93_block_size    = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
2584             nfa_rw_cb.i93_afi_location  = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2585 
2586             if ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
2587             {
2588                 nfa_rw_cb.i93_num_block     = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK;
2589             }
2590             else
2591             {
2592                 nfa_rw_cb.i93_num_block     = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK;
2593             }
2594 
2595             /* read AFI */
2596             if (RW_I93ReadSingleBlock ((UINT8)(nfa_rw_cb.i93_afi_location / nfa_rw_cb.i93_block_size)) != NFC_STATUS_OK)
2597             {
2598                 /* notify activation without AFI/IC-Ref */
2599                 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
2600                 activate_notify = TRUE;
2601 
2602                 tag_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE);
2603                 tag_params.i93.dsfid      = nfa_rw_cb.i93_dsfid;
2604                 tag_params.i93.block_size = nfa_rw_cb.i93_block_size;
2605                 tag_params.i93.num_block  = nfa_rw_cb.i93_num_block;
2606                 memcpy (tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
2607             }
2608         }
2609         else
2610         {
2611             /* All of ICODE supports Get System Information Command */
2612             /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */
2613             /* just try for others */
2614 
2615             if (RW_I93GetSysInfo (nfa_rw_cb.i93_uid) != NFC_STATUS_OK)
2616             {
2617                 /* notify activation without AFI/MEM size/IC-Ref */
2618                 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
2619                 activate_notify = TRUE;
2620 
2621                 tag_params.i93.info_flags = I93_INFO_FLAG_DSFID;
2622                 tag_params.i93.dsfid      = nfa_rw_cb.i93_dsfid;
2623                 tag_params.i93.block_size = 0;
2624                 tag_params.i93.num_block  = 0;
2625                 memcpy (tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
2626             }
2627             else
2628             {
2629                 /* reset memory size */
2630                 nfa_rw_cb.i93_block_size = 0;
2631                 nfa_rw_cb.i93_num_block  = 0;
2632             }
2633         }
2634         break;
2635 
2636 
2637     default:
2638         /* No action needed for other protocols */
2639         break;
2640     }
2641 
2642     /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */
2643     if (activate_notify)
2644     {
2645         nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
2646         nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL);
2647     }
2648 
2649 
2650     return TRUE;
2651 }
2652 
2653 
2654 /*******************************************************************************
2655 **
2656 ** Function         nfa_rw_deactivate_ntf
2657 **
2658 ** Description      Handler for NFA_RW_DEACTIVATE_NTF
2659 **
2660 ** Returns          TRUE (message buffer to be freed by caller)
2661 **
2662 *******************************************************************************/
nfa_rw_deactivate_ntf(tNFA_RW_MSG * p_data)2663 BOOLEAN nfa_rw_deactivate_ntf(tNFA_RW_MSG *p_data)
2664 {
2665     /* Clear the activated flag */
2666     nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED;
2667 
2668     /* Free buffer for incoming NDEF message, in case we were in the middle of a read operation */
2669     nfa_rw_free_ndef_rx_buf();
2670 
2671     /* If there is a pending command message, then free it */
2672     if (nfa_rw_cb.p_pending_msg)
2673     {
2674         if (  (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_SEND_RAW_FRAME)
2675             &&(nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data)  )
2676         {
2677             GKI_freebuf(nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data);
2678         }
2679 
2680         GKI_freebuf(nfa_rw_cb.p_pending_msg);
2681         nfa_rw_cb.p_pending_msg = NULL;
2682     }
2683 
2684     /* If we are in the process of waking up tag from HALT state */
2685     if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT)
2686     {
2687         if (nfa_rw_cb.rw_data.data.p_data)
2688             GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
2689         nfa_rw_cb.rw_data.data.p_data = NULL;
2690     }
2691 
2692     /* Stop presence check timer (if started) */
2693     nfa_rw_stop_presence_check_timer();
2694 
2695     return TRUE;
2696 }
2697 
2698 /*******************************************************************************
2699 **
2700 ** Function         nfa_rw_handle_op_req
2701 **
2702 ** Description      Handler for NFA_RW_OP_REQUEST_EVT, operation request
2703 **
2704 ** Returns          TRUE if caller should free p_data
2705 **                  FALSE if caller does not need to free p_data
2706 **
2707 *******************************************************************************/
nfa_rw_handle_op_req(tNFA_RW_MSG * p_data)2708 BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data)
2709 {
2710     BOOLEAN freebuf = TRUE;
2711     UINT16  presence_check_start_delay = 0;
2712 
2713     /* Check if activated */
2714     if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED))
2715     {
2716         NFA_TRACE_ERROR0("nfa_rw_handle_op_req: not activated");
2717         return TRUE;
2718     }
2719     /* Check if currently busy with another API call */
2720     else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY)
2721     {
2722         return (nfa_rw_op_req_while_busy(p_data));
2723     }
2724     /* Check if currently busy with auto-presence check */
2725     else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY)
2726     {
2727         /* Cache the command (will be handled once auto-presence check is completed) */
2728         NFA_TRACE_DEBUG1("Deferring operation %i until after auto-presence check is completed", p_data->op_req.op);
2729         nfa_rw_cb.p_pending_msg = p_data;
2730         nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
2731         return (FALSE);
2732     }
2733 
2734     NFA_TRACE_DEBUG1("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op);
2735 
2736     nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
2737 
2738     /* Stop the presence check timer */
2739     nfa_rw_stop_presence_check_timer();
2740 
2741     /* Store the current operation */
2742     nfa_rw_cb.cur_op = p_data->op_req.op;
2743 
2744     /* Call appropriate handler for requested operation */
2745     switch (p_data->op_req.op)
2746     {
2747     case NFA_RW_OP_DETECT_NDEF:
2748         nfa_rw_cb.skip_dyn_locks = FALSE;
2749         nfa_rw_detect_ndef(p_data);
2750         break;
2751 
2752     case NFA_RW_OP_READ_NDEF:
2753         nfa_rw_read_ndef(p_data);
2754         break;
2755 
2756     case NFA_RW_OP_WRITE_NDEF:
2757         nfa_rw_write_ndef(p_data);
2758         break;
2759 
2760     case NFA_RW_OP_SEND_RAW_FRAME:
2761         presence_check_start_delay = p_data->op_req.params.send_raw_frame.p_data->layer_specific;
2762 
2763         NFC_SendData (NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data);
2764 
2765         /* Clear the busy flag */
2766         nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
2767 
2768         /* Start presence_check after specified delay */
2769         nfa_rw_check_start_presence_check_timer (presence_check_start_delay);
2770         break;
2771 
2772     case NFA_RW_OP_PRESENCE_CHECK:
2773         nfa_rw_presence_check(p_data);
2774         break;
2775 
2776     case NFA_RW_OP_FORMAT_TAG:
2777         nfa_rw_format_tag(p_data);
2778         break;
2779 
2780     case NFA_RW_OP_DETECT_LOCK_TLV:
2781         nfa_rw_detect_tlv(p_data, TAG_LOCK_CTRL_TLV);
2782         break;
2783 
2784     case NFA_RW_OP_DETECT_MEM_TLV:
2785         nfa_rw_detect_tlv(p_data, TAG_MEM_CTRL_TLV);
2786         break;
2787 
2788     case NFA_RW_OP_SET_TAG_RO:
2789         nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock;
2790         nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock);
2791         break;
2792 
2793     case NFA_RW_OP_T1T_RID:
2794         nfa_rw_t1t_rid(p_data);
2795         break;
2796 
2797     case NFA_RW_OP_T1T_RALL:
2798         nfa_rw_t1t_rall(p_data);
2799         break;
2800 
2801     case NFA_RW_OP_T1T_READ:
2802         nfa_rw_t1t_read(p_data);
2803         break;
2804 
2805     case NFA_RW_OP_T1T_WRITE:
2806         nfa_rw_t1t_write(p_data);
2807         break;
2808 
2809     case NFA_RW_OP_T1T_RSEG:
2810         nfa_rw_t1t_rseg(p_data);
2811         break;
2812 
2813     case NFA_RW_OP_T1T_READ8:
2814         nfa_rw_t1t_read8(p_data);
2815         break;
2816 
2817     case NFA_RW_OP_T1T_WRITE8:
2818         nfa_rw_t1t_write8(p_data);
2819         break;
2820 
2821         /* Type-2 tag commands */
2822     case NFA_RW_OP_T2T_READ:
2823         nfa_rw_t2t_read(p_data);
2824         break;
2825 
2826     case NFA_RW_OP_T2T_WRITE:
2827         nfa_rw_t2t_write(p_data);
2828         break;
2829 
2830     case NFA_RW_OP_T2T_SECTOR_SELECT:
2831         nfa_rw_t2t_sector_select(p_data);
2832         break;
2833 
2834         /* Type-3 tag commands */
2835     case NFA_RW_OP_T3T_READ:
2836         nfa_rw_t3t_read(p_data);
2837         break;
2838 
2839     case NFA_RW_OP_T3T_WRITE:
2840         nfa_rw_t3t_write(p_data);
2841         break;
2842 
2843     case NFA_RW_OP_T3T_GET_SYSTEM_CODES:
2844         nfa_rw_t3t_get_system_codes(p_data);
2845         break;
2846 
2847         /* ISO 15693 tag commands */
2848     case NFA_RW_OP_I93_INVENTORY:
2849     case NFA_RW_OP_I93_STAY_QUIET:
2850     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2851     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2852     case NFA_RW_OP_I93_LOCK_BLOCK:
2853     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2854     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2855     case NFA_RW_OP_I93_SELECT:
2856     case NFA_RW_OP_I93_RESET_TO_READY:
2857     case NFA_RW_OP_I93_WRITE_AFI:
2858     case NFA_RW_OP_I93_LOCK_AFI:
2859     case NFA_RW_OP_I93_WRITE_DSFID:
2860     case NFA_RW_OP_I93_LOCK_DSFID:
2861     case NFA_RW_OP_I93_GET_SYS_INFO:
2862     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2863         nfa_rw_i93_command (p_data);
2864         break;
2865 
2866     default:
2867         NFA_TRACE_ERROR1("nfa_rw_handle_api: unhandled operation: %i", p_data->op_req.op);
2868         break;
2869     }
2870 
2871     return (freebuf);
2872 }
2873 
2874 
2875 /*******************************************************************************
2876 **
2877 ** Function         nfa_rw_op_req_while_busy
2878 **
2879 ** Description      Handle operation request while busy
2880 **
2881 ** Returns          TRUE if caller should free p_data
2882 **                  FALSE if caller does not need to free p_data
2883 **
2884 *******************************************************************************/
nfa_rw_op_req_while_busy(tNFA_RW_MSG * p_data)2885 static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data)
2886 {
2887     BOOLEAN             freebuf = TRUE;
2888     tNFA_CONN_EVT_DATA  conn_evt_data;
2889     UINT8               event;
2890 
2891     NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API");
2892 
2893     /* Return appropriate event for requested API, with status=BUSY */
2894     conn_evt_data.status = NFA_STATUS_BUSY;
2895 
2896     switch (p_data->op_req.op)
2897     {
2898     case NFA_RW_OP_DETECT_NDEF:
2899         conn_evt_data.ndef_detect.cur_size = 0;
2900         conn_evt_data.ndef_detect.max_size = 0;
2901         conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
2902         event = NFA_NDEF_DETECT_EVT;
2903         break;
2904     case NFA_RW_OP_READ_NDEF:
2905     case NFA_RW_OP_T1T_RID:
2906     case NFA_RW_OP_T1T_RALL:
2907     case NFA_RW_OP_T1T_READ:
2908     case NFA_RW_OP_T1T_RSEG:
2909     case NFA_RW_OP_T1T_READ8:
2910     case NFA_RW_OP_T2T_READ:
2911     case NFA_RW_OP_T3T_READ:
2912         event = NFA_READ_CPLT_EVT;
2913         break;
2914     case NFA_RW_OP_WRITE_NDEF:
2915     case NFA_RW_OP_T1T_WRITE:
2916     case NFA_RW_OP_T1T_WRITE8:
2917     case NFA_RW_OP_T2T_WRITE:
2918     case NFA_RW_OP_T3T_WRITE:
2919         event = NFA_WRITE_CPLT_EVT;
2920         break;
2921     case NFA_RW_OP_FORMAT_TAG:
2922         event = NFA_FORMAT_CPLT_EVT;
2923         break;
2924         case NFA_RW_OP_DETECT_LOCK_TLV:
2925     case NFA_RW_OP_DETECT_MEM_TLV:
2926         event = NFA_TLV_DETECT_EVT;
2927         break;
2928     case NFA_RW_OP_SET_TAG_RO:
2929         event = NFA_SET_TAG_RO_EVT;
2930         break;
2931     case NFA_RW_OP_T2T_SECTOR_SELECT:
2932         event = NFA_SELECT_CPLT_EVT;
2933         break;
2934     case NFA_RW_OP_I93_INVENTORY:
2935     case NFA_RW_OP_I93_STAY_QUIET:
2936     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2937     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2938     case NFA_RW_OP_I93_LOCK_BLOCK:
2939     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2940     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2941     case NFA_RW_OP_I93_SELECT:
2942     case NFA_RW_OP_I93_RESET_TO_READY:
2943     case NFA_RW_OP_I93_WRITE_AFI:
2944     case NFA_RW_OP_I93_LOCK_AFI:
2945     case NFA_RW_OP_I93_WRITE_DSFID:
2946     case NFA_RW_OP_I93_LOCK_DSFID:
2947     case NFA_RW_OP_I93_GET_SYS_INFO:
2948     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2949         event = NFA_I93_CMD_CPLT_EVT;
2950         break;
2951     default:
2952         return (freebuf);
2953     }
2954     nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
2955 
2956     return (freebuf);
2957 }
2958 
2959 /*******************************************************************************
2960 **
2961 ** Function         nfa_rw_command_complete
2962 **
2963 ** Description      Handle command complete: clear the busy flag,
2964 **                  and start the presence check timer if applicable.
2965 **
2966 ** Returns          None
2967 **
2968 *******************************************************************************/
nfa_rw_command_complete(void)2969 void nfa_rw_command_complete(void)
2970 {
2971     /* Clear the busy flag */
2972     nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
2973 
2974     /* Restart presence_check timer */
2975     nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL);
2976 }
2977