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