source: trunk/csctapi/ifd_towitoko.c@ 1182

Last change on this file since 1182 was 1182, checked in by dingo35, 12 years ago

Move Coolstream Reset and Getstatus to ifd_cool.c

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.