blob: b231f1e32cdfecfd47014d68743b37baa2e1cae6 [file] [log] [blame]
/*
* 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*/