source: trunk/csctapi/io_serial.c@ 1

Last change on this file since 1 was 1, checked in by root, 14 years ago

initial import

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