- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / csctapi / io_serial.c
blob5647af6e9c53a26440e05510571d6a2e63634f36
1 /*
2 io_serial.c
3 Serial port input/output functions
5 This file is part of the Unix driver for Towitoko smartcard readers
6 Copyright (C) 2000 2001 Carlos Prados <cprados@yahoo.com>
8 This version is modified by doz21 to work in a special manner ;)
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.
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.
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
25 #include "../globals.h"
26 #ifdef WITH_CARDREADER
28 #if defined(__HPUX__)
29 #include <sys/modem.h>
30 #endif
32 #include <poll.h>
34 #if defined(__linux__) && !defined(__ANDROID__)
35 #include <linux/serial.h>
36 #endif
38 #if defined(__ANDROID__)
39 #include "../extapi/linux/serial.h"
40 #endif
42 #include "../oscam-time.h"
43 #include "icc_async.h"
44 #include "io_serial.h"
46 #if defined(__APPLE__)
47 #include <IOKIT/serial/ioss.h>
48 #endif
50 #define OK 0
51 #define ERROR 1
53 #define IO_SERIAL_FILENAME_LENGTH 32
56 * Internal functions declaration
59 static int32_t IO_Serial_Bitrate(int32_t bitrate);
61 static bool IO_Serial_WaitToWrite(struct s_reader *reader, uint32_t delay_us, uint32_t timeout_us);
63 static int32_t oscam_sem;
65 void IO_Serial_Ioctl_Lock(struct s_reader *reader, int32_t flag)
67 if((reader->typ != R_DB2COM1) && (reader->typ != R_DB2COM2)) { return; }
68 if(!flag)
69 { oscam_sem = 0; }
70 else while(oscam_sem != reader->typ)
72 while(oscam_sem)
73 if(reader->typ == R_DB2COM1)
74 { cs_sleepms(6); }
75 else
76 { cs_sleepms(8); }
77 oscam_sem = reader->typ;
78 cs_sleepms(1);
82 bool IO_Serial_DTR_RTS(struct s_reader *reader, int32_t *dtr, int32_t *rts)
84 const struct s_cardreader *crdr_ops = reader->crdr;
85 if (!crdr_ops) return ERROR;
87 if(crdr_ops->set_DTS_RTS)
88 { return crdr_ops->set_DTS_RTS(reader, dtr, rts); }
90 uint32_t msr;
91 uint32_t mbit;
93 if(dtr)
95 mbit = TIOCM_DTR;
96 #if defined(TIOCMBIS) && defined(TIOBMBIC)
97 if(ioctl(reader->handle, *dtr ? TIOCMBIS : TIOCMBIC, &mbit) < 0)
98 { return ERROR; }
99 #else
100 if(ioctl(reader->handle, TIOCMGET, &msr) < 0)
101 { return ERROR; }
102 if(*dtr)
103 { msr |= mbit; }
104 else
105 { msr &= ~mbit; }
106 if(ioctl(reader->handle, TIOCMSET, &msr) < 0)
107 { return ERROR; }
108 #endif
109 rdr_log_dbg(reader, D_DEVICE, "Setting %s=%i", "DTR", *dtr);
112 if(rts)
114 mbit = TIOCM_RTS;
115 #if defined(TIOCMBIS) && defined(TIOBMBIC)
116 if(ioctl(reader->handle, *rts ? TIOCMBIS : TIOCMBIC, &mbit) < 0)
117 { return ERROR; }
118 #else
119 if(ioctl(reader->handle, TIOCMGET, &msr) < 0)
120 { return ERROR; }
121 if(*rts)
122 { msr |= mbit; }
123 else
124 { msr &= ~mbit; }
125 if(ioctl(reader->handle, TIOCMSET, &msr) < 0)
126 { return ERROR; }
127 #endif
128 rdr_log_dbg(reader, D_DEVICE, "Setting %s=%i", "RTS", *rts);
131 return OK;
135 * Public functions definition
138 bool IO_Serial_SetBitrate(struct s_reader *reader, uint32_t bitrate, struct termios *tio)
140 /* Set the bitrate */
141 #if !defined(__linux__)
142 #if !defined(__APPLE__)
143 if(IO_Serial_Bitrate(bitrate) == B0)
145 rdr_log(reader, "Baudrate %u not supported", bitrate);
146 return ERROR;
148 else
150 //no overclocking
151 cfsetospeed(tio, IO_Serial_Bitrate(bitrate));
152 cfsetispeed(tio, IO_Serial_Bitrate(bitrate));
153 rdr_log_dbg(reader, D_DEVICE, "standard baudrate: cardmhz=%d mhz=%d -> effective baudrate %u",
154 reader->cardmhz, reader->mhz, bitrate);
156 #endif
157 #endif
159 /* Set the bitrate */
160 #if defined(__linux__)
161 //FIXME workaround for Smargo until native mode works
162 if((reader->mhz == reader->cardmhz) && (reader->smargopatch != 1) && IO_Serial_Bitrate(bitrate) != B0)
164 //no overclocking
165 cfsetospeed(tio, IO_Serial_Bitrate(bitrate));
166 cfsetispeed(tio, IO_Serial_Bitrate(bitrate));
167 rdr_log_dbg(reader, D_DEVICE, "standard baudrate: cardmhz=%d mhz=%d -> effective baudrate %u",
168 reader->cardmhz, reader->mhz, bitrate);
170 else
172 //over or underclocking
173 /* these structures are only available on linux */
174 struct serial_struct nuts;
175 // This makes valgrind happy, because it doesn't know what TIOCGSERIAL does
176 // Without this there are lots of misleading errors of type:
177 // "Conditional jump or move depends on uninitialised value(s)"
178 nuts.baud_base = 0;
179 nuts.custom_divisor = 0;
180 ioctl(reader->handle, TIOCGSERIAL, &nuts);
181 int32_t custom_baud_asked = bitrate * reader->mhz / reader->cardmhz;
182 nuts.custom_divisor = (nuts.baud_base + (custom_baud_asked / 2)) / custom_baud_asked;
183 int32_t custom_baud_delivered = nuts.baud_base / nuts.custom_divisor;
184 rdr_log_dbg(reader, D_DEVICE, "custom baudrate: cardmhz=%d mhz=%d custom_baud=%d baud_base=%d divisor=%d -> effective baudrate %d",
185 reader->cardmhz, reader->mhz, custom_baud_asked, nuts.baud_base, nuts.custom_divisor, custom_baud_delivered);
186 int32_t baud_diff = custom_baud_delivered - custom_baud_asked;
187 if(baud_diff < 0)
188 { baud_diff = (-baud_diff); }
189 if(baud_diff > 0.05 * custom_baud_asked)
191 rdr_log(reader, "WARNING: your card is asking for custom_baudrate = %i, but your configuration can only deliver custom_baudrate = %i", custom_baud_asked, custom_baud_delivered);
192 rdr_log(reader, "You are over- or underclocking, try OSCam when running your reader at normal clockspeed as required by your card, and setting mhz and cardmhz parameters accordingly.");
193 if(nuts.baud_base <= 115200)
194 { rdr_log(reader, "You are probably connecting your reader via a serial port, OSCam has more flexibility switching to custom_baudrates when using an USB->serial converter, preferably based on FTDI chip."); }
196 nuts.flags &= ~ASYNC_SPD_MASK;
197 nuts.flags |= ASYNC_SPD_CUST;
198 ioctl(reader->handle, TIOCSSERIAL, &nuts);
199 cfsetospeed(tio, IO_Serial_Bitrate(38400));
200 cfsetispeed(tio, IO_Serial_Bitrate(38400));
202 #endif
204 /* Set the bitrate */
205 #if defined(__APPLE__)
206 if(IO_Serial_Bitrate(bitrate) == B0)
208 if(ioctl(reader->handle, IOSSIOSPEED, &bitrate) < 0)
210 rdr_log(reader, "Baudrate %u not supported", bitrate);
211 return ERROR;
213 else
215 rdr_log_dbg(reader, D_DEVICE, "custom baudrate: cardmhz=%d mhz=%d -> effective baudrate %u",
216 reader->cardmhz, reader->mhz, bitrate);
219 else
221 //no overclocking
222 cfsetospeed(tio, IO_Serial_Bitrate(bitrate));
223 cfsetispeed(tio, IO_Serial_Bitrate(bitrate));
224 rdr_log_dbg(reader, D_DEVICE, "standard baudrate: cardmhz=%d mhz=%d -> effective baudrate %u",
225 reader->cardmhz, reader->mhz, bitrate);
227 #endif
228 return OK;
231 bool IO_Serial_SetParams(struct s_reader *reader, uint32_t bitrate, uint32_t bits, int32_t parity, uint32_t stopbits, int32_t *dtr, int32_t *rts)
233 struct termios newtio;
235 if(reader->typ == R_INTERNAL)
236 { return ERROR; }
238 memset(&newtio, 0, sizeof(newtio));
240 if(IO_Serial_SetBitrate(reader, bitrate, & newtio))
241 { return ERROR; }
243 /* Set the character size */
244 switch(bits)
246 case 5:
247 newtio.c_cflag |= CS5;
248 break;
250 case 6:
251 newtio.c_cflag |= CS6;
252 break;
254 case 7:
255 newtio.c_cflag |= CS7;
256 break;
258 case 8:
259 newtio.c_cflag |= CS8;
260 break;
263 /* Set the parity */
264 switch(parity)
266 case PARITY_ODD:
267 newtio.c_cflag |= PARENB;
268 newtio.c_cflag |= PARODD;
269 break;
271 case PARITY_EVEN:
272 newtio.c_cflag |= PARENB;
273 newtio.c_cflag &= ~PARODD;
274 break;
276 case PARITY_NONE:
277 newtio.c_cflag &= ~PARENB;
278 break;
281 /* Set the number of stop bits */
282 switch(stopbits)
284 case 1:
285 newtio.c_cflag &= (~CSTOPB);
286 break;
287 case 2:
288 newtio.c_cflag |= CSTOPB;
289 break;
292 /* Selects raw (non-canonical) input and output */
293 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
294 newtio.c_oflag &= ~OPOST;
295 #if 1
296 newtio.c_iflag |= IGNPAR;
297 /* Ignore parity errors!!! Windows driver does so why shouldn't I? */
298 #endif
299 /* Enable receiver, hang on close, ignore control line */
300 newtio.c_cflag |= CREAD | HUPCL | CLOCAL;
302 /* Read 1 byte minimun, no timeout specified */
303 newtio.c_cc[VMIN] = 1;
304 newtio.c_cc[VTIME] = 0;
306 if(IO_Serial_SetProperties(reader, newtio))
307 { return ERROR; }
309 reader->current_baudrate = bitrate;
311 IO_Serial_Ioctl_Lock(reader, 1);
312 IO_Serial_DTR_RTS(reader, dtr, rts);
313 IO_Serial_Ioctl_Lock(reader, 0);
314 return OK;
317 bool IO_Serial_SetProperties(struct s_reader *reader, struct termios newtio)
319 if(reader->typ == R_INTERNAL)
320 { return OK; }
322 if(tcsetattr(reader->handle, TCSANOW, &newtio) < 0) // set terminal attributes.
323 { return ERROR; }
325 int32_t mctl;
326 rdr_log_dbg(reader, D_DEVICE, "Getting readerstatus...");
327 if(ioctl(reader->handle, TIOCMGET, &mctl) >= 0) // get reader statusbits
329 mctl &= ~TIOCM_RTS;
330 rdr_log_dbg(reader, D_DEVICE, "Set reader ready to Send");
331 ioctl(reader->handle, TIOCMSET, &mctl); // set reader ready to send.
333 else { rdr_log(reader, "WARNING: Cant get readerstatus!"); }
335 return OK;
338 int32_t IO_Serial_SetParity(struct s_reader *reader, unsigned char parity)
340 struct termios tio;
341 int32_t current_parity;
342 // Get current parity
343 if(tcgetattr(reader->handle, &tio) != 0)
345 rdr_log(reader, "ERROR: Could not get current parity, %s (errno=%d %s)", __func__, errno, strerror(errno));
346 current_parity = 5; // set to unknown (5 is not predefined!)
348 else
350 if(((tio.c_cflag) & PARENB) == PARENB)
352 if(((tio.c_cflag) & PARODD) == PARODD)
353 { current_parity = PARITY_ODD; }
354 else
355 { current_parity = PARITY_EVEN; }
357 else
359 current_parity = PARITY_NONE;
363 if(current_parity != parity)
365 rdr_log_dbg(reader, D_IFD, "Setting parity from %s to %s",
366 current_parity == PARITY_ODD ? "Odd" :
367 current_parity == PARITY_NONE ? "None" :
368 current_parity == PARITY_EVEN ? "Even" : "Unknown",
370 parity == PARITY_ODD ? "Odd" :
371 parity == PARITY_NONE ? "None" :
372 parity == PARITY_EVEN ? "Even" : "Invalid");
374 // Set the parity
375 switch(parity)
377 case PARITY_ODD:
378 tio.c_cflag |= PARENB;
379 tio.c_cflag |= PARODD;
380 break;
382 case PARITY_EVEN:
383 tio.c_cflag |= PARENB;
384 tio.c_cflag &= ~PARODD;
385 break;
387 case PARITY_NONE:
388 tio.c_cflag &= ~PARENB;
389 break;
391 if(IO_Serial_SetProperties(reader, tio))
393 rdr_log_dbg(reader, D_IFD, "ERROR: could set parity!");
394 return ERROR;
398 return OK;
401 void IO_Serial_Flush(struct s_reader *reader)
403 unsigned char b;
404 uint8_t n = 0;
405 tcflush(reader->handle, TCIOFLUSH);
406 struct timeb starttotal, endtotal;
407 struct timeb start, end;
408 cs_ftimeus(&starttotal);
409 endtotal = starttotal;
410 cs_ftimeus(&start);
411 end = start;
412 int64_t gone = 0;
413 while(!IO_Serial_Read(reader, 0, 75000, 1, &b)) // first appears between 9~75ms
415 n++;
416 cs_ftimeus(&end);
417 gone = comp_timebus(&end, &start);
418 rdr_log_dbg(reader, D_DEVICE, "Flush readed byte Nr %d value %.2x time_us %"PRId64, n, b, gone);
419 cs_ftimeus(&start); // Reset timer
420 end = start;
422 cs_ftimeus(&endtotal);
423 gone = comp_timebus(&endtotal, &starttotal);
424 rdr_log_dbg(reader, D_DEVICE, "Buffers readed %d bytes total time_us %"PRId64, n, gone);
427 void IO_Serial_Sendbreak(struct s_reader *reader, int32_t duration)
429 tcsendbreak(reader->handle, duration / 1000);
432 bool IO_Serial_Read(struct s_reader *reader, uint32_t delay, uint32_t timeout, uint32_t size, unsigned char *data)
434 uint32_t count = 0;
436 if(timeout == 0) // General fix for readers not communicating timeout and delay
438 if(reader->read_timeout != 0) { timeout = reader->read_timeout; }
439 else { timeout = 9999000; } // hope 9999000 is long enough!
440 rdr_log_dbg(reader, D_DEVICE, "Warning: read timeout 0 changed to %d us", timeout);
443 rdr_log_dbg(reader, D_DEVICE, "Read timeout %d us, read delay %d us, to read %d char(s), chunksize %d char(s)", timeout, delay, size, size);
445 #if defined(WITH_STAPI) || defined(WITH_STAPI5) || defined(__SH4__) //internal stapi and sh4 readers need special treatment as they don't respond correctly to poll and some sh4 boxes only can read 1 byte at once
446 if(reader->typ == R_INTERNAL)
448 int32_t readed;
449 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
450 const uint32_t chunksize = INT_MAX;
451 #elif defined(__SH4__)
452 const uint32_t chunksize = 1;
453 #endif
454 struct timeb start, end;
455 cs_ftime(&start);
456 end = start;
457 int64_t gone = 0;
458 int32_t timeout_ms = timeout / 1000;
459 readed = 0;
461 while(gone < timeout_ms)
463 readed = read(reader->handle, &data[count], size - count >= chunksize ? chunksize : size - count);
464 cs_ftime(&end);
465 if(readed > 0)
467 count += readed;
468 cs_ftime(&start); // Reset timer
469 end = start;
471 gone = comp_timeb(&end, &start);
472 if(count < size)
474 if(readed < (int32_t)chunksize) { cs_sleepus(1); }
475 continue;
477 else { break; }
479 if(count < size)
481 rdr_log_dump_dbg(reader, D_DEVICE, data, count, "Receiving:");
482 return ERROR;
485 else
486 #endif // read all chars at once for all other boxes
488 while(count < size)
490 int32_t readed = -1, errorcount = 0;
491 AGAIN:
492 if(IO_Serial_WaitToRead(reader, delay, timeout))
494 rdr_log_dbg(reader, D_DEVICE, "Timeout in IO_Serial_WaitToRead, timeout=%d us", timeout);
495 return ERROR;
498 while(readed < 0 && errorcount < 10)
500 readed = read(reader->handle, &data[count], size - count);
501 if(readed < 0)
503 if(errno == EINTR) { continue; } // try again in case of interrupt
504 if(errno == EAGAIN) { goto AGAIN; } //EAGAIN needs select procedure again
505 rdr_log(reader, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno));
506 errorcount++;
510 if(readed == 0)
512 rdr_log_dump_dbg(reader, D_DEVICE, data, count, "Receiving:");
513 rdr_log_dbg(reader, D_DEVICE, "Received End of transmission");
514 return ERROR;
516 count += readed;
519 rdr_log_dump_dbg(reader, D_DEVICE, data, count, "Receiving:");
520 return OK;
523 int32_t IO_Serial_Receive(struct s_reader *reader, unsigned char *buffer, uint32_t size, uint32_t delay, uint32_t timeout)
525 return IO_Serial_Read(reader, delay, timeout, size, buffer);
528 bool IO_Serial_Write(struct s_reader *reader, uint32_t delay, uint32_t timeout, uint32_t size, const unsigned char *data)
530 const struct s_cardreader *crdr_ops = reader->crdr;
531 if (!crdr_ops) return ERROR;
533 if(timeout == 0) // General fix for readers not communicating timeout and delay
535 if(reader->char_delay != 0) { timeout = reader->char_delay; }
536 else { timeout = 1000000; }
537 rdr_log_dbg(reader, D_DEVICE, "Warning: write timeout 0 changed to %d us", timeout);
539 uint32_t count, to_send, i_w;
540 unsigned char data_w[MAX_ECM_SIZE];
542 to_send = (delay ? 1 : size); // calculate chars to send at one
543 rdr_log_dbg(reader, D_DEVICE, "Write timeout %d us, write delay %d us, to send %d char(s), chunksize %d char(s)", timeout, delay, size, to_send);
545 for(count = 0; count < size; count += to_send)
547 if(count + to_send > size)
549 to_send = size - count;
551 uint16_t errorcount = 0, to_do = to_send;
552 for(i_w = 0; i_w < to_send; i_w++)
553 { data_w [i_w] = data [count + i_w]; }
554 rdr_log_dump_dbg(reader, D_DEVICE, data_w + (to_send - to_do), to_do, "Sending:");
555 AGAIN:
556 if(!IO_Serial_WaitToWrite(reader, delay, timeout))
558 while(to_do != 0)
560 int32_t u = write(reader->handle, data_w + (to_send - to_do), to_do);
561 if(u < 1)
563 if(errno == EINTR) { continue; } //try again in case of Interrupted system call
564 if(errno == EAGAIN) { goto AGAIN; } //EAGAIN needs a select procedure again
565 errorcount++;
566 int16_t written = count + to_send - to_do;
567 if(u != 0)
569 rdr_log(reader, "ERROR: %s: Written=%d of %d (errno=%d %s)",
570 __func__, written , size, errno, strerror(errno));
572 if(errorcount > 10) //exit if more than 10 errors
574 return ERROR;
577 else
579 to_do -= u;
580 errorcount = 0;
581 if(crdr_ops->read_written)
582 { reader->written += u; } // these readers echo transmitted chars
586 else
588 rdr_log(reader, "Timeout in IO_Serial_WaitToWrite, delay=%d us, timeout=%d us", delay, timeout);
589 if(crdr_ops->read_written && reader->written > 0) // these readers need to read all transmitted chars before they can receive!
591 unsigned char buf[256];
592 rdr_log_dbg(reader, D_DEVICE, "Reading %d echoed transmitted chars...", reader->written);
593 int32_t n = reader->written;
594 if(IO_Serial_Read(reader, 0, 9990000, n, buf)) // use 9990000 = aprox 10 seconds (since written chars could be hughe!)
595 { return ERROR; }
596 reader->written = 0;
597 rdr_log_dbg(reader, D_DEVICE, "Reading of echoed transmitted chars done!");
599 return ERROR;
602 if(crdr_ops->read_written && reader->written > 0) // these readers need to read all transmitted chars before they can receive!
604 unsigned char buf[256];
605 rdr_log_dbg(reader, D_DEVICE, "Reading %d echoed transmitted chars...", reader->written);
606 int32_t n = reader->written;
607 if(IO_Serial_Read(reader, 0, 9990000, n, buf)) // use 9990000 = aprox 10 seconds (since written chars could be hughe!)
608 { return ERROR; }
609 reader->written = 0;
610 rdr_log_dbg(reader, D_DEVICE, "Reading of echoed transmitted chars done!");
612 return OK;
615 #define MAX_TRANSMIT 255
617 int32_t IO_Serial_Transmit(struct s_reader *reader, unsigned char *buffer, uint32_t size, uint32_t UNUSED(expectedlen), uint32_t delay, uint32_t timeout)
619 uint32_t sent, to_send;
620 for(sent = 0; sent < size; sent = sent + to_send)
622 to_send = MIN(size, MAX_TRANSMIT);
623 if(IO_Serial_Write(reader, delay, timeout , to_send, buffer + sent))
624 { return ERROR; }
626 return OK;
629 int32_t IO_Serial_Close(struct s_reader *reader)
632 rdr_log_dbg(reader, D_DEVICE, "Closing serial port %s", reader->device);
633 cs_sleepms(100); // maybe a dirty fix for the restart problem posted by wonderdoc
634 if(reader->fdmc >= 0) { close(reader->fdmc); }
635 if(reader->handle >= 0 && close(reader->handle) != 0)
636 { return ERROR; }
638 reader->written = 0;
640 return OK;
644 * Internal functions definition
647 static int32_t IO_Serial_Bitrate(int32_t bitrate)
649 static const struct BaudRates
651 int32_t real;
652 speed_t apival;
653 } BaudRateTab[] =
655 #ifdef B230400
656 { 230400, B230400 },
657 #endif
658 #ifdef B115200
659 { 115200, B115200 },
660 #endif
661 #ifdef B76800
662 { 76800, B76800 },
663 #endif
664 #ifdef B57600
665 { 57600, B57600 },
666 #endif
667 #ifdef B38400
668 { 38400, B38400 },
669 #endif
670 #ifdef B28800
671 { 28800, B28800 },
672 #endif
673 #ifdef B19200
674 { 19200, B19200 },
675 #endif
676 #ifdef B14400
677 { 14400, B14400 },
678 #endif
679 #ifdef B9600
680 { 9600, B9600 },
681 #endif
682 #ifdef B7200
683 { 7200, B7200 },
684 #endif
685 #ifdef B4800
686 { 4800, B4800 },
687 #endif
688 #ifdef B2400
689 { 2400, B2400 },
690 #endif
691 #ifdef B1200
692 { 1200, B1200 },
693 #endif
694 #ifdef B600
695 { 600, B600 },
696 #endif
697 #ifdef B300
698 { 300, B300 },
699 #endif
700 #ifdef B200
701 { 200, B200 },
702 #endif
703 #ifdef B150
704 { 150, B150 },
705 #endif
706 #ifdef B134
707 { 134, B134 },
708 #endif
709 #ifdef B110
710 { 110, B110 },
711 #endif
712 #ifdef B75
713 { 75, B75 },
714 #endif
715 #ifdef B50
716 { 50, B50 },
717 #endif
720 int32_t i;
722 for(i = 0; i < (int)(sizeof(BaudRateTab) / sizeof(struct BaudRates)); i++)
724 int32_t b = BaudRateTab[i].real;
725 int32_t d = ((b - bitrate) * 10000) / b;
726 if(abs(d) <= 350)
728 return BaudRateTab[i].apival;
731 return B0;
734 bool IO_Serial_WaitToRead(struct s_reader *reader, uint32_t delay_us, uint32_t timeout_us)
736 struct pollfd ufds;
737 struct timeb start, end;
738 int32_t ret_val;
739 int32_t in_fd;
740 int64_t polltimeout = timeout_us / 1000;
742 if(delay_us > 0)
743 { cs_sleepus(delay_us); } // wait in us
744 in_fd = reader->handle;
746 ufds.fd = in_fd;
747 ufds.events = POLLIN | POLLPRI;
748 ufds.revents = 0x0000;
749 cs_ftime(&start); // register start time
750 while(1)
752 ret_val = poll(&ufds, 1, polltimeout);
753 cs_ftime(&end); // register end time
754 switch(ret_val)
756 case -1:
757 if(errno == EINTR || errno == EAGAIN)
759 cs_sleepus(1);
760 if(timeout_us > 0)
762 polltimeout = (timeout_us / 1000) - comp_timeb(&end, &start);
763 if(polltimeout < 0) { polltimeout = 0; }
765 continue;
767 rdr_log(reader, "ERROR: %s: timeout=%"PRId64" ms (errno=%d %s)", __func__, comp_timeb(&end, &start), errno, strerror(errno));
768 return ERROR;
769 default:
770 if(ufds.revents & (POLLIN | POLLPRI))
771 { return OK; }
772 else
773 { return ERROR; }
778 static bool IO_Serial_WaitToWrite(struct s_reader *reader, uint32_t delay_us, uint32_t timeout_us)
780 struct pollfd ufds;
781 struct timeb start, end;
782 int32_t ret_val;
783 int32_t out_fd;
784 int64_t polltimeout = timeout_us / 1000;
786 #if !defined(WITH_COOLAPI) && !defined(WITH_COOLAPI2)
787 if(reader->typ == R_INTERNAL) { return OK; } // needed for internal readers, otherwise error!
788 #endif
789 if(delay_us > 0)
790 { cs_sleepus(delay_us); } // wait in us
791 out_fd = reader->handle;
793 ufds.fd = out_fd;
794 ufds.events = POLLOUT;
795 ufds.revents = 0x0000;
796 cs_ftime(&start); // register start time
797 while(1)
799 ret_val = poll(&ufds, 1, polltimeout);
800 cs_ftime(&end); // register end time
801 switch(ret_val)
803 case 0:
804 rdr_log(reader, "ERROR: not ready to write, timeout=%"PRId64" ms", comp_timeb(&end, &start));
805 return ERROR;
806 case -1:
807 if(errno == EINTR || errno == EAGAIN)
809 cs_sleepus(1);
810 if(timeout_us > 0)
812 polltimeout = (timeout_us / 1000) - comp_timeb(&end, &start);
813 if(polltimeout < 0) { polltimeout = 0; }
815 continue;
817 rdr_log(reader, "ERROR: %s: timeout=%"PRId64" ms (errno=%d %s)", __func__, comp_timeb(&end, &start), errno, strerror(errno));
818 return ERROR;
819 default:
820 if(((ufds.revents) & POLLOUT) == POLLOUT)
821 { return OK; }
822 else
823 { return ERROR; }
828 bool IO_Serial_InitPnP(struct s_reader *reader)
830 uint32_t PnP_id_size = 0;
831 unsigned char PnP_id[IO_SERIAL_PNPID_SIZE]; /* PnP Id of the serial device */
832 int32_t dtr = IO_SERIAL_HIGH;
833 int32_t cts = IO_SERIAL_LOW;
835 if(IO_Serial_SetParams(reader, 1200, 7, PARITY_NONE, 1, &dtr, &cts))
836 { return ERROR; }
838 while((PnP_id_size < IO_SERIAL_PNPID_SIZE) && !IO_Serial_Read(reader, 0, 200000, 1, &(PnP_id[PnP_id_size])))
839 { PnP_id_size++; }
841 return OK;
844 int32_t IO_Serial_GetStatus(struct s_reader *reader, int32_t *status)
846 uint32_t modembits = 0;
847 if(ioctl(reader->handle, TIOCMGET, &modembits) == -1)
849 rdr_log(reader, "ERROR: %s: ioctl(TIOCMGET): %s", __func__, strerror(errno));
850 return ERROR;
852 *status = 0;
853 switch(reader->detect & 0x7f)
855 case 0:
856 *status = modembits & TIOCM_CAR;
857 break;
858 case 1:
859 *status = modembits & TIOCM_DSR;
860 break;
861 case 2:
862 *status = modembits & TIOCM_CTS;
863 break;
864 case 3:
865 *status = modembits & TIOCM_RNG;
866 break;
868 if(!(reader->detect & 0x80))
869 { *status = !*status; }
870 return OK;
873 int32_t IO_Serial_SetBaudrate(struct s_reader *reader, uint32_t baudrate)
875 rdr_log_dbg(reader, D_IFD, "Setting baudrate to %u", baudrate);
876 // Get current settings
877 struct termios tio;
878 call(tcgetattr(reader->handle, &tio) != 0);
879 // Set new baudrate
880 call(IO_Serial_SetBitrate(reader, baudrate, &tio));
881 call(IO_Serial_SetProperties(reader, tio));
882 reader->current_baudrate = baudrate; //so if update fails, reader->current_baudrate is not changed either
883 return OK;
886 #endif