nfa_ce_act.c revision 58268861a9aee36b541b6534c341657fb221c2f2
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*******************************************************************************/
49void 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*******************************************************************************/
120void 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*******************************************************************************/
178void 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*******************************************************************************/
245void 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*******************************************************************************/
287void 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*******************************************************************************/
337void 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*******************************************************************************/
365tNFA_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*******************************************************************************/
497BOOLEAN 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*******************************************************************************/
534void 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*******************************************************************************/
617void 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*******************************************************************************/
636tNFA_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*******************************************************************************/
680tNFC_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*******************************************************************************/
749BOOLEAN 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*******************************************************************************/
924BOOLEAN 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            (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
951        }
952
953        return TRUE;
954    }
955    else
956    {
957        deact_type = NFC_DEACTIVATE_TYPE_IDLE;
958    }
959
960    /* Tag is in idle state */
961    p_cb->flags &= ~NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
962
963    /* First, notify app of deactivation */
964    for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
965    {
966        if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
967        {
968            if (  (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
969                &&(i == p_cb->idx_cur_active)  )
970            {
971                conn_evt.deactivated.type =  deact_type;
972                (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
973            }
974            else if (  (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
975                     &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP))
976            {
977                /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
978                if (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND))
979                {
980                    if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
981                    {
982                        conn_evt.deactivated.type =  deact_type;
983                        (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
984                    }
985                    else
986                    {
987                        conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
988                        conn_evt.ce_deactivated.type   = deact_type;
989                        (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
990                    }
991                }
992            }
993            else if (  (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
994                     &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
995            {
996                if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
997                {
998                    conn_evt.deactivated.type = deact_type;
999                    (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
1000                }
1001                else
1002                {
1003                    conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
1004                    conn_evt.ce_deactivated.type   = deact_type;
1005                    (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
1006                }
1007            }
1008        }
1009    }
1010
1011    /* Check if app initiated the deactivation (due to API deregister). If so, remove entry from listen_info table. */
1012    if (p_cb->flags & NFA_CE_FLAGS_APP_INIT_DEACTIVATION)
1013    {
1014        p_cb->flags &= ~NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1015        nfa_ce_remove_listen_info_entry (p_cb->idx_cur_active, TRUE);
1016    }
1017
1018    p_cb->p_active_conn_cback = NULL;
1019    p_cb->idx_cur_active      = NFA_CE_LISTEN_INFO_IDX_INVALID;
1020
1021    /* Restart listening (if any listen_info entries are still active) */
1022    nfa_ce_restart_listen_check ();
1023
1024    return TRUE;
1025}
1026
1027/*******************************************************************************
1028**
1029** Function         nfa_ce_disable_local_tag
1030**
1031** Description      Disable local NDEF tag
1032**                      - clean up control block
1033**                      - remove NDEF discovery configuration
1034**
1035** Returns          Nothing
1036**
1037*******************************************************************************/
1038void nfa_ce_disable_local_tag (void)
1039{
1040    tNFA_CE_CB *p_cb = &nfa_ce_cb;
1041    tNFA_CONN_EVT_DATA evt_data;
1042
1043    NFA_TRACE_DEBUG0 ("Disabling local NDEF tag");
1044
1045    /* If local NDEF tag is in use, then disable it */
1046    if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
1047    {
1048        /* NDEF Tag is in not idle state */
1049        if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1050            &&(p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)  )
1051        {
1052            /* wait for deactivation */
1053            p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1054            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1055        }
1056        else
1057        {
1058            /* Notify DM to stop listening for ndef  */
1059            if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
1060            {
1061                nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1062                p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
1063            }
1064            nfa_ce_remove_listen_info_entry (NFA_CE_LISTEN_INFO_IDX_NDEF, TRUE);
1065        }
1066    }
1067    else
1068    {
1069        /* Notify application */
1070        evt_data.status = NFA_STATUS_OK;
1071        nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &evt_data);
1072    }
1073}
1074
1075/*******************************************************************************
1076**
1077** Function         nfa_ce_api_cfg_local_tag
1078**
1079** Description      Configure local NDEF tag
1080**                      - store ndef attributes in to control block
1081**                      - update discovery configuration
1082**
1083** Returns          TRUE (message buffer to be freed by caller)
1084**
1085*******************************************************************************/
1086BOOLEAN nfa_ce_api_cfg_local_tag (tNFA_CE_MSG *p_ce_msg)
1087{
1088    tNFA_CE_CB *p_cb = &nfa_ce_cb;
1089    tNFA_CONN_EVT_DATA conn_evt;
1090
1091    /* Check if disabling local tag */
1092    if (p_ce_msg->local_tag.protocol_mask == 0)
1093    {
1094        nfa_ce_disable_local_tag ();
1095        return TRUE;
1096    }
1097
1098    NFA_TRACE_DEBUG5 ("Configuring local NDEF tag: protocol_mask=%01x cur_size=%i, max_size=%i, readonly=%i",
1099            p_ce_msg->local_tag.protocol_mask,
1100            p_ce_msg->local_tag.ndef_cur_size,
1101            p_ce_msg->local_tag.ndef_max_size,
1102            p_ce_msg->local_tag.read_only,
1103            p_ce_msg->local_tag.uid_len);
1104
1105    /* If local tag was already set, then check if NFA_CeConfigureLocalTag called to change protocol mask  */
1106    if (  (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
1107        &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
1108        &&((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
1109            != (p_ce_msg->local_tag.protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)))  )
1110    {
1111        /* Listening for different tag protocols. Stop discovery */
1112        nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1113        p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
1114
1115        /* clear NDEF contents */
1116        CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
1117        CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
1118    }
1119
1120    /* Store NDEF info to control block */
1121    p_cb->p_ndef_data   = p_ce_msg->local_tag.p_ndef_data;
1122    p_cb->ndef_cur_size = p_ce_msg->local_tag.ndef_cur_size;
1123    p_cb->ndef_max_size = p_ce_msg->local_tag.ndef_max_size;
1124
1125    /* Fill in LISTEN_INFO entry for NDEF */
1126    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags = NFA_CE_LISTEN_INFO_IN_USE;
1127    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask = p_ce_msg->local_tag.protocol_mask;
1128    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].p_conn_cback = nfa_dm_conn_cback_event_notify;
1129    if (p_ce_msg->local_tag.read_only)
1130        p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags |= NFC_CE_LISTEN_INFO_READONLY_NDEF;
1131    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_system_code = T3T_SYSTEM_CODE_NDEF;
1132
1133    /* Set NDEF contents */
1134    conn_evt.status = NFA_STATUS_FAILED;
1135
1136    if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
1137    {
1138        /* Ok to set contents now */
1139        if (nfa_ce_set_content () != NFA_STATUS_OK)
1140        {
1141            NFA_TRACE_ERROR0 ("nfa_ce_api_cfg_local_tag: could not set contents");
1142            nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
1143            return TRUE;
1144        }
1145
1146        /* Start listening and notify app of status */
1147        conn_evt.status = nfa_ce_start_listening ();
1148        nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
1149    }
1150
1151    return TRUE;
1152}
1153
1154/*******************************************************************************
1155**
1156** Function         nfa_ce_api_reg_listen
1157**
1158** Description      Register listen params for Felica system code, T4T AID,
1159**                  or UICC
1160**
1161** Returns          TRUE (message buffer to be freed by caller)
1162**
1163*******************************************************************************/
1164BOOLEAN nfa_ce_api_reg_listen (tNFA_CE_MSG *p_ce_msg)
1165{
1166    tNFA_CE_CB *p_cb = &nfa_ce_cb;
1167    tNFA_CONN_EVT_DATA conn_evt;
1168    UINT8 i;
1169    UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
1170
1171    NFA_TRACE_DEBUG1 ("Registering UICC/Felica/Type-4 tag listener. Type=%i", p_ce_msg->reg_listen.listen_type);
1172
1173    /* Look for available entry in listen_info table                                        */
1174    /* - If registering UICC listen, make sure there isn't another entry for the ee_handle  */
1175    /* - Skip over entry 0 (reserved for local NDEF tag)                                    */
1176    for (i=1; i<NFA_CE_LISTEN_INFO_MAX; i++)
1177    {
1178        if (  (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1179            &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
1180            &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
1181            &&(p_cb->listen_info[i].ee_handle == p_ce_msg->reg_listen.ee_handle)  )
1182        {
1183
1184            NFA_TRACE_ERROR1 ("UICC (0x%x) listening already specified", p_ce_msg->reg_listen.ee_handle);
1185            conn_evt.status = NFA_STATUS_FAILED;
1186            nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1187            return TRUE;
1188        }
1189        /* If this is a free entry, and we haven't found one yet, remember it */
1190        else if (  (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE))
1191                 &&(listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)  )
1192        {
1193            listen_info_idx = i;
1194        }
1195    }
1196
1197    /* Add new entry to listen_info table */
1198    if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)
1199    {
1200        NFA_TRACE_ERROR1 ("Maximum listen callbacks exceeded (%i)", NFA_CE_LISTEN_INFO_MAX);
1201
1202        if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1203        {
1204            conn_evt.status = NFA_STATUS_FAILED;
1205            nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1206        }
1207        else
1208        {
1209            /* Notify application */
1210            conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1211            conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1212            (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1213        }
1214        return TRUE;
1215    }
1216    else
1217    {
1218        NFA_TRACE_DEBUG1 ("NFA_CE: adding listen_info entry %i", listen_info_idx);
1219
1220        /* Store common parameters */
1221        /* Mark entry as 'in-use', and NFA_CE_LISTEN_INFO_START_NTF_PND */
1222        /* (LISTEN_START_EVT will be notified when discovery successfully starts */
1223        p_cb->listen_info[listen_info_idx].flags = NFA_CE_LISTEN_INFO_IN_USE | NFA_CE_LISTEN_INFO_START_NTF_PND;
1224        p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1225        p_cb->listen_info[listen_info_idx].protocol_mask = 0;
1226
1227        /* Store type-specific parameters */
1228        switch (p_ce_msg->reg_listen.listen_type)
1229        {
1230        case NFA_CE_REG_TYPE_ISO_DEP:
1231            p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_ISO_DEP;
1232            p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_T4T_AID;
1233            p_cb->listen_info[listen_info_idx].p_conn_cback =p_ce_msg->reg_listen.p_conn_cback;
1234
1235            /* Register this AID with CE_T4T */
1236            if ((p_cb->listen_info[listen_info_idx].t4t_aid_handle = CE_T4tRegisterAID (p_ce_msg->reg_listen.aid_len,
1237                                                                                        p_ce_msg->reg_listen.aid,
1238                                                                                        nfa_ce_handle_t4t_aid_evt)) == CE_T4T_AID_HANDLE_INVALID)
1239            {
1240                NFA_TRACE_ERROR0 ("Unable to register AID");
1241                p_cb->listen_info[listen_info_idx].flags = 0;
1242
1243                /* Notify application */
1244                conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1245                conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1246                (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1247
1248                return TRUE;
1249            }
1250            if (p_cb->listen_info[listen_info_idx].t4t_aid_handle == CE_T4T_WILDCARD_AID_HANDLE)
1251                nfa_ce_cb.idx_wild_card     = listen_info_idx;
1252            break;
1253
1254        case NFA_CE_REG_TYPE_FELICA:
1255            p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_T3T;
1256            p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_FELICA;
1257            p_cb->listen_info[listen_info_idx].p_conn_cback = p_ce_msg->reg_listen.p_conn_cback;
1258
1259            /* Store system code and nfcid2 */
1260            p_cb->listen_info[listen_info_idx].t3t_system_code = p_ce_msg->reg_listen.system_code;
1261            memcpy (p_cb->listen_info[listen_info_idx].t3t_nfcid2, p_ce_msg->reg_listen.nfcid2, NCI_RF_F_UID_LEN);
1262            break;
1263
1264#if (NFC_NFCEE_INCLUDED == TRUE)
1265        case NFA_CE_REG_TYPE_UICC:
1266            p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_UICC;
1267            p_cb->listen_info[listen_info_idx].p_conn_cback = &nfa_dm_conn_cback_event_notify;
1268
1269            /* Store EE handle and Tech */
1270            p_cb->listen_info[listen_info_idx].ee_handle = p_ce_msg->reg_listen.ee_handle;
1271            p_cb->listen_info[listen_info_idx].tech_mask = p_ce_msg->reg_listen.tech_mask;
1272            break;
1273#endif
1274        }
1275    }
1276
1277    /* Start listening */
1278    if ((conn_evt.status = nfa_ce_start_listening ()) != NFA_STATUS_OK)
1279    {
1280        NFA_TRACE_ERROR0 ("nfa_ce_api_reg_listen: unable to register new listen params with DM");
1281        p_cb->listen_info[listen_info_idx].flags = 0;
1282    }
1283
1284    /* Nofitify app of status */
1285    if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1286    {
1287        (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1288    }
1289    else
1290    {
1291        conn_evt.ce_registered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
1292        NFA_TRACE_DEBUG1 ("nfa_ce_api_reg_listen: registered handle 0x%04X", conn_evt.ce_registered.handle);
1293        (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1294    }
1295
1296    return TRUE;
1297}
1298
1299/*******************************************************************************
1300**
1301** Function         nfa_ce_api_dereg_listen
1302**
1303** Description      Deregister listen params
1304**
1305** Returns          TRUE (message buffer to be freed by caller)
1306**
1307*******************************************************************************/
1308BOOLEAN nfa_ce_api_dereg_listen (tNFA_CE_MSG *p_ce_msg)
1309{
1310    tNFA_CE_CB *p_cb = &nfa_ce_cb;
1311    UINT8 listen_info_idx;
1312    tNFA_CONN_EVT_DATA conn_evt;
1313
1314#if (NFC_NFCEE_INCLUDED == TRUE)
1315    /* Check if deregistering UICC , or virtual secure element listen */
1316    if (p_ce_msg->dereg_listen.listen_info == NFA_CE_LISTEN_INFO_UICC)
1317    {
1318        /* Deregistering UICC listen. Look for listen_info for this UICC ee handle */
1319        for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
1320        {
1321            if (  (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
1322                &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
1323                &&(p_cb->listen_info[listen_info_idx].ee_handle == p_ce_msg->dereg_listen.handle)  )
1324            {
1325                /* UICC is in not idle state */
1326                if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1327                    &&(p_cb->idx_cur_active == listen_info_idx)  )
1328                {
1329                    /* wait for deactivation */
1330                    p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1331                    nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1332                }
1333                else
1334                {
1335                    /* Stop listening */
1336                    if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
1337                    {
1338                        nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
1339                        p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1340                    }
1341
1342                    /* Remove entry and notify application */
1343                    nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
1344                }
1345                break;
1346            }
1347        }
1348
1349        if (listen_info_idx == NFA_CE_LISTEN_INFO_MAX)
1350        {
1351            NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for UICC");
1352            conn_evt.status = NFA_STATUS_INVALID_PARAM;
1353            nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1354        }
1355    }
1356    else
1357#endif
1358    {
1359        /* Deregistering virtual secure element listen */
1360        listen_info_idx = p_ce_msg->dereg_listen.handle & NFA_HANDLE_MASK;
1361        if (nfa_ce_cb.idx_wild_card == listen_info_idx)
1362        {
1363            nfa_ce_cb.idx_wild_card     = NFA_CE_LISTEN_INFO_IDX_INVALID;
1364        }
1365
1366        if (  (listen_info_idx < NFA_CE_LISTEN_INFO_MAX)
1367            &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE))
1368        {
1369            /* virtual secure element is in not idle state */
1370            if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1371                &&(p_cb->idx_cur_active == listen_info_idx)  )
1372            {
1373                /* wait for deactivation */
1374                p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1375                nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1376            }
1377            else
1378            {
1379                /* Stop listening */
1380                if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
1381                {
1382                    nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
1383                    p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1384                }
1385
1386                /* Remove entry and notify application */
1387                nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
1388            }
1389        }
1390        else
1391        {
1392            NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for Felica/T4tAID");
1393            conn_evt.status = NFA_STATUS_INVALID_PARAM;
1394            nfa_dm_conn_cback_event_notify (NFA_CE_DEREGISTERED_EVT, &conn_evt);
1395        }
1396    }
1397
1398    return TRUE;
1399}
1400
1401/*******************************************************************************
1402**
1403** Function         nfa_ce_api_cfg_isodep_tech
1404**
1405** Description      Configure the technologies (NFC-A and/or NFC-B) to listen for
1406**                  ISO-DEP
1407**
1408** Returns          TRUE (message buffer to be freed by caller)
1409**
1410*******************************************************************************/
1411BOOLEAN nfa_ce_api_cfg_isodep_tech (tNFA_CE_MSG *p_ce_msg)
1412{
1413    nfa_ce_cb.isodep_disc_mask  = 0;
1414    if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_A)
1415        nfa_ce_cb.isodep_disc_mask  = NFA_DM_DISC_MASK_LA_ISO_DEP;
1416
1417    if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_B)
1418        nfa_ce_cb.isodep_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
1419    return TRUE;
1420}
1421