[8] | 1 | /*
|
---|
| 2 | pps.c
|
---|
| 3 | Protocol Parameters Selection
|
---|
| 4 |
|
---|
| 5 | This file is part of the Unix driver for Towitoko smartcard readers
|
---|
| 6 | Copyright (C) 2000 2001 Carlos Prados <cprados@yahoo.com>
|
---|
| 7 |
|
---|
| 8 | This version is modified by doz21 to work in a special manner ;)
|
---|
| 9 |
|
---|
| 10 | This library is free software; you can redistribute it and/or
|
---|
| 11 | modify it under the terms of the GNU Lesser General Public
|
---|
| 12 | License as published by the Free Software Foundation; either
|
---|
| 13 | version 2 of the License, or (at your option) any later version.
|
---|
| 14 |
|
---|
| 15 | This library is distributed in the hope that it will be useful,
|
---|
| 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 18 | Lesser General Public License for more details.
|
---|
| 19 |
|
---|
| 20 | You should have received a copy of the GNU Lesser General Public
|
---|
| 21 | License along with this library; if not, write to the Free Software
|
---|
| 22 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
| 23 | */
|
---|
| 24 |
|
---|
| 25 | #include "pps.h"
|
---|
| 26 | #include "atr.h"
|
---|
| 27 | #include "protocol_t0.h"
|
---|
| 28 | #include "protocol_t1.h"
|
---|
| 29 | #include <stdlib.h>
|
---|
| 30 | #include <stdio.h>
|
---|
| 31 | #include <string.h>
|
---|
[1177] | 32 | #include "ifd.h"
|
---|
[1210] | 33 | #include "../globals.h"
|
---|
[8] | 34 |
|
---|
| 35 | /*
|
---|
| 36 | * Not exported constants definition
|
---|
| 37 | */
|
---|
| 38 |
|
---|
| 39 | #define PPS_DEFAULT_PROTOCOL 0x00
|
---|
| 40 |
|
---|
| 41 | /*
|
---|
| 42 | * Not exported macros definition
|
---|
| 43 | */
|
---|
| 44 |
|
---|
| 45 | #define PPS_HAS_PPS1(block) ((block[1] & 0x10) == 0x10)
|
---|
| 46 | #define PPS_HAS_PPS2(block) ((block[1] & 0x20) == 0x20)
|
---|
| 47 | #define PPS_HAS_PPS3(block) ((block[1] & 0x40) == 0x40)
|
---|
| 48 |
|
---|
| 49 | /*
|
---|
| 50 | * Not exported funtions declaration
|
---|
| 51 | */
|
---|
| 52 |
|
---|
[565] | 53 | static int PPS_Exchange (PPS * pps, BYTE * params, unsigned *length);
|
---|
[8] | 54 |
|
---|
[565] | 55 | static bool PPS_Match (BYTE * request, unsigned len_request, BYTE * reply, unsigned len_reply);
|
---|
[8] | 56 |
|
---|
[565] | 57 | static unsigned PPS_GetLength (BYTE * block);
|
---|
[8] | 58 |
|
---|
[1126] | 59 | static int PPS_InitICC (PPS * pps);
|
---|
[8] | 60 |
|
---|
[885] | 61 | static int PPS_InitProtocol (PPS * pps, int protocol_selected);
|
---|
[8] | 62 |
|
---|
[565] | 63 | static BYTE PPS_GetPCK (BYTE * block, unsigned length);
|
---|
[8] | 64 |
|
---|
| 65 | /*
|
---|
| 66 | * Exported functions definition
|
---|
| 67 | */
|
---|
| 68 |
|
---|
[565] | 69 | PPS * PPS_New (ICC_Async * icc)
|
---|
[8] | 70 | {
|
---|
| 71 | PPS *pps;
|
---|
[565] | 72 |
|
---|
| 73 | pps = (PPS *) malloc (sizeof (PPS));
|
---|
| 74 |
|
---|
| 75 | if (pps != NULL)
|
---|
| 76 | {
|
---|
[8] | 77 | pps->icc = icc;
|
---|
| 78 | pps->protocol = NULL;
|
---|
| 79 | pps->parameters.t = PPS_DEFAULT_PROTOCOL;
|
---|
[885] | 80 | pps->parameters.FI = ATR_DEFAULT_FI;
|
---|
[8] | 81 | pps->parameters.d = ATR_DEFAULT_D;
|
---|
| 82 | pps->parameters.n = ATR_DEFAULT_N;
|
---|
| 83 | }
|
---|
[565] | 84 |
|
---|
[8] | 85 | return pps;
|
---|
| 86 | }
|
---|
| 87 |
|
---|
[565] | 88 | int PPS_Perform (PPS * pps, BYTE * params, unsigned *length)
|
---|
[8] | 89 | {
|
---|
[735] | 90 | //Performs PPS Exchange on command when *length >0
|
---|
| 91 | //If unsuccesfull, or when length <= 0
|
---|
| 92 | //Gets parametes from ATR
|
---|
| 93 | //If necessary perform PPS session
|
---|
| 94 | //
|
---|
[885] | 95 | //Output is pps->params.FI,n,d,t set with correct values
|
---|
[735] | 96 | //and switched SC-device conform these values to correct baudrate
|
---|
[885] | 97 | //
|
---|
| 98 | //We need to store FI instread of F, because SCI_DEV works with FI
|
---|
| 99 | //and it is easier to overclock then
|
---|
| 100 | //also from FI -> F is easy, other way around not
|
---|
[735] | 101 |
|
---|
[565] | 102 | ATR *atr;
|
---|
[735] | 103 | int ret;
|
---|
| 104 | bool PPS_success;
|
---|
[552] | 105 |
|
---|
[735] | 106 | /* Perform PPS Exchange if requested by command */
|
---|
[565] | 107 | if ((*length) > 0)
|
---|
[552] | 108 | {
|
---|
[565] | 109 | ret = PPS_Exchange (pps, params, length);
|
---|
| 110 |
|
---|
[8] | 111 | /* Get parameters from PPS handsake */
|
---|
[565] | 112 | if (ret == PPS_OK)
|
---|
| 113 | {
|
---|
[8] | 114 | pps->parameters.t = params[1] & 0x0F;
|
---|
[565] | 115 |
|
---|
| 116 | if (PPS_HAS_PPS1 (params))
|
---|
| 117 | {
|
---|
[885] | 118 | pps->parameters.FI = (params[2] >> 4);
|
---|
[8] | 119 | pps->parameters.d = atr_d_table[(params[2] & 0x0F)];
|
---|
| 120 | }
|
---|
[565] | 121 |
|
---|
[699] | 122 | /*
|
---|
[565] | 123 | ret = PPS_InitICC(pps);
|
---|
| 124 |
|
---|
[8] | 125 | if (ret != PPS_OK)
|
---|
| 126 | return ret;
|
---|
[699] | 127 | */
|
---|
[565] | 128 | }
|
---|
[699] | 129 | /*
|
---|
[565] | 130 | else
|
---|
| 131 | {
|
---|
[552] | 132 | return ret;
|
---|
[8] | 133 | }
|
---|
[699] | 134 | */
|
---|
[565] | 135 | }
|
---|
[735] | 136 | PPS_success = PPS_OK;
|
---|
[885] | 137 | int protocol_selected = 0; //stores which TAi,TBi etc. bytes must be used 0 means not set
|
---|
[735] | 138 | atr = ICC_Async_GetAtr (pps->icc);
|
---|
| 139 | if ((*length) <= 0 || !PPS_success) // If not by command, or PPS Exchange by command failed: Try PPS Exchange by ATR or Get parameters from ATR
|
---|
[565] | 140 | {
|
---|
[1210] | 141 | int numprot = atr->pn;
|
---|
| 142 | //if there is a trailing TD, this number is one too high
|
---|
[746] | 143 | BYTE tx;
|
---|
[1210] | 144 | if (ATR_GetInterfaceByte (atr, numprot-1, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK)
|
---|
| 145 | if ((tx & 0xF0) == 0)
|
---|
| 146 | numprot--;
|
---|
[1194] | 147 | cs_debug("ATR reports %i protocol lines:",numprot);
|
---|
[735] | 148 | int i,point;
|
---|
| 149 | char txt[50];
|
---|
[1064] | 150 | bool OffersT[3]; //T14 stored as T2
|
---|
[925] | 151 | for (i = 0; i <= 2; i++)
|
---|
| 152 | OffersT[i] = FALSE;
|
---|
[746] | 153 | for (i=1; i<= numprot; i++) {
|
---|
[1194] | 154 | point = 0;
|
---|
[746] | 155 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TA, &tx) == ATR_OK) {
|
---|
| 156 | sprintf((char *)txt+point,"TA%i=%02X ",i,tx);
|
---|
[735] | 157 | point +=7;
|
---|
| 158 | }
|
---|
[746] | 159 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TB, &tx) == ATR_OK) {
|
---|
| 160 | sprintf((char *)txt+point,"TB%i=%02X ",i,tx);
|
---|
[735] | 161 | point +=7;
|
---|
| 162 | }
|
---|
[746] | 163 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TC, &tx) == ATR_OK) {
|
---|
| 164 | sprintf((char *)txt+point,"TC%i=%02X ",i,tx);
|
---|
[735] | 165 | point +=7;
|
---|
| 166 | }
|
---|
[746] | 167 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK) {
|
---|
| 168 | sprintf((char *)txt+point,"TD%i=%02X ",i,tx);
|
---|
[735] | 169 | point +=7;
|
---|
[925] | 170 | tx &= 0X0F;
|
---|
| 171 | sprintf((char *)txt+point,"(T%i)",tx);
|
---|
| 172 | if (tx == 14)
|
---|
| 173 | OffersT[2] = TRUE;
|
---|
| 174 | else
|
---|
| 175 | OffersT[tx] = TRUE;
|
---|
[735] | 176 | }
|
---|
[925] | 177 | else {
|
---|
[746] | 178 | sprintf((char *)txt+point,"no TD%i means T0",i);
|
---|
[925] | 179 | OffersT[0] = TRUE;
|
---|
| 180 | }
|
---|
[735] | 181 | cs_debug("%s",txt);
|
---|
| 182 | }
|
---|
[925] | 183 |
|
---|
| 184 | int numprottype = 0;
|
---|
| 185 | for (i = 0; i <= 2; i++)
|
---|
| 186 | if (OffersT[i])
|
---|
| 187 | numprottype ++;
|
---|
[959] | 188 | cs_debug("%i protocol types detected. Historical bytes: %s",numprottype, cs_hexdump(1,atr->hb,atr->hbn));
|
---|
[735] | 189 |
|
---|
| 190 | //If more than one protocol type and/or TA1 parameter values other than the default values and/or N equeal to 255 is/are indicated in the answer to reset, the card shall know unambiguously, after having sent the answer to reset, which protocol type or/and transmission parameter values (FI, D, N) will be used. Consequently a selection of the protocol type and/or the transmission parameters values shall be specified.
|
---|
[565] | 191 | ATR_GetParameter (atr, ATR_PARAMETER_N, &(pps->parameters.n));
|
---|
[925] | 192 | ATR_GetProtocolType(atr,1,&(pps->parameters.t)); //get protocol from TD1
|
---|
[1140] | 193 | BYTE TA2;
|
---|
| 194 | bool SpecificMode = (ATR_GetInterfaceByte (atr, 2, ATR_INTERFACE_BYTE_TA, &TA2) == ATR_OK); //if TA2 present, specific mode, else negotiable mode
|
---|
| 195 | if (SpecificMode) {
|
---|
| 196 | pps->parameters.t = TA2 & 0x0F;
|
---|
| 197 | if ((TA2 & 0x10) != 0x10) { //bit 5 set to 0 means F and D explicitly defined in interface characters
|
---|
| 198 | BYTE TA1;
|
---|
| 199 | if (ATR_GetInterfaceByte (atr, 1 , ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) {
|
---|
| 200 | pps->parameters.FI = TA1 >> 4;
|
---|
| 201 | ATR_GetParameter (atr, ATR_PARAMETER_D, &(pps->parameters.d));
|
---|
| 202 | }
|
---|
| 203 | else {
|
---|
| 204 | pps->parameters.FI = ATR_DEFAULT_FI;
|
---|
| 205 | pps->parameters.d = ATR_DEFAULT_D;
|
---|
| 206 | }
|
---|
| 207 | }
|
---|
| 208 | else {
|
---|
| 209 | cs_log("Specific mode: speed 'implicitly defined', not sure how to proceed, assuming default values");
|
---|
| 210 | pps->parameters.FI = ATR_DEFAULT_FI;
|
---|
| 211 | pps->parameters.d = ATR_DEFAULT_D;
|
---|
| 212 | }
|
---|
| 213 | cs_debug("Specific mode: T%i, F=%.0f, D=%.6f, N=%.0f\n", pps->parameters.t, (double) atr_f_table[pps->parameters.FI], pps->parameters.d, pps->parameters.n);
|
---|
| 214 | }
|
---|
| 215 | else { //negotiable mode
|
---|
| 216 |
|
---|
[1194] | 217 | bool NeedsPTS = ((pps->parameters.t != 14) && (numprottype > 1 || (atr->ib[0][ATR_INTERFACE_BYTE_TA].present == TRUE && atr->ib[0][ATR_INTERFACE_BYTE_TA].value != 0x11) || pps->parameters.n == 255)); //needs PTS according to ISO 7816 , SCI gets stuck on our PTS
|
---|
| 218 | if (NeedsPTS) {
|
---|
| 219 | // PTSS PTS0 PTS1 PTS2 PTS3 PCK
|
---|
| 220 | // PTSS PTS0 PTS1 PCK
|
---|
| 221 | BYTE req[] = { 0xFF, 0x10, 0x00, 0x00 }; //we currently do not support PTS2, standard guardtimes
|
---|
[746] | 222 | req[1]=0x10 | pps->parameters.t; //PTS0 always flags PTS1 to be sent always
|
---|
[1194] | 223 | if (ATR_GetInterfaceByte (atr, 1, ATR_INTERFACE_BYTE_TA, &req[2]) != ATR_OK) //PTS1
|
---|
[746] | 224 | req[2] = 0x11; //defaults FI and DI to 1
|
---|
[735] | 225 | //req[3]=PPS_GetPCK(req,sizeof(req)-1); will be set by PPS_Exchange
|
---|
[746] | 226 | unsigned int len = sizeof(req);
|
---|
[735] | 227 | ret = PPS_Exchange (pps, req, &len);
|
---|
| 228 | if (ret == PPS_OK) {
|
---|
[885] | 229 | pps->parameters.FI = req[2] >> 4;
|
---|
[735] | 230 | BYTE DI = req[2] & 0x0F;
|
---|
| 231 | pps->parameters.d = (double) (atr_d_table[DI]);
|
---|
| 232 | PPS_success = TRUE;
|
---|
[1194] | 233 | cs_debug("PTS Succesfull, selected protocol: T%i, F=%.0f, D=%.6f, N=%.0f\n", pps->parameters.t, (double) atr_f_table[pps->parameters.FI], pps->parameters.d, pps->parameters.n);
|
---|
[735] | 234 | }
|
---|
| 235 | else
|
---|
[1194] | 236 | cs_ddump(req,4,"PTS Failure, response:");
|
---|
[735] | 237 | }
|
---|
[925] | 238 |
|
---|
[1194] | 239 | //FIXME Currently InitICC sets baudrate to 9600 for all T14 cards (=no switching);
|
---|
| 240 | //When for SCI, T14 protocol, TA1 is obeyed, this goes OK for mosts devices, but somehow on DM7025 Sky S02 card goes wrong when setting ETU (ok on DM800/DM8000)
|
---|
| 241 | if (!PPS_success) {//last PPS not succesfull
|
---|
| 242 | BYTE TA1;
|
---|
| 243 | if (ATR_GetInterfaceByte (atr, 1 , ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) {
|
---|
| 244 | pps->parameters.FI = TA1 >> 4;
|
---|
| 245 | ATR_GetParameter (atr, ATR_PARAMETER_D, &(pps->parameters.d));
|
---|
| 246 | }
|
---|
| 247 | else { //do not obey TA1
|
---|
| 248 | pps->parameters.FI = ATR_DEFAULT_FI;
|
---|
| 249 | pps->parameters.d = ATR_DEFAULT_D;
|
---|
| 250 | }
|
---|
| 251 | ATR_GetProtocolType (atr, 1, &(pps->parameters.t));
|
---|
| 252 | protocol_selected = 1;
|
---|
| 253 |
|
---|
| 254 | if (NeedsPTS) {
|
---|
| 255 | if ((pps->parameters.d == 32) || (pps->parameters.d == 12) || (pps->parameters.d == 20))
|
---|
| 256 | pps->parameters.d = 0; //behave conform "old" atr_d_table; viaccess cards that fail PTS need this
|
---|
| 257 | }
|
---|
| 258 | /////Here all non-ISO behaviour
|
---|
| 259 | /////End all non-ISO behaviour
|
---|
[959] | 260 |
|
---|
[1194] | 261 | cs_debug("No PTS %s, selected protocol T%i, F=%.0f, D=%.6f, N=%.0f\n", NeedsPTS?"happened":"needed", pps->parameters.t, (double) atr_f_table[pps->parameters.FI], pps->parameters.d, pps->parameters.n);
|
---|
[959] | 262 | }
|
---|
[1140] | 263 | }//end negotiable mode
|
---|
[735] | 264 | }//end length<0
|
---|
[746] | 265 |
|
---|
| 266 | //make sure no zero values
|
---|
[885] | 267 | double F = (double) atr_f_table[pps->parameters.FI];
|
---|
| 268 | if (!F) {
|
---|
| 269 | pps->parameters.FI = ATR_DEFAULT_FI;
|
---|
[1117] | 270 | cs_log("Warning: F=0 is invalid, forcing FI=%d", pps->parameters.FI);
|
---|
[746] | 271 | }
|
---|
| 272 | if (!pps->parameters.d) {
|
---|
| 273 | pps->parameters.d = ATR_DEFAULT_D;
|
---|
| 274 | cs_log("Warning: D=0 is invalid, forcing D=%.0f",pps->parameters.d);
|
---|
| 275 | }
|
---|
[885] | 276 |
|
---|
| 277 | pps->icc->protocol_type = pps->parameters.t;
|
---|
[565] | 278 |
|
---|
[552] | 279 | #ifdef DEBUG_PROTOCOL
|
---|
[736] | 280 | printf("PPS: T=%i, F=%.0f, D=%.6f, N=%.0f\n",
|
---|
[565] | 281 | pps->parameters.t,
|
---|
[885] | 282 | F,
|
---|
[565] | 283 | pps->parameters.d,
|
---|
| 284 | pps->parameters.n);
|
---|
[552] | 285 | #endif
|
---|
[735] | 286 |
|
---|
[1126] | 287 | ret = PPS_InitICC(pps);
|
---|
[735] | 288 |
|
---|
| 289 | if (ret != PPS_OK)
|
---|
| 290 | return ret;
|
---|
[565] | 291 |
|
---|
[552] | 292 | /* Initialize selected protocol with selected parameters */
|
---|
[1126] | 293 | if (pps->parameters.t == 1)
|
---|
| 294 | ret = PPS_InitProtocol (pps, 3); //FIXME in practice most T1 cards carry timing parameters in TA3, TB3 and TC3
|
---|
| 295 | else
|
---|
| 296 | ret = PPS_InitProtocol (pps, 2); //FIXME T0 cards carry timing parameters in TC2
|
---|
[8] | 297 |
|
---|
| 298 | return ret;
|
---|
| 299 | }
|
---|
| 300 |
|
---|
[565] | 301 | void * PPS_GetProtocol (PPS * pps)
|
---|
[8] | 302 | {
|
---|
| 303 | return pps->protocol;
|
---|
| 304 | }
|
---|
| 305 |
|
---|
[565] | 306 | PPS_ProtocolParameters *PPS_GetProtocolParameters (PPS * pps)
|
---|
[8] | 307 | {
|
---|
| 308 | /* User must Remember not to reference this struct after removing PPS */
|
---|
| 309 | return &(pps->parameters);
|
---|
| 310 | }
|
---|
| 311 |
|
---|
[565] | 312 | void PPS_Delete (PPS * pps)
|
---|
[8] | 313 | {
|
---|
[565] | 314 | free (pps);
|
---|
[8] | 315 | }
|
---|
| 316 |
|
---|
| 317 | /*
|
---|
| 318 | * Not exported funtions definition
|
---|
| 319 | */
|
---|
| 320 |
|
---|
[565] | 321 | static int PPS_Exchange (PPS * pps, BYTE * params, unsigned *length)
|
---|
[8] | 322 | {
|
---|
| 323 | BYTE confirm[PPS_MAX_LENGTH];
|
---|
| 324 | unsigned len_request, len_confirm;
|
---|
| 325 | int ret;
|
---|
| 326 | #ifdef DEBUG_PROTOCOL
|
---|
| 327 | int i;
|
---|
| 328 | #endif
|
---|
[565] | 329 |
|
---|
| 330 | len_request = PPS_GetLength (params);
|
---|
[8] | 331 | params[len_request - 1] = PPS_GetPCK(params, len_request - 1);
|
---|
[565] | 332 |
|
---|
[8] | 333 | #ifdef DEBUG_PROTOCOL
|
---|
[565] | 334 | printf ("PPS: Sending request: ");
|
---|
[8] | 335 | for (i = 0; i < len_request; i++)
|
---|
[565] | 336 | printf ("%X ", params[i]);
|
---|
| 337 | printf ("\n");
|
---|
[8] | 338 | #endif
|
---|
[735] | 339 |
|
---|
| 340 | cs_debug("PTS: Sending request: %s", cs_hexdump(1, params, len_request));
|
---|
[1177] | 341 |
|
---|
[8] | 342 | /* Send PPS request */
|
---|
[1177] | 343 | #ifdef COOL
|
---|
| 344 | //unsigned char ptsAck[10];
|
---|
| 345 | //u_int8 ptsLen = len_request;
|
---|
| 346 | unsigned short int ptsLen = len_request;
|
---|
| 347 | int Status = cnxt_smc_start_pps(handle, params, confirm, &ptsLen, TRUE);
|
---|
| 348 | printf ("cnxt_smc_start_pps Status=%i\n", Status);
|
---|
| 349 | len_confirm = ptsLen;
|
---|
| 350 | #ifdef DEBUG_PROTOCOL
|
---|
| 351 | printf("COOL: confirm: \n");
|
---|
| 352 | for (i = 0; i < ptsLen; i++)
|
---|
| 353 | printf ("%02X", confirm[i]);
|
---|
| 354 | printf ("\n");
|
---|
| 355 | fflush(stdout);
|
---|
| 356 | printf("COOL: req: \n");
|
---|
| 357 | for (i = 0; i < len_request; i++)
|
---|
| 358 | printf ("%02X", params[i]);
|
---|
| 359 | printf ("\n");
|
---|
| 360 | fflush(stdout);
|
---|
| 361 | #endif
|
---|
| 362 | if (Status)
|
---|
| 363 | return PPS_HANDSAKE_ERROR;
|
---|
| 364 | #else
|
---|
[565] | 365 | if (ICC_Async_Transmit (pps->icc, len_request, params) != ICC_ASYNC_OK)
|
---|
[8] | 366 | return PPS_ICC_ERROR;
|
---|
[565] | 367 |
|
---|
[8] | 368 | /* Get PPS confirm */
|
---|
[565] | 369 | if (ICC_Async_Receive (pps->icc, 2, confirm) != ICC_ASYNC_OK)
|
---|
[8] | 370 | return PPS_ICC_ERROR;
|
---|
[565] | 371 |
|
---|
| 372 | len_confirm = PPS_GetLength (confirm);
|
---|
| 373 |
|
---|
| 374 | if (ICC_Async_Receive (pps->icc, len_confirm - 2, confirm + 2) != ICC_ASYNC_OK)
|
---|
[8] | 375 | return PPS_ICC_ERROR;
|
---|
| 376 |
|
---|
| 377 | #ifdef DEBUG_PROTOCOL
|
---|
[565] | 378 | printf ("PPS: Receivig confirm: ");
|
---|
[8] | 379 | for (i = 0; i < len_confirm; i++)
|
---|
[565] | 380 | printf ("%X ", confirm[i]);
|
---|
| 381 | printf ("\n");
|
---|
[8] | 382 | #endif
|
---|
[565] | 383 |
|
---|
[735] | 384 | cs_debug("PTS: Receiving confirm: %s", cs_hexdump(1, confirm, len_confirm));
|
---|
| 385 |
|
---|
[565] | 386 | if (!PPS_Match (params, len_request, confirm, len_confirm))
|
---|
[8] | 387 | ret = PPS_HANDSAKE_ERROR;
|
---|
| 388 | else
|
---|
| 389 | ret = PPS_OK;
|
---|
[1177] | 390 | #endif
|
---|
[565] | 391 |
|
---|
[8] | 392 | /* Copy PPS handsake */
|
---|
[565] | 393 | memcpy (params, confirm, len_confirm);
|
---|
[8] | 394 | (*length) = len_confirm;
|
---|
[565] | 395 |
|
---|
[8] | 396 | return ret;
|
---|
| 397 | }
|
---|
| 398 |
|
---|
[565] | 399 | static bool PPS_Match (BYTE * request, unsigned len_request, BYTE * confirm, unsigned len_confirm)
|
---|
[8] | 400 | {
|
---|
| 401 | /* See if the reply differs from request */
|
---|
[750] | 402 | if ((len_request != len_confirm) || (memcmp (request, confirm, len_request)))
|
---|
[565] | 403 | {
|
---|
[8] | 404 | /* See if the card specifies other than default FI and D */
|
---|
[748] | 405 | //if ((PPS_HAS_PPS1 (confirm)) && (confirm[2] != request[2]))
|
---|
[8] | 406 | return FALSE;
|
---|
| 407 | }
|
---|
[565] | 408 |
|
---|
[8] | 409 | return TRUE;
|
---|
| 410 | }
|
---|
| 411 |
|
---|
[565] | 412 | static unsigned PPS_GetLength (BYTE * block)
|
---|
[8] | 413 | {
|
---|
| 414 | unsigned length = 3;
|
---|
[565] | 415 |
|
---|
| 416 | if (PPS_HAS_PPS1 (block))
|
---|
| 417 | length++;
|
---|
| 418 |
|
---|
| 419 | if (PPS_HAS_PPS2 (block))
|
---|
| 420 | length++;
|
---|
| 421 |
|
---|
| 422 | if (PPS_HAS_PPS3 (block))
|
---|
| 423 | length++;
|
---|
| 424 |
|
---|
[8] | 425 | return length;
|
---|
| 426 | }
|
---|
| 427 |
|
---|
[1126] | 428 | static int PPS_InitICC (PPS * pps)
|
---|
[8] | 429 | {
|
---|
[699] | 430 | #ifdef SCI_DEV
|
---|
[885] | 431 | #include <sys/ioctl.h>
|
---|
| 432 | #include "sci_global.h"
|
---|
| 433 | #include "sci_ioctl.h"
|
---|
[1210] | 434 | if(pps->icc->ifd->io->reader_type == R_INTERNAL)
|
---|
[885] | 435 | {
|
---|
| 436 | int n;
|
---|
| 437 | SCI_PARAMETERS params;
|
---|
| 438 | //memset(¶ms,0,sizeof(SCI_PARAMETERS));
|
---|
| 439 | if (ioctl(pps->icc->ifd->io->fd, IOCTL_GET_PARAMETERS, ¶ms) < 0 )
|
---|
| 440 | return PPS_ICC_ERROR;
|
---|
| 441 |
|
---|
[959] | 442 | ATR *atr = ICC_Async_GetAtr (pps->icc);
|
---|
[885] | 443 |
|
---|
| 444 | params.T = pps->parameters.t;
|
---|
[1078] | 445 | params.fs = atr_fs_table[pps->parameters.FI] / 1000000;
|
---|
[959] | 446 | double F = (double) atr_f_table[pps->parameters.FI];
|
---|
[1126] | 447 | //for Irdeto T14 cards, do not set ETU
|
---|
| 448 | if (!(atr->hbn >= 6 && !memcmp(atr->hb, "IRDETO", 6) && params.T == 14))
|
---|
| 449 | params.ETU = F / pps->parameters.d;
|
---|
[1064] | 450 | if (pps->parameters.n == 255) //only for T0 or also for T1?
|
---|
[885] | 451 | params.EGT = 0;
|
---|
| 452 | else
|
---|
| 453 | params.EGT = pps->parameters.n;
|
---|
| 454 |
|
---|
| 455 | double a;
|
---|
| 456 | ATR_GetParameter(atr, ATR_PARAMETER_P, &a);
|
---|
| 457 | params.P=(unsigned char)a;
|
---|
| 458 | ATR_GetParameter(atr, ATR_PARAMETER_I, &a);
|
---|
| 459 | params.I=(unsigned char)a;
|
---|
| 460 |
|
---|
[1078] | 461 | cs_debug("Setting T=%d fs=%lu mhz ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d", (int)params.T, params.fs, (int)params.ETU, (int)params.WWT, (int)params.CWT, (int)params.BWT, (int)params.EGT, (int)params.clock_stop_polarity, (int)params.check, (int)params.P, (int)params.I, (int)params.U);
|
---|
| 462 |
|
---|
[885] | 463 | if (ioctl(pps->icc->ifd->io->fd, IOCTL_SET_PARAMETERS, ¶ms)!=0)
|
---|
| 464 | return PPS_ICC_ERROR;
|
---|
[1078] | 465 |
|
---|
[885] | 466 | }
|
---|
[1177] | 467 | #elif COOL
|
---|
[1228] | 468 | if(reader[ridx].typ == R_INTERNAL) {
|
---|
[1189] | 469 | int mhz = atr_fs_table[pps->parameters.FI] / 10000;
|
---|
| 470 | if (!Cool_SetBaudrate(mhz))
|
---|
| 471 | return PPS_ICC_ERROR;
|
---|
[1177] | 472 | #ifdef DEBUG_PROTOCOL
|
---|
[1189] | 473 | printf("Coolstream: set clock to %i * 10kHz\n", mhz);
|
---|
[699] | 474 | #endif
|
---|
[1189] | 475 | return PPS_OK;
|
---|
[1177] | 476 | }
|
---|
| 477 | #endif
|
---|
[885] | 478 | {
|
---|
[8] | 479 | unsigned long baudrate;
|
---|
[885] | 480 | double F = (double) atr_f_table[pps->parameters.FI];
|
---|
[746] | 481 | if (pps->parameters.t == 14)
|
---|
| 482 | baudrate = 9600;
|
---|
| 483 | else
|
---|
[1228] | 484 | baudrate = pps->parameters.d * ICC_Async_GetClockRate () / F;
|
---|
[699] | 485 |
|
---|
[8] | 486 | #ifdef DEBUG_PROTOCOL
|
---|
[565] | 487 | printf ("PPS: Baudrate = %d\n", (int)baudrate);
|
---|
[8] | 488 | #endif
|
---|
[565] | 489 |
|
---|
[699] | 490 |
|
---|
[565] | 491 | if (ICC_Async_SetBaudrate (pps->icc, baudrate) != ICC_ASYNC_OK)
|
---|
[8] | 492 | return PPS_ICC_ERROR;
|
---|
[565] | 493 |
|
---|
[8] | 494 | return PPS_OK;
|
---|
[885] | 495 | }
|
---|
[8] | 496 | }
|
---|
| 497 |
|
---|
[885] | 498 | static int PPS_InitProtocol (PPS * pps, int selected_protocol)
|
---|
[8] | 499 | {
|
---|
| 500 | int ret;
|
---|
[565] | 501 |
|
---|
| 502 | if (pps->parameters.t == ATR_PROTOCOL_TYPE_T0)
|
---|
| 503 | {
|
---|
| 504 | pps->protocol = Protocol_T0_New ();
|
---|
| 505 |
|
---|
| 506 | if ((pps->protocol) != NULL)
|
---|
| 507 | {
|
---|
[885] | 508 | ret = Protocol_T0_Init ((Protocol_T0 *) pps->protocol, (ICC_Async *) pps->icc, &(pps->parameters), selected_protocol);
|
---|
[565] | 509 |
|
---|
| 510 | if (ret != PROTOCOL_T0_OK)
|
---|
| 511 | {
|
---|
| 512 | Protocol_T0_Delete ((Protocol_T0 *) pps->protocol);
|
---|
[8] | 513 | pps->protocol = NULL;
|
---|
| 514 | return PPS_PROTOCOL_ERROR;
|
---|
| 515 | }
|
---|
[565] | 516 |
|
---|
[8] | 517 | return PPS_OK;
|
---|
[565] | 518 | }
|
---|
| 519 | }
|
---|
| 520 | else if (pps->parameters.t == ATR_PROTOCOL_TYPE_T1)
|
---|
| 521 | {
|
---|
| 522 | pps->protocol = Protocol_T1_New ();
|
---|
| 523 |
|
---|
| 524 | if (pps->protocol != NULL)
|
---|
| 525 | {
|
---|
[1126] | 526 | ret = Protocol_T1_Init ((Protocol_T1 *) pps->protocol, (ICC_Async *) pps->icc, selected_protocol);
|
---|
[565] | 527 |
|
---|
| 528 | if (ret != PROTOCOL_T1_OK)
|
---|
| 529 | {
|
---|
| 530 | Protocol_T1_Delete ((Protocol_T1 *) pps->protocol);
|
---|
[8] | 531 | pps->protocol = NULL;
|
---|
| 532 | return PPS_PROTOCOL_ERROR;
|
---|
| 533 | }
|
---|
[565] | 534 |
|
---|
[8] | 535 | return PPS_OK;
|
---|
| 536 | }
|
---|
[565] | 537 | }
|
---|
| 538 | else if (pps->parameters.t == ATR_PROTOCOL_TYPE_T14)
|
---|
| 539 | {
|
---|
| 540 | pps->protocol = Protocol_T14_New ();
|
---|
| 541 |
|
---|
| 542 | if ((pps->protocol) != NULL)
|
---|
| 543 | {
|
---|
[885] | 544 | ret = Protocol_T14_Init ((Protocol_T14 *) pps->protocol, (ICC_Async *) pps->icc, &(pps->parameters), selected_protocol);
|
---|
[565] | 545 |
|
---|
| 546 | if (ret != PROTOCOL_T14_OK)
|
---|
| 547 | {
|
---|
| 548 | Protocol_T14_Delete ((Protocol_T14 *) pps->protocol);
|
---|
[8] | 549 | pps->protocol = NULL;
|
---|
| 550 | return PPS_PROTOCOL_ERROR;
|
---|
| 551 | }
|
---|
[565] | 552 |
|
---|
[8] | 553 | return PPS_OK;
|
---|
[565] | 554 | }
|
---|
| 555 | }
|
---|
| 556 | else
|
---|
| 557 | {
|
---|
[8] | 558 | pps->protocol = NULL;
|
---|
| 559 | }
|
---|
[565] | 560 |
|
---|
[8] | 561 | return PPS_PROTOCOL_ERROR;
|
---|
| 562 | }
|
---|
[959] | 563 |
|
---|
[565] | 564 | static BYTE PPS_GetPCK (BYTE * block, unsigned length)
|
---|
[8] | 565 | {
|
---|
| 566 | BYTE pck;
|
---|
| 567 | unsigned i;
|
---|
[565] | 568 |
|
---|
[8] | 569 | pck = block[0];
|
---|
| 570 | for (i = 1; i < length; i++)
|
---|
| 571 | pck ^= block[i];
|
---|
[565] | 572 |
|
---|
[8] | 573 | return pck;
|
---|
| 574 | }
|
---|