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