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