/*
 * Copyright (C) 2010 NXP Semiconductors
 *
 * 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.
 */
/*!
* \file  phHal4Nfc_Emulation.c
* \brief Hal4 Emulation source.
*
* Project: NFC-FRI 1.1
*
* $Date: Wed May 26 18:03:59 2010 $
* $Author: ing07385 $
* $Revision: 1.35 $
* $Aliases: NFC_FRI1.1_WK1023_R35_1 $
*
*/

/* ---------------------------Include files ------------------------------------*/
#include <phHciNfc.h>
#include <phHal4Nfc.h>
#include <phHal4Nfc_Internal.h>
#include <phOsalNfc.h>

/* ------------------------------- Macros ------------------------------------*/

/* Note : Macros required and used  only in this module to be declared here*/


/* --------------------Structures and enumerations --------------------------*/


/*Event Notification handler for emulation*/
void phHal4Nfc_HandleEmulationEvent(
                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                    void *pInfo
                                    )
{
    phNfc_sNotificationInfo_t *psNotificationInfo = (phNfc_sNotificationInfo_t *)
                                                                            pInfo;
    phHal4Nfc_NotificationInfo_t uNotificationInfo = {NULL};
    /*Pass on Event notification info from Hci to Upper layer*/
    uNotificationInfo.psEventInfo = psNotificationInfo->info;
    if(NULL != Hal4Ctxt->sUpperLayerInfo.pEventNotification)
    {        
        Hal4Ctxt->sUpperLayerInfo.pEventNotification(
            Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt,
            psNotificationInfo->type,
            uNotificationInfo,
            NFCSTATUS_SUCCESS
            );
    }
    else/*No Event notification handler registered*/
    {
        /*Use default handler to notify to the upper layer*/
        if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
        {
            Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
                Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
                psNotificationInfo->type,
                uNotificationInfo,
                NFCSTATUS_SUCCESS
                );
        }
    }
    return;
}

/*  Switch mode from Virtual to Wired or Vice Versa for SMX.
*/
NFCSTATUS phHal4Nfc_Switch_SMX_Mode(                                    
                                    phHal_sHwReference_t      *psHwReference,
                                    phHal_eSmartMX_Mode_t      smx_mode,
                                    pphHal4Nfc_GenCallback_t   pSwitchModecb,
                                    void                      *pContext
                                    )
{
    NFCSTATUS CfgStatus = NFCSTATUS_PENDING;
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    static phHal_sADD_Cfg_t sSmxCfg;
    
    /*NULL  checks*/
    if((NULL == psHwReference) || (NULL == pSwitchModecb))
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
    }
    /*Check Initialised state*/
    else if((NULL == psHwReference->hal_context)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4CurrentState 
                                               < eHal4StateOpenAndReady)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4NextState 
                                               == eHal4StateClosed))
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
    }
    else
    {
        Hal4Ctxt = psHwReference->hal_context;
        /*Previous POLL Config has not completed or device is connected,
          do not allow poll*/
        if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
        {
            PHDBG_INFO("Hal4:Configuration in progress.Returning status Busy");
            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
        }
        else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
        {
            /**If config discovery has not been called prior to this ,allocate 
               ADD Context here*/
            if (NULL == Hal4Ctxt->psADDCtxtInfo)
            {
                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
                    phOsalNfc_GetMemory((uint32_t)
                                        (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
                if(NULL != Hal4Ctxt->psADDCtxtInfo)
                {
                    (void)memset(Hal4Ctxt->psADDCtxtInfo,
                                    0,sizeof(phHal4Nfc_ADDCtxtInfo_t));
                }
            }
            if(NULL == Hal4Ctxt->psADDCtxtInfo)
            {
                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
                CfgStatus= PHNFCSTVAL(CID_NFC_HAL , 
                                        NFCSTATUS_INSUFFICIENT_RESOURCES);
            }
            else
            {   
                /* Register Upper layer context */
                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
                /* Switch request to Wired mode */
                if(eSmartMx_Wired == smx_mode)
                {
                    if(Hal4Ctxt->Hal4CurrentState 
                                    == eHal4StateTargetConnected)
                    {
                        PHDBG_INFO("Hal4:In Connected state.Returning Busy");
                        CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
                    }
                    /*It is Mandatory to register a listener before switching 
                      to wired mode*/
                    else if(NULL ==
                            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
                    {
                        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , 
                            NFCSTATUS_FAILED);
                    }
                    else
                    {
                        Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
                        Hal4Ctxt->psADDCtxtInfo->smx_discovery = TRUE;
                        sSmxCfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
                        sSmxCfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
                        /*Switch mode to wired*/
                        CfgStatus = phHciNfc_Switch_SmxMode (
                                                    Hal4Ctxt->psHciHandle,
                                                    psHwReference,
                                                    smx_mode,
                                                    &sSmxCfg
                                                    );
                    }
                }
                else
                {
                    Hal4Ctxt->psADDCtxtInfo->smx_discovery = FALSE;
                    /*Switch mode to virtual or off*/
                    CfgStatus = phHciNfc_Switch_SmxMode (
                                        Hal4Ctxt->psHciHandle,
                                        psHwReference,
                                        smx_mode,
                                        &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
                                        );
                }

                /* Change the State of the HAL only if Switch mode Returns
                   Success*/
                if ( NFCSTATUS_PENDING == CfgStatus )
                {
                    Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
                    Hal4Ctxt->sUpperLayerInfo.pConfigCallback
                        = pSwitchModecb;
                }
            }           
        }
        else/*Return Status not initialised*/
        {
            phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
        }
    }
    return CfgStatus;
}



/*  Switch mode for Swp.*/
NFCSTATUS phHal4Nfc_Switch_Swp_Mode(                                    
                                    phHal_sHwReference_t      *psHwReference,
                                    phHal_eSWP_Mode_t          swp_mode,
                                    pphHal4Nfc_GenCallback_t   pSwitchModecb,
                                    void                      *pContext
                                    )
{
    NFCSTATUS CfgStatus = NFCSTATUS_PENDING;
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 
    /*NULL checks*/
    if(NULL == psHwReference  
        || NULL == pSwitchModecb
        )
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
    }
    /*Check Initialised state*/
    else if((NULL == psHwReference->hal_context)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4CurrentState 
                                               < eHal4StateOpenAndReady)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4NextState 
                                               == eHal4StateClosed))
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
    }
    else
    {
        Hal4Ctxt = psHwReference->hal_context;
        /*Previous POLL CFG has not completed or device is connected,
          do not allow poll*/
        if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
        {
            PHDBG_INFO("Hal4:Configuration in progress.Returning status Busy");
            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
        }
        else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
        {
             /**If config discovery has not been called prior to this ,allocate 
               ADD Context here*/
            if (NULL == Hal4Ctxt->psADDCtxtInfo)
            {
                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
                    phOsalNfc_GetMemory((uint32_t)
                                        (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
                if(NULL != Hal4Ctxt->psADDCtxtInfo)
                {
                    (void)memset(Hal4Ctxt->psADDCtxtInfo,
                                    0,sizeof(phHal4Nfc_ADDCtxtInfo_t));
                }
            }
            if(NULL == Hal4Ctxt->psADDCtxtInfo)
            {
                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
                CfgStatus= PHNFCSTVAL(CID_NFC_HAL , 
                                        NFCSTATUS_INSUFFICIENT_RESOURCES);
            }
            else
            {   
                /* Register Upper layer context */
                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 
                /*Switch mode to On or off*/
                CfgStatus = phHciNfc_Switch_SwpMode(
                                    Hal4Ctxt->psHciHandle,
                                    psHwReference,
                                    swp_mode
                                    );

                /* Change the State of the HAL only if Switch mode Returns
                   Success*/
                if ( NFCSTATUS_PENDING == CfgStatus )
                {
                    Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
                    Hal4Ctxt->sUpperLayerInfo.pConfigCallback
                        = pSwitchModecb;
                }
            }           
        }
        else/*Return Status not initialised*/
        {
            phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
        }
    }
    return CfgStatus;
}

#ifdef FULL_HAL4_EMULATION_ENABLE
/*  Switch Emulation mode ON or OFF.*/
NFCSTATUS phHal4Nfc_Host_Emulation_Mode( 
                                        phHal_sHwReference_t      *psHwReference,
                                        phNfc_eModeType_t          eModeType,
                                        pphHal4Nfc_GenCallback_t   pEmulationModecb,
                                        void                      *pContext
                                        )
{
    NFCSTATUS RetStatus = NFCSTATUS_PENDING;
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    /*NULL checks*/
    if(NULL == psHwReference  
        || NULL == pEmulationModecb
        )
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
    }
    /*Check Initialised state*/
    else if((NULL == psHwReference->hal_context)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4CurrentState 
                                               < eHal4StateOpenAndReady)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4NextState 
                                               == eHal4StateClosed))
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
    }    
    else
    {

    }
    return NFCSTATUS_PENDING;
}
#endif /*FULL_HAL4_EMULATION_ENABLE*/
