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

📄 tlp3cb.c

📁 基于windows ce环境下对smart card 基于pc/sc架构下驱动例程
💻 C
📖 第 1 页 / 共 4 页
字号:
        // is Le + 2 status bytes
        //
        bytesToSend = *requestLength;
        bytesToRead = SmartcardExtension->T0.Le + 2;

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

		SmartcardExtension->SmartcardRequest.BufferLength = bytesToSend;
		SmartcardExtension->SmartcardReply.BufferLength=bytesToRead;
		status=StarIccCommand(0xe3,1,SmartcardExtension);
		RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3TransmitT0   status = %d\r\n"),status));
		RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3TransmitT0   replybuffer = %s\r\n"),SmartcardExtension->SmartcardReply.Buffer));
		if(status!=STATUS_SUCCESS)
		{
			return status;
		}

//lbq change
/*
        //
        // 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)
                    leave;

                //
                // The TLP3 echos all sent bytes. We read the echo 
                // back into our send buffer
                //
                *serialIoControlCode = SMARTCARD_READ;
                *replyLength = *requestLength;
                SmartcardExtension->SmartcardReply.Buffer = &requestBuffer[currentByte];
                                                    
                status = TLP3SerialIo(
                    SmartcardExtension
                    );

                if (status != STATUS_SUCCESS)
                    leave;

                currentByte += *requestLength;
                bytesToSend -= *requestLength;
            }

            // 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;

                //
                // Read in the second status byte
                //
                SmartcardExtension->SmartcardReply.Buffer = 
                    &replyBuffer[1];

                status = TLP3SerialIo(
                    SmartcardExtension
                    );

                SmartcardExtension->SmartcardReply.BufferLength = 2;

                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(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!TLP3TransmitT0: <- Data %ld bytes, SW1=%02x SW2=%02x\n"),
                    szDriverName,
                    bytesToRead,
                    replyBuffer[bytesToRead - 2], 
                    replyBuffer[bytesToRead - 1])
                    );
            }
#endif
        }
    }
    finally {

        // Restore pointers to their original location
        SmartcardExtension->SmartcardRequest.Buffer = 
            requestBuffer;

        SmartcardExtension->SmartcardReply.Buffer = 
            replyBuffer;

        if (status == STATUS_TIMEOUT) {

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

        if (status == STATUS_SUCCESS) {
             
            status = SmartcardT0Reply(
                SmartcardExtension
                );
        }
    }

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3TransmitT0: Exit(%lx)\n"),
        szDriverName,
        status)
        );
*/
    return status;
}    

NTSTATUS
TLP3Transmit(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

    This function is called by the smart card library whenever a transmission
    is required. 

Arguments:

    SmartcardExtension - Pointer to smart card data struct.

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS status;

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

    _try {
         
        status=(PurgeComm(SmartcardExtension->ReaderExtension->hSerialPort,
            PURGE_RXCLEAR | PURGE_TXCLEAR))?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
        if (status != STATUS_SUCCESS) 
            leave;

        do {

            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;

            //
            // Tell the lib function how many bytes I need for the prologue
            //
//            *requestLength = 0;

            switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {

                case SCARD_PROTOCOL_RAW:
                    status = SmartcardRawRequest(SmartcardExtension);
                    break;

                case SCARD_PROTOCOL_T0:
                    //
                    // T=0 requires a bit more work.
                    // So we do this in a seperate function.
                    //
                    status = TLP3TransmitT0(SmartcardExtension);
                    leave;
                    
                case SCARD_PROTOCOL_T1:
                    status = TLP3TransmitT0(SmartcardExtension);
                    leave;
//                    status = SmartcardT1Request(SmartcardExtension);
//                    break;

                default:
                    status = TLP3TransmitT0(SmartcardExtension);
                    leave;
//                    status = STATUS_INVALID_DEVICE_REQUEST;
//                    leave;
                    
            }

            if (status != STATUS_SUCCESS) {

                leave;
            }

            //
            // Write the command to the card
            //
            *replyLength = 0;
            *serialIoControlCode = SMARTCARD_WRITE;

            status = TLP3SerialIo(SmartcardExtension);

            if (status != STATUS_SUCCESS) {

                leave;
            }

            //
            // The Bull reader always echos the bytes sent, so read that echo back
            //
            *serialIoControlCode = SMARTCARD_READ;
            *replyLength = *requestLength;

            status = TLP3SerialIo(SmartcardExtension);

            if (status != STATUS_SUCCESS) {

                leave;
            }

            switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {

                case SCARD_PROTOCOL_RAW:
                    status = SmartcardRawReply(SmartcardExtension);
                    break;

                case SCARD_PROTOCOL_T1:
                    //
                    // Check if the card requested a waiting time extension
                    //
                    if (SmartcardExtension->T1.Wtx) {
                        DWORD dwMilliSecond=
                            (SmartcardExtension->T1.Wtx * SmartcardExtension->CardCapabilities.T1.BWT) 
                            /MICROSECONDS_PER_MILLISECOND;
                        Sleep(dwMilliSecond);
                    }

                    //
                    // Read NAD, PCB and LEN fields
                    //
                    *replyLength = 3;

                    status = TLP3SerialIo(SmartcardExtension);

                    // 
                    // Check for timeout first. If the card did not reply 
                    // we need to send a resend request
                    //
                    if (status != STATUS_TIMEOUT) {

                        if (status != STATUS_SUCCESS) {

                            leave;
                        }

                        //

⌨️ 快捷键说明

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