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