source: trunk/csctapi/ifd_towitoko.c@ 70

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

csctapi/io_serial.c : fix the serial port read/write wait routine to use select instead of poll

This make them compatible with Mac OS X and now oscamd works on OS X. The same code off course
still works on linux and other unix platforms. I let that code ran for 24h before commiting this code.
If you have any issue let me know and I'llr evert to poll for non compatible machines.

all the others : fix all the warning due to sign difference (mostly uchar versus char). This make the code compile

with -Werror on the more strict version of gcc (which is the case on OS X). I also noticed that in a lot of places
the code use a buffer defined as an uchar * ... and use strings functions (strnXXXX) where some memcpy/memcmp .. function
would have been preferable as we're suposedly manipulation a binary buffer. Anyway I fixed all of them and it now compile
without any warning or error on linux and OS X (and also probably on all the other unices but we will have to try before
adding -Werror on the other platform).

File size: 19.0 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
50/*
51 * Not exported constants
52 */
53
54#define IFD_TOWITOKO_TIMEOUT 1000
55#define IFD_TOWITOKO_DELAY 0
56#define IFD_TOWITOKO_BAUDRATE 9600
57#define IFD_TOWITOKO_PS 15
58#define IFD_TOWITOKO_MAX_TRANSMIT 255
59//#define IFD_TOWITOKO_ATR_TIMEOUT 200
60//#define IFD_TOWITOKO_ATR_TIMEOUT 400
61#define IFD_TOWITOKO_ATR_TIMEOUT 800
62#define IFD_TOWITOKO_ATR_MIN_LENGTH 1
63#define IFD_TOWITOKO_CLOCK_RATE (625L * 9600L)
64//#define IFD_TOWITOKO_CLOCK_RATE (372L * 9600L)
65
66#define HI(a) (((a) & 0xff00) >> 8)
67#define LO(a) ((a) & 0x00ff)
68
69/*
70 * Not exported functions declaration
71 */
72
73static int IFD_Towitoko_GetReaderInfo (IFD * ifd);
74static void IFD_Towitoko_Clear (IFD * ifd);
75
76#ifdef USE_GPIO
77
78int gpio_outen,gpio_out,gpio_in;
79unsigned int pin,gpio;
80int gpio_detect=0;
81
82static void set_gpio(int level)
83{
84 read(gpio_outen, &gpio, sizeof(gpio));
85 gpio |= pin;
86 write(gpio_outen, &gpio, sizeof(gpio));
87
88 read(gpio_out, &gpio, sizeof(gpio));
89 if (level>0)
90 gpio|=pin;
91 else
92 gpio&=~pin;
93 write(gpio_out, &gpio, sizeof(gpio));
94}
95
96static void set_gpio1(int level)
97{
98 read(gpio_outen, &gpio, sizeof(gpio));
99 gpio |= 2;
100 write(gpio_outen, &gpio, sizeof(gpio));
101
102 read(gpio_out, &gpio, sizeof(gpio));
103 if (level>0)
104 gpio|=2;
105 else
106 gpio&=~2;
107 write(gpio_out, &gpio, sizeof(gpio));
108}
109
110static void set_gpio_input(void)
111{
112 read(gpio_outen, &gpio, sizeof(gpio));
113 gpio &= ~pin;
114 write(gpio_outen, &gpio, sizeof(gpio));
115}
116
117static int get_gpio(void)
118{
119 set_gpio_input();
120 read(gpio_in, &gpio, sizeof(gpio));
121 return ((int)((gpio&pin)?1:0));
122}
123#endif
124
125/*
126 * Exported functions definition
127 */
128
129IFD * IFD_Towitoko_New ()
130{
131 IFD *ifd;
132
133 ifd = (IFD *) malloc (sizeof (IFD));
134
135 if (ifd != NULL)
136 IFD_Towitoko_Clear (ifd);
137
138 return ifd;
139}
140
141void IFD_Towitoko_Delete (IFD * ifd)
142{
143 free (ifd);
144}
145
146int IFD_Towitoko_Init (IFD * ifd, IO_Serial * io, BYTE slot)
147{
148 IO_Serial_Properties props;
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: Initialicing 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 props.input_bitrate = IFD_TOWITOKO_BAUDRATE;
183 props.output_bitrate = IFD_TOWITOKO_BAUDRATE;
184 props.bits = 8;
185 props.stopbits = 2;
186 props.parity = IO_SERIAL_PARITY_EVEN;
187 props.dtr = IO_SERIAL_HIGH;
188// props.dtr = IO_SERIAL_LOW;
189// props.rts = IO_SERIAL_HIGH;
190 props.rts = IO_SERIAL_LOW;
191
192
193 if (!IO_Serial_SetProperties (io, &props))
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 (ifd, IFD_TOWITOKO_LED_OFF);
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 IO_Serial_Properties props;
262
263 if(ifd->io->com==RTYP_SCI)
264 {
265 return IFD_TOWITOKO_OK;
266 }
267
268 if (IFD_Towitoko_GetMaxBaudrate (ifd) < baudrate)
269 {
270#ifdef DEBUG_IFD
271 printf ("IFD: Tried to set unsupported baudrate: %lu", baudrate);
272#endif
273 return IFD_TOWITOKO_PARAM_ERROR;
274 }
275
276#ifdef DEBUG_IFD
277 printf ("IFD: Setting baudrate to %lu\n", baudrate);
278#endif
279
280 /* Get current settings */
281 if (!IO_Serial_GetProperties (ifd->io, &props))
282 return IFD_TOWITOKO_IO_ERROR;
283
284 if (props.output_bitrate == baudrate)
285 return IFD_TOWITOKO_OK;
286
287
288 /* Set serial device bitrate */
289 props.output_bitrate = baudrate;
290 props.input_bitrate = baudrate;
291
292 if (!IO_Serial_SetProperties (ifd->io, &props))
293 return IFD_TOWITOKO_IO_ERROR;
294
295 return IFD_TOWITOKO_OK;
296}
297
298int IFD_Towitoko_GetBaudrate (IFD * ifd, unsigned long *baudrate)
299{
300 IO_Serial_Properties props;
301
302 if(ifd->io->com==RTYP_SCI)
303 {
304 return IFD_TOWITOKO_OK;
305 }
306
307 /* Get current settings */
308 if (!IO_Serial_GetProperties (ifd->io, &props))
309 return IFD_TOWITOKO_IO_ERROR;
310
311 (*baudrate) = props.output_bitrate;
312
313 return IFD_TOWITOKO_OK;
314}
315
316extern int IFD_Towitoko_SetParity (IFD * ifd, BYTE parity)
317{
318 IO_Serial_Properties props;
319
320 if(ifd->io->com==RTYP_SCI)
321 {
322 return IFD_TOWITOKO_OK;
323 }
324
325#ifdef DEBUG_IFD
326 printf ("IFD: Parity = %s\n",
327 parity == IFD_TOWITOKO_PARITY_ODD ? "Odd" :
328 parity == IFD_TOWITOKO_PARITY_EVEN ? "Even" : "Invalid");
329#endif
330
331 if ((parity != IFD_TOWITOKO_PARITY_EVEN) && (parity != IFD_TOWITOKO_PARITY_ODD) && (parity != IFD_TOWITOKO_PARITY_NONE))
332 return IFD_TOWITOKO_PARAM_ERROR;
333
334 /* Get current settings */
335 if (!IO_Serial_GetProperties (ifd->io, &props))
336 return IFD_TOWITOKO_IO_ERROR;
337
338 if (props.parity !=parity)
339 {
340 props.parity = parity;
341
342 if (!IO_Serial_SetProperties (ifd->io, &props))
343 return IFD_TOWITOKO_IO_ERROR;
344 }
345
346 return IFD_TOWITOKO_OK;
347}
348
349int IFD_Towitoko_SetLED (IFD * ifd, BYTE color)
350{
351 return IFD_TOWITOKO_OK;
352}
353
354int IFD_Towitoko_GetStatus (IFD * ifd, BYTE * result)
355{
356 BYTE status[2];
357 unsigned int modembits=0;
358 int in;
359
360// printf("\n%08X\n", (int)ifd->io);
361
362// status : 0 -start, 1 - card, 2- no card
363
364#ifdef SCI_DEV
365 if(ifd->io->com==RTYP_SCI)
366 {
367 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
368 return IFD_TOWITOKO_IO_ERROR;
369 }
370 else
371#endif
372#if defined(TUXBOX) && defined(PPC)
373 if ((ifd->io->com==RTYP_DB2COM1) || (ifd->io->com==RTYP_DB2COM2))
374 {
375 ushort msr=1;
376 extern int fdmc;
377 IO_Serial_Ioctl_Lock(ifd->io, 1);
378 ioctl(fdmc, GET_PCDAT, &msr);
379 if (ifd->io->com==RTYP_DB2COM2)
380 in=(!(msr & 1));
381 else
382 in=((msr & 0x0f00) == 0x0f00);
383 IO_Serial_Ioctl_Lock(ifd->io, 0);
384 }
385 else
386#endif
387#ifdef USE_GPIO
388 if (gpio_detect)
389 in=get_gpio();
390 else
391#endif
392 {
393 extern int oscam_card_detect;
394 if (ioctl(ifd->io->fd, TIOCMGET,&modembits)<0)
395 return IFD_TOWITOKO_IO_ERROR;
396 switch(oscam_card_detect&0x7f)
397 {
398 case 0: in=(modembits & TIOCM_CAR); break;
399 case 1: in=(modembits & TIOCM_DSR); break;
400 case 2: in=(modembits & TIOCM_CTS); break;
401 case 3: in=(modembits & TIOCM_RNG); break;
402 default: in=0; // dummy
403 }
404 if (!(oscam_card_detect&0x80))
405 in=!in;
406 }
407
408 if (in)
409 {
410 if(ifd->status == 0)
411 {
412 status[0] = IFD_TOWITOKO_CARD_CHANGE;
413 ifd->status = 1;
414#ifdef USE_GPIO
415 if (gpio_detect) set_gpio1(0);
416#endif
417 }
418 else if(ifd->status == 1)
419 {
420 status[0] = IFD_TOWITOKO_CARD_NOCHANGE;
421 }
422 else
423 {
424 status[0] = IFD_TOWITOKO_CARD_CHANGE;
425 ifd->status = 1;
426#ifdef USE_GPIO
427 if (gpio_detect) set_gpio1(0);
428#endif
429 }
430 }
431 else
432 {
433 if(ifd->status == 0)
434 {
435 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
436 ifd->status = 2;
437#ifdef USE_GPIO
438 if (gpio_detect) set_gpio1(1);
439#endif
440 }
441 else if(ifd->status == 1)
442 {
443 status[0] = IFD_TOWITOKO_NOCARD_CHANGE;
444 ifd->status = 2;
445#ifdef USE_GPIO
446 if (gpio_detect) set_gpio1(1);
447#endif
448 }
449 else
450 {
451 status[0] = IFD_TOWITOKO_NOCARD_NOCHANGE;
452 }
453 }
454
455
456 (*result) = status[0];
457
458#ifdef DEBUG_IFD
459 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");
460#endif
461
462 return IFD_TOWITOKO_OK;
463}
464
465int IFD_Towitoko_ActivateICC (IFD * ifd)
466{
467#ifdef DEBUG_IFD
468 printf ("IFD: Activating card\n");
469#endif
470#ifdef SCI_DEV
471 if(ifd->io->com==RTYP_SCI)
472 {
473 int in;
474
475#if defined(TUXBOX) && defined(MIPSEL)
476 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
477#else
478 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_ACTIVATED, &in)<0)
479#endif
480 return IFD_TOWITOKO_IO_ERROR;
481
482 if(in)
483 {
484 struct timespec req_ts;
485 req_ts.tv_sec = 0;
486 req_ts.tv_nsec = 50000000;
487 nanosleep (&req_ts, NULL);
488 return IFD_TOWITOKO_OK;
489 }
490 else
491 {
492 return IFD_TOWITOKO_IO_ERROR;
493 }
494 }
495 else
496#endif
497 {
498 return IFD_TOWITOKO_OK;
499 }
500}
501
502int IFD_Towitoko_DeactivateICC (IFD * ifd)
503{
504#ifdef DEBUG_IFD
505 printf ("IFD: Deactivating card\n");
506#endif
507
508#ifdef SCI_DEV
509 if(ifd->io->com==RTYP_SCI)
510 {
511 int in;
512
513#if defined(TUXBOX) && defined(MIPSEL)
514 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
515#else
516 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_ACTIVATED, &in)<0)
517#endif
518 return IFD_TOWITOKO_IO_ERROR;
519
520 if(in)
521 {
522 if(ioctl(ifd->io->fd, IOCTL_SET_DEACTIVATE)<0)
523 return IFD_TOWITOKO_IO_ERROR;
524 }
525
526
527 }
528#endif
529
530 return IFD_TOWITOKO_OK;
531}
532
533//extern void print_hex_data(unsigned char *data, int len);
534
535int IFD_Towitoko_ResetAsyncICC (IFD * ifd, ATR ** atr)
536{
537
538#ifdef DEBUG_IFD
539 printf ("IFD: Resetting card:\n");
540#endif
541
542#ifdef SCI_DEV
543 if(ifd->io->com==RTYP_SCI)
544 {
545 unsigned char buf[SCI_MAX_ATR_SIZE];
546 int n = 0;
547 SCI_PARAMETERS params;
548 static char irdeto[] = "IRDETO";
549
550 (*atr) = NULL;
551
552 if(ioctl(ifd->io->fd, IOCTL_SET_RESET)<0)
553 return IFD_TOWITOKO_IO_ERROR;
554
555 if(ioctl(ifd->io->fd, IOCTL_SET_ATR_READY)<0)
556 return IFD_TOWITOKO_IO_ERROR;
557 while(n<SCI_MAX_ATR_SIZE && IO_Serial_Read(ifd->io, IFD_TOWITOKO_ATR_TIMEOUT, 1, buf+n))
558 {
559 n++;
560 }
561
562 if(n==0)
563 return IFD_TOWITOKO_IO_ERROR;
564
565 if(ioctl(ifd->io->fd, IOCTL_GET_PARAMETERS, &params)<0)
566 return IFD_TOWITOKO_IO_ERROR;
567/*
568 printf("T=%d\n", (int)params.T);
569 printf("f=%d\n", (int)params.f);
570 printf("ETU=%d\n", (int)params.ETU);
571 printf("WWT=%d\n", (int)params.WWT);
572 printf("CWT=%d\n", (int)params.CWT);
573 printf("BWT=%d\n", (int)params.BWT);
574 printf("EGT=%d\n", (int)params.EGT);
575 printf("clock=%d\n", (int)params.clock_stop_polarity);
576 printf("check=%d\n", (int)params.check);
577 printf("P=%d\n", (int)params.P);
578 printf("I=%d\n", (int)params.I);
579 printf("U=%d\n", (int)params.U);
580*/
581
582// print_hex_data(buf, n);
583 if(n>9 && !memcmp(buf+4, irdeto, 6))
584 {
585 params.T = 14;
586 params.WWT = 1500;
587 params.EGT = 5;
588 buf[0]=0x3B;
589 }
590/*
591 if(params.ETU>600 && (buf[0]!=0x3B || buf[0]!=0x3F))
592 {
593 params.T = 14;
594 params.WWT = 1500;
595 params.EGT = 5;
596 buf[0]=0x3B;
597 }
598*/
599 (*atr) = ATR_New ();
600 if(ATR_InitFromArray ((*atr), buf, n) == ATR_OK)
601 {
602 struct timespec req_ts;
603 double a;
604
605 ATR_GetParameter(*atr, ATR_PARAMETER_P, &a);
606// printf("atr P=%f\n", a);
607 params.P = (unsigned char)a;
608 ATR_GetParameter(*atr, ATR_PARAMETER_I, &a);
609// printf("atr I=%f\n", a);
610 params.I = (unsigned char)a;
611
612
613 if(ioctl(ifd->io->fd, IOCTL_SET_PARAMETERS, &params)!=0)
614 {
615 ATR_Delete (*atr);
616 (*atr) = NULL;
617 return IFD_TOWITOKO_IO_ERROR;
618 }
619
620
621/*
622 ioctl(ifd->io->fd, IOCTL_GET_PARAMETERS, &params);
623
624 printf("T=%d\n", (int)params.T);
625 printf("f=%d\n", (int)params.f);
626 printf("ETU=%d\n", (int)params.ETU);
627 printf("WWT=%d\n", (int)params.WWT);
628 printf("CWT=%d\n", (int)params.CWT);
629 printf("BWT=%d\n", (int)params.BWT);
630 printf("EGT=%d\n", (int)params.EGT);
631 printf("clock=%d\n", (int)params.clock_stop_polarity);
632 printf("check=%d\n", (int)params.check);
633 printf("P=%d\n", (int)params.P);
634 printf("I=%d\n", (int)params.I);
635 printf("U=%d\n", (int)params.U);*/
636
637
638
639 req_ts.tv_sec = 0;
640 req_ts.tv_nsec = 50000000;
641 nanosleep (&req_ts, NULL);
642 return IFD_TOWITOKO_OK;
643 }
644 else
645 {
646 ATR_Delete (*atr);
647 (*atr) = NULL;
648 return IFD_TOWITOKO_IO_ERROR;
649 }
650 }
651 else
652#endif
653 {
654 int ret;
655 int parity;
656 int i;
657 int par[3] = {IFD_TOWITOKO_PARITY_EVEN, IFD_TOWITOKO_PARITY_ODD, IFD_TOWITOKO_PARITY_NONE};
658#ifdef HAVE_NANOSLEEP
659 struct timespec req_ts;
660 req_ts.tv_sec = 0;
661 req_ts.tv_nsec = 50000000;
662#endif
663
664 for(i=0; i<3; i++)
665 {
666 parity = par[i];
667 IO_Serial_Flush(ifd->io);
668
669 ret = IFD_Towitoko_SetParity (ifd, parity);
670 if (ret != IFD_TOWITOKO_OK)
671 return ret;
672
673 ret = IFD_TOWITOKO_IO_ERROR;
674
675 IO_Serial_Ioctl_Lock(ifd->io, 1);
676#ifdef USE_GPIO
677 if (gpio_detect)
678 {
679 set_gpio(0);
680 set_gpio1(0);
681 }
682 else
683#endif
684 IO_Serial_RTS_Set(ifd->io);
685
686#ifdef HAVE_NANOSLEEP
687 nanosleep (&req_ts, NULL);
688#else
689 usleep (50000L);
690#endif
691#ifdef USE_GPIO
692 if (gpio_detect)
693 {
694 set_gpio_input();
695 set_gpio1(1);
696 }
697 else
698#endif
699 IO_Serial_RTS_Clr(ifd->io);
700
701 IO_Serial_Ioctl_Lock(ifd->io, 0);
702
703 (*atr) = ATR_New ();
704
705 if(ATR_InitFromStream ((*atr), ifd->io, IFD_TOWITOKO_ATR_TIMEOUT) == ATR_OK)
706 ret = IFD_TOWITOKO_OK;
707
708 /* Succesfully retrive ATR */
709 if (ret == IFD_TOWITOKO_OK)
710 {
711 break;
712 }
713 else
714 {
715 ATR_Delete (*atr);
716 (*atr) = NULL;
717#ifdef USE_GPIO
718 if (gpio_detect) set_gpio1(0);
719#endif
720 }
721 }
722
723 IO_Serial_Flush(ifd->io);
724#ifndef NO_PAR_SWITCH
725 IFD_Towitoko_SetParity (ifd, IFD_TOWITOKO_PARITY_NONE);
726#endif
727 return ret;
728 }
729}
730
731int IFD_Towitoko_Transmit (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
732{
733 unsigned block_delay, char_delay, sent=0, to_send = 0;
734
735#ifdef DEBUG_IFD
736 printf ("IFD: Transmit: ");
737 for (sent = 0; sent < size; sent++)
738 printf ("%X ", buffer[sent]);
739 printf ("\n");
740#endif
741
742
743 /* Calculate delays */
744 char_delay = IFD_TOWITOKO_DELAY + timings->char_delay;
745 block_delay = IFD_TOWITOKO_DELAY + timings->block_delay;
746
747#ifdef USE_GPIO
748 if (gpio_detect) set_gpio1(0);
749#endif
750 for (sent = 0; sent < size; sent = sent + to_send)
751 {
752 /* Calculate number of bytes to send */
753 to_send = MIN(size, IFD_TOWITOKO_MAX_TRANSMIT);
754
755 /* Send data */
756 if ((sent == 0) && (block_delay != char_delay))
757 {
758 if (!IO_Serial_Write (ifd->io, block_delay, 1, buffer))
759 return IFD_TOWITOKO_IO_ERROR;
760
761 if (!IO_Serial_Write (ifd->io, char_delay, to_send-1, buffer+1))
762 return IFD_TOWITOKO_IO_ERROR;
763 }
764 else
765 {
766 if (!IO_Serial_Write (ifd->io, char_delay, to_send, buffer+sent))
767 return IFD_TOWITOKO_IO_ERROR;
768 }
769 }
770#ifdef USE_GPIO
771 if (gpio_detect) set_gpio1(1);
772#endif
773 return IFD_TOWITOKO_OK;
774}
775
776int IFD_Towitoko_Receive (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
777{
778 unsigned char_timeout, block_timeout;
779#ifdef DEBUG_IFD
780 int i;
781#endif
782
783 /* Calculate timeouts */
784 char_timeout = IFD_TOWITOKO_TIMEOUT + timings->char_timeout;
785 block_timeout = IFD_TOWITOKO_TIMEOUT + timings->block_timeout;
786#ifdef USE_GPIO
787 if (gpio_detect) set_gpio1(0);
788#endif
789 if (block_timeout != char_timeout)
790 {
791 /* Read first byte using block timeout */
792 if (!IO_Serial_Read (ifd->io, block_timeout, 1, buffer))
793 return IFD_TOWITOKO_IO_ERROR;
794
795 if (size > 1)
796 {
797 /* Read remaining data bytes using char timeout */
798 if (!IO_Serial_Read (ifd->io, char_timeout, size - 1, buffer + 1))
799 return IFD_TOWITOKO_IO_ERROR;
800 }
801 }
802 else
803 {
804 /* Read all data bytes with the same timeout */
805 if (!IO_Serial_Read (ifd->io, char_timeout, size, buffer))
806 return IFD_TOWITOKO_IO_ERROR;
807 }
808#ifdef USE_GPIO
809 if (gpio_detect) set_gpio1(1);
810#endif
811
812#ifdef DEBUG_IFD
813 printf ("IFD: Receive: ");
814 for (i = 0; i < size; i++)
815 printf ("%X ", buffer[i]);
816 printf ("\n");
817#endif
818
819 return IFD_TOWITOKO_OK;
820}
821
822
823BYTE IFD_Towitoko_GetType (IFD * ifd)
824{
825 return ifd->type;
826}
827
828void IFD_Towitoko_GetDescription (IFD * ifd, BYTE * desc, unsigned length)
829{
830 char buffer[3];
831
832 if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_II)
833 memcpy (desc,"CE2",MIN(length,3));
834
835 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_I)
836 memcpy (desc,"CE1",MIN(length,3));
837
838 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_INT)
839 memcpy (desc,"CDI",MIN(length,3));
840
841 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_MICRO)
842 memcpy (desc,"CDM",MIN(length,3));
843
844 else if (ifd->type == IFD_TOWITOKO_KARTENZWERG_II)
845 memcpy (desc,"KZ2",MIN(length,3));
846
847 else if (ifd->type == IFD_TOWITOKO_KARTENZWERG)
848 memcpy (desc,"KZ1",MIN(length,3));
849
850 else if (ifd->type == IFD_TOWITOKO_MULTICAM)
851 memcpy (desc,"MCM",MIN(length,3));
852
853 else
854 memcpy (desc,"UNK",MIN(length,3));
855
856 snprintf (buffer, 3, "%02X", ifd->firmware);
857
858 if (length > 3)
859 memcpy (desc+3, buffer, MIN(length-3,2));
860}
861
862BYTE
863IFD_Towitoko_GetFirmware (IFD * ifd)
864{
865 return ifd->firmware;
866}
867
868BYTE
869IFD_Towitoko_GetSlot (IFD * ifd)
870{
871 return ifd->slot;
872}
873
874unsigned
875IFD_Towitoko_GetNumSlots (IFD * ifd)
876{
877 return 1;
878}
879
880unsigned long
881IFD_Towitoko_GetClockRate (IFD * ifd)
882{
883 return IFD_TOWITOKO_CLOCK_RATE;
884}
885
886unsigned long
887IFD_Towitoko_GetMaxBaudrate (IFD * ifd)
888{
889 return 115200L;
890}
891
892/*
893 * Not exported funcions definition
894 */
895
896
897static int IFD_Towitoko_GetReaderInfo (IFD * ifd)
898{
899 BYTE status[3];
900
901 status[0] = IFD_TOWITOKO_MULTICAM;
902 status[1] = 0x00;
903
904 ifd->type = status[0];
905 ifd->firmware = status[1];
906
907#ifdef DEBUG_IFD
908 printf ("IFD: Reader type = %s\n",
909 status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_II ? "Chipdrive Extern II" :
910 status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_I ? "Chipdrive Extern I" :
911 status[0] == IFD_TOWITOKO_CHIPDRIVE_INT ? "Chipdrive Intern" :
912 status[0] == IFD_TOWITOKO_CHIPDRIVE_MICRO ? "Chipdrive Micro" :
913 status[0] == IFD_TOWITOKO_KARTENZWERG_II ? "Kartenzwerg II" :
914 status[0] == IFD_TOWITOKO_MULTICAM ? "Multicam" :
915 status[0] == IFD_TOWITOKO_KARTENZWERG ? "Kartenzwerg" : "Unknown");
916#endif
917
918 return IFD_TOWITOKO_OK;
919}
920
921
922static void IFD_Towitoko_Clear (IFD * ifd)
923{
924 ifd->io = NULL;
925 ifd->slot = 0x00;
926 ifd->type = 0x00;
927 ifd->firmware = 0x00;
928 ifd->status = 0;
929}
Note: See TracBrowser for help on using the repository browser.