diff options
Diffstat (limited to 'src/phLibNfc_SE.c')
-rw-r--r-- | src/phLibNfc_SE.c | 609 |
1 files changed, 609 insertions, 0 deletions
diff --git a/src/phLibNfc_SE.c b/src/phLibNfc_SE.c new file mode 100644 index 0000000..2361a87 --- /dev/null +++ b/src/phLibNfc_SE.c @@ -0,0 +1,609 @@ +/* + * 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 phLibNfc_SE.c + + * Project: NFC FRI / HALDL + * + * $Date: Thu Apr 22 13:59:50 2010 $ + * $Author: ing07385 $ + * $Revision: 1.65 $ + * $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $ + * + */ + +/* +************************* Header Files *************************************** +*/ + +#include <phNfcStatus.h> +#include <phLibNfc.h> +#include <phHal4Nfc.h> +#include <phOsalNfc.h> +#include <phLibNfc_Internal.h> +#include <phLibNfc_SE.h> +#include <phLibNfc_ndef_raw.h> +#include <phLibNfc_initiator.h> +#include <phLibNfc_discovery.h> + +/* +*************************** Macro's **************************************** +*/ + +#ifndef STATIC_DISABLE +#define STATIC static +#else +#define STATIC +#endif + +/* +*************************** Global Variables ********************************** +*/ + +/*This Structure contains the Secure Element information*/ +phLibNfc_SE_List_t sSecuredElementInfo[PHLIBNFC_MAXNO_OF_SE]; + +/* +*************************** Static Function Declaration *********************** +*/ + +/* Response callback for SE Set Mode*/ +STATIC +void phLibNfc_SE_SetMode_cb(void *context, NFCSTATUS status); + + +/* SE register listner response notification */ +STATIC +void phLibNfc_SeNotification(void *context, + phHal_eNotificationType_t type, + phHal4Nfc_NotificationInfo_t info, + NFCSTATUS status + ); +/* +*************************** Function Definitions ****************************** +*/ + +/** +* Registers notification handler to handle secure element specific events +*/ +NFCSTATUS phLibNfc_SE_NtfRegister ( + pphLibNfc_SE_NotificationCb_t pSE_NotificationCb, + void *pContext + ) +{ + NFCSTATUS Status = NFCSTATUS_SUCCESS; + pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)gpphLibContext; + + if((NULL == gpphLibContext) || + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + Status = NFCSTATUS_NOT_INITIALISED; + } + else if((pSE_NotificationCb == NULL) + ||(NULL == pContext)) + { + /*parameters sent by upper layer are not valid*/ + Status = NFCSTATUS_INVALID_PARAMETER; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + Status = NFCSTATUS_SHUTDOWN; + } + else + { + /*Register SE notification with lower layer. + Any activity on Smx or UICC will be notified */ + Status = phHal4Nfc_RegisterNotification( + pLibContext->psHwReference, + eRegisterSecureElement, + phLibNfc_SeNotification, + (void*)pLibContext); + if(Status == NFCSTATUS_SUCCESS) + { + pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb = pSE_NotificationCb; + pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt=pContext; + } + else + { + /* Registration failed */ + Status = NFCSTATUS_FAILED; + } + } + return Status; +} +/** +* SE Notification events are notified with this callback +*/ +STATIC void phLibNfc_SeNotification(void *context, + phHal_eNotificationType_t type, + phHal4Nfc_NotificationInfo_t info, + NFCSTATUS status) +{ + pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)context; + phHal_sEventInfo_t *pEvtInfo = NULL; + phLibNfc_uSeEvtInfo_t Se_Trans_Info={0}; + phLibNfc_SE_List_t *pSeInfo=NULL; + + if(pLibContext != gpphLibContext) + { + /*wrong context returned*/ + phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + } + else + { + if((status == NFCSTATUS_SUCCESS) && (type == NFC_EVENT_NOTIFICATION)) + { + pEvtInfo = info.psEventInfo; + status = NFCSTATUS_SUCCESS; + if((pEvtInfo->eventSource == phHal_ePICC_DevType ) + && (pEvtInfo->eventHost == phHal_eHostController) ) + { + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_Type = phLibNfc_SE_Type_SmartMX; + /* Smartx Mx is Activated */ + pSeInfo = &sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX]; + } + if(pEvtInfo->eventHost == phHal_eUICCHost) + { + /* UICC is Activate */ + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type = phLibNfc_SE_Type_UICC; + pSeInfo = &sSecuredElementInfo[LIBNFC_SE_UICC_INDEX]; + } + else + { + /*presently Smx event source is not supported */ + } + if(pSeInfo!=NULL) + { + switch(pEvtInfo->eventType) + { + case NFC_EVT_TRANSACTION: + { + if(pEvtInfo->eventInfo.aid.length != 0) + { + /*copy the Application id on which transaction happened*/ + Se_Trans_Info.UiccEvtInfo.aid.buffer =pEvtInfo->eventInfo.aid.buffer; + Se_Trans_Info.UiccEvtInfo.aid.length =pEvtInfo->eventInfo.aid.length; + } + if((pEvtInfo->eventHost == phHal_eUICCHost) + && (info.psEventInfo->eventInfo.uicc_info.param.length + != 0)) + { + /*copy the parameters info on which transaction happened*/ + Se_Trans_Info.UiccEvtInfo.param.buffer = + info.psEventInfo->eventInfo.uicc_info.param.buffer; + Se_Trans_Info.UiccEvtInfo.param.length = + info.psEventInfo->eventInfo.uicc_info.param.length; + } + /*Notify to upper layer that transaction had happened on the + one of the application stored in UICC or Smx*/ + (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)( + pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt, + phLibNfc_eSE_EvtStartTransaction, + pSeInfo->hSecureElement, + &Se_Trans_Info, + status); + break; + } + case NFC_EVT_END_OF_TRANSACTION: + { + (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)( + pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt, + phLibNfc_eSE_EvtEndTransaction, + pSeInfo->hSecureElement, + &Se_Trans_Info, + status); + break; + } + case NFC_EVT_CONNECTIVITY: + { + (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)( + pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt, + phLibNfc_eSE_EvtConnectivity, + pSeInfo->hSecureElement, + &Se_Trans_Info, + status); + break; + } + case NFC_EVT_START_OF_TRANSACTION: + default: + { + break; + } + } + } + else + { + + } + } + } + return; +} + +/** + * Unregister the Secured Element Notification. + */ +NFCSTATUS phLibNfc_SE_NtfUnregister(void) +{ + NFCSTATUS Status = NFCSTATUS_SUCCESS; + pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)gpphLibContext; + + if((NULL == gpphLibContext) || + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + /*Lib Nfc is not initialized*/ + Status = NFCSTATUS_NOT_INITIALISED; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + Status = NFCSTATUS_SHUTDOWN; + } + else + { + /*Unregister SE event notification with lower layer. + even some transaction happens on UICC or Smx will not + be notified afterworlds */ + Status = phHal4Nfc_UnregisterNotification( + pLibContext->psHwReference, + eRegisterSecureElement, + pLibContext); + if(Status != NFCSTATUS_SUCCESS) + { + /*Unregister failed*/ + Status=NFCSTATUS_FAILED; + } + pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb=NULL; + pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt=NULL; + } + return Status; +} + +/** +* Get list of available Secure Elements +*/ +NFCSTATUS phLibNfc_SE_GetSecureElementList( + phLibNfc_SE_List_t* pSE_List, + uint8_t* uSE_count + ) +{ + NFCSTATUS Status = NFCSTATUS_SUCCESS; + uint8_t uNo_Of_SE = 0; + + if((NULL == gpphLibContext) || + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + Status = NFCSTATUS_NOT_INITIALISED; + } + else if((NULL ==pSE_List) || (NULL ==uSE_count)) + { + Status = NFCSTATUS_INVALID_PARAMETER; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + Status = NFCSTATUS_SHUTDOWN; + } + else + { + /*Check for which type of Secure Element is available*/ + if(gpphLibContext->psHwReference->uicc_connected==TRUE) + { + /* Populate the UICC type */ + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type = phLibNfc_SE_Type_UICC; + + /* Populate the UICC handle */ + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement =(phLibNfc_Handle) + (LIBNFC_SE_UICC_INDEX + LIBNFC_SE_BASE_HANDLE); + +#ifdef NXP_HAL_ENABLE_SMX + + pSE_List[LIBNFC_SE_UICC_INDEX].eSE_Type = + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type; + pSE_List[LIBNFC_SE_UICC_INDEX].hSecureElement = (phLibNfc_Handle) + (LIBNFC_SE_UICC_INDEX + LIBNFC_SE_BASE_HANDLE); + pSE_List[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState; +#else + pSE_List->eSE_Type = + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type; + pSE_List->hSecureElement = (phLibNfc_Handle) + (LIBNFC_SE_UICC_INDEX + LIBNFC_SE_BASE_HANDLE); + pSE_List->eSE_CurrentState = + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState; +#endif + /* update the No of SE retrieved */ + uNo_Of_SE ++; + + } + if (gpphLibContext->psHwReference->smx_connected ==TRUE) + { + /* if the Smx is also connected to the PN544 */ + /* Populate the SMX type */ + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_Type = phLibNfc_SE_Type_SmartMX; + + /* Populate the SMX handle */ + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement =(phLibNfc_Handle) + (LIBNFC_SE_SMARTMX_INDEX + LIBNFC_SE_BASE_HANDLE); + pSE_List[LIBNFC_SE_SMARTMX_INDEX].eSE_Type = + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_Type; + pSE_List[LIBNFC_SE_SMARTMX_INDEX].hSecureElement = (phLibNfc_Handle) + (LIBNFC_SE_SMARTMX_INDEX + LIBNFC_SE_BASE_HANDLE); + pSE_List[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState = + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState; + + /* update the No of SE retrieved */ + uNo_Of_SE ++; + + } + *uSE_count = uNo_Of_SE; + } + return Status; +} + +/** +* Sets secure element mode. +* This function configures SE to specific mode based on activation mode type +*/ + +NFCSTATUS phLibNfc_SE_SetMode ( phLibNfc_Handle hSE_Handle, + phLibNfc_eSE_ActivationMode eActivation_mode, + pphLibNfc_SE_SetModeRspCb_t pSE_SetMode_Rsp_cb, + void * pContext + ) +{ + NFCSTATUS Status = NFCSTATUS_SUCCESS; + phHal_eEmulationType_t eEmulationType = NFC_SMARTMX_EMULATION; + pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)gpphLibContext; + + if((NULL == gpphLibContext) || + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + Status = NFCSTATUS_NOT_INITIALISED; + } + else if((pSE_SetMode_Rsp_cb ==NULL) + ||(NULL == pContext)||(NULL==(void *)hSE_Handle)) + { + Status=NFCSTATUS_INVALID_PARAMETER; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + Status = NFCSTATUS_SHUTDOWN; + } + else if((pLibContext->status.GenCb_pending_status == TRUE) + ||(NULL!=pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb)) + { + /*previous callback is pending still*/ + Status =NFCSTATUS_REJECTED; + } + else + { + switch(eActivation_mode) + { + case phLibNfc_SE_ActModeVirtual: + case phLibNfc_SE_ActModeDefault: + { + if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + { + eEmulationType = NFC_UICC_EMULATION; + /*Enable the UICC -External reader can see it*/ + pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc = TRUE; + } + else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + { + eEmulationType = NFC_SMARTMX_EMULATION; + /*Enable the SMX -External reader can see it*/ + pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation = TRUE; + } + else + { + Status=NFCSTATUS_INVALID_HANDLE; + } + if(Status==NFCSTATUS_SUCCESS) + { + pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeVirtual; + pLibContext->sCardEmulCfg.emuType = eEmulationType; + Status = phHal4Nfc_ConfigParameters( + pLibContext->psHwReference, + NFC_EMULATION_CONFIG, + (phHal_uConfig_t*)&pLibContext->sCardEmulCfg, + phLibNfc_SE_SetMode_cb, + pLibContext); + } + } + break; + case phLibNfc_SE_ActModeWired: + { + if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + { + if(pLibContext->CBInfo.pClientNtfRegRespCB!=NULL) + { + /*Disable the SMX -External reader can't see it anymore*/ + pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation = FALSE; + pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeWired; + + Status = phHal4Nfc_Switch_SMX_Mode( + pLibContext->psHwReference, + eSmartMx_Wired, + phLibNfc_SE_SetMode_cb, + pLibContext + ); + } + } + else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + { + /*This mode is not applicable to UICC*/ + Status = NFCSTATUS_REJECTED; + } + else + { + Status = NFCSTATUS_INVALID_HANDLE; + } + } + break; + + case phLibNfc_SE_ActModeOff: + { + /*UICC emulation deactivate*/ + if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + { + eEmulationType = NFC_UICC_EMULATION; + /*Disable the UICC -External reader can't see it anymore*/ + pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc = FALSE; + + } + else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + { + eEmulationType = NFC_SMARTMX_EMULATION; + /*Disable the SMX -External reader can't see it anymore*/ + pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation=FALSE; + + } + else + { + Status = NFCSTATUS_INVALID_HANDLE; + } + if(Status==NFCSTATUS_SUCCESS) + { + pLibContext->sCardEmulCfg.emuType = eEmulationType; + pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeOff; + Status = phHal4Nfc_ConfigParameters(pLibContext->psHwReference, + NFC_EMULATION_CONFIG, + (phHal_uConfig_t*)&pLibContext->sCardEmulCfg, + phLibNfc_SE_SetMode_cb, + pLibContext); + } + } + break; + default: + Status=NFCSTATUS_INVALID_PARAMETER; + break; + + }/*End of eActivation_mode switch */ + if(Status==NFCSTATUS_PENDING) + { + pLibContext->sSeContext.hSetemp=hSE_Handle; + pLibContext->status.GenCb_pending_status = TRUE; + pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb = pSE_SetMode_Rsp_cb; + pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt=pContext; + } + else if(Status == NFCSTATUS_INVALID_HANDLE) + { + Status= Status; + } + else + { + Status = NFCSTATUS_FAILED; + } + } + return Status; +} +/** +* Callback for Se Set mode +*/ +STATIC void phLibNfc_SE_SetMode_cb(void *context, NFCSTATUS status) +{ + pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)context; + pphLibNfc_SE_SetModeRspCb_t pUpperLayerCb=NULL; + void *pUpperContext=NULL; + phLibNfc_Handle hSeHandle=0; + uint8_t TempState=FALSE; + + if(pLibContext != gpphLibContext) + { + /*wrong context returned*/ + phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + } + else + { + if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) + { + /*If shutdown is called in between allow shutdown to happen*/ + phLibNfc_Pending_Shutdown(); + status = NFCSTATUS_SHUTDOWN; + } + else + { + if(status == NFCSTATUS_SUCCESS) + { + hSeHandle = pLibContext->sSeContext.hSetemp; + + if(hSeHandle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + { + if(TRUE==pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc) + { + /*If Activation mode was virtual allow external reader to see it*/ + pLibContext->sSeContext.uUiccActivate = TRUE; + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = phLibNfc_SE_Active; + } + else + { + /*If Activation mode was wired don't allow external reader to see it*/ + pLibContext->sSeContext.uUiccActivate = FALSE; + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = + phLibNfc_SE_Inactive; + } + status = NFCSTATUS_SUCCESS; + TempState = pLibContext->sSeContext.uUiccActivate; + } + else if (hSeHandle==sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + { + if(TRUE==pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation) + { + /*If Activation mode was virtual allow external reader to see it*/ + pLibContext->sSeContext.uSmxActivate = TRUE; + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState = + phLibNfc_SE_Active; + } + else + { + /*If Activation mode was wired don't allow external reader to see it*/ + pLibContext->sSeContext.uSmxActivate = FALSE; + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState= + phLibNfc_SE_Inactive; + } + status = NFCSTATUS_SUCCESS; + TempState = pLibContext->sSeContext.uSmxActivate; + } + else + { + status = NFCSTATUS_FAILED; + } + } + else + { + status = NFCSTATUS_FAILED; + } + pLibContext->status.GenCb_pending_status = FALSE; + } + + } + pUpperLayerCb = pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb; + pUpperContext = pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt; + pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb = NULL; + pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt = NULL; + PHNFC_UNUSED_VARIABLE(TempState); + /* Call the upper layer cb */ + if(pUpperLayerCb!= NULL ) + { + (*pUpperLayerCb)(pUpperContext, + hSeHandle, + status); + } + return; +} + + + |