NTSTATUS CBT1Transmit( PSMARTCARD_EXTENSION SmartcardExtension ) /*++ CBT1Transmit: finishes the callback RDF_TRANSMIT for the T1 protocol Arguments: SmartcardExtension context of call Return Value: STATUS_SUCCESS STATUS_NO_MEDIA STATUS_TIMEOUT STATUS_INVALID_DEVICE_REQUEST --*/ { NTSTATUS NTStatus = STATUS_SUCCESS; ULONG IOBytes; SmartcardDebug( DEBUG_TRACE, ( "PSCR!CBT1Transmit: Enter\n" ) ); // // use the lib support to construct the T=1 packets // do { // // no header for the T=1 protocol // SmartcardExtension->SmartcardRequest.BufferLength = 0; // // SCM-TM: Siemens 4440 accepts only NAD=0!!! // SmartcardExtension->T1.NAD = 0; // // let the lib setup the T=1 APDU & check for errors // NTStatus = SmartcardT1Request( SmartcardExtension ); if ( NT_SUCCESS( NTStatus )) { // send command (don't calculate LRC because CRC may be used!) IOBytes = 0; NTStatus = PscrWriteDirect( SmartcardExtension->ReaderExtension, SmartcardExtension->SmartcardRequest.Buffer, SmartcardExtension->SmartcardRequest.BufferLength, &IOBytes ); if ( !NT_SUCCESS(NTStatus)) { SmartcardDebug( DEBUG_TRACE, ( "PSCR!CBT1Transmit: PscrWriteDirect error (%lx)\n", NTStatus ) ); } // // extend the timeout if a Wtx request was sent by the card. if the // card responds before the waiting time extension expires, the data are // buffered in the reader. A delay without polling the reader status // slows down the performance of the driver, but wtx is an exeption, // not the rule. // if (SmartcardExtension->T1.Wtx) { SysDelay( (( SmartcardExtension->T1.Wtx * SmartcardExtension->CardCapabilities.T1.BWT + 999L )/ 1000L) ); } // get response SmartcardExtension->SmartcardReply.BufferLength = 0; NTStatus = PscrRead( SmartcardExtension->ReaderExtension, SmartcardExtension->SmartcardReply.Buffer, MAX_T1_BLOCK_SIZE, &SmartcardExtension->SmartcardReply.BufferLength ); // if PscrRead detects an LRC error, ignore it (maybe CRC used) if ( NTStatus == STATUS_CRC_ERROR ) { SmartcardDebug( DEBUG_TRACE, ( "PSCR!CBT1Transmit: PscrRead CRC error (%lx)\n", NTStatus ) ); } // // We even continue if the prev. read failed. // We let the smart card library continue, because it might // send a resynch. request in case of a timeout // NTStatus = SmartcardT1Reply( SmartcardExtension ); } // continue if the lib wants to send the next packet } while ( NTStatus == STATUS_MORE_PROCESSING_REQUIRED ); // start freeze routine, if an interrupt was sent, but no freeze data was read if( SmartcardExtension->ReaderExtension->RequestInterrupt ) PscrFreeze( SmartcardExtension ); SmartcardDebug( DEBUG_TRACE, ( "PSCR!CBT1Transmit: Exit (%lx)\n", NTStatus ) ); return( NTStatus ); }
/*! * \brief Function performs data transmissions T=1.<br> * <br> * \param [in] pSmartcardExtension A pointer to the smart card extension, SMARTCARD_EXTENSION, of the device. * * \retval STATUS_SUCCESS the routine successfully end. */ static NTSTATUS transmitT1(IN PSMARTCARD_EXTENSION pSmartcardExtension) { dbg_log("transmitT1 start"); NTSTATUS status = STATUS_SUCCESS; do { // reset request buffer before calling SmartcardT1Request // not to add any Header with T=1 message. RtlZeroMemory(pSmartcardExtension->SmartcardRequest.Buffer, pSmartcardExtension->SmartcardRequest.BufferLength); pSmartcardExtension->SmartcardRequest.BufferLength = 0; dbg_log("pSmartcardExtension->T1.IFSC: 0x%08X", pSmartcardExtension->T1.IFSC); dbg_log("pSmartcardExtension->T1.IFSD: 0x%08X", pSmartcardExtension->T1.IFSD); status = SmartcardT1Request(pSmartcardExtension); if (status != STATUS_SUCCESS) { dbg_log("SmartcardT0Request failed! - status: 0x%08X", status); return status; } dbg_log("transmitT1 SEND: "); dbg_ba2s( (char const *const)pSmartcardExtension->SmartcardRequest.Buffer, pSmartcardExtension->SmartcardRequest.BufferLength ); dbg_log("pSmartcardExtension->SmartcardRequest.Buffer[1]: 0x%08X", pSmartcardExtension->SmartcardRequest.Buffer[1]); // send command to JCOP simulator. PREADER_EXTENSION pReaderExtension = pSmartcardExtension->ReaderExtension; // send "T1" meessage. unsigned char mty = 0x11; // MTY 0x11(T1 Message) unsigned char nad = 0x00; // NAD status = sendMessage( pReaderExtension, mty, nad, (char *)pSmartcardExtension->SmartcardRequest.Buffer, (unsigned short)pSmartcardExtension->SmartcardRequest.BufferLength, (char *)pSmartcardExtension->SmartcardReply.Buffer, (unsigned short)pSmartcardExtension->SmartcardReply.BufferSize, (unsigned short *) & pSmartcardExtension->SmartcardReply.BufferLength, NULL // wait indefinitely ); dbg_log( "pSmartcardExtension->SmartcardReply.BufferLength: %d", pSmartcardExtension->SmartcardReply.BufferLength ); dbg_ba2s( (char *const)pSmartcardExtension->SmartcardReply.Buffer, pSmartcardExtension->SmartcardReply.BufferLength ); if (status != STATUS_SUCCESS) { dbg_log("sendApduMessage failed! - status: 0x%08X", status); return status; } status = SmartcardT1Reply(pSmartcardExtension); dbg_log("SmartcardT1Reply - status: 0x%08X", status); } while (status == STATUS_MORE_PROCESSING_REQUIRED); if (status != STATUS_SUCCESS) { dbg_log("SmartcardT0Reply failed! - status: 0x%08X", status); return status; } dbg_log("transmitT1 end - status: 0x%08X", status); return status; }