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