Home | History | Annotate | Download | only in ce
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2011-2013 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 *******************************************************************************/
     49 void nfa_ce_handle_t3t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
     50 {
     51     tNFA_CE_CB *p_cb = &nfa_ce_cb;
     52     tNFA_CONN_EVT_DATA conn_evt;
     53 
     54     NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt: event 0x%x", event);
     55 
     56     switch (event)
     57     {
     58     case CE_T3T_NDEF_UPDATE_START_EVT:
     59         /* Notify app using callback associated with the active ndef */
     60         if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
     61         {
     62             conn_evt.status = NFA_STATUS_OK;
     63             (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
     64         }
     65         else
     66         {
     67             NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_START_EVT, but no active NDEF");
     68         }
     69         break;
     70 
     71     case CE_T3T_NDEF_UPDATE_CPLT_EVT:
     72         /* Notify app using callback associated with the active ndef */
     73         if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
     74         {
     75             conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
     76             conn_evt.ndef_write_cplt.len    = p_ce_data->update_info.length;
     77             conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
     78             (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
     79         }
     80         else
     81         {
     82             NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_CPLT_EVT, but no active NDEF");
     83         }
     84         break;
     85 
     86     case CE_T3T_RAW_FRAME_EVT:
     87         if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
     88         {
     89             conn_evt.data.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 *******************************************************************************/
    118 void 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 *******************************************************************************/
    176 void 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 *******************************************************************************/
    242 void 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 *******************************************************************************/
    284 void 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 *******************************************************************************/
    334 void 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 *******************************************************************************/
    362 tNFA_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 *******************************************************************************/
    494 BOOLEAN 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 *******************************************************************************/
    531 void 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 *******************************************************************************/
    614 void 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 *******************************************************************************/
    633 tNFA_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 *******************************************************************************/
    677 tNFC_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 *******************************************************************************/
    746 BOOLEAN 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 *******************************************************************************/
    921 BOOLEAN 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 *******************************************************************************/
   1026 void 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 *******************************************************************************/
   1074 BOOLEAN 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 *******************************************************************************/
   1152 BOOLEAN 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 *******************************************************************************/
   1294 BOOLEAN 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 *******************************************************************************/
   1393 BOOLEAN 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