Mercurial > hg > index.cgi
comparison src/lwwire-serial.c @ 0:bef2801ac83e
Initial checkin with reference implementation of core protocol
Initial checkin. Has the initial version of the protocol documentation along
with a reference implementation of the core protocol.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 08 May 2016 12:56:39 -0600 |
parents | |
children | cfc9524cca2c |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bef2801ac83e |
---|---|
1 /* | |
2 Set up a serial port and launch a lwwire process to handle it. The lwwire | |
3 process will be called with "exec". | |
4 | |
5 Usage: | |
6 | |
7 lwwire-serial <port> [speed] [lwwire binary args...] | |
8 | |
9 <port> is the device name for the serial port. [speed] is the optional speed | |
10 to set the port to with a default of 115200. [lwwire binary] is the optional | |
11 name for the lwwire binary. Default is "./lwwire". If [lwwire binary] is | |
12 specified, then [speed] must also be specified. | |
13 | |
14 */ | |
15 | |
16 #include <errno.h> | |
17 #include <fcntl.h> | |
18 #include <stdio.h> | |
19 #include <stdlib.h> | |
20 #include <string.h> | |
21 #include <termios.h> | |
22 #include <unistd.h> | |
23 | |
24 int main(int argc, char **argv) | |
25 { | |
26 char *lwwire = "lwwire"; | |
27 int speed = 115200; | |
28 char *port; | |
29 int i, rargc; | |
30 char **rargv; | |
31 int fd; | |
32 struct termios io_mod; | |
33 | |
34 if (argc >= 4) | |
35 { | |
36 lwwire = argv[3]; | |
37 } | |
38 if (argc >= 3) | |
39 { | |
40 speed = strtol(argv[2], NULL, 10); | |
41 } | |
42 if (argc < 2) | |
43 { | |
44 fprintf(stderr, "Usage: %s <port> [<speed> [<lwwire binary> [args]]]\n", argv[0]); | |
45 exit(0); | |
46 } | |
47 port = argv[1]; | |
48 | |
49 fprintf(stderr, "Starting lwwire on port '%s' at speed %d\n", port, speed); | |
50 | |
51 // open serial port | |
52 fd = open(port, O_RDWR | O_NOCTTY); | |
53 if (fd < 0) | |
54 { | |
55 fprintf(stderr, "Error opening port %s: %s\n", port, strerror(errno)); | |
56 exit(1); | |
57 } | |
58 // set up parameters | |
59 // this is all theoretically *mostly* posix correct except for some of the | |
60 // Bxxxx constants. | |
61 tcgetattr(fd, &io_mod); | |
62 io_mod.c_iflag &= | |
63 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); | |
64 io_mod.c_oflag &= ~OPOST; | |
65 io_mod.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); | |
66 io_mod.c_cflag &= ~(CSIZE|PARENB); | |
67 io_mod.c_cflag |= CS8; | |
68 switch (speed) | |
69 { | |
70 case 38400: | |
71 cfsetispeed(&io_mod, B38400); | |
72 cfsetospeed(&io_mod, B38400); | |
73 break; | |
74 | |
75 case 57600: | |
76 cfsetispeed(&io_mod, B57600); | |
77 cfsetospeed(&io_mod, B57600); | |
78 break; | |
79 | |
80 case 115200: | |
81 cfsetispeed(&io_mod, B115200); | |
82 cfsetospeed(&io_mod, B115200); | |
83 break; | |
84 | |
85 case 230400: | |
86 cfsetispeed(&io_mod, B230400); | |
87 cfsetospeed(&io_mod, B230400); | |
88 break; | |
89 | |
90 default: | |
91 fprintf(stderr, "Unrecognzied speed %d on port %s; using 38400\n", speed, port); | |
92 cfsetispeed(&io_mod, B38400); | |
93 cfsetospeed(&io_mod, B38400); | |
94 break; | |
95 } | |
96 | |
97 if (tcsetattr(fd, TCSANOW, &io_mod) < 0) | |
98 { | |
99 fprintf(stderr, "Cannot set serial line mode properly: %s", strerror(errno)); | |
100 exit(1); | |
101 } | |
102 | |
103 // set up stdin/stdout | |
104 if (dup2(fd, 0) < 0) | |
105 { | |
106 fprintf(stderr, "Cannot set up stdin file descriptor: %s\n", strerror(errno)); | |
107 exit(1); | |
108 } | |
109 if (dup2(fd, 1) < 0) | |
110 { | |
111 fprintf(stderr, "Cannot set up stdout file descriptor: %s\n", strerror(errno)); | |
112 exit(1); | |
113 } | |
114 // close the original FD since we don't need it any more. | |
115 close(fd); | |
116 | |
117 // execute binary | |
118 rargc = 1; | |
119 if (argc >= 5) | |
120 { | |
121 rargc += argc - 4; | |
122 } | |
123 rargv = malloc(sizeof(char *) * (rargc + 1)); | |
124 rargv[0] = lwwire; | |
125 for (i = 4; i < argc; i++) | |
126 { | |
127 fprintf(stderr, "Passing argument %d of %d: %s\n", i - 3, rargc, argv[i]); | |
128 rargv[i - 3] = argv[i]; | |
129 } | |
130 rargv[rargc] = NULL; | |
131 | |
132 execv(lwwire, rargv); | |
133 fprintf(stderr, "Failed to execute %s: %s\n", lwwire, strerror(errno)); | |
134 exit(1); | |
135 } |