source: trunk/csctapi/ifd_towitoko.c@ 1221

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

Fix compiler errors on tuxbox and mipsel platforms

File size: 14.9 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#include "../globals.h"
51
52/*
53 * Not exported constants
54 */
55
56#define IFD_TOWITOKO_TIMEOUT 1000
57#define IFD_TOWITOKO_DELAY 0
58#define IFD_TOWITOKO_BAUDRATE 9600
59//#define IFD_TOWITOKO_PS 15
60#define IFD_TOWITOKO_MAX_TRANSMIT 255
61//#define IFD_TOWITOKO_ATR_TIMEOUT 200
62//#define IFD_TOWITOKO_ATR_TIMEOUT 400
63#define IFD_TOWITOKO_ATR_TIMEOUT 800
64#define IFD_TOWITOKO_ATR_MIN_LENGTH 1
65#define IFD_TOWITOKO_CLOCK_RATE (625L * 9600L)
66//#define IFD_TOWITOKO_CLOCK_RATE (372L * 9600L)
67
68#define HI(a) (((a) & 0xff00) >> 8)
69#define LO(a) ((a) & 0x00ff)
70
71/*
72 * Not exported functions declaration
73 */
74
75static int IFD_Towitoko_GetReaderInfo (IFD * ifd);
76static void IFD_Towitoko_Clear (IFD * ifd);
77
78#ifdef USE_GPIO
79
80int gpio_outen,gpio_out,gpio_in;
81unsigned int pin,gpio;
82int gpio_detect=0;
83
84static void set_gpio(int level)
85{
86 read(gpio_outen, &gpio, sizeof(gpio));
87 gpio |= pin;
88 write(gpio_outen, &gpio, sizeof(gpio));
89
90 read(gpio_out, &gpio, sizeof(gpio));
91 if (level>0)
92 gpio|=pin;
93 else
94 gpio&=~pin;
95 write(gpio_out, &gpio, sizeof(gpio));
96}
97
98static void set_gpio1(int level)
99{
100 read(gpio_outen, &gpio, sizeof(gpio));
101 gpio |= 2;
102 write(gpio_outen, &gpio, sizeof(gpio));
103
104 read(gpio_out, &gpio, sizeof(gpio));
105 if (level>0)
106 gpio|=2;
107 else
108 gpio&=~2;
109 write(gpio_out, &gpio, sizeof(gpio));
110}
111
112static void set_gpio_input(void)
113{
114 read(gpio_outen, &gpio, sizeof(gpio));
115 gpio &= ~pin;
116 write(gpio_outen, &gpio, sizeof(gpio));
117}
118
119static int get_gpio(void)
120{
121 set_gpio_input();
122 read(gpio_in, &gpio, sizeof(gpio));
123 return ((int)((gpio&pin)?1:0));
124}
125#endif
126
127/*
128 * Exported functions definition
129 */
130
131IFD * IFD_Towitoko_New ()
132{
133 IFD *ifd;
134
135 ifd = (IFD *) malloc (sizeof (IFD));
136
137 if (ifd != NULL)
138 IFD_Towitoko_Clear (ifd);
139
140 return ifd;
141}
142
143void IFD_Towitoko_Delete (IFD * ifd)
144{
145 free (ifd);
146}
147
148int IFD_Towitoko_Init (IFD * ifd, IO_Serial * io, BYTE slot)
149{
150 int ret;
151
152#ifdef USE_GPIO
153 extern int oscam_card_detect;
154 if (oscam_card_detect>4)
155 {
156 gpio_detect=oscam_card_detect-3;
157 pin = 1<<gpio_detect;
158 gpio_outen=open("/dev/gpio/outen",O_RDWR);
159 gpio_out=open("/dev/gpio/out",O_RDWR);
160 gpio_in=open("/dev/gpio/in",O_RDWR);
161 set_gpio_input();
162 }
163#endif
164
165#ifdef DEBUG_IFD
166 printf ("IFD: Initializing slot number %d, com=%d\n", slot, io->reader_type);
167#endif
168
169// if ((slot != IFD_TOWITOKO_SLOT_MULTICAM) && (slot != IFD_TOWITOKO_SLOT_A) && (slot != IFD_TOWITOKO_SLOT_B))
170 if (slot != IFD_TOWITOKO_SLOT_MULTICAM )
171 return IFD_TOWITOKO_PARAM_ERROR;
172
173 if(io->reader_type==R_INTERNAL)
174 {
175 ifd->io = io;
176 ifd->slot = slot;
177 ifd->type = IFD_TOWITOKO_MULTICAM;
178 return IFD_TOWITOKO_OK;
179 }
180
181
182 /* Default serial port settings */
183 io->input_bitrate = IFD_TOWITOKO_BAUDRATE;
184 io->output_bitrate = IFD_TOWITOKO_BAUDRATE;
185 io->bits = 8;
186 io->stopbits = 2;
187 io->parity = IO_SERIAL_PARITY_EVEN;
188 io->dtr = IO_SERIAL_HIGH;
189// io->dtr = IO_SERIAL_LOW;
190// io->rts = IO_SERIAL_HIGH;
191 io->rts = IO_SERIAL_LOW;
192
193
194 if (!IO_Serial_SetProperties (io))
195 return IFD_TOWITOKO_IO_ERROR;
196
197 /* Default ifd settings */
198
199 ifd->io = io;
200 ifd->slot = slot;
201 ifd->type = IFD_TOWITOKO_MULTICAM;
202
203 ret = IFD_Towitoko_SetBaudrate (ifd, IFD_TOWITOKO_BAUDRATE);
204
205 if (ret != IFD_TOWITOKO_OK)
206 {
207 IFD_Towitoko_Clear (ifd);
208 return ret;
209 }
210
211 ret = IFD_Towitoko_SetParity (ifd, IFD_TOWITOKO_PARITY_EVEN);
212
213 if (ret != IFD_TOWITOKO_OK)
214 {
215 IFD_Towitoko_Clear (ifd);
216 return ret;
217 }
218
219 ret = IFD_Towitoko_GetReaderInfo (ifd);
220
221 if (ret != IFD_TOWITOKO_OK)
222 {
223 IFD_Towitoko_Clear (ifd);
224 }
225 else
226 {
227 IO_Serial_Flush(ifd->io);
228 }
229
230 return ret;
231}
232
233int IFD_Towitoko_Close (IFD * ifd)
234{
235 int ret;
236
237#ifdef USE_GPIO
238 if(gpio_detect)
239 {
240 close(gpio_outen);
241 close(gpio_out);
242 close(gpio_in);
243 }
244#endif
245
246#ifdef DEBUG_IFD
247 printf ("IFD: Closing slot number %d\n", ifd->slot);
248#endif
249
250 ret = IFD_Towitoko_SetLED ();
251 if (ret != IFD_TOWITOKO_OK)
252 return ret;
253
254 IFD_Towitoko_Clear (ifd);
255
256
257 return IFD_TOWITOKO_OK;
258}
259
260int IFD_Towitoko_SetBaudrate (IFD * ifd, unsigned long baudrate)
261{
262 if(ifd->io->reader_type==R_INTERNAL)
263 {
264 return IFD_TOWITOKO_OK;
265 }
266/*
267 if (IFD_Towitoko_GetMaxBaudrate () < baudrate)
268 {
269#ifdef DEBUG_IFD
270 printf ("IFD: Tried to set unsupported baudrate: %lu", baudrate);
271#endif
272 return IFD_TOWITOKO_PARAM_ERROR;
273 }*/
274
275#ifdef DEBUG_IFD
276 printf ("IFD: Setting baudrate to %lu\n", baudrate);
277#endif
278 /* Get current settings */
279 if (!IO_Serial_GetProperties (ifd->io))
280 return IFD_TOWITOKO_IO_ERROR;
281
282 if (ifd->io->output_bitrate == baudrate)
283 return IFD_TOWITOKO_OK;
284
285
286 /* Set serial device bitrate */
287 ifd->io->output_bitrate = baudrate;
288 ifd->io->input_bitrate = baudrate;
289
290 if (!IO_Serial_SetProperties (ifd->io))
291 return IFD_TOWITOKO_IO_ERROR;
292
293 return IFD_TOWITOKO_OK;
294}
295
296int IFD_Towitoko_GetBaudrate (IFD * ifd, unsigned long *baudrate)
297{
298 if(ifd->io->reader_type==R_INTERNAL)
299 {
300 return IFD_TOWITOKO_OK;
301 }
302
303 /* Get current settings */
304 if (!IO_Serial_GetProperties (ifd->io))
305 return IFD_TOWITOKO_IO_ERROR;
306
307 (*baudrate) = ifd->io->output_bitrate;
308
309 return IFD_TOWITOKO_OK;
310}
311
312extern int IFD_Towitoko_SetParity (IFD * ifd, BYTE parity)
313{
314 if(ifd->io->reader_type==R_INTERNAL)
315 {
316 return IFD_TOWITOKO_OK;
317 }
318
319#ifdef DEBUG_IFD
320 printf ("IFD: Parity = %s\n",
321 parity == IFD_TOWITOKO_PARITY_ODD ? "Odd" :
322 parity == IFD_TOWITOKO_PARITY_EVEN ? "Even" : "Invalid");
323#endif
324
325 if ((parity != IFD_TOWITOKO_PARITY_EVEN) && (parity != IFD_TOWITOKO_PARITY_ODD) && (parity != IFD_TOWITOKO_PARITY_NONE))
326 return IFD_TOWITOKO_PARAM_ERROR;
327
328 /* Get current settings */
329 if (!IO_Serial_GetProperties (ifd->io))
330 return IFD_TOWITOKO_IO_ERROR;
331
332 if (ifd->io->parity !=parity)
333 {
334 ifd->io->parity = parity;
335
336 if (!IO_Serial_SetProperties (ifd->io))
337 return IFD_TOWITOKO_IO_ERROR;
338 }
339
340 return IFD_TOWITOKO_OK;
341}
342
343int IFD_Towitoko_SetLED ()
344{
345 return IFD_TOWITOKO_OK;
346}
347
348int IFD_Towitoko_ActivateICC (IFD * ifd)
349{
350#ifdef DEBUG_IFD
351 printf ("IFD: Activating card\n");
352#endif
353#ifdef SCI_DEV
354 if(ifd->io->reader_type==R_INTERNAL)
355 {
356 int in;
357
358#if defined(TUXBOX) && (defined(MIPSEL) || defined(PPC) || defined(SH4))
359 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
360#else
361 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_ACTIVATED, &in)<0)
362#endif
363 return IFD_TOWITOKO_IO_ERROR;
364
365 if(in)
366 {
367 struct timespec req_ts;
368 req_ts.tv_sec = 0;
369 req_ts.tv_nsec = 50000000;
370 nanosleep (&req_ts, NULL);
371 return IFD_TOWITOKO_OK;
372 }
373 else
374 {
375 return IFD_TOWITOKO_IO_ERROR;
376 }
377 }
378 else
379#endif
380 {
381 return IFD_TOWITOKO_OK;
382 }
383}
384
385int IFD_Towitoko_DeactivateICC (IFD * ifd)
386{
387#ifdef DEBUG_IFD
388 printf ("IFD: Deactivating card\n");
389#endif
390
391#ifdef SCI_DEV
392 if(ifd->io->reader_type==R_INTERNAL)
393 {
394 int in;
395
396#if defined(TUXBOX) && (defined(MIPSEL) || defined(PPC) || defined(SH4))
397 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_PRESENT, &in)<0)
398#else
399 if(ioctl(ifd->io->fd, IOCTL_GET_IS_CARD_ACTIVATED, &in)<0)
400#endif
401 return IFD_TOWITOKO_IO_ERROR;
402
403 if(in)
404 {
405 if(ioctl(ifd->io->fd, IOCTL_SET_DEACTIVATE)<0)
406 return IFD_TOWITOKO_IO_ERROR;
407 }
408
409
410 }
411#endif
412
413 return IFD_TOWITOKO_OK;
414}
415
416//extern void print_hex_data(unsigned char *data, int len);
417
418int IFD_Towitoko_ResetAsyncICC (IFD * ifd, ATR ** atr)
419{
420
421#ifdef DEBUG_IFD
422 printf ("IFD: Resetting card:\n");
423#endif
424
425 int ret;
426 int parity;
427 int i;
428 int par[3] = {IFD_TOWITOKO_PARITY_EVEN, IFD_TOWITOKO_PARITY_ODD, IFD_TOWITOKO_PARITY_NONE};
429#ifdef HAVE_NANOSLEEP
430 struct timespec req_ts;
431 req_ts.tv_sec = 0;
432 req_ts.tv_nsec = 50000000;
433#endif
434
435 (*atr) = NULL;
436 for(i=0; i<3; i++)
437 {
438 parity = par[i];
439 IO_Serial_Flush(ifd->io);
440
441 ret = IFD_Towitoko_SetParity (ifd, parity);
442 if (ret != IFD_TOWITOKO_OK)
443 return ret;
444
445 ret = IFD_TOWITOKO_IO_ERROR;
446
447 IO_Serial_Ioctl_Lock(1);
448#ifdef USE_GPIO
449 if (gpio_detect)
450 {
451 set_gpio(0);
452 set_gpio1(0);
453 }
454 else
455#endif
456 IO_Serial_RTS_Set(ifd->io);
457
458#ifdef HAVE_NANOSLEEP
459 nanosleep (&req_ts, NULL);
460#else
461 usleep (50000L);
462#endif
463#ifdef USE_GPIO
464 if (gpio_detect)
465 {
466 set_gpio_input();
467 set_gpio1(1);
468 }
469 else
470#endif
471 IO_Serial_RTS_Clr(ifd->io);
472
473 IO_Serial_Ioctl_Lock(0);
474
475 (*atr) = ATR_New ();
476
477 if(ATR_InitFromStream ((*atr), ifd->io, IFD_TOWITOKO_ATR_TIMEOUT) == ATR_OK)
478 ret = IFD_TOWITOKO_OK;
479
480 /* Succesfully retrive ATR */
481 if (ret == IFD_TOWITOKO_OK)
482 {
483 break;
484 }
485 else
486 {
487 ATR_Delete (*atr);
488 (*atr) = NULL;
489#ifdef USE_GPIO
490 if (gpio_detect) set_gpio1(0);
491#endif
492 }
493 }
494
495 IO_Serial_Flush(ifd->io);
496
497/*
498 //PLAYGROUND faking ATR for test purposes only
499 //
500 // 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 };
501 // 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 };
502 // S02 = irdeto unsigned char atr_test[] = { 0x3B, 0x9F, 0x21, 0x0E, 0x49, 0x52, 0x44, 0x45, 0x54, 0x4F, 0x20, 0x41, 0x43, 0x53, 0x03};
503 //cryptoworks unsigned char atr_test[] = { 0x3B, 0x78, 0x12, 0x00, 0x00, 0x65, 0xC4, 0x05, 0xFF, 0x8F, 0xF1, 0x90, 0x00 };
504 ATR_Delete(*atr); //throw away actual ATR
505 (*atr) = ATR_New ();
506 ATR_InitFromArray ((*atr), atr_test, sizeof(atr_test));
507 //END OF PLAYGROUND
508*/
509
510 return ret;
511}
512
513int IFD_Towitoko_Transmit (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
514{
515 unsigned block_delay, char_delay, sent=0, to_send = 0;
516
517#ifdef DEBUG_IFD
518 printf ("IFD: Transmit: ");
519 for (sent = 0; sent < size; sent++)
520 printf ("%X ", buffer[sent]);
521 printf ("\n");
522#endif
523
524
525 /* Calculate delays */
526 char_delay = IFD_TOWITOKO_DELAY + timings->char_delay;
527 block_delay = IFD_TOWITOKO_DELAY + timings->block_delay;
528
529#ifdef USE_GPIO
530 if (gpio_detect) set_gpio1(0);
531#endif
532 for (sent = 0; sent < size; sent = sent + to_send)
533 {
534 /* Calculate number of bytes to send */
535 to_send = MIN(size, IFD_TOWITOKO_MAX_TRANSMIT);
536
537 /* Send data */
538 if ((sent == 0) && (block_delay != char_delay))
539 {
540 if (!IO_Serial_Write (ifd->io, block_delay, 1, buffer))
541 return IFD_TOWITOKO_IO_ERROR;
542
543 if (!IO_Serial_Write (ifd->io, char_delay, to_send-1, buffer+1))
544 return IFD_TOWITOKO_IO_ERROR;
545 }
546 else
547 {
548 if (!IO_Serial_Write (ifd->io, char_delay, to_send, buffer+sent))
549 return IFD_TOWITOKO_IO_ERROR;
550 }
551 }
552#ifdef USE_GPIO
553 if (gpio_detect) set_gpio1(1);
554#endif
555 return IFD_TOWITOKO_OK;
556}
557
558int IFD_Towitoko_Receive (IFD * ifd, IFD_Timings * timings, unsigned size, BYTE * buffer)
559{
560 unsigned char_timeout, block_timeout;
561#ifdef DEBUG_IFD
562 int i;
563#endif
564
565 /* Calculate timeouts */
566 char_timeout = IFD_TOWITOKO_TIMEOUT + timings->char_timeout;
567 block_timeout = IFD_TOWITOKO_TIMEOUT + timings->block_timeout;
568#ifdef USE_GPIO
569 if (gpio_detect) set_gpio1(0);
570#endif
571 if (block_timeout != char_timeout)
572 {
573 /* Read first byte using block timeout */
574 if (!IO_Serial_Read (ifd->io, block_timeout, 1, buffer))
575 return IFD_TOWITOKO_IO_ERROR;
576
577 if (size > 1)
578 {
579 /* Read remaining data bytes using char timeout */
580 if (!IO_Serial_Read (ifd->io, char_timeout, size - 1, buffer + 1))
581 return IFD_TOWITOKO_IO_ERROR;
582 }
583 }
584 else
585 {
586 /* Read all data bytes with the same timeout */
587 if (!IO_Serial_Read (ifd->io, char_timeout, size, buffer))
588 return IFD_TOWITOKO_IO_ERROR;
589 }
590#ifdef USE_GPIO
591 if (gpio_detect) set_gpio1(1);
592#endif
593
594#ifdef DEBUG_IFD
595 printf ("IFD: Receive: ");
596 for (i = 0; i < size; i++)
597 printf ("%X ", buffer[i]);
598 printf ("\n");
599#endif
600
601 return IFD_TOWITOKO_OK;
602}
603
604
605BYTE IFD_Towitoko_GetType (IFD * ifd)
606{
607 return ifd->type;
608}
609
610void IFD_Towitoko_GetDescription (IFD * ifd, BYTE * desc, unsigned length)
611{
612 char buffer[3];
613
614 if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_II)
615 memcpy (desc,"CE2",MIN(length,3));
616
617 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_EXT_I)
618 memcpy (desc,"CE1",MIN(length,3));
619
620 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_INT)
621 memcpy (desc,"CDI",MIN(length,3));
622
623 else if (ifd->type == IFD_TOWITOKO_CHIPDRIVE_MICRO)
624 memcpy (desc,"CDM",MIN(length,3));
625
626 else if (ifd->type == IFD_TOWITOKO_KARTENZWERG_II)
627 memcpy (desc,"KZ2",MIN(length,3));
628
629 else if (ifd->type == IFD_TOWITOKO_KARTENZWERG)
630 memcpy (desc,"KZ1",MIN(length,3));
631
632 else if (ifd->type == IFD_TOWITOKO_MULTICAM)
633 memcpy (desc,"MCM",MIN(length,3));
634
635 else
636 memcpy (desc,"UNK",MIN(length,3));
637
638 snprintf (buffer, 3, "%02X", ifd->firmware);
639
640 if (length > 3)
641 memcpy (desc+3, buffer, MIN(length-3,2));
642}
643
644BYTE
645IFD_Towitoko_GetFirmware (IFD * ifd)
646{
647 return ifd->firmware;
648}
649
650BYTE
651IFD_Towitoko_GetSlot (IFD * ifd)
652{
653 return ifd->slot;
654}
655
656unsigned
657IFD_Towitoko_GetNumSlots ()
658{
659 return 1;
660}
661
662unsigned long
663IFD_Towitoko_GetMaxBaudrate ()
664{
665 return 115200L;
666}
667
668/*
669 * Not exported funcions definition
670 */
671
672
673static int IFD_Towitoko_GetReaderInfo (IFD * ifd)
674{
675 BYTE status[3];
676
677 status[0] = IFD_TOWITOKO_MULTICAM;
678 status[1] = 0x00;
679
680 ifd->type = status[0];
681 ifd->firmware = status[1];
682
683#ifdef DEBUG_IFD
684 printf ("IFD: Reader type = %s\n",
685 status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_II ? "Chipdrive Extern II" :
686 status[0] == IFD_TOWITOKO_CHIPDRIVE_EXT_I ? "Chipdrive Extern I" :
687 status[0] == IFD_TOWITOKO_CHIPDRIVE_INT ? "Chipdrive Intern" :
688 status[0] == IFD_TOWITOKO_CHIPDRIVE_MICRO ? "Chipdrive Micro" :
689 status[0] == IFD_TOWITOKO_KARTENZWERG_II ? "Kartenzwerg II" :
690 status[0] == IFD_TOWITOKO_MULTICAM ? "Multicam" :
691 status[0] == IFD_TOWITOKO_KARTENZWERG ? "Kartenzwerg" : "Unknown");
692#endif
693
694 return IFD_TOWITOKO_OK;
695}
696
697
698static void IFD_Towitoko_Clear (IFD * ifd)
699{
700 ifd->io = NULL;
701 ifd->slot = 0x00;
702 ifd->type = 0x00;
703 ifd->firmware = 0x00;
704 reader[ridx].status = 0;
705}
Note: See TracBrowser for help on using the repository browser.