/*
 * 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: // PLG ++
                    
                    (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
                            pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
                            phLibNfc_eSE_EvtTypeTransaction,
                            pSeInfo->hSecureElement,
                            &Se_Trans_Info,
                            status);

                    break; // PLG --
                    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;
}



