11#if !defined(_WIN32) || defined(__GNUC__) && !defined(__MINGW32__)
16#include <sys/termios.h>
21#if defined(_WIN32) && !defined(_WIN32_WCE)
23#if defined(__GNUC__) && !defined(__MINGW32__)
24#include <netinet/in.h>
25#include <sys/socket.h>
35#define time_add(t1, t2, tr) \
37 (tr).tv_sec = (t1).tv_sec + (t2).tv_sec; \
38 (tr).tv_usec = (t1).tv_usec + (t2).tv_usec; \
39 while ((tr).tv_usec >= 1000000L) { \
41 (tr).tv_usec -= 1000000L; \
44#define time_greater(t1, t2) \
45 ((t1.tv_sec > t2.tv_sec) || \
46 ((t1.tv_sec == t2.tv_sec) && (t1.tv_usec > t2.tv_usec)))
48#if defined(_WIN32) && !defined(__CYGWIN__)
50static HANDLE commConnections[maxCom];
51static int curCom = -1;
58 printf(
"vrpn_open_commport(): Entering\n");
60#if defined(hpux) || defined(__hpux) || defined(ultrix) || defined(FreeBSD) || \
64 "vrpn_open_commport(): Not yet implemented in this operating system\n");
75 struct termios sttyArgs;
79 if (curCom + 1 >= maxCom) {
80 fprintf(stderr,
"VRPN: To many communication connections open, edit "
81 "vrpn_Serial.C and recompile\n");
85 hCom = CreateFile(portname, GENERIC_READ | GENERIC_WRITE,
92 if (hCom == INVALID_HANDLE_VALUE) {
93 perror(
"vrpn_open_commport: cannot open serial port");
94 fprintf(stderr,
" (Make sure port name is valid and it has not been "
95 "opened by another program. Note that on Windows "
96 "COM ports with numbers larger than 9 must be opened "
97 "using names like \\\\.\\COM10 rather than COM10)\n");
101 if ((fSuccess = GetCommState(hCom, &dcb)) == 0) {
102 perror(
"vrpn_open_commport: cannot get serial port configuration "
109 dcb.fDtrControl = DTR_CONTROL_ENABLE;
114 dcb.BaudRate = CBR_300;
117 dcb.BaudRate = CBR_1200;
120 dcb.BaudRate = CBR_2400;
123 dcb.BaudRate = CBR_4800;
126 dcb.BaudRate = CBR_9600;
129 dcb.BaudRate = CBR_19200;
132 dcb.BaudRate = CBR_38400;
135 dcb.BaudRate = CBR_57600;
138 dcb.BaudRate = CBR_115200;
141 fprintf(stderr,
"vrpn_open_commport: unknown baud rate %ld\n", baud);
149 dcb.Parity = NOPARITY;
168 fprintf(stderr,
"vrpn_open_commport: unknown parity setting\n");
173 dcb.StopBits = ONESTOPBIT;
176 else if (charsize == 7)
180 "vrpn_open_commport: unknown character size (charsize = %d)\n",
188 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
191 if ((fSuccess = SetCommState(hCom, &dcb)) == 0) {
192 perror(
"vrpn_open_commport: cannot set serial port configuration "
198 cto.ReadIntervalTimeout = MAXDWORD;
199 cto.ReadTotalTimeoutMultiplier = MAXDWORD;
200 cto.ReadTotalTimeoutConstant = 1;
201 cto.WriteTotalTimeoutConstant = 0;
202 cto.WriteTotalTimeoutMultiplier = 0;
204 if ((fSuccess = SetCommTimeouts(hCom, &cto)) == 0) {
205 perror(
"vrpn_open_commport: cannot set serial port timeouts");
211 commConnections[curCom] = hCom;
220#if defined(sol) || defined(__APPLE__) || defined(linux)
221 if ((fileDescriptor = open(portname, O_RDWR | O_NDELAY | O_NOCTTY)) == -1) {
223 if ((fileDescriptor = open(portname, O_RDWR)) == -1) {
225 perror(
"vrpn_open_commport: cannot open serial port");
230 printf(
"vrpn_open_commport(): Getting settings\n");
233 if (tcgetattr(fileDescriptor, &sttyArgs) == -1) {
234 perror(
"vrpn_open_commport: tcgetattr failed");
273 fprintf(stderr,
"vrpn_open_commport: unknown baud rate %ld\n", baud);
276 cfsetispeed(&sttyArgs, speed);
277 cfsetospeed(&sttyArgs, speed);
279 sttyArgs.c_iflag = (IGNBRK | IGNPAR);
280 sttyArgs.c_oflag = 0;
281 sttyArgs.c_lflag = 0;
283 sttyArgs.c_cflag &= ~CSIZE;
285 sttyArgs.c_cflag |= CSIZE & CS8;
286 else if (charsize == 7)
287 sttyArgs.c_cflag |= CSIZE & CS7;
290 "vrpn_open_commport: unknown character size (charsize = %d)\n",
294 sttyArgs.c_cflag &= ~CSTOPB;
298 sttyArgs.c_cflag &= ~PARENB;
301 sttyArgs.c_cflag |= PARENB | PARODD;
304 sttyArgs.c_cflag |= PARENB;
305 sttyArgs.c_cflag &= ~PARODD;
310 fprintf(stderr,
"vrpn_open_commport: unsupported parity setting (only "
311 "none, odd and even)\n");
312 close(fileDescriptor);
316 sttyArgs.c_cflag |= CREAD;
317 sttyArgs.c_cflag |= CLOCAL;
319 sttyArgs.c_cc[VMIN] = 0;
320 sttyArgs.c_cc[VTIME] = 0;
324 sttyArgs.c_cflag |= CRTSCTS;
328 printf(
"vrpn_open_commport(): Setting settings\n");
331 if (tcsetattr(fileDescriptor, TCSANOW, &sttyArgs) == -1) {
332 perror(
"vrpn_open_commport: tcsetattr failed");
333 close(fileDescriptor);
338 printf(
"vrpn_open_commport(): Exiting\n");
340 return (fileDescriptor);
351 printf(
"vrpn_close_commport(): Entering\n");
353#if defined(_WIN32) && !defined(__CYGWIN__)
354 int ret = CloseHandle(commConnections[comm]);
356 for (
int i = comm; i < curCom - 1; i++)
357 commConnections[i] = commConnections[i + 1];
359 commConnections[curCom--] = NULL;
371 printf(
"vrpn_set_rts(): Entering\n");
378 return EscapeCommFunction(commConnections[comm], SETRTS) != 0;
387 if (ioctl(comm, TIOCMGET, &flags) == -1) {
388 perror(
"vrpn_set_rts: Failed to get modem status bits");
392 if (ioctl(comm, TIOCMSET, &flags) == -1) {
393 perror(
"vrpn_set_rts: Failed to set modem status bits");
405 printf(
"vrpn_clear_rts(): Entering\n");
412 return EscapeCommFunction(commConnections[comm], CLRRTS) != 0;
421 if (ioctl(comm, TIOCMGET, &flags) == -1) {
422 perror(
"vrpn_set_rts: Failed to get modem status bits");
426 if (ioctl(comm, TIOCMSET, &flags) == -1) {
427 perror(
"vrpn_set_rts: Failed to set modem status bits");
441 printf(
"vrpn_flush_input_buffer(): Entering\n");
443#if defined(hpux) || defined(__hpux) || defined(ultrix) || defined(__CYGWIN__)
446 "vrpn_flush_input_buffer: Not impemented on cygwin, ultrix, or HP\n");
450 if (PurgeComm(commConnections[comm], PURGE_RXCLEAR) != 0) {
457 return tcflush(comm, TCIFLUSH);
468 printf(
"vrpn_flush_output_buffer(): Entering\n");
470#if defined(hpux) || defined(__hpux) || defined(ultrix) || defined(__CYGWIN__)
471 fprintf(stderr,
"vrpn_flush_output_buffer: Not impemented on NT, ultrix, "
477 return PurgeComm(commConnections[comm], PURGE_TXCLEAR);
479 return tcflush(comm, TCOFLUSH);
491 printf(
"vrpn_drain_output_buffer(): Entering\n");
493#if defined(hpux) || defined(__hpux) || defined(ultrix) || \
494 defined(__CYGWIN__) || defined(__ANDROID__)
496 fprintf(stderr,
"vrpn_drain_output_buffer: Not impemented on NT, ultrix, "
502 return FlushFileBuffers(commConnections[comm]) == 0;
504 return tcdrain(comm);
519 printf(
"vrpn_read_available_characters(): Entering\n");
521#if defined(_WIN32) && !defined(__CYGWIN__)
523 if ((comm < 0) | (comm >= maxCom)) {
524 fprintf(stderr,
"vrpn_read_available_characters: Invalid comm: %d\n", comm);
531 OVERLAPPED Overlapped;
533 Overlapped.Offset = 0;
534 Overlapped.OffsetHigh = 0;
535 Overlapped.hEvent = NULL;
537 if ((fSuccess = ClearCommError(commConnections[comm], &errors, &cstat)) ==
539 perror(
"vrpn_read_available_characters: can't get current status");
543 if (cstat.cbInQue > 0) {
544 if ((fSuccess = ReadFile(commConnections[comm], buffer,
545 static_cast<DWORD
>(bytes), &numRead,
546 &Overlapped)) == 0) {
548 "vrpn_read_available_characters: can't read from serial port");
565 int cReadThisTime = 0;
566 int cSpaceLeft = bytes;
567 unsigned char *pch = buffer;
570 if ((cReadThisTime = read(comm, (
char *)pch, cSpaceLeft)) == -1) {
573 if (errno == EINTR) {
577 perror(
"vrpn_read_available_characters: cannot read from "
579 fprintf(stderr,
"buffer = %p, %d\n", pch,
580 static_cast<int>(bytes));
584 cSpaceLeft -= cReadThisTime;
585 pch += cReadThisTime;
586 }
while ((cReadThisTime != 0) && (cSpaceLeft > 0));
587 bRead = pch - buffer;
590 printf(
"vrpn_read_available_characters(): Exiting\n");
601 size_t bytes,
struct timeval *timeout)
604 printf(
"vrpn_read_available_characters(timeout): Entering\n");
606 struct timeval start, finish, now;
608 unsigned char *where = buffer;
612 if (timeout == NULL) {
616 memcpy(&finish, &now,
sizeof(finish));
621 memcpy(&now, &start,
sizeof(now));
634 if (
static_cast<size_t>(sofar) == bytes) {
638 if (timeout != NULL) {
644 printf(
"vrpn_read_available_characters(timeout): Exiting\n");
654 printf(
"vrpn_write_characters(): Entering\n");
656#if defined(_WIN32) && !defined(__CYGWIN__)
659 OVERLAPPED Overlapped;
661 Overlapped.Offset = 0;
662 Overlapped.OffsetHigh = 0;
663 Overlapped.hEvent = NULL;
666 WriteFile(commConnections[comm], buffer,
static_cast<DWORD
>(bytes),
667 &numWritten, &Overlapped)) == 0) {
668 perror(
"vrpn_write_characters: can't write to serial port");
674 return write(comm, buffer, bytes);
683 for (i = 0; i < bytes; i++) {
689 return static_cast<int>(bytes);
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
#define time_greater(t1, t2)
int vrpn_set_rts(int comm)
int vrpn_write_slowly(int comm, const unsigned char *buffer, size_t bytes, int millisec_delay)
int vrpn_close_commport(int comm)
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
int vrpn_drain_output_buffer(int comm)
Wait until all of the characters in the output buffer are sent, then return.
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
#define time_add(t1, t2, tr)
int vrpn_flush_output_buffer(int comm)
Throw out any characters (do not send) within the output buffer.
int vrpn_clear_rts(int comm)
int vrpn_open_commport(const char *portname, long baud, int charsize, vrpn_SER_PARITY parity, bool rts_flow)
Open a serial port, given its name and baud rate.
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
void vrpn_SleepMsecs(double dMilliSecs)
#define vrpn_gettimeofday