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