source: trunk/csctapi/io_serial.c@ 72

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

csctapi/io_serial.[c,h] : added the irdeto param to the IO_Serial_Set_Smartreader_Freq

as after talking to a contact, we thing we need to set NN to 1 for irdete (and 0 for seca).

File size: 24.4 KB
Line 
1 /*
2 io_serial.c
3 Serial port input/output 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#include <errno.h>
30#ifdef OS_HPUX
31#include <sys/modem.h>
32#endif
33#include <termios.h>
34#include <unistd.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#ifdef HAVE_POLL
38#include <sys/poll.h>
39#else
40#include <sys/signal.h>
41#include <sys/types.h>
42#include <sys/time.h>
43#endif
44#include <sys/ioctl.h>
45#include <time.h>
46#include "io_serial.h"
47#include "mc_global.h"
48
49#ifdef OS_LINUX
50#include <linux/serial.h>
51#endif
52
53#define IO_SERIAL_FILENAME_LENGTH 32
54
55/*
56 * Internal functions declaration
57 */
58
59static int IO_Serial_Bitrate(int bitrate);
60
61static bool IO_Serial_WaitToRead (int hnd, unsigned delay_ms, unsigned timeout_ms);
62
63static bool IO_Serial_WaitToWrite (IO_Serial *io, unsigned delay_ms, unsigned timeout_ms);
64
65static void IO_Serial_DeviceName (unsigned com, bool usbserial, char * filename, unsigned length);
66
67static bool IO_Serial_InitPnP (IO_Serial * io);
68
69static void IO_Serial_Clear (IO_Serial * io);
70
71static bool IO_Serial_GetPropertiesCache(IO_Serial * io, IO_Serial_Properties * props);
72
73static void IO_Serial_SetPropertiesCache(IO_Serial * io, IO_Serial_Properties * props);
74
75static void IO_Serial_ClearPropertiesCache (IO_Serial * io);
76
77static int _in_echo_read = 0;
78int io_serial_need_dummy_char = 0;
79
80int fdmc=(-1);
81
82#if defined(TUXBOX) && defined(PPC)
83void IO_Serial_Ioctl_Lock(IO_Serial * io, int flag)
84{
85 extern int *oscam_sem;
86 if ((io->com!=RTYP_DB2COM1) && (io->com!=RTYP_DB2COM2)) return;
87 if (!flag)
88 *oscam_sem=0;
89 else while (*oscam_sem!=io->com)
90 {
91 while (*oscam_sem)
92 usleep((io->com)*2000);
93 *oscam_sem=io->com;
94 usleep(1000);
95 }
96}
97
98static bool IO_Serial_DTR_RTS_dbox2(int mcport, int dtr, int set)
99{
100 int rc;
101 unsigned short msr;
102 unsigned int mbit;
103 unsigned short rts_bits[2]={ 0x10, 0x800};
104 unsigned short dtr_bits[2]={0x100, 0};
105
106#ifdef DEBUG_IO
107printf("IO: multicam.o %s %s\n", dtr ? "dtr" : "rts", set ? "set" : "clear"); fflush(stdout);
108#endif
109 if ((rc=ioctl(fdmc, GET_PCDAT, &msr))>=0)
110 {
111 if (dtr) // DTR
112 {
113 if (dtr_bits[mcport])
114 {
115 if (set)
116 msr&=(unsigned short)(~dtr_bits[mcport]);
117 else
118 msr|=dtr_bits[mcport];
119 rc=ioctl(fdmc, SET_PCDAT, &msr);
120 }
121 else
122 rc=0; // Dummy, can't handle using multicam.o
123 }
124 else // RTS
125 {
126 if (set)
127 msr&=(unsigned short)(~rts_bits[mcport]);
128 else
129 msr|=rts_bits[mcport];
130 rc=ioctl(fdmc, SET_PCDAT, &msr);
131 }
132 }
133 return((rc<0) ? FALSE : TRUE);
134}
135#endif
136
137bool IO_Serial_DTR_RTS(IO_Serial * io, int dtr, int set)
138{
139 unsigned int msr;
140 unsigned int mbit;
141
142#if defined(TUXBOX) && defined(PPC)
143 if ((io->com==RTYP_DB2COM1) || (io->com==RTYP_DB2COM2))
144 return(IO_Serial_DTR_RTS_dbox2(io->com==RTYP_DB2COM2, dtr, set));
145#endif
146
147 mbit=(dtr) ? TIOCM_DTR : TIOCM_RTS;
148#if defined(TIOCMBIS) && defined(TIOBMBIC)
149 if (ioctl (io->fd, set ? TIOCMBIS : TIOCMBIC, &mbit) < 0)
150 return FALSE;
151#else
152 if (ioctl(io->fd, TIOCMGET, &msr) < 0)
153 return FALSE;
154 if (set)
155 msr|=mbit;
156 else
157 msr&=~mbit;
158 return((ioctl(io->fd, TIOCMSET, &msr)<0) ? FALSE : TRUE);
159#endif
160}
161
162/*
163 * Public functions definition
164 */
165
166IO_Serial * IO_Serial_New (int reader_type)
167{
168 IO_Serial *io;
169
170 io = (IO_Serial *) malloc (sizeof (IO_Serial));
171
172 if (io != NULL)
173 IO_Serial_Clear (io);
174
175 io->reader_type=reader_type;
176
177 return io;
178}
179
180bool IO_Serial_Init (IO_Serial * io, unsigned com, bool usbserial, bool pnp)
181{
182 char filename[IO_SERIAL_FILENAME_LENGTH];
183
184 IO_Serial_DeviceName (com, usbserial, filename, IO_SERIAL_FILENAME_LENGTH);
185
186#ifdef DEBUG_IO
187 printf ("IO: Opening serial port %s\n", filename);
188#endif
189
190 if (com < 1)
191 return FALSE;
192
193 io->com = com;
194
195#ifdef SCI_DEV
196 if (com==RTYP_SCI)
197 io->fd = open (filename, O_RDWR);
198 else
199#endif
200
201#ifdef OS_MACOSX
202 io->fd = open (filename, O_RDWR | O_NOCTTY | O_NDELAY );
203#else
204 io->fd = open (filename, O_RDWR | O_NOCTTY | O_SYNC);
205#endif
206
207 if (io->fd < 0)
208 return FALSE;
209
210#if defined(TUXBOX) && defined(PPC)
211 if ((com==RTYP_DB2COM1) || (com==RTYP_DB2COM2))
212 if ((fdmc = open(DEV_MULTICAM, O_RDWR)) < 0)
213 {
214 close(io->fd);
215 return FALSE;
216 }
217#endif
218
219 if (com!=RTYP_SCI)
220 IO_Serial_InitPnP (io);
221
222 io->usbserial=usbserial;
223
224 if(io->com!=RTYP_SCI)
225 IO_Serial_Flush(io);
226
227 return TRUE;
228}
229
230bool IO_Serial_GetProperties (IO_Serial * io, IO_Serial_Properties * props)
231{
232 struct termios currtio;
233 speed_t i_speed, o_speed;
234 unsigned int mctl;
235
236#ifdef SCI_DEV
237 if(io->com==RTYP_SCI)
238 return FALSE;
239#endif
240
241 if (IO_Serial_GetPropertiesCache(io, props))
242 return TRUE;
243
244 if (tcgetattr (io->fd, &currtio) != 0)
245 return FALSE;
246
247 o_speed = cfgetospeed (&currtio);
248
249 switch (o_speed)
250 {
251#ifdef B0
252 case B0:
253 props->output_bitrate = 0;
254 break;
255#endif
256#ifdef B50
257 case B50:
258 props->output_bitrate = 50;
259 break;
260#endif
261#ifdef B75
262 case B75:
263 props->output_bitrate = 75;
264 break;
265#endif
266#ifdef B110
267 case B110:
268 props->output_bitrate = 110;
269 break;
270#endif
271#ifdef B134
272 case B134:
273 props->output_bitrate = 134;
274 break;
275#endif
276#ifdef B150
277 case B150:
278 props->output_bitrate = 150;
279 break;
280#endif
281#ifdef B200
282 case B200:
283 props->output_bitrate = 200;
284 break;
285#endif
286#ifdef B300
287 case B300:
288 props->output_bitrate = 300;
289 break;
290#endif
291#ifdef B600
292 case B600:
293 props->output_bitrate = 600;
294 break;
295#endif
296#ifdef B1200
297 case B1200:
298 props->output_bitrate = 1200;
299 break;
300#endif
301#ifdef B1800
302 case B1800:
303 props->output_bitrate = 1800;
304 break;
305#endif
306#ifdef B2400
307 case B2400:
308 props->output_bitrate = 2400;
309 break;
310#endif
311#ifdef B4800
312 case B4800:
313 props->output_bitrate = 4800;
314 break;
315#endif
316#ifdef B9600
317 case B9600:
318 props->output_bitrate = 9600;
319 break;
320#endif
321#ifdef B19200
322 case B19200:
323 props->output_bitrate = 19200;
324 break;
325#endif
326#ifdef B38400
327 case B38400:
328 props->output_bitrate = 38400;
329 break;
330#endif
331#ifdef B57600
332 case B57600:
333 props->output_bitrate = 57600;
334 break;
335#endif
336#ifdef B115200
337 case B115200:
338 props->output_bitrate = 115200;
339 break;
340#endif
341#ifdef B230400
342 case B230400:
343 props->output_bitrate = 230400;
344 break;
345#endif
346 default:
347 props->output_bitrate = 1200;
348 break;
349 }
350
351 i_speed = cfgetispeed (&currtio);
352
353 switch (i_speed)
354 {
355#ifdef B0
356 case B0:
357 props->input_bitrate = 0;
358 break;
359#endif
360#ifdef B50
361 case B50:
362 props->input_bitrate = 50;
363 break;
364#endif
365#ifdef B75
366 case B75:
367 props->input_bitrate = 75;
368 break;
369#endif
370#ifdef B110
371 case B110:
372 props->input_bitrate = 110;
373 break;
374#endif
375#ifdef B134
376 case B134:
377 props->input_bitrate = 134;
378 break;
379#endif
380#ifdef B150
381 case B150:
382 props->input_bitrate = 150;
383 break;
384#endif
385#ifdef B200
386 case B200:
387 props->input_bitrate = 200;
388 break;
389#endif
390#ifdef B300
391 case B300:
392 props->input_bitrate = 300;
393 break;
394#endif
395#ifdef B600
396 case B600:
397 props->input_bitrate = 600;
398 break;
399#endif
400#ifdef B1200
401 case B1200:
402 props->input_bitrate = 1200;
403 break;
404#endif
405#ifdef B1800
406 case B1800:
407 props->input_bitrate = 1800;
408 break;
409#endif
410#ifdef B2400
411 case B2400:
412 props->input_bitrate = 2400;
413 break;
414#endif
415#ifdef B4800
416 case B4800:
417 props->input_bitrate = 4800;
418 break;
419#endif
420#ifdef B9600
421 case B9600:
422 props->input_bitrate = 9600;
423 break;
424#endif
425#ifdef B19200
426 case B19200:
427 props->input_bitrate = 19200;
428 break;
429#endif
430#ifdef B38400
431 case B38400:
432 props->input_bitrate = 38400;
433 break;
434#endif
435#ifdef B57600
436 case B57600:
437 props->input_bitrate = 57600;
438 break;
439#endif
440#ifdef B115200
441 case B115200:
442 props->input_bitrate = 115200;
443 break;
444#endif
445#ifdef B230400
446 case B230400:
447 props->input_bitrate = 230400;
448 break;
449#endif
450 default:
451 props->input_bitrate = 1200;
452 break;
453 }
454
455 switch (currtio.c_cflag & CSIZE)
456 {
457 case CS5:
458 props->bits = 5;
459 break;
460 case CS6:
461 props->bits = 6;
462 break;
463 case CS7:
464 props->bits = 7;
465 break;
466 case CS8:
467 props->bits = 8;
468 break;
469 }
470
471 if (((currtio.c_cflag) & PARENB) == PARENB)
472 {
473 if (((currtio.c_cflag) & PARODD) == PARODD)
474 props->parity = IO_SERIAL_PARITY_ODD;
475 else
476 props->parity = IO_SERIAL_PARITY_EVEN;
477 }
478 else
479 {
480 props->parity = IO_SERIAL_PARITY_NONE;
481 }
482
483 if (((currtio.c_cflag) & CSTOPB) == CSTOPB)
484 props->stopbits = 2;
485 else
486 props->stopbits = 1;
487
488 if (ioctl (io->fd, TIOCMGET, &mctl) < 0)
489 return FALSE;
490
491 props->dtr = ((mctl & TIOCM_DTR) ? IO_SERIAL_HIGH : IO_SERIAL_LOW);
492 props->rts = ((mctl & TIOCM_RTS) ? IO_SERIAL_HIGH : IO_SERIAL_LOW);
493
494 IO_Serial_SetPropertiesCache (io, props);
495
496#ifdef DEBUG_IO
497 printf("IO: Getting properties: %ld bps; %d bits/byte; %s parity; %d stopbits; dtr=%d; rts=%d\n", props->input_bitrate, props->bits, props->parity == IO_SERIAL_PARITY_EVEN ? "Even" : props->parity == IO_SERIAL_PARITY_ODD ? "Odd" : "None", props->stopbits, props->dtr, props->rts);
498#endif
499
500 return TRUE;
501}
502
503bool IO_Serial_SetProperties (IO_Serial * io, IO_Serial_Properties * props)
504{
505 struct termios newtio;
506 unsigned int modembits;
507
508#ifdef SCI_DEV
509 if(io->com==RTYP_SCI)
510 return FALSE;
511#endif
512
513 // printf("IO: Setting properties: com%d, %ld bps; %d bits/byte; %s parity; %d stopbits; dtr=%d; rts=%d\n", io->com, props->input_bitrate, props->bits, props->parity == IO_SERIAL_PARITY_EVEN ? "Even" : props->parity == IO_SERIAL_PARITY_ODD ? "Odd" : "None", props->stopbits, props->dtr, props->rts);
514 memset (&newtio, 0, sizeof (newtio));
515 /* Set the bitrate */
516
517 extern int mhz;
518 extern int reader_irdeto_mode;
519
520 if(io->reader_type==RTYP_SMART)
521 {
522#ifdef DEBUG_IO
523 printf("IO: SMARTREADER .. switching to frequency to %2.2fMHz\n", (float)mhz/100.0);
524#endif
525 if(!IO_Serial_Set_Smartreader_Freq(io,mhz,reader_irdeto_mode))
526 {
527#ifdef DEBUG_IO
528 printf("IO: SMARTREADER .. ERROR switching to 6MHz\n");
529#endif
530 return FALSE;
531 }
532 }
533
534 if (mhz == 600)
535 {
536
537 /* for 6MHz */
538 if (reader_irdeto_mode)
539 {
540 cfsetospeed(&newtio, IO_Serial_Bitrate(props->output_bitrate));
541 cfsetispeed(&newtio, IO_Serial_Bitrate(props->input_bitrate));
542 }
543 else
544 {
545#ifdef OS_LINUX
546 /* these structures are only available on linux as fas as we know so limit this code to OS_LINUX */
547 struct serial_struct nuts;
548 ioctl(io->fd, TIOCGSERIAL, &nuts);
549 nuts.custom_divisor = nuts.baud_base / 9600 * 3.57 / 6;
550 nuts.flags &= ~ASYNC_SPD_MASK;
551 nuts.flags |= ASYNC_SPD_CUST;
552 ioctl(io->fd, TIOCSSERIAL, &nuts);
553 cfsetospeed(&newtio, IO_Serial_Bitrate(38400));
554 cfsetispeed(&newtio, IO_Serial_Bitrate(38400));
555#else
556 cfsetospeed(&newtio, IO_Serial_Bitrate(props->output_bitrate));
557 cfsetispeed(&newtio, IO_Serial_Bitrate(props->input_bitrate));
558#endif
559 }
560 }
561 else if (mhz == 357 || mhz == 358)
562 {
563 /* for 3.57 MHz */
564 if (reader_irdeto_mode)
565 {
566#ifdef OS_LINUX
567 /* these structures are only available on linux as fas as we know so limit this code to OS_LINUX */
568 struct serial_struct nuts;
569 ioctl(io->fd, TIOCGSERIAL, &nuts);
570 nuts.custom_divisor = nuts.baud_base / 5713;
571 nuts.flags &= ~ASYNC_SPD_MASK;
572 nuts.flags |= ASYNC_SPD_CUST;
573 ioctl(io->fd, TIOCSSERIAL, &nuts);
574 cfsetospeed(&newtio, IO_Serial_Bitrate(38400));
575 cfsetispeed(&newtio, IO_Serial_Bitrate(38400));
576#else
577 cfsetospeed(&newtio, IO_Serial_Bitrate(props->output_bitrate));
578 cfsetispeed(&newtio, IO_Serial_Bitrate(props->input_bitrate));
579#endif
580 }
581 else
582 {
583 cfsetospeed(&newtio, IO_Serial_Bitrate(props->output_bitrate));
584 cfsetispeed(&newtio, IO_Serial_Bitrate(props->input_bitrate));
585 }
586 }
587 else
588 {
589 /* invalid */
590 return FALSE;
591 }
592
593 /* Set the character size */
594 switch (props->bits)
595 {
596 case 5:
597 newtio.c_cflag |= CS5;
598 break;
599
600 case 6:
601 newtio.c_cflag |= CS6;
602 break;
603
604 case 7:
605 newtio.c_cflag |= CS7;
606 break;
607
608 case 8:
609 newtio.c_cflag |= CS8;
610 break;
611 }
612
613 /* Set the parity */
614 switch (props->parity)
615 {
616 case IO_SERIAL_PARITY_ODD:
617 newtio.c_cflag |= PARENB;
618 newtio.c_cflag |= PARODD;
619 break;
620
621 case IO_SERIAL_PARITY_EVEN:
622 newtio.c_cflag |= PARENB;
623 newtio.c_cflag &= ~PARODD;
624 break;
625
626 case IO_SERIAL_PARITY_NONE:
627 newtio.c_cflag &= ~PARENB;
628 break;
629 }
630
631 /* Set the number of stop bits */
632 switch (props->stopbits)
633 {
634 case 1:
635 newtio.c_cflag &= (~CSTOPB);
636 break;
637 case 2:
638 newtio.c_cflag |= CSTOPB;
639 break;
640 }
641
642 /* Selects raw (non-canonical) input and output */
643 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
644 newtio.c_oflag &= ~OPOST;
645#if 1
646 newtio.c_iflag |= IGNPAR;
647 /* Ignore parity errors!!! Windows driver does so why shouldn't I? */
648#endif
649 /* Enable receiber, hang on close, ignore control line */
650 newtio.c_cflag |= CREAD | HUPCL | CLOCAL;
651
652 /* Read 1 byte minimun, no timeout specified */
653 newtio.c_cc[VMIN] = 1;
654 newtio.c_cc[VTIME] = 0;
655
656// tcdrain(io->fd);
657 if (tcsetattr (io->fd, TCSANOW, &newtio) < 0)
658 return FALSE;
659// tcflush(io->fd, TCIOFLUSH);
660// if (tcsetattr (io->fd, TCSAFLUSH, &newtio) < 0)
661// return FALSE;
662
663 IO_Serial_Ioctl_Lock(io, 1);
664 IO_Serial_DTR_RTS(io, 0, props->rts == IO_SERIAL_HIGH);
665 IO_Serial_DTR_RTS(io, 1, props->dtr == IO_SERIAL_HIGH);
666 IO_Serial_Ioctl_Lock(io, 0);
667
668 IO_Serial_SetPropertiesCache (io, props);
669
670#ifdef DEBUG_IO
671 printf("IO: Setting properties: com%d, %ld bps; %d bits/byte; %s parity; %d stopbits; dtr=%d; rts=%d\n", io->com, props->input_bitrate, props->bits, props->parity == IO_SERIAL_PARITY_EVEN ? "Even" : props->parity == IO_SERIAL_PARITY_ODD ? "Odd" : "None", props->stopbits, props->dtr, props->rts);
672#endif
673 return TRUE;
674}
675
676void IO_Serial_Flush (IO_Serial * io)
677{
678 BYTE b;
679 while(IO_Serial_Read(io, 1000, 1, &b));
680}
681
682
683void IO_Serial_GetPnPId (IO_Serial * io, BYTE * pnp_id, unsigned *length)
684{
685 (*length) = io->PnP_id_size;
686 memcpy (pnp_id, io->PnP_id, io->PnP_id_size);
687}
688
689unsigned IO_Serial_GetCom (IO_Serial * io)
690{
691 return io->com;
692}
693
694
695bool IO_Serial_Read (IO_Serial * io, unsigned timeout, unsigned size, BYTE * data)
696{
697 BYTE c;
698 int count = 0;
699
700
701 if((io->com!=RTYP_SCI) && (io->wr>0))
702 {
703 BYTE buf[256];
704 int n = io->wr;
705 io->wr = 0;
706
707 if(!IO_Serial_Read (io, timeout, n, buf))
708 {
709 return FALSE;
710 }
711 }
712
713#ifdef DEBUG_IO
714 printf ("IO: Receiving: ");
715 fflush (stdout);
716#endif
717 for (count = 0; count < size * (_in_echo_read ? (1+io_serial_need_dummy_char) : 1); count++)
718 {
719 if (IO_Serial_WaitToRead (io->fd, 0, timeout))
720 {
721 if (read (io->fd, &c, 1) != 1)
722 {
723#ifdef DEBUG_IO
724 printf ("ERROR\n");
725 fflush (stdout);
726#endif
727 return FALSE;
728 }
729 data[_in_echo_read ? count/(1+io_serial_need_dummy_char) : count] = c;
730
731#ifdef DEBUG_IO
732 printf ("%X ", c);
733 fflush (stdout);
734#endif
735 }
736 else
737 {
738#ifdef DEBUG_IO
739 printf ("TIMEOUT\n");
740 fflush (stdout);
741#endif
742 tcflush (io->fd, TCIFLUSH);
743 return FALSE;
744 }
745 }
746
747 _in_echo_read = 0;
748
749#ifdef DEBUG_IO
750 printf ("\n");
751 fflush (stdout);
752#endif
753
754 return TRUE;
755}
756
757
758
759
760bool IO_Serial_Write (IO_Serial * io, unsigned delay, unsigned size, BYTE * data)
761{
762 unsigned count, to_send;
763 BYTE data_w[512];
764 int i_w;
765#ifdef DEBUG_IO
766 unsigned i;
767
768 printf ("IO: Sending: ");
769 fflush (stdout);
770#endif
771 /* Discard input data from previous commands */
772// tcflush (io->fd, TCIFLUSH);
773
774 for (count = 0; count < size; count += to_send)
775 {
776// if(io->com==RTYP_SCI)
777// to_send = 1;
778// else
779 to_send = (delay? 1: size);
780
781 if (IO_Serial_WaitToWrite (io, delay, 1000))
782 {
783 for (i_w=0; i_w < to_send; i_w++) {
784 data_w [(1+io_serial_need_dummy_char)*i_w] = data [count + i_w];
785 if (io_serial_need_dummy_char) {
786 data_w [2*i_w+1] = 0x00;
787 }
788 }
789 unsigned int u = write (io->fd, data_w, (1+io_serial_need_dummy_char)*to_send);
790 _in_echo_read = 1;
791 if (u != (1+io_serial_need_dummy_char)*to_send)
792 {
793#ifdef DEBUG_IO
794 printf ("ERROR\n");
795 fflush (stdout);
796#endif
797 if(io->com!=RTYP_SCI)
798 io->wr += u;
799 return FALSE;
800 }
801
802 if(io->com!=RTYP_SCI)
803 io->wr += to_send;
804
805#ifdef DEBUG_IO
806 for (i=0; i<(1+io_serial_need_dummy_char)*to_send; i++)
807 printf ("%X ", data_w[count + i]);
808 fflush (stdout);
809#endif
810 }
811 else
812 {
813#ifdef DEBUG_IO
814 printf ("TIMEOUT\n");
815 fflush (stdout);
816#endif
817// tcflush (io->fd, TCIFLUSH);
818 return FALSE;
819 }
820 }
821
822#ifdef DEBUG_IO
823 printf ("\n");
824 fflush (stdout);
825#endif
826
827 return TRUE;
828}
829
830bool IO_Serial_Close (IO_Serial * io)
831{
832 char filename[IO_SERIAL_FILENAME_LENGTH];
833
834 IO_Serial_DeviceName (io->com, io->usbserial, filename, IO_SERIAL_FILENAME_LENGTH);
835
836#ifdef DEBUG_IO
837 printf ("IO: Clossing serial port %s\n", filename);
838#endif
839
840#if defined(TUXBOX) && defined(PPC)
841 close(fdmc);
842#endif
843 if (close (io->fd) != 0)
844 return FALSE;
845
846 IO_Serial_ClearPropertiesCache (io);
847 IO_Serial_Clear (io);
848
849 return TRUE;
850}
851
852void IO_Serial_Delete (IO_Serial * io)
853{
854 if (io->props != NULL)
855 free (io->props);
856
857 free (io);
858}
859
860/*
861 * Internal functions definition
862 */
863
864static int IO_Serial_Bitrate(int bitrate)
865{
866#ifdef B230400
867 if ((bitrate)>=230400) return B230400;
868#endif
869#ifdef B115200
870 if ((bitrate)>=115200) return B115200;
871#endif
872#ifdef B57600
873 if ((bitrate)>=57600) return B57600;
874#endif
875#ifdef B38400
876 if ((bitrate)>=38400) return B38400;
877#endif
878#ifdef B19200
879 if ((bitrate)>=19200) return B19200;
880#endif
881#ifdef B9600
882 if ((bitrate)>=9600) return B9600;
883#endif
884#ifdef B4800
885 if ((bitrate)>=4800) return B4800;
886#endif
887#ifdef B2400
888 if ((bitrate)>=2400) return B2400;
889#endif
890#ifdef B1800
891 if ((bitrate)>=1800) return B1800;
892#endif
893#ifdef B1200
894 if ((bitrate)>=1200) return B1200;
895#endif
896#ifdef B600
897 if ((bitrate)>=600) return B600;
898#endif
899#ifdef B300
900 if ((bitrate)>=300) return B300;
901#endif
902#ifdef B200
903 if ((bitrate)>=200) return B200;
904#endif
905#ifdef B150
906 if ((bitrate)>=150) return B150;
907#endif
908#ifdef B134
909 if ((bitrate)>=134) return B134;
910#endif
911#ifdef B110
912 if ((bitrate)>=110) return B110;
913#endif
914#ifdef B75
915 if ((bitrate)>=75) return B75;
916#endif
917#ifdef B50
918 if ((bitrate)>=50) return B50;
919#endif
920#ifdef B0
921 if ((bitrate)>=0) return B0;
922#endif
923 return 0; /* Should never get here */
924}
925
926static bool IO_Serial_WaitToRead (int hnd, unsigned delay_ms, unsigned timeout_ms)
927{
928 fd_set rfds;
929 fd_set erfds;
930 struct timeval tv;
931 int select_ret;
932 int in_fd;
933
934 if (delay_ms > 0)
935 {
936#ifdef HAVE_NANOSLEEP
937 struct timespec req_ts;
938
939 req_ts.tv_sec = delay_ms / 1000;
940 req_ts.tv_nsec = (delay_ms % 1000) * 1000000L;
941 nanosleep (&req_ts, NULL);
942#else
943 usleep (delay_ms * 1000L);
944#endif
945 }
946
947 in_fd=hnd;
948
949 FD_ZERO(&rfds);
950 FD_SET(in_fd, &rfds);
951
952 FD_ZERO(&erfds);
953 FD_SET(in_fd, &erfds);
954
955 tv.tv_sec = timeout_ms/1000;
956 tv.tv_usec = (timeout_ms % 1000) * 1000L;
957 select_ret = select(in_fd+1, &rfds, NULL, &erfds, &tv);
958 if(select_ret==-1)
959 {
960 printf("select_ret=%i\n" , select_ret);
961 printf("errno =%d\n", errno);
962 fflush(stdout);
963 return (FALSE);
964 }
965
966 if (FD_ISSET(in_fd, &erfds))
967 {
968 printf("fd is in error fds\n");
969 printf("errno =%d\n", errno);
970 fflush(stdout);
971 return (FALSE);
972 }
973
974 return(FD_ISSET(in_fd,&rfds));
975}
976
977static bool IO_Serial_WaitToWrite (IO_Serial *io, unsigned delay_ms, unsigned timeout_ms)
978{
979 fd_set wfds;
980 fd_set ewfds;
981 struct timeval tv;
982 int select_ret;
983 int out_fd;
984
985#ifdef SCI_DEV
986 if(io->com==RTYP_SCI)
987 return TRUE;
988#endif
989
990 if (delay_ms > 0)
991 {
992#ifdef HAVE_NANOSLEEP
993 struct timespec req_ts;
994
995 req_ts.tv_sec = delay_ms / 1000;
996 req_ts.tv_nsec = (delay_ms % 1000) * 1000000L;
997 nanosleep (&req_ts, NULL);
998#else
999 usleep (delay_ms * 1000L);
1000#endif
1001 }
1002
1003 out_fd=io->fd;
1004
1005 FD_ZERO(&wfds);
1006 FD_SET(out_fd, &wfds);
1007
1008 FD_ZERO(&ewfds);
1009 FD_SET(out_fd, &ewfds);
1010
1011 tv.tv_sec = timeout_ms/1000L;
1012 tv.tv_usec = (timeout_ms % 1000) * 1000L;
1013
1014 select_ret = select(out_fd+1, NULL, &wfds, &ewfds, &tv);
1015
1016 if(select_ret==-1)
1017 {
1018 printf("select_ret=%d\n" , select_ret);
1019 printf("errno =%d\n", errno);
1020 fflush(stdout);
1021 return (FALSE);
1022 }
1023
1024 if (FD_ISSET(out_fd, &ewfds))
1025 {
1026 printf("fd is in ewfds\n");
1027 printf("errno =%d\n", errno);
1028 fflush(stdout);
1029 return (FALSE);
1030 }
1031
1032 return(FD_ISSET(out_fd,&wfds));
1033
1034}
1035
1036static void IO_Serial_Clear (IO_Serial * io)
1037{
1038 io->fd = -1;
1039 io->props = NULL;
1040 io->com = 0;
1041 memset (io->PnP_id, 0, IO_SERIAL_PNPID_SIZE);
1042 io->PnP_id_size = 0;
1043 io->usbserial = FALSE;
1044 io->wr = 0;
1045}
1046
1047static void IO_Serial_SetPropertiesCache(IO_Serial * io, IO_Serial_Properties * props)
1048{
1049#ifdef SCI_DEV
1050 if(io->com==RTYP_SCI)
1051 return;
1052#endif
1053
1054 if (io->props == NULL)
1055 io->props = (IO_Serial_Properties *) malloc (sizeof (IO_Serial_Properties));
1056#ifdef DEBUG_IO
1057 printf ("IO: Catching properties\n");
1058#endif
1059
1060 memcpy (io->props, props, sizeof (IO_Serial_Properties));
1061}
1062
1063static bool IO_Serial_GetPropertiesCache(IO_Serial * io, IO_Serial_Properties * props)
1064{
1065 if (io->props != NULL)
1066 {
1067 memcpy (props, io->props, sizeof (IO_Serial_Properties));
1068#if 0
1069#ifdef DEBUG_IO
1070 printf("IO: Getting properties (catched): %ld bps; %d bits/byte; %s parity; %d stopbits; dtr=%d; rts=%d\n", props->input_bitrate, props->bits, props->parity == IO_SERIAL_PARITY_EVEN ? "Even" : props->parity == IO_SERIAL_PARITY_ODD ? "Odd" : "None", props->stopbits, props->dtr, props->rts);
1071#endif
1072#endif
1073 return TRUE;
1074 }
1075
1076 return FALSE;
1077}
1078
1079static void IO_Serial_ClearPropertiesCache (IO_Serial * io)
1080{
1081#ifdef DEBUG_IO
1082 printf ("IO: Clearing properties cache\n");
1083#endif
1084 if (io->props != NULL)
1085 {
1086 free (io->props);
1087 io->props = NULL;
1088 }
1089}
1090
1091static void IO_Serial_DeviceName (unsigned com, bool usbserial, char * filename, unsigned length)
1092{
1093 extern char oscam_device[];
1094 snprintf (filename, length, "%s", oscam_device);
1095// if(com==1)
1096// snprintf (filename, length, "/dev/tts/%d", com - 1);
1097// else
1098// snprintf (filename, length, "/dev/sci%d", com - 2);
1099}
1100
1101static bool IO_Serial_InitPnP (IO_Serial * io)
1102{
1103 IO_Serial_Properties props;
1104 int i = 0;
1105 props.input_bitrate = 1200;
1106 props.output_bitrate = 1200;
1107 props.parity = IO_SERIAL_PARITY_NONE;
1108 props.bits = 7;
1109 props.stopbits = 1;
1110 props.dtr = IO_SERIAL_HIGH;
1111// props.rts = IO_SERIAL_HIGH;
1112 props.rts = IO_SERIAL_LOW;
1113
1114 if (!IO_Serial_SetProperties (io, &props))
1115 return FALSE;
1116
1117 while ((i < IO_SERIAL_PNPID_SIZE) && IO_Serial_Read (io, 200, 1, &(io->PnP_id[i])))
1118 i++;
1119
1120 io->PnP_id_size = i;
1121 return TRUE;
1122}
1123
1124
1125bool IO_Serial_Set_Smartreader_Freq(IO_Serial * io, int freq, int irdeto_mode)
1126 {
1127 struct termios term;
1128 struct termios orig;
1129 unsigned int u;
1130 unsigned char fi_di[4]={0x01, 0x01, 0x74, 0x01};
1131 unsigned char fr[3]={0x02, 0x00, 0x00};
1132 unsigned char nn[2]={0x03, 0x00};
1133 unsigned char pr[2]={0x04, 0x00};
1134 unsigned char in[2]={0x05, 0x00};
1135
1136 orig=term;
1137
1138 /* set smartreader in CMD mode */
1139 tcgetattr(io->fd, &term);
1140
1141 term.c_cflag &= ~CSIZE;
1142 term.c_cflag |= CS5;
1143 cfsetospeed(&term, 9600);
1144 cfsetispeed(&term, 9600);
1145 tcsetattr(io->fd, TCSANOW, &term);
1146 freq*=10;
1147 fr[1]=(unsigned char)((freq & 0xff00)>>8);
1148 fr[2]=(unsigned char)(freq & 0x00ff);
1149
1150 // printf("fr = %02x %02x %02x\n" , fr[0],fr[1],fr[2]);
1151
1152 if(irdeto_mode)
1153 nn[1]=0x01;
1154
1155 // send the commands
1156 IO_Serial_Write (io, 0, 4, fi_di);
1157 IO_Serial_Flush(io);
1158
1159 IO_Serial_Write (io, 0, 3, fr);
1160 IO_Serial_Flush(io);
1161
1162 IO_Serial_Write (io, 0, 2, nn);
1163 IO_Serial_Flush(io);
1164
1165 IO_Serial_Write (io, 0, 3, pr);
1166 IO_Serial_Flush(io);
1167
1168 IO_Serial_Write (io, 0, 2, in);
1169 IO_Serial_Flush(io);
1170
1171 /* set smartreader in DATA mode */
1172 tcgetattr(io->fd, &orig);
1173 orig.c_cflag &= ~CSIZE;
1174 orig.c_cflag |= CS8;
1175 tcsetattr(io->fd, TCSANOW, &orig);
1176
1177 return TRUE;
1178 }
1179
Note: See TracBrowser for help on using the repository browser.