source: branches/monitor-improvement/csctapi/io_serial.c@ 1189

Last change on this file since 1189 was 1189, checked in by alno, 12 years ago

WebIf:

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