diff options
author | Nick Pelly <npelly@google.com> | 2010-09-23 12:47:58 -0700 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-09-23 13:53:18 -0700 |
commit | 5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch) | |
tree | 190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phHal4Nfc_ADD.c | |
parent | 4ff7c86a2c706b150078274455406f1b04966e1a (diff) | |
download | external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.zip external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.gz external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.bz2 |
Initial libnfc checkin
Source: Trusted_NFC_Device_Host_AA03.01e02_google.zip code drop (23-Sep-2010)
Change-Id: Ie47f18423f949a8d3e0815d13f55c814312add24
Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'src/phHal4Nfc_ADD.c')
-rw-r--r-- | src/phHal4Nfc_ADD.c | 981 |
1 files changed, 981 insertions, 0 deletions
diff --git a/src/phHal4Nfc_ADD.c b/src/phHal4Nfc_ADD.c new file mode 100644 index 0000000..2d9e2fd --- /dev/null +++ b/src/phHal4Nfc_ADD.c @@ -0,0 +1,981 @@ +/* + * 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_ADD.c + * \brief Hal4Nfc_ADD source. + * + * Project: NFC-FRI 1.1 + * + * $Date: Mon May 31 11:43:42 2010 $ + * $Author: ing07385 $ + * $Revision: 1.151 $ + * $Aliases: NFC_FRI1.1_WK1023_R35_1 $ + * + */ + +/* ---------------------------Include files ----------------------------------*/ +#include <phHciNfc.h> +#include <phHal4Nfc.h> +#include <phHal4Nfc_Internal.h> +#include <phOsalNfc.h> + +/* ------------------------------- Macros ------------------------------------*/ +#define NFCIP_ACTIVE_SHIFT 0x03U +#define NXP_UID 0x04U +#define NXP_MIN_UID_LEN 0x07U +/* --------------------Structures and enumerations --------------------------*/ + +NFCSTATUS phHal4Nfc_ConfigParameters( + phHal_sHwReference_t *psHwReference, + phHal_eConfigType_t CfgType, + phHal_uConfig_t *puConfig, + pphHal4Nfc_GenCallback_t pConfigCallback, + void *pContext + ) +{ + NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + /*NULL checks*/ + if(NULL == psHwReference + || NULL == pConfigCallback + || NULL == puConfig + ) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); + } + /*Check if initialised*/ + 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; + /*If previous Configuration request has not completed,do not allow new + configuration*/ + if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring) + { + PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy"); + CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY); + } + else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady) + { + /*Allocate ADD context*/ + 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(CfgType) + { + /*NFC_EMULATION_CONFIG*/ + case NFC_EMULATION_CONFIG: + { + (void)memcpy((void *)&Hal4Ctxt->uConfig, + (void *)puConfig, + sizeof(phHal_uConfig_t) + ); + break; + } + /*P2P Configuration*/ + case NFC_P2P_CONFIG: + { + /*If general bytes are not provided by above layer copy zeros + in general bytes*/ + if(puConfig->nfcIPConfig.generalBytesLength == 0) + { + Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength = 0x30; + (void)memset(Hal4Ctxt->uConfig.nfcIPConfig.generalBytes, + 0,Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength + ); + } + else + { + (void)memcpy((void *)&Hal4Ctxt->uConfig, + (void *)puConfig, + sizeof(phHal_uConfig_t) + ); + } + break; + } + /*Protection config*/ + case NFC_SE_PROTECTION_CONFIG: + { +#ifdef IGNORE_EVT_PROTECTED + Hal4Ctxt->Ignore_Event_Protected = FALSE; +#endif/*#ifdef IGNORE_EVT_PROTECTED*/ + (void)memcpy((void *)&Hal4Ctxt->uConfig, + (void *)puConfig, + sizeof(phHal_uConfig_t) + ); + break; + } + default: + CfgStatus = NFCSTATUS_FAILED; + break; + } + if ( NFCSTATUS_SUCCESS == CfgStatus ) + { + /*Issue configure with given configuration*/ + CfgStatus = phHciNfc_Configure( + (void *)Hal4Ctxt->psHciHandle, + (void *)psHwReference, + CfgType, + &Hal4Ctxt->uConfig + ); + /* Change the State of the HAL only if status is Pending */ + if ( NFCSTATUS_PENDING == CfgStatus ) + { + Hal4Ctxt->Hal4NextState = eHal4StateConfiguring; + Hal4Ctxt->sUpperLayerInfo.pConfigCallback + = pConfigCallback; + } + } + } + } + else + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); + } + } + return CfgStatus; +} + + +/**Configure the discovery*/ +NFCSTATUS phHal4Nfc_ConfigureDiscovery( + phHal_sHwReference_t *psHwReference, + phHal_eDiscoveryConfigMode_t discoveryMode, + phHal_sADD_Cfg_t *discoveryCfg, + pphHal4Nfc_GenCallback_t pConfigCallback, + void *pContext + ) +{ + NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + if(NULL == psHwReference + || NULL == pConfigCallback + || NULL == discoveryCfg + ) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); + } + 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; + /*If previous Configuration request has not completed ,do not allow + new configuration*/ + if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring) + { + PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy"); + CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY); + } + else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady) + { + 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(discoveryMode) + { + case NFC_DISCOVERY_START: + PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_START"); + break; + case NFC_DISCOVERY_CONFIG: + PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_CONFIG"); + /*Since sADDCfg is allocated in stack ,copy the ADD + configuration structure to HAL4 context*/ + (void)memcpy((void *) + &(Hal4Ctxt->psADDCtxtInfo->sADDCfg), + (void *)discoveryCfg, + sizeof(phHal_sADD_Cfg_t) + ); + PHDBG_INFO("Hal4:Finished copying sADDCfg"); + Hal4Ctxt->psADDCtxtInfo->smx_discovery = FALSE; +#ifdef UPDATE_NFC_ACTIVE + Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo.EnableNfcActive + = ( 0 == Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode? + Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode: + NXP_NFCIP_ACTIVE_DEFAULT); + Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode = (( + Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode << + (NXP_NFCIP_ACTIVE_DEFAULT * NFCIP_ACTIVE_SHIFT)) + | Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode); +#endif/*#ifdef UPDATE_NFC_ACTIVE*/ + /* information system_code(Felica) and + AFI(ReaderB) to be populated later */ + + CfgStatus = phHciNfc_Config_Discovery( + (void *)Hal4Ctxt->psHciHandle, + (void *)psHwReference, + &(Hal4Ctxt->psADDCtxtInfo->sADDCfg) + );/*Configure HCI Discovery*/ + break; + case NFC_DISCOVERY_STOP: + break; + /*Restart Discovery wheel*/ + case NFC_DISCOVERY_RESUME: + PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_RESUME"); + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; + CfgStatus = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)psHwReference, + FALSE + ); + break; + default: + break; + } + /* Change the State of the HAL only if HCI Configure + Returns status as Pending */ + if ( NFCSTATUS_PENDING == CfgStatus ) + { + (void)memcpy((void *) + &(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig), + (void *)&(discoveryCfg->PollDevInfo.PollCfgInfo), + sizeof(phHal_sPollDevInfo_t) + ); + PHDBG_INFO("Hal4:Finished copying PollCfgInfo"); + PHDBG_INFO("Hal4:Configure returned NFCSTATUS_PENDING"); + Hal4Ctxt->Hal4NextState = eHal4StateConfiguring; + Hal4Ctxt->sUpperLayerInfo.pConfigCallback + = pConfigCallback; + } + else/*Configure failed.Restore old poll dev info*/ + { + (void)memcpy((void *) + &(Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo), + (void *)&(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig), + sizeof(phHal_sPollDevInfo_t) + ); + } + } + } + else + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); + } + } + return CfgStatus; +} + + +/*Configuration completion handler*/ +void phHal4Nfc_ConfigureComplete(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo, + uint8_t type + ) +{ + pphHal4Nfc_GenCallback_t pConfigCallback + = Hal4Ctxt->sUpperLayerInfo.pConfigCallback; + pphHal4Nfc_ConnectCallback_t pUpperConnectCb + = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb; + NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status; + if((type == NFC_NOTIFY_POLL_ENABLED) ||(type == NFC_NOTIFY_POLL_RESTARTED)) + { + Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = TRUE; + PHDBG_INFO("Hal4:Poll Config Complete"); + } + else + { + Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = FALSE; + PHDBG_WARNING("Hal4:Poll disabled,config success or config error"); + } + if(NULL != Hal4Ctxt->sUpperLayerInfo.pConfigCallback) + { +#ifdef MERGE_SAK_SW2 + if((NFC_UICC_EMULATION == Hal4Ctxt->uConfig.emuConfig.emuType)&& + (FALSE == + Hal4Ctxt->uConfig.emuConfig.config.uiccEmuCfg.enableUicc)) + { + Status = phHciNfc_System_Configure ( + Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + PH_HAL4NFC_TGT_MERGE_ADDRESS, + PH_HAL4NFC_TGT_MERGE_SAK /*config value*/ + ); + } + if(NFCSTATUS_PENDING != Status) + { +#endif/*#ifdef MERGE_SAK_SW2*/ + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + Hal4Ctxt->sUpperLayerInfo.pConfigCallback = NULL; + (*pConfigCallback)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,Status + ); +#ifdef MERGE_SAK_SW2 + } +#endif/*#ifdef MERGE_SAK_SW2*/ + } + /**if connect failed and discovery wheel was restarted*/ + else if(Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb) + { + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; + /*Notify to the upper layer*/ + (*pUpperConnectCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + NFCSTATUS_FAILED + ); + } + else + { + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + /**if disconnect failed and discovery wheel was restarted*/ + if ( NULL != Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb) + { + ((phNfc_sCompletionInfo_t *)pInfo)->status = NFCSTATUS_SUCCESS; + phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo); + } + } +} + + +/**Handler for Target discovery completion for all remote device types*/ +void phHal4Nfc_TargetDiscoveryComplete( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + static phHal4Nfc_DiscoveryInfo_t sDiscoveryInfo; + NFCSTATUS status = NFCSTATUS_SUCCESS; + /**SAK byte*/ + uint8_t Sak = 0; + /*Union type to encapsulate and return the discovery info*/ + phHal4Nfc_NotificationInfo_t uNotificationInfo; + /*All the following types will be discovered as type A ,and differentiation + will have to be done within this module based on SAK byte and UID info*/ + phHal_eRemDevType_t aRemoteDevTypes[3] = { + phHal_eISO14443_A_PICC, + phHal_eNfcIP1_Target, + phHal_eMifare_PICC + }; + /*Count is used to add multiple info into remote dvice list for devices that + support multiple protocols*/ + uint8_t Count = 0, + NfcIpDeviceCount = 0;/**<Number of NfcIp devices discovered*/ + uint16_t nfc_id = 0; + /*remote device info*/ + phHal_sRemoteDevInformation_t *psRemoteDevInfo = NULL; + status = ((phNfc_sCompletionInfo_t *)pInfo)->status; + /*Update Hal4 state*/ + Hal4Ctxt->Hal4CurrentState = eHal4StateTargetDiscovered; + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + PHDBG_INFO("Hal4:Remotedevice Discovered"); + if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info) + { + /*Extract Remote device Info*/ + psRemoteDevInfo = (phHal_sRemoteDevInformation_t *) + ((phNfc_sCompletionInfo_t *)pInfo)->info; + + switch(psRemoteDevInfo->RemDevType) + { + case phHal_eISO14443_A_PICC:/*for TYPE A*/ + { + Sak = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; + if((Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A) + || (TRUE == Hal4Ctxt->psADDCtxtInfo->smx_discovery)) + { + /*Check if Iso is Supported*/ + if(Sak & ISO_14443_BITMASK) + { + Count++; + } + /*Check for Mifare Supported*/ + if(Sak & MIFARE_BITMASK) + { + aRemoteDevTypes[Count] = phHal_eMifare_PICC; + Count++; + } + else if((0 == Sak)&& (0 == Count)) + { + /*Mifare check*/ + if((NXP_UID == + psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0]) + &&(NXP_MIN_UID_LEN <= + psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength)) + { + aRemoteDevTypes[Count] = phHal_eMifare_PICC; + + } + else/*TYPE 3A*/ + { + aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; + } + Count++; + } + else + { + } + } + /*Check for P2P target passive*/ + if((Sak & NFCIP_BITMASK) && + (NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)&& + (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode + & phHal_ePassive106)) + { + aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; + Count++; + } + }/*case phHal_eISO14443_A_PICC:*/ + break; + case phHal_eNfcIP1_Target:/*P2P target detected*/ + aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; + Count++; + break; + case phHal_eISO14443_B_PICC: /*TYPE_B*/ +#ifdef TYPE_B + aRemoteDevTypes[Count] = phHal_eISO14443_B_PICC; + Count++; + break; +#endif + case phHal_eFelica_PICC: /*Felica*/ +#ifdef TYPE_FELICA + { + /*nfc_id is used to differentiate between Felica and NfcIp target + discovered in Type F*/ + nfc_id = (((uint16_t)psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[0]) + << BYTE_SIZE) | + psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[1]; + /*check for NfcIp target*/ + if(NXP_NFCIP_NFCID2_ID == nfc_id) + { + if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) + &&((Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode + & phHal_ePassive212) || + (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode + & phHal_ePassive424))) + { + aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; + Count++; + } + } + else/*Felica*/ + { + if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica212 + || Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica424) + { + aRemoteDevTypes[Count] = phHal_eFelica_PICC; + Count++; + } + } + break; + } +#endif + case phHal_eJewel_PICC: /*Jewel*/ +#ifdef TYPE_JEWEL + { + /*Report Jewel tags only if TYPE A is enabled*/ + if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A) + { + aRemoteDevTypes[Count] = phHal_eJewel_PICC; + Count++; + } + break; + } +#endif +#ifdef TYPE_ISO15693 + case phHal_eISO15693_PICC: /*ISO15693*/ + { + if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso15693) + { + aRemoteDevTypes[Count] = phHal_eISO15693_PICC; + Count++; + } + break; + } +#endif /* #ifdef TYPE_ISO15693 */ + /*Types currently not supported*/ + case phHal_eISO14443_BPrime_PICC: + default: + PHDBG_WARNING("Hal4:Notification for Not supported types"); + break; + }/*End of switch*/ + /*Update status code to success if atleast one device info is available*/ + status = (((NFCSTATUS_SUCCESS != status) + && (NFCSTATUS_MULTIPLE_TAGS != status)) + &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))? + NFCSTATUS_SUCCESS:status; + + /*Update status to NFCSTATUS_MULTIPLE_PROTOCOLS if count > 1 ,and this + is first discovery notification from Hci*/ + status = ((NFCSTATUS_SUCCESS == status) + &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0) + &&(Count > 1)?NFCSTATUS_MULTIPLE_PROTOCOLS:status); + /*If multiple protocols are supported ,allocate separate remote device + information for each protocol supported*/ + /*Allocate and copy Remote device info into Hal4 Context*/ + while(Count) + { + PHDBG_INFO("Hal4:Count is not zero"); + --Count; + /*Allocate memory for each of Count number of + devices*/ + if(NULL == Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) + { + Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] + = (phHal_sRemoteDevInformation_t *) + phOsalNfc_GetMemory( + (uint32_t)( + sizeof(phHal_sRemoteDevInformation_t)) + ); + } + if(NULL == Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) + { + status = PHNFCSTVAL(CID_NFC_HAL, + NFCSTATUS_INSUFFICIENT_RESOURCES); + phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); + break; + } + else + { + (void)memcpy( + (void *)Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices], + (void *)psRemoteDevInfo, + sizeof(phHal_sRemoteDevInformation_t) + ); + /*Now copy appropriate device type from aRemoteDevTypes array*/ + Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]->RemDevType + = aRemoteDevTypes[Count]; + /*Increment number of devices*/ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices++; + }/*End of else*/ + }/*End of while*/ + + /*If Upper layer is interested only in P2P notifications*/ + if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) + &&(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1) + &&(phHal_eNfcIP1_Target == Hal4Ctxt->rem_dev_list[0]->RemDevType)) + ||(NULL == Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)) + ) + { + PHDBG_INFO("Hal4:Trying to notify P2P Listener"); + /*NFCSTATUS_SUCCESS or NFCSTATUS_MULTIPLE_PROTOCOLS*/ + if((NFCSTATUS_SUCCESS == status) + ||(NFCSTATUS_MULTIPLE_PROTOCOLS == status)) + { + /*Pick only the P2P target device info from the list*/ + for(Count = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; + Count > 0;--Count) + { + /*Only one P2P target can be detected in one discovery*/ + if(phHal_eNfcIP1_Target == + Hal4Ctxt->rem_dev_list[Count-1]->RemDevType) + { + (void)memcpy( + (void *)Hal4Ctxt->rem_dev_list[0], + (void *)Hal4Ctxt->rem_dev_list[Count-1], + sizeof(phHal_sRemoteDevInformation_t) + ); + NfcIpDeviceCount = 1; + break; + } + } + /*If any P2p devices are discovered free other device info*/ + while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > NfcIpDeviceCount) + { + phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[ + --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]); + Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; + } + /*Issue P2P notification*/ + if(NfcIpDeviceCount == 1) + { + sDiscoveryInfo.NumberOfDevices + = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; + sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; + uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; + PHDBG_INFO("Hal4:Calling P2P listener"); + (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)( + (void *)(Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt), + NFC_DISCOVERY_NOTIFICATION, + uNotificationInfo, + NFCSTATUS_SUCCESS + ); + } + else/*Restart Discovery wheel*/ + { + PHDBG_INFO("Hal4:No P2P device in list"); + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; + PHDBG_INFO("Hal4:Restart discovery1"); + status = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + ); + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? + eHal4StateConfiguring: + Hal4Ctxt->Hal4NextState); + } + } + /*More discovery info available ,get next info from HCI*/ + else if((NFCSTATUS_MULTIPLE_TAGS == status) + &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices + < MAX_REMOTE_DEVICES)) + { + status = phHciNfc_Select_Next_Target ( + Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref + ); + } + else/*Failed discovery ,restart discovery*/ + { + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; + PHDBG_INFO("Hal4:Restart discovery2"); + status = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + );/*Restart Discovery wheel*/ + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? + eHal4StateConfiguring: + Hal4Ctxt->Hal4NextState); + } + }/*if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)...*/ + /*Notify if Upper layer is interested in tag notifications,also notify + P2p if its in the list with other tags*/ + else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification) + { + PHDBG_INFO("Hal4:Trying to notify Tag notification"); + /*Multiple tags in field, get discovery info a second time for the + other devices*/ + if((NFCSTATUS_MULTIPLE_TAGS == status) + &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices < MAX_REMOTE_DEVICES)) + { + PHDBG_INFO("Hal4:select next target1"); + status = phHciNfc_Select_Next_Target ( + Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref + ); + } + /*Single tag multiple protocols scenario,Notify Multiple Protocols + status to upper layer*/ + else if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) + { + PHDBG_INFO("Hal4:Multiple Tags or protocols"); + sDiscoveryInfo.NumberOfDevices + = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; + sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; + uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; + (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( + (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), + NFC_DISCOVERY_NOTIFICATION, + uNotificationInfo, + status + ); + } + else /*NFCSTATUS_SUCCESS*/ + { + if(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1) + &&(phHal_eNfcIP1_Target + == Hal4Ctxt->rem_dev_list[0]->RemDevType)) + ||(NFCSTATUS_SUCCESS != status) + || (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0) + )/*device detected but upper layer is not interested + in the type(P2P) or activate next failed*/ + { + while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 0) + { + phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[ + --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]); + Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; + } + PHDBG_INFO("Hal4:Restart discovery3"); + status = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + );/*Restart Discovery wheel*/ + Hal4Ctxt->Hal4NextState = ( + NFCSTATUS_PENDING == status?eHal4StateConfiguring + :Hal4Ctxt->Hal4NextState + ); + } + else/*All remote device info available.Notify to upper layer*/ + { + /*Update status for MULTIPLE_TAGS here*/ + status = (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 1? + NFCSTATUS_MULTIPLE_TAGS:status); + /*If listener is registered ,call it*/ + sDiscoveryInfo.NumberOfDevices + = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; + sDiscoveryInfo.ppRemoteDevInfo + = Hal4Ctxt->rem_dev_list; + uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; + PHDBG_INFO("Hal4:Calling Discovery Handler1"); + (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( + (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), + NFC_DISCOVERY_NOTIFICATION, + uNotificationInfo, + status + ); + } + } + } /*else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)*/ + else/*listener not registered ,Restart Discovery wheel*/ + { + PHDBG_INFO("Hal4:No listener registered.Ignoring Discovery \ + Notification"); + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; + PHDBG_INFO("Hal4:Restart discovery4"); + status = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + ); + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? + eHal4StateConfiguring: + Hal4Ctxt->Hal4NextState); + } + }/*if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)*/ + else/*NULL info received*/ + { + sDiscoveryInfo.NumberOfDevices + = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; + sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; + uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; + /*If Discovery info is available from previous notifications try to + notify that to the upper layer*/ + if((NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification) +#ifdef NFC_RF_NOISE_SW + &&((NFCSTATUS_SUCCESS == status) + || (NFCSTATUS_MULTIPLE_TAGS == status)) +#endif /* #ifdef NFC_RF_NOISE_SW */ + ) + { +#ifndef NFC_RF_NOISE_SW + status = (((NFCSTATUS_SUCCESS != status) + && (NFCSTATUS_MULTIPLE_TAGS != status)) + &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))? + NFCSTATUS_SUCCESS:status; +#endif/*#ifndef NFC_RF_NOISE_SW*/ + PHDBG_INFO("Hal4:Calling Discovery Handler2"); + (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( + (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), + NFC_DISCOVERY_NOTIFICATION, + uNotificationInfo, + status + ); + } + else/*Restart Discovery wheel*/ + { + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; + PHDBG_INFO("Hal4:Restart discovery5"); + status = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + ); + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? + eHal4StateConfiguring:Hal4Ctxt->Hal4NextState); + } + }/*else*/ + return; +} + + +/**Register Notification handlers*/ +NFCSTATUS phHal4Nfc_RegisterNotification( + phHal_sHwReference_t *psHwReference, + phHal4Nfc_RegisterType_t eRegisterType, + pphHal4Nfc_Notification_t pNotificationHandler, + void *Context + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + if(NULL == pNotificationHandler || NULL == psHwReference) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); + } + 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 + { + /*Extract context from hardware reference*/ + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + switch(eRegisterType) + { + case eRegisterTagDiscovery: + Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = Context; + Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification + = pNotificationHandler; /*Register the tag Notification*/ + break; + case eRegisterP2PDiscovery: + Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = Context; + Hal4Ctxt->sUpperLayerInfo.pP2PNotification + = pNotificationHandler; /*Register the P2P Notification*/ + break; + case eRegisterHostCardEmulation: + RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED; + break; + case eRegisterSecureElement: + Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = Context; + Hal4Ctxt->sUpperLayerInfo.pEventNotification + = pNotificationHandler; /*Register the Se Notification*/ + break; + default: + Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = Context; + Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler + = pNotificationHandler; /*Register the default Notification*/ + break; + } + PHDBG_INFO("Hal4:listener registered"); + } + return RetStatus; +} + + +/**Unregister Notification handlers*/ +NFCSTATUS phHal4Nfc_UnregisterNotification( + phHal_sHwReference_t *psHwReference, + phHal4Nfc_RegisterType_t eRegisterType, + void *Context + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + if(psHwReference == NULL) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); + } + 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 + { + /*Extract context from hardware reference*/ + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + switch(eRegisterType) + { + case eRegisterTagDiscovery: + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = Context; + Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = NULL; + /*UnRegister the tag Notification*/ + Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL; + PHDBG_INFO("Hal4:Tag Discovery Listener Unregistered"); + break; + case eRegisterP2PDiscovery: + Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = NULL; + /*UnRegister the p2p Notification*/ + Hal4Ctxt->sUpperLayerInfo.pP2PNotification = NULL; + PHDBG_INFO("Hal4:P2P Discovery Listener Unregistered"); + break; + case eRegisterHostCardEmulation:/*RFU*/ + RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED; + break; + /*UnRegister the Se Notification*/ + case eRegisterSecureElement: + Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = NULL; + Hal4Ctxt->sUpperLayerInfo.pEventNotification = NULL; + PHDBG_INFO("Hal4:SE Listener Unregistered"); + break; + default: + Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = NULL; + /*UnRegister the default Notification*/ + Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler = NULL; + PHDBG_INFO("Hal4:Default Listener Unregistered"); + break; + } + } + return RetStatus; +} + + |