source: trunk/csctapi/pps.c@ 1285

Last change on this file since 1285 was 1285, checked in by dingo35, 11 years ago

Isolate T0 and T14 timing aspects and move them to pps.c

File size: 15.2 KB
Line 
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>
32#include "ifd.h"
33#include "../globals.h"
34
35/*
36 * Not exported constants definition
37 */
38
39#define PPS_DEFAULT_PROTOCOL 0x00
40#define PROTOCOL_T0_DEFAULT_WI 10
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
53static int PPS_Exchange (BYTE * params, unsigned *length);
54
55static bool PPS_Match (BYTE * request, unsigned len_request, BYTE * reply, unsigned len_reply);
56
57static unsigned PPS_GetLength (BYTE * block);
58
59static int PPS_InitICC ();
60
61static int PPS_InitProtocol ();
62
63static BYTE PPS_GetPCK (BYTE * block, unsigned length);
64
65/*
66 * Exported functions definition
67 */
68
69PPS * PPS_New ()
70{
71 PPS *pps;
72
73 pps = (PPS *) malloc (sizeof (PPS));
74
75 if (pps != NULL)
76 {
77 protocol = NULL;
78 parameters.t = PPS_DEFAULT_PROTOCOL;
79 parameters.FI = ATR_DEFAULT_FI;
80 parameters.d = ATR_DEFAULT_D;
81 parameters.n = ATR_DEFAULT_N;
82 }
83
84 return pps;
85}
86
87int PPS_Perform (PPS * pps, BYTE * params, unsigned *length)
88{
89 //Performs PPS Exchange on command when *length >0
90 //If unsuccesfull, or when length <= 0
91 //Gets parametes from ATR
92 //If necessary perform PPS session
93 //
94 //Output is pps->params.FI,n,d,t set with correct values
95 //and switched SC-device conform these values to correct baudrate
96 //
97 //We need to store FI instread of F, because SCI_DEV works with FI
98 //and it is easier to overclock then
99 //also from FI -> F is easy, other way around not
100
101 int ret;
102 bool PPS_success;
103
104 /* Perform PPS Exchange if requested by command */
105 if ((*length) > 0)
106 {
107 ret = PPS_Exchange (params, length);
108
109 /* Get parameters from PPS handsake */
110 if (ret == PPS_OK)
111 {
112 parameters.t = params[1] & 0x0F;
113
114 if (PPS_HAS_PPS1 (params))
115 {
116 parameters.FI = (params[2] >> 4);
117 parameters.d = atr_d_table[(params[2] & 0x0F)];
118 }
119
120/*
121 ret = PPS_InitICC(pps);
122
123 if (ret != PPS_OK)
124 return ret;
125*/
126 }
127/*
128 else
129 {
130 return ret;
131 }
132*/
133 }
134 PPS_success = PPS_OK;
135 int protocol_selected = 0; //stores which TAi,TBi etc. bytes must be used 0 means not set
136 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
137 {
138 int numprot = atr->pn;
139 //if there is a trailing TD, this number is one too high
140 BYTE tx;
141 if (ATR_GetInterfaceByte (atr, numprot-1, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK)
142 if ((tx & 0xF0) == 0)
143 numprot--;
144 cs_debug("ATR reports %i protocol lines:",numprot);
145 int i,point;
146 char txt[50];
147 bool OffersT[3]; //T14 stored as T2
148 for (i = 0; i <= 2; i++)
149 OffersT[i] = FALSE;
150 for (i=1; i<= numprot; i++) {
151 point = 0;
152 if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TA, &tx) == ATR_OK) {
153 sprintf((char *)txt+point,"TA%i=%02X ",i,tx);
154 point +=7;
155 }
156 if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TB, &tx) == ATR_OK) {
157 sprintf((char *)txt+point,"TB%i=%02X ",i,tx);
158 point +=7;
159 }
160 if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TC, &tx) == ATR_OK) {
161 sprintf((char *)txt+point,"TC%i=%02X ",i,tx);
162 point +=7;
163 }
164 if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK) {
165 sprintf((char *)txt+point,"TD%i=%02X ",i,tx);
166 point +=7;
167 tx &= 0X0F;
168 sprintf((char *)txt+point,"(T%i)",tx);
169 if (tx == 14)
170 OffersT[2] = TRUE;
171 else
172 OffersT[tx] = TRUE;
173 }
174 else {
175 sprintf((char *)txt+point,"no TD%i means T0",i);
176 OffersT[0] = TRUE;
177 }
178 cs_debug("%s",txt);
179 }
180
181 int numprottype = 0;
182 for (i = 0; i <= 2; i++)
183 if (OffersT[i])
184 numprottype ++;
185 cs_debug("%i protocol types detected. Historical bytes: %s",numprottype, cs_hexdump(1,atr->hb,atr->hbn));
186
187//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.
188 ATR_GetParameter (atr, ATR_PARAMETER_N, &(parameters.n));
189 ATR_GetProtocolType(atr,1,&(parameters.t)); //get protocol from TD1
190 BYTE TA2;
191 bool SpecificMode = (ATR_GetInterfaceByte (atr, 2, ATR_INTERFACE_BYTE_TA, &TA2) == ATR_OK); //if TA2 present, specific mode, else negotiable mode
192 if (SpecificMode) {
193 parameters.t = TA2 & 0x0F;
194 if ((TA2 & 0x10) != 0x10) { //bit 5 set to 0 means F and D explicitly defined in interface characters
195 BYTE TA1;
196 if (ATR_GetInterfaceByte (atr, 1 , ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) {
197 parameters.FI = TA1 >> 4;
198 ATR_GetParameter (atr, ATR_PARAMETER_D, &(parameters.d));
199 }
200 else {
201 parameters.FI = ATR_DEFAULT_FI;
202 parameters.d = ATR_DEFAULT_D;
203 }
204 }
205 else {
206 cs_log("Specific mode: speed 'implicitly defined', not sure how to proceed, assuming default values");
207 parameters.FI = ATR_DEFAULT_FI;
208 parameters.d = ATR_DEFAULT_D;
209 }
210 cs_debug("Specific mode: T%i, F=%.0f, D=%.6f, N=%.0f\n", parameters.t, (double) atr_f_table[parameters.FI], parameters.d, parameters.n);
211 }
212 else { //negotiable mode
213
214 bool NeedsPTS = ((parameters.t != 14) && (numprottype > 1 || (atr->ib[0][ATR_INTERFACE_BYTE_TA].present == TRUE && atr->ib[0][ATR_INTERFACE_BYTE_TA].value != 0x11) || parameters.n == 255)); //needs PTS according to ISO 7816 , SCI gets stuck on our PTS
215 if (NeedsPTS) {
216 // PTSS PTS0 PTS1 PTS2 PTS3 PCK
217 // PTSS PTS0 PTS1 PCK
218 BYTE req[] = { 0xFF, 0x10, 0x00, 0x00 }; //we currently do not support PTS2, standard guardtimes
219 req[1]=0x10 | parameters.t; //PTS0 always flags PTS1 to be sent always
220 if (ATR_GetInterfaceByte (atr, 1, ATR_INTERFACE_BYTE_TA, &req[2]) != ATR_OK) //PTS1
221 req[2] = 0x11; //defaults FI and DI to 1
222 //req[3]=PPS_GetPCK(req,sizeof(req)-1); will be set by PPS_Exchange
223 unsigned int len = sizeof(req);
224 ret = PPS_Exchange (req, &len);
225 if (ret == PPS_OK) {
226 parameters.FI = req[2] >> 4;
227 BYTE DI = req[2] & 0x0F;
228 parameters.d = (double) (atr_d_table[DI]);
229 PPS_success = TRUE;
230 cs_debug("PTS Succesfull, selected protocol: T%i, F=%.0f, D=%.6f, N=%.0f\n", parameters.t, (double) atr_f_table[parameters.FI], parameters.d, parameters.n);
231 }
232 else
233 cs_ddump(req,4,"PTS Failure, response:");
234 }
235
236 //FIXME Currently InitICC sets baudrate to 9600 for all T14 cards (=no switching);
237 //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)
238 if (!PPS_success) {//last PPS not succesfull
239 BYTE TA1;
240 if (ATR_GetInterfaceByte (atr, 1 , ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) {
241 parameters.FI = TA1 >> 4;
242 ATR_GetParameter (atr, ATR_PARAMETER_D, &(parameters.d));
243 }
244 else { //do not obey TA1
245 parameters.FI = ATR_DEFAULT_FI;
246 parameters.d = ATR_DEFAULT_D;
247 }
248 ATR_GetProtocolType (atr, 1, &(parameters.t));
249 protocol_selected = 1;
250
251 if (NeedsPTS) {
252 if ((parameters.d == 32) || (parameters.d == 12) || (parameters.d == 20))
253 parameters.d = 0; //behave conform "old" atr_d_table; viaccess cards that fail PTS need this
254 }
255 /////Here all non-ISO behaviour
256 /////End all non-ISO behaviour
257
258 cs_debug("No PTS %s, selected protocol T%i, F=%.0f, D=%.6f, N=%.0f\n", NeedsPTS?"happened":"needed", parameters.t, (double) atr_f_table[parameters.FI], parameters.d, parameters.n);
259 }
260 }//end negotiable mode
261 }//end length<0
262
263 //make sure no zero values
264 double F = (double) atr_f_table[parameters.FI];
265 if (!F) {
266 parameters.FI = ATR_DEFAULT_FI;
267 cs_log("Warning: F=0 is invalid, forcing FI=%d", parameters.FI);
268 }
269 if (!parameters.d) {
270 parameters.d = ATR_DEFAULT_D;
271 cs_log("Warning: D=0 is invalid, forcing D=%.0f",parameters.d);
272 }
273
274 protocol_type = parameters.t;
275
276#ifdef DEBUG_PROTOCOL
277 printf("PPS: T=%i, F=%.0f, D=%.6f, N=%.0f\n",
278 parameters.t,
279 F,
280 parameters.d,
281 parameters.n);
282#endif
283
284 ret = PPS_InitICC(pps);
285
286 if (ret != PPS_OK)
287 return ret;
288
289 /* Initialize selected protocol with selected parameters */
290 return PPS_InitProtocol ();
291}
292
293void * PPS_GetProtocol ()
294{
295 return protocol;
296}
297
298PPS_ProtocolParameters *PPS_GetProtocolParameters ()
299{
300 /* User must Remember not to reference this struct after removing PPS */
301 return &(parameters);
302}
303
304void PPS_Delete (PPS * pps)
305{
306 free (pps);
307}
308
309/*
310 * Not exported funtions definition
311 */
312
313static int PPS_Exchange (BYTE * params, unsigned *length)
314{
315 BYTE confirm[PPS_MAX_LENGTH];
316 unsigned len_request, len_confirm;
317 int ret;
318#ifdef DEBUG_PROTOCOL
319 int i;
320#endif
321
322 len_request = PPS_GetLength (params);
323 params[len_request - 1] = PPS_GetPCK(params, len_request - 1);
324
325#ifdef DEBUG_PROTOCOL
326 printf ("PPS: Sending request: ");
327 for (i = 0; i < len_request; i++)
328 printf ("%X ", params[i]);
329 printf ("\n");
330#endif
331
332 cs_debug("PTS: Sending request: %s", cs_hexdump(1, params, len_request));
333
334 /* Send PPS request */
335#ifdef COOL
336 //unsigned char ptsAck[10];
337 //u_int8 ptsLen = len_request;
338 unsigned short int ptsLen = len_request;
339 int Status = cnxt_smc_start_pps(handle, params, confirm, &ptsLen, TRUE);
340 printf ("cnxt_smc_start_pps Status=%i\n", Status);
341 len_confirm = ptsLen;
342#ifdef DEBUG_PROTOCOL
343 printf("COOL: confirm: \n");
344 for (i = 0; i < ptsLen; i++)
345 printf ("%02X", confirm[i]);
346 printf ("\n");
347 fflush(stdout);
348 printf("COOL: req: \n");
349 for (i = 0; i < len_request; i++)
350 printf ("%02X", params[i]);
351 printf ("\n");
352 fflush(stdout);
353#endif
354 if (Status)
355 return PPS_HANDSAKE_ERROR;
356#else
357 if (ICC_Async_Transmit (len_request, params) != ICC_ASYNC_OK)
358 return PPS_ICC_ERROR;
359
360 /* Get PPS confirm */
361 if (ICC_Async_Receive (2, confirm) != ICC_ASYNC_OK)
362 return PPS_ICC_ERROR;
363
364 len_confirm = PPS_GetLength (confirm);
365
366 if (ICC_Async_Receive (len_confirm - 2, confirm + 2) != ICC_ASYNC_OK)
367 return PPS_ICC_ERROR;
368
369#ifdef DEBUG_PROTOCOL
370 printf ("PPS: Receivig confirm: ");
371 for (i = 0; i < len_confirm; i++)
372 printf ("%X ", confirm[i]);
373 printf ("\n");
374#endif
375
376 cs_debug("PTS: Receiving confirm: %s", cs_hexdump(1, confirm, len_confirm));
377
378 if (!PPS_Match (params, len_request, confirm, len_confirm))
379 ret = PPS_HANDSAKE_ERROR;
380 else
381 ret = PPS_OK;
382#endif
383
384 /* Copy PPS handsake */
385 memcpy (params, confirm, len_confirm);
386 (*length) = len_confirm;
387
388 return ret;
389}
390
391static bool PPS_Match (BYTE * request, unsigned len_request, BYTE * confirm, unsigned len_confirm)
392{
393 /* See if the reply differs from request */
394 if ((len_request != len_confirm) || (memcmp (request, confirm, len_request)))
395 {
396 /* See if the card specifies other than default FI and D */
397 //if ((PPS_HAS_PPS1 (confirm)) && (confirm[2] != request[2]))
398 return FALSE;
399 }
400
401 return TRUE;
402}
403
404static unsigned PPS_GetLength (BYTE * block)
405{
406 unsigned length = 3;
407
408 if (PPS_HAS_PPS1 (block))
409 length++;
410
411 if (PPS_HAS_PPS2 (block))
412 length++;
413
414 if (PPS_HAS_PPS3 (block))
415 length++;
416
417 return length;
418}
419
420static int PPS_InitICC ()
421{
422#ifdef SCI_DEV
423#include <sys/ioctl.h>
424#include "sci_global.h"
425#include "sci_ioctl.h"
426 if(reader[ridx].typ == R_INTERNAL)
427 {
428 int n;
429 SCI_PARAMETERS params;
430 //memset(&params,0,sizeof(SCI_PARAMETERS));
431 if (ioctl(reader[ridx].handle, IOCTL_GET_PARAMETERS, &params) < 0 )
432 return PPS_ICC_ERROR;
433
434 params.T = parameters.t;
435 params.fs = atr_fs_table[parameters.FI] / 1000000;
436 double F = (double) atr_f_table[parameters.FI];
437 //for Irdeto T14 cards, do not set ETU
438 if (!(atr->hbn >= 6 && !memcmp(atr->hb, "IRDETO", 6) && params.T == 14))
439 params.ETU = F / parameters.d;
440 if (parameters.n == 255) //only for T0 or also for T1?
441 params.EGT = 0;
442 else
443 params.EGT = parameters.n;
444
445 double a;
446 ATR_GetParameter(atr, ATR_PARAMETER_P, &a);
447 params.P=(unsigned char)a;
448 ATR_GetParameter(atr, ATR_PARAMETER_I, &a);
449 params.I=(unsigned char)a;
450
451 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);
452
453 if (ioctl(reader[ridx].handle, IOCTL_SET_PARAMETERS, &params)!=0)
454 return PPS_ICC_ERROR;
455
456 }
457#elif COOL
458 if(reader[ridx].typ == R_INTERNAL) {
459 int mhz = atr_fs_table[parameters.FI] / 10000;
460 if (!Cool_SetBaudrate(mhz))
461 return PPS_ICC_ERROR;
462#ifdef DEBUG_PROTOCOL
463 printf("Coolstream: set clock to %i * 10kHz\n", mhz);
464#endif
465 return PPS_OK;
466 }
467#endif
468 {
469 unsigned long baudrate;
470 double F = (double) atr_f_table[parameters.FI];
471 if (parameters.t == 14)
472 baudrate = 9600;
473 else
474 baudrate = parameters.d * ICC_Async_GetClockRate () / F;
475
476#ifdef DEBUG_PROTOCOL
477 printf ("PPS: Baudrate = %d\n", (int)baudrate);
478#endif
479
480
481 if (ICC_Async_SetBaudrate (baudrate) != ICC_ASYNC_OK)
482 return PPS_ICC_ERROR;
483
484 return PPS_OK;
485 }
486}
487
488static int PPS_InitProtocol ()
489{
490 int ret;
491
492 if ((parameters.t == ATR_PROTOCOL_TYPE_T0) || (parameters.t == ATR_PROTOCOL_TYPE_T14))
493 {
494 BYTE wi;
495
496 /* Integer value WI = TC2, by default 10 */
497#ifndef PROTOCOL_T0_USE_DEFAULT_TIMINGS
498 if (ATR_GetInterfaceByte (atr, 2, ATR_INTERFACE_BYTE_TC, &(wi)) != ATR_OK)
499#endif
500 wi = PROTOCOL_T0_DEFAULT_WI;
501
502 /* WWT = 960 * WI * (Fi / f) * 1000 milliseconds */
503 double F = (double) atr_f_table[parameters.FI];
504 unsigned long wwt = (long unsigned int) (960 * wi * (F / ICC_Async_GetClockRate ()) * 1000);
505 if (parameters.t == 14)
506 wwt >>= 1; //is this correct?
507
508 /* Set timings */
509 icc_timings.block_timeout = wwt;
510 icc_timings.char_timeout = wwt;
511 ICC_Async_SetTimings ();
512
513#ifdef DEBUG_PROTOCOL
514 printf ("Protocol: T=%i: WWT=%d, Clockrate=%lu\n", params->t, (int)(wwt),ICC_Async_GetClockRate());
515#endif
516 return PPS_OK;
517 }
518 else if (parameters.t == ATR_PROTOCOL_TYPE_T1)
519 {
520 ret = Protocol_T1_Init ();
521
522 if (ret != PROTOCOL_T1_OK)
523 {
524 protocol = NULL;
525 return PPS_PROTOCOL_ERROR;
526 }
527
528 return PPS_OK;
529 }
530 else
531 {
532 protocol = NULL;
533 }
534
535 return PPS_PROTOCOL_ERROR;
536}
537
538static BYTE PPS_GetPCK (BYTE * block, unsigned length)
539{
540 BYTE pck;
541 unsigned i;
542
543 pck = block[0];
544 for (i = 1; i < length; i++)
545 pck ^= block[i];
546
547 return pck;
548}
Note: See TracBrowser for help on using the repository browser.