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

📄 smcprot.c

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

            } else {
             	
                SmartcardExtension->T1.State = T1_I_BLOCK;
            }

            // No break here !!
            
        case T1_I_BLOCK:
            SmartcardExtension->T1.State = T1_I_BLOCK;

            //
            // Set the number of bytes we will transmit to the card.
            // This is the lesser of IFSD and IFSC
            //
            SmartcardExtension->T1.InfBytesSent = SmartcardExtension->T1.IFSC;
    
            if (SmartcardExtension->T1.InfBytesSent > SmartcardExtension->T1.IFSD) {

                SmartcardExtension->T1.InfBytesSent = SmartcardExtension->T1.IFSD;
            }

            // Send either max frame size or remaining bytes
            if (SmartcardExtension->T1.BytesToSend > SmartcardExtension->T1.InfBytesSent) {
            	
				SmartcardExtension->T1.MoreData = TRUE;
                t1SendFrame.Len = SmartcardExtension->T1.InfBytesSent;

            } else {

            	SmartcardExtension->T1.MoreData = FALSE;             	
                t1SendFrame.Len = (UCHAR) SmartcardExtension->T1.BytesToSend;
            }
                
            t1SendFrame.Nad = SmartcardExtension->T1.NAD;

            //
            // ProtocolControlByte:
            //      b7 - SendSequenceNumber
            //      b6 - MoreDatatBit
            //
            t1SendFrame.Pcb = 
                (SmartcardExtension->T1.SSN) << 6 |
                (SmartcardExtension->T1.MoreData ? T1_MORE_DATA : 0);
            
            t1SendFrame.Inf = 
                SmartcardExtension->IoRequest.RequestBuffer + 
                IoHeader->ScardIoRequest.cbPciLength +
                SmartcardExtension->T1.BytesSent;

            SmartcardDebug(
        		DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Request: I(%d.%d) ->\n"),
                DRIVER_NAME,
			   	SmartcardExtension->T1.SSN,
                (SmartcardExtension->T1.MoreData ? 1 : 0))
                );
            break; 
            
        case T1_R_BLOCK:
            SmartcardDebug(
        		DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Request: R(%d) ->\n"),
                DRIVER_NAME,
			   	SmartcardExtension->T1.RSN)
                );

            t1SendFrame.Nad = SmartcardExtension->T1.NAD;
            //
            // ProtocolControlByte:
            //      b5 -    SequenceNumber
            //      b1-4 -  ErrorCode
            //
            t1SendFrame.Pcb = 
                0x80 | 
                (SmartcardExtension->T1.RSN) << 4 |
                (SmartcardExtension->T1.LastError);
            
			//
			// If this R-Block is a response to an error
			// we have to restore to the original state we had before 
			//
			if (SmartcardExtension->T1.LastError) {

				SmartcardExtension->T1.LastError = 0;

				//
				// We must have a defined original state here
				//
				ASSERT(SmartcardExtension->T1.OriginalState != 0);

                if (SmartcardExtension->T1.OriginalState == 0) {

                    SmartcardExtension->T1.State = T1_START;
                    return STATUS_INTERNAL_ERROR;                 	
                }

				SmartcardExtension->T1.State = 
					SmartcardExtension->T1.OriginalState;
			}
                
            t1SendFrame.Len = 0;
            t1SendFrame.Inf = NULL;
            break;    

        case T1_IFS_RESPONSE:
            SmartcardDebug(
        		DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Request: T1_IFS_RESPONSE\n"),
                DRIVER_NAME)
                );
                
			// Restore to the original state we had before
			ASSERT(SmartcardExtension->T1.OriginalState != 0);

            if (SmartcardExtension->T1.OriginalState == 0) {
             	
			    SmartcardExtension->T1.State = 
				    SmartcardExtension->T1.OriginalState;
            }

            t1SendFrame.Nad = SmartcardExtension->T1.NAD;

            // Send IFS response
            t1SendFrame.Pcb = 0xE1;
            t1SendFrame.Len = 1;

            // New length of INF-Field
            t1SendFrame.Inf = &SmartcardExtension->T1.IFSC;
            break;    
            
        case T1_RESYNCH_REQUEST:
            SmartcardDebug(
        		DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Request: T1_RESYNCH_REQUEST\n"),
                DRIVER_NAME)
                );

            t1SendFrame.Nad = SmartcardExtension->T1.NAD;

            // Resynch request
            t1SendFrame.Pcb = 0xC0;
            t1SendFrame.Len = 0;
            t1SendFrame.Inf = NULL;

            // Set the send sequence number to 0
            SmartcardExtension->T1.SSN = 0;    
            break;
            
        case T1_ABORT_REQUEST:
            SmartcardDebug(
        		DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Request: T1_ABORT_REQUEST\n"),
                DRIVER_NAME)
                );
                
            t1SendFrame.Nad = SmartcardExtension->T1.NAD;

            // Send ABORT request
            t1SendFrame.Pcb = 0xC2;
            t1SendFrame.Len = 0;
            t1SendFrame.Inf = NULL;
            break;    
            
        case T1_ABORT_RESPONSE:
            SmartcardDebug(
        		DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Request: T1_ABORT_RESPONSE\n"),
                DRIVER_NAME)
                );
			SmartcardExtension->T1.State = T1_START;
                
            t1SendFrame.Nad = SmartcardExtension->T1.NAD;

            // Send ABORT response
            t1SendFrame.Pcb = 0xE2;
            t1SendFrame.Len = 0;
            t1SendFrame.Inf = NULL;
            break;    
            
        case T1_WTX_RESPONSE:
            SmartcardDebug(
        		DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Request: T1_WTX_RESPONSE\n"),
                DRIVER_NAME)
                );

			// Restore to the original state we had before
			ASSERT(SmartcardExtension->T1.OriginalState != 0);

			SmartcardExtension->T1.State = 
				SmartcardExtension->T1.OriginalState;

            t1SendFrame.Nad = SmartcardExtension->T1.NAD;

            // Send WTX response
            t1SendFrame.Pcb = 0xE3;
            t1SendFrame.Len = 1;
            t1SendFrame.Inf = &SmartcardExtension->T1.Wtx;
            break;    
        default:
            SmartcardDebug(
        		DEBUG_ERROR,
                (TEXT("%s!SmartcardT1Request: Invalid State %d\n"),
                DRIVER_NAME, SmartcardExtension->T1.State)
                );
            return STATUS_INVALID_DEVICE_STATE;
    }

    // Insert Node Address byte
    smartcardRequest->Buffer[smartcardRequest->BufferLength] = 
        t1SendFrame.Nad;
        
    // Insert ProtocolControlByte
    smartcardRequest->Buffer[smartcardRequest->BufferLength + 1] = 
        t1SendFrame.Pcb;
        
    // Length of INF field
    smartcardRequest->Buffer[smartcardRequest->BufferLength + 2] = 
        t1SendFrame.Len;

    // Insert INF field data
    if (t1SendFrame.Len > 0) {
    
        RtlCopyMemory(
            &smartcardRequest->Buffer[smartcardRequest->BufferLength + 3],
            t1SendFrame.Inf,
            t1SendFrame.Len
        );
    }

    // Compute checksum
    SmartcardT1Chksum(
        &smartcardRequest->Buffer[smartcardRequest->BufferLength],
        SmartcardExtension->CardCapabilities.T1.EDC,
        FALSE
        );

#if (DBG || DEBUG)
#if !defined(SMCLIB_VXD) && !defined(SMCLIB_CE)
    if (SmartcardGetDebugLevel() & DEBUG_T1_TEST) {
    
        LARGE_INTEGER Ticks;
        UCHAR RandomVal;
        KeQueryTickCount(&Ticks);

        RandomVal = (UCHAR) Ticks.LowPart % 4;

        if (RandomVal == 0) {

            smartcardRequest->Buffer[smartcardRequest->BufferLength - 1] += 1;

            SmartcardDebug(
                DEBUG_ERROR,
                (TEXT("%s!SmartcardT1Request: Simulating bad checksum\n"),
                DRIVER_NAME)
                );
        }

    }
#endif

	DumpT1Block(
		smartcardRequest->Buffer + headerSize,
        SmartcardExtension->CardCapabilities.T1.EDC
		);
#endif

	//
	// If the card uses invers convention invert the data
	// NOTE: do not invert any header data the reader may use
    //
	if (SmartcardExtension->CardCapabilities.InversConvention) {

		SmartcardInvertData(
			&smartcardRequest->Buffer[smartcardRequest->BufferLength],
    		(SmartcardExtension->CardCapabilities.T1.EDC & T1_CRC_CHECK ? 5 : 4) +
			t1SendFrame.Len
			);
	}

	//
	// Update the number of bytes that are in the buffer
	// A T1 block is at least 4 bytes long with LRC check and 5 bytes with CRC check
	//
	smartcardRequest->BufferLength +=
		(SmartcardExtension->CardCapabilities.T1.EDC & T1_CRC_CHECK ? 5 : 4) +
		t1SendFrame.Len;

	return STATUS_SUCCESS;
}        

NTSTATUS
#ifdef SMCLIB_VXD
SMCLIB_SmartcardT1Reply(
#else
SmartcardT1Reply(
#endif
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++                     
                         
 Routine Description:
 
 Arguments:
 
    DeviceObject - Supplies a pointer to the device object for this request.
    
 Return Value:
                         
--*/
    
{
    T1_BLOCK_FRAME t1RecFrame;
	NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
    PIO_HEADER IoHeader = (PIO_HEADER) SmartcardExtension->T1.ReplyData;
    BOOLEAN packetOk = TRUE, chksumOk = TRUE;


    // signal that we received an answer
    SmartcardExtension->T1.WaitForReply = FALSE;

    // Invert the data of an inverse convention card
	if (SmartcardExtension->CardCapabilities.InversConvention) {

		SmartcardInvertData(
			SmartcardExtension->SmartcardReply.Buffer,
	        SmartcardExtension->SmartcardReply.BufferLength
			);
	}

	// Clear waiting time extension
	SmartcardExtension->T1.Wtx = 0;

    try {                

        ULONG expectedLength = 
            SCARD_T1_PROLOGUE_LENGTH +
            SmartcardExtension->SmartcardReply.Buffer[2] +
		    (SmartcardExtension->CardCapabilities.T1.EDC & T1_CRC_CHECK ? 2 : 1);

        if (SmartcardExtension->SmartcardReply.BufferLength < 4 ||
            SmartcardExtension->SmartcardReply.BufferLength != expectedLength) {

            SmartcardDebug(
                DEBUG_ERROR,
                (TEXT("%s!SmartcardT1Reply: Packet length incorrect\n"),
                DRIVER_NAME)
                );

            packetOk = FALSE;

        } else {
         	
            // calculate the checksum
            chksumOk = SmartcardT1Chksum(
                SmartcardExtension->SmartcardReply.Buffer,
                SmartcardExtension->CardCapabilities.T1.EDC,
                TRUE
                );

#if DBG
#ifndef SMCLIB_VXD
            if (SmartcardGetDebugLevel() & DEBUG_T1_TEST) {

                // inject some checksum errors

                LARGE_INTEGER Ticks;
                UCHAR RandomVal;
                KeQueryTickCount(&Ticks);

                RandomVal = (UCHAR) Ticks.LowPart % 4;

                if (RandomVal == 0) {

                    chksumOk = FALSE;

                    SmartcardDebug(
                        DEBUG_ERROR,
                        (TEXT("%s!SmartcardT1Reply: Simulating bad checksum\n"),
                        DRIVER_NAME)
                        );
                }
            }
#endif
#endif
        }

        if (chksumOk == FALSE) {

            SmartcardDebug(
    		    DEBUG_ERROR,
                (TEXT("%s!SmartcardT1Reply: Bad checksum\n"), 
                DRIVER_NAME)
                );
        }

        if (packetOk == FALSE || chksumOk == FALSE) {

		    SmartcardExtension->T1.LastError = 
			    (chksumOk ? T1_ERROR_OTHER : T1_ERROR_CHKSUM);

		    if (SmartcardExtension->T1.OriginalState == 0) {

			    SmartcardExtension->T1.OriginalState = 
                    SmartcardExtension->T1.State;
		    }
        
            if (SmartcardExtension->T1.Resend++ == T1_MAX_RETRIES) {
        
                SmartcardExtension->T1.Resend = 0;
            
                // Try to resynchronize since the resend requests have failed
                SmartcardExtension->T1.State = T1_RESYNCH_REQUEST;
                leave;

            } 
            
            // If the last request was a resynch we try again to resynch
            if (SmartcardExtension->T1.State != T1_RESYNCH_REQUEST) {
        
                // Chksum not OK; request resend of last block
                SmartcardExtension->T1.State = T1_R_BLOCK;
            }
            leave;
        }

	    //
	    // The checksum of the packet is ok.
	    // Now check the rest of the packet
	    //

	    // Clear the last error
	    SmartcardExtension->T1.LastError = 0;

        t1RecFrame.Nad = SmartcardExtension->SmartcardReply.Buffer[0];
        t1RecFrame.Pcb = SmartcardExtension->SmartcardReply.Buffer[1];
        t1RecFrame.Len = SmartcardExtension->SmartcardReply.Buffer[2];
        t1RecFrame.Inf = &SmartcardExtension->SmartcardReply.Buffer[3];

        // 
        // If the last block we sent was a ifs request, 

⌨️ 快捷键说明

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