source: trunk/csctapi/io_serial.c@ 45

Last change on this file since 45 was 45, checked in by smurzch2, 14 years ago

Now it compiles also on cygwin.

But not really tested, as I don't have a real Windows PC.
Should works, except the videoguard2.
Thanks to the streamboard guys for reporting the bug and helping in the
resolution.

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