]>
cvs.zerfleddert.de Git - rigol/blob - rigold.c
955975a0a1d1ab2539a5bc48202cc4bdb7c2f168
2 #include <sys/socket.h>
17 static int send_binary(int s
, char *buf
, int len
)
22 ret
= write(s
, buf
, len
);
34 static int send_text(int s
, char *fmt
, ...)
41 cnt
= vsnprintf(buf
, sizeof(buf
), fmt
, argp
);
47 return send_binary(s
, buf
, cnt
);
50 static int send_command_output(int s
, struct scope
*sc
, char *cmd
)
52 unsigned char buf
[1024*1024];
55 res
= sendscpi(sc
, cmd
, buf
, sizeof(buf
));
56 send_binary(s
, (char*)buf
, res
);
61 static void serve_index(int s
, struct scope
*sc
, char *param
)
66 send_text(s
, "HTTP/1.0 200 OK\n");
67 send_text(s
, "Content-type: text/html\n\n");
68 send_text(s
, "<html><head><title>%s</title></head><body bgcolor=\"#ffffff\" text=\"#000000\">\n", scope_idn(sc
));
69 send_text(s
, "<img src=\"/cgi-bin/lcd\" height=\"234\" width=\"320\">\n");
70 send_text(s
, "<br>\n");
73 update_scope_status(sc
);
76 send_text(s
, "System: Language: %s, Counter: %d, Beep: %d<br><br>\n",
77 sc
->status
.system
.lang
,
78 sc
->status
.system
.counter_enabled
,
79 sc
->status
.system
.beep_enabled
);
81 send_text(s
, "Keyboard: Key Lock: %d<br><br>\n",
82 sc
->status
.keyboard
.key_lock
);
84 send_text(s
, "Measure: Source: %s, Total: %d<br>\n",
85 sc
->status
.measure
.source
,
86 sc
->status
.measure
.total
);
88 send_text(s
, "Measure CH1:<br>\n");
89 send_text(s
, "VPP: %lg, VMAX: %lg, VMIN: %lg, VAMPLITUDE: %lg, VTOP: %lg, VBASE: %lg, VAVERAGE: %lg, VRMS: %lg<br>\n",
90 sc
->status
.measure
.ch1
.vpp
,
91 sc
->status
.measure
.ch1
.vmax
,
92 sc
->status
.measure
.ch1
.vmin
,
93 sc
->status
.measure
.ch1
.vamplitude
,
94 sc
->status
.measure
.ch1
.vtop
,
95 sc
->status
.measure
.ch1
.vbase
,
96 sc
->status
.measure
.ch1
.vaverage
,
97 sc
->status
.measure
.ch1
.vrms
);
99 send_text(s
, "Overshoot: %lg, Preshoot: %lg<br>\n",
100 sc
->status
.measure
.ch1
.overshoot
,
101 sc
->status
.measure
.ch1
.preshoot
);
103 send_text(s
, "Frequency: %lg, Risetime: %lg, Falltime: %lg<br>\n",
104 sc
->status
.measure
.ch1
.frequency
,
105 sc
->status
.measure
.ch1
.risetime
,
106 sc
->status
.measure
.ch1
.falltime
);
108 send_text(s
, "Period: %lg, Pwidth: %lg, Nwidth: %lg, Pdutycycle: %lg, Ndutycycle: %lg<br>\n",
109 sc
->status
.measure
.ch1
.period
,
110 sc
->status
.measure
.ch1
.pwidth
,
111 sc
->status
.measure
.ch1
.nwidth
,
112 sc
->status
.measure
.ch1
.pdutycycle
,
113 sc
->status
.measure
.ch1
.ndutycycle
);
115 send_text(s
, "Pdelay: %lg, Ndelay: %lg<br>\n",
116 sc
->status
.measure
.ch1
.pdelay
,
117 sc
->status
.measure
.ch1
.ndelay
);
119 send_text(s
, "Measure CH2:<br>\n");
120 send_text(s
, "VPP: %lg, VMAX: %lg, VMIN: %lg, VAMPLITUDE: %lg, VTOP: %lg, VBASE: %lg, VAVERAGE: %lg, VRMS: %lg<br>\n",
121 sc
->status
.measure
.ch2
.vpp
,
122 sc
->status
.measure
.ch2
.vmax
,
123 sc
->status
.measure
.ch2
.vmin
,
124 sc
->status
.measure
.ch2
.vamplitude
,
125 sc
->status
.measure
.ch2
.vtop
,
126 sc
->status
.measure
.ch2
.vbase
,
127 sc
->status
.measure
.ch2
.vaverage
,
128 sc
->status
.measure
.ch2
.vrms
);
130 send_text(s
, "Overshoot: %lg, Preshoot: %lg<br>\n",
131 sc
->status
.measure
.ch2
.overshoot
,
132 sc
->status
.measure
.ch2
.preshoot
);
134 send_text(s
, "Frequency: %lg, Risetime: %lg, Falltime: %lg<br>\n",
135 sc
->status
.measure
.ch2
.frequency
,
136 sc
->status
.measure
.ch2
.risetime
,
137 sc
->status
.measure
.ch2
.falltime
);
139 send_text(s
, "Period: %lg, Pwidth: %lg, Nwidth: %lg, Pdutycycle: %lg, Ndutycycle: %lg<br>\n",
140 sc
->status
.measure
.ch2
.period
,
141 sc
->status
.measure
.ch2
.pwidth
,
142 sc
->status
.measure
.ch2
.nwidth
,
143 sc
->status
.measure
.ch2
.pdutycycle
,
144 sc
->status
.measure
.ch2
.ndutycycle
);
146 send_text(s
, "Pdelay: %lg, Ndelay: %lg<br>\n",
147 sc
->status
.measure
.ch2
.pdelay
,
148 sc
->status
.measure
.ch2
.ndelay
);
150 send_text(s
, "<br>Acquire: Type: %s, Mode: %s, Averages: %d, CH1: %.10lg samples/s, CH2: %.10lg samples/s<br>\n",
151 sc
->status
.acquire
.type
,
152 sc
->status
.acquire
.mode
,
153 sc
->status
.acquire
.averages
,
154 sc
->status
.acquire
.srate_ch1
,
155 sc
->status
.acquire
.srate_ch2
);
157 send_text(s
, "<br>Display: Type: %s, Grid: %s, Persist: %d, MNUDisplay: %s, MNUStatus: %d, Screen: %s, Brightness: %d, Intensity: %d<br><br>\n",
158 sc
->status
.display
.type
,
159 sc
->status
.display
.grid
,
160 sc
->status
.display
.persist
,
161 sc
->status
.display
.mnudisplay
,
162 sc
->status
.display
.mnustatus
,
163 sc
->status
.display
.screen
,
164 sc
->status
.display
.brightness
,
165 sc
->status
.display
.intensity
);
167 for (i
= 1; i
<= 2; i
++) {
169 ch
= &(sc
->status
.channel
.ch1
);
171 ch
= &(sc
->status
.channel
.ch2
);
173 send_text(s
, "Channel %d: ", i
);
175 send_text(s
, "BWLimit: %d, Coupling: %s, Displayed: %d, Inverted: %d, Offset: %lg, Probe: %lgX, Scale: %lg, Filter: %d, Memory Depth: %d, Vernier: %s<br>\n",
188 send_text(s
, "<br>Horizontal: Mode: %s, Offset: %lg, Delayed Offset: %lg, Scale: %lg, Format: %s<br>\n",
189 sc
->status
.timebase
.mode
,
190 sc
->status
.timebase
.offset
,
191 sc
->status
.timebase
.delayed_offset
,
192 sc
->status
.timebase
.scale
,
193 sc
->status
.timebase
.format
);
195 send_text(s
, "<br>Math: Math Displayed: %d, FFT Displayed: %d<br>\n",
196 sc
->status
.math
.displayed
,
197 sc
->status
.fft
.displayed
);
199 send_text(s
, "<br>Data: ");
200 send_text(s
, "<a href=\"/cgi-bin/data?CHAN1\">Channel 1</a> ");
201 send_text(s
, "<a href=\"/cgi-bin/data?CHAN2\">Channel 2</a> ");
202 send_text(s
, "<a href=\"/cgi-bin/data?DIG\">Digital</a> ");
203 send_text(s
, "<a href=\"/cgi-bin/data?MATH\">Math</a> ");
204 send_text(s
, "<a href=\"/cgi-bin/data?FFT\">FFT</a><br>");
206 send_text(s
, "<br>\n");
207 send_text(s
, "<form method=\"get\" action=\"\">\n");
208 send_text(s
, "<input type=\"text\" name=\"cmd\" value=\"");
210 if (strncmp(param
, "cmd=", 4) == 0)
215 send_text(s
, "\">\n");
216 send_text(s
, "<input type=\"submit\">\n");
217 send_text(s
, "</form>\n");
218 send_text(s
, "<a href=\"?cmd=:RUN\">RUN</a> ");
219 send_text(s
, "<a href=\"?cmd=:STOP\">STOP</a> ");
220 send_text(s
, "<a href=\"?cmd=:FORC\">FORCE</a> ");
223 if (strchr (param
, '?')) {
224 send_text(s
, "<pre>< ");
226 send_text(s
, "\n> ");
227 send_command_output(s
, sc
, param
);
228 send_text(s
, "</pre>\n");
230 sendscpi(sc
, param
, NULL
, 0);
234 send_text(s
, "</body></html>\n");
237 static void serve_lcd(int s
, struct scope
*sc
)
244 png
= get_lcd(sc
, &imglen
, 0);
251 send_text(s
, "HTTP/1.0 200 OK\n");
252 send_text(s
, "Content-type: image/png\n");
253 snprintf(buf
, sizeof(buf
), "Content-length: %u\n\n", imglen
);
255 send_binary(s
, (char*)png
, imglen
);
259 static void serve_data(int s
, struct scope
*sc
, char *source
)
265 send_text(s
, "HTTP/1.0 200 OK\n");
266 send_text(s
, "Content-type: text/plain\n\n");
269 data
= scope_get_data(sc
, source
, &len
);
273 for (i
= 0; i
< (len
-1); i
++) {
274 send_text(s
, "%d,", data
[i
]);
276 send_text(s
, "%d", data
[len
-1]);
281 static void serve_404(int s
)
283 send_text(s
, "HTTP/1.0 404 Not found\n");
284 send_text(s
, "Content-type: text/html\n\n");
285 send_text(s
, "<html><head><title>404</title></head>");
286 send_text(s
, "<body bgcolor=\"#ffffff\" text=\"#000000\">\n");
287 send_text(s
, "<h1>404</h1>");
288 send_text(s
, "</body></html>\n");
291 int is_eor(char *buf
)
295 /* This does not completely work, when the request is split
296 in multiple packets... */
297 if (strstr(buf
, "\x0d\x0a\x0d\x0a")) {
299 } else if (strstr(buf
, "\x0a\x0a")) {
301 } else if (strcmp(buf
, "\x0d\x0a") == 0) {
303 } else if (strcmp(buf
, "\x0a") == 0) {
311 static void parse_request(int s
, struct scope
*sc
)
317 const char delim
[] = " \t\x0d\x0a";
323 ret
=read(s
, buf
, sizeof(buf
)-1);
332 token
= strtok_r(buf
, delim
, &saveptr
);
335 /* TODO: Only GET... */
336 token
= strtok_r(NULL
, delim
, &saveptr
);
339 bzero(&file
, sizeof(file
));
340 strncpy(file
, token
, sizeof(file
)-1);
344 ret
=read(s
, buf
, sizeof(buf
)-1);
354 param
= strchr(file
, '?');
359 while ((token
= strchr(param
, '%')) != NULL
) {
362 if (strlen(token
+1) < 2)
365 strncpy(buf
, token
+1, 3);
368 *token
= (char)strtoul(buf
, NULL
, 16);
369 memmove(token
+1, token
+3, strlen(token
)-2);
372 while ((token
= strchr(param
, '+')) != NULL
) {
377 if (strcmp("/", file
) == 0) {
378 serve_index(s
, sc
, param
);
379 } else if (strcmp("/cgi-bin/lcd", file
) == 0) {
381 } else if (strcmp("/cgi-bin/data", file
) == 0) {
382 serve_data(s
, sc
, param
);
388 void sighandler(int sig
)
395 printf("Signal %d received\n", sig
);
400 int main(int argc
, char **argv
)
402 struct sigaction act
;
407 struct sockaddr_in sin
, clientsin
;
408 unsigned short port
= 8088;
412 printf("Scope not found!\n");
416 bzero(&act
, sizeof(act
));
417 act
.sa_handler
= sighandler
;
418 act
.sa_flags
= SA_RESTART
;
419 if (sigaction(SIGPIPE
, &act
, NULL
) == -1) {
424 bzero(&act
, sizeof(act
));
425 act
.sa_handler
= sighandler
;
426 if (sigaction(SIGALRM
, &act
, NULL
) == -1) {
431 if ((sock
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1) {
440 bzero(&sin
, sizeof(sin
));
441 sin
.sin_addr
.s_addr
=htonl(INADDR_ANY
);
442 sin
.sin_family
=AF_INET
;
443 sin
.sin_port
=htons(port
);
446 setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
, &opt
,sizeof(opt
));
448 if (bind(sock
, (struct sockaddr
*)&sin
, sizeof(sin
)) == -1) {
454 printf("Listening on Port %u\n", port
);
457 bzero(&clientsin
, sizeof(clientsin
));
458 slen
= sizeof(clientsin
);
459 if ((csock
= accept(sock
, (struct sockaddr
*)&clientsin
, &slen
)) == -1) {
463 parse_request(csock
, sc
);