Fill in ATR value to output buffer of IOCTL_SMARTCARD_POWER

This commit is contained in:
Chris Gunn 2018-07-26 18:44:24 -07:00
Родитель 2e5b1025bc
Коммит 2ea0b98043
11 изменённых файлов: 180 добавлений и 298 удалений

Просмотреть файл

@ -1107,11 +1107,10 @@ Return Value:
NTSTATUS status = STATUS_SUCCESS;
PNFCCX_ESE_INTERFACE eseInterface;
DWORD *pdwPower = (DWORD*)InputBuffer;
BYTE atrBuffer[PHHAL_MAX_ATR_LENGTH] = {};
size_t atrBufferLength = sizeof(atrBuffer);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(InputBufferLength);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(OutputBufferLength);
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
@ -1124,19 +1123,22 @@ Return Value:
WdfWaitLockAcquire(eseInterface->SmartCardLock, NULL);
if (!eseInterface->SmartCardConnected) {
if (!eseInterface->SmartCardConnected)
{
status = STATUS_NO_MEDIA;
WdfWaitLockRelease(eseInterface->SmartCardLock);
goto Done;
}
WdfWaitLockRelease(eseInterface->SmartCardLock);
switch (*pdwPower)
{
case SCARD_COLD_RESET:
case SCARD_WARM_RESET:
NfcCxESEInterfaceResetCard(eseInterface);
status = NfcCxRFInterfaceESEReset(
eseInterface->FdoContext->RFInterface,
atrBuffer,
atrBufferLength,
&atrBufferLength);
break;
case SCARD_POWER_DOWN:
@ -1148,10 +1150,35 @@ Return Value:
break;
}
WdfWaitLockRelease(eseInterface->SmartCardLock);
if (!NT_SUCCESS(status))
{
TRACE_LINE(LEVEL_ERROR, "eSE Reset failed. %!STATUS!", status);
goto Done;
}
if (NULL != OutputBuffer)
{
//
// Fill in the ATR value.
//
status = NfcCxCopyToBuffer(atrBuffer, atrBufferLength, (BYTE*)OutputBuffer, &OutputBufferLength);
}
Done:
if (NT_SUCCESS(status))
{
TRACE_LINE(LEVEL_INFO, "Completing request %p, with %!STATUS!, 0x%I64x", Request, status, atrBufferLength);
WdfRequestCompleteWithInformation(Request, status, atrBufferLength);
//
// Since we have completed the request here,
// return STATUS_PENDING to avoid double completion of the request
//
status = STATUS_PENDING;
}
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
TRACE_LOG_NTSTATUS_ON_FAILURE(status);
return status;
}
@ -1595,7 +1622,7 @@ NfcCxESEInterfaceDispatchAttributeAtr(
Routine Description:
This routine dispatches to get the present state
This routine dispatches to get the ATR value
Arguments:
@ -1619,14 +1646,17 @@ Return Value:
WdfWaitLockAcquire(ESEInterface->SmartCardLock, NULL);
if (!ESEInterface->SmartCardConnected) {
WdfWaitLockRelease(ESEInterface->SmartCardLock);
TRACE_LINE(LEVEL_ERROR, "SmartCard not connected");
status = STATUS_INVALID_DEVICE_STATE;
goto Done;
}
WdfWaitLockRelease(ESEInterface->SmartCardLock);
TRACE_LINE(LEVEL_INFO, "Get Attribute to start Output Buffer length is %Iu....", *pcbOutputBuffer);
status = NfcCxRFInterfaceESEGetATRString(
status = NfcCxRFInterfaceESEReset(
rfInterface,
(PBYTE)pbOutputBuffer,
*pcbOutputBuffer,
@ -1637,7 +1667,6 @@ Return Value:
}
Done:
WdfWaitLockRelease(ESEInterface->SmartCardLock);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
@ -1683,38 +1712,3 @@ Done:
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
//
// Other internal methods below
//
_Requires_lock_not_held_(ESEInterface->SmartCardLock)
NTSTATUS
NfcCxESEInterfaceResetCard(
_In_ PNFCCX_ESE_INTERFACE ESEInterface
)
/*++
Routine Description:
This routine warm resets the smart card
Arguments:
ESEInterface - The eSE Interface
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
status = NfcCxSEInterfaceResetCard(ESEInterface->FdoContext->SEInterface, ESEInterface->SecureElementId);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}

Просмотреть файл

@ -9,7 +9,7 @@ Module Name:
Abstract:
eSE Interface declaration
Environment:
User-mode Driver Framework
@ -84,10 +84,10 @@ NfcCxESEInterfaceStop(
_In_ PNFCCX_ESE_INTERFACE ESEInterface
);
FN_NFCCX_DDI_MODULE_ISIOCTLSUPPORTED
FN_NFCCX_DDI_MODULE_ISIOCTLSUPPORTED
NfcCxESEInterfaceIsIoctlSupported;
FN_NFCCX_DDI_MODULE_IODISPATCH
FN_NFCCX_DDI_MODULE_IODISPATCH
NfcCxESEInterfaceIoDispatch;
//
@ -182,13 +182,3 @@ NfcCxESEInterfaceDispatchAttributeIccType(
_Out_bytecap_(*pcbOutputBuffer) PBYTE pbOutputBuffer,
_Inout_ size_t* pcbOutputBuffer
);
//
// Helper methods below don't have locking constraints
//
_Requires_lock_not_held_(ESEInterface->SmartCardLock)
NTSTATUS
NfcCxESEInterfaceResetCard(
_In_ PNFCCX_ESE_INTERFACE ESEInterface
);

Просмотреть файл

@ -316,7 +316,7 @@ NfcCxRFInterfaceGetEventType(
return NfcCxEventConfig;
case LIBNFC_SE_SET_MODE:
case LIBNFC_EMEBEDDED_SE_TRANSCEIVE:
case LIBNFC_EMBEDDED_SE_GET_ATR_STRING:
case LIBNFC_EMBEDDED_SE_RESET:
return NfcCxEventSE;
default:
return NfcCxEventInvalid;
@ -1660,83 +1660,6 @@ Done:
return status;
}
NTSTATUS
NfcCxRFInterfaceResetCard(
_In_ PNFCCX_RF_INTERFACE RFInterface,
_In_ phLibNfc_Handle hSecureElement
)
/*++
Routine Description:
Resets an SE.
Arguments:
RFInterface - The RF Interface
hSecureElement - The handle to the secure element
Return Value:
STATUS_SUCCESS - If card emulation mode is correctly set
STATUS_INVALID_PARAMETER - If handle to secure element is invalid
--*/
{
NTSTATUS status = STATUS_SUCCESS;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
WdfWaitLockAcquire(RFInterface->DeviceLock, NULL);
phLibNfc_SE_List_t* pSecureElement = nullptr;
status = NfcCxRFInterfaceGetSecureElementFromHandle(RFInterface, hSecureElement, &pSecureElement);
if (!NT_SUCCESS(status))
{
TRACE_LINE(LEVEL_ERROR, "%!STATUS!", status);
goto Done;
}
phLibNfc_eSE_ActivationMode currentActivationMode = pSecureElement->eSE_ActivationMode;
phLibNfc_PowerLinkModes_t currentPowerLinkMode = pSecureElement->eSE_PowerLinkMode;
//
// Turn off SE
//
RFInterface->SEActivationMode = phLibNfc_SE_ActModeOff;
RFInterface->SEPowerAndLinkControl = phLibNfc_PLM_NfccDecides;
status = NfcCxRFInterfaceExecute(RFInterface,
LIBNFC_SE_SET_MODE,
(UINT_PTR)pSecureElement,
0);
if (!NT_SUCCESS(status))
{
TRACE_LINE(LEVEL_ERROR, "Failed to turn off SE, %!STATUS!", status);
goto Done;
}
//
// Restore SE's activation mode
//
RFInterface->SEActivationMode = currentActivationMode;
RFInterface->SEPowerAndLinkControl = currentPowerLinkMode;
status = NfcCxRFInterfaceExecute(RFInterface,
LIBNFC_SE_SET_MODE,
(UINT_PTR)pSecureElement,
0);
if (!NT_SUCCESS(status))
{
TRACE_LINE(LEVEL_ERROR, "Failed to restore SE activation mode, %!STATUS!", status);
goto Done;
}
Done:
WdfWaitLockRelease(RFInterface->DeviceLock);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
NTSTATUS
NfcCxRFInterfaceSetRoutingTable(
_In_ PNFCCX_RF_INTERFACE RFInterface,
@ -1980,7 +1903,7 @@ Return Value:
//
// Validating the buffer sizes to safeguard the DWORD cast.
//
//
if (DWORD_MAX < InputBufferLength ||
DWORD_MAX < OutputBufferLength) {
NT_ASSERTMSG("Buffer size is validated at dispatch time, this should never be larger than DWORD_MAX", FALSE);
@ -2014,7 +1937,7 @@ Done:
}
NTSTATUS
NfcCxRFInterfaceESEGetATRString(
NfcCxRFInterfaceESEReset(
_In_ PNFCCX_RF_INTERFACE RFInterface,
_Out_writes_bytes_to_(OutputBufferLength, *pOutputBufferUsed) PBYTE OutputBuffer,
_In_ size_t OutputBufferLength,
@ -2024,7 +1947,7 @@ NfcCxRFInterfaceESEGetATRString(
Routine Description:
This routine is called from the EmbeddedSE module to get the SE's ATR (answer to reset).
This routine is called from the EmbeddedSE module to reset eSE and get ATR.
Arguments:
@ -2045,7 +1968,7 @@ Return Value:
//
// Validating the buffer sizes to safeguard the DWORD cast.
//
//
if (DWORD_MAX < OutputBufferLength) {
NT_ASSERTMSG("Buffer size is validated at dispatch time, this should never be larger than DWORD_MAX", FALSE);
status = STATUS_INVALID_BUFFER_SIZE;
@ -2062,7 +1985,7 @@ Return Value:
RFInterface->SeATRInfo.pBuff = OutputBuffer;
RFInterface->SeATRInfo.dwLength = (DWORD)OutputBufferLength;
status = NfcCxRFInterfaceExecute(RFInterface, LIBNFC_EMBEDDED_SE_GET_ATR_STRING, NULL, NULL);
status = NfcCxRFInterfaceExecute(RFInterface, LIBNFC_EMBEDDED_SE_RESET, NULL, NULL);
*pOutputBufferUsed = RFInterface->SeATRInfo.dwLength;
@ -3277,8 +3200,8 @@ NfcCxRFInterfaceTargetTransceiveCB(
}
// Note: In most cases, we will receive the data in the buffer we provided.
else if (rfInterface->sTransceiveBuffer.sRecvData.buffer != pResBuffer->buffer) {
RtlCopyMemory(rfInterface->sTransceiveBuffer.sRecvData.buffer,
pResBuffer->buffer,
RtlCopyMemory(rfInterface->sTransceiveBuffer.sRecvData.buffer,
pResBuffer->buffer,
pResBuffer->length);
}
@ -3510,7 +3433,7 @@ Done:
}
static VOID
NfcCxRFInterfaceESEGetATRStringSeqCB(
NfcCxRFInterfaceESEResetSeqCB(
_In_ void* pContext,
_In_ pphNfc_SeAtr_Info_t pResAtrInfo,
_In_ NFCSTATUS NfcStatus
@ -3519,7 +3442,7 @@ NfcCxRFInterfaceESEGetATRStringSeqCB(
Routine Description:
Invoked when the eSE Get ATR operation has completed.
Invoked when the eSE reset operation has completed.
*/
{
@ -3546,7 +3469,7 @@ Routine Description:
}
NTSTATUS
NfcCxRFInterfaceESEGetATRStringSeq(
NfcCxRFInterfaceESEResetSeq(
_In_ PNFCCX_RF_INTERFACE RFInterface,
_In_ NTSTATUS /*Status*/,
_In_opt_ VOID* /*Param1*/,
@ -3556,8 +3479,8 @@ NfcCxRFInterfaceESEGetATRStringSeq(
Routine Description:
Starts an eSE Get ATR operation. Function is triggered on the LibNfc thread in response to the
LIBNFC_EMBEDDED_SE_GET_ATR_STRING message.
Starts an eSE reset operation. Function is triggered on the LibNfc thread in response to the
LIBNFC_EMBEDDED_SE_RESET message.
*/
{
@ -3585,7 +3508,7 @@ Routine Description:
goto Done;
}
nfcStatus = phLibNfc_eSE_GetAtr(hSE_handle, &RFInterface->SeATRInfo, NfcCxRFInterfaceESEGetATRStringSeqCB, &LibNfcContext);
nfcStatus = phLibNfc_eSE_Abort(hSE_handle, &RFInterface->SeATRInfo, NfcCxRFInterfaceESEResetSeqCB, &LibNfcContext);
status = NfcCxNtStatusFromNfcStatus(nfcStatus);
Done:
@ -4817,7 +4740,7 @@ NfcCxRFInterfaceLibNfcMessageHandler(
case LIBNFC_SE_SET_MODE:
case LIBNFC_SE_SET_ROUTING_TABLE:
case LIBNFC_EMEBEDDED_SE_TRANSCEIVE:
case LIBNFC_EMBEDDED_SE_GET_ATR_STRING:
case LIBNFC_EMBEDDED_SE_RESET:
case LIBNFC_SNEP_CLIENT_PUT:
{
rfInterface->pLibNfcContext->Status = NfcCxStateInterfaceStateHandler(NfcCxRFInterfaceGetStateInterface(rfInterface),
@ -6040,7 +5963,7 @@ NfcCxRFInterfaceESETransceiveSeqComplete(
}
static NTSTATUS
NfcCxRFInterfaceESEGetATRStringSeqComplete(
NfcCxRFInterfaceESEResetSeqComplete(
_In_ PNFCCX_RF_INTERFACE RFInterface,
_In_ NTSTATUS Status,
_In_opt_ VOID* /*Param1*/,
@ -6649,16 +6572,16 @@ NfcCxRFInterfaceStateSEEvent(
}
break;
case LIBNFC_EMBEDDED_SE_GET_ATR_STRING:
case LIBNFC_EMBEDDED_SE_RESET:
{
NFCCX_CX_BEGIN_SEQUENCE_MAP(EmbeddedSEGetATRStringSequence)
RF_INTERFACE_EMBEDDEDSE_GET_ATR_STRING_SEQUENCE
NFCCX_CX_BEGIN_SEQUENCE_MAP(EmbeddedSEResetSequence)
RF_INTERFACE_EMBEDDEDSE_RESET_SEQUENCE
NFCCX_CX_END_SEQUENCE_MAP()
EmbeddedSEGetATRStringSequence[ARRAYSIZE(EmbeddedSEGetATRStringSequence) - 1].SequenceProcess =
NfcCxRFInterfaceESEGetATRStringSeqComplete;
EmbeddedSEResetSequence[ARRAYSIZE(EmbeddedSEResetSequence) - 1].SequenceProcess =
NfcCxRFInterfaceESEResetSeqComplete;
NFCCX_INIT_SEQUENCE(RfInterface, EmbeddedSEGetATRStringSequence);
NFCCX_INIT_SEQUENCE(RfInterface, EmbeddedSEResetSequence);
status = NfcCxSequenceHandler(RfInterface, RfInterface->pSeqHandler, STATUS_SUCCESS, Param2, Param3);
}
break;

Просмотреть файл

@ -9,7 +9,7 @@ Module Name:
Abstract:
RFInterface declarations
Environment:
User-mode Driver Framework
@ -51,7 +51,7 @@ typedef enum _NFCCX_LIBNFC_MESSAGE {
LIBNFC_SEQUENCE_HANDLER,
LIBNFC_DTA_MESSAGE,
LIBNFC_EMEBEDDED_SE_TRANSCEIVE,
LIBNFC_EMBEDDED_SE_GET_ATR_STRING,
LIBNFC_EMBEDDED_SE_RESET,
LIBNFC_MESSAGE_MAX,
} NFCCX_LIBNFC_MESSAGE, *PNFCCX_LIBNFC_MESSAGE;
@ -132,7 +132,7 @@ typedef struct _NFCCX_RF_INTERFACE {
UCHAR uiNfcIP_Tgt_Mode;
UCHAR uiNfcCE_Mode;
ULONG uiDuration;
UCHAR uiBailout;
UCHAR uiBailout;
// Store timetamp for Kovio last detection time to detect the tag being read again too quickly
ULONGLONG bKovioDetected;
@ -191,7 +191,7 @@ typedef struct _NFCCX_RF_INTERFACE {
typedef struct _NFCCX_RF_LIBNFC_REQUEST_CONTEXT {
PNFCCX_RF_INTERFACE RFInterface;
PNFCCX_CX_SEQUENCE Sequence;
PNFCCX_CX_SEQUENCE Sequence;
} NFCCX_RF_LIBNFC_REQUEST_CONTEXT, *PNFCCX_RF_LIBNFC_REQUEST_CONTEXT;
//
@ -334,12 +334,6 @@ NfcCxRFInterfaceSetCardActivationMode(
_In_ phLibNfc_PowerLinkModes_t ePowerAndLinkControl
);
NTSTATUS
NfcCxRFInterfaceResetCard(
_In_ PNFCCX_RF_INTERFACE RFInterface,
_In_ phLibNfc_Handle hSecureElement
);
NTSTATUS
NfcCxRFInterfaceSetRoutingTable(
_In_ PNFCCX_RF_INTERFACE RFInterface,
@ -388,7 +382,7 @@ NfcCxRFInterfaceESETransmit(
);
NTSTATUS
NfcCxRFInterfaceESEGetATRString(
NfcCxRFInterfaceESEReset(
_In_ PNFCCX_RF_INTERFACE RFInterface,
_Out_writes_bytes_to_(OutputBufferLength, *pOutputBufferUsed) PBYTE OutputBuffer,
_In_ size_t OutputBufferLength,
@ -516,7 +510,7 @@ FN_NFCCX_CX_SEQUENCE_ENTRY NfcCxRFInterfacePreRecovery;
FN_NFCCX_CX_SEQUENCE_ENTRY NfcCxRFInterfacePostRecovery;
FN_NFCCX_CX_SEQUENCE_ENTRY NfcCxRFInterfaceESETransceiveSeq;
FN_NFCCX_CX_SEQUENCE_ENTRY NfcCxRFInterfaceESEGetATRStringSeq;
FN_NFCCX_CX_SEQUENCE_ENTRY NfcCxRFInterfaceESEResetSeq;
#define RF_INTERFACE_INITIALIZE_SEQUENCE \
NFCCX_CX_SEQUENCE_ENTRY(NfcCxRFInterfacePreInitialize) \
@ -567,8 +561,8 @@ FN_NFCCX_CX_SEQUENCE_ENTRY NfcCxRFInterfaceESEGetATRStringSeq;
#define RF_INTERFACE_EMBEDDEDSE_TRANSCEIVE_SEQUENCE \
NFCCX_CX_SEQUENCE_ENTRY(NfcCxRFInterfaceESETransceiveSeq)
#define RF_INTERFACE_EMBEDDEDSE_GET_ATR_STRING_SEQUENCE \
NFCCX_CX_SEQUENCE_ENTRY(NfcCxRFInterfaceESEGetATRStringSeq)
#define RF_INTERFACE_EMBEDDEDSE_RESET_SEQUENCE \
NFCCX_CX_SEQUENCE_ENTRY(NfcCxRFInterfaceESEResetSeq)
#define RF_INTERFACE_SE_NTF_REGISTER_SEQUENCE NFCCX_CX_SEQUENCE_ENTRY(NfcCxRFInterfaceSENtfRegister)

Просмотреть файл

@ -2674,7 +2674,7 @@ Return Value:
// If present OverWrite the Keys else Validate KeyTable Size and Write the Keys
if ((dwKeyIndex = ((LoadKey*)ScInterface->StorageCardKey)->ExtractKeyIndex(KeyNumber)) != (DWORD)-1) {
TRACE_LINE(LEVEL_INFO, "OverWrite the Keys in the Available Index\n");
if (((LoadKey*)ScInterface->StorageCardKey)->OverWriteKeys(dwKeyIndex, KeyNumber, pCommandApdu->DataIn, MAX_BUFFERSIZE)){
if (((LoadKey*)ScInterface->StorageCardKey)->OverWriteKeys(dwKeyIndex, KeyNumber, pCommandApdu->DataIn, MAX_BUFFERSIZE)) {
RtlCopyMemory(Sw1Sw2, APDU_STATUS_SUCCESS, DEFAULT_APDU_STATUS_SIZE);
}
}

Просмотреть файл

@ -2792,54 +2792,6 @@ Done:
return status;
}
NTSTATUS
NfcCxSEInterfaceResetCard(
_In_ PNFCCX_SE_INTERFACE SEInterface,
_In_ const GUID& SecureElementId
)
/*++
Routine Description:
Resets an SE by power cycling it (or equivalent)
Arguments:
SEInterface - A pointer to the SEInterface
SecureElementId - The GUID of the SE
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
//
// Get the SE handle
//
phLibNfc_Handle hSecureElement;
if (!NfcCxSEInterfaceGetSecureElementHandle(
SEInterface->FdoContext->RFInterface,
SecureElementId,
&hSecureElement))
{
TRACE_LINE(LEVEL_ERROR, "Invalid secure element identifier %!GUID!", &SecureElementId);
status = STATUS_INVALID_PARAMETER;
goto Done;
}
status = NfcCxRFInterfaceResetCard(
SEInterface->FdoContext->RFInterface,
hSecureElement);
Done:
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
NTSTATUS
NfcCxSEInterfaceGetActivationMode(
_In_ PNFCCX_RF_INTERFACE RFInterface,

Просмотреть файл

@ -9,7 +9,7 @@ Module Name:
Abstract:
SE Interface declaration
Environment:
User-mode Driver Framework
@ -83,7 +83,7 @@ typedef struct _NFCCX_SE_INTERFACE {
WDFWAITLOCK SEManagerLock;
_Guarded_by_(SEManagerLock)
PNFCCX_FILE_CONTEXT SEManager;
//
// Secure Element Events
//
@ -124,11 +124,11 @@ NfcCxSEInterfaceStop(
_In_ PNFCCX_SE_INTERFACE SEInterface
);
FN_NFCCX_DDI_MODULE_ISIOCTLSUPPORTED
FN_NFCCX_DDI_MODULE_ISIOCTLSUPPORTED
NfcCxSEInterfaceIsIoctlSupported;
FN_NFCCX_DDI_MODULE_IODISPATCH
FN_NFCCX_DDI_MODULE_IODISPATCH
NfcCxSEInterfaceIoDispatch;
NTSTATUS
@ -269,12 +269,6 @@ NfcCxSEInterfaceUpdateSEActivationMode(
_In_ const NFCCX_SE_POWER_SETTINGS& PowerSettings
);
NTSTATUS
NfcCxSEInterfaceResetCard(
_In_ PNFCCX_SE_INTERFACE SEInterface,
_In_ const GUID& SecureElementId
);
NTSTATUS
NfcCxSEInterfaceGetRoutingTable(
_In_ PNFCCX_RF_INTERFACE RFInterface,

Просмотреть файл

@ -2258,7 +2258,7 @@ typedef void(*pphLibNfc_GetAtrCallback_t)(
/**
* \ingroup grp_lib_nfc
* \brief This function shall retreive the ATR (Answer to Request) from Secure element.
* \brief This function shall reset SE and retreive ATR (Answer to Reset).
*
* \param[in] hSE_Handle Handle to secure element
* \param[in] pAtrInfo pointer to #phNfc_SeAtr_Info_t structure
@ -2275,7 +2275,7 @@ typedef void(*pphLibNfc_GetAtrCallback_t)(
* \retval #NFCSTATUS_SHUTDOWN Shutdown in progress.
* \retval #NFCSTATUS_FAILED Operation failed.
*/
extern NFCSTATUS phLibNfc_eSE_GetAtr(phLibNfc_Handle hSE_Handle,
extern NFCSTATUS phLibNfc_eSE_Abort(phLibNfc_Handle hSE_Handle,
phNfc_SeAtr_Info_t* pAtrInfo,
pphLibNfc_GetAtrCallback_t pGetAtr_RspCb,
void* pContext);

Просмотреть файл

@ -244,16 +244,8 @@ phHciNfc_Transceive(void *pHciContext,
wStatus = phHciNfc_CoreSend (pHciCtxt,&tSendParams,&phHciNfc_CmdSendCb, pHciCtxt);
if(NFCSTATUS_PENDING == wStatus)
{
if (tSendParams.bIns == PHHCINFC_EVENT_ABORT)
{
pHciCtxt->Cb_Info.pClientInitCb = NULL;
pHciCtxt->Cb_Info.pClientCntx = NULL;
}
else
{
pHciCtxt->Cb_Info.pClientInitCb = pRspCb;
pHciCtxt->Cb_Info.pClientCntx = pContext;
}
pHciCtxt->Cb_Info.pClientInitCb = pRspCb;
pHciCtxt->Cb_Info.pClientCntx = pContext;
pHciCtxt->SendCb_Info.pClientInitCb = NULL;
pHciCtxt->SendCb_Info.pClientCntx = NULL;
}
@ -271,6 +263,7 @@ phHciNfc_Transceive(void *pHciContext,
PH_LOG_HCI_FUNC_EXIT();
return wStatus;
}
NFCSTATUS
phHciNfc_AnyGetParameter(
void *pHciContext,
@ -1483,7 +1476,7 @@ phHciNfc_eSE_EvtAbort(
/* Copy send parameters to hci context */
pHciCtxt->pSendParams = pSendParams;
/* Ins value is Wired Mode Shutdown */
pSendParams->bIns = PHHCINFC_EVENT_ABORT;
pSendParams->bIns = PHHCINFC_EVT_ABORT;
/* Message Type is Event */
pSendParams->bMsgType = phHciNfc_e_HcpMsgTypeEvent;
/* Data */

Просмотреть файл

@ -32,7 +32,7 @@ static NFCSTATUS phLibNfc_HciDataSendComplete(void* pContext,NFCSTATUS status,vo
static void phHciNfc_eSETransceiveTimeOutCb(uint32_t dwTimerId, void *pContext);
static NFCSTATUS phHciNfc_CreateSETransceiveTimer(phHciNfc_HciContext_t *pHciContext);
static void phLibNfc_eSE_GetAtrProc(void* pContext, NFCSTATUS status, void* pInfo);
static void phLibNfc_eSE_ResetProc(void* pContext, NFCSTATUS status, void* pInfo);
static NFCSTATUS phHciNfc_CreateSEGetAtrTimer(phHciNfc_HciContext_t *pHciContext);
//ETSI 12 changes
@ -531,7 +531,7 @@ static NFCSTATUS phLibNfc_HciDataSend(void* pContext,NFCSTATUS status,void* pInf
{
wStatus = phHciNfc_Transceive(pLibCtx->pHciContext,
bPipeId,
PHHCINFC_PROP_DATA_EVENT,
PHHCINFC_EVT_C_APDU,
pLibCtx->pSeTransInfo->sSendData.length,
pLibCtx->pSeTransInfo->sSendData.buffer,
&phLibNfc_SeSendCb,
@ -796,14 +796,14 @@ phHciNfc_ProcessEventsOnApduPipe(void *pContext, NFCSTATUS wStatus, void *pInfo)
pHciContext = (pphHciNfc_HciContext_t)pContext;
switch (pReceivedParams->bIns)
{
case PHHCINFC_PROP_DATA_EVENT:
case PHHCINFC_EVT_R_APDU:
(void)phLibNfc_HciDataSendProc(pLibContext, wStatus, pInfo);
break;
case PHHCINFC_PROP_WTX_EVENT:
case PHHCINFC_EVT_WTX:
{
phLibNfc_sSeWtxEventInfo_t tWtxInfo = { 0 };
PH_LOG_LIBNFC_INFO_STR("EVENT_WTX_REQ received");
PH_LOG_LIBNFC_INFO_STR("EVT_WTX received");
if (pLibContext->CBInfo.pSeClientEvtWtxCb != NULL)
{
tWtxInfo.dwTime = PHHCINFC_DEFAULT_HCI_TX_RX_TIME_OUT;
@ -854,8 +854,8 @@ phHciNfc_ProcessEventsOnApduPipe(void *pContext, NFCSTATUS wStatus, void *pInfo)
}
}
break;
case PHHCINFC_EVENT_ATR_RECV:
(void)phLibNfc_eSE_GetAtrProc(pContext, wStatus, pInfo);
case PHHCINFC_EVT_ATR:
(void)phLibNfc_eSE_ResetProc(pContext, wStatus, pInfo);
break;
default:
break;
@ -1374,7 +1374,7 @@ static void phHciNfc_eSEGetAtrTimeOutCb(uint32_t dwTimerId, void *pContext)
pLibCtx->pAtrInfo->pBuff = NULL;
pLibCtx->pAtrInfo->dwLength = 0;
(void)phLibNfc_eSE_GetAtrProc(pLibCtx->pHciContext, NFCSTATUS_RESPONSE_TIMEOUT, NULL);
(void)phLibNfc_eSE_ResetProc(pLibCtx->pHciContext, NFCSTATUS_RESPONSE_TIMEOUT, NULL);
}
else
{
@ -1383,7 +1383,48 @@ static void phHciNfc_eSEGetAtrTimeOutCb(uint32_t dwTimerId, void *pContext)
PH_LOG_LIBNFC_FUNC_EXIT();
}
static void phLibNfc_eSE_GetAtrProc(void* pContext, NFCSTATUS status, void* pInfo)
static void phLibNfc_eSE_LegacyAbortProc(void* pContext, NFCSTATUS status, void* pInfo)
{
pphLibNfc_Context_t pLibCtx = phLibNfc_GetContext();
phHciNfc_HciContext_t *pHciContext = NULL;
NFCSTATUS wStatus = NFCSTATUS_FAILED;
PH_LOG_LIBNFC_FUNC_ENTRY();
UNREFERENCED_PARAMETER(pInfo);
if (NULL == pLibCtx)
{
PH_LOG_LIBNFC_CRIT_STR("LibNfc context invalid");
}
else if (status != NFCSTATUS_SUCCESS)
{
PH_LOG_LIBNFC_CRIT_STR("Received failed status: %!NFCSTATUS!", status);
}
else if ((NULL == pLibCtx->pHciContext) || (pContext != pLibCtx->pHciContext))
{
PH_LOG_LIBNFC_CRIT_STR("Invalid Hci context received!");
}
else
{
pHciContext = pLibCtx->pHciContext;
wStatus = phHciNfc_AnyGetParameter(
pHciContext,
pHciContext->aSEPipeList[PHHCI_ESE_APDU_PIPE_LIST_INDEX].bGateId,
PHHCINFC_APDU_GATE_ATR_REG_ID,
pHciContext->aSEPipeList[PHHCI_ESE_APDU_PIPE_LIST_INDEX].bPipeId,
&phLibNfc_eSE_ResetProc,
pContext);
if (wStatus != NFCSTATUS_PENDING)
{
PH_LOG_LIBNFC_CRIT_STR("ANY_GET_PARAMETER(ATR) on APDU gate failed, status:%!NFCSTATUS!", wStatus);
}
}
PH_LOG_LIBNFC_FUNC_EXIT();
}
static void phLibNfc_eSE_ResetProc(void* pContext, NFCSTATUS status, void* pInfo)
{
pphLibNfc_Context_t pLibCtx = phLibNfc_GetContext();
phHciNfc_HciContext_t *pHciContext = NULL;
@ -1392,6 +1433,7 @@ static void phLibNfc_eSE_GetAtrProc(void* pContext, NFCSTATUS status, void* pInf
void *pClientCntx = NULL;
NFCSTATUS wStatus = NFCSTATUS_FAILED;
PH_LOG_LIBNFC_FUNC_ENTRY();
if (NULL != pLibCtx)
{
if ((status == NFCSTATUS_SUCCESS) && (pInfo != NULL))
@ -1443,6 +1485,7 @@ static void phLibNfc_eSE_GetAtrProc(void* pContext, NFCSTATUS status, void* pInf
{
PH_LOG_LIBNFC_CRIT_STR("Received FAILED status or pInfo Invalid");
}
pClientCb = pLibCtx->CBInfo.pSeClientGetAtrCb;
pClientCntx = pLibCtx->CBInfo.pSeClientGetAtrCntx;
pLibCtx->CBInfo.pSeClientGetAtrCb = NULL;
@ -1462,7 +1505,7 @@ static void phLibNfc_eSE_GetAtrProc(void* pContext, NFCSTATUS status, void* pInf
}
NFCSTATUS
phLibNfc_eSE_GetAtr(
phLibNfc_eSE_Abort(
phLibNfc_Handle hSE_Handle,
phNfc_SeAtr_Info_t* pAtrInfo,
pphLibNfc_GetAtrCallback_t pGetAtr_RspCb,
@ -1493,7 +1536,7 @@ phLibNfc_eSE_GetAtr(
if (wStatus != NFCSTATUS_SUCCESS)
{
/* Returns NFCSTATUS_BUSY to the Application*/
PH_LOG_LIBNFC_CRIT_STR("BUSY, eSE Transceive or eSE_GetAtr API is in progress");
PH_LOG_LIBNFC_CRIT_STR("BUSY, eSE Transceive or eSE Reset is in progress");
}
else if (NULL == pAtrInfo->pBuff || 0 == pAtrInfo->dwLength)
{
@ -1525,33 +1568,24 @@ phLibNfc_eSE_GetAtr(
}
else
{
phHciNfc_HciVersion_t seHciVersion =
phHciNfc_GetHciVersionForHost(pHciContext, seInfo->hciHostId);
if (seHciVersion >= phHciNfc_e_HciVersion12)
{
wStatus = phHciNfc_Transceive(
pLibCtx->pHciContext,
pHciContext->aSEPipeList[PHHCI_ESE_APDU_PIPE_LIST_INDEX].bPipeId,
PHHCINFC_EVENT_ABORT,
0,
NULL,
&phLibNfc_eSE_GetAtrProc,
pLibCtx->pHciContext);
}
else
{
wStatus = phHciNfc_AnyGetParameter(
pLibCtx->pHciContext,
pHciContext->aSEPipeList[PHHCI_ESE_APDU_PIPE_LIST_INDEX].bGateId,
PHHCINFC_APDU_GATE_ATR_REG_ID,
pHciContext->aSEPipeList[PHHCI_ESE_APDU_PIPE_LIST_INDEX].bPipeId,
&phLibNfc_eSE_GetAtrProc,
pLibCtx->pHciContext);
}
// EVT_ATR exists only on HCI v12+, so:
// - for HCI v12.0+: wait for EVT_ATR which must be raised after EVT_ABORT
// - for HCI v11 or older: ATR will be retrieved from APDU registry with ANY_GET_PARAMETER command
BOOL isEvtAtrSupported =
phHciNfc_GetHciVersionForHost(pHciContext, seInfo->hciHostId) >= phHciNfc_e_HciVersion12;
wStatus = phHciNfc_Transceive(
pLibCtx->pHciContext,
pHciContext->aSEPipeList[PHHCI_ESE_APDU_PIPE_LIST_INDEX].bPipeId,
PHHCINFC_EVT_ABORT,
0,
NULL,
isEvtAtrSupported ? NULL : phLibNfc_eSE_LegacyAbortProc,
pLibCtx->pHciContext);
if (NFCSTATUS_PENDING != wStatus)
{
PH_LOG_LIBNFC_CRIT_STR("Get ATR Failed!");
PH_LOG_LIBNFC_CRIT_STR("eSE Reset failure, %!NFCSTATUS!", wStatus);
wStatus = NFCSTATUS_FAILED;
pLibCtx->CBInfo.pSeClientGetAtrCb = NULL;
pLibCtx->CBInfo.pSeClientGetAtrCntx = NULL;
@ -1564,22 +1598,25 @@ phLibNfc_eSE_GetAtr(
pLibCtx->CBInfo.pSeClientGetAtrCntx = pContext;
pLibCtx->pAtrInfo = pAtrInfo;
NFCSTATUS wSEGetAtrTimerStatus = phHciNfc_CreateSEGetAtrTimer(pHciContext);
if (wSEGetAtrTimerStatus == NFCSTATUS_SUCCESS)
if (isEvtAtrSupported)
{
/* Start the SE TxRx Timer*/
pHciContext = (phHciNfc_HciContext_t *)pLibCtx->pHciContext;
pHciContext->tHciSeGetAtrTimerInfo.dwTimeOut = PHHCINFC_DEFAULT_HCI_TX_RX_TIME_OUT;
wSEGetAtrTimerStatus = phOsalNfc_Timer_Start(pHciContext->tHciSeGetAtrTimerInfo.dwRspTimerId,
pHciContext->tHciSeGetAtrTimerInfo.dwTimeOut,
&phHciNfc_eSEGetAtrTimeOutCb,
pLibCtx);
if (wSEGetAtrTimerStatus != NFCSTATUS_SUCCESS)
NFCSTATUS wSEGetAtrTimerStatus = phHciNfc_CreateSEGetAtrTimer(pHciContext);
if (wSEGetAtrTimerStatus == NFCSTATUS_SUCCESS)
{
// Wait for EVT_ATR
pHciContext->tHciSeGetAtrTimerInfo.dwTimeOut = PHHCINFC_DEFAULT_HCI_TX_RX_TIME_OUT;
wSEGetAtrTimerStatus = phOsalNfc_Timer_Start(
pHciContext->tHciSeGetAtrTimerInfo.dwRspTimerId,
pHciContext->tHciSeGetAtrTimerInfo.dwTimeOut,
&phHciNfc_eSEGetAtrTimeOutCb,
pLibCtx);
}
else
{
phOsalNfc_Timer_Delete(pHciContext->tHciSeGetAtrTimerInfo.dwRspTimerId);
PH_LOG_LIBNFC_CRIT_STR("SE Get Atr Timer Start Failed");
}
}
}
}
}
@ -1598,10 +1635,10 @@ NFCSTATUS phHciNfc_CheckTransactionOnApduPipe(void)
pLibCtx->CBInfo.pSeClientGetAtrCb != NULL)
{
/* Indicates that either eSE Transceive or
** eSE_GetAtr API is in progress
** eSE Reset is in progress
*/
wStatus = NFCSTATUS_BUSY;
PH_LOG_LIBNFC_INFO_STR("eSE Transceive or Get ATR API in progress");
PH_LOG_LIBNFC_INFO_STR("eSE Transceive or eSE Reset is in progress");
}
else
{

Просмотреть файл

@ -55,18 +55,23 @@
#define PH_LIBNFC_INTERNAL_HCI_CONNECTIVITY_EVENT (0x10)
#define PH_LIBNFC_INTERNAL_HCI_TRANSACTION_EVENT (0x12)
// ETSI TS 102 622, v12.1.0, Section 12.2.2
enum PHHCINFC_APDU_GATE_EVENTS
{
PHHCINFC_EVT_C_APDU = 0x10, // EVT_C-APDU
PHHCINFC_EVT_ABORT = 0x11, // EVT_ABORT
PHHCINFC_EVT_END_OF_APDU_TRANSACTION = 0x21, // EVT_END_OF_APDU_TRANSACTION
};
// ETSI TS 102 622, v12.1.0, Section 12.3.2
enum PHHCINFC_APDU_APPLICATION_GATE_EVENTS
{
PHHCINFC_PROP_DATA_EVENT = 0x10, // aka EVT_R-APDU
PHHCINFC_PROP_WTX_EVENT = 0x11, // aka EVT_WTX
PHHCINFC_EVT_R_APDU = 0x10, // EVT_R-APDU
PHHCINFC_EVT_WTX = 0x11, // EVT_WTX
PHHCINFC_EVT_ATR = 0x12, // EVT_ATR
};
#define PHHCINFC_NO_PIPE_DATA 0xFF
/* HCI EVT_ABORT and EVT_ATR as per ETSI12*/
#define PHHCINFC_EVENT_ABORT 0x11
#define PHHCINFC_EVENT_ATR_RECV 0x12
#define PHLIBNFC_TRANSACTION_AID 0x81
#define PHLIBNFC_TRANSACTION_PARAM 0x82