source: trunk/csctapi/io_serial.c@ 69

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

csctapi/io_serial.c : update of the mac os x serial IO. Works on SECA at 3.58 and 6MHz, not on viaccess.
As I rewrote my own code (looking at the existing one) I think this is most probably a timing issue.
The initial problem on OS X are the IO_Serial_WaitToWrite and IO_Serial_WaitToRead function that always
return a timeout as I have to set the port in O_NDELAY for it to work on OS X, O_SYNC doesn't work.
I might try to fix these routine instead and see how it goes but I'm affraid that without the sync mode this
is not going to work as expected.

File size: 24.9 KB
Line 
1/*
2 io_serial.c
3 Serial port input/output functions
4
5 This file is part of the Unix driver for Towitoko smartcard readers
6 Copyright (C) 2000 2001 Carlos Prados <cprados@yahoo.com>
7
8 This version is modified by doz21 to work in a special manner ;)
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#include "defines.h"
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#ifdef OS_HPUX
30#include <sys/modem.h>
31#endif
32#include <termios.h>
33#include <unistd.h>
34#include <sys/stat.h>
35#include <fcntl.h>
36#ifdef HAVE_POLL
37#include <sys/poll.h>
38#else
39#include <sys/signal.h>
40#include <sys/types.h>
41#include <sys/time.h>
42#endif
43#include <sys/ioctl.h>
44#include <time.h>
45#include "io_serial.h"
46#include "mc_global.h"
47
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
699 if((io->com!=RTYP_SCI) && (io->wr>0))
700 {
701 BYTE buf[256];
702 int n = io->wr;
703 io->wr = 0;
704
705 if(!IO_Serial_Read_MacOSX (io, timeout, n, buf))
706 {
707 return FALSE;
708 }
709 }
710
711#ifdef DEBUG_IO
712 printf ("IO: IO_Serial_Read_MacOSX\n");
713 printf ("IO: Receiving %d byte(s): ",size);
714 fflush (stdout);
715#endif
716 while(TRUE)
717 {
718 nByte=read(io->fd,&c,1);
719 if(nByte<=0)
720 {
721 usleep (1000L); // 1ms
722 m_timeout++;
723 if(m_timeout==timeout)
724 {
725#ifdef DEBUG_IO
726 printf ("TIMEOUT\n");
727 fflush (stdout);
728#endif
729 tcflush (io->fd, TCIFLUSH);
730 return FALSE;
731 }
732 }
733 else
734 {
735 m_timeout=0;
736#ifdef DEBUG_IO
737 printf ("%02X ", c);
738 fflush (stdout);
739#endif
740 data[_in_echo_read ? totalRead/(1+io_serial_need_dummy_char) : totalRead] = c;
741 totalRead+=nByte;
742 if(length == totalRead)
743 break;
744 }
745 }
746
747 _in_echo_read = 0;
748
749#ifdef DEBUG_IO
750 printf ("\n");
751 fflush (stdout);
752 printf("exiting IO_Serial_Read_MacOSX [true]\n" );
753#endif
754 return TRUE;
755}
756
757//
758// Send "size" Byte data present in data
759// return true if data was correctly send
760//
761bool IO_Serial_Write_MacOSX (IO_Serial * io, unsigned delay, unsigned size, BYTE * data)
762{
763 int nByte;
764 int m_delay;
765 BYTE data_w[512];
766 int i_w;
767 unsigned count, to_send;
768
769#ifdef DEBUG_IO
770 unsigned i;
771 printf ("IO: IO_Serial_Write_MacOSX\n");
772 printf ("IO: Sending %d byte(s) : ",size);
773 fflush (stdout);
774#endif
775
776 m_delay=0;
777 nByte=0;
778 to_send = (delay? 1: size);
779
780 // send the data
781 for (count = 0; count < size; count += to_send)
782 {
783 for (i_w=0; i_w < to_send; i_w++)
784 {
785 data_w [(1+io_serial_need_dummy_char)*i_w] = data [count + i_w];
786 if (io_serial_need_dummy_char)
787 {
788 data_w [2*i_w+1] = 0x00;
789 }
790 }
791
792 nByte=write(io->fd,data_w,(1+io_serial_need_dummy_char)*to_send);
793 _in_echo_read = 1;
794
795 if(nByte<=0 || nByte!=(1+io_serial_need_dummy_char)*to_send)
796 {
797 tcflush (io->fd, TCIFLUSH);
798 if(io->com!=RTYP_SCI)
799 io->wr += nByte;
800
801#ifdef DEBUG_IO
802 printf ("ERROR\n");
803 printf("exiting IO_Serial_Write_MacOSX [false]\n" );
804 fflush (stdout);
805#endif
806 return FALSE;
807 }
808 if(delay)
809 usleep(delay*1000L);
810
811 if(io->com!=RTYP_SCI)
812 io->wr += to_send;
813
814#ifdef DEBUG_IO
815 for (i=0; i<(1+io_serial_need_dummy_char)*to_send; i++)
816 printf ("%02 X ", data_w[count + i]);
817 fflush (stdout);
818#endif
819
820 }
821
822#ifdef DEBUG_IO
823 printf ("\n");
824 fflush (stdout);
825#endif
826 return TRUE;
827}
828
829
830
831bool IO_Serial_Read (IO_Serial * io, unsigned timeout, unsigned size, BYTE * data)
832{
833 BYTE c;
834 int count = 0;
835
836
837 if((io->com!=RTYP_SCI) && (io->wr>0))
838 {
839 BYTE buf[256];
840 int n = io->wr;
841 io->wr = 0;
842
843 if(!IO_Serial_Read (io, timeout, n, buf))
844 {
845 return FALSE;
846 }
847 }
848
849#ifdef DEBUG_IO
850 printf ("IO: Receiving: ");
851 fflush (stdout);
852#endif
853 for (count = 0; count < size * (_in_echo_read ? (1+io_serial_need_dummy_char) : 1); count++)
854 {
855 if (IO_Serial_WaitToRead (io->fd, 0, timeout))
856 {
857 if (read (io->fd, &c, 1) != 1)
858 {
859#ifdef DEBUG_IO
860 printf ("ERROR\n");
861 fflush (stdout);
862#endif
863 return FALSE;
864 }
865 data[_in_echo_read ? count/(1+io_serial_need_dummy_char) : count] = c;
866
867#ifdef DEBUG_IO
868 printf ("%X ", c);
869 fflush (stdout);
870#endif
871 }
872 else
873 {
874#ifdef DEBUG_IO
875 printf ("TIMEOUT\n");
876 fflush (stdout);
877#endif
878 tcflush (io->fd, TCIFLUSH);
879 return FALSE;
880 }
881 }
882
883 _in_echo_read = 0;
884
885#ifdef DEBUG_IO
886 printf ("\n");
887 fflush (stdout);
888#endif
889
890 return TRUE;
891}
892
893
894
895
896bool IO_Serial_Write (IO_Serial * io, unsigned delay, unsigned size, BYTE * data)
897{
898 unsigned count, to_send;
899 BYTE data_w[512];
900 int i_w;
901#ifdef DEBUG_IO
902 unsigned i;
903
904 printf ("IO: Sending: ");
905 fflush (stdout);
906#endif
907 /* Discard input data from previous commands */
908// tcflush (io->fd, TCIFLUSH);
909
910 for (count = 0; count < size; count += to_send)
911 {
912// if(io->com==RTYP_SCI)
913// to_send = 1;
914// else
915 to_send = (delay? 1: size);
916
917 if (IO_Serial_WaitToWrite (io, delay, 1000))
918 {
919 for (i_w=0; i_w < to_send; i_w++) {
920 data_w [(1+io_serial_need_dummy_char)*i_w] = data [count + i_w];
921 if (io_serial_need_dummy_char) {
922 data_w [2*i_w+1] = 0x00;
923 }
924 }
925 unsigned int u = write (io->fd, data_w, (1+io_serial_need_dummy_char)*to_send);
926 _in_echo_read = 1;
927 if (u != (1+io_serial_need_dummy_char)*to_send)
928 {
929#ifdef DEBUG_IO
930 printf ("ERROR\n");
931 fflush (stdout);
932#endif
933 if(io->com!=RTYP_SCI)
934 io->wr += u;
935 return FALSE;
936 }
937
938 if(io->com!=RTYP_SCI)
939 io->wr += to_send;
940
941#ifdef DEBUG_IO
942 for (i=0; i<(1+io_serial_need_dummy_char)*to_send; i++)
943 printf ("%X ", data_w[count + i]);
944 fflush (stdout);
945#endif
946 }
947 else
948 {
949#ifdef DEBUG_IO
950 printf ("TIMEOUT\n");
951 fflush (stdout);
952#endif
953// tcflush (io->fd, TCIFLUSH);
954 return FALSE;
955 }
956 }
957
958#ifdef DEBUG_IO
959 printf ("\n");
960 fflush (stdout);
961#endif
962
963 return TRUE;
964}
965
966bool IO_Serial_Close (IO_Serial * io)
967{
968 char filename[IO_SERIAL_FILENAME_LENGTH];
969
970 IO_Serial_DeviceName (io->com, io->usbserial, filename, IO_SERIAL_FILENAME_LENGTH);
971
972#ifdef DEBUG_IO
973 printf ("IO: Clossing serial port %s\n", filename);
974#endif
975
976#if defined(TUXBOX) && defined(PPC)
977 close(fdmc);
978#endif
979 if (close (io->fd) != 0)
980 return FALSE;
981
982 IO_Serial_ClearPropertiesCache (io);
983 IO_Serial_Clear (io);
984
985 return TRUE;
986}
987
988void IO_Serial_Delete (IO_Serial * io)
989{
990 if (io->props != NULL)
991 free (io->props);
992
993 free (io);
994}
995
996/*
997 * Internal functions definition
998 */
999
1000static int IO_Serial_Bitrate(int bitrate)
1001{
1002#ifdef B230400
1003 if ((bitrate)>=230400) return B230400;
1004#endif
1005#ifdef B115200
1006 if ((bitrate)>=115200) return B115200;
1007#endif
1008#ifdef B57600
1009 if ((bitrate)>=57600) return B57600;
1010#endif
1011#ifdef B38400
1012 if ((bitrate)>=38400) return B38400;
1013#endif
1014#ifdef B19200
1015 if ((bitrate)>=19200) return B19200;
1016#endif
1017#ifdef B9600
1018 if ((bitrate)>=9600) return B9600;
1019#endif
1020#ifdef B4800
1021 if ((bitrate)>=4800) return B4800;
1022#endif
1023#ifdef B2400
1024 if ((bitrate)>=2400) return B2400;
1025#endif
1026#ifdef B1800
1027 if ((bitrate)>=1800) return B1800;
1028#endif
1029#ifdef B1200
1030 if ((bitrate)>=1200) return B1200;
1031#endif
1032#ifdef B600
1033 if ((bitrate)>=600) return B600;
1034#endif
1035#ifdef B300
1036 if ((bitrate)>=300) return B300;
1037#endif
1038#ifdef B200
1039 if ((bitrate)>=200) return B200;
1040#endif
1041#ifdef B150
1042 if ((bitrate)>=150) return B150;
1043#endif
1044#ifdef B134
1045 if ((bitrate)>=134) return B134;
1046#endif
1047#ifdef B110
1048 if ((bitrate)>=110) return B110;
1049#endif
1050#ifdef B75
1051 if ((bitrate)>=75) return B75;
1052#endif
1053#ifdef B50
1054 if ((bitrate)>=50) return B50;
1055#endif
1056#ifdef B0
1057 if ((bitrate)>=0) return B0;
1058#endif
1059 return 0; /* Should never get here */
1060}
1061
1062static bool IO_Serial_WaitToRead (int hnd, unsigned delay_ms, unsigned timeout_ms)
1063{
1064 int rval;
1065 struct pollfd ufds;
1066
1067 if (delay_ms > 0)
1068 {
1069#ifdef HAVE_NANOSLEEP
1070 struct timespec req_ts;
1071
1072 req_ts.tv_sec = delay_ms / 1000;
1073 req_ts.tv_nsec = (delay_ms % 1000) * 1000000L;
1074 nanosleep (&req_ts, NULL);
1075#else
1076 usleep (delay_ms * 1000L);
1077#endif
1078 }
1079
1080 ufds.fd = hnd;
1081 ufds.events = POLLIN;
1082 ufds.revents = 0x0000;
1083
1084 rval = poll (&ufds, 1, timeout_ms);
1085 if (rval != 1)
1086 return (FALSE);
1087
1088 return (((ufds.revents) & POLLIN) == POLLIN);
1089}
1090
1091static bool IO_Serial_WaitToWrite (IO_Serial *io, unsigned delay_ms, unsigned timeout_ms)
1092{
1093 int rval;
1094 struct pollfd ufds;
1095
1096#ifdef SCI_DEV
1097 if(io->com==RTYP_SCI)
1098 return TRUE;
1099#endif
1100
1101 if (delay_ms > 0)
1102 {
1103#ifdef HAVE_NANOSLEEP
1104 struct timespec req_ts;
1105
1106 req_ts.tv_sec = delay_ms / 1000;
1107 req_ts.tv_nsec = (delay_ms % 1000) * 1000000L;
1108 nanosleep (&req_ts, NULL);
1109#else
1110 usleep (delay_ms * 1000L);
1111#endif
1112 }
1113
1114 ufds.fd = io->fd;
1115 ufds.events = POLLOUT;
1116 ufds.revents = 0x0000;
1117
1118 rval = poll (&ufds, 1, timeout_ms);
1119 if (rval != 1)
1120 return (FALSE);
1121
1122 return (((ufds.revents) & POLLOUT) == POLLOUT);
1123}
1124
1125static void IO_Serial_Clear (IO_Serial * io)
1126{
1127 io->fd = -1;
1128 io->props = NULL;
1129 io->com = 0;
1130 memset (io->PnP_id, 0, IO_SERIAL_PNPID_SIZE);
1131 io->PnP_id_size = 0;
1132 io->usbserial = FALSE;
1133 io->wr = 0;
1134}
1135
1136static void IO_Serial_SetPropertiesCache(IO_Serial * io, IO_Serial_Properties * props)
1137{
1138#ifdef SCI_DEV
1139 if(io->com==RTYP_SCI)
1140 return;
1141#endif
1142
1143 if (io->props == NULL)
1144 io->props = (IO_Serial_Properties *) malloc (sizeof (IO_Serial_Properties));
1145#ifdef DEBUG_IO
1146 printf ("IO: Catching properties\n");
1147#endif
1148
1149 memcpy (io->props, props, sizeof (IO_Serial_Properties));
1150}
1151
1152static bool IO_Serial_GetPropertiesCache(IO_Serial * io, IO_Serial_Properties * props)
1153{
1154 if (io->props != NULL)
1155 {
1156 memcpy (props, io->props, sizeof (IO_Serial_Properties));
1157#if 0
1158#ifdef DEBUG_IO
1159 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);
1160#endif
1161#endif
1162 return TRUE;
1163 }
1164
1165 return FALSE;
1166}
1167
1168static void IO_Serial_ClearPropertiesCache (IO_Serial * io)
1169{
1170#ifdef DEBUG_IO
1171 printf ("IO: Clearing properties cache\n");
1172#endif
1173 if (io->props != NULL)
1174 {
1175 free (io->props);
1176 io->props = NULL;
1177 }
1178}
1179
1180static void IO_Serial_DeviceName (unsigned com, bool usbserial, char * filename, unsigned length)
1181{
1182 extern char oscam_device[];
1183 snprintf (filename, length, "%s", oscam_device);
1184// if(com==1)
1185// snprintf (filename, length, "/dev/tts/%d", com - 1);
1186// else
1187// snprintf (filename, length, "/dev/sci%d", com - 2);
1188}
1189
1190static bool IO_Serial_InitPnP (IO_Serial * io)
1191{
1192 IO_Serial_Properties props;
1193 int i = 0;
1194 props.input_bitrate = 1200;
1195 props.output_bitrate = 1200;
1196 props.parity = IO_SERIAL_PARITY_NONE;
1197 props.bits = 7;
1198 props.stopbits = 1;
1199 props.dtr = IO_SERIAL_HIGH;
1200// props.rts = IO_SERIAL_HIGH;
1201 props.rts = IO_SERIAL_LOW;
1202
1203 if (!IO_Serial_SetProperties (io, &props))
1204 return FALSE;
1205
1206#ifdef OS_MACOSX
1207 while ((i < IO_SERIAL_PNPID_SIZE) && IO_Serial_Read_MacOSX (io, 200, 1, &(io->PnP_id[i])))
1208 i++;
1209#else
1210 while ((i < IO_SERIAL_PNPID_SIZE) && IO_Serial_Read (io, 200, 1, &(io->PnP_id[i])))
1211 i++;
1212#endif
1213
1214 io->PnP_id_size = i;
1215 return TRUE;
1216}
Note: See TracBrowser for help on using the repository browser.