source: trunk/csctapi/ifd_towitoko.c @ 477

Last change on this file since 477 was 477, checked in by dingo35, 10 years ago

Fix serial comm parameters for Tuxbox devices

File size: 18.6 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//              cs_dump(buf, n, "BUF:");
569        if(n>9 && !memcmp(buf+4, irdeto, 6))
570        {
571            params.T = 14;
572            params.WWT = 1500;
573            params.EGT = 5;
574            buf[0]=0x3B;
575        }
576/*                 
577        if(params.ETU>600 && (buf[0]!=0x3B || buf[0]!=0x3F))
578        {
579            params.T = 14;
580            params.WWT = 1500;
581            params.EGT = 5;
582            buf[0]=0x3B;
583        }
584*/         
585        (*atr) = ATR_New ();
586        if(ATR_InitFromArray ((*atr), buf, n) == ATR_OK)
587        {
588            struct timespec req_ts;
589            double a;
590           
591            ATR_GetParameter(*atr, ATR_PARAMETER_D, &a);
592//          printf("atr D=%f\n", a);
593            params.ETU /= (unsigned char)a;
594            ATR_GetParameter(*atr, ATR_PARAMETER_N, &a);
595            params.EGT = (unsigned char)a;
596            ATR_GetParameter(*atr, ATR_PARAMETER_P, &a);
597//          printf("atr P=%f\n", a);
598            params.P = (unsigned char)a;
599            ATR_GetParameter(*atr, ATR_PARAMETER_I, &a);
600//          printf("atr I=%f\n", a);
601            params.I = (unsigned char)a;
602
603            if(ioctl(ifd->io->fd, IOCTL_SET_PARAMETERS, &params)!=0)
604            {
605                ATR_Delete (*atr);
606                (*atr) = NULL;
607                return IFD_TOWITOKO_IO_ERROR;
608            }
609           
610            ioctl(ifd->io->fd, IOCTL_GET_PARAMETERS, &params);
611           
612            cs_debug("T=%d f=%d ETU=%d WWT=%d CWT=%d BWT=%d EGT=%d clock=%d check=%d P=%d I=%d U=%d", (int)params.T, (int)params.f, (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);
613           
614            req_ts.tv_sec = 0;
615            req_ts.tv_nsec = 50000000;
616            nanosleep (&req_ts, NULL);
617            return IFD_TOWITOKO_OK;
618        }
619        else
620        {
621            ATR_Delete (*atr);
622            (*atr) = NULL;
623            return IFD_TOWITOKO_IO_ERROR;
624        }
625    }
626    else
627#endif
628    {
629        int ret;
630        int parity;
631        int i;
632        int par[3] = {IFD_TOWITOKO_PARITY_EVEN, IFD_TOWITOKO_PARITY_ODD, IFD_TOWITOKO_PARITY_NONE};
633#ifdef HAVE_NANOSLEEP
634        struct timespec req_ts;
635        req_ts.tv_sec = 0;
636        req_ts.tv_nsec = 50000000;
637#endif
638       
639        for(i=0; i<3; i++)
640        {
641            parity = par[i];
642            IO_Serial_Flush(ifd->io);
643
644            ret = IFD_Towitoko_SetParity (ifd, parity);
645            if (ret != IFD_TOWITOKO_OK)
646                return ret;
647
648            ret = IFD_TOWITOKO_IO_ERROR;
649
650            IO_Serial_Ioctl_Lock(ifd->io, 1);
651#ifdef USE_GPIO
652            if (gpio_detect)
653            {
654                set_gpio(0);
655                set_gpio1(0);
656            }
657            else
658#endif
659                IO_Serial_RTS_Set(ifd->io);
660
661#ifdef HAVE_NANOSLEEP
662            nanosleep (&req_ts, NULL);
663#else
664            usleep (50000L);
665#endif
666#ifdef USE_GPIO
667            if (gpio_detect)
668            {
669                set_gpio_input();
670                set_gpio1(1);
671            }
672            else
673#endif
674                IO_Serial_RTS_Clr(ifd->io);
675           
676            IO_Serial_Ioctl_Lock(ifd->io, 0);
677
678            (*atr) = ATR_New ();
679
680            if(ATR_InitFromStream ((*atr), ifd->io, IFD_TOWITOKO_ATR_TIMEOUT) == ATR_OK)
681                ret = IFD_TOWITOKO_OK;
682
683            /* Succesfully retrive ATR */
684            if (ret == IFD_TOWITOKO_OK)
685            {           
686                break;
687            }
688            else
689            {
690                ATR_Delete (*atr);
691                (*atr) = NULL;
692#ifdef USE_GPIO
693                if (gpio_detect) set_gpio1(0);
694#endif
695            }   
696        }
697   
698        IO_Serial_Flush(ifd->io);
699#ifndef NO_PAR_SWITCH
700        IFD_Towitoko_SetParity (ifd, IFD_TOWITOKO_PARITY_NONE);
701#endif
702        return ret;
703    }
704}
705
706int IFD_Towitoko_Transmit (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
707{
708    unsigned block_delay, char_delay, sent=0, to_send = 0;
709
710#ifdef DEBUG_IFD
711    printf ("IFD: Transmit: ");
712    for (sent = 0; sent < size; sent++)
713    printf ("%X ", buffer[sent]);
714    printf ("\n");
715#endif
716
717
718    /* Calculate delays */
719    char_delay = IFD_TOWITOKO_DELAY + timings->char_delay;
720    block_delay = IFD_TOWITOKO_DELAY + timings->block_delay;
721
722#ifdef USE_GPIO
723    if (gpio_detect) set_gpio1(0);
724#endif
725    for (sent = 0; sent < size; sent = sent + to_send) 
726    {
727        /* Calculate number of bytes to send */
728        to_send = MIN(size, IFD_TOWITOKO_MAX_TRANSMIT);
729               
730        /* Send data */
731        if ((sent == 0) && (block_delay != char_delay))
732        {
733            if (!IO_Serial_Write (ifd->io, block_delay, 1, buffer))
734                return IFD_TOWITOKO_IO_ERROR;
735           
736            if (!IO_Serial_Write (ifd->io, char_delay, to_send-1, buffer+1))
737                return IFD_TOWITOKO_IO_ERROR;
738        }
739        else
740        {
741            if (!IO_Serial_Write (ifd->io, char_delay, to_send, buffer+sent))
742                return IFD_TOWITOKO_IO_ERROR;
743        }
744    }
745#ifdef USE_GPIO
746    if (gpio_detect) set_gpio1(1);
747#endif
748    return IFD_TOWITOKO_OK;
749}
750
751int IFD_Towitoko_Receive (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
752{
753    unsigned char_timeout, block_timeout;
754#ifdef DEBUG_IFD
755    int i;
756#endif
757       
758    /* Calculate timeouts */
759    char_timeout = IFD_TOWITOKO_TIMEOUT + timings->char_timeout;
760    block_timeout = IFD_TOWITOKO_TIMEOUT + timings->block_timeout;
761#ifdef USE_GPIO
762    if (gpio_detect) set_gpio1(0);
763#endif
764    if (block_timeout != char_timeout)
765    {
766        /* Read first byte using block timeout */
767        if (!IO_Serial_Read (ifd->io, block_timeout, 1, buffer))
768            return IFD_TOWITOKO_IO_ERROR;
769       
770        if (size > 1)
771        {
772            /* Read remaining data bytes using char timeout */
773            if (!IO_Serial_Read (ifd->io, char_timeout, size - 1, buffer + 1))
774                return IFD_TOWITOKO_IO_ERROR;
775        }
776    }
777    else
778    {
779        /* Read all data bytes with the same timeout */
780        if (!IO_Serial_Read (ifd->io, char_timeout, size, buffer))
781            return IFD_TOWITOKO_IO_ERROR;
782    }
783#ifdef USE_GPIO
784    if (gpio_detect) set_gpio1(1);
785#endif
786   
787#ifdef DEBUG_IFD
788    printf ("IFD: Receive: ");
789    for (i = 0; i < size; i++)
790    printf ("%X ", buffer[i]);
791    printf ("\n");
792#endif
793   
794    return IFD_TOWITOKO_OK;
795}
796
797
798BYTE IFD_Towitoko_GetType (IFD * ifd)
799{
800    return ifd->type;
801}
802
803void IFD_Towitoko_GetDescription (IFD * ifd, BYTE * desc, unsigned length)
804{
805    char buffer[3];
806
807    if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_II)
808        memcpy (desc,"CE2",MIN(length,3));
809
810    else if  (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_I)
811        memcpy (desc,"CE1",MIN(length,3));
812
813    else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_INT)
814        memcpy (desc,"CDI",MIN(length,3));
815
816    else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_MICRO)
817        memcpy (desc,"CDM",MIN(length,3));
818
819    else if (ifd->type == IFD_TOWITOKO_KARTENZWERG_II) 
820        memcpy (desc,"KZ2",MIN(length,3));
821
822    else if (ifd->type == IFD_TOWITOKO_KARTENZWERG)
823        memcpy (desc,"KZ1",MIN(length,3));
824       
825    else if (ifd->type == IFD_TOWITOKO_MULTICAM)
826        memcpy (desc,"MCM",MIN(length,3));
827
828    else 
829        memcpy (desc,"UNK",MIN(length,3));
830   
831    snprintf (buffer, 3, "%02X", ifd->firmware);
832
833    if (length > 3)
834        memcpy (desc+3, buffer, MIN(length-3,2));
835}
836
837BYTE
838IFD_Towitoko_GetFirmware (IFD * ifd)
839{
840    return ifd->firmware;
841}
842
843BYTE
844IFD_Towitoko_GetSlot (IFD * ifd)
845{
846    return ifd->slot;
847}
848
849unsigned
850IFD_Towitoko_GetNumSlots (IFD * ifd)
851{
852    return 1;
853}
854
855unsigned long
856IFD_Towitoko_GetClockRate (IFD * ifd)
857{
858    return IFD_TOWITOKO_CLOCK_RATE;
859}
860
861unsigned long 
862IFD_Towitoko_GetMaxBaudrate (IFD * ifd)
863{
864    return 115200L;
865}
866
867/*
868 * Not exported funcions definition
869 */
870
871
872static int IFD_Towitoko_GetReaderInfo (IFD * ifd)
873{
874    BYTE status[3];
875   
876    status[0] = IFD_TOWITOKO_MULTICAM;
877    status[1] = 0x00;   
878   
879    ifd->type = status[0];
880    ifd->firmware = status[1];
881   
882#ifdef DEBUG_IFD
883    printf ("IFD: Reader type = %s\n",
884    status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_II ? "Chipdrive Extern II" :
885    status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_I ? "Chipdrive Extern I" :
886    status[0] == IFD_TOWITOKO_CHIPDRIVE_INT ? "Chipdrive Intern" :
887    status[0] == IFD_TOWITOKO_CHIPDRIVE_MICRO ? "Chipdrive Micro" :
888    status[0] == IFD_TOWITOKO_KARTENZWERG_II ? "Kartenzwerg II" :
889    status[0] == IFD_TOWITOKO_MULTICAM ? "Multicam" : 
890    status[0] == IFD_TOWITOKO_KARTENZWERG ? "Kartenzwerg" : "Unknown");
891#endif
892   
893    return IFD_TOWITOKO_OK;
894}
895
896
897static void IFD_Towitoko_Clear (IFD * ifd)
898{
899    ifd->io = NULL;
900    ifd->slot = 0x00;
901    ifd->type = 0x00;
902    ifd->firmware = 0x00;
903    ifd->status = 0;
904}
Note: See TracBrowser for help on using the repository browser.