From 5cb98de5d0ad9d0e69af459d911bcd1157162ce1 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 25 Aug 2020 00:14:52 -0500 Subject: [PATCH] Allow setting baud, flow control for TNCs Changes: * Add argument to patty_kiss_tnc_new(), patty_kiss_tnc_new_fd(), a pointer to patty_kiss_tnc_info, to allow specifying baud and flow control * Rework patty_ax25_if_kiss_tnc_info to hold patty_kiss_tnc_info as a hack to allow instantiating a KISS TNC-based network interface with desired baud and flow control --- examples/ax25dump.c | 2 +- examples/daemon.c | 24 +++++++----------------- examples/decode.c | 4 ++-- include/patty/ax25/if.h | 4 ++++ include/patty/kiss.h | 23 +++++++++++++++++++++-- src/if.c | 4 ++-- src/kiss.c | 31 ++++++++++++++++++++++++++++--- src/sock.c | 2 +- 8 files changed, 66 insertions(+), 28 deletions(-) diff --git a/examples/ax25dump.c b/examples/ax25dump.c index 88e4143..18a2a46 100644 --- a/examples/ax25dump.c +++ b/examples/ax25dump.c @@ -70,7 +70,7 @@ int main(int argc, char **argv) { goto error_client_setsockopt; } - if ((raw = patty_kiss_tnc_new_fd(fd)) == NULL) { + if ((raw = patty_kiss_tnc_new_fd(fd, NULL)) == NULL) { fprintf(stderr, "%s: fd %d: %s: %s\n", argv[0], fd, "patty_kiss_tnc_new_fd()", strerror(errno)); diff --git a/examples/daemon.c b/examples/daemon.c index f445f2a..ba2a41f 100644 --- a/examples/daemon.c +++ b/examples/daemon.c @@ -32,7 +32,13 @@ int main(int argc, char **argv) { patty_daemon *daemon; patty_ax25_if_kiss_tnc_info info = { - .type = PATTY_AX25_IF_KISS_TNC_INFO_FD + .type = PATTY_AX25_IF_KISS_TNC_INFO_FD, + + .flags = PATTY_KISS_TNC_BAUD + | PATTY_KISS_TNC_FLOW, + + .baud = B9600, + .flow = PATTY_KISS_TNC_FLOW_CRTSCTS }; if (argc < 2) { @@ -63,22 +69,6 @@ int main(int argc, char **argv) { } fprintf(stderr, "pts %s\n", pts); - } else { - struct termios t; - - memset(&t, '\0', sizeof(t)); - - t.c_cflag = CS8 | CREAD | HUPCL | CRTSCTS; - t.c_iflag = IGNPAR; - t.c_cc[VTIME] = 0; - t.c_cc[VMIN] = 1; - - cfsetspeed(&t, B9600); - - if (tcsetattr(info.fd, TCSANOW, &t) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], argv[1], "tcsetattr()", strerror(errno)); - } } errno = 0; diff --git a/examples/decode.c b/examples/decode.c index e742d8b..4b59dd1 100644 --- a/examples/decode.c +++ b/examples/decode.c @@ -33,8 +33,8 @@ int main(int argc, char **argv) { } tnc = (argc == 2)? - patty_kiss_tnc_new(argv[1]): - patty_kiss_tnc_new_fd(0); + patty_kiss_tnc_new(argv[1], NULL): + patty_kiss_tnc_new_fd(0, NULL); if (tnc == NULL) { perror("Unable to open TNC"); diff --git a/include/patty/ax25/if.h b/include/patty/ax25/if.h index 57260d5..b9c7e93 100644 --- a/include/patty/ax25/if.h +++ b/include/patty/ax25/if.h @@ -58,6 +58,10 @@ enum patty_ax25_if_kiss_tnc_info_type { }; typedef struct _patty_ax25_if_kiss_tnc_info { + int flags; + speed_t baud; + enum patty_kiss_tnc_flow flow; + enum patty_ax25_if_kiss_tnc_info_type type; int fd; diff --git a/include/patty/kiss.h b/include/patty/kiss.h index b7ea23a..5566553 100644 --- a/include/patty/kiss.h +++ b/include/patty/kiss.h @@ -2,6 +2,7 @@ #define _PATTY_KISS_H #include +#include #define PATTY_KISS_FEND 0xc0 #define PATTY_KISS_FESC 0xdb @@ -34,9 +35,27 @@ ssize_t patty_kiss_frame_send(int fd, typedef struct _patty_kiss_tnc patty_kiss_tnc; -patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd); +#define PATTY_KISS_TNC_BAUD (1 << 0) +#define PATTY_KISS_TNC_FLOW (1 << 1) -patty_kiss_tnc *patty_kiss_tnc_new(const char *device); +enum patty_kiss_tnc_flow { + PATTY_KISS_TNC_FLOW_NONE, + PATTY_KISS_TNC_FLOW_CRTSCTS, + PATTY_KISS_TNC_FLOW_XONXOFF +}; + +typedef struct _patty_kiss_tnc_info { + int flags; + + speed_t baud; + enum patty_kiss_tnc_flow flow; +} patty_kiss_tnc_info; + +patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd, + patty_kiss_tnc_info *info); + +patty_kiss_tnc *patty_kiss_tnc_new(const char *device, + patty_kiss_tnc_info *info); int patty_kiss_tnc_fd(patty_kiss_tnc *tnc); diff --git a/src/if.c b/src/if.c index 54c8908..a8d4d7e 100644 --- a/src/if.c +++ b/src/if.c @@ -12,8 +12,8 @@ static int init_tnc(patty_ax25_if *iface, patty_ax25_if_kiss_tnc_info *info) { static int number = 0; iface->tnc = (info->type == PATTY_AX25_IF_KISS_TNC_INFO_FD)? - patty_kiss_tnc_new_fd(info->fd): - patty_kiss_tnc_new(info->path); + patty_kiss_tnc_new_fd(info->fd, (patty_kiss_tnc_info *)info): + patty_kiss_tnc_new(info->path, (patty_kiss_tnc_info *)info); if (iface->tnc == NULL) { goto error_kiss_tnc_new; diff --git a/src/kiss.c b/src/kiss.c index 97d8310..1a47cc6 100644 --- a/src/kiss.c +++ b/src/kiss.c @@ -120,7 +120,8 @@ error_io: return -1; } -patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd) { +patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd, + patty_kiss_tnc_info *info) { patty_kiss_tnc *tnc; if ((tnc = malloc(sizeof(*tnc))) == NULL) { @@ -140,6 +141,29 @@ patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd) { cfmakeraw(&tnc->attrs); + if (info) { + if (info->flags & PATTY_KISS_TNC_BAUD) { + cfsetspeed(&tnc->attrs, info->baud); + } + + if (info->flags & PATTY_KISS_TNC_FLOW) { + switch (info->flow) { + case PATTY_KISS_TNC_FLOW_NONE: + break; + + case PATTY_KISS_TNC_FLOW_CRTSCTS: + tnc->attrs.c_cflag |= CRTSCTS; + + break; + + case PATTY_KISS_TNC_FLOW_XONXOFF: + tnc->attrs.c_iflag |= IXON | IXOFF; + + break; + } + } + } + if (tcflush(fd, TCIOFLUSH) < 0) { goto error_tcflush; } @@ -170,7 +194,8 @@ error_malloc_tnc: return NULL; } -patty_kiss_tnc *patty_kiss_tnc_new(const char *device) { +patty_kiss_tnc *patty_kiss_tnc_new(const char *device, + patty_kiss_tnc_info *info) { patty_kiss_tnc *tnc; int fd; struct stat st; @@ -205,7 +230,7 @@ patty_kiss_tnc *patty_kiss_tnc_new(const char *device) { } } - if ((tnc = patty_kiss_tnc_new_fd(fd)) == NULL) { + if ((tnc = patty_kiss_tnc_new_fd(fd, info)) == NULL) { goto error_tnc_new_fd; } diff --git a/src/sock.c b/src/sock.c index c39df4a..695d6e2 100644 --- a/src/sock.c +++ b/src/sock.c @@ -134,7 +134,7 @@ static patty_ax25_sock *init_dgram(patty_ax25_sock *sock, } static patty_ax25_sock *init_raw(patty_ax25_sock *sock) { - if ((sock->raw = patty_kiss_tnc_new_fd(sock->fd)) == NULL) { + if ((sock->raw = patty_kiss_tnc_new_fd(sock->fd, NULL)) == NULL) { goto error_kiss_tnc_new_fd; }