| 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 |
| 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 | */ |
| 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 | |
| | 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; |