| /* |
| * 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*/ |