Example #1
0
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 );
}
Example #2
0
/*!
 * \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;
}