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

📄 smcprot.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        // we expect the card to reply with an ifs response.
        //
        if (SmartcardExtension->T1.State == T1_IFS_REQUEST) {

            // Check if the card properly responded to an ifs request
            if (t1RecFrame.Pcb == T1_IFS_RESPONSE) {

                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!SmartcardT1Reply:   T1_IFS_RESPONSE\n"),
                    DRIVER_NAME)
                    );

                // The smart card acked our ifsd size
                SmartcardExtension->T1.State = T1_I_BLOCK;
                leave;
            }

            if ((t1RecFrame.Pcb & 0x82) == 0x82) {

                //
                // The card does not support ifs request, so we stop 
                // sending this and continue with a data block
                // (the card is NOT ISO conform)
                //
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!SmartcardT1Reply:   Card does not support IFS REQUEST\n"),
                    DRIVER_NAME)
                    );

                SmartcardExtension->T1.State = T1_I_BLOCK;
                leave;
            }

            //
            // The card replied with junk to our ifs request.
            // It doesn't make sense to continue.
            //
            status = STATUS_DEVICE_PROTOCOL_ERROR;
            leave;
        }
    
        // 
        // If the last block was a resync. request,
        // we expect the card to answer with a resynch response.
        //
        if (SmartcardExtension->T1.State == T1_RESYNCH_REQUEST) {

            // Check if the card properly responded to an resynch request
            if (t1RecFrame.Pcb != T1_RESYNCH_RESPONSE) {
        
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!SmartcardT1Reply:   Card response is not ISO conform! Aborting...\n"),
                    DRIVER_NAME)
                    );

                status = STATUS_DEVICE_PROTOCOL_ERROR;
                leave;

            } 
            
            SmartcardDebug(
                DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Reply:   T1_RESYNCH_RESPONSE\n"),
                DRIVER_NAME)
                );

		    // Reset error counter
		    SmartcardExtension->T1.Resend = 0;

            // The smart card has successfully responded to a resynch request
            SmartcardExtension->T1.RSN = 0;
            SmartcardExtension->T1.SSN = 0;

			//
			// Do a complete restart of the whole transmission
			// but without resetting the resynch counter
            //
            SmartcardExtension->T1.State = T1_RESTART;
            leave;
        }

        //
        // Now check for other protocol states...
        //
    
        //
        // Copy NAD value back to user buffer if this is an extended io-header
        // containing the nad
        //
        if (IoHeader->ScardIoRequest.cbPciLength > sizeof(SCARD_IO_REQUEST) &&
            IoHeader->Asn1Data[0] == 0x81 &&
            IoHeader->Asn1Data[1] == 0x01 &&
            IoHeader->Asn1Data[3] == 0x00) {

            IoHeader->Asn1Data[2] = t1RecFrame.Nad;         	
        }

        if ((t1RecFrame.Pcb & 0x80) == 0) {

            // This is an I-block

            SmartcardDebug(
        	    DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Reply:   I(%d.%d) <-\n"),
                DRIVER_NAME,
                (t1RecFrame.Pcb & 0x40) >> 6,
			    (t1RecFrame.Pcb & 0x20)	>> 5)
                );

            if (((t1RecFrame.Pcb & 0x40) >> 6) == SmartcardExtension->T1.RSN) {

			    // I-Block with correct sequence number
    
                PUCHAR data;
                ULONG minBufferSize;

			    // Reset error counter and error indicator
	            SmartcardExtension->T1.Resend = 0;
                SmartcardExtension->T1.OriginalState = 0;

                // We can 'increase' the number of correctly received I-Blocks
                SmartcardExtension->T1.RSN ^= 1;

			    if (SmartcardExtension->T1.State == T1_I_BLOCK) {

				    // This I-Block is also an acknowledge for the I-Block we sent 
	                SmartcardExtension->T1.SSN ^= 1;
			    }
        
                // Check size of user buffer
                minBufferSize = 
                    IoHeader->ScardIoRequest.cbPciLength +
                    SmartcardExtension->T1.BytesReceived +
                    t1RecFrame.Len;
        
                if (SmartcardExtension->IoRequest.ReplyBufferLength < minBufferSize) {
            
                    status = STATUS_BUFFER_TOO_SMALL;
                    leave;
                }

                ASSERT(SmartcardExtension->T1.ReplyData);
                //
                // Let data pointer point behind struct.
                // All reply data will be stored there.
                // 
                data = 
                    SmartcardExtension->T1.ReplyData + 
                    IoHeader->ScardIoRequest.cbPciLength +
                    SmartcardExtension->T1.BytesReceived;

                // Copy data to user buffer
                RtlCopyMemory(
                    data,
                    t1RecFrame.Inf,
                    t1RecFrame.Len
                    );
              
                SmartcardExtension->T1.BytesReceived += t1RecFrame.Len;
        
                if (t1RecFrame.Pcb & T1_MORE_DATA) {
    
                    // Ack this block and request the next block
                    SmartcardExtension->T1.State = T1_R_BLOCK;
        
                } else {
        
                    //
                    // This was the last block of the transmission
                    // Set number of bytes returned by this transmission
                    //
                    *SmartcardExtension->IoRequest.Information = 
                        IoHeader->ScardIoRequest.cbPciLength + 
                        SmartcardExtension->T1.BytesReceived;

                    // Copy the result back to the user buffer
                    ASSERT(SmartcardExtension->IoRequest.ReplyBuffer != NULL);

                    RtlCopyMemory(
                        SmartcardExtension->IoRequest.ReplyBuffer,
                        SmartcardExtension->T1.ReplyData,
                        IoHeader->ScardIoRequest.cbPciLength +
                            SmartcardExtension->T1.BytesReceived                        
                        );
        
                    status = STATUS_SUCCESS;
                }
                leave;
            }

            //
		    // I-Block with wrong sequence number
		    // We try T1_MAX_RETRIES times to resend the last block.
		    // If this is unsuccessfull, we try to resynch.
		    // If resynch is unsuccessfull we abort the transmission.
		    //
            SmartcardDebug(
        	    DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Reply: Block number incorrect\n"),
                DRIVER_NAME)
                );

		    SmartcardExtension->T1.LastError = T1_ERROR_OTHER;

            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
	            SmartcardExtension->T1.State = T1_RESYNCH_REQUEST;
                leave;
            }

            // request the block again.
	        SmartcardExtension->T1.State = T1_R_BLOCK;
            leave;
        } 
    
        if ((t1RecFrame.Pcb & 0xC0) == 0x80) {

            // This is an R-block

		    UCHAR RSN = (t1RecFrame.Pcb & 0x10) >> 4;
    
            SmartcardDebug(
        	    DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Reply:   R(%d) <-\n"),
                DRIVER_NAME,
                RSN)
                );
    
            if (RSN != SmartcardExtension->T1.SSN &&  
                SmartcardExtension->T1.MoreData) {
    
                // The ICC has acked the last block
	            SmartcardExtension->T1.Resend = 0;

                SmartcardExtension->T1.BytesSent += SmartcardExtension->T1.InfBytesSent;
                SmartcardExtension->T1.BytesToSend -= SmartcardExtension->T1.InfBytesSent;
                SmartcardExtension->T1.SSN ^= 1;
                SmartcardExtension->T1.State = T1_I_BLOCK;

                leave;
		    } 

            //
            // We have an error condition...
            //

            ASSERT(t1RecFrame.Pcb & 0x0f);
            
            if ((t1RecFrame.Pcb & 0x02) && 
                SmartcardExtension->T1.State == T1_IFS_REQUEST) {

                //
                // The card does not support ifs request, so 
                // we stop sending this and continue with a data block
                // (the card is NOT ISO conform)
                //
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!SmartcardT1Reply:   Card does not support IFS REQUEST\n"),
                    DRIVER_NAME)
                    );

                SmartcardExtension->T1.State = T1_I_BLOCK;
                leave;
            } 

    	    // We have to resend the last block
            SmartcardDebug(
                DEBUG_PROTOCOL,
                (TEXT("%s!SmartcardT1Reply:   Card reports error\n"),
                DRIVER_NAME)
                );

            if (SmartcardExtension->T1.Resend++ == T1_MAX_RETRIES) {

                SmartcardExtension->T1.Resend = 0;
    
                if (SmartcardExtension->T1.OriginalState == 0) {
                
					// Save current state
					SmartcardExtension->T1.OriginalState = 
						SmartcardExtension->T1.State;
                }

	            // Try to resynchronize
	            SmartcardExtension->T1.State = T1_RESYNCH_REQUEST;
            } 
            leave;        
        } 

        //
        // This is an S-block
        // 

        switch (t1RecFrame.Pcb) {

            case T1_IFS_REQUEST:
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!SmartcardT1Reply:   T1_IFS_REQUEST\n"),
                    DRIVER_NAME)
                    );

                // The smart card wants to exend the IFS - size
                SmartcardExtension->T1.IFSC = 
                    SmartcardExtension->SmartcardReply.Buffer[3];
       
		        // Save current state
			    ASSERT(SmartcardExtension->T1.OriginalState == 0);

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

                SmartcardExtension->T1.State = T1_IFS_RESPONSE;
                break;
        
            case T1_ABORT_REQUEST:
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!SmartcardT1Reply:   T1_ABORT_REQUEST\n"),
                    DRIVER_NAME)
                    );

                SmartcardExtension->T1.State = T1_ABORT_RESPONSE;
                break;
        
            case T1_WTX_REQUEST:
                SmartcardDebug(
                    DEBUG_PROTOCOL,
                    (TEXT("%s!SmartcardT1Reply:   T1_WTX_REQUEST\n"),
                    DRIVER_NAME)
                    );
            
                // Smart card needs longer wait time
                SmartcardExtension->T1.Wtx = 
                    SmartcardExtension->SmartcardReply.Buffer[3];

		        // Save current state
			    ASSERT(SmartcardExtension->T1.OriginalState == 0);

		        SmartcardExtension->T1.OriginalState =
		            SmartcardExtension->T1.State;
            
                SmartcardExtension->T1.State = T1_WTX_RESPONSE;
			    break;
        
            case T1_VPP_ERROR:
                SmartcardDebug(
                    DEBUG_ERROR,
                    (TEXT("%s!SmartcardT1Reply:   T1_VPP_ERROR\n"),
                    DRIVER_NAME)
                    );

                status = STATUS_DEVICE_POWER_FAILURE;
                break;

		    default:
			    ASSERTMSG(
				    TEXT("SmartcardT1Reply: Invalid Pcb "),
				    FALSE
				    );

                status = STATUS_DEVICE_PROTOCOL_ERROR;
                break;
        }
    }
    finally {
     	
#if DBG
        if (packetOk && chksumOk) {
         	
            DumpT1Block(
	            SmartcardExtension->SmartcardReply.Buffer,
                SmartcardExtension->CardCapabilities.T1.EDC
	            );
        }
#endif

        if (SmartcardExtension->T1.State == T1_RESYNCH_REQUEST && 
            SmartcardExtension->T1.Resynch++ == T1_MAX_RETRIES) {
    
            SmartcardDebug(
                DEBUG_ERROR,
                (TEXT("%s!SmartcardT1Reply: Too many errors! Aborting...\n"),
                DRIVER_NAME)
                );

		    status = STATUS_DEVICE_PROTOCOL_ERROR;
        }
            
        if (status != STATUS_MORE_PROCESSING_REQUIRED) {

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

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

            if (SmartcardExtension->T1.ReplyData) {
             	
                // free the reply data buffer
#ifdef SMCLIB_VXD
                _HeapFree(SmartcardExtension->T1.ReplyData, 0);
#elif defined(SMCLIB_CE)
                LocalFree(SmartcardExtension->T1.ReplyData);
#else               
                
                ExFreePool(SmartcardExtension->T1.ReplyData);
#endif
                SmartcardExtension->T1.ReplyData = NULL;             	
            }
            SmartcardExtension->T1.OriginalState = 0;
            SmartcardExtension->T1.NAD = 0;
        }

    }
    return status;
}

#if DBG
#pragma optimize( "", on )
#endif                              

⌨️ 快捷键说明

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