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

📄 sci_prot.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 5 页
字号:
/*----------------------------------------------------------------------------+|       This source code has been made available to you by IBM on an AS-IS|       basis.  Anyone receiving this source is licensed under IBM|       copyrights to use it in any way he or she deems fit, including|       copying it, modifying it, compiling it, and redistributing it either|       with or without modifications.  No license under IBM patents or|       patent applications is to be implied by the copyright license.||       Any user of this software should understand that IBM cannot provide|       technical support for this software and will not be responsible for|       any consequences resulting from the use of this software.||       Any person who transfers this source code or any derivative work|       must include the IBM copyright notice, this paragraph, and the|       preceding two paragraphs in the transferred software.||       COPYRIGHT   I B M   CORPORATION 2001|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Author:    Mike Lepore| Component: sci| File:      sci_prot.c| Purpose:   Smart Card protocol layer functions for the Smart Card.| Changes:|| Date:       Author            Comment:| ----------  ----------------  -----------------------------------------------| 03/22/2001  MAL               Initial check-in.| 03/26/2001  Zongwei Liu       Port to Linux| 09/26/2001  Zongwei Liu       Port to pallas| 10/10/2001  Zongwei Liu       Port to OS-Adaption layer| 12/03/2001  MAL, Zongwei Liu  Fixed error handling bug in sc_apdu() by adding |                    check_incoming_data(). This fixed incorrect receive length|                    occurring when card responds with a two byte error-code|                    instead of the expected number of bytes. Also fixed error|                    handling problem in sc_t1_command(). Improved data handling|                    efficiency in sc_t0_command().+----------------------------------------------------------------------------*/#include <stdio.h>#include <fcntl.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <linux/ioctl.h>#include "sci/sci_inf.h"#include "sc.h"#include "sci_prot.h"static SC_CONTROL_BLOCK sc_cb[SCI_NUMBER_OF_CONTROLLERS];/* tables from ISO/IEC 7816 */static unsigned long Fi_TABLE[] = {    372, 372, 558, 744, 1116, 1488, 1860, RFU,    RFU, 512, 768, 1024, 1536, 2048, RFU, RFU};static unsigned long f_TABLE[] = {    4000000, 5000000, 6000000, 8000000, 12000000, 16000000, 20000000, RFU,    RFU, 5000000, 7500000, 10000000, 15000000, 20000000, RFU, RFU};static unsigned long Di_TABLE[] = {    RFU, 1, 2, 4, 8, 16, 32, RFU,    12, 20, RFU, RFU, RFU, RFU, RFU, RFU};extern int fd[2];static void check_incoming_data(unsigned char *buffer,                                unsigned long *length,                                unsigned char SW1,                                unsigned char SW2);/****************************************************************************** Function:    sc_reset**** Purpose:     Perform a reset, receive and process the ATR, and extract all**              ATR parameters.**** Parameters:  sc_id: zero-based number to identify smart card controller**** Returns:     SCI_ERROR_OK: if successful**              other error code if a failure occurs*****************************************************************************/SCI_ERROR sc_reset(unsigned long sc_id){    SCI_ERROR rc = SCI_ERROR_OK;    SCI_PARAMETERS sci_parameters;    I_BYTES p_ibyte[SC_MAX_ATR_SIZE];    I_BYTES *p_ibyter = 0;    I_BYTES *p_ibytew = 0;    unsigned long i = 0;    unsigned long x = 0;    unsigned long index = 0;    ssize_t bytes_rec = 0;    unsigned char current = 0;    unsigned char lrc = 0;    unsigned long Fi = 0;    unsigned long Di = 0;    unsigned long f = 0;    unsigned long card_present;    if (sc_id < SCI_NUMBER_OF_CONTROLLERS)    {        ioctl(fd[sc_id], IOCTL_GET_IS_CARD_PRESENT, &card_present);        if (card_present == 1)        {            /* initialize protocol state */            sc_cb[sc_id].atr_size = 0;            sc_cb[sc_id].p_historical = 0;            sc_cb[sc_id].historical_size = 0;            sc_cb[sc_id].TCK_present = 0;            sc_cb[sc_id].firstT = SC_ATR_T;            sc_cb[sc_id].currentT = SC_ATR_T;            sc_cb[sc_id].NS = 0;            sc_cb[sc_id].proposed_IFSD = SC_ATR_IFSD;            sc_cb[sc_id].IFSD = SC_ATR_IFSD;            /* set atr parameter defaults */            sc_cb[sc_id].sc_parameters.T = SC_ATR_T;            sc_cb[sc_id].sc_parameters.maskT = SC_ATR_T;            sc_cb[sc_id].sc_parameters.F = SC_ATR_FI;            sc_cb[sc_id].sc_parameters.D = SC_ATR_DI;            sc_cb[sc_id].sc_parameters.FI = SC_ATR_FI;            sc_cb[sc_id].sc_parameters.DI = SC_ATR_DI;            sc_cb[sc_id].sc_parameters.II = SC_ATR_II;            sc_cb[sc_id].sc_parameters.PI1 = SC_ATR_PI1;            sc_cb[sc_id].sc_parameters.PI2 = SC_ATR_PI2;            sc_cb[sc_id].sc_parameters.WI = SC_ATR_WI;            sc_cb[sc_id].sc_parameters.XI = SC_ATR_XI;            sc_cb[sc_id].sc_parameters.UI = SC_ATR_UI;            sc_cb[sc_id].sc_parameters.N = SC_ATR_N;            sc_cb[sc_id].sc_parameters.CWI = SC_ATR_CWI;            sc_cb[sc_id].sc_parameters.BWI = SC_ATR_BWI;            sc_cb[sc_id].sc_parameters.IFSC = SC_ATR_IFSC;            sc_cb[sc_id].sc_parameters.check = SC_ATR_CHECK;            p_ibytew = p_ibyte;            p_ibyter = p_ibyte;            *p_ibytew = TS;            p_ibytew++;            if (ioctl(fd[sc_id], IOCTL_SET_RESET) == 0)            {                if (ioctl(fd[sc_id], IOCTL_GET_PARAMETERS, &sci_parameters)                    == 0)                {                    while ((p_ibyter != p_ibytew) && (rc == SCI_ERROR_OK))                    {                        /* read 1 ATR byte */                        if ((rc = read(fd[sc_id], &current, 1)) > 0)                        {                            rc = SCI_ERROR_OK;                            sc_cb[sc_id].ATR[index] = current;                            index++;                            switch (*p_ibyter)                            {                                case TS:                                    *p_ibytew = T0;                                    p_ibytew++;                                    break;                                case T0:                                    /* save number of historical bytes */                                    sc_cb[sc_id].historical_size =                                        (current & 0x0F);                                    /* check for presence of TA(1) */                                    if ((current & 0x10) == 0x10)                                    {                                        *p_ibytew = TA;                                        p_ibytew++;                                    }                                    /* check for presence of TB(1) */                                    if ((current & 0x20) == 0x20)                                    {                                        *p_ibytew = TB;                                        p_ibytew++;                                    }                                    /* check for presence of TC(1) */                                    if ((current & 0x40) == 0x40)                                    {                                        *p_ibytew = TC;                                        p_ibytew++;                                    }                                    /* check for presence of TD(1) */                                    if ((current & 0x80) == 0x80)                                    {                                        *p_ibytew = TD;                                        p_ibytew++;                                    }                                    else                                    {                                        /* TD(1) is absent- protocol T='0' is the only offer */                                        sci_parameters.T = 0;                                        sc_cb[sc_id].sc_parameters.T = 0;                                        sc_cb[sc_id].sc_parameters.maskT = 1;                                        /* push any TK's and TCK into queue */                                        for (x = 0;                                             x < sc_cb[sc_id].historical_size;                                             x++)                                        {                                            *p_ibytew = TK;                                            p_ibytew++;                                        }                                        if (sc_cb[sc_id].sc_parameters.                                            maskT != 1)                                        {                                            /* If T=0 isn't the only offer, a check byte is present                                              */                                            *p_ibytew = TCK;                                            p_ibytew++;                                        }                                    }                                    i++;                                    break;                                case TA:                                    if (i == 1)                                    {                                        /* extract Fl and Dl from TA(1) to determine Fi, Di, and f */                                        sc_cb[sc_id].sc_parameters.FI =                                            ((current & 0xF0) >> 4);                                        sc_cb[sc_id].sc_parameters.DI =                                            (current & 0x0F);                                        Fi = Fi_TABLE[sc_cb[sc_id].                                                      sc_parameters.FI];                                        Di = Di_TABLE[sc_cb[sc_id].                                                      sc_parameters.DI];                                        f = f_TABLE[sc_cb[sc_id].                                                    sc_parameters.FI];                                    }                                    else if (i == 2)                                    {                                        /* check bit 5 of TA(2) */                                        if ((current & 0x10) == 0)                                        {                                            /* use Fi and Di from TA(1), if it is present */                                            if (f != 0)                                            {                                                sci_parameters.f = f;                                            }                                            if ((Fi != 0) && (Di != 0))                                            {                                                sci_parameters.ETU =                                                    (Fi / Di);                                            }                                            /* card starts in specific mode using this protocol */                                            /* this overrides first offered protocol */                                            sci_parameters.T =                                                (current & 0x0F);                                            sc_cb[sc_id].sc_parameters.T =                                                sci_parameters.T;                                            sc_cb[sc_id].sc_parameters.F =                                                sc_cb[sc_id].sc_parameters.FI;                                            sc_cb[sc_id].sc_parameters.D =                                                sc_cb[sc_id].sc_parameters.DI;                                        }                                    }                                    else if (i > 2)                                    {                                        /* TD(i-1) must indicate T=1 for IFSC */                                        if (sc_cb[sc_id].currentT == 1)                                        {                                            /* 0x00 and 0xFF are RFU */                                            if ((current >= 0x01) &&                                                (current <= 0xFE))                                            {                                                sc_cb[sc_id].sc_parameters.                                                    IFSC = current;                                            }                                        }                                        /* check for global indication from TD(i-1) */                                        if (sc_cb[sc_id].currentT == 15)                                        {                                            /* check for class */                                            sc_cb[sc_id].sc_parameters.UI =                                                (current & 0x3F);                                            switch (sc_cb[sc_id].                                                    sc_parameters.UI)                                            {                                                case 1:                                                    sci_parameters.U =                                                        SCI_CLASS_A;                                                    break;                                                case 2:                                                    /* SCI is class A-only class A and AB cards                                                       allowed */                                                    sci_parameters.U =                                                        SCI_CLASS_B;                                                    rc = SCI_ERROR_FAIL;                                                    // sci_deactivate(sc_id);                                                    ioctl(fd[sc_id],                                                          IOCTL_SET_DEACTIVATE);                                                    break;                                                case 3:                                                    sci_parameters.U =                                                        SCI_CLASS_AB;                                                    break;                                            }                                            /* check for clock stop capabilities */                                            sc_cb[sc_id].sc_parameters.XI =                                                ((current & 0xC0) >> 6);                                            switch (sc_cb[sc_id].                                                    sc_parameters.XI)                                            {                                                case 0:                                                    sci_parameters.                                                        clock_stop_polarity =                                                        SCI_CLOCK_STOP_DISABLED;                                                    break;                                                case 1:

⌨️ 快捷键说明

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