diff options
Diffstat (limited to 'RetoolingForOpenSprints/serproxy-0.1.3.src/sio.c')
| -rw-r--r-- | RetoolingForOpenSprints/serproxy-0.1.3.src/sio.c | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/RetoolingForOpenSprints/serproxy-0.1.3.src/sio.c b/RetoolingForOpenSprints/serproxy-0.1.3.src/sio.c new file mode 100644 index 0000000..b14c784 --- /dev/null +++ b/RetoolingForOpenSprints/serproxy-0.1.3.src/sio.c @@ -0,0 +1,383 @@ +/* + * sio.c + * + * serial port routines + * + * (C)1999 Stefano Busti + * + */ + +#include <stdio.h> +#include <string.h> + +#include "sio.h" +#include "string.h" + +#if defined(SIO_TTY) +# include <unistd.h> +# include <termios.h> +#elif defined(SIO_WIN32) +# include <io.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +void serialinfo_init(serialinfo_s *sinfo) +{ + sinfo->device = NULL; + sinfo->port = 1; + sinfo->baud = 9600; + sinfo->parity = SIO_PARITY_NONE; + sinfo->stopbits = 1; + sinfo->databits = 8; +} + +void serialinfo_assign(serialinfo_s *dst, serialinfo_s *src) +{ + dst->port = src->port; + dst->baud = src->baud; + dst->parity = src->parity; + dst->stopbits = src->stopbits; + dst->databits = src->databits; + str_assign(&dst->device, src->device); +} + +void serialinfo_cleanup(serialinfo_s *sinfo) +{ + str_cleanup(&sinfo->device); +} + +int sio_init(sio_s *sio) +{ + sio->fd = 0; + + serialinfo_init(&sio->info); + + return 0; +} + +void sio_cleanup(sio_s *sio) +{ + if (sio_isopen(sio)) + sio_close(sio); + + serialinfo_cleanup(&sio->info); +} + +void sio_assign(sio_s *dst, sio_s *src) +{ + dst->fd = src->fd; +#ifdef SIO_WIN32 + dst->hComm = src->hComm; +#endif + serialinfo_assign(&dst->info, &src->info); +} + +int sio_open(sio_s *sio) +{ + char filename[20]; + +#if defined(SIO_TTY) + struct termios t; + int fd, c_stop, c_data, i_parity, c_parity; + speed_t speed; + + if (sio_isopen(sio)) + return -1; + + if (sio->info.device && strlen(sio->info.device) > 0) + { + fd = open(sio->info.device, O_RDWR); + } + else + { + sprintf(filename, "/dev/ttyS%hd", sio->info.port - 1); + fd = open(filename, O_RDWR); + } + + if (fd == -1) + return -1; + + if (tcgetattr(fd, &t)) + { + close(fd); + return -1; + } + + switch(sio->info.baud) + { + case 0: speed = B0; break; + case 50: speed = B50; break; + case 75: speed = B75; break; + case 110: speed = B110; break; + case 134: speed = B134; break; + case 150: speed = B150; break; + case 300: speed = B300; break; + case 600: speed = B600; break; + case 1200: speed = B1200; break; + case 1800: speed = B1800; break; + case 2400: speed = B2400; break; + case 4800: speed = B4800; break; + case 9600: speed = B9600; break; + case 19200: speed = B19200; break; + case 38400: speed = B38400; break; + case 57600: speed = B57600; break; + case 115200: speed = B115200; break; + case 230400: speed = B230400; break; + default: speed = B0; break; + } + + if (speed == B0) + { + close(fd); + return -1; + } + + if (cfsetospeed(&t, speed)) + { + close(fd); + return -1; + } + + if (cfsetispeed(&t, speed)) + { + close(fd); + return -1; + } + + switch(sio->info.stopbits) + { + case 1: c_stop = 0; break; + case 2: c_stop = CSTOPB; break; + default: close(fd); return -1; + } + + switch(sio->info.databits) + { + case 5: c_data = CS5; break; + case 6: c_data = CS6; break; + case 7: c_data = CS7; break; + case 8: c_data = CS8; break; + default: close(fd); return -1; + } + + switch(sio->info.parity) + { + case SIO_PARITY_NONE: + i_parity = IGNPAR; + c_parity = 0; + break; + + case SIO_PARITY_EVEN: + i_parity = INPCK; + c_parity = PARENB; + break; + + case SIO_PARITY_ODD: + i_parity = INPCK; + c_parity = PARENB | PARODD; + break; + + default: + close(fd); + return -1; + } + + if (tcsetattr(fd, TCSANOW, &t)) + { + close(fd); + return -1; + } + + sio->fd = fd; + + return 0; +#elif defined(SIO_WIN32) + int fd; + HANDLE hComm; + DCB dcb; + COMMTIMEOUTS cto = { MAXDWORD, 0, 0, 4, 4 }; + + if (sio_isopen(sio)) + return -1; + + if (sio->info.device && strlen(sio->info.device) > 0) + { + fd = _open(sio->info.device, _O_RDWR); + } + else + { + sprintf(filename, "COM%hd", sio->info.port); + fd = _open(filename, _O_RDWR); + } + + if (fd == -1) + return -1; + + /* Grab the fd's windows handle */ + hComm = (HANDLE)_get_osfhandle(fd); + + if (!SetCommTimeouts(hComm, &cto)) + { + _close(fd); + return -1; + } + + dcb.DCBlength = sizeof(dcb); + memset(&dcb, sizeof(dcb), 0); + + if (!GetCommState(hComm, &dcb)) + { + _close(fd); + return -1; + } + + dcb.BaudRate = sio->info.baud; + //dcb.fBinary = TRUE; + dcb.fParity = (sio->info.parity == SIO_PARITY_NONE) ? FALSE : TRUE; + dcb.fOutxCtsFlow = FALSE; + dcb.fOutxDsrFlow = FALSE; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + dcb.fDsrSensitivity = FALSE; + dcb.fTXContinueOnXoff = FALSE; + dcb.fOutX = FALSE; + dcb.fInX = FALSE; + dcb.fErrorChar = FALSE; + dcb.fNull = FALSE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.fAbortOnError = FALSE; + dcb.ByteSize = sio->info.databits; + + switch (sio->info.parity) + { + case SIO_PARITY_NONE: dcb.Parity = 0; break; + case SIO_PARITY_ODD: dcb.Parity = 1; break; + case SIO_PARITY_EVEN: dcb.Parity = 2; break; + default: _close(fd); return -1; + } + + switch (sio->info.stopbits) + { + case 1: dcb.StopBits = 0; break; + case 2: dcb.StopBits = 2; break; + default: _close(fd); return -1; + } + + if (!SetCommState(hComm, &dcb)) + { + _close(fd); + return -1; + } + + sio->fd = fd; + sio->hComm = hComm; + + return 0; +#endif +} + +void sio_close(sio_s *sio) +{ +#if defined(SIO_TTY) + close(sio->fd); + sio->fd = 0; +#elif defined(SIO_WIN32) + _close(sio->fd); + sio->fd = 0; + sio->hComm = INVALID_HANDLE_VALUE; +#endif +} + +#ifdef SIO_TTY +__inline +#endif +int sio_read(sio_s *sio, void *buf, size_t count) +{ +#if defined(SIO_TTY) + return read(sio->fd, buf, count); +#elif defined(SIO_WIN32) + int res; + if (!ReadFile(sio->hComm, buf, count, &res, NULL)) + return -1; + return res; +#endif +} + +#ifdef SIO_TTY +__inline +#endif +int sio_write(sio_s *sio, void *buf, size_t count) +{ +#if defined(SIO_TTY) + return write(sio->fd, buf, count); +#elif defined(SIO_WIN32) + int res; + if (!WriteFile(sio->hComm, buf, count, &res, NULL)) + return -1; + return res; +#endif +} + +int sio_isopen(sio_s *sio) +{ + return (sio->fd != 0); +} + +int sio_setinfo(sio_s *sio, serialinfo_s *info) +{ + serialinfo_assign(&sio->info, info); + return 0; +} + +void sio_flush(sio_s *sio, int dir) +{ + if (sio_isopen(sio)) + { +#if defined(SIO_TTY) + switch(dir) + { + case SIO_IN: tcflush(sio->fd, TCIFLUSH); break; + case SIO_OUT: tcflush(sio->fd, TCOFLUSH); break; + case SIO_IN | SIO_OUT: tcflush(sio->fd, TCIOFLUSH); break; + } +#elif defined(SIO_WIN32) + DWORD flags = 0; + + if (sio_isopen(sio)) + { + if (dir & SIO_IN) + flags |= PURGE_RXCLEAR | PURGE_RXABORT; + if (dir & SIO_OUT) + flags |= PURGE_TXCLEAR | PURGE_TXABORT; + } + + PurgeComm(sio->hComm, flags); +#endif + } +} + +void sio_drain(sio_s *sio) +{ + if (sio_isopen(sio)) + { +#if defined(SIO_TTY) + tcdrain(sio->fd); +#elif defined(SIO_WIN32) + FlushFileBuffers(sio->hComm); +#endif + } +} + +void sio_debug(sio_s *sio, FILE *f) +{ + fprintf(f, "sio {\n"); + fprintf(f, "\tfd = %d\n", sio_isopen(sio) ? sio->fd : 0); + fprintf(f, "\tport = %d\n", sio->info.port); + fprintf(f, "\tbaud = %ld\n", sio->info.baud); + fprintf(f, "\tparity = %d\n", sio->info.parity); + fprintf(f, "\tstopbits = %d\n", sio->info.stopbits); + fprintf(f, "\tdatabits = %d\n", sio->info.databits); + fprintf(f, "\topen = %d\n", sio_isopen(sio)); + fprintf(f, "}\n\n"); +} |
