source: trunk/csctapi/io_serial.c@ 68

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

csctapi/io_serial.c : remove trace messages I forgot before my last commit... sorry

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