static void static_PSeHalSmRawExchangeApdu( tContext* pContext, tPSeHalSmRawInstance* pInstance, uint32_t nChannelIdentifier, tPBasicGenericDataCallbackFunction* pCallback, void* pCallbackParameter, const uint8_t* pSendApduBuffer, uint32_t nSendApduBufferLength, uint8_t* pReceivedApduBuffer, uint32_t nReceivedApduBufferMaxLength) { tSESlot* pSlot; tCSePorting* pSePorting; uint32_t nSlotIdentifier; uint32_t nSessionIdentifier; if (static_PSeHalSmRawGetParameters(pContext, pInstance, &pSlot, &pSePorting, &nSlotIdentifier, &nSessionIdentifier) != W_SUCCESS) { PDebugError("static_PSeHalSmRawExchangeApdu: Failed to get current parameters"); return; } PDFCFillCallbackContext( pContext, (tDFCCallback*)pCallback, pCallbackParameter, &pSlot->sExchange.sCallbackContext); CSeExchangeApdu(pSePorting, nSlotIdentifier, nSessionIdentifier, nChannelIdentifier, pSendApduBuffer, nSendApduBufferLength, pReceivedApduBuffer, nReceivedApduBufferMaxLength); }
/* @todo - documentation */ static void static_PSeHalSmRawCloseChannel( tContext* pContext, tPSeHalSmRawInstance* pInstance, uint32_t nChannelIdentifier, tPBasicGenericCallbackFunction* pCallback, void* pCallbackParameter) { tSESlot* pSlot; tCSePorting* pSePorting; uint32_t nSlotIdentifier; uint32_t nSessionIdentifier; if (static_PSeHalSmRawGetParameters(pContext, pInstance, &pSlot, &pSePorting, &nSlotIdentifier, &nSessionIdentifier) != W_SUCCESS) { PDebugError("static_PSeHalSmRawCloseChannel: Failed to get current parameters"); return; } PDFCFillCallbackContext( pContext, (tDFCCallback*)pCallback, pCallbackParameter, &pSlot->sExchange.sCallbackContext); CSeCloseChannel(pSePorting, nSlotIdentifier, nSessionIdentifier, nChannelIdentifier); }
/* @todo - documentation */ static void static_PSeHalSmRawOpenChannel( tContext* pContext, tPSeHalSmRawInstance* pInstance, tPBasicGenericDataCallbackFunction* pCallback, void* pCallbackParameter, uint32_t nType, const uint8_t* pAID, uint32_t nAIDLength) { tSESlot* pSlot; tCSePorting* pSePorting; uint32_t nSlotIdentifier; uint32_t nSessionIdentifier; if (static_PSeHalSmRawGetParameters(pContext, pInstance, &pSlot, &pSePorting, &nSlotIdentifier, &nSessionIdentifier) != W_SUCCESS) { PDebugError("static_tPSeHalSmRawOpenLogicalChannel: Failed to get current parameters"); return; } PDFCFillCallbackContext( pContext, (tDFCCallback*)pCallback, pCallbackParameter, &pSlot->sExchange.sCallbackContext); CSeOpenChannel(pSePorting, nSlotIdentifier, nSessionIdentifier, nType, pAID, nAIDLength); }
/** * Close a 7816 channel * * @param[in] pContext The context * * @param[in] pNDEFConnection The NDEF connection * * @param[in] nError The error to send after the channel has been closed */ static void static_PNDEFType4CloseChannel( tContext* pContext, tNDEFConnection* pNDEFConnection, tPBasicGenericDataCallbackFunction * pCallback, void * pCallbackParameter, W_ERROR nError) { pNDEFConnection->sType.t4.pChannelCallback = pCallback; pNDEFConnection->sType.t4.pChannelCallbackParameter = pCallbackParameter; /* Save the error */ pNDEFConnection->nError = nError; if (pNDEFConnection->sType.t4.h7816Channel != W_NULL_HANDLE) { /* Close the channel */ PBasicCloseHandleSafe(pContext, pNDEFConnection->sType.t4.h7816Channel, static_PNDEFType4CloseChannelCompleted, pNDEFConnection); pNDEFConnection->sType.t4.h7816Channel = W_NULL_HANDLE; } else { /* Channel is already closed. Send result */ tDFCCallbackContext sCallbackContext; PDFCFillCallbackContext(pContext, (tDFCCallback*)static_PNDEFType4CloseChannelCompleted, pNDEFConnection, &sCallbackContext); PDFCPostContext2(&sCallbackContext, W_SUCCESS); } }
/** * Open a 7816 channel used to exchanged APDU * * @param[in] pContext The context * * @param[in] pNDEFConnection The NDEF connection */ static void static_PNDEFType4OpenChannel( tContext* pContext, tNDEFConnection* pNDEFConnection, tPBasicGenericDataCallbackFunction * pCallback, void * pCallbackParameter) { pNDEFConnection->sType.t4.pChannelCallback = pCallback; pNDEFConnection->sType.t4.pChannelCallbackParameter = pCallbackParameter; if (pNDEFConnection->sType.t4.h7816Channel == W_NULL_HANDLE) { /* Open a raw channel used to exchange APDU */ P7816OpenChannelInternal( pContext, pNDEFConnection->hConnection, static_PNDEFType4OpenChannelCompleted, pNDEFConnection, W_7816_CHANNEL_TYPE_RAW, (const uint8_t*)null, 0); } else { /* Channel is already opened. Send result */ tDFCCallbackContext sCallbackContext; PDFCFillCallbackContext(pContext, (tDFCCallback*)static_PNDEFType4OpenChannelCompleted, pNDEFConnection, &sCallbackContext); PDFCPostContext3(&sCallbackContext, pNDEFConnection->sType.t4.h7816Channel, W_SUCCESS); } }
/* See header */ void PP2PEstablishLinkDriver2Internal( tContext * pContext, W_HANDLE hLink, tPBasicGenericCallbackFunction* pReleaseCallback, void* pReleaseCallbackParameter, W_HANDLE * phOperation) { tP2PInstance * pP2PInstance = PContextGetP2PInstance(pContext); tLLCPInstance * pLLCPInstance = &pP2PInstance->sLLCPInstance; tP2PLink * pP2PLink = null; W_ERROR nError; if (phOperation != null) { * phOperation = W_NULL_HANDLE; } nError = PHandleGetObject(pContext, hLink, P_HANDLE_TYPE_P2P_LINK, (void **) & pP2PLink); if ((nError != W_SUCCESS) || (pP2PLink == null)) { /* Should not occur, internal error */ PDebugError("PP2PEstablishLinkDriver2 : unable to retrieve link !!!! "); return; } PDebugTrace("PP2PEstablishLinkDriver2 : %08x %p", pP2PLink->hLink, pP2PLink); PDFCFillCallbackContext( pContext, (tDFCCallback*)pReleaseCallback, pReleaseCallbackParameter, & pP2PLink->sReleaseCC); if (phOperation != null) { * phOperation = pP2PLink->hEstablishOperation = PBasicCreateOperation(pContext, static_P2PCancelLinkEstablishment, pP2PLink); if (* phOperation == W_NULL_HANDLE) { /* unable to allocate the establish operation !!! */ static_PP2PCallLinkEstablishmentCallback(pContext, pP2PLink, W_ERROR_OUT_OF_RESOURCE); PHandleClose(pContext, pP2PLink->hLink); return; } } /* Add the link to the P2P instance */ static_PP2PRegisterLink(pContext, pP2PLink); static_PP2PIncrementLLCPUsageCount(pContext); if (pLLCPInstance->nRole != LLCP_ROLE_NONE) { /* If the LLCP is already connected, call the establishment callback now */ static_PP2PCallLinkEstablishmentCallback(pContext, pP2PLink, W_SUCCESS); } }
/* See client API */ void PP2PURILookup( tContext * pContext, W_HANDLE hLink, tPP2PURILookupCompleted * pCallback, void * pCallbackParameter, const char16_t * pServiceURI) { tDFCCallbackContext * pCallbackContext = (tDFCCallbackContext *) CMemoryAlloc(sizeof(tDFCCallbackContext)); W_ERROR nError; if (pCallbackContext != null) { PDFCFillCallbackContext(pContext, (tDFCCallback *) pCallback, pCallbackParameter, pCallbackContext); if (pServiceURI != null) { PP2PURILookupDriver(pContext, hLink, static_PP2PURILookupCompleted, pCallbackContext, pServiceURI, PUtilStringLength(pServiceURI) * sizeof(char16_t)); } else { /* all errors are handled in the driver implementation */ PP2PURILookupDriver(pContext, hLink, static_PP2PURILookupCompleted, pCallbackContext, null, 0); } nError = PContextGetLastIoctlError(pContext); if (nError != W_SUCCESS) { tDFCCallbackContext sCallbackContext; PDFCFillCallbackContext(pContext, (tDFCCallback *) static_PP2PURILookupCompleted, pCallbackContext, &sCallbackContext); PDFCPostContext3(&sCallbackContext, 0, nError); } } else { tDFCCallbackContext sCallbackContext; PDFCFillCallbackContext(pContext, (tDFCCallback *) pCallback, pCallbackParameter, &sCallbackContext); PDFCPostContext3(&sCallbackContext, 0, W_ERROR_OUT_OF_RESOURCE); } }
/* See WP2PEstablishLink */ W_HANDLE PP2PEstablishLinkDriver1Internal( tContext * pContext, tPBasicGenericHandleCallbackFunction* pEstablishmentCallback, void* pEstablishmentCallbackParameter ) { tDFCCallbackContext sCallbackContext; tP2PLink * pP2PLink = null; W_ERROR nError; PDFCFillCallbackContext( pContext, (tDFCCallback*)pEstablishmentCallback, pEstablishmentCallbackParameter, & sCallbackContext); if (PP2PCheckP2PSupport(pContext) == W_FALSE) { nError = W_ERROR_RF_PROTOCOL_NOT_SUPPORTED; goto error; } pP2PLink = CMemoryAlloc(sizeof(tP2PLink)); if (pP2PLink == null) { nError = W_ERROR_OUT_OF_RESOURCE; goto error; } CMemoryFill(pP2PLink, 0, sizeof(tP2PLink)); nError = PHandleRegister(pContext, pP2PLink, P_HANDLE_TYPE_P2P_LINK, &pP2PLink->hLink); if (nError != W_SUCCESS) { goto error; } pP2PLink->sEstablishmentCC = sCallbackContext; return pP2PLink->hLink; error: if (pP2PLink != null) { CMemoryFree(pP2PLink); } PDFCPostContext3(&sCallbackContext, W_NULL_HANDLE, nError); return W_NULL_HANDLE; }
/* See tCSeCallback */ static void static_PSeHalCallback( void* pCallbackParameter, uint32_t nHalSlotIdentifier, uint32_t nOperation, bool_t bSuccess, uint32_t nParam1, uint32_t nParam2) { tContext* pContext = (tContext*)pCallbackParameter; tPSeHalInstance* pSeHalInstance; uint32_t nIndex; tDFCCallbackContext sCallbackContext; /* Lock the context to prevent re-entrancy issues */ PContextLock(pContext); PDebugTrace("static_PSeHalCallback(%d, code=%d)", nHalSlotIdentifier, nOperation); pSeHalInstance = PContextGetSeHalInstance(pContext); if(pSeHalInstance->bIsInitialized == W_FALSE) { PDebugError("static_PSeHalCallback(): bad state, ignoring the event"); goto return_function; } nIndex = static_PSeHalFindSlot(pSeHalInstance, nHalSlotIdentifier); if(nIndex == P_SE_HAL_MAXIMUM_SE_NUMBER) { PDebugError("static_PSeHalCallback(): wrong slot identifier, ignoring the event"); goto return_function; } switch(nOperation) { case C_SE_OPERATION_GET_INFO: if(pSeHalInstance->aSlotArray[nIndex].pGetInfoCallback == null) { PDebugError("static_PSeHalCallback(): no get info pending"); goto return_function; } if(pSeHalInstance->aSlotArray[nIndex].nGetInfoAtrBufferLength < nParam2) { PDebugError("static_PSeHalCallback(): ATR too long for th buffer"); goto return_function; } PDFCFillCallbackContext( pContext, (tDFCCallback*)pSeHalInstance->aSlotArray[nIndex].pGetInfoCallback, pSeHalInstance->aSlotArray[nIndex].pGetInfoCallbackParameter, &sCallbackContext ); pSeHalInstance->aSlotArray[nIndex].pGetInfoCallback = null; PDFCPostContext5( &sCallbackContext, pSeHalInstance->aSlotArray[nIndex].nHalSlotIdentifier, nParam1, nParam2, (bSuccess != W_FALSE)?W_SUCCESS:W_ERROR_TIMEOUT ); break; case C_SE_OPERATION_OPEN: case C_SE_OPERATION_EXCHANGE: case C_SE_OPERATION_CLOSE: PSeHalSmNotifyOperationCompletion(pContext, pSeHalInstance->aSlotArray[nIndex].nHalSlotIdentifier, nOperation, bSuccess, nParam1, nParam2); break; case C_SE_NOTIFY_HOT_PLUG: PSEDriverNotifyHotPlug(pContext, nHalSlotIdentifier, bSuccess); break; case C_SE_NOTIFY_STK_ACTIVATE_SWP: PSEDriverNotifyStkActivateSwp(pContext, nHalSlotIdentifier); break; case C_SE_NOTIFY_STK_REFRESH: if((nParam1 != P_SE_STK_REFRESH_CODE_FILE_CHANGE_NOTIFICATION) && (nParam1 != P_SE_STK_REFRESH_CODE_UICC_RESET)) { PDebugError("static_PSeHalCallback(): wrong code for the STK REFRESH command"); goto return_function; } if(nParam2 > sizeof(pSeHalInstance->aRefreshFileList)) { PDebugError("static_PSeHalCallback(): file list length too long for the STK REFRESH command"); goto return_function; } PSEDriverNotifyStkRefresh(pContext, nHalSlotIdentifier, nParam1, pSeHalInstance->aRefreshFileList, nParam2); break; default: PDebugError("static_PSeHalCallback(): wrong operation code"); goto return_function; } return_function: /* Release the lock */ PContextReleaseLock(pContext); }
static void static_PBPrimeUserExchangeData( tContext* pContext, void* pObject, tPBasicGenericDataCallbackFunction* pCallback, void* pCallbackParameter, const uint8_t* pReaderToCardBuffer, uint32_t nReaderToCardBufferLength, uint8_t* pCardToReaderBuffer, uint32_t nCardToReaderBufferMaxLength, W_HANDLE* phOperation) { tPBPrimeUserConnection* pBPrimeUserConnection = (tPBPrimeUserConnection*)pObject; tDFCCallbackContext sCallbackContext; W_ERROR nError = W_SUCCESS; PDebugTrace("static_PBPrimeUserExchangeData"); PDFCFillCallbackContext( pContext, (tDFCCallback*)pCallback, pCallbackParameter, &sCallbackContext ); /* Check if an operation is still pending */ if ( pBPrimeUserConnection->hCurrentOperation != W_NULL_HANDLE ) { PDebugError("static_PBPrimeUserExchangeData: operation already pending"); nError = W_ERROR_BAD_STATE; goto return_error; } /* Check the card buffer size */ if ((nReaderToCardBufferLength == 0) || (pReaderToCardBuffer == null)) { PDebugError("static_PBPrimeUserExchangeData: nReaderToCardBufferLength / pReaderToCardBuffer can not be null"); nError = W_ERROR_BAD_PARAMETER; goto return_error; } if ( ((pCardToReaderBuffer == null) && (nCardToReaderBufferMaxLength != 0)) || ((pCardToReaderBuffer != null) && (nCardToReaderBufferMaxLength == 0)) ) { PDebugError("static_PBPrimeUserExchangeData: inconsistency between pCardToReaderBuffer and nCardToReaderBufferMaxLength"); nError = W_ERROR_BAD_PARAMETER; goto return_error; } /* Get an operation handle if needed */ if((pBPrimeUserConnection->hCurrentOperation = PBasicCreateOperation( pContext, static_PBPrimeUserExchangeDataCancel, pBPrimeUserConnection)) == W_NULL_HANDLE) { PDebugError("static_PBPrimeUserExchangeData: Cannot allocate the operation"); nError = W_ERROR_OUT_OF_RESOURCE; goto return_error; } if(phOperation != null) { /* Duplicate the handle to be referenced internally and in the returned handle */ nError = PHandleDuplicate(pContext, pBPrimeUserConnection->hCurrentOperation, phOperation ); if(nError != W_SUCCESS) { PDebugError("static_PBPrimeUserExchangeData: Error returned by PHandleDuplicate()"); PHandleClose(pContext, pBPrimeUserConnection->hCurrentOperation); pBPrimeUserConnection->hCurrentOperation = W_NULL_HANDLE; goto return_error; } } pBPrimeUserConnection->hCurrentDriverOperation = PBPrimeDriverExchangeData( pContext, pBPrimeUserConnection->hDriverConnection, static_PBPrimeUserExchangeDataCompleted, pBPrimeUserConnection, pReaderToCardBuffer, nReaderToCardBufferLength, pCardToReaderBuffer, nCardToReaderBufferMaxLength); nError = PContextGetLastIoctlError(pContext); if (nError != W_SUCCESS) { PDebugError("static_PBPrimeUserExchangeData: Error returned by PContextGetLastIoctlError()"); PHandleClose(pContext, pBPrimeUserConnection->hCurrentOperation); pBPrimeUserConnection->hCurrentOperation = W_NULL_HANDLE; goto return_error; } /* Store the callback context */ pBPrimeUserConnection->sCallbackContext = sCallbackContext; /* Increment the reference count to keep the connection object alive during the operation. The reference count is decreased in static_PBPrimeUserExchangeDataCompleted when the NFC HAL operation is completed */ PHandleIncrementReferenceCount(pBPrimeUserConnection); return; return_error: PDebugError("static_PBPrimeUserExchangeData: returning %s", PUtilTraceError(nError)); PDFCPostContext3( &sCallbackContext, 0, nError ); }
/* See Header file */ void PBPrimeUserCreateConnection( tContext* pContext, W_HANDLE hUserConnection, W_HANDLE hDriverConnection, tPBasicGenericCallbackFunction* pCallback, void* pCallbackParameter, uint8_t nProtocol, const uint8_t* pBuffer, uint32_t nLength ) { tPBPrimeUserConnection* pBPrimeUserConnection; tDFCCallbackContext sCallbackContext; W_ERROR nError; PDFCFillCallbackContext( pContext, (tDFCCallback*)pCallback, pCallbackParameter, &sCallbackContext ); /* Create the B PRIME buffer */ pBPrimeUserConnection = (tPBPrimeUserConnection*)CMemoryAlloc( sizeof(tPBPrimeUserConnection) ); if ( pBPrimeUserConnection == null ) { PDebugError("PBPrimeUserCreateConnection: pBPrimeUserConnection == null"); nError = W_ERROR_OUT_OF_RESOURCE; goto return_function; } CMemoryFill(pBPrimeUserConnection, 0, sizeof(tPBPrimeUserConnection)); pBPrimeUserConnection->nProtocol = nProtocol; /* Store the callback context */ pBPrimeUserConnection->sCallbackContext = sCallbackContext; /* Store the connection information */ pBPrimeUserConnection->hDriverConnection = hDriverConnection; /* Parse the information */ if ( ( nError = static_PBPrimeUserParseCardInfo( pContext, pBPrimeUserConnection, pBuffer, nLength ) ) != W_SUCCESS ) { PDebugError( "PBPrimeUserCreateConnection: error while parsing the card information"); CMemoryFree(pBPrimeUserConnection); goto return_function; } /* Add the B PRIME structure */ if ( ( nError = PHandleAddHeir( pContext, hUserConnection, pBPrimeUserConnection, P_HANDLE_TYPE_B_PRIME_USER_CONNECTION ) ) != W_SUCCESS ) { PDebugError("PBPrimeUserCreateConnection: could not add the B PRIME buffer"); /* Send the result */ CMemoryFree(pBPrimeUserConnection); goto return_function; } return_function: if(nError != W_SUCCESS) { PDebugError( "PBPrimeUserCreateConnection: returning %s", PUtilTraceError(nError) ); } PDFCPostContext2( &sCallbackContext, nError ); }
void PNDEFFormatNDEFType6(tContext* pContext, W_HANDLE hConnection, tPBasicGenericCallbackFunction *pCallback, void *pCallbackParameter, uint8_t nTypeTag, uint32_t nTagSize) { t15693Format* p15693Format = null; tDFCCallbackContext sCallbackContext; PDebugTrace("PNDEFFormatNDEFType6"); /* Get the connection property number to check if it exists */ PDFCFillCallbackContext( pContext, (tDFCCallback*)pCallback, pCallbackParameter, &sCallbackContext ); p15693Format = (t15693Format*)CMemoryAlloc( sizeof(t15693Format) ); if ( p15693Format == null ) { PDebugError("PNDEFFormatNDEFType6: p15693Format == null"); PDFCPostContext2( &sCallbackContext, W_ERROR_OUT_OF_RESOURCE ); return; } /* Store the connection information */ p15693Format->sCallbackContext = sCallbackContext; switch (nTypeTag) { case W_PROP_TI_TAGIT : P15WriteInternal(pContext, hConnection, static_W15693WriteCompleted, p15693Format, g_TagItFormat, 0, sizeof(g_TagItFormat), W_FALSE); break; case W_PROP_NXP_ICODE : switch (nTagSize) { case P_15693_PHILIPS_SL2ICS20_SIZE: P15WriteInternal(pContext, hConnection, static_W15693WriteCompleted, p15693Format, g_ICodeSL2ICS20Format, 0, sizeof(g_ICodeSL2ICS20Format), W_FALSE); break; case P_15693_PHILIPS_SL2ICS53_SIZE: P15WriteInternal(pContext, hConnection, static_W15693WriteCompleted, p15693Format, g_ICodeSL2ICS53Format, 0, sizeof(g_ICodeSL2ICS53Format), W_FALSE); break; case P_15693_PHILIPS_SL2ICS50_SIZE: P15WriteInternal(pContext, hConnection, static_W15693WriteCompleted, p15693Format, g_ICodeSL2ICS50Format, 0, sizeof(g_ICodeSL2ICS50Format), W_FALSE); break; default: static_W15693WriteCompleted(pContext, p15693Format, W_ERROR_CONNECTION_COMPATIBILITY); break; } break; case W_PROP_ST_LRI_512 : P15WriteInternal(pContext, hConnection, static_W15693WriteCompleted, p15693Format, g_LRI512Format, 0, sizeof(g_LRI512Format), W_FALSE); break; } }
/** * Sends Select Application APDU * * @param[in] pContext The context * * @param[in] pNDEFConnection The NDEF connection */ static void static_PNDEFType4SelectApplication( tContext* pContext, tNDEFConnection* pNDEFConnection, tPBasicGenericDataCallbackFunction * pCallback, void * pCallbackParameter) { pNDEFConnection->sType.t4.pCCCache = PCacheConnectionGetBuffer(pContext, P_NDEF_4_CC_CACHE_ID, 0, &pNDEFConnection->sType.t4.nCCCacheLength); pNDEFConnection->sType.t4.pNDEFCache = PCacheConnectionGetBuffer(pContext, P_NDEF_4_NDEF_CACHE_ID, 0, &pNDEFConnection->sType.t4.nNDEFCacheLength); if ((pNDEFConnection->sType.t4.pCCCache == null) || (pNDEFConnection->sType.t4.pNDEFCache == null)) { /* NFC Type 4 Tag v2.0 specific commands (with optional Le byte) */ static const uint8_t aSelectApplicationv20[] = { P_7816SM_CLA, P_7816SM_INS_SELECT, P_7816SM_P1_SELECT_AID, P_7816SM_P2_SELECT_AID, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00 }; /* NFC Type 4 Tag v1.0 specific commands (with non-standard Le byte) */ static const uint8_t aSelectApplicationv10[] = { P_7816SM_CLA, P_7816SM_INS_SELECT, P_7816SM_P1_SELECT_AID, P_7816SM_P2_SELECT_AID, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00, 0x00 }; const uint8_t * pSelectApplication; uint8_t nCommandLength = 0; PDebugTrace("static_PNDEFType4SelectApplication"); switch (pNDEFConnection->sType.t4.nVariant) { case P_NDEF_4_VERSION_20: pSelectApplication = aSelectApplicationv20; nCommandLength = sizeof(aSelectApplicationv20); break; case P_NDEF_4_VERSION_20_NON_STANDARD: pSelectApplication = aSelectApplicationv20; nCommandLength = sizeof(aSelectApplicationv20) - 1; break; case P_NDEF_4_VERSION_10: pSelectApplication = aSelectApplicationv10; nCommandLength = sizeof (aSelectApplicationv10) - 1; break; case P_NDEF_4_VERSION_10_NON_STANDARD: pSelectApplication = aSelectApplicationv10; nCommandLength = sizeof (aSelectApplicationv10); break; default: PDebugError("static_PNDEFType4SelectApplication : invalid tag type"); return; } /* Send the command */ P7816ExchangeApduInternal( pContext, pNDEFConnection->sType.t4.h7816Channel, pCallback, pCallbackParameter, pSelectApplication, nCommandLength, pNDEFConnection->pReceivedBuffer, pNDEFConnection->nBufferLength); } else { tDFCCallbackContext sCallbackContext; PDebugTrace("static_PNDEFType4SelectApplication : skipping select due to cache existence"); pNDEFConnection->pReceivedBuffer[0] = 0x90; pNDEFConnection->pReceivedBuffer[1] = 0x00; PDFCFillCallbackContext(pContext, (tDFCCallback *) pCallback, pCallbackParameter, &sCallbackContext); PDFCPostContext3(&sCallbackContext, 2, W_SUCCESS); } }