source: branches/smartreader/csctapi/ifd_towitoko.c@ 1186

Last change on this file since 1186 was 1186, checked in by rorothetroll, 12 years ago

resync with trunk. Old smartreader code is gone (and will soon be gone from trunk). I'm restarting from trunk to do a clean implementation of the samrtreader support using libusb.

File size: 19.2 KB
Line 
1/*
2 ifd_towitoko.c
3 This module provides IFD handling functions.
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 "defines.h"
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#ifdef OS_HPUX
30#include <sys/modem.h>
31#endif
32#include <termios.h>
33#include <unistd.h>
34#include <sys/stat.h>
35#include <fcntl.h>
36#ifdef HAVE_POLL
37#include <sys/poll.h>
38#else
39#include <sys/signal.h>
40#include <sys/types.h>
41#include <sys/time.h>
42#endif
43#include <sys/ioctl.h>
44#include <time.h>
45#include "ifd_towitoko.h"
46#include "io_serial.h"
47#include "sci_global.h"
48#include "sci_ioctl.h"
49#include "ifd.h"
50
51/*
52 * Not exported constants
53 */
54
55#define IFD_TOWITOKO_TIMEOUT 1000
56#define IFD_TOWITOKO_DELAY 0
57#define IFD_TOWITOKO_BAUDRATE 9600
58//#define IFD_TOWITOKO_PS 15
59#define IFD_TOWITOKO_MAX_TRANSMIT 255
60//#define IFD_TOWITOKO_ATR_TIMEOUT 200
61//#define IFD_TOWITOKO_ATR_TIMEOUT 400
62#define IFD_TOWITOKO_ATR_TIMEOUT 800
63#define IFD_TOWITOKO_ATR_MIN_LENGTH 1
64#define IFD_TOWITOKO_CLOCK_RATE (625L * 9600L)
65//#define IFD_TOWITOKO_CLOCK_RATE (372L * 9600L)
66
67#define HI(a) (((a) & 0xff00) >> 8)
68#define LO(a) ((a) & 0x00ff)
69
70/*
71 * Not exported functions declaration
72 */
73
74static int IFD_Towitoko_GetReaderInfo (IFD * ifd);
75static void IFD_Towitoko_Clear (IFD * ifd);
76
77#ifdef USE_GPIO
78
79int gpio_outen,gpio_out,gpio_in;
80unsigned int pin,gpio;
81int gpio_detect=0;
82
83static void set_gpio(int level)
84{
85 read(gpio_outen, &gpio, sizeof(gpio));
86 gpio |= pin;
87 write(gpio_outen, &gpio, sizeof(gpio));
88
89 read(gpio_out, &gpio, sizeof(gpio));
90 if (level>0)
91 gpio|=pin;
92 else
93 gpio&=~pin;
94 write(gpio_out, &gpio, sizeof(gpio));
95}
96
97static void set_gpio1(int level)
98{
99 read(gpio_outen, &gpio, sizeof(gpio));
100 gpio |= 2;
101 write(gpio_outen, &gpio, sizeof(gpio));
102
103 read(gpio_out, &gpio, sizeof(gpio));
104 if (level>0)
105 gpio|=2;
106 else
107 gpio&=~2;
108 write(gpio_out, &gpio, sizeof(gpio));
109}
110
111static void set_gpio_input(void)
112{
113 read(gpio_outen, &gpio, sizeof(gpio));
114 gpio &= ~pin;
115 write(gpio_outen, &gpio, sizeof(gpio));
116}
117
118static int get_gpio(void)
119{
120 set_gpio_input();
121 read(gpio_in, &gpio, sizeof(gpio));
122 return ((int)((gpio&pin)?1:0));
123}
124#endif
125
126/*
127 * Exported functions definition
128 */
129
130IFD * IFD_Towitoko_New ()
131{
132 IFD *ifd;
133
134 ifd = (IFD *) malloc (sizeof (IFD));
135
136 if (ifd != NULL)
137 IFD_Towitoko_Clear (ifd);
138
139 return ifd;
140}
141
142void IFD_Towitoko_Delete (IFD * ifd)
143{
144 free (ifd);
145}
146
147int IFD_Towitoko_Init (IFD * ifd, IO_Serial * io, BYTE slot)
148{
149 int ret;
150
151#ifdef USE_GPIO
152 extern int oscam_card_detect;
153 if (oscam_card_detect>4)
154 {
155 gpio_detect=oscam_card_detect-3;
156 pin = 1<<gpio_detect;
157 gpio_outen=open("/dev/gpio/outen",O_RDWR);
158 gpio_out=open("/dev/gpio/out",O_RDWR);
159 gpio_in=open("/dev/gpio/in",O_RDWR);
160 set_gpio_input();
161 }
162#endif
163
164#ifdef DEBUG_IFD
165 printf ("IFD: Initializing slot number %d, com=%d\n", slot, io->com);
166#endif
167
168// if ((slot != IFD_TOWITOKO_SLOT_MULTICAM) && (slot != IFD_TOWITOKO_SLOT_A) && (slot != IFD_TOWITOKO_SLOT_B))
169 if (slot != IFD_TOWITOKO_SLOT_MULTICAM )
170 return IFD_TOWITOKO_PARAM_ERROR;
171
172 if(io->com==RTYP_SCI)
173 {
174 ifd->io = io;
175 ifd->slot = slot;
176 ifd->type = IFD_TOWITOKO_MULTICAM;
177 return IFD_TOWITOKO_OK;
178 }
179
180
181 /* Default serial port settings */
182 io->input_bitrate = IFD_TOWITOKO_BAUDRATE;
183 io->output_bitrate = IFD_TOWITOKO_BAUDRATE;
184 io->bits = 8;
185 io->stopbits = 2;
186 io->parity = IO_SERIAL_PARITY_EVEN;
187 io->dtr = IO_SERIAL_HIGH;
188// io->dtr = IO_SERIAL_LOW;
189// io->rts = IO_SERIAL_HIGH;
190 io->rts = IO_SERIAL_LOW;
191
192
193 if (!IO_Serial_SetProperties (io))
194 return IFD_TOWITOKO_IO_ERROR;
195
196 /* Default ifd settings */
197
198 ifd->io = io;
199 ifd->slot = slot;
200 ifd->type = IFD_TOWITOKO_MULTICAM;
201
202 ret = IFD_Towitoko_SetBaudrate (ifd, IFD_TOWITOKO_BAUDRATE);
203
204 if (ret != IFD_TOWITOKO_OK)
205 {
206 IFD_Towitoko_Clear (ifd);
207 return ret;
208 }
209
210 ret = IFD_Towitoko_SetParity (ifd, IFD_TOWITOKO_PARITY_EVEN);
211
212 if (ret != IFD_TOWITOKO_OK)
213 {
214 IFD_Towitoko_Clear (ifd);
215 return ret;
216 }
217
218 ret = IFD_Towitoko_GetReaderInfo (ifd);
219
220 if (ret != IFD_TOWITOKO_OK)
221 {
222 IFD_Towitoko_Clear (ifd);
223 }
224 else
225 {
226 IO_Serial_Flush(ifd->io);
227 }
228
229 return ret;
230}
231
232int IFD_Towitoko_Close (IFD * ifd)
233{
234 int ret;
235
236#ifdef USE_GPIO
237 if(gpio_detect)
238 {
239 close(gpio_outen);
240 close(gpio_out);
241 close(gpio_in);
242 }
243#endif
244
245#ifdef DEBUG_IFD
246 printf ("IFD: Closing slot number %d\n", ifd->slot);
247#endif
248
249 ret = IFD_Towitoko_SetLED ();
250 if (ret != IFD_TOWITOKO_OK)
251 return ret;
252
253 IFD_Towitoko_Clear (ifd);
254
255
256 return IFD_TOWITOKO_OK;
257}
258
259int IFD_Towitoko_SetBaudrate (IFD * ifd, unsigned long baudrate)
260{
261 if(ifd->io->com==RTYP_SCI)
262 {
263 return IFD_TOWITOKO_OK;
264 }
265/*
266 if (IFD_Towitoko_GetMaxBaudrate () < baudrate)
267 {
268#ifdef DEBUG_IFD
269 printf ("IFD: Tried to set unsupported baudrate: %lu", baudrate);
270#endif
271 return IFD_TOWITOKO_PARAM_ERROR;
272 }*/
273
274#ifdef DEBUG_IFD
275 printf ("IFD: Setting baudrate to %lu\n", baudrate);
276#endif
277 /* Get current settings */
278 if (!IO_Serial_GetProperties (ifd->io))
279 return IFD_TOWITOKO_IO_ERROR;
280
281 if (ifd->io->output_bitrate == baudrate)
282 return IFD_TOWITOKO_OK;
283
284
285 /* Set serial device bitrate */
286 ifd->io->output_bitrate = baudrate;
287 ifd->io->input_bitrate = baudrate;
288
289 if (!IO_Serial_SetProperties (ifd->io))
290 return IFD_TOWITOKO_IO_ERROR;
291
292 return IFD_TOWITOKO_OK;
293}
294
295int IFD_Towitoko_GetBaudrate (IFD * ifd, unsigned long *baudrate)
296{
297 if(ifd->io->com==RTYP_SCI)
298 {
299 return IFD_TOWITOKO_OK;
300 }
301
302 /* Get current settings */
303 if (!IO_Serial_GetProperties (ifd->io))
304 return IFD_TOWITOKO_IO_ERROR;
305
306 (*baudrate) = ifd->io->output_bitrate;
307
308 return IFD_TOWITOKO_OK;
309}
310
311extern int IFD_Towitoko_SetParity (IFD * ifd, BYTE parity)
312{
313 if(ifd->io->com==RTYP_SCI)
314 {
315 return IFD_TOWITOKO_OK;
316 }
317
318#ifdef DEBUG_IFD
319 printf ("IFD: Parity = %s\n",
320 parity == IFD_TOWITOKO_PARITY_ODD ? "Odd" :
321 parity == IFD_TOWITOKO_PARITY_EVEN ? "Even" : "Invalid");
322#endif
323
324 if ((parity != IFD_TOWITOKO_PARITY_EVEN) && (parity != IFD_TOWITOKO_PARITY_ODD) && (parity != IFD_TOWITOKO_PARITY_NONE))
325 return IFD_TOWITOKO_PARAM_ERROR;
326
327 /* Get current settings */
328 if (!IO_Serial_GetProperties (ifd->io))
329 return IFD_TOWITOKO_IO_ERROR;
330
331 if (ifd->io->parity !=parity)
332 {
333 ifd->io->parity = parity;
334
335 if (!IO_Serial_SetProperties (ifd->io))
336 return IFD_TOWITOKO_IO_ERROR;
337 }
338
339 return IFD_TOWITOKO_OK;
340}
341
342int IFD_Towitoko_SetLED ()
343{
344 return IFD_TOWITOKO_OK;
345}
346
347int IFD_Towitoko_GetStatus (IFD * ifd, BYTE * result)
348{
349 BYTE status[2];
350 unsigned int modembits=0;
351 int in;
352
353// printf("\n%08X\n", (int)ifd->io);
354
355// status : 0 -start, 1 - card, 2- no card
356
357#ifdef SCI_DEV
358 if(ifd->io->com==RTYP_SCI)
359 {
360 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
361 return IFD_TOWITOKO_IO_ERROR;
362 }
363 else
364#elif COOL
365 if(ifd->io->com==RTYP_SCI)
366 {
367 if (!Cool_GetStatus(&in))
368 return IFD_TOWITOKO_IO_ERROR;
369 }
370 else
371#endif
372
373#if defined(TUXBOX) && defined(PPC)
374 if ((ifd->io->com==RTYP_DB2COM1) || (ifd->io->com==RTYP_DB2COM2))
375 {
376 ushort msr=1;
377 extern int fdmc;
378 IO_Serial_Ioctl_Lock(ifd->io, 1);
379 ioctl(fdmc, GET_PCDAT, &msr);
380 if (ifd->io->com==RTYP_DB2COM2)
381 in=(!(msr & 1));
382 else
383 in=((msr & 0x0f00) == 0x0f00);
384 IO_Serial_Ioctl_Lock(ifd->io, 0);
385 }
386 else
387#endif
388#ifdef USE_GPIO
389 if (gpio_detect)
390 in=get_gpio();
391 else
392#endif
393 {
394 extern int oscam_card_detect;
395 if (ioctl(ifd->io->fd, TIOCMGET,&modembits)<0)
396 return IFD_TOWITOKO_IO_ERROR;
397 switch(oscam_card_detect&0x7f)
398 {
399 case 0: in=(modembits & TIOCM_CAR); break;
400 case 1: in=(modembits & TIOCM_DSR); break;
401 case 2: in=(modembits & TIOCM_CTS); break;
402 case 3: in=(modembits & TIOCM_RNG); break;
403 default: in=0; // dummy
404 }
405 if (!(oscam_card_detect&0x80))
406 in=!in;
407 }
408
409 if (in)
410 {
411 if(ifd->status == 0)
412 {
413 status[0] = IFD_TOWITOKO_CARD_CHANGE;
414 ifd->status = 1;
415#ifdef USE_GPIO
416 if (gpio_detect) set_gpio1(0);
417#endif
418 }
419 else if(ifd->status == 1)
420 {
421 status[0] = IFD_TOWITOKO_CARD_NOCHANGE;
422 }
423 else
424 {
425 status[0] = IFD_TOWITOKO_CARD_CHANGE;
426 ifd->status = 1;
427#ifdef USE_GPIO
428 if (gpio_detect) set_gpio1(0);
429#endif
430 }
431 }
432 else
433 {
434 if(ifd->status == 0)
435 {
436 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
437 ifd->status = 2;
438#ifdef USE_GPIO
439 if (gpio_detect) set_gpio1(1);
440#endif
441 }
442 else if(ifd->status == 1)
443 {
444 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
445 ifd->status = 2;
446#ifdef USE_GPIO
447 if (gpio_detect) set_gpio1(1);
448#endif
449 }
450 else
451 {
452 status[0] = IFD_TOWITOKO_NOCARD_NOCHANGE;
453 }
454 }
455
456
457 (*result) = status[0];
458
459#ifdef DEBUG_IFD
460 printf ("IFD: com%d Status = %s / %s\n", ifd->io->com, IFD_TOWITOKO_CARD(status[0])? "card": "no card", IFD_TOWITOKO_CHANGE(status[0])? "change": "no change");
461#endif
462
463 return IFD_TOWITOKO_OK;
464}
465
466int IFD_Towitoko_ActivateICC (IFD * ifd)
467{
468#ifdef DEBUG_IFD
469 printf ("IFD: Activating card\n");
470#endif
471#ifdef SCI_DEV
472 if(ifd->io->com==RTYP_SCI)
473 {
474 int in;
475
476#if defined(TUXBOX) && (defined(MIPSEL) || defined(PPC) || defined(SH4))
477 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
478#else
479 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_ACTIVATED, &in)<0)
480#endif
481 return IFD_TOWITOKO_IO_ERROR;
482
483 if(in)
484 {
485 struct timespec req_ts;
486 req_ts.tv_sec = 0;
487 req_ts.tv_nsec = 50000000;
488 nanosleep (&req_ts, NULL);
489 return IFD_TOWITOKO_OK;
490 }
491 else
492 {
493 return IFD_TOWITOKO_IO_ERROR;
494 }
495 }
496 else
497#endif
498 {
499 return IFD_TOWITOKO_OK;
500 }
501}
502
503int IFD_Towitoko_DeactivateICC (IFD * ifd)
504{
505#ifdef DEBUG_IFD
506 printf ("IFD: Deactivating card\n");
507#endif
508
509#ifdef SCI_DEV
510 if(ifd->io->com==RTYP_SCI)
511 {
512 int in;
513
514#if defined(TUXBOX) && (defined(MIPSEL) || defined(PPC) || defined(SH4))
515 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
516#else
517 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_ACTIVATED, &in)<0)
518#endif
519 return IFD_TOWITOKO_IO_ERROR;
520
521 if(in)
522 {
523 if(ioctl(ifd->io->fd, IOCTL_SET_DEACTIVATE)<0)
524 return IFD_TOWITOKO_IO_ERROR;
525 }
526
527
528 }
529#endif
530
531 return IFD_TOWITOKO_OK;
532}
533
534//extern void print_hex_data(unsigned char *data, int len);
535
536int IFD_Towitoko_ResetAsyncICC (IFD * ifd, ATR ** atr)
537{
538
539#ifdef DEBUG_IFD
540 printf ("IFD: Resetting card:\n");
541#endif
542
543#ifdef SCI_DEV
544 if(ifd->io->com==RTYP_SCI)
545 {
546 unsigned char buf[SCI_MAX_ATR_SIZE];
547 int n = 0;
548 SCI_PARAMETERS params;
549#ifdef SH4
550 struct timeval tv, tv_spent;
551 int atr_size = 2, TDi_exists = 0;
552#endif
553
554 (*atr) = NULL;
555
556#ifdef SH4
557 memset(&params,0,sizeof(SCI_PARAMETERS));
558
559 params.ETU = 372;
560 params.EGT = 3;
561 params.fs = 9;
562 params.T = 0;
563
564 if(ioctl(ifd->io->fd, IOCTL_SET_PARAMETERS, &params)!=0)
565 return IFD_TOWITOKO_IO_ERROR;
566#endif
567
568 if(ioctl(ifd->io->fd, IOCTL_SET_RESET)<0)
569 return IFD_TOWITOKO_IO_ERROR;
570
571#ifdef SH4
572 gettimeofday(&tv,0);
573 memcpy(&tv_spent,&tv,sizeof(struct timeval));
574
575 while(n<atr_size && (tv_spent.tv_sec-tv.tv_sec)<10)
576 {
577 if(IO_Serial_Read(ifd->io, IFD_TOWITOKO_ATR_TIMEOUT, 1, buf+n))
578 n++;
579 gettimeofday(&tv_spent,0);
580 if(n==2) // format character
581 {
582 // high nibble = TA1 , TB1 , TC1 , TD1
583 if(buf[n-1] & 0x10)
584 atr_size++;
585 if(buf[n-1] & 0x20)
586 atr_size++;
587 if(buf[n-1] & 0x40)
588 atr_size++;
589 if(buf[n-1] & 0x80)
590 {
591 atr_size++;
592 TDi_exists=atr_size;
593 }
594 atr_size+=(buf[n-1] & 0x0F); // historical bytes
595 }
596 if( (TDi_exists>0) && (n==TDi_exists) )
597 {
598 TDi_exists=0;
599 // high nibble = TA1 , TB1 , TC1 , TD1
600 if(buf[n-1] & 0x10)
601 atr_size++;
602 if(buf[n-1] & 0x20)
603 atr_size++;
604 if(buf[n-1] & 0x40)
605 atr_size++;
606 if(buf[n-1] & 0x80)
607 {
608 atr_size++;
609 TDi_exists=atr_size;
610 }
611 }
612 }
613#else
614 while(n<SCI_MAX_ATR_SIZE && IO_Serial_Read(ifd->io, IFD_TOWITOKO_ATR_TIMEOUT, 1, buf+n))
615 {
616 n++;
617 }
618#endif
619
620 if(n==0)
621 return IFD_TOWITOKO_IO_ERROR;
622#endif
623
624#ifdef SCI_DEV
625 (*atr) = ATR_New ();
626 if(ATR_InitFromArray ((*atr), buf, n) == ATR_OK)
627 {
628 struct timespec req_ts;
629 req_ts.tv_sec = 0;
630 req_ts.tv_nsec = 50000000;
631 nanosleep (&req_ts, NULL);
632#ifdef SCI_DEV
633 if (ioctl(ifd->io->fd, IOCTL_SET_ATR_READY)<0)
634 return IFD_TOWITOKO_IO_ERROR;
635#endif
636 return IFD_TOWITOKO_OK;
637 }
638 else
639 {
640 ATR_Delete (*atr);
641 (*atr) = NULL;
642 return IFD_TOWITOKO_IO_ERROR;
643 }
644 }
645 else
646#endif
647 {
648 int ret;
649 int parity;
650 int i;
651 int par[3] = {IFD_TOWITOKO_PARITY_EVEN, IFD_TOWITOKO_PARITY_ODD, IFD_TOWITOKO_PARITY_NONE};
652#ifdef HAVE_NANOSLEEP
653 struct timespec req_ts;
654 req_ts.tv_sec = 0;
655 req_ts.tv_nsec = 50000000;
656#endif
657
658 (*atr) = NULL;
659 for(i=0; i<3; i++)
660 {
661 parity = par[i];
662 IO_Serial_Flush(ifd->io);
663
664 ret = IFD_Towitoko_SetParity (ifd, parity);
665 if (ret != IFD_TOWITOKO_OK)
666 return ret;
667
668 ret = IFD_TOWITOKO_IO_ERROR;
669
670 IO_Serial_Ioctl_Lock(ifd->io, 1);
671#ifdef USE_GPIO
672 if (gpio_detect)
673 {
674 set_gpio(0);
675 set_gpio1(0);
676 }
677 else
678#endif
679 IO_Serial_RTS_Set(ifd->io);
680
681#ifdef HAVE_NANOSLEEP
682 nanosleep (&req_ts, NULL);
683#else
684 usleep (50000L);
685#endif
686#ifdef USE_GPIO
687 if (gpio_detect)
688 {
689 set_gpio_input();
690 set_gpio1(1);
691 }
692 else
693#endif
694 IO_Serial_RTS_Clr(ifd->io);
695
696 IO_Serial_Ioctl_Lock(ifd->io, 0);
697
698 (*atr) = ATR_New ();
699
700 if(ATR_InitFromStream ((*atr), ifd->io, IFD_TOWITOKO_ATR_TIMEOUT) == ATR_OK)
701 ret = IFD_TOWITOKO_OK;
702
703 /* Succesfully retrive ATR */
704 if (ret == IFD_TOWITOKO_OK)
705 {
706 break;
707 }
708 else
709 {
710 ATR_Delete (*atr);
711 (*atr) = NULL;
712#ifdef USE_GPIO
713 if (gpio_detect) set_gpio1(0);
714#endif
715 }
716 }
717
718 IO_Serial_Flush(ifd->io);
719#ifndef NO_PAR_SWITCH
720 IFD_Towitoko_SetParity (ifd, IFD_TOWITOKO_PARITY_NONE);
721#endif
722
723/*
724 //PLAYGROUND faking ATR for test purposes only
725 //
726 // sky 919 unsigned char atr_test[] = { 0x3F, 0xFF, 0x13, 0x25, 0x03, 0x10, 0x80, 0x33, 0xB0, 0x0E, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x49, 0x54, 0x02, 0x00, 0x00 };
727 // HD+ unsigned char atr_test[] = { 0x3F, 0xFF, 0x95, 0x00, 0xFF, 0x91, 0x81, 0x71, 0xFE, 0x47, 0x00, 0x44, 0x4E, 0x41, 0x53, 0x50, 0x31, 0x34, 0x32, 0x20, 0x52, 0x65, 0x76, 0x47, 0x43, 0x34, 0x63 };
728 // S02 = irdeto unsigned char atr_test[] = { 0x3B, 0x9F, 0x21, 0x0E, 0x49, 0x52, 0x44, 0x45, 0x54, 0x4F, 0x20, 0x41, 0x43, 0x53, 0x03};
729 //cryptoworks unsigned char atr_test[] = { 0x3B, 0x78, 0x12, 0x00, 0x00, 0x65, 0xC4, 0x05, 0xFF, 0x8F, 0xF1, 0x90, 0x00 };
730 ATR_Delete(*atr); //throw away actual ATR
731 (*atr) = ATR_New ();
732 ATR_InitFromArray ((*atr), atr_test, sizeof(atr_test));
733 //END OF PLAYGROUND
734*/
735
736 return ret;
737 }
738}
739
740int IFD_Towitoko_Transmit (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
741{
742 unsigned block_delay, char_delay, sent=0, to_send = 0;
743
744#ifdef DEBUG_IFD
745 printf ("IFD: Transmit: ");
746 for (sent = 0; sent < size; sent++)
747 printf ("%X ", buffer[sent]);
748 printf ("\n");
749#endif
750
751
752 /* Calculate delays */
753 char_delay = IFD_TOWITOKO_DELAY + timings->char_delay;
754 block_delay = IFD_TOWITOKO_DELAY + timings->block_delay;
755
756#ifdef USE_GPIO
757 if (gpio_detect) set_gpio1(0);
758#endif
759 for (sent = 0; sent < size; sent = sent + to_send)
760 {
761 /* Calculate number of bytes to send */
762 to_send = MIN(size, IFD_TOWITOKO_MAX_TRANSMIT);
763
764 /* Send data */
765 if ((sent == 0) && (block_delay != char_delay))
766 {
767 if (!IO_Serial_Write (ifd->io, block_delay, 1, buffer))
768 return IFD_TOWITOKO_IO_ERROR;
769
770 if (!IO_Serial_Write (ifd->io, char_delay, to_send-1, buffer+1))
771 return IFD_TOWITOKO_IO_ERROR;
772 }
773 else
774 {
775 if (!IO_Serial_Write (ifd->io, char_delay, to_send, buffer+sent))
776 return IFD_TOWITOKO_IO_ERROR;
777 }
778 }
779#ifdef USE_GPIO
780 if (gpio_detect) set_gpio1(1);
781#endif
782 return IFD_TOWITOKO_OK;
783}
784
785int IFD_Towitoko_Receive (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
786{
787 unsigned char_timeout, block_timeout;
788#ifdef DEBUG_IFD
789 int i;
790#endif
791
792 /* Calculate timeouts */
793 char_timeout = IFD_TOWITOKO_TIMEOUT + timings->char_timeout;
794 block_timeout = IFD_TOWITOKO_TIMEOUT + timings->block_timeout;
795#ifdef USE_GPIO
796 if (gpio_detect) set_gpio1(0);
797#endif
798 if (block_timeout != char_timeout)
799 {
800 /* Read first byte using block timeout */
801 if (!IO_Serial_Read (ifd->io, block_timeout, 1, buffer))
802 return IFD_TOWITOKO_IO_ERROR;
803
804 if (size > 1)
805 {
806 /* Read remaining data bytes using char timeout */
807 if (!IO_Serial_Read (ifd->io, char_timeout, size - 1, buffer + 1))
808 return IFD_TOWITOKO_IO_ERROR;
809 }
810 }
811 else
812 {
813 /* Read all data bytes with the same timeout */
814 if (!IO_Serial_Read (ifd->io, char_timeout, size, buffer))
815 return IFD_TOWITOKO_IO_ERROR;
816 }
817#ifdef USE_GPIO
818 if (gpio_detect) set_gpio1(1);
819#endif
820
821#ifdef DEBUG_IFD
822 printf ("IFD: Receive: ");
823 for (i = 0; i < size; i++)
824 printf ("%X ", buffer[i]);
825 printf ("\n");
826#endif
827
828 return IFD_TOWITOKO_OK;
829}
830
831
832BYTE IFD_Towitoko_GetType (IFD * ifd)
833{
834 return ifd->type;
835}
836
837void IFD_Towitoko_GetDescription (IFD * ifd, BYTE * desc, unsigned length)
838{
839 char buffer[3];
840
841 if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_II)
842 memcpy (desc,"CE2",MIN(length,3));
843
844 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_I)
845 memcpy (desc,"CE1",MIN(length,3));
846
847 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_INT)
848 memcpy (desc,"CDI",MIN(length,3));
849
850 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_MICRO)
851 memcpy (desc,"CDM",MIN(length,3));
852
853 else if (ifd->type == IFD_TOWITOKO_KARTENZWERG_II)
854 memcpy (desc,"KZ2",MIN(length,3));
855
856 else if (ifd->type == IFD_TOWITOKO_KARTENZWERG)
857 memcpy (desc,"KZ1",MIN(length,3));
858
859 else if (ifd->type == IFD_TOWITOKO_MULTICAM)
860 memcpy (desc,"MCM",MIN(length,3));
861
862 else
863 memcpy (desc,"UNK",MIN(length,3));
864
865 snprintf (buffer, 3, "%02X", ifd->firmware);
866
867 if (length > 3)
868 memcpy (desc+3, buffer, MIN(length-3,2));
869}
870
871BYTE
872IFD_Towitoko_GetFirmware (IFD * ifd)
873{
874 return ifd->firmware;
875}
876
877BYTE
878IFD_Towitoko_GetSlot (IFD * ifd)
879{
880 return ifd->slot;
881}
882
883unsigned
884IFD_Towitoko_GetNumSlots ()
885{
886 return 1;
887}
888
889unsigned long
890IFD_Towitoko_GetMaxBaudrate ()
891{
892 return 115200L;
893}
894
895/*
896 * Not exported funcions definition
897 */
898
899
900static int IFD_Towitoko_GetReaderInfo (IFD * ifd)
901{
902 BYTE status[3];
903
904 status[0] = IFD_TOWITOKO_MULTICAM;
905 status[1] = 0x00;
906
907 ifd->type = status[0];
908 ifd->firmware = status[1];
909
910#ifdef DEBUG_IFD
911 printf ("IFD: Reader type = %s\n",
912 status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_II ? "Chipdrive Extern II" :
913 status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_I ? "Chipdrive Extern I" :
914 status[0] == IFD_TOWITOKO_CHIPDRIVE_INT ? "Chipdrive Intern" :
915 status[0] == IFD_TOWITOKO_CHIPDRIVE_MICRO ? "Chipdrive Micro" :
916 status[0] == IFD_TOWITOKO_KARTENZWERG_II ? "Kartenzwerg II" :
917 status[0] == IFD_TOWITOKO_MULTICAM ? "Multicam" :
918 status[0] == IFD_TOWITOKO_KARTENZWERG ? "Kartenzwerg" : "Unknown");
919#endif
920
921 return IFD_TOWITOKO_OK;
922}
923
924
925static void IFD_Towitoko_Clear (IFD * ifd)
926{
927 ifd->io = NULL;
928 ifd->slot = 0x00;
929 ifd->type = 0x00;
930 ifd->firmware = 0x00;
931 ifd->status = 0;
932}
Note: See TracBrowser for help on using the repository browser.