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
29 #include <sys/modem.h>
34 #if defined(__linux__) && !defined(__ANDROID__)
35 #include <linux/serial.h>
38 #if defined(__ANDROID__)
39 #include "../extapi/linux/serial.h"
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>
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; }
70 else while(oscam_sem
!= reader
->typ
)
73 if(reader
->typ
== R_DB2COM1
)
77 oscam_sem
= reader
->typ
;
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
); }
96 #if defined(TIOCMBIS) && defined(TIOBMBIC)
97 if(ioctl(reader
->handle
, *dtr
? TIOCMBIS
: TIOCMBIC
, &mbit
) < 0)
100 if(ioctl(reader
->handle
, TIOCMGET
, &msr
) < 0)
106 if(ioctl(reader
->handle
, TIOCMSET
, &msr
) < 0)
109 rdr_log_dbg(reader
, D_DEVICE
, "Setting %s=%i", "DTR", *dtr
);
115 #if defined(TIOCMBIS) && defined(TIOBMBIC)
116 if(ioctl(reader
->handle
, *rts
? TIOCMBIS
: TIOCMBIC
, &mbit
) < 0)
119 if(ioctl(reader
->handle
, TIOCMGET
, &msr
) < 0)
125 if(ioctl(reader
->handle
, TIOCMSET
, &msr
) < 0)
128 rdr_log_dbg(reader
, D_DEVICE
, "Setting %s=%i", "RTS", *rts
);
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
);
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
);
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
)
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
);
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)"
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
;
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));
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
);
215 rdr_log_dbg(reader
, D_DEVICE
, "custom baudrate: cardmhz=%d mhz=%d -> effective baudrate %u",
216 reader
->cardmhz
, reader
->mhz
, bitrate
);
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
);
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
)
238 memset(&newtio
, 0, sizeof(newtio
));
240 if(IO_Serial_SetBitrate(reader
, bitrate
, & newtio
))
243 /* Set the character size */
247 newtio
.c_cflag
|= CS5
;
251 newtio
.c_cflag
|= CS6
;
255 newtio
.c_cflag
|= CS7
;
259 newtio
.c_cflag
|= CS8
;
267 newtio
.c_cflag
|= PARENB
;
268 newtio
.c_cflag
|= PARODD
;
272 newtio
.c_cflag
|= PARENB
;
273 newtio
.c_cflag
&= ~PARODD
;
277 newtio
.c_cflag
&= ~PARENB
;
281 /* Set the number of stop bits */
285 newtio
.c_cflag
&= (~CSTOPB
);
288 newtio
.c_cflag
|= CSTOPB
;
292 /* Selects raw (non-canonical) input and output */
293 newtio
.c_lflag
&= ~(ICANON
| ECHO
| ECHOE
| ISIG
);
294 newtio
.c_oflag
&= ~OPOST
;
296 newtio
.c_iflag
|= IGNPAR
;
297 /* Ignore parity errors!!! Windows driver does so why shouldn't I? */
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
))
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);
317 bool IO_Serial_SetProperties(struct s_reader
*reader
, struct termios newtio
)
319 if(reader
->typ
== R_INTERNAL
)
322 if(tcsetattr(reader
->handle
, TCSANOW
, &newtio
) < 0) // set terminal attributes.
326 rdr_log_dbg(reader
, D_DEVICE
, "Getting readerstatus...");
327 if(ioctl(reader
->handle
, TIOCMGET
, &mctl
) >= 0) // get reader statusbits
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!"); }
338 int32_t IO_Serial_SetParity(struct s_reader
*reader
, unsigned char parity
)
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!)
350 if(((tio
.c_cflag
) & PARENB
) == PARENB
)
352 if(((tio
.c_cflag
) & PARODD
) == PARODD
)
353 { current_parity
= PARITY_ODD
; }
355 { current_parity
= PARITY_EVEN
; }
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");
378 tio
.c_cflag
|= PARENB
;
379 tio
.c_cflag
|= PARODD
;
383 tio
.c_cflag
|= PARENB
;
384 tio
.c_cflag
&= ~PARODD
;
388 tio
.c_cflag
&= ~PARENB
;
391 if(IO_Serial_SetProperties(reader
, tio
))
393 rdr_log_dbg(reader
, D_IFD
, "ERROR: could set parity!");
401 void IO_Serial_Flush(struct s_reader
*reader
)
405 tcflush(reader
->handle
, TCIOFLUSH
);
406 struct timeb starttotal
, endtotal
;
407 struct timeb start
, end
;
408 cs_ftimeus(&starttotal
);
409 endtotal
= starttotal
;
413 while(!IO_Serial_Read(reader
, 0, 75000, 1, &b
)) // first appears between 9~75ms
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
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
)
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
)
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;
454 struct timeb start
, end
;
458 int32_t timeout_ms
= timeout
/ 1000;
461 while(gone
< timeout_ms
)
463 readed
= read(reader
->handle
, &data
[count
], size
- count
>= chunksize
? chunksize
: size
- count
);
468 cs_ftime(&start
); // Reset timer
471 gone
= comp_timeb(&end
, &start
);
474 if(readed
< (int32_t)chunksize
) { cs_sleepus(1); }
481 rdr_log_dump_dbg(reader
, D_DEVICE
, data
, count
, "Receiving:");
486 #endif // read all chars at once for all other boxes
490 int32_t readed
= -1, errorcount
= 0;
492 if(IO_Serial_WaitToRead(reader
, delay
, timeout
))
494 rdr_log_dbg(reader
, D_DEVICE
, "Timeout in IO_Serial_WaitToRead, timeout=%d us", timeout
);
498 while(readed
< 0 && errorcount
< 10)
500 readed
= read(reader
->handle
, &data
[count
], size
- count
);
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
));
512 rdr_log_dump_dbg(reader
, D_DEVICE
, data
, count
, "Receiving:");
513 rdr_log_dbg(reader
, D_DEVICE
, "Received End of transmission");
519 rdr_log_dump_dbg(reader
, D_DEVICE
, data
, count
, "Receiving:");
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:");
556 if(!IO_Serial_WaitToWrite(reader
, delay
, timeout
))
560 int32_t u
= write(reader
->handle
, data_w
+ (to_send
- to_do
), to_do
);
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
566 int16_t written
= count
+ to_send
- to_do
;
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
581 if(crdr_ops
->read_written
)
582 { reader
->written
+= u
; } // these readers echo transmitted chars
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!)
597 rdr_log_dbg(reader
, D_DEVICE
, "Reading of echoed transmitted chars done!");
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!)
610 rdr_log_dbg(reader
, D_DEVICE
, "Reading of echoed transmitted chars done!");
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
))
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)
644 * Internal functions definition
647 static int32_t IO_Serial_Bitrate(int32_t bitrate
)
649 static const struct BaudRates
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
;
728 return BaudRateTab
[i
].apival
;
734 bool IO_Serial_WaitToRead(struct s_reader
*reader
, uint32_t delay_us
, uint32_t timeout_us
)
737 struct timeb start
, end
;
740 int64_t polltimeout
= timeout_us
/ 1000;
743 { cs_sleepus(delay_us
); } // wait in us
744 in_fd
= reader
->handle
;
747 ufds
.events
= POLLIN
| POLLPRI
;
748 ufds
.revents
= 0x0000;
749 cs_ftime(&start
); // register start time
752 ret_val
= poll(&ufds
, 1, polltimeout
);
753 cs_ftime(&end
); // register end time
757 if(errno
== EINTR
|| errno
== EAGAIN
)
762 polltimeout
= (timeout_us
/ 1000) - comp_timeb(&end
, &start
);
763 if(polltimeout
< 0) { polltimeout
= 0; }
767 rdr_log(reader
, "ERROR: %s: timeout=%"PRId64
" ms (errno=%d %s)", __func__
, comp_timeb(&end
, &start
), errno
, strerror(errno
));
770 if(ufds
.revents
& (POLLIN
| POLLPRI
))
778 static bool IO_Serial_WaitToWrite(struct s_reader
*reader
, uint32_t delay_us
, uint32_t timeout_us
)
781 struct timeb start
, end
;
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!
790 { cs_sleepus(delay_us
); } // wait in us
791 out_fd
= reader
->handle
;
794 ufds
.events
= POLLOUT
;
795 ufds
.revents
= 0x0000;
796 cs_ftime(&start
); // register start time
799 ret_val
= poll(&ufds
, 1, polltimeout
);
800 cs_ftime(&end
); // register end time
804 rdr_log(reader
, "ERROR: not ready to write, timeout=%"PRId64
" ms", comp_timeb(&end
, &start
));
807 if(errno
== EINTR
|| errno
== EAGAIN
)
812 polltimeout
= (timeout_us
/ 1000) - comp_timeb(&end
, &start
);
813 if(polltimeout
< 0) { polltimeout
= 0; }
817 rdr_log(reader
, "ERROR: %s: timeout=%"PRId64
" ms (errno=%d %s)", __func__
, comp_timeb(&end
, &start
), errno
, strerror(errno
));
820 if(((ufds
.revents
) & POLLOUT
) == POLLOUT
)
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
))
838 while((PnP_id_size
< IO_SERIAL_PNPID_SIZE
) && !IO_Serial_Read(reader
, 0, 200000, 1, &(PnP_id
[PnP_id_size
])))
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
));
853 switch(reader
->detect
& 0x7f)
856 *status
= modembits
& TIOCM_CAR
;
859 *status
= modembits
& TIOCM_DSR
;
862 *status
= modembits
& TIOCM_CTS
;
865 *status
= modembits
& TIOCM_RNG
;
868 if(!(reader
->detect
& 0x80))
869 { *status
= !*status
; }
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
878 call(tcgetattr(reader
->handle
, &tio
) != 0);
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