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

📄 tlp3cb.c

📁 基于windows ce环境下对smart card 基于pc/sc架构下驱动例程
💻 C
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++


Module Name:

    tlp3cb.c

Abstract:

    Callback functions for smart card library

--*/
#include <stdio.h>
#include <smclib.h>
#include <devload.h>
#include <tchar.h>

#include "TLP3CE.h"
#include "BullTLP3.h"                            

NTSTATUS StarIccCommand(
	UCHAR Command,
	UCHAR CardNo,
	PSMARTCARD_EXTENSION SmartcardExtension);

NTSTATUS
TLP3ReaderPower(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

    The smart card lib requires to have this function. It is called 
    for certain power requests to the card. We do nothing here, because
    this action is performed in the StartIo function.

--*/
{
    ULONG step, waitTime,  numTry = 0, minWaitTime;
    NTSTATUS status = STATUS_SUCCESS;
    PREADER_EXTENSION pReaderExtension = SmartcardExtension->ReaderExtension;
    LARGE_INTEGER liProcessClock;

    RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPower: Enter\r\n")));

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3ReaderPower: Enter (%lx)\n"),
        szDriverName,
        SmartcardExtension->MinorIoControlCode)
        );

    _try {
         
        //
        // Set standard parameters for serial port
        // 
        pReaderExtension->SerialConfigData.SerialControlBlock.DCBlength=sizeof(DCB);
        pReaderExtension->SerialConfigData.SerialControlBlock.BaudRate=CBR_9600;
        pReaderExtension->SerialConfigData.SerialControlBlock.StopBits=ONESTOPBITS;
//        pReaderExtension->SerialConfigData.SerialControlBlock.fParity=1; // Even Pariry check
        pReaderExtension->SerialConfigData.SerialControlBlock.Parity=NOPARITY;
//        pReaderExtension->SerialConfigData.SerialControlBlock.fBinary=1; // Skip EOF; 8-bit binary data.
        pReaderExtension->SerialConfigData.SerialControlBlock.ByteSize=DATABITS_8;
        // Time out set.
        pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=READ_INTERVAL_TIMEOUT_DEFAULT;
        pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
            READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
        pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier=
            pReaderExtension->SerialConfigData.Timeouts.WriteTotalTimeoutMultiplier=0;

        status = TLP3ConfigureSerialPort(SmartcardExtension);

        ASSERT(status == STATUS_SUCCESS);

        if (status != STATUS_SUCCESS) {

            leave;
        }                     

        // We don't send data to the reader, so set Number of bytes to send = 0
        SmartcardExtension->SmartcardRequest.BufferLength = 0;

        // Default number of bytes we expect to get back
        SmartcardExtension->SmartcardReply.BufferLength = 0;

        //
        // Since power down triggers the UpdateSerialStatus function, we have
        // to inform it that we forced the change of the status and not the user
        // (who might have removed and inserted a card)
        //
        SmartcardExtension->ReaderExtension->PowerRequest = TRUE;
        SmartcardExtension->ReaderExtension->ModemStatusChanged=FALSE;

        // purge the serial buffer (it can contain the pnp id of the reader)
        status=(PurgeComm(pReaderExtension->hSerialPort,
            PURGE_RXCLEAR | PURGE_TXCLEAR))?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;

        ASSERT(status == STATUS_SUCCESS);

        if (status != STATUS_SUCCESS) {

            leave;
        }

        SmartcardExtension->CardCapabilities.ATR.Length = 0;

        step=(SmartcardExtension->MinorIoControlCode == SCARD_WARM_RESET)?4:0;
        for (; NT_SUCCESS(status); step++) {

            switch (step) {

                case 0:
                    // RTS = 0 means reader is in command mode
                    status=EscapeCommFunction(pReaderExtension->hSerialPort,
                        CLRRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
                    //
                    // This is the minimum wait time we have to wait before
                    // we can send commands to the microcontroller.
                    //
                    waitTime = 1000;
                    break;

                case 1:
					SmartcardExtension->SmartcardRequest.BufferLength = 0;
					SmartcardExtension->SmartcardReply.BufferLength=0;

				    RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerdown  begin \r\n")));

					status=StarIccCommand(0xe2,1,SmartcardExtension);

					RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerdown  end status = %d\r\n"),status));
					RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerdown  end replybuffer = %s\r\n"),SmartcardExtension->SmartcardReply.Buffer));

					if(status!=STATUS_SUCCESS)
					{
						leave;
					}

/*				
                    // write power down command to the reader
                    SmartcardExtension->ReaderExtension->SerialIoControlCode =
                        SMARTCARD_WRITE;
                    SmartcardExtension->SmartcardRequest.BufferLength =    1;

                    SmartcardExtension->SmartcardRequest.Buffer[0] = 
                        READER_CMD_POWER_DOWN;

                    waitTime = 100;
                    status=TLP3SerialIo( SmartcardExtension);
*/                    break;

				case 2:
/*
                    // Read back the echo of the reader
                    SmartcardExtension->ReaderExtension->SerialIoControlCode =
                        SMARTCARD_READ;
                    SmartcardExtension->SmartcardReply.BufferLength = 1;

                    // Wait the recovery time for the microcontroller 
                    waitTime = 1000;
                    status=TLP3SerialIo( SmartcardExtension);
*/
					break;

                case 3:
                    // set RTS again so the microcontroller can execute the command
                    status=EscapeCommFunction(pReaderExtension->hSerialPort,
                        SETRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
                    waitTime = 10000;
                    break;

                case 4:
                    if (SmartcardExtension->MinorIoControlCode == SCARD_POWER_DOWN) {

                        if (SmartcardExtension->ReaderCapabilities.CurrentState >
                            SCARD_PRESENT) {
                             
                            SmartcardExtension->ReaderCapabilities.CurrentState = 
                                SCARD_PRESENT;
                        }

                        SmartcardExtension->CardCapabilities.Protocol.Selected = 
                            SCARD_PROTOCOL_UNDEFINED;

                        SmartcardExtension->ReaderExtension->PowerRequest = FALSE;

                        status = STATUS_SUCCESS;                 
                        leave;
                    }

                    // clear RTS to switch to command mode
                    status=EscapeCommFunction(pReaderExtension->hSerialPort,
                        CLRRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
                    // Wait the recovery time for the microcontroller 
                    waitTime = 1000;
                    break;

                case 5:
                    // write the appropriate reset command to the reader
					
					SmartcardExtension->SmartcardRequest.BufferLength = 0;
//					SmartcardExtension->SmartcardReply.BufferLength=0;
					status=StarIccCommand(0xe1,1,SmartcardExtension);

					RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerup  end replybuffer = %s\r\n"),SmartcardExtension->SmartcardReply.Buffer));
					RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerUp  status=%d \r\n"),status));
					if(status!=STATUS_SUCCESS)
					{
						return status;
					}
					return STATUS_SUCCESS;

//                    status=TLP3SerialIo( SmartcardExtension);
//                    waitTime = 100;
                    break;

                case 6:
/*
                    // Read back the echo of the reader
                    SmartcardExtension->ReaderExtension->SerialIoControlCode =
                        SMARTCARD_READ;
                    SmartcardExtension->SmartcardReply.BufferLength = 1;

                    //
                    // This is the time we need to wait for the microcontroller
                    // to recover before we can set RTS again
                    //
                    status=TLP3SerialIo( SmartcardExtension);
                    waitTime = 1000;
*/                    break;

                case 7:
/*                    // set RTS again so the microcontroller can execute the command
                    status=EscapeCommFunction(pReaderExtension->hSerialPort,
                        SETRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
                    waitTime = 10000; 
*/                    break;

                case 8:
                    // Here we check the card or reader event is changed or not.
                    // if it is. it is better to aborted it. Otherwise. It take
                    // long time to timeout.
                    if (SmartcardExtension->ReaderExtension->ModemStatusChanged) {
                        status = STATUS_MEDIA_CHANGED;
                        leave;
                    };
                    //
                    // We now try to get the ATR as fast as possible.
                    // Therefor we prev. set a very short read timeout and
                    // expect that the card delivered its ATR within this 
                    // short time. To verify the correctness of the ATR we call
                    // SmartcardUpdateCardCapabilities(). If this call returns
                    // with STATUS_SUCCESS we know that the ATR is complete.
                    // Otherwise we read again and append the new data to the 
                    // ATR buffer in the CardCapabilities and try again.
                    //
                    SmartcardExtension->ReaderExtension->SerialIoControlCode = 
                        SMARTCARD_READ;

                    SmartcardExtension->SmartcardReply.BufferLength = 
                        MAXIMUM_ATR_LENGTH - 
                        SmartcardExtension->CardCapabilities.ATR.Length;
                    status=TLP3SerialIo( SmartcardExtension);
                    waitTime = 0;                                     
                    break;

                case 9:
                    if (SmartcardExtension->SmartcardReply.BufferLength != 0) {

                        ASSERT(
                            SmartcardExtension->CardCapabilities.ATR.Length +
                            SmartcardExtension->SmartcardReply.BufferLength <
                            MAXIMUM_ATR_LENGTH
                            );

                        if( SmartcardExtension->CardCapabilities.ATR.Length +
                            SmartcardExtension->SmartcardReply.BufferLength >=
                            MAXIMUM_ATR_LENGTH) {

                            status = STATUS_UNRECOGNIZED_MEDIA;
                            leave;
                        }
                     
                        // we got some ATR bytes. 
                        RtlCopyMemory(
                            SmartcardExtension->CardCapabilities.ATR.Buffer + 
                                SmartcardExtension->CardCapabilities.ATR.Length,
                            SmartcardExtension->SmartcardReply.Buffer,
                            SmartcardExtension->SmartcardReply.BufferLength
                            );

                        SmartcardExtension->CardCapabilities.ATR.Length += 
                            (UCHAR) SmartcardExtension->SmartcardReply.BufferLength;

                        status = SmartcardUpdateCardCapabilities(
                            SmartcardExtension
                            );

                        // Only retry if we got at least some bytes, but not the whole ATR
                        if (status != STATUS_SUCCESS && numTry < 10/*100*/) {

                            // ATR is incomplete. Try again to get ATR bytes.
                            numTry += 1;
                            // continue with step 8
                            step = 7;
                            status = STATUS_TIMEOUT;
                            continue;                         
                        }

                    }
                    if (status != STATUS_SUCCESS) {

                        leave;
                    }
                    // No break

                case 10:
                    if (SmartcardExtension->ReaderCapabilities.CurrentState <=
                        SCARD_ABSENT) {

                        status = STATUS_MEDIA_CHANGED;
                    } 
                    if (status != STATUS_SUCCESS) {

                        leave;                         
                    }

                    // Copy ATR to user space
                    if (SmartcardExtension->IoRequest.ReplyBuffer) {
                
                        RtlCopyMemory(
                            SmartcardExtension->IoRequest.ReplyBuffer,
                            SmartcardExtension->CardCapabilities.ATR.Buffer,
                            SmartcardExtension->CardCapabilities.ATR.Length
                            );

                        // Tell user length of ATR
                        *SmartcardExtension->IoRequest.Information =
                            SmartcardExtension->CardCapabilities.ATR.Length;
                    }

                    //
                    // If the card uses invers convention we need to switch
                    // the serial driver to odd paritiy
                    //
                    if (SmartcardExtension->CardCapabilities.InversConvention) {
                        //serialConfigData->LineControl.Parity = ODD_PARITY;
                        pReaderExtension->SerialConfigData.SerialControlBlock.fParity=1; // Even Pariry check
                        pReaderExtension->SerialConfigData.SerialControlBlock.Parity=ODDPARITY;
                    }

                    //
                    // If the extra guard time is 255 it means that our
                    // frame with have to expect from the card has only
                    // 1 instead of 2 stop bits 
                    // 1start bit + 8data bits + 1parity + 1stop == 11 etu
                    // see iso 7816-3 6.1.4.4 Extra Guard Time N
                    //
                    if (SmartcardExtension->CardCapabilities.PtsData.StopBits == 1) {
                        //serialConfigData->LineControl.StopBits = STOP_BIT_1;      
                        pReaderExtension->SerialConfigData.SerialControlBlock.StopBits=ONESTOPBIT;

                    }

                    // depending on the protocol set the timeout values
                    if (SmartcardExtension->CardCapabilities.Protocol.Selected &
                        SCARD_PROTOCOL_T1) {
                        // set timeouts
                        pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
                            (SmartcardExtension->CardCapabilities.T1.BWT +
                            MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
                        pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
                            (SmartcardExtension->CardCapabilities.T1.CWT +
                            MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;

⌨️ 快捷键说明

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