/*******************************************************************************
**
** Function         EXTNS_Init
**
** Description      This function Initializes Mifare Classic Extns. Allocates
**                  required memory and initializes the Mifare Classic Vars
**
** Returns          NFCSTATUS_SUCCESS if successfully initialized
**                  NFCSTATUS_FAILED otherwise
**
*******************************************************************************/
NFCSTATUS EXTNS_Init(tNFA_DM_CBACK        *p_nfa_dm_cback,
                     tNFA_CONN_CBACK      *p_nfa_conn_cback)
{
    NFCSTATUS status = NFCSTATUS_FAILED;

    /* reset config cache */
    resetNxpConfig();

    /* Initialize Log level */
    phNxpLog_InitializeLogLevel();

    /* Validate parameters */
    if( (!p_nfa_dm_cback) || (!p_nfa_conn_cback) )
    {
        NXPLOG_EXTNS_E ("EXTNS_Init(): error null callback");
        goto clean_and_return;
    }

    gphNxpExtns_Context.p_dm_cback = p_nfa_dm_cback;
    gphNxpExtns_Context.p_conn_cback = p_nfa_conn_cback;

    if( NFCSTATUS_SUCCESS != phNxpExtns_MfcModuleInit() )
    {
       NXPLOG_EXTNS_E("ERROR: MFC Module Init Failed");
       goto clean_and_return;
    }
    gphNxpExtns_Context.Extns_status = EXTNS_STATUS_OPEN;

    status = NFCSTATUS_SUCCESS;
    return status;

clean_and_return:
    gphNxpExtns_Context.Extns_status = EXTNS_STATUS_CLOSE;
    return status;
}
/*******************************************************************************
 **
 ** Function         phNxpNciHal_TestMode_open
 **
 ** Description      It opens the physical connection with NFCC (pn547) and
 **                  creates required client thread for operation.
 **
 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
 **
 *******************************************************************************/
NFCSTATUS phNxpNciHal_TestMode_open (void)
{
    /* Thread */
    pthread_t test_rx_thread;

    phOsalNfc_Config_t tOsalConfig;
    phTmlNfc_Config_t tTmlConfig;
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    uint16_t read_len = 255;

    /* initialize trace level */
    phNxpLog_InitializeLogLevel();

    if (phNxpNciHal_init_monitor() == NULL)
    {
        NXPLOG_NCIHAL_E("Init monitor failed");
        return NFCSTATUS_FAILED;
    }

    CONCURRENCY_LOCK();

    memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
    memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));

    gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
    gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN547 */
    tTmlConfig.pDevName = (int8_t *) "/dev/pn544";
    tOsalConfig.dwCallbackThreadId = (uint32_t) gDrvCfg.nClientId;
    tOsalConfig.pLogFile = NULL;
    tTmlConfig.dwGetMsgThreadId = (uint32_t) gDrvCfg.nClientId;
    nxpncihal_ctrl.gDrvCfg.nClientId = (uint32_t) gDrvCfg.nClientId;

    /* Initialize TML layer */
    status = phTmlNfc_Init(&tTmlConfig);
    if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
        goto clean_and_return;
    }

    if (pthread_create(&test_rx_thread, NULL,
            phNxpNciHal_test_rx_thread, NULL) != 0)
    {
        NXPLOG_NCIHAL_E("pthread_create failed");
        phTmlNfc_Shutdown();
        goto clean_and_return;
    }

    timeoutTimerId = phOsalNfc_Timer_Create();

    if(timeoutTimerId == 0xFFFF)
    {
        NXPLOG_NCIHAL_E("phOsalNfc_Timer_Create failed");
    }
    else
    {
        NXPLOG_NCIHAL_D("phOsalNfc_Timer_Create SUCCESS");
    }
    CONCURRENCY_UNLOCK();

    return NFCSTATUS_SUCCESS;

clean_and_return:
    CONCURRENCY_UNLOCK();
    phNxpNciHal_cleanup_monitor();
    return NFCSTATUS_FAILED;
}