Mercurial > hg > index.cgi
view src/lwwire-serial.c @ 9:a11b330771e0
Fix buffer pointer handling when logging received bytes
Actually save the read buffer pointer so we can log the actual protocol
bytes read in all cases correctly instead of displaying out of bounds memory
in the case where the packet arrives in multiple pieces.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sat, 30 Jul 2016 10:35:14 -0600 |
parents | cfc9524cca2c |
children |
line wrap: on
line source
/* Set up a serial port and launch a lwwire process to handle it. The lwwire process will be called with "exec". Usage: lwwire-serial <port> [speed] [lwwire binary args...] <port> is the device name for the serial port. [speed] is the optional speed to set the port to with a default of 115200. [lwwire binary] is the optional name for the lwwire binary. Default is "./lwwire". If [lwwire binary] is specified, then [speed] must also be specified. */ #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <termios.h> #include <unistd.h> int main(int argc, char **argv) { char *lwwire = "lwwire"; int speed = 115200; char *port; int i, rargc; char **rargv; int fd; struct termios io_mod; if (argc >= 4) { lwwire = argv[3]; } if (argc >= 3) { speed = strtol(argv[2], NULL, 10); } if (argc < 2) { fprintf(stderr, "Usage: %s <port> [<speed> [<lwwire binary> [args]]]\n", argv[0]); exit(0); } port = argv[1]; fprintf(stderr, "Starting lwwire on port '%s' at speed %d\n", port, speed); // open serial port fd = open(port, O_RDWR | O_NOCTTY); if (fd < 0) { fprintf(stderr, "Error opening port %s: %s\n", port, strerror(errno)); exit(1); } // set up parameters // this is all theoretically *mostly* posix correct except for some of the // Bxxxx constants. tcgetattr(fd, &io_mod); io_mod.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); io_mod.c_oflag &= ~OPOST; io_mod.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); io_mod.c_cflag &= ~(CSIZE|PARENB); io_mod.c_cflag |= CS8; switch (speed) { case 38400: cfsetispeed(&io_mod, B38400); cfsetospeed(&io_mod, B38400); break; case 57600: cfsetispeed(&io_mod, B57600); cfsetospeed(&io_mod, B57600); break; case 115200: cfsetispeed(&io_mod, B115200); cfsetospeed(&io_mod, B115200); break; #ifdef B230400 case 230400: cfsetispeed(&io_mod, B230400); cfsetospeed(&io_mod, B230400); break; #endif #ifdef B460800 case 460800: cfsetispeed(&io_mod, B460800); cfsetospeed(&io_mod, B460800); break; #endif #ifdef B921600 case 921600: cfsetispeed(&io_mod, B921600); cfsetospeed(&io_mod, B921600); break; #endif default: fprintf(stderr, "Unrecognzied speed %d on port %s; using 38400\n", speed, port); cfsetispeed(&io_mod, B38400); cfsetospeed(&io_mod, B38400); break; } if (tcsetattr(fd, TCSANOW, &io_mod) < 0) { fprintf(stderr, "Cannot set serial line mode properly: %s", strerror(errno)); exit(1); } // set up stdin/stdout if (dup2(fd, 0) < 0) { fprintf(stderr, "Cannot set up stdin file descriptor: %s\n", strerror(errno)); exit(1); } if (dup2(fd, 1) < 0) { fprintf(stderr, "Cannot set up stdout file descriptor: %s\n", strerror(errno)); exit(1); } // close the original FD since we don't need it any more. close(fd); // execute binary rargc = 1; if (argc >= 5) { rargc += argc - 4; } rargv = malloc(sizeof(char *) * (rargc + 1)); rargv[0] = lwwire; for (i = 4; i < argc; i++) { fprintf(stderr, "Passing argument %d of %d: %s\n", i - 3, rargc, argv[i]); rargv[i - 3] = argv[i]; } rargv[rargc] = NULL; execv(lwwire, rargv); fprintf(stderr, "Failed to execute %s: %s\n", lwwire, strerror(errno)); exit(1); }