Changeset 1037

Show
Ignore:
Timestamp:
05/07/08 21:45:22 (7 months ago)
Author:
alonbl
Message:

Support CCID 1.10 and fix pts and parameter setting in the proper order

By: Chaskiel Grundman

I have apparently been sitting on a patch that does pts and parameter setting in the proper order for most of a year. (the problem you have seems to be that the existing code changes the baud rate before doing pts, so the card responds at the old baud rate) I do not know why I did not submit this patch earlier. I do know that I have not really tested it recently

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/ifd/ifd-ccid.c

    r1030 r1037  
    650650        } 
    651651 
    652         if (ccid.bcdCCID != 0x100) { 
    653                 ct_error("ccid: unknown ccid version %d.%d%d supported only 1.00", 
    654                         (ccid.bcdCCID >> 8) & 0xf, 
    655                         (ccid.bcdCCID >> 4) & 0xf, 
    656                         (ccid.bcdCCID >> 0) & 0xf 
     652        if (ccid.bcdCCID != 0x100 && ccid.bcdCCID != 0x110) { 
     653                ct_error("ccid: unknown ccid version %02d.02%d supported only 1.00, 1.10", 
     654                        (ccid.bcdCCID >> 8) & 0xff, 
     655                        (ccid.bcdCCID >> 0) & 0xff 
    657656                ); 
    658657                ifd_device_close(dev); 
     
    755754                st->proto_support |= SUPPORT_ESCAPE; 
    756755        } 
    757  
     756        ifd_debug(3, "Accepted %04x:%04x with features 0x%x and protocols 0x%x", de.idVendor, de.idProduct, ccid.dwFeatures, ccid.dwProtocols); 
    758757        return 0; 
    759758} 
     
    970969        ifd_protocol_t *p; 
    971970        ifd_atr_info_t atr_info; 
    972         int r; 
     971        int r, paramlen; 
    973972 
    974973        slot = &reader->slot[s]; 
     
    10481047                return r; 
    10491048        } 
    1050  
    1051         /* does FLAG_AUTO_PARAMS select the protocol??? */ 
    1052         memset(parambuf, 0, sizeof(parambuf)); 
    1053         memset(ctl, 0, 3); 
    1054         if (proto == IFD_PROTOCOL_T0) { 
    1055                 r = 5; 
    1056                 ctl[0] = 0; 
    1057                 /* TA1 -> Fi | Di */ 
    1058                 if (atr_info.TA[0] != -1) 
    1059                         parambuf[0] = atr_info.TA[0]; 
    1060                 else 
    1061                         parambuf[0] = 0x11;     /* default is Fi = Di = 1 */ 
    1062                 parambuf[1] = 0; 
    1063                 /* TC1 -> N */ 
    1064                 if (atr_info.TC[0] != -1) 
    1065                         parambuf[2] = atr_info.TC[0]; 
    1066                 /* TC2 -> WI */ 
    1067                 if (atr_info.TC[1] != -1) 
    1068                         parambuf[3] = atr_info.TC[1]; 
    1069                 else 
    1070                         parambuf[3] = 0x0a;     /* default WI=10 */ 
    1071                 /* TA3 -> clock stop parameter */ 
    1072                 /* XXX check for IFD clock stop support */ 
    1073                 if (atr_info.TA[2] != -1) 
    1074                         parambuf[4] = atr_info.TA[2] >> 6; 
    1075         } else if (proto == IFD_PROTOCOL_T1) { 
    1076                 r = 7; 
    1077                 ctl[0] = 1; 
    1078                 if (atr_info.TA[0] != -1) 
    1079                         parambuf[0] = atr_info.TA[0]; 
    1080                 else 
    1081                         parambuf[0] = 0x11; 
    1082                 parambuf[1] = 0x10; 
    1083                 /* TC3 -> LRC/CRC selection */ 
    1084                 if (atr_info.TC[2] == 1) 
    1085                         parambuf[1] |= 0x1; 
    1086                 /* TC1 -> N */ 
    1087                 if (atr_info.TC[0] != -1) 
    1088                         parambuf[2] = atr_info.TC[0]; 
    1089                 /* atr_info->TB3 -> BWI/CWI */ 
    1090                 if (atr_info.TB[2] != -1) 
    1091                         parambuf[3] = atr_info.TB[2]; 
    1092                 else 
    1093                         parambuf[3] = 0xD4; 
    1094                 parambuf[4] = 0; 
    1095                 /* TA3 -> IFSC */ 
    1096                 if (atr_info.TA[2] != -1) 
    1097                         parambuf[5] = atr_info.TA[2]; 
    1098                 else 
    1099                         parambuf[5] = 0x20; 
    1100                 /* XXX CCID supports setting up clock stop for T=1, but the 
    1101                  * T=1 ATR does not define a clock-stop byte. 
    1102                  */ 
    1103         } 
     1049        /* ccid doesn't have a parameter for this */ 
     1050        if (atr_info.TC[0] == 255) 
     1051                atr_info.TC[0] = -1; 
     1052 
     1053        /* 
     1054         * guard time increase must precede PTS 
     1055         * we don't need to do this separate step if 
     1056         * a) the ccid does automatic parameter setting, or 
     1057         * b) the ccid parses the atr itself, or 
     1058         * c) the ccid does pts itself when we set parameters, or 
     1059         * d) the ICC does not require extra guard time 
     1060         * In all but the first case, we'll do parameter setting later,  
     1061         * so fetch the default parameters now. 
     1062         */ 
    11041063        if ((st->flags & FLAG_NO_SETPARAM) == 0) { 
    1105                 r = ccid_simple_wcommand(reader, s, CCID_CMD_SETPARAMS, ctl, 
    1106                                          parambuf, r); 
     1064                memset(parambuf, 0, sizeof(parambuf)); 
     1065                memset(ctl, 0, 3); 
     1066                r = ccid_simple_rcommand(reader, s, CCID_CMD_GETPARAMS, 
     1067                        ctl, parambuf, 7); 
    11071068                if (r < 0) 
    11081069                        return r; 
    1109         } 
    1110  
    1111         /* is PTS available? N (guard time) must be changed before PTS 
    1112          * is performed. What about F and D? */ 
     1070                if (proto == IFD_PROTOCOL_T0) { 
     1071                        paramlen = 5; 
     1072                        ctl[0] = 0; 
     1073                } 
     1074                else { 
     1075                        paramlen = 7; 
     1076                        ctl[0] = 1; 
     1077                } 
     1078                if ((st->flags & (FLAG_NO_PTS | FLAG_AUTO_ATRPARSE)) == 0 && 
     1079                        atr_info.TC[0] != -1) { 
     1080 
     1081                        parambuf[2] = atr_info.TC[0]; 
     1082                        r = ccid_simple_wcommand(reader, s, CCID_CMD_SETPARAMS, 
     1083                                ctl, parambuf, paramlen); 
     1084                        if (r < 0) 
     1085                                return r; 
     1086                } 
     1087        } 
     1088 
    11131089        if ((st->flags & FLAG_NO_PTS) == 0 && 
    1114             (proto == IFD_PROTOCOL_T1 || atr_info.TA[0] != -1 
    1115              || atr_info.TC[0] == 255)) { 
     1090                (proto == IFD_PROTOCOL_T1 || atr_info.TA[0] != -1)) { 
     1091 
    11161092                unsigned char pts[7], ptsret[7]; 
    11171093                int ptslen; 
     
    11321108                        return r; 
    11331109                } 
     1110        } 
     1111 
     1112        if ((st->flags & FLAG_NO_SETPARAM) == 0 && 
     1113                ((st->flags & FLAG_AUTO_ATRPARSE) == 0 | 
     1114                proto != IFD_PROTOCOL_T0)) { 
     1115 
     1116                /* if FLAG_AUTO_ATRPARSE, only set the protocol. */ 
     1117                if ((st->flags & FLAG_AUTO_ATRPARSE) == 0) { 
     1118                        if (proto == IFD_PROTOCOL_T0) { 
     1119                                /* TA1 -> Fi | Di */ 
     1120                                if (atr_info.TA[0] != -1) 
     1121                                        parambuf[0] = atr_info.TA[0]; 
     1122                                /* TC1 -> N */ 
     1123                                if (atr_info.TC[0] != -1) 
     1124                                        parambuf[2] = atr_info.TC[0]; 
     1125                                /* TC2 -> WI */ 
     1126                                if (atr_info.TC[1] != -1) 
     1127                                        parambuf[3] = atr_info.TC[1]; 
     1128                                /* TA3 -> clock stop parameter */ 
     1129                                /* XXX check for IFD clock stop support */ 
     1130                                if (atr_info.TA[2] != -1) 
     1131                                        parambuf[4] = atr_info.TA[2] >> 6; 
     1132                        } 
     1133                        else if (proto == IFD_PROTOCOL_T1) { 
     1134                                if (atr_info.TA[0] != -1) 
     1135                                        parambuf[0] = atr_info.TA[0]; 
     1136                                parambuf[1] = 0x10; 
     1137                                /* TC3 -> LRC/CRC selection */ 
     1138                                if (atr_info.TC[2] == 1) 
     1139                                        parambuf[1] |= 0x1; 
     1140                                else 
     1141                                        parambuf[1] &= 0xfe; 
     1142                                /* TC1 -> N */ 
     1143                                if (atr_info.TC[0] != -1) 
     1144                                        parambuf[2] = atr_info.TC[0]; 
     1145                                /* atr_info->TB3 -> BWI/CWI */ 
     1146                                if (atr_info.TB[2] != -1) 
     1147                                        parambuf[3] = atr_info.TB[2]; 
     1148                                /* TA3 -> IFSC */ 
     1149                                if (atr_info.TA[2] != -1) 
     1150                                        parambuf[5] = atr_info.TA[2]; 
     1151                                /* 
     1152                                 * XXX CCID supports setting up clock stop for T=1, but the 
     1153                                 * T=1 ATR does not define a clock-stop byte. 
     1154                                 */ 
     1155                        } 
     1156                } 
     1157                r = ccid_simple_wcommand(reader, s, CCID_CMD_SETPARAMS, ctl, 
     1158                        parambuf, paramlen); 
     1159                if (r < 0) 
     1160                        return r; 
    11341161        } 
    11351162