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