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