| /* |
| * 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*/ |
| #ifdef LLCP_DISCON_CHANGES |
| Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext; |
| #else /* #ifdef LLCP_DISCON_CHANGES */ |
| Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; |
| #endif /* #ifdef LLCP_DISCON_CHANGES */ |
| 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 = 0x00; |
| (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*/ |
| #ifdef LLCP_DISCON_CHANGES |
| Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext; |
| #else /* #ifdef LLCP_DISCON_CHANGES */ |
| Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; |
| #endif /* #ifdef LLCP_DISCON_CHANGES */ |
| 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)( |
| #ifdef LLCP_DISCON_CHANGES |
| Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt, |
| #else /* #ifdef LLCP_DISCON_CHANGES */ |
| Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, |
| #endif /* #ifdef LLCP_DISCON_CHANGES */ |
| 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*/ |
| switch( Sak ) |
| { |
| case 0x01: // 1K Classic |
| case 0x09: // Mini |
| case 0x08: // 1K |
| case 0x18: // 4K |
| case 0x88: // Infineon 1K |
| case 0x98: // Pro 4K |
| case 0xB8: // Pro 4K |
| case 0x28: // 1K emulation |
| case 0x38: // 4K emulation |
| aRemoteDevTypes[Count] = phHal_eMifare_PICC; |
| Count++; |
| break; |
| } |
| 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; |
| Count++; |
| } |
| } |
| if ( !(Sak & NFCIP_BITMASK) ) |
| { |
| // Always add a separate 3A target on a separate |
| // handle, so the upper layers can connect to it. |
| aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; |
| Count++; |
| } |
| } |
| /*Check for P2P target passive*/ |
| if((Sak & NFCIP_BITMASK) && |
| (NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)&& |
| (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode |
| & phHal_ePassive106)) |
| { |
| if( Sak == 0x53 // Fudan card incompatible to ISO18092 |
| && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0] == 0x04 |
| && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[1] == 0x00 |
| ) |
| { |
| aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; |
| Count++; |
| } |
| else |
| { |
| 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; |
| } |
| |
| |