| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817 |
- /*
- * Copyright (c) 2011 Petr Stetiar <[email protected]>, Gaben Ltd.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <termios.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/timeb.h>
- #include <sys/ioctl.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include "librs232/rs232.h"
- struct rs232_port_t *
- rs232_init(void)
- {
- struct rs232_port_t *p = NULL;
- p = (struct rs232_port_t *) malloc(sizeof(struct rs232_port_t));
- if (p == NULL)
- return NULL;
- p->pt = (struct rs232_posix_t *) malloc(sizeof(struct rs232_posix_t));
- if (p->pt == NULL)
- return NULL;
- DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
- memset(p->pt, 0, sizeof(struct rs232_posix_t));
- memset(p->dev, 0, RS232_STRLEN_DEVICE+1);
- strncpyz(p->dev, RS232_PORT_POSIX, RS232_STRLEN_DEVICE);
- p->baud = RS232_BAUD_115200;
- p->data = RS232_DATA_8;
- p->parity = RS232_PARITY_NONE;
- p->stop = RS232_STOP_1;
- p->flow = RS232_FLOW_OFF;
- p->status = RS232_PORT_CLOSED;
- p->dtr = RS232_DTR_OFF;
- p->rts = RS232_RTS_OFF;
- return p;
- }
- void
- rs232_end(struct rs232_port_t *p)
- {
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
- if (!rs232_port_open(p)) {
- free(p->pt);
- free(p);
- return;
- }
- rs232_flush(p);
- if (tcsetattr(ux->fd, TCSANOW, &ux->oldterm) < 0) {
- DBG("tcsetattr() %d %s\n", errno, strerror(errno))
- return;
- }
- rs232_close(p);
- free(p->pt);
- free(p);
- }
- unsigned int
- rs232_in_queue(struct rs232_port_t *p, unsigned int *in_bytes)
- {
- fd_set set;
- int ret;
- int b;
- struct timeval tv;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- FD_ZERO(&set);
- FD_SET(ux->fd, &set);
- /* don't work reliable with 0 */
- tv.tv_usec = 1;
- tv.tv_sec = 0;
- select(ux->fd+1, &set, NULL, NULL, &tv);
- ret = ioctl(ux->fd, FIONREAD, &b);
- if (ret == -1) {
- *in_bytes = 0;
- DBG("%s\n", "RS232_ERR_IOCTL");
- return RS232_ERR_IOCTL;
- }
- *in_bytes = b;
- DBG("in_bytes=%d\n", b);
- return RS232_ERR_NOERROR;
- }
- /* some USB<->RS232 converters buffer a lot, so this function tries to discard
- this buffer - useful mainly after rs232_open() */
- void
- rs232_in_queue_clear(struct rs232_port_t *p)
- {
- fd_set set;
- unsigned int ret;
- unsigned int blen;
- unsigned char *buf = NULL;
- struct timeval tv;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
- if (!rs232_port_open(p))
- return;
- rs232_in_queue(p, &blen);
- if (blen > 0) {
- buf = (unsigned char*) malloc(blen * sizeof(unsigned char*)+1);
- if (buf == NULL)
- return;
- FD_ZERO(&set);
- FD_SET(ux->fd, &set);
- tv.tv_usec = 1;
- tv.tv_sec = 0;
- ret = select(ux->fd+1, &set, NULL, NULL, &tv);
- DBG("select=%d\n", ret);
- if (ret <= 0) {
- free(buf);
- return;
- }
- ret = read(ux->fd, buf, blen);
- DBG("read=%d\n", ret);
- free(buf);
- }
- }
- unsigned int
- rs232_read(struct rs232_port_t *p, unsigned char *buf, unsigned int buf_len,
- unsigned int *read_len)
- {
- int r;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p buf_len=%d\n", (void *)p, p->pt, buf_len);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- r = read(ux->fd, buf, buf_len);
- if (r == -1) {
- *read_len = 0;
- DBG("errno: %d strerror: %s %s\n",
- errno, strerror(errno), "RS232_ERR_READ");
- return RS232_ERR_READ;
- }
- *read_len = r;
- DBG("read_len=%d hex='%s' ascii='%s'\n", r, rs232_hex_dump(buf, r),
- rs232_ascii_dump(buf, r));
- return RS232_ERR_NOERROR;
- }
- static int
- duration(struct timeval *t1, struct timeval *t2)
- {
- return (t2->tv_sec-t1->tv_sec)*1000 + (t2->tv_usec - t1->tv_usec)/1000;
- }
- /* this function waits either for timeout or buf_len bytes,
- whatever happens first and doesn't return earlier */
- unsigned int
- rs232_read_timeout_forced(struct rs232_port_t *p, unsigned char *buf,
- unsigned int buf_len, unsigned int *read_len,
- unsigned int timeout)
- {
- int b;
- int ret;
- int reti;
- fd_set set;
- int r;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- struct timeval tv;
- struct timeval t1;
- struct timeval t2;
- DBG("p=%p p->pt=%p buf_len=%d timeout=%d\n", (void *)p, p->pt, buf_len,
- timeout);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- FD_ZERO(&set);
- FD_SET(ux->fd, &set);
- tv.tv_sec = (timeout * 1000) / 1000000;
- tv.tv_usec = (timeout * 1000) % 1000000;
- *read_len = 0;
- gettimeofday(&t1, NULL);
- while (1) {
- ret = select(ux->fd+1, &set, NULL, NULL, &tv);
- gettimeofday(&t2, NULL);
- if (ret == 0) {
- DBG("%s\n", "select timeout");
- break;
- }
- if (ret == -1) {
- DBG("%s\n", "select error");
- break;
- }
- if (duration(&t1, &t2) >= (int) timeout) {
- DBG("%s\n", "timeout");
- break;
- }
- reti = ioctl(ux->fd, FIONREAD, &b);
- if (reti == -1) {
- DBG("%s\n", "ioctl error");
- break;
- }
- if ((unsigned int) b >= buf_len) {
- DBG("fionread=%d\n", b);
- break;
- }
- }
- switch (ret) {
- case 0:
- DBG("%s\n", "RS232_ERR_TIMEOUT");
- return RS232_ERR_TIMEOUT;
- case 1:
- r = read(ux->fd, buf, buf_len);
- if (r == -1) {
- DBG("errno: %d strerror: %s %s\n",
- errno, strerror(errno), "RS232_ERR_READ");
- return RS232_ERR_READ;
- }
- DBG("read_len=%d hex='%s' ascii='%s'\n", r,
- rs232_hex_dump(buf, r),
- rs232_ascii_dump(buf, r));
- *read_len = r;
- break;
- default:
- DBG("%s\n", "RS232_ERR_SELECT");
- return RS232_ERR_SELECT;
- }
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_read_timeout(struct rs232_port_t *p, unsigned char *buf,
- unsigned int buf_len, unsigned int *read_len,
- unsigned int timeout)
- {
- int ret;
- fd_set set;
- int r;
- struct timeval tv;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p buf_len=%d timeout=%d\n", (void *)p, p->pt,
- buf_len, timeout);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- FD_ZERO(&set);
- FD_SET(ux->fd, &set);
- tv.tv_sec = (timeout * 1000) / 1000000;
- tv.tv_usec = (timeout * 1000) % 1000000;
- *read_len = 0;
- ret = select(ux->fd+1, &set, NULL, NULL, &tv);
- switch (ret) {
- case 0:
- DBG("%s\n", "RS232_ERR_TIMEOUT");
- return RS232_ERR_TIMEOUT;
- case 1:
- r = read(ux->fd, buf, buf_len);
- if (r == -1) {
- DBG("errno: %d strerror: %s %s\n",
- errno, strerror(errno), "RS232_ERR_READ");
- return RS232_ERR_READ;
- }
- DBG("read_len=%d hex='%s' ascii='%s'\n", r,
- rs232_hex_dump(buf, r),
- rs232_ascii_dump(buf, r));
- *read_len = r;
- break;
- default:
- DBG("%s\n", "RS232_ERR_SELECT");
- return RS232_ERR_SELECT;
- }
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_write(struct rs232_port_t *p, const unsigned char *buf, unsigned int buf_len,
- unsigned int *write_len)
- {
- int w;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p hex='%s' ascii='%s' buf_len=%d\n",
- (void *)p, p->pt, rs232_hex_dump(buf, buf_len),
- rs232_ascii_dump(buf, buf_len), buf_len);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- w = write(ux->fd, buf, buf_len);
- if (w == -1) {
- DBG("errno: %d strerror: %s %s\n",
- errno, strerror(errno), "RS232_ERR_WRITE");
- *write_len = 0;
- return RS232_ERR_WRITE;
- }
- *write_len = w;
- DBG("write_len=%d hex='%s' ascii='%s'\n", w, rs232_hex_dump(buf, w),
- rs232_ascii_dump(buf, w));
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_write_timeout(struct rs232_port_t *p, const unsigned char *buf,
- unsigned int buf_len, unsigned int *write_len,
- unsigned int timeout)
- {
- int ret;
- fd_set set;
- int w;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- struct timeval tv;
- DBG("p=%p p->pt=%p timeout=%d\n", (void *)p, p->pt, timeout);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- FD_ZERO(&set);
- FD_SET(ux->fd, &set);
- tv.tv_sec = (timeout * 1000) / 1000000;
- tv.tv_usec = (timeout * 1000) % 1000000;
- *write_len = 0;
- ret = select(ux->fd+1, NULL, &set, NULL, &tv);
- switch (ret) {
- case 0:
- DBG("%s\n", "RS232_ERR_TIMEOUT");
- return RS232_ERR_TIMEOUT;
- case 1:
- w = write(ux->fd, buf, buf_len);
- if (w == -1) {
- DBG("errno: %d strerror: %s %s\n",
- errno, strerror(errno), "RS232_ERR_WRITE");
- return RS232_ERR_WRITE;
- }
- *write_len = w;
- DBG("write_len=%d hex='%s' ascii='%s'\n", w,
- rs232_hex_dump(buf, w),
- rs232_ascii_dump(buf, w));
- break;
- default:
- DBG("%s\n", "RS232_ERR_SELECT");
- return RS232_ERR_SELECT;
- }
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_open(struct rs232_port_t *p)
- {
- int flags;
- struct termios term;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
- ux->fd = open(p->dev, O_RDWR | O_NOCTTY | O_NDELAY);
- if (ux->fd < 0) {
- DBG("open() %d %s\n", errno, strerror(errno))
- return RS232_ERR_OPEN;
- }
- /*
- * On OSX (and maybe on more systems), we need to open() the port with
- * O_NDELAY, because otherwise it would block forever waiting for DCD
- * signal, so here we restore back to blocking operations.
- */
- flags = fcntl(ux->fd, F_GETFL);
- flags &= ~O_NDELAY;
- fcntl(ux->fd, F_SETFL, flags);
- if (tcflush(ux->fd, TCIOFLUSH) < 0) {
- DBG("tcflush() %d %s\n", errno, strerror(errno))
- return RS232_ERR_CONFIG;
- }
- GET_PORT_STATE(ux->fd, &term)
- GET_PORT_STATE(ux->fd, &ux->oldterm)
- term.c_cflag |= (CREAD | CLOCAL);
- term.c_iflag = IGNPAR;
- term.c_oflag = 0;
- term.c_lflag = 0;
- term.c_cc[VINTR] = _POSIX_VDISABLE;
- term.c_cc[VQUIT] = _POSIX_VDISABLE;
- term.c_cc[VSTART] = _POSIX_VDISABLE;
- term.c_cc[VSTOP] = _POSIX_VDISABLE;
- term.c_cc[VSUSP] = _POSIX_VDISABLE;
- term.c_cc[VEOF] = _POSIX_VDISABLE;
- term.c_cc[VEOL] = _POSIX_VDISABLE;
- term.c_cc[VERASE] = _POSIX_VDISABLE;
- term.c_cc[VKILL] = _POSIX_VDISABLE;
- SET_PORT_STATE(ux->fd, &term)
- rs232_set_baud(p, p->baud);
- rs232_set_data(p, p->data);
- rs232_set_parity(p, p->parity);
- rs232_set_stop(p, p->stop);
- rs232_set_flow(p, p->flow);
- p->status = RS232_PORT_OPEN;
- return RS232_ERR_NOERROR;
- }
- void
- rs232_set_device(struct rs232_port_t *p, const char *device)
- {
- DBG("p=%p old=%s new=%s\n", (void *)p, p->dev, device);
- strncpyz(p->dev, device, RS232_STRLEN_DEVICE);
- return;
- }
- unsigned int
- rs232_set_baud(struct rs232_port_t *p, enum rs232_baud_e baud)
- {
- struct termios term;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p baud=%d (%s bauds)\n",
- (void *)p, p->pt, baud, rs232_strbaud(baud));
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- GET_PORT_STATE(ux->fd, &term)
- switch (baud) {
- case RS232_BAUD_300:
- cfsetispeed(&term, B300);
- cfsetospeed(&term, B300);
- break;
- case RS232_BAUD_2400:
- cfsetispeed(&term, B2400);
- cfsetospeed(&term, B2400);
- break;
- case RS232_BAUD_4800:
- cfsetispeed(&term, B4800);
- cfsetospeed(&term, B4800);
- break;
- case RS232_BAUD_9600:
- cfsetispeed(&term, B9600);
- cfsetospeed(&term, B9600);
- break;
- case RS232_BAUD_19200:
- cfsetispeed(&term, B19200);
- cfsetospeed(&term, B19200);
- break;
- case RS232_BAUD_38400:
- cfsetispeed(&term, B38400);
- cfsetospeed(&term, B38400);
- break;
- case RS232_BAUD_57600:
- cfsetispeed(&term, B57600);
- cfsetospeed(&term, B57600);
- break;
- case RS232_BAUD_115200:
- cfsetispeed(&term, B115200);
- cfsetospeed(&term, B115200);
- break;
- case RS232_BAUD_460800:
- cfsetispeed(&term, B460800);
- cfsetospeed(&term, B460800);
- break;
- default:
- return RS232_ERR_UNKNOWN;
- }
- SET_PORT_STATE(ux->fd, &term)
- p->baud = baud;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_set_dtr(struct rs232_port_t *p, enum rs232_dtr_e state)
- {
- int ret;
- int set;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p dtr=%d (dtr control %s)\n",
- (void *)p, p->pt, state, rs232_strdtr(state));
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- ret = ioctl(ux->fd, TIOCMGET, &set);
- if (ret == -1) {
- DBG("%s\n", "TIOCMGET RS232_ERR_IOCTL");
- return RS232_ERR_IOCTL;
- }
- switch (state) {
- case RS232_DTR_OFF:
- set &= ~TIOCM_DTR;
- break;
- case RS232_DTR_ON:
- set |= TIOCM_DTR;
- break;
- default:
- return RS232_ERR_UNKNOWN;
- }
- ret = ioctl(ux->fd, TIOCMSET, &set);
- if (ret == -1) {
- DBG("%s\n", "TIOCMSET RS232_ERR_IOCTL");
- return RS232_ERR_IOCTL;
- }
- p->dtr = state;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_set_rts(struct rs232_port_t *p, enum rs232_rts_e state)
- {
- int ret;
- int set;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p rts=%d (rts control %s)\n",
- (void *)p, p->pt, state, rs232_strrts(state));
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- ret = ioctl(ux->fd, TIOCMGET, &set);
- if (ret == -1) {
- DBG("%s\n", "TIOCMGET RS232_ERR_IOCTL");
- return RS232_ERR_IOCTL;
- }
- switch (state) {
- case RS232_RTS_OFF:
- set &= ~TIOCM_RTS;
- break;
- case RS232_RTS_ON:
- set |= TIOCM_RTS;
- break;
- default:
- return RS232_ERR_UNKNOWN;
- }
- ret = ioctl(ux->fd, TIOCMSET, &set);
- if (ret == -1) {
- DBG("%s\n", "TIOCMSET RS232_ERR_IOCTL");
- return RS232_ERR_IOCTL;
- }
- p->rts = state;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_set_parity(struct rs232_port_t *p, enum rs232_parity_e parity)
- {
- struct termios term;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p parity=%d (parity %s)\n",
- (void *)p, p->pt, parity, rs232_strparity(parity));
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- GET_PORT_STATE(ux->fd, &term)
- switch (parity) {
- case RS232_PARITY_NONE:
- term.c_cflag &= ~PARENB;
- break;
- case RS232_PARITY_ODD:
- term.c_cflag |= (PARENB | PARODD);
- break;
- case RS232_PARITY_EVEN:
- term.c_cflag &= ~PARODD;
- term.c_cflag |= PARENB;
- break;
- default:
- return RS232_ERR_UNKNOWN;
- }
- SET_PORT_STATE(ux->fd, &term)
- p->parity = parity;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_set_stop(struct rs232_port_t *p, enum rs232_stop_e stop)
- {
- struct termios term;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p stop=%d (%s stop bits)\n",
- (void *)p, p->pt, stop, rs232_strstop(stop));
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- GET_PORT_STATE(ux->fd, &term)
- term.c_cflag &= ~CSTOPB;
- switch (stop) {
- case RS232_STOP_1:
- break;
- case RS232_STOP_2:
- term.c_cflag |= CSTOPB;
- break;
- default:
- return RS232_ERR_UNKNOWN;
- }
- SET_PORT_STATE(ux->fd, &term)
- p->stop = stop;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_set_data(struct rs232_port_t *p, enum rs232_data_e data)
- {
- struct termios term;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p data=%d (%s data bits)\n",
- (void *)p, p->pt, data, rs232_strdata(data));
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- GET_PORT_STATE(ux->fd, &term)
- term.c_cflag &= ~CSIZE;
- switch (data) {
- case RS232_DATA_5:
- term.c_cflag |= CS5;
- break;
- case RS232_DATA_6:
- term.c_cflag |= CS6;
- break;
- case RS232_DATA_7:
- term.c_cflag |= CS7;
- break;
- case RS232_DATA_8:
- term.c_cflag |= CS8;
- break;
- default:
- return RS232_ERR_UNKNOWN;
- }
- SET_PORT_STATE(ux->fd, &term)
- p->data = data;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_set_flow(struct rs232_port_t *p, enum rs232_flow_e flow)
- {
- struct termios term;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p flow=%d (flow control %s)\n",
- (void *)p, p->pt, flow, rs232_strflow(flow));
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- GET_PORT_STATE(ux->fd, &term)
- switch (flow) {
- case RS232_FLOW_OFF:
- term.c_cflag &= ~CRTSCTS;
- term.c_iflag &= ~(IXON | IXOFF | IXANY);
- break;
- case RS232_FLOW_HW:
- term.c_cflag |= CRTSCTS;
- term.c_iflag &= ~(IXON | IXOFF | IXANY);
- break;
- case RS232_FLOW_XON_XOFF:
- term.c_cflag &= ~CRTSCTS;
- term.c_iflag |= (IXON | IXOFF | IXANY);
- break;
- default:
- return RS232_ERR_UNKNOWN;
- }
- SET_PORT_STATE(ux->fd, &term)
- p->flow = flow;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_flush(struct rs232_port_t *p)
- {
- int ret;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- ret = tcflush(ux->fd, TCIOFLUSH);
- if (ret == -1)
- return RS232_ERR_FLUSH;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_close(struct rs232_port_t *p)
- {
- int ret;
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
- if (!rs232_port_open(p))
- return RS232_ERR_PORT_CLOSED;
- ret = close(ux->fd);
- if (ret == -1)
- return RS232_ERR_CLOSE;
- p->status = RS232_PORT_CLOSED;
- return RS232_ERR_NOERROR;
- }
- unsigned int
- rs232_fd(struct rs232_port_t *p)
- {
- struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
- DBG("p=%p p->pt=%p ux->fd=%d\n", (void *)p, p->pt, ux->fd);
- return (unsigned int) ux->fd;
- }
|