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

📄 smcutil.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            status = STATUS_UNRECOGNIZED_MEDIA;
            leave;
        }
    }
    finally {

        if (status != STATUS_SUCCESS) {

            if (cardCapabilities->InversConvention == TRUE) {

    		    SmartcardInvertData(
                    cardCapabilities->ATR.Buffer, 
                    cardCapabilities->ATR.Length
                    );             	

        		cardCapabilities->InversConvention = FALSE;
            }

        }
    }

    if (status != STATUS_SUCCESS)
        return status;
        
    // store historical characters
	RtlCopyMemory(
		cardCapabilities->HistoricalChars.Buffer,
		atrString,
		cardCapabilities->HistoricalChars.Length
		);

    //
	// Now convert TA - TD values to global interface bytes
    //

	// Clock rate conversion
	cardCapabilities->Fl = (TA[0] & 0xf0) >> 4;

	// bit rate adjustment
	cardCapabilities->Dl = (TA[0] & 0x0f);

	// Maximum programming current factor
	cardCapabilities->II = (TB[0] & 0xc0) >> 6;

	// Programming voltage in 0.1 Volts
	cardCapabilities->P = (TB[1] ? TB[1] : (TB[0] & 0x1f) * 10);

	// Extra guard time
	cardCapabilities->N = TC[0];

	//
	// Check if the Dl and Fl values are valid
	// 
	if (BitRateAdjustment[cardCapabilities->Dl].DNumerator == 0 ||
		ClockRateConversion[cardCapabilities->Fl].F == 0) {

        SmartcardDebug(
            DEBUG_ATR,
            (TEXT("   Dl = %02x or Fl = %02x invalid\n"),
            cardCapabilities->Dl,
            cardCapabilities->Fl)
            );

        return STATUS_UNRECOGNIZED_MEDIA;
	}

   ASSERT(readerCapabilities->CLKFrequency.Max != 0);
    ASSERT(readerCapabilities->CLKFrequency.Default != 0);

    SmartcardDebug(
        DEBUG_ATR,
        (TEXT("   Card parameters from ATR:\n      Fl = %02x (%ld KHz), Dl = %02x, I = %02x, P = %02x, N = %02x\n"),
        cardCapabilities->Fl,
        ClockRateConversion[cardCapabilities->Fl].fs / 1000,
        cardCapabilities->Dl,
        cardCapabilities->II,
        cardCapabilities->P,
        cardCapabilities->N)
        );

    //
    // assume default clock frequency
    //
    fs = readerCapabilities->CLKFrequency.Default * 1000l;
    if (fs == 0) {

        fs = 372 * 9600l;
    }

    if (cardCapabilities->PtsData.Type == PTS_TYPE_DEFAULT) {

        //
        // Assume default parameters
        //
        cardCapabilities->PtsData.Fl = 1;
        cardCapabilities->PtsData.Dl = 1;

        cardCapabilities->PtsData.DataRate = 
            readerCapabilities->DataRate.Default;

        cardCapabilities->PtsData.CLKFrequency = 
            readerCapabilities->CLKFrequency.Default;
    }

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

        //
        // Try to find optimal parameters:
        // Highest possible clock frequency of the card 
        // combined with fastes data rate
        //

        //
        // We now try to find a working Fl and Dl combination
        //

        if (cardCapabilities->PtsData.Type == PTS_TYPE_OPTIMAL) {
         	
            cardCapabilities->PtsData.Fl = cardCapabilities->Fl;
        }

        ASSERT(cardCapabilities->PtsData.Fl < 16);
        ASSERT(ClockRateConversion[cardCapabilities->PtsData.Fl].F);

        if (cardCapabilities->PtsData.Fl > 15 ||
            ClockRateConversion[cardCapabilities->PtsData.Fl].F == 0) {

            return STATUS_INVALID_PARAMETER;
        }

        do {
            
            ULONG cardFreq;

            if (readerCapabilities->CLKFrequenciesSupported.Entries == 0 ||
                readerCapabilities->CLKFrequenciesSupported.List == NULL) {

                //
                // The clock freq. list supplied by the reader is empty
                // We take the standard values supplied by the reader
                //
                readerCapabilities->CLKFrequenciesSupported.List =
                    &readerCapabilities->CLKFrequency.Default;

                readerCapabilities->CLKFrequenciesSupported.Entries = 2;
            }

            //
            // Find the highest possible clock freq. supported 
            // by the card and the reader
            //
            cardFreq = 
                ClockRateConversion[cardCapabilities->PtsData.Fl].fs / 
                1000;

            cardCapabilities->PtsData.CLKFrequency = 0;

            for (i = 0; i < readerCapabilities->CLKFrequenciesSupported.Entries; i++) {

                // look for highes possible reader frequency
                if (readerCapabilities->CLKFrequenciesSupported.List[i] > 
                    cardCapabilities->PtsData.CLKFrequency &&
                    readerCapabilities->CLKFrequenciesSupported.List[i] <= 
                    cardFreq) {

                    cardCapabilities->PtsData.CLKFrequency =
                        readerCapabilities->CLKFrequenciesSupported.List[i];
                }
            }

            fs = cardCapabilities->PtsData.CLKFrequency * 1000;
            cardCapabilities->PtsData.DataRate = 0;

            ASSERT(fs != 0);
            if (fs == 0) {

                return STATUS_INVALID_PARAMETER;             	
            }

            if (cardCapabilities->PtsData.Type == PTS_TYPE_OPTIMAL) {
         	    
                cardCapabilities->PtsData.Dl = cardCapabilities->Dl;
            }
            ASSERT(cardCapabilities->PtsData.Dl < 16);
            ASSERT(BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator);

            if (cardCapabilities->PtsData.Dl > 15 ||
                BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator == 0) {

                return STATUS_INVALID_PARAMETER;
            }

            if (readerCapabilities->DataRatesSupported.Entries == 0 ||
                readerCapabilities->DataRatesSupported.List == NULL) {

                //
                // The data rate list supplied by the reader is empty.
                // We take the standard min/max values of the reader
                //
                readerCapabilities->DataRatesSupported.List =
                    &readerCapabilities->DataRate.Default;

                readerCapabilities->DataRatesSupported.Entries = 2;
            }

            //
            // Now try to find the highest possible matching data rate
            // (A matching data rate is one that VERY close 
            // to one supplied by the reader)
            //
            while(cardCapabilities->PtsData.Dl > 1) {

                ULONG dataRate;

                //
                // Calculate the data rate using the current values
                //
                dataRate = 
                    (BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator * 
                    fs) / 
                    (BitRateAdjustment[cardCapabilities->PtsData.Dl].DDivisor * 
                    ClockRateConversion[cardCapabilities->PtsData.Fl].F);

                //
                // Try to find a matching data rate
                //
                for (i = 0; i < readerCapabilities->DataRatesSupported.Entries; i++) {

                    if (readerCapabilities->DataRatesSupported.List[i] * 101 > dataRate * 100 &&
                        readerCapabilities->DataRatesSupported.List[i] * 99 < dataRate * 100) {

                        cardCapabilities->PtsData.DataRate = 
                            readerCapabilities->DataRatesSupported.List[i];

                        break;                         	
                    }
                }

                if (cardCapabilities->PtsData.DataRate) {

                    break;                 	
                }

                //
                // Select the next valid lower D value
                //
                while (BitRateAdjustment[--cardCapabilities->PtsData.Dl].DNumerator == 0)
                    ;
            }
                 
            if (cardCapabilities->PtsData.Fl == 1 && 
                cardCapabilities->PtsData.Dl == 1) {

                cardCapabilities->PtsData.DataRate =
                    readerCapabilities->DataRate.Default;                    

                cardCapabilities->PtsData.CLKFrequency = 
                    readerCapabilities->CLKFrequency.Default;

                break;
            }

            if (cardCapabilities->PtsData.DataRate) {

                break;                 	
            }
            //
            // Select the next valid lower F value
            //
            while (ClockRateConversion[--cardCapabilities->PtsData.Fl].F == 0)
                ;

        } while(cardCapabilities->PtsData.DataRate == 0);
    }

    ASSERT(fs != 0);
    ASSERT(cardCapabilities->PtsData.Dl < 16);
    ASSERT(BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator != 0);

    //
    // We calculate the ETU on basis of the timing supplied by the 
    // clk-frequency of the reader
    //
    //
    // Work etu in units of time resolution(TR) (NOT in seconds)
    //
    cardCapabilities->etu = 
        1 +     // required to round up
   		(TR * 
   		BitRateAdjustment[cardCapabilities->PtsData.Dl].DDivisor *
		ClockRateConversion[cardCapabilities->PtsData.Fl].F) /
   		(BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator * 
        fs);

    //
	// guard time in micro seconds
    // the guard time is the gap between the end of the
    // current character and the beginning of the next character
    //
    cardCapabilities->GT = 0;

    if (cardCapabilities->N == 0) {

        cardCapabilities->PtsData.StopBits = 2;

    } else if (cardCapabilities->N == 255) {

        cardCapabilities->PtsData.StopBits = 1;   	

    } else {
     	
	    cardCapabilities->GT = cardCapabilities->N * cardCapabilities->etu;
    }

    SmartcardDebug(
        DEBUG_ATR,
        (TEXT("   PTS parameters (%s):\n      Fl = %02x (%ld KHz), Dl = %02x (%ld Bps, %d Stop Bits)\n"),
        ptsType[cardCapabilities->PtsData.Type],
        cardCapabilities->PtsData.Fl,
        cardCapabilities->PtsData.CLKFrequency,
        cardCapabilities->PtsData.Dl,
        cardCapabilities->PtsData.DataRate,
        cardCapabilities->PtsData.StopBits)
        );

    SmartcardDebug(
        DEBUG_ATR,
        (TEXT("   Calculated timing values:\n      Work etu = %ld micro sec, Guard time = %ld micro sec\n"),
        cardCapabilities->etu,
        cardCapabilities->GT)
        );

	if (TA2Present || numProtocols <= 1 && cardCapabilities->Fl == 1 && cardCapabilities->Dl == 1) {

		//
		// If the card supports only one protocol (or T=0 as default)
        // and only standard paramters then PTS selection is not available
		//
		SmartcardExtension->ReaderCapabilities.CurrentState = 
			SCARD_SPECIFIC;

	} else {
     	
        SmartcardExtension->ReaderCapabilities.CurrentState = 
      //      SCARD_NEGOTIABLE;
    		SCARD_SPECIFIC;
    }

    //
	// Now find protocol specific data
    //

    if (TD[0] == 0) {
        
		cardCapabilities->Protocol.Supported |=
			SCARD_PROTOCOL_T0;

		cardCapabilities->T0.WI = TC[1];

		if (cardCapabilities->PtsData.Dl > 0 && 
            cardCapabilities->PtsData.Dl < 6) {

			cardCapabilities->T0.WT = 1 +
				cardCapabilities->T0.WI *
				960 * cardCapabilities->etu * 
		   		Pow2((UCHAR) (cardCapabilities->PtsData.Dl - 1));

		} else { 

			cardCapabilities->T0.WT = 1+
				cardCapabilities->T0.WI *
				960 * cardCapabilities->etu /
		   		Pow2((UCHAR) (cardCapabilities->PtsData.Dl - 1));			        
		} 

        SmartcardDebug(
            DEBUG_ATR,
            (TEXT("   T=0 Values from ATR:\n      WI = %ld\n"),
            cardCapabilities->T0.WI)
            );
        SmartcardDebug(
            DEBUG_ATR,
            (TEXT("   T=0 Timing from ATR:\n      WT = %ld ms\n"),
            cardCapabilities->T0.WT / 1000)
            );
    }

    if (protocolTypes & SCARD_PROTOCOL_T1) {

        for (i = 0; TD[i] != 1 && i < MAXIMUM_ATR_CODES; i++)
            ;
    
        for (; TD[i] == 1 && i < MAXIMUM_ATR_CODES; i++) 
            ;

        if (i == MAXIMUM_ATR_CODES) {

            return STATUS_UNRECOGNIZED_MEDIA;         	
        }

		cardCapabilities->Protocol.Supported |= 
			SCARD_PROTOCOL_T1;

		cardCapabilities->T1.IFSC = 
			(TA[i] ? TA[i] : 32);

		cardCapabilities->T1.CWI = 
			((TB[i] & 0x0f) ? (TB[i] & 0x0f) : T1_CWI_DEFAULT);

		cardCapabilities->T1.BWI = 
			((TB[i] & 0xf0) >> 4 ? (TB[i] & 0xf0) >> 4 : T1_BWI_DEFAULT);

		cardCapabilities->T1.EDC = 
			(TC[i] & 0x01);

		cardCapabilities->T1.CWT = 1 +
			(Pow2(cardCapabilities->T1.CWI) + 11) * cardCapabilities->etu;

		cardCapabilities->T1.BWT = 1 +
			((Pow2(cardCapabilities->T1.BWI) * TR) / 10) + 
			11 * cardCapabilities->etu;

        SmartcardDebug(
            DEBUG_ATR,
            (TEXT("   T=1 Values from ATR:\n      IFSC = %ld, CWI = %ld, BWI = %ld, EDC = %02x\n"),
            cardCapabilities->T1.IFSC,
            cardCapabilities->T1.CWI,
            cardCapabilities->T1.BWI,
            cardCapabilities->T1.EDC)
            );
        SmartcardDebug(
            DEBUG_ATR,
            (TEXT("   T=1 Timing from ATR:\n      CWT = %ld ms, BWT = %ld ms\n"),
            cardCapabilities->T1.CWT / 1000,
            cardCapabilities->T1.BWT / 1000)
            );
    }

	if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) {
		
        if (TA2Present) {

            //
            // TA2 is present in the ATR, so use 
            // the protocol indicated in the ATR
            //
            cardCapabilities->Protocol.Selected = 1 << TA[1];
         	
        } else {
         	
		    //
		    // The card only supports one protocol
		    // So make that one protocol the current one to use
		    //
		    cardCapabilities->Protocol.Selected = 
			    cardCapabilities->Protocol.Supported;
        }

        SmartcardDebug(
            DEBUG_ATR,
            (TEXT("   Mode: Specific %s\n\n"),          
            TA2Present ? TEXT("set by TA(2)") : TEXT(""))
            );

	} else {

        SmartcardDebug(
            DEBUG_ATR,
            (TEXT("   Mode: Negotiable\n\n"))
            );
    }

    //
    // Every card has to support the 'raw' protocol
    // It enables the usage of cards that have their own protocol defined
    //
    SmartcardExtension->CardCapabilities.Protocol.Supported |= 
        SCARD_PROTOCOL_RAW;

    return STATUS_SUCCESS;
}


⌨️ 快捷键说明

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