comparison loadtools/tpinterf.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children 8d7dcfd9df53
comparison
equal deleted inserted replaced
-1:000000000000 0:e7502631a0f9
1 /*
2 * Target program interface - this module provides some primitives
3 * for communicating programmatically with loadagent and possibly
4 * other target-utils. This module will be linked by both
5 * fc-loadtool and fc-chainload.
6 */
7
8 #include <sys/types.h>
9 #include <sys/time.h>
10 #include <sys/errno.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <strings.h>
14 #include <stdlib.h>
15
16 extern int errno;
17
18 extern int target_fd;
19
20 /* definition matches ../target-utils/libcommon/cmdentry.c */
21 #define MAXCMD 527
22
23 /*
24 * static buffer between tpinterf_make_cmd and tpinterf_send_cmd
25 *
26 * We store the command with an ending \r\n so we can use it for
27 * matching the received echo as well, hence the sizing of the
28 * buffer.
29 */
30 static char cmdbuf[MAXCMD+2];
31 static int cmdlen;
32
33 static int
34 arg_chars_valid(arg)
35 char *arg;
36 {
37 char *cp;
38
39 for (cp = arg; *cp; cp++)
40 if (*cp < ' ' || *cp > '~')
41 return(0);
42 return(1);
43 }
44
45 /*
46 * This function takes a command for the target in argv form and
47 * converts it to a space-separated continuous string which can be
48 * passed as tty "keyboard" input to the target, enforcing length
49 * and character validity limits in the process. The output is
50 * stored in an internal static buffer for subsequent
51 * tpinterf_send_cmd().
52 *
53 * Return value: 0 if everything OK, or -1 if some constraint is
54 * violated.
55 */
56 tpinterf_make_cmd(argv)
57 char **argv;
58 {
59 int arglen;
60 char **ap, *dp;
61
62 dp = cmdbuf;
63 cmdlen = 0;
64 for (ap = argv; *ap; ap++) {
65 arglen = strlen(*ap);
66 if (ap != argv)
67 arglen++; /* separating space */
68 if (arglen > MAXCMD - cmdlen)
69 return(-1);
70 if (!arg_chars_valid(*ap))
71 return(-1);
72 if (ap != argv)
73 *dp++ = ' ';
74 strcpy(dp, *ap);
75 dp += strlen(*ap);
76 cmdlen += arglen;
77 }
78 *dp++ = '\r';
79 *dp = '\n';
80 return(0);
81 }
82
83 /*
84 * This function sends the previously-constructed command to the target,
85 * and collects the expected echo.
86 *
87 * Return value: 0 if successful, -1 on errors (timeout or wrong response)
88 */
89 tpinterf_send_cmd()
90 {
91 char echobuf[MAXCMD+2];
92 fd_set fds;
93 struct timeval tv;
94 int rcvd, cc;
95
96 write(target_fd, cmdbuf, cmdlen + 1);
97 for (rcvd = 0; rcvd < cmdlen + 2; ) {
98 FD_ZERO(&fds);
99 FD_SET(target_fd, &fds);
100 tv.tv_sec = 1;
101 tv.tv_usec = 0;
102 cc = select(target_fd+1, &fds, NULL, NULL, &tv);
103 if (cc < 0) {
104 if (errno == EINTR)
105 continue;
106 perror("select");
107 return(-1);
108 }
109 if (cc < 1) {
110 fprintf(stderr,
111 "error: timeout waiting for command echo\n");
112 return(-1);
113 }
114 cc = read(target_fd, echobuf + rcvd, cmdlen + 2 - rcvd);
115 if (cc <= 0) {
116 perror("read after successful select");
117 return(-1);
118 }
119 rcvd += cc;
120 }
121 if (bcmp(echobuf, cmdbuf, cmdlen + 2)) {
122 fprintf(stderr, "error: command echo mismatch\n");
123 return(-1);
124 } else
125 return(0);
126 }
127
128 /*
129 * This functions reads the serial output from the target until a
130 * '=' prompt is received. All intermediate output is passed to
131 * stdout.
132 *
133 * Return value: 0 if '=' prompt received immediately,
134 * positive if some scribble came before the prompt, -1 on errors
135 * (timeout, read errors, etc).
136 */
137 tpinterf_pass_output(timeout)
138 {
139 char buf[512], *cp;
140 fd_set fds;
141 struct timeval tv;
142 int cc, newline = 1, totout = 0;
143
144 for (;;) {
145 FD_ZERO(&fds);
146 FD_SET(target_fd, &fds);
147 tv.tv_sec = timeout;
148 tv.tv_usec = 0;
149 cc = select(target_fd+1, &fds, NULL, NULL, &tv);
150 if (cc < 0) {
151 if (errno == EINTR)
152 continue;
153 perror("select");
154 return(-1);
155 }
156 if (cc < 1) {
157 fprintf(stderr,
158 "error: timeout waiting for \'=\' prompt from target\n");
159 return(-1);
160 }
161 cc = read(target_fd, buf, sizeof buf);
162 if (cc <= 0) {
163 perror("read after successful select");
164 return(-1);
165 }
166 for (cp = buf; cc; cp++) {
167 cc--;
168 if (*cp == '=' && newline && !cc)
169 return(totout);
170 putchar(*cp);
171 totout++;
172 if (*cp == '\n')
173 newline = 1;
174 else
175 newline = 0;
176 }
177 }
178 }