⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlp3cb.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
            }

            if (status != STATUS_TIMEOUT && 
                memcmp(ptsRequest, ptsReply, 4) == 0) {

                // the card replied correctly to our pts-request
                break;
            }

            if (SmartcardExtension->CardCapabilities.PtsData.Type !=
                PTS_TYPE_DEFAULT) {

                SmartcardDebug(
                    DEBUG_TRACE,
                    (TEXT("%s!TLP3SetProtocol: PTS failed. Trying default parameters...\n"),
                    szDriverName,
                    status)
                    );
                //
                // The card did either NOT reply or it replied incorrectly
                // so try default values
                //
                SmartcardExtension->CardCapabilities.PtsData.Type = 
                    PTS_TYPE_DEFAULT;

                SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;

                status = TLP3ReaderPower(SmartcardExtension);

                continue;
            } 
            
            // the card failed the pts-request
            status = STATUS_DEVICE_PROTOCOL_ERROR;
            leave;
        } 

      
        if (!QueryPerformanceFrequency(&liProcessClock)) { // not supported
            // ASSUME it is 66 Mhz CPU Clock
            liProcessClock.HighPart=0;
            liProcessClock.LowPart=66*1000000L;
        };
        // Minimum wait set to 5k instruction in Milli Second.
        liProcessClock.QuadPart/=1000; // Frequncy in Milli Second.
        minWaitTime = (DWORD) ((5000L*5+liProcessClock.QuadPart/2)/(liProcessClock.QuadPart));

        // now indicate that we're in specific mode 
        SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;

        // return the selected protocol to the caller
        *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = 
            SmartcardExtension->CardCapabilities.Protocol.Selected;

        *SmartcardExtension->IoRequest.Information = 
            sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
    } 
    finally {

        if (status == STATUS_TIMEOUT) {

            // STATUS_TIMEOUT is not mapped to a Win32 error code
            status = STATUS_IO_TIMEOUT;             

            *SmartcardExtension->IoRequest.Information = 0;

        } else if (status != STATUS_SUCCESS) {
            
            SmartcardExtension->CardCapabilities.Protocol.Selected = 
                SCARD_PROTOCOL_UNDEFINED;

            *SmartcardExtension->IoRequest.Information = 0;
        } 
    }

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3SetProtocol: Exit(%lx)\n"),
        szDriverName,
        status)
        );

   return status;
}

NTSTATUS
TLP3TransmitT0(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

    This function performs a T=0 transmission.

Arguments:

    SmartcardExtension - Pointer to smart card data struct.

Return Value:

    NTSTATUS

--*/
{
    PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
    PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
    PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
    PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
    PULONG serialIoControlCode = &SmartcardExtension->ReaderExtension->SerialIoControlCode;
    ULONG bytesToSend, bytesToRead, currentByte = 0;
    BOOLEAN restartWorkWaitingTime = FALSE;
    DWORD dwMilliSecond;
    NTSTATUS status;

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3TransmitT0: Enter\n"),
        szDriverName)
        );

    try {

        // Let the lib build a T=0 packet
        status = SmartcardT0Request(
            SmartcardExtension
            );

        if (status != STATUS_SUCCESS) 
            leave;

        //
        // The number of bytes we expect from the card
        // is Le + 2 status bytes
        //
        bytesToSend = *requestLength;
        bytesToRead = SmartcardExtension->T0.Le + 3;

        SmartcardDebug(
            DEBUG_TRACE,
            (TEXT("%s!TLP3TransmitT0: Send %d and Received %d \n"),
            szDriverName,bytesToSend,bytesToRead)
            );

        //
        // Send the first 5 bytes to the card
        //
        *requestLength = 5;

        do {

            UCHAR procByte;

            //
            // According to ISO 7816 a procedure byte of 
            // 60 should be treated as a request for a one time wait.
            // In this case we do not write anything to the card
            //
            if (restartWorkWaitingTime == FALSE) {

                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!TLP3TransmitT0: -> Sending %s (%ld bytes)\n"),
                    szDriverName,
                    (currentByte == 0 ? TEXT("header") : TEXT("data")),
                    *requestLength)
                    );
                //
                // Write to the card
                //
                *serialIoControlCode = SMARTCARD_WRITE;
                SmartcardExtension->SmartcardRequest.Buffer = &requestBuffer[currentByte];

                status = TLP3SerialIo(
                    SmartcardExtension
                    );

                if (status != STATUS_SUCCESS)
                	{
                		DEBUGMSG(1,(TEXT("status != STATUS_SUCCESS, leave====>>>\r\n")));
                    		leave;
                	}
	
                currentByte += *requestLength;
                bytesToSend -= *requestLength;
				
            }

	if((*requestLength ==5)&&(bytesToSend==0)){
		 *serialIoControlCode = SMARTCARD_READ;
                *replyLength = bytesToRead;

                status = TLP3SerialIo(
                    SmartcardExtension
                    );

		if (status != STATUS_SUCCESS) 
                leave;
			 
              SmartcardExtension->SmartcardReply.BufferLength = bytesToRead;
		restartWorkWaitingTime = TRUE;

		bytesToSend = 0;
              bytesToRead = 0;

		break;

	
           
	}else{
		
                // Read the 'Procedure byte'.
            SmartcardExtension->SmartcardReply.Buffer = &procByte;
            *serialIoControlCode = SMARTCARD_READ;
            *replyLength = 1;

            status = TLP3SerialIo(
                SmartcardExtension
                );

            if (status != STATUS_SUCCESS) 
                leave;

            restartWorkWaitingTime = FALSE;
				
	}
            //
            // Check the procedure byte. 
            // Please take a look at ISO 7816 Part 3 Section 8.2.2
            //
            if (procByte == requestBuffer[1] || 
                procByte == requestBuffer[1] + 1) {

                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!TLP3TransmitT0: <- ACK (send all)\n"),
                    szDriverName)
                    );

                // All remaining data bytes can be sent at once
                *requestLength = bytesToSend;

            } else if (procByte == (UCHAR) ~requestBuffer[1] ||
                       procByte == (UCHAR) ~(requestBuffer[1] + 1)) {

                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!TLP3TransmitT0: <- ACK (send single)\n"),
                    szDriverName)
                    );

                // We can send only one byte
                *requestLength = 1;

            } else if (procByte == 0x60 ||
                       SmartcardExtension->CardCapabilities.InversConvention &&
                       procByte == 0xf9) {

                //
                // We have to reset the wait time and try again to read
                //
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!TLP3TransmitT0: <- NULL (%ldms)\n"),
                    szDriverName,
                    SmartcardExtension->CardCapabilities.T0.WT / 1000)
                    );

                dwMilliSecond=(SmartcardExtension->CardCapabilities.T0.WT+MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
                if (dwMilliSecond) {
                    Sleep(dwMilliSecond);
                }
                //
                // Set flag that we only should read the proc byte
                // without writing data to the card
                //
                restartWorkWaitingTime = TRUE;

            } else {
                 
                //
                // The card returned a status byte.
                // Status bytes are always two bytes long.
                // Store this byte first and then read the next
                //
                replyBuffer[0] = procByte;

                *serialIoControlCode = SMARTCARD_READ;
                *replyLength = 1;
                bytesToSend = 0;
                bytesToRead = 0;

			replyBuffer[1] = *(SmartcardExtension->SmartcardReply.Buffer + 1) ;
				

                SmartcardExtension->SmartcardReply.BufferLength = 2;

	//DEBUGMSG(1,(TEXT("*replyBuffer = 0x%x\r\n"),*SmartcardExtension->SmartcardReply.Buffer));
	//DEBUGMSG(1,(TEXT("*replyBuffer+1 = 0x%x\r\n"),*(SmartcardExtension->SmartcardReply.Buffer+1)));
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!TLP3TransmitT0: <- SW1=%02x SW2=%02x\n"),
                    szDriverName,
                    replyBuffer[0], 
                    replyBuffer[1])
                    );
            }

        } while(bytesToSend || restartWorkWaitingTime);


        if (status != STATUS_SUCCESS)
            leave;

        if (bytesToRead != 0) {

            *serialIoControlCode = SMARTCARD_READ;
            *replyLength = bytesToRead;

            SmartcardExtension->SmartcardReply.Buffer = 
                replyBuffer;

            status = TLP3SerialIo(
                SmartcardExtension
                );
#if DBG || DEBUG
            if (status == STATUS_SUCCESS) {
                 
                SmartcardDebug(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -