1 /******************************************************************************
2  *
3  *  Copyright (C) 2011-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_CE state machine.
23  *
24  ******************************************************************************/
25 #include <string.h>
26 #include "nfa_ce_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 "ce_api.h"
32 #if (NFC_NFCEE_INCLUDED == TRUE)
33 #include "nfa_ee_int.h"
34 #endif
35 
36 /*****************************************************************************
37 * Protocol-specific event handlers
38 *****************************************************************************/
39 
40 /*******************************************************************************
41 **
42 ** Function         nfa_ce_handle_t3t_evt
43 **
44 ** Description      Handler for Type-3 tag card emulation events
45 **
46 ** Returns          Nothing
47 **
48 *******************************************************************************/
nfa_ce_handle_t3t_evt(tCE_EVENT event,tCE_DATA * p_ce_data)49 void nfa_ce_handle_t3t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
50 {
51     tNFA_CE_CB *p_cb = &nfa_ce_cb;
52     tNFA_CONN_EVT_DATA conn_evt;
53 
54     NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt: event 0x%x", event);
55 
56     switch (event)
57     {
58     case CE_T3T_NDEF_UPDATE_START_EVT:
59         /* Notify app using callback associated with the active ndef */
60         if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
61         {
62             conn_evt.status = NFA_STATUS_OK;
63             (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
64         }
65         else
66         {
67             NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_START_EVT, but no active NDEF");
68         }
69         break;
70 
71     case CE_T3T_NDEF_UPDATE_CPLT_EVT:
72         /* Notify app using callback associated with the active ndef */
73         if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
74         {
75             conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
76             conn_evt.ndef_write_cplt.len    = p_ce_data->update_info.length;
77             conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
78             (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
79         }
80         else
81         {
82             NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_CPLT_EVT, but no active NDEF");
83         }
84         break;
85 
86     case CE_T3T_RAW_FRAME_EVT:
87         if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
88         {
89             conn_evt.data.status = p_ce_data->raw_frame.status;
90             conn_evt.data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
91             conn_evt.data.len    = p_ce_data->raw_frame.p_data->len;
92             (*p_cb->p_active_conn_cback) (NFA_DATA_EVT, &conn_evt);
93         }
94         else
95         {
96             conn_evt.ce_data.status = p_ce_data->raw_frame.status;
97             conn_evt.ce_data.handle = (NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active));
98             conn_evt.ce_data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
99             conn_evt.ce_data.len    = p_ce_data->raw_frame.p_data->len;
100             (*p_cb->p_active_conn_cback) (NFA_CE_DATA_EVT, &conn_evt);
101         }
102         GKI_freebuf (p_ce_data->raw_frame.p_data);
103         break;
104 
105     default:
106         NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt unhandled event=0x%02x", event);
107         break;
108     }
109 }
110 
111 /*******************************************************************************
112 **
113 ** Function         nfa_ce_handle_t4t_evt
114 **
115 ** Description      Handler for Type-4 tag card emulation events (for NDEF case)
116 **
117 ** Returns          Nothing
118 **
119 *******************************************************************************/
nfa_ce_handle_t4t_evt(tCE_EVENT event,tCE_DATA * p_ce_data)120 void nfa_ce_handle_t4t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
121 {
122     tNFA_CE_CB *p_cb = &nfa_ce_cb;
123     tNFA_CONN_EVT_DATA conn_evt;
124 
125     NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt: event 0x%x", event);
126 
127     /* AID for NDEF selected. we had notified the app of activation. */
128     p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_NDEF;
129     if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
130     {
131         p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
132     }
133 
134     switch (event)
135     {
136     case CE_T4T_NDEF_UPDATE_START_EVT:
137         conn_evt.status = NFA_STATUS_OK;
138         (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
139         break;
140 
141     case CE_T4T_NDEF_UPDATE_CPLT_EVT:
142         conn_evt.ndef_write_cplt.len    = p_ce_data->update_info.length;
143         conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
144 
145         if (NDEF_MsgValidate (p_ce_data->update_info.p_data, p_ce_data->update_info.length, TRUE) != NDEF_OK)
146             conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
147         else
148             conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
149 
150         (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
151         break;
152 
153     case CE_T4T_NDEF_UPDATE_ABORT_EVT:
154         conn_evt.ndef_write_cplt.len    = 0;
155         conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
156         conn_evt.ndef_write_cplt.p_data = NULL;
157         (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
158         break;
159 
160     default:
161         /* CE_T4T_RAW_FRAME_EVT is not used in NFA CE */
162         NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt unhandled event=0x%02x", event);
163         break;
164     }
165 }
166 
167 
168 /*******************************************************************************
169 **
170 ** Function         nfa_ce_handle_t4t_aid_evt
171 **
172 ** Description      Handler for Type-4 tag AID events (for AIDs registered using
173 **                  NFA_CeRegisterT4tAidOnDH)
174 **
175 ** Returns          Nothing
176 **
177 *******************************************************************************/
nfa_ce_handle_t4t_aid_evt(tCE_EVENT event,tCE_DATA * p_ce_data)178 void nfa_ce_handle_t4t_aid_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
179 {
180     tNFA_CE_CB *p_cb = &nfa_ce_cb;
181     UINT8 listen_info_idx;
182     tNFA_CONN_EVT_DATA conn_evt;
183 
184     NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_aid_evt: event 0x%x", event);
185 
186     /* Get listen_info for this aid callback */
187     for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
188     {
189         if ((p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
190             (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID) &&
191             (p_cb->listen_info[listen_info_idx].t4t_aid_handle == p_ce_data->raw_frame.aid_handle))
192         {
193             p_cb->idx_cur_active      = listen_info_idx;
194             p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
195             break;
196         }
197     }
198 
199     if (event == CE_T4T_RAW_FRAME_EVT)
200     {
201         if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
202         {
203             /* Found listen_info entry */
204             conn_evt.ce_activated.handle =   NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE) p_cb->idx_cur_active);
205 
206             /* If we have not notified the app of activation, do so now */
207             if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
208             {
209                 p_cb->listen_info[p_cb->idx_cur_active].flags &= ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
210 
211                 memcpy (&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
212                 conn_evt.ce_activated.status = NFA_STATUS_OK;
213                 (*p_cb->p_active_conn_cback) (NFA_CE_ACTIVATED_EVT, &conn_evt);
214             }
215 
216             /* Notify app of AID data */
217             conn_evt.ce_data.status = p_ce_data->raw_frame.status;
218             conn_evt.ce_data.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
219             conn_evt.ce_data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
220             conn_evt.ce_data.len    = p_ce_data->raw_frame.p_data->len;
221             (*p_cb->p_active_conn_cback) (NFA_CE_DATA_EVT, &conn_evt);
222         }
223         else
224         {
225             NFA_TRACE_ERROR1 ("nfa_ce_handle_t4t_aid_evt: unable to find listen_info for aid hdl %i", p_ce_data->raw_frame.aid_handle)
226         }
227 
228         GKI_freebuf (p_ce_data->raw_frame.p_data);
229     }
230 }
231 
232 /*****************************************************************************
233 * Discovery configuration and discovery event handlers
234 *****************************************************************************/
235 
236 /*******************************************************************************
237 **
238 ** Function         nfa_ce_discovery_cback
239 **
240 ** Description      Processing event from discovery callback
241 **
242 ** Returns          None
243 **
244 *******************************************************************************/
nfa_ce_discovery_cback(tNFA_DM_RF_DISC_EVT event,tNFC_DISCOVER * p_data)245 void nfa_ce_discovery_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
246 {
247     tNFA_CE_MSG ce_msg;
248     NFA_TRACE_DEBUG1 ("nfa_ce_discovery_cback(): event:0x%02X", event);
249 
250     switch (event)
251     {
252     case NFA_DM_RF_DISC_START_EVT:
253         NFA_TRACE_DEBUG1 ("nfa_ce_handle_disc_start (status=0x%x)", p_data->start);
254         break;
255 
256     case NFA_DM_RF_DISC_ACTIVATED_EVT:
257         ce_msg.activate_ntf.hdr.event = NFA_CE_ACTIVATE_NTF_EVT;
258         ce_msg.activate_ntf.p_activation_params = &p_data->activate;
259         nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
260         break;
261 
262     case NFA_DM_RF_DISC_DEACTIVATED_EVT:
263         /* DM broadcasts deactivaiton event in listen sleep state, so check before processing */
264         if (nfa_ce_cb.flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
265         {
266             ce_msg.hdr.event = NFA_CE_DEACTIVATE_NTF_EVT;
267             ce_msg.hdr.layer_specific = p_data->deactivate.type;
268             nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
269         }
270         break;
271 
272     default:
273         NFA_TRACE_ERROR0 ("Unexpected event");
274         break;
275     }
276 }
277 
278 /*******************************************************************************
279 **
280 ** Function         nfc_ce_t3t_set_listen_params
281 **
282 ** Description      Set t3t listening parameters
283 **
284 ** Returns          Nothing
285 **
286 *******************************************************************************/
nfc_ce_t3t_set_listen_params(void)287 void nfc_ce_t3t_set_listen_params (void)
288 {
289     UINT8 i;
290     tNFA_CE_CB *p_cb = &nfa_ce_cb;
291     UINT8 tlv[32], *p_params;
292     UINT8 tlv_size;
293     UINT16 t3t_flags2_mask = 0xFFFF;        /* Mask of which T3T_IDs are disabled */
294     UINT8 t3t_idx = 0;
295 
296     /* Point to start of tlv buffer */
297     p_params = tlv;
298 
299     /* Set system code and NFCID2 */
300     for (i=0; i<NFA_CE_LISTEN_INFO_MAX; i++)
301     {
302         if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
303             (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
304         {
305             /* Set tag's system code and NFCID2 */
306             UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_ID1+t3t_idx);                 /* type */
307             UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_ID);                     /* length */
308             UINT16_TO_BE_STREAM (p_params, p_cb->listen_info[i].t3t_system_code);    /* System Code */
309             ARRAY_TO_BE_STREAM (p_params,  p_cb->listen_info[i].t3t_nfcid2, NCI_RF_F_UID_LEN);
310 
311             /* Set mask for this ID */
312             t3t_flags2_mask &= ~((UINT16) (1<<t3t_idx));
313             t3t_idx++;
314         }
315     }
316 
317     /* For NCI draft 22+, the polarity of NFC_PMID_LF_T3T_FLAGS2 is flipped */
318     t3t_flags2_mask = ~t3t_flags2_mask;
319 
320     UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_FLAGS2);      /* type */
321     UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_FLAGS2); /* length */
322     UINT16_TO_STREAM (p_params, t3t_flags2_mask);            /* Mask of IDs to disable listening */
323 
324     tlv_size = (UINT8) (p_params-tlv);
325     nfa_dm_check_set_config (tlv_size, (UINT8 *)tlv, FALSE);
326 }
327 
328 /*******************************************************************************
329 **
330 ** Function         nfa_ce_t3t_generate_rand_nfcid
331 **
332 ** Description      Generate a random NFCID2 for Type-3 tag
333 **
334 ** Returns          Nothing
335 **
336 *******************************************************************************/
nfa_ce_t3t_generate_rand_nfcid(UINT8 nfcid2[NCI_RF_F_UID_LEN])337 void nfa_ce_t3t_generate_rand_nfcid (UINT8 nfcid2[NCI_RF_F_UID_LEN])
338 {
339     UINT32 rand_seed = GKI_get_tick_count ();
340 
341     /* For Type-3 tag, nfcid2 starts witn 02:fe */
342     nfcid2[0] = 0x02;
343     nfcid2[1] = 0xFE;
344 
345     /* The remaining 6 bytes are random */
346     nfcid2[2] = (UINT8) (rand_seed & 0xFF);
347     nfcid2[3] = (UINT8) (rand_seed>>8 & 0xFF);
348     rand_seed>>=(rand_seed&3);
349     nfcid2[4] = (UINT8) (rand_seed & 0xFF);
350     nfcid2[5] = (UINT8) (rand_seed>>8 & 0xFF);
351     rand_seed>>=(rand_seed&3);
352     nfcid2[6] = (UINT8) (rand_seed & 0xFF);
353     nfcid2[7] = (UINT8) (rand_seed>>8 & 0xFF);
354 }
355 
356 /*******************************************************************************
357 **
358 ** Function         nfa_ce_start_listening
359 **
360 ** Description      Start listening
361 **
362 ** Returns          NFA_STATUS_OK if successful
363 **
364 *******************************************************************************/
nfa_ce_start_listening(void)365 tNFA_STATUS nfa_ce_start_listening (void)
366 {
367     tNFA_DM_DISC_TECH_PROTO_MASK listen_mask;
368     tNFA_CE_CB    *p_cb = &nfa_ce_cb;
369     tNFA_HANDLE   disc_handle;
370     UINT8         listen_info_idx;
371 
372     /*************************************************************************/
373     /* Construct protocol preference list to listen for */
374 
375     /* First, get protocol preference for active NDEF (if any) */
376     if (  (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
377         &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle == NFA_HANDLE_INVALID))
378     {
379         listen_mask = 0;
380 
381         if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_T3T)
382         {
383             /* set T3T config params */
384             nfc_ce_t3t_set_listen_params ();
385 
386             listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
387         }
388 
389         if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
390         {
391             listen_mask |= nfa_ce_cb.isodep_disc_mask;
392         }
393 
394         disc_handle = nfa_dm_add_rf_discover (listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_ce_discovery_cback);
395 
396         if (disc_handle == NFA_HANDLE_INVALID)
397             return (NFA_STATUS_FAILED);
398         else
399             p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = disc_handle;
400     }
401 
402     /* Next, add protocols from non-NDEF, if any */
403     for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
404     {
405         /* add RF discovery to DM only if it is not added yet */
406         if (  (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
407             &&(p_cb->listen_info[listen_info_idx].rf_disc_handle == NFA_HANDLE_INVALID))
408         {
409             if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_FELICA)
410             {
411                 /* set T3T config params */
412                 nfc_ce_t3t_set_listen_params ();
413 
414                 disc_handle = nfa_dm_add_rf_discover (NFA_DM_DISC_MASK_LF_T3T,
415                                                       NFA_DM_DISC_HOST_ID_DH,
416                                                       nfa_ce_discovery_cback);
417 
418                 if (disc_handle == NFA_HANDLE_INVALID)
419                     return (NFA_STATUS_FAILED);
420                 else
421                     p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
422             }
423             else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID)
424             {
425                 disc_handle = nfa_dm_add_rf_discover (nfa_ce_cb.isodep_disc_mask,
426                                                        NFA_DM_DISC_HOST_ID_DH,
427                                                        nfa_ce_discovery_cback);
428 
429                 if (disc_handle == NFA_HANDLE_INVALID)
430                     return (NFA_STATUS_FAILED);
431                 else
432                     p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
433             }
434 #if (NFC_NFCEE_INCLUDED == TRUE)
435             else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
436             {
437                 listen_mask = 0;
438                 if (nfa_ee_is_active (p_cb->listen_info[listen_info_idx].ee_handle))
439                 {
440                     if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_A)
441                     {
442                         listen_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
443                     }
444                     if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_B)
445                     {
446                         listen_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
447                     }
448                     if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_F)
449                     {
450                         listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
451                     }
452                     if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
453                     {
454                         listen_mask |= NFA_DM_DISC_MASK_L_B_PRIME;
455                     }
456                 }
457 
458                 if (listen_mask)
459                 {
460                     /* Start listening for requested technologies */
461                     /* register discovery callback to NFA DM */
462                     disc_handle = nfa_dm_add_rf_discover (listen_mask,
463                                                           (tNFA_DM_DISC_HOST_ID) (p_cb->listen_info[listen_info_idx].ee_handle &0x00FF),
464                                                           nfa_ce_discovery_cback);
465 
466                     if (disc_handle == NFA_HANDLE_INVALID)
467                         return (NFA_STATUS_FAILED);
468                     else
469                     {
470                         p_cb->listen_info[listen_info_idx].rf_disc_handle  = disc_handle;
471                         p_cb->listen_info[listen_info_idx].tech_proto_mask = listen_mask;
472                     }
473                 }
474                 else
475                 {
476                     NFA_TRACE_ERROR1 ("UICC[0x%x] is not activated",
477                                        p_cb->listen_info[listen_info_idx].ee_handle);
478                 }
479             }
480 #endif
481         }
482     }
483 
484     return NFA_STATUS_OK;
485 }
486 
487 /*******************************************************************************
488 **
489 ** Function         nfa_ce_restart_listen_check
490 **
491 ** Description      Called on deactivation. Check if any active listen_info entries to listen for
492 **
493 ** Returns          TRUE if listening is restarted.
494 **                  FALSE if listening not restarted
495 **
496 *******************************************************************************/
nfa_ce_restart_listen_check(void)497 BOOLEAN nfa_ce_restart_listen_check (void)
498 {
499     tNFA_CE_CB *p_cb = &nfa_ce_cb;
500     UINT8 listen_info_idx;
501 
502     /* Check if any active entries in listen_info table */
503     for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
504     {
505         if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
506             break;
507     }
508 
509     /* Restart listening if there are any active listen_info entries */
510     if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
511     {
512         /* restart listening */
513         nfa_ce_start_listening ();
514     }
515     else
516     {
517         /* No active listen_info entries */
518         return FALSE;
519     }
520 
521     return TRUE;
522 }
523 
524 /*******************************************************************************
525 **
526 ** Function         nfa_ce_remove_listen_info_entry
527 **
528 ** Description      Remove entry from listen_info table. (when API deregister is called or listen_start failed)
529 **
530 **
531 ** Returns          Nothing
532 **
533 *******************************************************************************/
nfa_ce_remove_listen_info_entry(UINT8 listen_info_idx,BOOLEAN notify_app)534 void nfa_ce_remove_listen_info_entry (UINT8 listen_info_idx, BOOLEAN notify_app)
535 {
536     tNFA_CE_CB *p_cb = &nfa_ce_cb;
537     tNFA_CONN_EVT_DATA conn_evt;
538 
539     NFA_TRACE_DEBUG1 ("NFA_CE: removing listen_info entry %i", listen_info_idx);
540 
541     /* Notify app that listening has stopped  if requested (for API deregister) */
542     /* For LISTEN_START failures, app has already notified of NFA_LISTEN_START_EVT failure */
543     if (notify_app)
544     {
545         if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF)
546         {
547             conn_evt.status = NFA_STATUS_OK;
548             (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
549         }
550 #if (NFC_NFCEE_INCLUDED == TRUE)
551         else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
552         {
553             conn_evt.status = NFA_STATUS_OK;
554             (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
555         }
556 #endif
557         else
558         {
559             conn_evt.ce_deregistered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
560             (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_DEREGISTERED_EVT, &conn_evt);
561         }
562     }
563 
564 
565     /* Handle NDEF stopping */
566     if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF)
567     {
568         /* clear NDEF contents */
569         CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
570         CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
571 
572         if (p_cb->listen_info[listen_info_idx].protocol_mask & NFA_PROTOCOL_MASK_T3T)
573         {
574             p_cb->listen_info[listen_info_idx].protocol_mask = 0;
575 
576             /* clear T3T Flags for NDEF */
577             nfc_ce_t3t_set_listen_params ();
578         }
579 
580         /* Free scratch buffer for this NDEF, if one was allocated */
581         nfa_ce_free_scratch_buf ();
582     }
583     /* If stopping listening Felica system code, then clear T3T Flags for this */
584     else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_FELICA)
585     {
586         p_cb->listen_info[listen_info_idx].protocol_mask = 0;
587 
588         /* clear T3T Flags for registered Felica system code */
589         nfc_ce_t3t_set_listen_params ();
590     }
591     /* If stopping listening T4T AID, then deregister this AID from CE_T4T */
592     else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID)
593     {
594         /* Free t4t_aid_cback used by this AID */
595         CE_T4tDeregisterAID (p_cb->listen_info[listen_info_idx].t4t_aid_handle);
596     }
597 
598     if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID )
599     {
600         nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
601         p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
602     }
603 
604     /* Remove entry from listen_info table */
605     p_cb->listen_info[listen_info_idx].flags = 0;
606 }
607 
608 /*******************************************************************************
609 **
610 ** Function         nfa_ce_free_scratch_buf
611 **
612 ** Description      free scratch buffer (if one is allocated)
613 **
614 ** Returns          nothing
615 **
616 *******************************************************************************/
nfa_ce_free_scratch_buf(void)617 void nfa_ce_free_scratch_buf (void)
618 {
619     tNFA_CE_CB *p_cb = &nfa_ce_cb;
620     if (p_cb->p_scratch_buf)
621     {
622         nfa_mem_co_free (p_cb->p_scratch_buf);
623         p_cb->p_scratch_buf = NULL;
624     }
625 }
626 
627 /*******************************************************************************
628 **
629 ** Function         nfa_ce_realloc_scratch_buffer
630 **
631 ** Description      Set scratch buffer if necessary (for writable NDEF messages)
632 **
633 ** Returns          NFA_STATUS_OK if successful
634 **
635 *******************************************************************************/
nfa_ce_realloc_scratch_buffer(void)636 tNFA_STATUS nfa_ce_realloc_scratch_buffer (void)
637 {
638     tNFA_STATUS result = NFA_STATUS_OK;
639 
640     /* If current NDEF message is read-only, then we do not need a scratch buffer */
641     if (nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFC_CE_LISTEN_INFO_READONLY_NDEF)
642     {
643         /* Free existing scratch buffer, if one was allocated */
644         nfa_ce_free_scratch_buf ();
645     }
646     else
647     {
648         /* If no scratch buffer allocated yet, or if current scratch buffer size is different from current ndef size, */
649         /* then allocate a new scratch buffer. */
650         if ((nfa_ce_cb.p_scratch_buf == NULL) ||
651             (nfa_ce_cb.scratch_buf_size != nfa_ce_cb.ndef_max_size))
652         {
653             /* Free existing scratch buffer, if one was allocated */
654             nfa_ce_free_scratch_buf ();
655 
656             if ((nfa_ce_cb.p_scratch_buf = (UINT8 *) nfa_mem_co_alloc (nfa_ce_cb.ndef_max_size)) != NULL)
657             {
658                 nfa_ce_cb.scratch_buf_size = nfa_ce_cb.ndef_max_size;
659             }
660             else
661             {
662                 NFA_TRACE_ERROR1 ("Unable to allocate scratch buffer for writable NDEF message (%i bytes)", nfa_ce_cb.ndef_max_size);
663                 result=NFA_STATUS_FAILED;
664             }
665         }
666     }
667 
668     return (result);
669 }
670 
671 /*******************************************************************************
672 **
673 ** Function         nfa_ce_set_content
674 **
675 ** Description      Set NDEF contents
676 **
677 ** Returns          void
678 **
679 *******************************************************************************/
nfa_ce_set_content(void)680 tNFC_STATUS nfa_ce_set_content (void)
681 {
682     tNFC_STATUS status;
683     tNFA_CE_CB *p_cb = &nfa_ce_cb;
684     tNFA_PROTOCOL_MASK ndef_protocol_mask;
685     BOOLEAN readonly;
686 
687     /* Check if listening for NDEF */
688     if (!(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE))
689     {
690         /* Not listening for NDEF */
691         return (NFA_STATUS_OK);
692     }
693 
694     NFA_TRACE_DEBUG0 ("Setting NDEF contents");
695 
696     readonly = (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFC_CE_LISTEN_INFO_READONLY_NDEF) ? TRUE : FALSE;
697     ndef_protocol_mask = p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask;
698 
699     /* Allocate a scratch buffer if needed (for handling write-requests) */
700     if ((status = nfa_ce_realloc_scratch_buffer ()) == NFA_STATUS_OK)
701     {
702         if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_T3T) && (status == NFA_STATUS_OK))
703         {
704             /* Type3Tag    - NFC-F */
705             status = CE_T3tSetLocalNDEFMsg (readonly,
706                                             p_cb->ndef_max_size,
707                                             p_cb->ndef_cur_size,
708                                             p_cb->p_ndef_data,
709                                             p_cb->p_scratch_buf);
710         }
711 
712         if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) && (status == NFA_STATUS_OK))
713         {
714             /* ISODEP/4A,4B- NFC-A or NFC-B */
715             status = CE_T4tSetLocalNDEFMsg (readonly,
716                                             p_cb->ndef_max_size,
717                                             p_cb->ndef_cur_size,
718                                             p_cb->p_ndef_data,
719                                             p_cb->p_scratch_buf);
720         }
721     }
722 
723     if (status != NFA_STATUS_OK)
724     {
725         /* clear NDEF contents */
726         CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
727         CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
728 
729         NFA_TRACE_ERROR1 ("Unable to set contents (error %02x)", status);
730     }
731 
732     return (status);
733 }
734 
735 
736 /*******************************************************************************
737 **
738 ** Function         nfa_ce_activate_ntf
739 **
740 ** Description      Action when activation has occured (NFA_CE_ACTIVATE_NTF_EVT)
741 **
742 **                  - Find the listen_info entry assocated with this activation
743 **                      - get the app callback that registered for this listen
744 **                      - call CE_SetActivatedTagType with activation parameters
745 **
746 ** Returns          TRUE (message buffer to be freed by caller)
747 **
748 *******************************************************************************/
nfa_ce_activate_ntf(tNFA_CE_MSG * p_ce_msg)749 BOOLEAN nfa_ce_activate_ntf (tNFA_CE_MSG *p_ce_msg)
750 {
751     tNFC_ACTIVATE_DEVT *p_activation_params = p_ce_msg->activate_ntf.p_activation_params;
752     tNFA_CE_CB *p_cb = &nfa_ce_cb;
753     tNFA_CONN_EVT_DATA conn_evt;
754     tCE_CBACK *p_ce_cback = NULL;
755     UINT16 t3t_system_code = 0xFFFF;
756     UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
757     UINT8 *p_nfcid2 = NULL;
758     UINT8 i;
759     BOOLEAN t4t_activate_pending = FALSE;
760 
761     NFA_TRACE_DEBUG1 ("nfa_ce_activate_ntf () protocol=%d", p_ce_msg->activate_ntf.p_activation_params->protocol);
762 
763     /* Tag is in listen active state */
764     p_cb->flags |= NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
765 
766     /* Store activation parameters */
767     memcpy (&p_cb->activation_params, p_activation_params, sizeof (tNFC_ACTIVATE_DEVT));
768 
769     /* Find the listen_info entry corresponding to this activation */
770     if (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
771     {
772         /* Look for T3T entries in listen_info table that match activated system code and NFCID2 */
773         for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
774         {
775             /* Look for entries with NFA_PROTOCOL_MASK_T3T */
776             if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
777             {
778                 if (p_cb->listen_info[listen_info_idx].protocol_mask & NFA_PROTOCOL_MASK_T3T)
779                 {
780                     /* Check if system_code and nfcid2 that matches activation params */
781                     p_nfcid2 = p_cb->listen_info[listen_info_idx].t3t_nfcid2;
782                     t3t_system_code = p_cb->listen_info[listen_info_idx].t3t_system_code;
783 
784                     /* Compare NFCID2 (note: NFCC currently does not return system code in activation parameters) */
785                     if ((memcmp (p_nfcid2, p_cb->activation_params.rf_tech_param.param.lf.nfcid2, NCI_RF_F_UID_LEN)==0)
786                          /* && (t3t_system_code == p_ce_msg->activation.p_activate_info->rf_tech_param.param.lf.system_code) */)
787                     {
788                         /* Found listen_info corresponding to this activation */
789                         break;
790                     }
791                 }
792 
793                 /* Check if entry is for T3T UICC */
794                 if ((p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC) &&
795                     (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_F))
796                 {
797                     break;
798                 }
799             }
800         }
801 
802         p_ce_cback = nfa_ce_handle_t3t_evt;
803     }
804     else if (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
805     {
806         p_ce_cback = nfa_ce_handle_t4t_evt;
807 
808         /* For T4T, we do not know which AID will be selected yet */
809 
810 
811         /* For all T4T entries in listen_info, set T4T_ACTIVATE_NOTIFY_PENDING flag */
812         for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
813         {
814             if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
815             {
816                 if (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
817                 {
818                     /* Found listen_info table entry for T4T raw listen */
819                     p_cb->listen_info[i].flags |= NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
820 
821                     /* If entry if for NDEF, select it, so application gets nofitifed of ACTIVATE_EVT now */
822                     if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
823                     {
824                         listen_info_idx = NFA_CE_LISTEN_INFO_IDX_NDEF;
825                     }
826 
827                     t4t_activate_pending = TRUE;
828                 }
829 
830 #if (NFC_NFCEE_INCLUDED == TRUE)
831                 /* Check if entry is for ISO_DEP UICC */
832                 if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
833                 {
834                     if (  (  (p_cb->activation_params.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A)
835                            &&(p_cb->listen_info[i].tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP)  )
836                                                        ||
837                           (  (p_cb->activation_params.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B)
838                            &&(p_cb->listen_info[i].tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)  )  )
839                     {
840                         listen_info_idx = i;
841                     }
842                 }
843 #endif
844             }
845         }
846 
847         /* If listening for ISO_DEP, but not NDEF nor UICC, then notify CE module now and wait for reader/writer to SELECT an AID */
848         if (t4t_activate_pending && (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID))
849         {
850             CE_SetActivatedTagType (&p_cb->activation_params, 0, p_ce_cback);
851             return TRUE;
852         }
853     }
854     else if (p_cb->activation_params.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
855     {
856         /* search any entry listening UICC */
857         for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
858         {
859             if (  (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
860                 &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC))
861             {
862                 listen_info_idx = i;
863                 break;
864             }
865         }
866     }
867 
868     /* Check if valid listen_info entry was found */
869     if (  (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)
870         ||((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) && !(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)))
871     {
872         NFA_TRACE_DEBUG1 ("No listen_info found for this activation. listen_info_idx=%d", listen_info_idx);
873         return (TRUE);
874     }
875 
876     p_cb->listen_info[listen_info_idx].flags &= ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
877 
878     /* Get CONN_CBACK for this activation */
879     p_cb->p_active_conn_cback = p_cb->listen_info[listen_info_idx].p_conn_cback;
880     p_cb->idx_cur_active = listen_info_idx;
881 
882     if (  (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
883         ||(p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_UICC))
884     {
885         memcpy (&(conn_evt.activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
886 
887         (*p_cb->p_active_conn_cback) (NFA_ACTIVATED_EVT, &conn_evt);
888     }
889     else
890     {
891         conn_evt.ce_activated.handle =   NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
892         memcpy (&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
893         conn_evt.ce_activated.status = NFA_STATUS_OK;
894 
895         (*p_cb->p_active_conn_cback) (NFA_CE_ACTIVATED_EVT, &conn_evt);
896     }
897 
898     /* we don't need any CE subsystem in case of NFCEE direct RF interface */
899     if (p_ce_cback)
900     {
901         /* Notify CE subsystem */
902         CE_SetActivatedTagType (&p_cb->activation_params, t3t_system_code, p_ce_cback);
903     }
904     return TRUE;
905 }
906 
907 /*******************************************************************************
908 **
909 ** Function         nfa_ce_deactivate_ntf
910 **
911 ** Description      Action when deactivate occurs. (NFA_CE_DEACTIVATE_NTF_EVT)
912 **
913 **                  - If deactivate due to API deregister, then remove its entry from
914 **                      listen_info table
915 **
916 **                  - If NDEF was modified while activated, then restore
917 **                      original NDEF contents
918 **
919 **                  - Restart listening (if any active entries in listen table)
920 **
921 ** Returns          TRUE (message buffer to be freed by caller)
922 **
923 *******************************************************************************/
nfa_ce_deactivate_ntf(tNFA_CE_MSG * p_ce_msg)924 BOOLEAN nfa_ce_deactivate_ntf (tNFA_CE_MSG *p_ce_msg)
925 {
926     tNFC_DEACT_TYPE deact_type = (tNFC_DEACT_TYPE) p_ce_msg->hdr.layer_specific;
927     tNFA_CE_CB *p_cb = &nfa_ce_cb;
928     tNFA_CONN_EVT_DATA conn_evt;
929     UINT8 i;
930 
931     NFA_TRACE_DEBUG1 ("nfa_ce_deactivate_ntf () deact_type=%d", deact_type);
932 
933     /* Check if deactivating to SLEEP mode */
934     if (  (deact_type == NFC_DEACTIVATE_TYPE_SLEEP)
935         ||(deact_type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
936     {
937         if ( nfa_ce_cb.idx_wild_card == NFA_CE_LISTEN_INFO_IDX_INVALID)
938         {
939             /* notify deactivated as sleep and wait for reactivation or deactivation to idle */
940             conn_evt.deactivated.type =  deact_type;
941 
942             /* if T4T AID application has not been selected then p_active_conn_cback could be NULL */
943             if (p_cb->p_active_conn_cback)
944                 (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
945         }
946         else
947         {
948             conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)nfa_ce_cb.idx_wild_card);
949             conn_evt.ce_deactivated.type   = deact_type;
950             if (p_cb->p_active_conn_cback)
951                 (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
952         }
953 
954         return TRUE;
955     }
956     else
957     {
958         deact_type = NFC_DEACTIVATE_TYPE_IDLE;
959     }
960 
961     /* Tag is in idle state */
962     p_cb->flags &= ~NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
963 
964     /* First, notify app of deactivation */
965     for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
966     {
967         if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
968         {
969             if (  (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
970                 &&(i == p_cb->idx_cur_active)  )
971             {
972                 conn_evt.deactivated.type =  deact_type;
973                 (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
974             }
975             else if (  (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
976                      &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP))
977             {
978                 /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
979                 if (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND))
980                 {
981                     if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
982                     {
983                         conn_evt.deactivated.type =  deact_type;
984                         (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
985                     }
986                     else
987                     {
988                         conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
989                         conn_evt.ce_deactivated.type   = deact_type;
990                         (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
991                     }
992                 }
993             }
994             else if (  (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
995                      &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
996             {
997                 if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
998                 {
999                     conn_evt.deactivated.type = deact_type;
1000                     (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
1001                 }
1002                 else
1003                 {
1004                     conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
1005                     conn_evt.ce_deactivated.type   = deact_type;
1006                     (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
1007                 }
1008             }
1009         }
1010     }
1011 
1012     /* Check if app initiated the deactivation (due to API deregister). If so, remove entry from listen_info table. */
1013     if (p_cb->flags & NFA_CE_FLAGS_APP_INIT_DEACTIVATION)
1014     {
1015         p_cb->flags &= ~NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1016         nfa_ce_remove_listen_info_entry (p_cb->idx_cur_active, TRUE);
1017     }
1018 
1019     p_cb->p_active_conn_cback = NULL;
1020     p_cb->idx_cur_active      = NFA_CE_LISTEN_INFO_IDX_INVALID;
1021 
1022     /* Restart listening (if any listen_info entries are still active) */
1023     nfa_ce_restart_listen_check ();
1024 
1025     return TRUE;
1026 }
1027 
1028 /*******************************************************************************
1029 **
1030 ** Function         nfa_ce_disable_local_tag
1031 **
1032 ** Description      Disable local NDEF tag
1033 **                      - clean up control block
1034 **                      - remove NDEF discovery configuration
1035 **
1036 ** Returns          Nothing
1037 **
1038 *******************************************************************************/
nfa_ce_disable_local_tag(void)1039 void nfa_ce_disable_local_tag (void)
1040 {
1041     tNFA_CE_CB *p_cb = &nfa_ce_cb;
1042     tNFA_CONN_EVT_DATA evt_data;
1043 
1044     NFA_TRACE_DEBUG0 ("Disabling local NDEF tag");
1045 
1046     /* If local NDEF tag is in use, then disable it */
1047     if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
1048     {
1049         /* NDEF Tag is in not idle state */
1050         if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1051             &&(p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)  )
1052         {
1053             /* wait for deactivation */
1054             p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1055             nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1056         }
1057         else
1058         {
1059             /* Notify DM to stop listening for ndef  */
1060             if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
1061             {
1062                 nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1063                 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
1064             }
1065             nfa_ce_remove_listen_info_entry (NFA_CE_LISTEN_INFO_IDX_NDEF, TRUE);
1066         }
1067     }
1068     else
1069     {
1070         /* Notify application */
1071         evt_data.status = NFA_STATUS_OK;
1072         nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &evt_data);
1073     }
1074 }
1075 
1076 /*******************************************************************************
1077 **
1078 ** Function         nfa_ce_api_cfg_local_tag
1079 **
1080 ** Description      Configure local NDEF tag
1081 **                      - store ndef attributes in to control block
1082 **                      - update discovery configuration
1083 **
1084 ** Returns          TRUE (message buffer to be freed by caller)
1085 **
1086 *******************************************************************************/
nfa_ce_api_cfg_local_tag(tNFA_CE_MSG * p_ce_msg)1087 BOOLEAN nfa_ce_api_cfg_local_tag (tNFA_CE_MSG *p_ce_msg)
1088 {
1089     tNFA_CE_CB *p_cb = &nfa_ce_cb;
1090     tNFA_CONN_EVT_DATA conn_evt;
1091 
1092     /* Check if disabling local tag */
1093     if (p_ce_msg->local_tag.protocol_mask == 0)
1094     {
1095         nfa_ce_disable_local_tag ();
1096         return TRUE;
1097     }
1098 
1099     NFA_TRACE_DEBUG5 ("Configuring local NDEF tag: protocol_mask=%01x cur_size=%i, max_size=%i, readonly=%i",
1100             p_ce_msg->local_tag.protocol_mask,
1101             p_ce_msg->local_tag.ndef_cur_size,
1102             p_ce_msg->local_tag.ndef_max_size,
1103             p_ce_msg->local_tag.read_only,
1104             p_ce_msg->local_tag.uid_len);
1105 
1106     /* If local tag was already set, then check if NFA_CeConfigureLocalTag called to change protocol mask  */
1107     if (  (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
1108         &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
1109         &&((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
1110             != (p_ce_msg->local_tag.protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)))  )
1111     {
1112         /* Listening for different tag protocols. Stop discovery */
1113         nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1114         p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
1115 
1116         /* clear NDEF contents */
1117         CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
1118         CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
1119     }
1120 
1121     /* Store NDEF info to control block */
1122     p_cb->p_ndef_data   = p_ce_msg->local_tag.p_ndef_data;
1123     p_cb->ndef_cur_size = p_ce_msg->local_tag.ndef_cur_size;
1124     p_cb->ndef_max_size = p_ce_msg->local_tag.ndef_max_size;
1125 
1126     /* Fill in LISTEN_INFO entry for NDEF */
1127     p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags = NFA_CE_LISTEN_INFO_IN_USE;
1128     p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask = p_ce_msg->local_tag.protocol_mask;
1129     p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].p_conn_cback = nfa_dm_conn_cback_event_notify;
1130     if (p_ce_msg->local_tag.read_only)
1131         p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags |= NFC_CE_LISTEN_INFO_READONLY_NDEF;
1132     p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_system_code = T3T_SYSTEM_CODE_NDEF;
1133 
1134     /* Set NDEF contents */
1135     conn_evt.status = NFA_STATUS_FAILED;
1136 
1137     if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
1138     {
1139         /* Ok to set contents now */
1140         if (nfa_ce_set_content () != NFA_STATUS_OK)
1141         {
1142             NFA_TRACE_ERROR0 ("nfa_ce_api_cfg_local_tag: could not set contents");
1143             nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
1144             return TRUE;
1145         }
1146 
1147         /* Start listening and notify app of status */
1148         conn_evt.status = nfa_ce_start_listening ();
1149         nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
1150     }
1151 
1152     return TRUE;
1153 }
1154 
1155 /*******************************************************************************
1156 **
1157 ** Function         nfa_ce_api_reg_listen
1158 **
1159 ** Description      Register listen params for Felica system code, T4T AID,
1160 **                  or UICC
1161 **
1162 ** Returns          TRUE (message buffer to be freed by caller)
1163 **
1164 *******************************************************************************/
nfa_ce_api_reg_listen(tNFA_CE_MSG * p_ce_msg)1165 BOOLEAN nfa_ce_api_reg_listen (tNFA_CE_MSG *p_ce_msg)
1166 {
1167     tNFA_CE_CB *p_cb = &nfa_ce_cb;
1168     tNFA_CONN_EVT_DATA conn_evt;
1169     UINT8 i;
1170     UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
1171 
1172     NFA_TRACE_DEBUG1 ("Registering UICC/Felica/Type-4 tag listener. Type=%i", p_ce_msg->reg_listen.listen_type);
1173 
1174     /* Look for available entry in listen_info table                                        */
1175     /* - If registering UICC listen, make sure there isn't another entry for the ee_handle  */
1176     /* - Skip over entry 0 (reserved for local NDEF tag)                                    */
1177     for (i=1; i<NFA_CE_LISTEN_INFO_MAX; i++)
1178     {
1179         if (  (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1180             &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
1181             &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
1182             &&(p_cb->listen_info[i].ee_handle == p_ce_msg->reg_listen.ee_handle)  )
1183         {
1184 
1185             NFA_TRACE_ERROR1 ("UICC (0x%x) listening already specified", p_ce_msg->reg_listen.ee_handle);
1186             conn_evt.status = NFA_STATUS_FAILED;
1187             nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1188             return TRUE;
1189         }
1190         /* If this is a free entry, and we haven't found one yet, remember it */
1191         else if (  (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE))
1192                  &&(listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)  )
1193         {
1194             listen_info_idx = i;
1195         }
1196     }
1197 
1198     /* Add new entry to listen_info table */
1199     if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)
1200     {
1201         NFA_TRACE_ERROR1 ("Maximum listen callbacks exceeded (%i)", NFA_CE_LISTEN_INFO_MAX);
1202 
1203         if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1204         {
1205             conn_evt.status = NFA_STATUS_FAILED;
1206             nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1207         }
1208         else
1209         {
1210             /* Notify application */
1211             conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1212             conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1213             (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1214         }
1215         return TRUE;
1216     }
1217     else
1218     {
1219         NFA_TRACE_DEBUG1 ("NFA_CE: adding listen_info entry %i", listen_info_idx);
1220 
1221         /* Store common parameters */
1222         /* Mark entry as 'in-use', and NFA_CE_LISTEN_INFO_START_NTF_PND */
1223         /* (LISTEN_START_EVT will be notified when discovery successfully starts */
1224         p_cb->listen_info[listen_info_idx].flags = NFA_CE_LISTEN_INFO_IN_USE | NFA_CE_LISTEN_INFO_START_NTF_PND;
1225         p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1226         p_cb->listen_info[listen_info_idx].protocol_mask = 0;
1227 
1228         /* Store type-specific parameters */
1229         switch (p_ce_msg->reg_listen.listen_type)
1230         {
1231         case NFA_CE_REG_TYPE_ISO_DEP:
1232             p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_ISO_DEP;
1233             p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_T4T_AID;
1234             p_cb->listen_info[listen_info_idx].p_conn_cback =p_ce_msg->reg_listen.p_conn_cback;
1235 
1236             /* Register this AID with CE_T4T */
1237             if ((p_cb->listen_info[listen_info_idx].t4t_aid_handle = CE_T4tRegisterAID (p_ce_msg->reg_listen.aid_len,
1238                                                                                         p_ce_msg->reg_listen.aid,
1239                                                                                         nfa_ce_handle_t4t_aid_evt)) == CE_T4T_AID_HANDLE_INVALID)
1240             {
1241                 NFA_TRACE_ERROR0 ("Unable to register AID");
1242                 p_cb->listen_info[listen_info_idx].flags = 0;
1243 
1244                 /* Notify application */
1245                 conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1246                 conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1247                 (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1248 
1249                 return TRUE;
1250             }
1251             if (p_cb->listen_info[listen_info_idx].t4t_aid_handle == CE_T4T_WILDCARD_AID_HANDLE)
1252                 nfa_ce_cb.idx_wild_card     = listen_info_idx;
1253             break;
1254 
1255         case NFA_CE_REG_TYPE_FELICA:
1256             p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_T3T;
1257             p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_FELICA;
1258             p_cb->listen_info[listen_info_idx].p_conn_cback = p_ce_msg->reg_listen.p_conn_cback;
1259 
1260             /* Store system code and nfcid2 */
1261             p_cb->listen_info[listen_info_idx].t3t_system_code = p_ce_msg->reg_listen.system_code;
1262             memcpy (p_cb->listen_info[listen_info_idx].t3t_nfcid2, p_ce_msg->reg_listen.nfcid2, NCI_RF_F_UID_LEN);
1263             break;
1264 
1265 #if (NFC_NFCEE_INCLUDED == TRUE)
1266         case NFA_CE_REG_TYPE_UICC:
1267             p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_UICC;
1268             p_cb->listen_info[listen_info_idx].p_conn_cback = &nfa_dm_conn_cback_event_notify;
1269 
1270             /* Store EE handle and Tech */
1271             p_cb->listen_info[listen_info_idx].ee_handle = p_ce_msg->reg_listen.ee_handle;
1272             p_cb->listen_info[listen_info_idx].tech_mask = p_ce_msg->reg_listen.tech_mask;
1273             break;
1274 #endif
1275         }
1276     }
1277 
1278     /* Start listening */
1279     if ((conn_evt.status = nfa_ce_start_listening ()) != NFA_STATUS_OK)
1280     {
1281         NFA_TRACE_ERROR0 ("nfa_ce_api_reg_listen: unable to register new listen params with DM");
1282         p_cb->listen_info[listen_info_idx].flags = 0;
1283     }
1284 
1285     /* Nofitify app of status */
1286     if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1287     {
1288         (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1289     }
1290     else
1291     {
1292         conn_evt.ce_registered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
1293         NFA_TRACE_DEBUG1 ("nfa_ce_api_reg_listen: registered handle 0x%04X", conn_evt.ce_registered.handle);
1294         (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1295     }
1296 
1297     return TRUE;
1298 }
1299 
1300 /*******************************************************************************
1301 **
1302 ** Function         nfa_ce_api_dereg_listen
1303 **
1304 ** Description      Deregister listen params
1305 **
1306 ** Returns          TRUE (message buffer to be freed by caller)
1307 **
1308 *******************************************************************************/
nfa_ce_api_dereg_listen(tNFA_CE_MSG * p_ce_msg)1309 BOOLEAN nfa_ce_api_dereg_listen (tNFA_CE_MSG *p_ce_msg)
1310 {
1311     tNFA_CE_CB *p_cb = &nfa_ce_cb;
1312     UINT8 listen_info_idx;
1313     tNFA_CONN_EVT_DATA conn_evt;
1314 
1315 #if (NFC_NFCEE_INCLUDED == TRUE)
1316     /* Check if deregistering UICC , or virtual secure element listen */
1317     if (p_ce_msg->dereg_listen.listen_info == NFA_CE_LISTEN_INFO_UICC)
1318     {
1319         /* Deregistering UICC listen. Look for listen_info for this UICC ee handle */
1320         for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
1321         {
1322             if (  (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
1323                 &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
1324                 &&(p_cb->listen_info[listen_info_idx].ee_handle == p_ce_msg->dereg_listen.handle)  )
1325             {
1326                 /* UICC is in not idle state */
1327                 if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1328                     &&(p_cb->idx_cur_active == listen_info_idx)  )
1329                 {
1330                     /* wait for deactivation */
1331                     p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1332                     nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1333                 }
1334                 else
1335                 {
1336                     /* Stop listening */
1337                     if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
1338                     {
1339                         nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
1340                         p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1341                     }
1342 
1343                     /* Remove entry and notify application */
1344                     nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
1345                 }
1346                 break;
1347             }
1348         }
1349 
1350         if (listen_info_idx == NFA_CE_LISTEN_INFO_MAX)
1351         {
1352             NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for UICC");
1353             conn_evt.status = NFA_STATUS_INVALID_PARAM;
1354             nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1355         }
1356     }
1357     else
1358 #endif
1359     {
1360         /* Deregistering virtual secure element listen */
1361         listen_info_idx = p_ce_msg->dereg_listen.handle & NFA_HANDLE_MASK;
1362         if (nfa_ce_cb.idx_wild_card == listen_info_idx)
1363         {
1364             nfa_ce_cb.idx_wild_card     = NFA_CE_LISTEN_INFO_IDX_INVALID;
1365         }
1366 
1367         if (  (listen_info_idx < NFA_CE_LISTEN_INFO_MAX)
1368             &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE))
1369         {
1370             /* virtual secure element is in not idle state */
1371             if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1372                 &&(p_cb->idx_cur_active == listen_info_idx)  )
1373             {
1374                 /* wait for deactivation */
1375                 p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1376                 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1377             }
1378             else
1379             {
1380                 /* Stop listening */
1381                 if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
1382                 {
1383                     nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
1384                     p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1385                 }
1386 
1387                 /* Remove entry and notify application */
1388                 nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
1389             }
1390         }
1391         else
1392         {
1393             NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for Felica/T4tAID");
1394             conn_evt.status = NFA_STATUS_INVALID_PARAM;
1395             nfa_dm_conn_cback_event_notify (NFA_CE_DEREGISTERED_EVT, &conn_evt);
1396         }
1397     }
1398 
1399     return TRUE;
1400 }
1401 
1402 /*******************************************************************************
1403 **
1404 ** Function         nfa_ce_api_cfg_isodep_tech
1405 **
1406 ** Description      Configure the technologies (NFC-A and/or NFC-B) to listen for
1407 **                  ISO-DEP
1408 **
1409 ** Returns          TRUE (message buffer to be freed by caller)
1410 **
1411 *******************************************************************************/
nfa_ce_api_cfg_isodep_tech(tNFA_CE_MSG * p_ce_msg)1412 BOOLEAN nfa_ce_api_cfg_isodep_tech (tNFA_CE_MSG *p_ce_msg)
1413 {
1414     nfa_ce_cb.isodep_disc_mask  = 0;
1415     if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_A)
1416         nfa_ce_cb.isodep_disc_mask  = NFA_DM_DISC_MASK_LA_ISO_DEP;
1417 
1418     if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_B)
1419         nfa_ce_cb.isodep_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
1420     return TRUE;
1421 }
1422