Mercurial > hg > index.cgi
view src/lwwire-serial.c @ 10:36c4cda4b6c4
Add extension support with the PINGPONG extension
Add extension support. There are two ways to add extensions:
1. as a shared object which will be loaded with ext=<filename> as a
parameter to lwwire. See the lwwire_pingpong.c file for details.
2. By doing basically the same thing as a shared object but linking it into
the main binary and calling lwwire_register_extension() appropriately.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sat, 30 Jul 2016 13:16:39 -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); }