/*
 * 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) && ((pEvtInfo->eventInfo.aid.length <= 16)))  // PLG
                        {
                            /*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;
                        }
						else
						{
							// PLG patch
                            Se_Trans_Info.UiccEvtInfo.aid.buffer = NULL;
							Se_Trans_Info.UiccEvtInfo.aid.length = 0;
						}
						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:
                    {
                        (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
                            pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
                            phLibNfc_eSE_EvtTypeTransaction,
                            pSeInfo->hSecureElement,
                            &Se_Trans_Info,
                            status);
                        break;
                    }
                    case NFC_EVT_FIELD_ON:
                    {
                        (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
                            pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
                            phLibNfc_eSE_EvtFieldOn,
                            pSeInfo->hSecureElement,
                            &Se_Trans_Info,
                            status);
                        break;
                    }
                    case NFC_EVT_FIELD_OFF:
                    {
                        (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
                             phLibNfc_eSE_EvtFieldOff,
                             pSeInfo->hSecureElement,
                             &Se_Trans_Info,
                             status);
                        break;
                    }
                    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)
                {
                    if(pLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)
                    {
                        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;

                    if(pLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)
                    {
                         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;
}



