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__)
49 const int maxCom = 50;
50 static HANDLE commConnections[maxCom];
51 static 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)\n");
99 if ((fSuccess = GetCommState(hCom, &dcb)) == 0) {
100 perror(
"vrpn_open_commport: cannot get serial port configuration "
107 dcb.fDtrControl = DTR_CONTROL_ENABLE;
112 dcb.BaudRate = CBR_300;
115 dcb.BaudRate = CBR_1200;
118 dcb.BaudRate = CBR_2400;
121 dcb.BaudRate = CBR_4800;
124 dcb.BaudRate = CBR_9600;
127 dcb.BaudRate = CBR_19200;
130 dcb.BaudRate = CBR_38400;
133 dcb.BaudRate = CBR_57600;
136 dcb.BaudRate = CBR_115200;
139 fprintf(stderr,
"vrpn_open_commport: unknown baud rate %ld\n", baud);
147 dcb.Parity = NOPARITY;
166 fprintf(stderr,
"vrpn_open_commport: unknown parity setting\n");
171 dcb.StopBits = ONESTOPBIT;
174 else if (charsize == 7)
178 "vrpn_open_commport: unknown character size (charsize = %d)\n",
186 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
189 if ((fSuccess = SetCommState(hCom, &dcb)) == 0) {
190 perror(
"vrpn_open_commport: cannot set serial port configuration "
196 cto.ReadIntervalTimeout = MAXDWORD;
197 cto.ReadTotalTimeoutMultiplier = MAXDWORD;
198 cto.ReadTotalTimeoutConstant = 1;
199 cto.WriteTotalTimeoutConstant = 0;
200 cto.WriteTotalTimeoutMultiplier = 0;
202 if ((fSuccess = SetCommTimeouts(hCom, &cto)) == 0) {
203 perror(
"vrpn_open_commport: cannot set serial port timeouts");
209 commConnections[curCom] = hCom;
218 #if defined(sol) || defined(__APPLE__) || defined(linux)
219 if ((fileDescriptor = open(portname, O_RDWR | O_NDELAY | O_NOCTTY)) == -1) {
221 if ((fileDescriptor = open(portname, O_RDWR)) == -1) {
223 perror(
"vrpn_open_commport: cannot open serial port");
228 printf(
"vrpn_open_commport(): Getting settings\n");
231 if (tcgetattr(fileDescriptor, &sttyArgs) == -1) {
232 perror(
"vrpn_open_commport: tcgetattr failed");
269 #endif // End B115200
271 fprintf(stderr,
"vrpn_open_commport: unknown baud rate %ld\n", baud);
274 cfsetispeed(&sttyArgs, speed);
275 cfsetospeed(&sttyArgs, speed);
277 sttyArgs.c_iflag = (IGNBRK | IGNPAR);
278 sttyArgs.c_oflag = 0;
279 sttyArgs.c_lflag = 0;
281 sttyArgs.c_cflag &= ~CSIZE;
283 sttyArgs.c_cflag |= CSIZE & CS8;
284 else if (charsize == 7)
285 sttyArgs.c_cflag |= CSIZE & CS7;
288 "vrpn_open_commport: unknown character size (charsize = %d)\n",
292 sttyArgs.c_cflag &= ~CSTOPB;
296 sttyArgs.c_cflag &= ~PARENB;
299 sttyArgs.c_cflag |= PARENB | PARODD;
302 sttyArgs.c_cflag |= PARENB;
303 sttyArgs.c_cflag &= ~PARODD;
308 fprintf(stderr,
"vrpn_open_commport: unsupported parity setting (only "
309 "none, odd and even)\n");
313 sttyArgs.c_cflag |= CREAD;
314 sttyArgs.c_cflag |= CLOCAL;
316 sttyArgs.c_cc[VMIN] = 0;
317 sttyArgs.c_cc[VTIME] = 0;
321 sttyArgs.c_cflag |= CRTSCTS;
325 printf(
"vrpn_open_commport(): Setting settings\n");
328 if (tcsetattr(fileDescriptor, TCSANOW, &sttyArgs) == -1) {
329 perror(
"vrpn_open_commport: tcsetattr failed");
330 close(fileDescriptor);
335 printf(
"vrpn_open_commport(): Exiting\n");
337 return (fileDescriptor);
341 #endif // !defined(...lots of stuff...)
348 printf(
"vrpn_close_commport(): Entering\n");
350 #if defined(_WIN32) && !defined(__CYGWIN__)
351 int ret = CloseHandle(commConnections[comm]);
353 for (
int i = comm; i < curCom - 1; i++)
354 commConnections[i] = commConnections[i + 1];
356 commConnections[curCom--] = NULL;
368 printf(
"vrpn_set_rts(): Entering\n");
375 return EscapeCommFunction(commConnections[comm], SETRTS) != 0;
384 if (ioctl(comm, TIOCMGET, &flags) == -1) {
385 perror(
"vrpn_set_rts: Failed to get modem status bits");
389 if (ioctl(comm, TIOCMSET, &flags) == -1) {
390 perror(
"vrpn_set_rts: Failed to set modem status bits");
402 printf(
"vrpn_clear_rts(): Entering\n");
409 return EscapeCommFunction(commConnections[comm], CLRRTS) != 0;
418 if (ioctl(comm, TIOCMGET, &flags) == -1) {
419 perror(
"vrpn_set_rts: Failed to get modem status bits");
423 if (ioctl(comm, TIOCMSET, &flags) == -1) {
424 perror(
"vrpn_set_rts: Failed to set modem status bits");
438 printf(
"vrpn_flush_input_buffer(): Entering\n");
440 #if defined(hpux) || defined(__hpux) || defined(ultrix) || defined(__CYGWIN__)
443 "vrpn_flush_input_buffer: Not impemented on cygwin, ultrix, or HP\n");
447 if (PurgeComm(commConnections[comm], PURGE_RXCLEAR) != 0) {
454 return tcflush(comm, TCIFLUSH);
465 printf(
"vrpn_flush_output_buffer(): Entering\n");
467 #if defined(hpux) || defined(__hpux) || defined(ultrix) || defined(__CYGWIN__)
468 fprintf(stderr,
"vrpn_flush_output_buffer: Not impemented on NT, ultrix, "
474 return PurgeComm(commConnections[comm], PURGE_TXCLEAR);
476 return tcflush(comm, TCOFLUSH);
488 printf(
"vrpn_drain_output_buffer(): Entering\n");
490 #if defined(hpux) || defined(__hpux) || defined(ultrix) || \
491 defined(__CYGWIN__) || defined(__ANDROID__)
493 fprintf(stderr,
"vrpn_drain_output_buffer: Not impemented on NT, ultrix, "
499 return FlushFileBuffers(commConnections[comm]) == 0;
501 return tcdrain(comm);
516 printf(
"vrpn_read_available_characters(): Entering\n");
518 #if defined(_WIN32) && !defined(__CYGWIN__)
523 OVERLAPPED Overlapped;
525 Overlapped.Offset = 0;
526 Overlapped.OffsetHigh = 0;
527 Overlapped.hEvent = NULL;
529 if ((fSuccess = ClearCommError(commConnections[comm], &errors, &cstat)) ==
531 perror(
"vrpn_read_available_characters: can't get current status");
535 if (cstat.cbInQue > 0) {
536 if ((fSuccess = ReadFile(commConnections[comm], buffer,
537 static_cast<DWORD>(bytes), &numRead,
538 &Overlapped)) == 0) {
540 "vrpn_read_available_characters: can't read from serial port");
557 int cReadThisTime = 0;
558 int cSpaceLeft = bytes;
559 unsigned char *pch = buffer;
562 if ((cReadThisTime = read(comm, (
char *)pch, cSpaceLeft)) == -1) {
565 if (errno == EINTR) {
569 perror(
"vrpn_read_available_characters: cannot read from "
571 fprintf(stderr,
"buffer = %p, %d\n", pch,
572 static_cast<int>(bytes));
576 cSpaceLeft -= cReadThisTime;
577 pch += cReadThisTime;
578 }
while ((cReadThisTime != 0) && (cSpaceLeft > 0));
579 bRead = pch - buffer;
582 printf(
"vrpn_read_available_characters(): Exiting\n");
593 size_t bytes,
struct timeval *timeout)
596 printf(
"vrpn_read_available_characters(timeout): Entering\n");
598 struct timeval start, finish, now;
600 unsigned char *where = buffer;
604 if (timeout == NULL) {
608 memcpy(&finish, &now,
sizeof(finish));
613 memcpy(&now, &start,
sizeof(now));
626 if (sofar == bytes) {
630 if (timeout != NULL) {
636 printf(
"vrpn_read_available_characters(timeout): Exiting\n");
646 printf(
"vrpn_write_characters(): Entering\n");
648 #if defined(_WIN32) && !defined(__CYGWIN__)
651 OVERLAPPED Overlapped;
653 Overlapped.Offset = 0;
654 Overlapped.OffsetHigh = 0;
655 Overlapped.hEvent = NULL;
658 WriteFile(commConnections[comm], buffer, static_cast<DWORD>(bytes),
659 &numWritten, &Overlapped)) == 0) {
660 perror(
"vrpn_write_characters: can't write to serial port");
666 return write(comm, buffer, bytes);
675 for (i = 0; i < bytes; i++) {
681 return static_cast<int>(bytes);