#include "core.h"
#include "acl.h"
#include "aclframe.h"
#include "smchdtv2.h"
/*-------------------------------------------------------------------------*
* Function:
* Smc_Open
*
* Purpose:
* Public API to open an instance of the smart card interface object.
*
* Inputs:
* Chip - instance of ASIC
* Name - name of SMC instance to open
* Mode - mode of instantiation
* CardType - type of the smart card: ISO or EMV
*
* Outputs:
* pSmcHandle - pointer to handle of the SMC component
* pbExist - pointer to current exist status of this component
*
* Return Codes:
* OK
* ERROR_INVALID_HANDLE
* ERROR_INVALID_NAME
* ERROR_NOT_INITIALIZED
* ERROR_NOT_SHARED
*-------------------------------------------------------------------------*/
RESULT Smc_Open ( HANDLE *pSmcHandle,
HANDLE Chip,
NAME Name,
MODE Mode,
BOOL *pbExist,
SMC_CARD_TYPE CardType)
{
PROCESS_CONTEXT *p ProcessContext = NULL;
CONTEXT *p Context = NULL;
SMC_PROCESS_CONTEXT *pSmcProcessContext = NULL;
SMC_CONTEXT *pSmcContext = NULL;
SMC_PROCESS_INSTANCE *pSmcProcessInstance = NULL;
SMC_INSTANCE *pSmcInstance = NULL;
UINT32 mutexName;
CORE_MUTEX_ID MutexId;
UINT32 memChan;
RESULT result;
UINT32 offset;
unsigned char *pBuf;
UINT32 ChipIndex;
/* get per process shared data per hardware instance pointer */
p ProcessContext = ( PROCESS_CONTEXT *)Chip;
if (p ProcessContext == NULL)
{
ASSERT (p ProcessContext != NULL);
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Invalid handle, ERROR!\n");
return ERROR_INVALID_HANDLE;
}
ChipIndex = p ProcessContext->p Context->Instance;
/* check name validity */
if (Name < SMC_1 || Name >= SMC_END_NAME)
{
ASSERT (Name >= SMC_END_NAME);
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Invalid name, ERROR!\n");
return ERROR_INVALID_NAME;
}
/* get global process-shared context pointer */
p Context = p ProcessContext->p Context;
if (p Context == NULL)
{
ASSERT (p Context != NULL);
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Not initialized, ERROR!\n");
return ERROR_NOT_INITIALIZED;
}
/* get SMC process context pointer */
pSmcProcessContext = &(p ProcessContext->smcProcessContext);
if (pSmcProcessContext == NULL)
{
ASSERT (pSmcProcessContext != NULL);
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Not initialized, ERROR!\n");
return ERROR_NOT_INITIALIZED;
}
/* get SMC global inter-process context pointer */
pSmcContext = &(p Context->smcContext);
if (pSmcContext == NULL)
{
ASSERT (pSmcContext != NULL);
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Not initialized, ERROR!\n");
return ERROR_NOT_INITIALIZED;
}
/* get SMC instance process context pointer */
pSmcProcessInstance = &(pSmcProcessContext->SmcProcessInstance [Name-1]);
if (pSmcProcessInstance == NULL)
{
ASSERT (pSmcProcessInstance != NULL);
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Not initialized, ERROR!\n");
return ERROR_NOT_INITIALIZED;
}
/* get SMC instance global context pointer */
pSmcInstance = &(pSmcContext->SmcInstance [Name-1]);
if (pSmcInstance == NULL)
{
ASSERT (pSmcInstance != NULL);
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Not initialized, ERROR!\n");
return ERROR_NOT_INITIALIZED;
}
/* create mutex for the shared instance context data */
if (pSmcProcessContext->MutexId == 0)
{
mutexName = SMC_MUTEX_GLOBAL + p Context->Instance;
MutexId = Core_MutexCreate (mutexName);
/* Check for an invalid mutex ID */
if (CORE_INVALID_ID == MutexId)
{
FwDbg_Printf ( SMC, DEBUGLEVEL_Error,
" Smc_Open: Invalid process context mutex ID.\n");
return ERROR_CORE_DRIVER;
}
else
{
pSmcProcessContext->MutexId = MutexId;
}
}
/* claim an exclusive access to the shared instance context data */
if ( Core_MutexLock (pSmcProcessContext->MutexId, OS_WAIT_FOREVER) != OS_OK)
{
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Core_MutexLock() failed, ERROR!\n");
return ERROR_CORE_DRIVER;
}
/* check if the SMC instance name is currently in use */
if (pSmcInstance->Name == Name)
{
/* check if it can be shared */
if (pSmcInstance->Mode == MODE_EXCLUSIVE)
{
/* shared instance context data access done, unlock the mutex */
if ( Core_MutexUnlock (pSmcProcessContext->MutexId) != OS_OK)
{
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Core_MutexUnlock() failed, ERROR!\n");
return ERROR_CORE_DRIVER;
}
/* open failed */
*pSmcHandle = 0;
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Not shared, ERROR!\n");
return ERROR_NOT_SHARED;
}
else
{
/* instance can be shared, increase the global count */
pSmcInstance->RefCount++;
*pbExist = TRUE;
}
}
else
{
/* this is the first time the instance is used */
*pbExist = FALSE;
/* initialize the global shared data */
pSmcInstance->Name = Name;
pSmcInstance->Mode = Mode;
pSmcInstance->RefCount = 1;
pSmcInstance->bConnected = FALSE;
pSmcInstance->CompType = NULL;
pSmcInstance->CompHandle = ( HANDLE)0;
pSmcInstance->bCardInserted = FALSE;
pSmcInstance->CardType = CardType;
pSmcInstance->bActivated = FALSE;
pSmcInstance->bClockStopSupported = FALSE;
pSmcInstance->LastCardMovementTime = 0;
/*
Preferable memory channel is assigned within CONTEXT
*/
memChan = p Context->MemoryChannel;
pSmcInstance->pBufferStart = (unsigned char *) Core_VideoMemAlloc
(p Context->Instance,
&memChan, SIZE_SMC_MSG_BUFFER,
1, &offset, ALLOC_TYPE_NORM);
pSmcInstance->BufferOffset = offset;
pBuf = pSmcInstance->pBufferStart;
}
/* shared instance context data access done, unlock the mutex */
if ( Core_MutexUnlock (pSmcProcessContext->MutexId) != OS_OK)
{
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Core_MutexUnlock() failed, ERROR!\n");
return ERROR_CORE_DRIVER;
}
/* instantiate the per process instance data */
if (pSmcProcessInstance->MutexId == 0)
{
/* create per instance mutex, do once per process instance */
MutexId = Core_MutexCreate (0);
/* Check for an invalid mutex ID */
if (CORE_INVALID_ID == MutexId)
{
FwDbg_Printf ( SMC, DEBUGLEVEL_Error,
" Smc_Open: Invalid process instance mutex ID.\n");
return ERROR_CORE_DRIVER;
}
else
{
pSmcProcessInstance->MutexId = MutexId;
}
}
/* claim an exclusive access to the to the instance per process */
if ( Core_MutexLock (pSmcProcessInstance->MutexId, OS_WAIT_FOREVER) != OS_OK)
{
FwDbg_Printf ( SMC,
DEBUGLEVEL_Error,
" Smc_Open: Core_MutexLock() failed, ERROR!\n");
return ERROR_CORE_DRIVER;
}
/* initial the instance data per process */
if (pSmcProcessInstance->RefCount == 0)
{
pSmcProcessInstance->Name = Name ;
pSmcProcessInstance->RefCount = 1;
pSmcProcessInstance-> ProcessContext = ( HANDLE)p ProcessContext;
pSmcProcessInstance->Signature = COMPONENT_BASE( SMC);
}
else
{
/* process instance is initialized before, increase the count only */
pSmcProcessInstance->RefCount++;
}
/* per process instance data access done, unlock the mutex */
if ( Core_MutexUnlock( pSmcProcessInstance->MutexId) != OS_OK)
{
FwDbg_Printf ( SMC,