From 8b510d71c10e9ecab44ce7d8eae46ce4e26ceeac Mon Sep 17 00:00:00 2001 From: Luka Miljak Date: Fri, 28 Mar 2014 19:52:15 +0100 Subject: [PATCH] Adding moxanix.cfg file. Moxanix is now configured with it. --- moxanix.cfg | 29 ++++++++++++ moxerver.c | 48 ++++++++++++++++++-- moxerver.h | 11 ++++- tty.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 197 insertions(+), 16 deletions(-) create mode 100644 moxanix.cfg diff --git a/moxanix.cfg b/moxanix.cfg new file mode 100644 index 0000000..e7e8325 --- /dev/null +++ b/moxanix.cfg @@ -0,0 +1,29 @@ +; port config format: +; +; [tcp_port] +; dev = {tty dev path} +; speed = {port baud rate} + +[4001] +dev = /dev/ttyUSB0 +speed = 9600 + +[4002] +dev = /dev/ttyS2 +speed = 115201 + +[4003] +dev = /dev/ttyS3 +speed = 115200 + +[4004] +dev = /dev/ttyS4 +speed = 115200 + +[4005] +dev = /dev/ttyS5 +speed = 115200 + +[4006] +dev = /dev/ttyS6 +speed = 115200 diff --git a/moxerver.c b/moxerver.c index 8f78577..468a6b7 100644 --- a/moxerver.c +++ b/moxerver.c @@ -5,6 +5,7 @@ */ #include "moxerver.h" +#include "parser.h" #include /* handling quit signals */ #include @@ -15,7 +16,8 @@ /* Prints help message. */ static void usage() { //TODO maybe some styling should be done - fprintf(stderr, "Usage: %s -p tcp_port -t tty_path [-d] [-h]\n", NAME); + fprintf(stderr, "Usage: %s -p tcp_port [-t tty_path] [-d] [-h]\n", NAME); + fprintf(stderr, "\t-t\ttty dev path (if not specified %s needs to be defined)\n", CONFILE); fprintf(stderr, "\t-d\tturns on debug messages\n"); fprintf(stderr, "\n"); } @@ -48,17 +50,46 @@ int time2string(time_t time, char* timestamp) { return 0; } +/* Parse handler function, used to configure serial port */ +int parse_handler(void *user, const char *section, const char *name, const char *value) { + + printf("[%s] section = %s, name = %s, value = %s\n", __func__, section, name, value); + + if (!strcmp(name, "speed") && (unsigned int)atoi(section) == server.port) { + printf("[%s] setting %s speed for port %s\n", __func__, value, section); + + if (cfsetispeed(&(tty_dev.ttyset), baud_to_speed(atoi(value))) < 0 || + cfsetospeed(&(tty_dev.ttyset), baud_to_speed(atoi(value))) < 0) { + fprintf(stderr, "[%s] error configuring tty device speed\n", NAME); + return -1; + } + } + + if (!strcmp(name, "dev") && (unsigned int)atoi(section) == server.port) + strcpy(tty_dev.path, value); + + return 1; +} + /* MoxaNix main program loop. */ int main(int argc, char *argv[]) { int ret; unsigned int tcp_port = -1; + int def_conf = 0; // is default config used or from .cfg file fd_set read_fds; int fdmax; struct timeval tv; pthread_t tty_thread; + + /* zero init tty_dev */ + if (cfsetispeed(&(tty_dev.ttyset), B0) < 0 || + cfsetospeed(&(tty_dev.ttyset), B0) < 0) { + fprintf(stderr, "[%s] error configuring tty device speed\n", NAME); + return -1; + } /* enable catching and handling some quit signals, SIGKILL can't be caught */ signal(SIGTERM, quit_handler); @@ -78,7 +109,7 @@ int main(int argc, char *argv[]) { case 'p': tcp_port = (unsigned int) atoi(optarg); break; - /* get tty device path */ + /* get tty device path, default config used */ case 't': if ((strnlen(optarg, DEV_PATH) == 0) || (strnlen(optarg, DEV_PATH) > (DEV_PATH - 1))) { @@ -89,6 +120,7 @@ int main(int argc, char *argv[]) { /* set tty device path in tty_dev struct */ strcpy(tty_dev.path, optarg); } + def_conf = 1; break; /* enable debug messages */ case 'd': @@ -104,13 +136,23 @@ int main(int argc, char *argv[]) { return -1; } } - + /* initialize */ fprintf(stderr, "[%s] TCP port: %d, TTY device path: %s\n", NAME, tcp_port, tty_dev.path); if (server_setup(&server, tcp_port) < 0) return -1; client.socket = -1; tty_dev.fd = -1; + /* parse config file if any */ + if (!def_conf && ((ret = ini_parse(CONFILE, &parse_handler, NULL)) == -1)) { + fprintf(stderr, "[%s] error opening config file %s\n", NAME, CONFILE); + usage(); + return -1; + } + else if (!def_conf && ret) { + fprintf(stderr, "[%s] error parsing congig file %s on line %d\n", NAME, CONFILE, ret); + return -1; + } /* open tty device */ if (tty_open(&tty_dev) < 0) { fprintf(stderr, "[%s] error: opening of tty device at %s failed\n" diff --git a/moxerver.h b/moxerver.h index 440ad44..618b7e6 100644 --- a/moxerver.h +++ b/moxerver.h @@ -16,6 +16,7 @@ #define DEV_PATH 32 #define TIMESTAMP_FORMAT "%d.%m.%Y. %H:%M:%S" #define TIMESTAMP_LEN 20+1 /* calculated following timestamp format */ +#define CONFILE "moxanix.cfg" /* Structures used for communication parameters. */ struct server_t { @@ -44,7 +45,7 @@ struct tty_t { int debug_messages; /* if > 0 debug messages will be printed */ struct server_t server; /* main server structure */ struct client_t client; /* connected client structure */ //TODO working with only 1 client, this can be expanded into a list -struct tty_t tty_dev; /* connected tty device */ +struct tty_t tty_dev; /* connected tty device */ /* Global functions used throughout the application. */ @@ -160,15 +161,21 @@ int telnet_handle_client_write(char *databuf, int *datalen); /* Opens the tty device and configures it. */ int tty_open(struct tty_t *tty_dev); + /* Closes the tty device. */ int tty_close(struct tty_t *tty_dev); + /* Reconfigures the tty device. */ int tty_reconfigure(struct tty_t *tty_dev, struct termios newttyset); + /* Reads incoming data from tty device to tty data buffer. */ int tty_read(struct tty_t *tty_dev); + /* Sends data from a buffer to tty device. */ int tty_write(struct tty_t *tty_dev, char *databuf, int datalen); + /* Main tty thread function */ void *tty_thread_func(void *arg); - +int speed_to_baud(speed_t speed); +speed_t baud_to_speed(int baud); diff --git a/tty.c b/tty.c index 0f60e4e..3eda2f8 100644 --- a/tty.c +++ b/tty.c @@ -7,6 +7,7 @@ #define TTY_THREAD_TIMEOUT_SEC 30 #define TTY_WAIT_TIMEOUT 5 /* seconds for select() timeout in server loop */ #define NAME "tty" +#define TTY_DEF_BAUD_RATE B115200 /* Opens the tty device and configures it. */ int tty_open(struct tty_t *tty_dev) { @@ -22,28 +23,36 @@ int tty_open(struct tty_t *tty_dev) { tty_dev->fd = fd; tty_dev->ttyset.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | - PARMRK | INPCK | ISTRIP | IXON); + PARMRK | INPCK | ISTRIP | IXON); tty_dev->ttyset.c_oflag &= ~(OCRNL | ONLCR | ONLRET | - ONOCR | OFILL | OLCUC | OPOST); + ONOCR | OFILL | OLCUC | OPOST); tty_dev->ttyset.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); tty_dev->ttyset.c_cflag &= ~(CSIZE | PARENB); tty_dev->ttyset.c_cflag |= CS8; tty_dev->ttyset.c_cc[VMIN] = 1; tty_dev->ttyset.c_cc[VTIME] = 0; - if(cfsetispeed(&(tty_dev->ttyset), B115200) < 0 || cfsetospeed(&(tty_dev->ttyset), B115200) < 0) { + /* if speed is set to B0 (e.g. cfg file is not provided), default values are used */ + if (cfgetispeed(&(tty_dev->ttyset)) == baud_to_speed(0) && + cfsetispeed(&(tty_dev->ttyset), TTY_DEF_BAUD_RATE) < 0) { fprintf(stderr, "[%s] error configuring tty device speed\n", NAME); return -errno; - } - - if(tcsetattr(tty_dev->fd, TCSAFLUSH, &(tty_dev->ttyset)) < 0) { + } + if (cfgetospeed(&(tty_dev->ttyset)) == baud_to_speed(0) && + cfsetospeed(&(tty_dev->ttyset), TTY_DEF_BAUD_RATE) < 0) { + fprintf(stderr, "[%s] error configuring tty device speed\n", NAME); + return -errno; + } + + if(tcsetattr(tty_dev->fd, TCSAFLUSH, &(tty_dev->ttyset)) < 0) { fprintf(stderr, "[%s] error configuring tty device\n", NAME); return -errno; - } + } return 0; - + } + /* Closes the tty device. */ int tty_close(struct tty_t *tty_dev) { // close and set "tty_dev.fd = -1" @@ -88,7 +97,7 @@ void *tty_thread_func(void *arg) { tv.tv_usec = 0; FD_ZERO(&read_fds); FD_SET(tty_dev->fd, &read_fds); - + /* wait with select() */ ret = select(tty_dev->fd + 1, &read_fds, NULL, NULL, &tv); @@ -101,9 +110,9 @@ void *tty_thread_func(void *arg) { //sleep(10); //if (read(tty_dev->fd, &c, 1) > 0) // printf("%c", c); - + //fprintf(stderr, "[%s] tty thread reporting ...\n", NAME); - //i++; + //i++; } fprintf(stderr, "[%s] tty thread stoped\n", NAME); @@ -111,3 +120,97 @@ void *tty_thread_func(void *arg) { return (void *)tty_dev;; } +/* + * Converts POSIX speed_t to a baud rate. The values of the + * constants for speed_t are not themselves portable. + */ +int speed_to_baud(speed_t speed) +{ + switch (speed) { + case B0: + return 0; + case B50: + return 50; + case B75: + return 75; + case B110: + return 110; + case B134: + return 134; + case B150: + return 150; + case B200: + return 200; + case B300: + return 300; + case B600: + return 600; + case B1200: + return 1200; + case B1800: + return 1800; + case B2400: + return 2400; + case B4800: + return 4800; + case B9600: + return 9600; + case B19200: + return 19200; + case B38400: + return 38400; + case B57600: + return 57600; + case B115200: + return 115200; + default: + return 115200; + } +} + +/* + * Converts a numeric baud rate to a POSIX speed_t. + */ +speed_t baud_to_speed(int baud) +{ + switch (baud) { + case 0: + return B0; + case 50: + return B50; + case 75: + return B75; + case 110: + return B110; + case 134: + return B134; + case 150: + return B150; + case 200: + return B200; + case 300: + return B300; + case 600: + return B600; + case 1200: + return B1200; + case 1800: + return B1800; + case 2400: + return B2400; + case 4800: + return B4800; + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + default: + return B115200; + } +}