C++程序  |  1967行  |  65.5 KB

/******************************************************************************
 *
 *  Copyright (C) 2010-2014 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/


/******************************************************************************
 *
 *  This file contains the action functions for device manager state
 *  machine.
 *
 ******************************************************************************/
#include <string.h>
#include "nfa_sys.h"
#include "nfa_api.h"
#include "nfa_dm_int.h"
#include "nfa_sys_int.h"
#include "nfa_ce_int.h"
#include "nfc_api.h"
#include "nfa_rw_int.h"
#include "nfa_rw_api.h"
#include "nfa_p2p_int.h"
#include "nci_hmsgs.h"

#if (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE))
#include "nfa_cho_int.h"
#endif

#if (NFC_NFCEE_INCLUDED == TRUE)
#include "nfa_ee_int.h"
#include "nfa_hci_int.h"
#endif

#if (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE))
#include "nfa_snep_int.h"
#endif

/* This is the timeout value to guarantee disable is performed within reasonable amount of time */
#ifndef NFA_DM_DISABLE_TIMEOUT_VAL
#define NFA_DM_DISABLE_TIMEOUT_VAL         1000
#endif

static void nfa_dm_set_init_nci_params (void);
static tNFA_STATUS nfa_dm_start_polling (void);
static BOOLEAN nfa_dm_deactivate_polling (void);
static void nfa_dm_excl_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
static void nfa_dm_poll_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);


/*******************************************************************************
**
** Function         nfa_dm_module_init_cback
**
** Description      Processing initialization complete event from sub-modules
**
** Returns          None
**
*******************************************************************************/
static void nfa_dm_module_init_cback (void)
{
    tNFA_DM_CBACK_DATA dm_cback_data;

    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_ENABLE_EVT_PEND;

    /* All subsystem are initialized */
    dm_cback_data.status = NFA_STATUS_OK;
    (*nfa_dm_cb.p_dm_cback) (NFA_DM_ENABLE_EVT, &dm_cback_data);
}

/*******************************************************************************
**
** Function         nfa_dm_nfcc_power_mode_proc_complete_cback
**
** Description      Processing complete of processing NFCC power state change
**                  from all sub-modules
**
** Returns          None
**
*******************************************************************************/
static void nfa_dm_nfcc_power_mode_proc_complete_cback (void)
{
    tNFA_DM_PWR_MODE_CHANGE power_mode_change;

    NFA_TRACE_DEBUG1 ("nfa_dm_nfcc_power_mode_proc_complete_cback () nfcc_pwr_mode = 0x%x",
                      nfa_dm_cb.nfcc_pwr_mode);

    /* if NFCC power state is change to full power */
    if (nfa_dm_cb.nfcc_pwr_mode != NFA_DM_PWR_MODE_OFF_SLEEP)
    {
        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_NFCC_IS_RESTORING;

        /* reconfigure BRCM NFCC */
        nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_CMD, NULL);
    }

    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SETTING_PWR_MODE;

    power_mode_change.status     = NFA_STATUS_OK;
    power_mode_change.power_mode = nfa_dm_cb.nfcc_pwr_mode;
    (*nfa_dm_cb.p_dm_cback) (NFA_DM_PWR_MODE_CHANGE_EVT, (tNFA_DM_CBACK_DATA*) &power_mode_change);
}
/*******************************************************************************
**
** Function         nfa_dm_sys_enable
**
** Description      This function on enable
**
** Returns          void
**
*******************************************************************************/
void nfa_dm_sys_enable (void)
{
    nfa_dm_set_init_nci_params ();
}

/*******************************************************************************
**
** Function         nfa_dm_set_init_nci_params
**
** Description      Set initial NCI configuration parameters
**
** Returns          void
**
*******************************************************************************/
static void nfa_dm_set_init_nci_params (void)
{
    UINT8   xx;

    /* set NCI default value if other than zero */

    /* LF_T3T_IDENTIFIERS_1/2/.../16 */
    for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX; xx++)
    {
        nfa_dm_cb.params.lf_t3t_id[xx][0] = 0xFF;
        nfa_dm_cb.params.lf_t3t_id[xx][1] = 0xFF;
        nfa_dm_cb.params.lf_t3t_id[xx][2] = 0x02;
        nfa_dm_cb.params.lf_t3t_id[xx][2] = 0xFE;
    }

    /* LF_T3T_PMM */
    for (xx = 0; xx < NCI_PARAM_LEN_LF_T3T_PMM; xx++)
    {
        nfa_dm_cb.params.lf_t3t_pmm[xx] = 0xFF;
    }

    /* LF_T3T_FLAGS:
    ** DH needs to set this configuration, even if default value (not listening) is used,
    ** to let NFCC know of intention (not listening) of DH.
    */

    /* FWI */
    nfa_dm_cb.params.fwi[0] = 0x04;

    /* WT */
    nfa_dm_cb.params.wt[0] = 14;

    /* Set CE default configuration */
    if (p_nfa_dm_ce_cfg[0])
    {
        nfa_dm_check_set_config (p_nfa_dm_ce_cfg[0], &p_nfa_dm_ce_cfg[1], FALSE);
    }

    /* Set optional general default configuration */
    if (p_nfa_dm_gen_cfg && p_nfa_dm_gen_cfg[0])
    {
        nfa_dm_check_set_config (p_nfa_dm_gen_cfg[0], &p_nfa_dm_gen_cfg[1], FALSE);
    }

    if (p_nfa_dm_interface_mapping && nfa_dm_num_dm_interface_mapping)
    {
        NFC_DiscoveryMap (nfa_dm_num_dm_interface_mapping, p_nfa_dm_interface_mapping, NULL);
    }
}

/*******************************************************************************
**
** Function         nfa_dm_proc_nfcc_power_mode
**
** Description      Processing NFCC power mode changes
**
** Returns          None
**
*******************************************************************************/
void nfa_dm_proc_nfcc_power_mode (UINT8 nfcc_power_mode)
{
    NFA_TRACE_DEBUG1 ("nfa_dm_proc_nfcc_power_mode (): nfcc_power_mode=%d",
                       nfcc_power_mode);

    /* if NFCC power mode is change to full power */
    if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL)
    {
        memset (&nfa_dm_cb.params, 0x00, sizeof (tNFA_DM_PARAMS));
        NFA_TRACE_DEBUG2 ("setcfg_pending_mask=0x%x, setcfg_pending_num=%d",
            nfa_dm_cb.setcfg_pending_mask, nfa_dm_cb.setcfg_pending_num);
        nfa_dm_cb.setcfg_pending_mask = 0;
        nfa_dm_cb.setcfg_pending_num  = 0;

        nfa_dm_set_init_nci_params ();
        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POWER_OFF_SLEEP;
    }
    else if (nfcc_power_mode == NFA_DM_PWR_MODE_OFF_SLEEP)
    {
        nfa_dm_cb.flags |= NFA_DM_FLAGS_POWER_OFF_SLEEP;
    }

    nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_DM);
}

/*******************************************************************************
**
** Function         nfa_dm_disable_event
**
** Description      report disable event
**
** Returns          void
**
*******************************************************************************/
static void nfa_dm_disable_event (void)
{
    /* Deregister DM from sys */
    nfa_sys_deregister (NFA_ID_DM);

    /* Notify app */
    nfa_dm_cb.flags &= ~(NFA_DM_FLAGS_DM_IS_ACTIVE
                        |NFA_DM_FLAGS_DM_DISABLING_NFC
                        |NFA_DM_FLAGS_ENABLE_EVT_PEND);
    (*nfa_dm_cb.p_dm_cback) (NFA_DM_DISABLE_EVT, NULL);
}

/*******************************************************************************
**
** Function         nfa_dm_nfc_response_cback
**
** Description      Call DM event hanlder with NFC response callback data
**
** Returns          void
**
*******************************************************************************/
static void nfa_dm_nfc_response_cback (tNFC_RESPONSE_EVT event, tNFC_RESPONSE *p_data)
{
    tNFA_DM_CBACK_DATA dm_cback_data;
    tNFA_GET_CONFIG   *p_nfa_get_confg;
    tNFA_CONN_EVT_DATA conn_evt;
    UINT8 dm_cback_evt;
    UINT8 max_ee = 0;

#if (BT_TRACE_VERBOSE == TRUE)
    NFA_TRACE_DEBUG2 ("nfa_dm_nfc_response_cback () %s(0x%x)", nfa_dm_nfc_revt_2_str (event), event);
#else
    NFA_TRACE_DEBUG1 ("nfa_dm_nfc_response_cback () event=0x%x", event);
#endif

    switch (event)
    {
    case NFC_ENABLE_REVT:                        /* 0  Enable event */

        /* NFC stack enabled. Enable nfa sub-systems */
        if (p_data->enable.status == NFC_STATUS_OK)
        {
            if (nfa_ee_max_ee_cfg != 0)
            {
                if (nfa_dm_cb.get_max_ee)
                {
                    max_ee = nfa_dm_cb.get_max_ee ();
                    if (max_ee)
                    {
                        nfa_ee_max_ee_cfg = max_ee;
                    }
                }
            }
            /* Initialize NFA subsystems */
            nfa_sys_enable_subsystems ();
        }
        else if (nfa_dm_cb.flags & NFA_DM_FLAGS_ENABLE_EVT_PEND)
        {
            /* Notify app */
            nfa_dm_cb.flags &= ~(NFA_DM_FLAGS_ENABLE_EVT_PEND | NFA_DM_FLAGS_DM_IS_ACTIVE);
            dm_cback_data.status = p_data->enable.status;
            (*nfa_dm_cb.p_dm_cback) (NFA_DM_ENABLE_EVT, &dm_cback_data);
        }
        break;

    case NFC_DISABLE_REVT:                       /* 1  Disable event */
        nfa_dm_disable_event ();
        break;

    case NFC_SET_CONFIG_REVT:                    /* 2  Set Config Response */
        /* If this setconfig was due to NFA_SetConfig, then notify the app */
        if (nfa_dm_cb.setcfg_pending_mask & 1)      /* lsb=whether last NCI_SET_CONFIG was due to NFA_SetConfig */
        {
            dm_cback_data.set_config.status         = p_data->set_config.status;
            dm_cback_data.set_config.num_param_id   = p_data->set_config.num_param_id;
            memcpy (dm_cback_data.set_config.param_ids, p_data->set_config.param_ids, p_data->set_config.num_param_id);
            (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
        }

        /* Update the pending mask */
        if (nfa_dm_cb.setcfg_pending_num>0)
        {
            nfa_dm_cb.setcfg_pending_mask >>= 1;
            nfa_dm_cb.setcfg_pending_num--;
        }
        else
        {
            /* This should not occur (means we got a SET_CONFIG_NTF that's unaccounted for */
            NFA_TRACE_ERROR0 ("NFA received unexpected NFC_SET_CONFIG_REVT");
        }
        break;

    case NFC_GET_CONFIG_REVT:                    /* 3  Get Config Response */
        if (p_data->get_config.status == NFC_STATUS_OK)
        {
            if ((p_nfa_get_confg = (tNFA_GET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_GET_CONFIG) + p_data->get_config.tlv_size))) != NULL)
            {
                p_nfa_get_confg->status = NFA_STATUS_OK;
                p_nfa_get_confg->tlv_size = p_data->get_config.tlv_size;
                memcpy (p_nfa_get_confg->param_tlvs, p_data->get_config.p_param_tlvs, p_data->get_config.tlv_size);
                (*nfa_dm_cb.p_dm_cback) (NFA_DM_GET_CONFIG_EVT, (tNFA_DM_CBACK_DATA *) p_nfa_get_confg);

                GKI_freebuf (p_nfa_get_confg);
                return;
            }
            else
            {
                NFA_TRACE_DEBUG0 ("nfa_dm_nfc_response_cback unable to allocate buffer");
            }
        }

        /* Return result of getconfig to the app */
        dm_cback_data.get_config.status = NFA_STATUS_FAILED;
        (*nfa_dm_cb.p_dm_cback) (NFA_DM_GET_CONFIG_EVT, &dm_cback_data);
        break;

#if (NFC_NFCEE_INCLUDED == TRUE)
    case NFC_NFCEE_DISCOVER_REVT:                /* NFCEE Discover response */
    case NFC_NFCEE_INFO_REVT:                    /* NFCEE Discover Notification */
    case NFC_EE_ACTION_REVT:                     /* EE Action notification */
    case NFC_NFCEE_MODE_SET_REVT:                /* NFCEE Mode Set response */
    case NFC_SET_ROUTING_REVT:                   /* Configure Routing response */
        nfa_ee_proc_evt (event, p_data);
        break;

    case NFC_EE_DISCOVER_REQ_REVT:               /* EE Discover Req notification */
        if (nfa_dm_is_active() &&
            (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) )
        {
            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
        }
        nfa_ee_proc_evt (event, p_data);
        break;

    case NFC_GET_ROUTING_REVT:                   /* Retrieve Routing response */
        break;
#endif

    case NFC_RF_FIELD_REVT:                      /* RF Field information            */
        dm_cback_data.rf_field.status          = NFA_STATUS_OK;
        dm_cback_data.rf_field.rf_field_status = p_data->rf_field.rf_field;
        (*nfa_dm_cb.p_dm_cback) (NFA_DM_RF_FIELD_EVT, &dm_cback_data);
        break;



    case NFC_GEN_ERROR_REVT:                     /* generic error command or notification */
        break;

    case NFC_NFCC_RESTART_REVT:                  /* NFCC has been re-initialized */

        if (p_data->status == NFC_STATUS_OK)
        {
            nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL;
            nfa_dm_cb.flags |= NFA_DM_FLAGS_NFCC_IS_RESTORING;

            /* NFCC will start from IDLE when turned on again */
            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
            nfa_dm_cb.disc_cb.disc_state = NFA_DM_RFST_IDLE;
        }
        else
        {
            nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
        }
        /* Notify NFA submodules change of NFCC power mode */
        nfa_sys_cback_reg_nfcc_power_mode_proc_complete (nfa_dm_nfcc_power_mode_proc_complete_cback);
        nfa_sys_notify_nfcc_power_mode (nfa_dm_cb.nfcc_pwr_mode);
        break;

    case NFC_NFCC_TIMEOUT_REVT:
    case NFC_NFCC_TRANSPORT_ERR_REVT:
        NFA_TRACE_DEBUG1 ("flags:0x%08x", nfa_dm_cb.flags);
        dm_cback_evt = (event == NFC_NFCC_TIMEOUT_REVT) ? NFA_DM_NFCC_TIMEOUT_EVT : NFA_DM_NFCC_TRANSPORT_ERR_EVT;
        (*nfa_dm_cb.p_dm_cback) (dm_cback_evt, NULL);
        break;

    case NFC_NFCC_POWER_OFF_REVT:
        nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;

        /* Notify NFA submodules change of NFCC power mode */
        nfa_sys_cback_reg_nfcc_power_mode_proc_complete (nfa_dm_nfcc_power_mode_proc_complete_cback);
        nfa_sys_notify_nfcc_power_mode (NFA_DM_PWR_MODE_OFF_SLEEP);
        break;

    case NFC_RF_COMM_PARAMS_UPDATE_REVT:
        conn_evt.status = p_data->status;
        nfa_dm_conn_cback_event_notify (NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
        break;


    default:
        break;
    }
}


/*******************************************************************************
**
** Function         nfa_dm_enable
**
** Description      Initialises the NFC device manager
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_enable (tNFA_DM_MSG *p_data)
{
    tNFA_DM_CBACK_DATA dm_cback_data;
    NFA_TRACE_DEBUG0 ("nfa_dm_enable ()");

    /* Check if NFA is already enabled */
    if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE))
    {
        /* Initialize BRCM control block, it musb be called before setting any flags */
        nfa_dm_cb.flags |= (NFA_DM_FLAGS_DM_IS_ACTIVE | NFA_DM_FLAGS_ENABLE_EVT_PEND);
        nfa_sys_cback_reg_enable_complete (nfa_dm_module_init_cback);


        /* Store Enable parameters */
        nfa_dm_cb.p_dm_cback    = p_data->enable.p_dm_cback;
        nfa_dm_cb.p_conn_cback  = p_data->enable.p_conn_cback;

        /* Enable NFC stack */
        NFC_Enable (nfa_dm_nfc_response_cback);
    }
    else
    {
        NFA_TRACE_ERROR0 ("nfa_dm_enable: ERROR ALREADY ENABLED.");
        dm_cback_data.status = NFA_STATUS_ALREADY_STARTED;
        (*(p_data->enable.p_dm_cback)) (NFA_DM_ENABLE_EVT, &dm_cback_data);
    }

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_disable
**
** Description      Disables the NFC device manager
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_disable (tNFA_DM_MSG *p_data)
{
    tNFC_DEACT_TYPE deactivate_type = NFA_DEACTIVATE_TYPE_IDLE;

    NFA_TRACE_DEBUG1 ("nfa_dm_disable (): graceful:%d", p_data->disable.graceful);

    if (p_data->disable.graceful)
    {
        /* if RF discovery is enabled */
        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)
        {
            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;

            if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
            {
                /* if waiting RSP in idle state */
                if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
                {
                    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
                }
            }
            else
            {
                nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
                nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
                if ((nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF)) == 0)
                {
                    /* not waiting to deactivate, clear the flag now */
                    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
                }
            }
        }
        /* Start timeout for graceful shutdown. If timer expires, then force an ungraceful shutdown */
        nfa_sys_start_timer (&nfa_dm_cb.tle, NFA_DM_TIMEOUT_DISABLE_EVT, NFA_DM_DISABLE_TIMEOUT_VAL);
    }

    /* Disable all subsystems other than DM (DM will be disabled after all  */
    /* the other subsystem have been disabled)                              */
    nfa_sys_disable_subsystems (p_data->disable.graceful);
    return (TRUE);
}


/*******************************************************************************
**
** Function         nfa_dm_disable_complete
**
** Description      Called when all NFA subsytems are disabled.
**
**                  NFC core stack can now be disabled.
**
** Returns          void
**
*******************************************************************************/
void nfa_dm_disable_complete (void)
{
    NFA_TRACE_DEBUG0 ("nfa_dm_disable_complete ()");

    if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_DISABLING_NFC) == 0)
    {
        NFA_TRACE_DEBUG0 ("nfa_dm_disable_complete (): proceeding with nfc core shutdown.");

        nfa_dm_cb.flags |= NFA_DM_FLAGS_DM_DISABLING_NFC;

        nfa_sys_stop_timer (&nfa_dm_cb.tle);

        /* Free all buffers for NDEF handlers */
        nfa_dm_ndef_dereg_all();

        /* Disable nfc core stack */
        NFC_Disable ();
    }
}

/*******************************************************************************
**
** Function         nfa_dm_set_config
**
** Description      Process set config command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_set_config (tNFA_DM_MSG *p_data)
{
    tNFC_STATUS status;
    UINT8       buff[255];
    UINT8      *p = buff;

    tNFA_DM_CBACK_DATA dm_cback_data;

    if (p_data->setconfig.length + 2 > 255)
    {
        /* Total length of TLV must be less than 256 (1 byte) */
        status = NFC_STATUS_FAILED;
    }
    else
    {
        UINT8_TO_STREAM (p, p_data->setconfig.param_id);
        UINT8_TO_STREAM (p, p_data->setconfig.length);
        ARRAY_TO_STREAM (p, p_data->setconfig.p_data, p_data->setconfig.length)
        status = nfa_dm_check_set_config ((UINT8) (p_data->setconfig.length + 2), buff, TRUE);
    }

    if (status != NFC_STATUS_OK)
    {
        dm_cback_data.set_config.status = NFA_STATUS_INVALID_PARAM;
        (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
    }

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_get_config
**
** Description      Process get config command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_get_config (tNFA_DM_MSG *p_data)
{
    NFC_GetConfig (p_data->getconfig.num_ids, p_data->getconfig.p_pmids);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_conn_cback_event_notify
**
** Description      Notify application of CONN_CBACK event, using appropriate
**                  callback
**
** Returns          nothing
**
*******************************************************************************/
void nfa_dm_conn_cback_event_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data)
{
    if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
    {
        /* Use exclusive RF mode callback */
        if (nfa_dm_cb.p_excl_conn_cback)
            (*nfa_dm_cb.p_excl_conn_cback) (event, p_data);
    }
    else
    {
        (*nfa_dm_cb.p_conn_cback) (event, p_data);
    }
}

/*******************************************************************************
**
** Function         nfa_dm_rel_excl_rf_control_and_notify
**
** Description      Stop exclusive RF control and notify app of
**                  NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT
**
** Returns          void
**
*******************************************************************************/
void nfa_dm_rel_excl_rf_control_and_notify (void)
{
    tNFA_CONN_EVT_DATA conn_evt;

    NFA_TRACE_DEBUG0 ("nfa_dm_rel_excl_rf_control_and_notify ()");

    /* Exclusive RF control stopped. Notify app */
    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_EXCL_RF_ACTIVE;

    /* Stop exclusive RF discovery for exclusive RF mode */
    nfa_dm_stop_excl_discovery ();

    /* Notify app that exclusive RF control has stopped */
    conn_evt.status = NFA_STATUS_OK;
    (*nfa_dm_cb.p_excl_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT, &conn_evt);
    nfa_dm_cb.p_excl_conn_cback = NULL;
    nfa_dm_cb.p_excl_ndef_cback = NULL;
}

/*******************************************************************************
**
** Function         nfa_dm_act_request_excl_rf_ctrl
**
** Description      Request exclusive RF control
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_request_excl_rf_ctrl (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA conn_evt;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_request_excl_rf_ctrl ()");

    if (!nfa_dm_cb.p_excl_conn_cback)
    {
        if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE)
        {
            conn_evt.status = NFA_STATUS_FAILED;
            (*p_data->req_excl_rf_ctrl.p_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
            return TRUE;
        }

        /* Store callbacks */
        nfa_dm_cb.p_excl_conn_cback = p_data->req_excl_rf_ctrl.p_conn_cback;
        nfa_dm_cb.p_excl_ndef_cback = p_data->req_excl_rf_ctrl.p_ndef_cback;

        nfa_dm_cb.flags |= NFA_DM_FLAGS_EXCL_RF_ACTIVE;

        /* start exclusive RF discovery */
        nfa_dm_start_excl_discovery (p_data->req_excl_rf_ctrl.poll_mask,
                                     &p_data->req_excl_rf_ctrl.listen_cfg,
                                     nfa_dm_excl_disc_cback);
    }
    else
    {
        NFA_TRACE_ERROR0 ("Exclusive rf control already requested");

        conn_evt.status = NFA_STATUS_FAILED;
        (*p_data->req_excl_rf_ctrl.p_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
    }

    return TRUE;
}


/*******************************************************************************
**
** Function         nfa_dm_act_release_excl_rf_ctrl
**
** Description      Release exclusive RF control
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_release_excl_rf_ctrl (tNFA_DM_MSG *p_data)
{
    NFA_TRACE_DEBUG0 ("nfa_dm_act_release_excl_rf_ctrl ()");

    /* nfa_dm_rel_excl_rf_control_and_notify() is called when discovery state goes IDLE */
    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;

    /* if discover command has been sent in IDLE state and waiting for response
    ** then just wait for responose. Otherwise initiate deactivating.
    */
    if (!(  (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
          &&(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)  ))
    {
        nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
    }

    if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
        nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.kovio_tle);

    return TRUE;
}

/*******************************************************************************
**
** Function         nfa_dm_act_deactivate
**
** Description      Process deactivate command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_deactivate (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA conn_evt;
    tNFA_DEACTIVATE_TYPE deact_type;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_deactivate ()");

    if (  (p_data->deactivate.sleep_mode == FALSE)                 /* Always allow deactivate to IDLE */
        ||(  (nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_T1T)      /* Do not allow deactivate to SLEEP for T1T,NFCDEP, ISO15693 */
           &&(nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_NFC_DEP)
           &&(nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_ISO15693)
           &&(nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO)  )  )
    {
        deact_type  = NFA_DEACTIVATE_TYPE_DISCOVERY;
        if (p_data->deactivate.sleep_mode)
        {
            if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)
            {
                /* Deactivate to sleep mode not allowed in this state. */
                deact_type = NFA_DEACTIVATE_TYPE_IDLE;
            }
            else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_LISTEN_SLEEP)
            {
                deact_type = NFA_DEACTIVATE_TYPE_SLEEP;
            }
        }
        if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES)
        {
            /* Only deactivate to IDLE is allowed in this state. */
            deact_type = NFA_DEACTIVATE_TYPE_IDLE;
        }

        if (  (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
            &&((nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) == 0x00)  )
        {
            /* Exclusive RF control doesn't use NFA P2P */
            /* NFA P2P will deactivate NFC link after deactivating LLCP link */
            if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED))
            {
                nfa_p2p_deactivate_llcp ();
            }
            else
            {
                nfa_dm_rf_deactivate (deact_type);
            }
            return (TRUE);
        }
        else
        {

            if (nfa_dm_rf_deactivate (deact_type) == NFA_STATUS_OK)
            {
                if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
                    nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.kovio_tle);
                nfa_rw_stop_presence_check_timer ();
                return (TRUE);
            }
        }
    }

    NFA_TRACE_ERROR0 ("nfa_dm_act_deactivate (): invalid protocol, mode or state");

    /* Notify error to application */
    conn_evt.status = NFA_STATUS_FAILED;
    nfa_dm_conn_cback_event_notify (NFA_DEACTIVATE_FAIL_EVT, &conn_evt);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_power_off_sleep
**
** Description      Process power off sleep mode request
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_power_off_sleep (tNFA_DM_MSG *p_data)
{
    NFA_TRACE_DEBUG0 ("nfa_dm_act_power_off_sleep ()");

    NFC_SetPowerOffSleep ((BOOLEAN) (p_data->hdr.layer_specific));

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_reg_vsc
**
** Description      Process registers VSC callback
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_reg_vsc(tNFA_DM_MSG *p_data)
{
    if (NFC_RegVSCback(p_data->reg_vsc.is_register, p_data->reg_vsc.p_cback) != NFC_STATUS_OK)
    {
        NFA_TRACE_ERROR0 ("NFC_RegVSCback failed");
    }
    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_send_vsc
**
** Description      Send the NCI Vendor Specific command to the NCI command queue
**
** Returns          FALSE (message buffer is NOT freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_send_vsc(tNFA_DM_MSG *p_data)
{
    BT_HDR  *p_cmd = (BT_HDR *)p_data;

    p_cmd->offset   = sizeof (tNFA_DM_API_SEND_VSC) - BT_HDR_SIZE;
    p_cmd->len      = p_data->send_vsc.cmd_params_len;
    NFC_SendVsCommand (p_data->send_vsc.oid, p_cmd, p_data->send_vsc.p_cback);

    /* Most dm action functions return TRUE, so nfa-sys frees the GKI buffer carrying the message,
     * This action function re-use the GKI buffer to send the VSC, so the GKI buffer can not be freed by nfa-sys */
    return (FALSE);
}

/*******************************************************************************
**
** Function         nfa_dm_start_polling
**
** Description      Start polling
**
** Returns          tNFA_STATUS
**
*******************************************************************************/
tNFA_STATUS nfa_dm_start_polling (void)
{
    tNFA_STATUS             status;
    tNFA_TECHNOLOGY_MASK    poll_tech_mask;
    tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;

    NFA_TRACE_DEBUG0 ("nfa_dm_start_polling ()");

    poll_tech_mask = nfa_dm_cb.poll_mask;

    /* start RF discovery with discovery callback */
    if (nfa_dm_cb.poll_disc_handle == NFA_HANDLE_INVALID)
    {
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
            poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
            poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
            poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
            poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
        }
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
        }
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
        }
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
            poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
        }
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
        }
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
        }
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
        }
        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO)
        {
            poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
        }

        nfa_dm_cb.poll_disc_handle = nfa_dm_add_rf_discover (poll_disc_mask,
                                                             NFA_DM_DISC_HOST_ID_DH,
                                                             nfa_dm_poll_disc_cback);

        if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
            status = NFA_STATUS_OK;
        else
            status = NFA_STATUS_FAILED;
    }
    else
    {
        status = NFA_STATUS_OK;
    }

    return (status);
}

/*******************************************************************************
**
** Function         nfa_dm_act_enable_polling
**
** Description      Process enable polling command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_enable_polling (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_enable_polling ()");

    if (  (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED))
        &&(!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)  )  )
    {
        nfa_dm_cb.poll_mask = p_data->enable_poll.poll_mask;

        if (nfa_dm_start_polling () == NFA_STATUS_OK)
        {
            nfa_dm_cb.flags |= NFA_DM_FLAGS_POLLING_ENABLED;

            evt_data.status = NFA_STATUS_OK;
            nfa_dm_conn_cback_event_notify (NFA_POLL_ENABLED_EVT, &evt_data);
            return (TRUE);
        }
    }
    else
    {
        NFA_TRACE_ERROR0 ("nfa_dm_act_enable_polling (): already started");
    }

    /* send NFA_POLL_ENABLED_EVT with NFA_STATUS_FAILED */
    evt_data.status = NFA_STATUS_FAILED;
    nfa_dm_conn_cback_event_notify (NFA_POLL_ENABLED_EVT, &evt_data);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_deactivate_polling
**
** Description      Deactivate any polling state
**
** Returns          TRUE if need to wait for deactivation
**
*******************************************************************************/
static BOOLEAN nfa_dm_deactivate_polling (void)
{
    NFA_TRACE_DEBUG0 ("nfa_dm_deactivate_polling ()");

    if (  (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES)
        ||(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)  )
    {
        nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
        return FALSE;
    }
    else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
    {
        if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP)
        {
            /* NFA P2P will deactivate NFC link after deactivating LLCP link */
            nfa_p2p_deactivate_llcp ();
        }
        else
        {
            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
        }
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/*******************************************************************************
**
** Function         nfa_dm_act_disable_polling
**
** Description      Process disable polling command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_disable_polling (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_disable_polling ()");

    if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
    {
        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POLLING_ENABLED;

        if (nfa_dm_deactivate_polling () == FALSE)
        {
            nfa_dm_delete_rf_discover (nfa_dm_cb.poll_disc_handle);
            nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;

            evt_data.status = NFA_STATUS_OK;
            nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
        }
        else
        {
            nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
        }
    }
    else
    {
        evt_data.status = NFA_STATUS_FAILED;
        nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
    }

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_enable_listening
**
** Description      Process enable listening command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_enable_listening (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_enable_listening ()");

    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_LISTEN_DISABLED;
    evt_data.status = NFA_STATUS_OK;
    nfa_dm_conn_cback_event_notify (NFA_LISTEN_ENABLED_EVT, &evt_data);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_disable_listening
**
** Description      Process disable listening command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_disable_listening (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_disable_listening ()");

    nfa_dm_cb.flags |= NFA_DM_FLAGS_LISTEN_DISABLED;
    evt_data.status = NFA_STATUS_OK;
    nfa_dm_conn_cback_event_notify (NFA_LISTEN_DISABLED_EVT, &evt_data);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_pause_p2p
**
** Description      Process Pause P2P command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_pause_p2p (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_pause_p2p ()");

    nfa_dm_cb.flags |= NFA_DM_FLAGS_P2P_PAUSED;
    evt_data.status = NFA_STATUS_OK;
    nfa_dm_conn_cback_event_notify (NFA_P2P_PAUSED_EVT, &evt_data);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_resume_p2p
**
** Description      Process resume P2P command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_resume_p2p (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_resume_p2p ()");

    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_P2P_PAUSED;
    evt_data.status = NFA_STATUS_OK;
    nfa_dm_conn_cback_event_notify (NFA_P2P_RESUMED_EVT, &evt_data);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_send_raw_frame
**
** Description      Send an raw frame on RF link
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_send_raw_frame (tNFA_DM_MSG *p_data)
{
    tNFC_STATUS status = NFC_STATUS_FAILED;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_send_raw_frame ()");

    /* If NFC link is activated */
    if (  (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
        ||(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)  )
    {
        nfa_dm_cb.flags |= NFA_DM_FLAGS_RAW_FRAME;
        NFC_SetReassemblyFlag (FALSE);
        /* If not in exclusive mode, and not activated for LISTEN, then forward raw data to NFA_RW to send */
        if (  !(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
            &&!(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)
            &&(  (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T1T)
               ||(nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T2T)
               ||(nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T3T)
               ||(nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO_DEP)
               ||(nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693)  )  )
        {
            /* if RW is checking presence then it will put into pending queue */
            status = nfa_rw_send_raw_frame ((BT_HDR*)p_data);
        }
        else
        {
            status = NFC_SendData (NFC_RF_CONN_ID, (BT_HDR*) p_data);
            if (status != NFC_STATUS_OK)
            {
                NFC_SetReassemblyFlag (TRUE);
            }
            /* Already freed or NCI layer will free buffer */
            return FALSE;
        }
    }

    if (status == NFC_STATUS_FAILED)
    {
        NFC_SetReassemblyFlag (TRUE);
        /* free the buffer */
        return TRUE;
    }
    else
    {
        /* NCI layer will free buffer */
        return FALSE;
    }
}

/*******************************************************************************
**
** Function         nfa_dm_set_p2p_listen_tech
**
** Description      Notify change of P2P listen technologies to NFA P2P
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_set_p2p_listen_tech (tNFA_DM_MSG *p_data)
{
    NFA_TRACE_DEBUG1 ("nfa_dm_set_p2p_listen_tech ()  tech_mask = %d",
                      p_data->set_p2p_listen_tech.tech_mask);

    nfa_p2p_update_listen_tech (p_data->set_p2p_listen_tech.tech_mask);
    nfa_dm_conn_cback_event_notify (NFA_SET_P2P_LISTEN_TECH_EVT, NULL);

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_start_rf_discovery
**
** Description      Process start RF discovery command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_start_rf_discovery (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_start_rf_discovery ()");

    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)
    {
        evt_data.status = NFA_STATUS_OK;
        nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
    }
    else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE)
    {
        evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
        nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
    }
    else
    {
        nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_ENABLED|NFA_DM_DISC_FLAGS_NOTIFY);
        nfa_dm_start_rf_discover ();
    }

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_stop_rf_discovery
**
** Description      Process stop RF discovery command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_stop_rf_discovery (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_stop_rf_discovery ()");

    if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) ||
        (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) )
    {
        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;

        /* if discover command has been sent in IDLE state and waiting for response */
        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
        {
            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
        }
        else
        {
            evt_data.status = NFA_STATUS_OK;
            nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
        }
    }
    else
    {
        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;

        if (nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE) == NFA_STATUS_OK)
        {
            if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
                nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.kovio_tle);
            nfa_rw_stop_presence_check_timer ();
        }
    }
    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_set_rf_disc_duration
**
** Description      Set duration for RF discovery
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_set_rf_disc_duration (tNFA_DM_MSG *p_data)
{
    nfa_dm_cb.disc_cb.disc_duration = p_data->disc_duration.rf_disc_dur_ms;
    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_get_rf_disc_duration
**
** Description      Get duration for RF discovery
**
** Returns          UINT16
**
*******************************************************************************/
UINT16 nfa_dm_act_get_rf_disc_duration ( )
{
    return (nfa_dm_cb.disc_cb.disc_duration);
}
/*******************************************************************************
**
** Function         nfa_dm_act_select
**
** Description      Process RF select command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_select (tNFA_DM_MSG *p_data)
{
    NFA_TRACE_DEBUG0 ("nfa_dm_act_select ()");

    nfa_dm_rf_discover_select (p_data->select.rf_disc_id,
                               p_data->select.protocol,
                               p_data->select.rf_interface);
    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_update_rf_params
**
** Description      Process update RF communication parameters command
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_update_rf_params (tNFA_DM_MSG *p_data)
{
    tNFA_CONN_EVT_DATA conn_evt;

    NFA_TRACE_DEBUG0 ("nfa_dm_act_update_rf_params ()");

    if (NFC_UpdateRFCommParams (&p_data->update_rf_params.params) != NFC_STATUS_OK)
    {
        conn_evt.status = NFA_STATUS_FAILED;
        nfa_dm_conn_cback_event_notify (NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
    }

    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_disable_timeout
**
** Description      timeout on disable process. Shutdown immediately
**
** Returns          TRUE (message buffer to be freed by caller)
**
*******************************************************************************/
BOOLEAN nfa_dm_act_disable_timeout (tNFA_DM_MSG *p_data)
{
    tNFA_DM_API_DISABLE disable;

    disable.graceful = FALSE;
    nfa_dm_disable ((tNFA_DM_MSG *) &disable);
    return (TRUE);
}

/*******************************************************************************
**
** Function         nfa_dm_act_conn_cback_notify
**
** Description      Notify app of reader/writer/ndef events
**
** Returns          nothing
**
*******************************************************************************/
void nfa_dm_act_conn_cback_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data)
{
    NFA_TRACE_DEBUG1 ("nfa_dm_act_conn_cback_notify (): event:0x%X", event);

    /* Notify event using appropriate CONN_CBACK */
    nfa_dm_conn_cback_event_notify (event, p_data);

    /* If not in exclusive RF mode, then read NDEF message from tag (if automatic reading is enabled) */
    if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE))
    {
        if (  (event == NFA_NDEF_DETECT_EVT)
            &&(nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF)  )
        {
            /* read NDEF message from tag */
            if (p_data->ndef_detect.status == NFA_STATUS_OK)
            {
                NFA_RwReadNDef ();
            }
            else if (p_data->ndef_detect.status == NFA_STATUS_FAILED)
            {
                nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
            }
            /* ignore NFA_STATUS_BUSY */
        }
        else if (  (event == NFA_READ_CPLT_EVT)
                 &&(nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF))
        {
            /* reading NDEF message is done */
            nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
        }
    }
}

/*******************************************************************************
**
** Function         nfa_dm_act_data_cback
**
** Description      Processing data from RF link
**
** Returns          None
**
*******************************************************************************/
static void nfa_dm_act_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
{
    BT_HDR             *p_msg;
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG1 ("nfa_dm_act_data_cback (): event = 0x%X", event);

    if (event == NFC_DATA_CEVT)
    {
        p_msg = (BT_HDR *) p_data->data.p_data;

        if (p_msg)
        {
            evt_data.data.status = p_data->data.status;
            evt_data.data.p_data = (UINT8 *) (p_msg + 1) + p_msg->offset;
            evt_data.data.len    = p_msg->len;

            nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data);

            GKI_freebuf (p_msg);
        }
        else
        {
            NFA_TRACE_ERROR0 ("nfa_dm_act_data_cback (): received NFC_DATA_CEVT with NULL data pointer");
        }
    }
    else if (event == NFC_DEACTIVATE_CEVT)
    {
        NFC_SetStaticRfCback (NULL);
    }
}

/*******************************************************************************
**
** Function         nfa_dm_excl_disc_cback
**
** Description      Processing event from discovery callback
**
** Returns          None
**
*******************************************************************************/
static void nfa_dm_excl_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG1 ("nfa_dm_excl_disc_cback (): event:0x%02X", event);

    switch (event)
    {
    case NFA_DM_RF_DISC_START_EVT:
        evt_data.status = NFA_STATUS_OK;
        nfa_dm_conn_cback_event_notify (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &evt_data);
        break;

    case NFA_DM_RF_DISC_ACTIVATED_EVT:
        if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A)
        {
            /* store SEL_RES response */
            nfa_dm_cb.disc_cb.activated_sel_res = p_data->activate.rf_tech_param.param.pa.sel_rsp;
        }

        if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)
        {
            /* Set data callback to receive raw frame */
            NFC_SetStaticRfCback (nfa_dm_act_data_cback);

            memset (&(evt_data.activated.params), 0x00, sizeof (tNFA_TAG_PARAMS));
            memcpy (&(evt_data.activated.activate_ntf), &(p_data->activate), sizeof (tNFC_ACTIVATE_DEVT));

            nfa_dm_conn_cback_event_notify (NFA_ACTIVATED_EVT, &evt_data);
        }
        else
        {
            /* holding activation notification until sub-module is ready */
            nfa_dm_cb.p_activate_ntf = (UINT8*) GKI_getbuf (sizeof (tNFC_ACTIVATE_DEVT));

            if (nfa_dm_cb.p_activate_ntf)
            {
                memcpy (nfa_dm_cb.p_activate_ntf,
                        &(p_data->activate),
                        sizeof (tNFC_ACTIVATE_DEVT));

                if (  (nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T1T)
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T2T)
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T3T)
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_ISO_DEP)
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFA_PROTOCOL_ISO15693)
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_KOVIO)  )
                {
                    /* Notify NFA tag sub-system */
                    nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, FALSE);
                }
                else /* if NFC-DEP, ISO-DEP with frame interface or others */
                {
                    /* Set data callback to receive raw frame */
                    NFC_SetStaticRfCback (nfa_dm_act_data_cback);
                    nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
                }
            }
            else
            {
                /* deactivate and restart RF discovery */
                nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
            }
        }
        break;

    case NFA_DM_RF_DISC_DEACTIVATED_EVT:

        /* if deactivated to idle or discovery */
        if (  (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
            ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)  )
        {
            /* clear stored NFCID/UID/KOVIO bar code */
            nfa_dm_cb.activated_nfcid_len = 0;
        }

        if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP)
        {
            /* Notify NFA RW sub-systems */
            nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, FALSE);
        }

        /* if deactivated as sleep mode */
        if (  (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
            ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
        {
            evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
        }
        else
        {
            evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
        }

        /* notify deactivation to upper layer */
        nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);

        /* clean up SEL_RES response */
        nfa_dm_cb.disc_cb.activated_sel_res = 0;
        break;

    default:
        NFA_TRACE_ERROR0 ("Unexpected event");
        break;
    }
}

/*******************************************************************************
**
** Function         nfa_dm_poll_disc_cback
**
** Description      Processing event from discovery callback
**
** Returns          None
**
*******************************************************************************/
static void nfa_dm_poll_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
{
    tNFA_CONN_EVT_DATA evt_data;

    NFA_TRACE_DEBUG1 ("nfa_dm_poll_disc_cback (): event:0x%02X", event);

    switch (event)
    {
    case NFA_DM_RF_DISC_START_EVT:
        break;

    case NFA_DM_RF_DISC_ACTIVATED_EVT:

        if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A)
        {
            /* store SEL_RES response */
            nfa_dm_cb.disc_cb.activated_sel_res = p_data->activate.rf_tech_param.param.pa.sel_rsp;
        }

        /* holding activation notification until sub-module is ready */
        nfa_dm_cb.p_activate_ntf = (UINT8*) GKI_getbuf (sizeof (tNFC_ACTIVATE_DEVT));

        if (nfa_dm_cb.p_activate_ntf)
        {
            memcpy (nfa_dm_cb.p_activate_ntf,
                    &(p_data->activate),
                    sizeof (tNFC_ACTIVATE_DEVT));

            if (  (nfa_dm_cb.disc_cb.activated_protocol     == NFC_PROTOCOL_NFC_DEP)
                &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_NFC_DEP)  )
            {
                if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED))
                {
                    /* activate LLCP */
                    nfa_p2p_activate_llcp (p_data);
                    if (nfa_dm_cb.p_activate_ntf)
                    {
                        GKI_freebuf (nfa_dm_cb.p_activate_ntf);
                        nfa_dm_cb.p_activate_ntf = NULL;
                    }
                }
                else
                {
                    NFA_TRACE_DEBUG0 ("P2P is paused");
                    nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
                }
            }
            else if (  (nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T1T)
                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T2T)
                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T3T)
                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_ISO_DEP)
                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_15693)
                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_KOVIO)
                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_MIFARE)  )
            {
                /* Notify NFA tag sub-system */
                nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, TRUE);
            }
            else /* if NFC-DEP/ISO-DEP with frame interface */
            {
                /* Set data callback to receive raw frame */
                NFC_SetStaticRfCback (nfa_dm_act_data_cback);
                nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
            }
        }
        else
        {
            /* deactivate and restart RF discovery */
            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
        }
        break;

    case NFA_DM_RF_DISC_DEACTIVATED_EVT:

        /* if deactivated to idle or discovery */
        if (  (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
            ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)  )
        {
            /* clear stored NFCID/UID/KOVIO bar code */
            nfa_dm_cb.activated_nfcid_len = 0;
        }

        if (  (nfa_dm_cb.disc_cb.activated_protocol     == NFC_PROTOCOL_NFC_DEP)
            &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_NFC_DEP)  )
        {
            /*
            ** If LLCP link is not deactivated yet,
            ** LLCP will receive deactivation ntf through data callback.
            ** NFA P2P will receive callback event from LLCP.
            */
        }
        else
        {
            /* Notify NFA RW sub-systems */
            nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, TRUE);
        }

        /* if NFA sent NFA_ACTIVATED_EVT earlier */
        if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_DEACTIVATED_EVT)
        {
            nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;

            /* if deactivated as sleep mode */
            if (  (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
                ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
            {
                evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
            }
            else
            {
                evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
            }
            /* notify deactivation to application */
            nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
        }

        /* clean up SEL_RES response */
        nfa_dm_cb.disc_cb.activated_sel_res = 0;

        if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED))
        {
            /* deregister discovery callback from NFA DM Discovery */
            nfa_dm_delete_rf_discover (nfa_dm_cb.poll_disc_handle);
            nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;

            /* this is for disable polling */
            if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_POLL_STOP_EVT)
            {
                nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_POLL_STOP_EVT;

                evt_data.status = NFA_STATUS_OK;
                nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
            }
        }
        break;
    }
}

/*******************************************************************************
**
** Function         nfa_dm_notify_activation_status
**
** Description      Processing activation status from sub-modules
**
** Returns          None
**
*******************************************************************************/
void nfa_dm_notify_activation_status (tNFA_STATUS status, tNFA_TAG_PARAMS *p_params)
{
    tNFA_CONN_EVT_DATA  evt_data;
    tNFC_RF_TECH_PARAMS *p_tech_params;
    UINT8               *p_nfcid = NULL, nfcid_len;

    NFA_TRACE_DEBUG1 ("nfa_dm_notify_activation_status (): status:0x%X", status);

    if (!nfa_dm_cb.p_activate_ntf)
    {
        /* this is for NFA P2P listen */
        return;
    }

    if (status == NFA_STATUS_OK)
    {
        /* notify NFC link activation */
        memcpy ( &(evt_data.activated.activate_ntf),
                 nfa_dm_cb.p_activate_ntf,
                 sizeof (tNFC_ACTIVATE_DEVT));

        p_tech_params = &evt_data.activated.activate_ntf.rf_tech_param;

        memset (&(evt_data.activated.params), 0x00, sizeof (tNFA_TAG_PARAMS));
        if (p_params)
        {
            memcpy (&(evt_data.activated.params),
                    p_params,
                    sizeof (tNFA_TAG_PARAMS));
        }

        /* get length of NFCID and location */
        if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_A)
        {
            if ((p_tech_params->param.pa.nfcid1_len == 0) && (p_params != NULL))
            {
                nfcid_len = sizeof(p_params->t1t.uid);
                p_nfcid   = p_params->t1t.uid;
                evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1_len = nfcid_len;
                memcpy (evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1, p_nfcid, nfcid_len);
            }
            else
            {
                nfcid_len = p_tech_params->param.pa.nfcid1_len;
                p_nfcid   = p_tech_params->param.pa.nfcid1;
            }
        }
        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_B)
        {
            nfcid_len = NFC_NFCID0_MAX_LEN;
            p_nfcid   = p_tech_params->param.pb.nfcid0;
        }
        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_F)
        {
            nfcid_len = NFC_NFCID2_LEN;
            p_nfcid   = p_tech_params->param.pf.nfcid2;
        }
        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_ISO15693)
        {
            nfcid_len = NFC_ISO15693_UID_LEN;
            p_nfcid   = p_tech_params->param.pi93.uid;
        }
        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_KOVIO)
        {
            nfcid_len = p_tech_params->param.pk.uid_len;
            p_nfcid   = p_tech_params->param.pk.uid;
        }
        else
        {
            nfcid_len = 0;
        }

        /*
        ** If not in exlusive RF mode, and
        **      P2P activation, then push default NDEF message through SNEP
        **      TAG activation, then read NDEF message
        */
        if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP)
        {
            /*
            ** Default NDEF message will be put to NFC Forum defualt SNEP server
            ** after receiving NFA_LLCP_ACTIVATED_EVT.
            */
        }
        else if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE))
        {
            /*
            ** if the same tag is activated then do not perform auto NDEF detection.
            ** Application may put a tag into sleep mode and reactivate the same tag.
            */

            if (  (p_tech_params->mode != nfa_dm_cb.activated_tech_mode)
                ||(nfcid_len != nfa_dm_cb.activated_nfcid_len)
                ||(memcmp (p_nfcid, nfa_dm_cb.activated_nfcid, nfcid_len)))
            {
                if (  (nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T1T)
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T2T)
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T3T)
                    ||(  (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP)
                       &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_ISO_DEP)  )
                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFA_PROTOCOL_ISO15693)  )
                {
                    if (p_nfa_dm_cfg->auto_detect_ndef)
                    {
                        if (p_nfa_dm_cfg->auto_read_ndef)
                        {
                            nfa_dm_cb.flags |= NFA_DM_FLAGS_AUTO_READING_NDEF;
                        }
                        NFA_RwDetectNDef ();
                    }
                    else if (p_nfa_dm_cfg->auto_read_ndef)
                    {
                        NFA_RwReadNDef ();
                    }
                }
            }
        }

        /* store activated tag information */
        nfa_dm_cb.activated_tech_mode = p_tech_params->mode;
        nfa_dm_cb.activated_nfcid_len = nfcid_len;
        if (nfcid_len)
            memcpy (nfa_dm_cb.activated_nfcid, p_nfcid, nfcid_len);

        nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;
        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING))
            nfa_dm_conn_cback_event_notify (NFA_ACTIVATED_EVT, &evt_data);
    }
    else
    {
        /* if NFC_DEP, NFA P2P will deactivate */
        if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP)
        {
            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
        }
    }

    GKI_freebuf (nfa_dm_cb.p_activate_ntf);
    nfa_dm_cb.p_activate_ntf = NULL;
}

#if (BT_TRACE_VERBOSE == TRUE)
/*******************************************************************************
**
** Function         nfa_dm_nfc_revt_2_str
**
** Description      convert nfc revt to string
**
*******************************************************************************/
char *nfa_dm_nfc_revt_2_str (tNFC_RESPONSE_EVT event)
{
    switch (event) {
    case NFC_ENABLE_REVT:
        return "NFC_ENABLE_REVT";

    case NFC_DISABLE_REVT:
        return "NFC_DISABLE_REVT";

    case NFC_SET_CONFIG_REVT:
        return "NFC_SET_CONFIG_REVT";

    case NFC_GET_CONFIG_REVT:
        return "NFC_GET_CONFIG_REVT";

    case NFC_NFCEE_DISCOVER_REVT:
        return "NFC_NFCEE_DISCOVER_REVT";

    case NFC_NFCEE_INFO_REVT:
        return "NFC_NFCEE_INFO_REVT";

    case NFC_NFCEE_MODE_SET_REVT:
        return "NFC_NFCEE_MODE_SET_REVT";

    case NFC_RF_FIELD_REVT:
        return "NFC_RF_FIELD_REVT";

    case NFC_EE_ACTION_REVT:
        return "NFC_EE_ACTION_REVT";

    case NFC_EE_DISCOVER_REQ_REVT:
        return "NFC_EE_DISCOVER_REQ_REVT";

    case NFC_SET_ROUTING_REVT:
        return "NFC_SET_ROUTING_REVT";

    case NFC_GET_ROUTING_REVT:
        return "NFC_GET_ROUTING_REVT";

    case NFC_GEN_ERROR_REVT:
        return "NFC_GEN_ERROR_REVT";

    case NFC_NFCC_RESTART_REVT:
        return "NFC_NFCC_RESTART_REVT";

    case NFC_NFCC_TIMEOUT_REVT:
        return "NFC_NFCC_TIMEOUT_REVT";

    case NFC_NFCC_TRANSPORT_ERR_REVT:
        return "NFC_NFCC_TRANSPORT_ERR_REVT";

    case NFC_NFCC_POWER_OFF_REVT:
        return "NFC_NFCC_POWER_OFF_REVT";

    default:
        return "unknown revt";
        break;
    }
}
#endif /* BT_VERBOSE */