source: trunk/csctapi/io_serial.c@ 54

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

Preliminary support for Mac OS X.

Now, it compile, but it will not work with the serial port.
Thanks rorothetroll for this patch

File size: 21.3 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#ifdef OS_LINUX
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#ifdef OS_LINUX
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(props->output_bitrate));
528 cfsetispeed(&newtio, IO_Serial_Bitrate(props->input_bitrate));
529#endif
530 }
531 } else if (mhz == 357 || mhz == 358) {
532 /* for 3.57 MHz */
533 if (reader_irdeto_mode) {
534#ifdef OS_LINUX
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(props->output_bitrate));
545 cfsetispeed(&newtio, IO_Serial_Bitrate(props->input_bitrate));
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.