715 lines
20 KiB
C
715 lines
20 KiB
C
#include "display.h"
|
|
#include "utility.h"
|
|
#include "params.h"
|
|
#include "sock.h"
|
|
#include "device.h"
|
|
|
|
#include <ctype.h>
|
|
|
|
#define MIN_REFRESH 5
|
|
#define MAX_REFRESH 30
|
|
|
|
/**
|
|
* Add a drop down selection box in a two-column table row
|
|
*
|
|
* \param buffer where the output is appended
|
|
* \param title text to go in column one
|
|
* \param name name of the selection object
|
|
*
|
|
* The browser will return name=value for the selection, using the name from
|
|
* the selection box and the value from the option selected.
|
|
*/
|
|
static void add_select_begin(BUFFER* buffer, char* title, char* name)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>\r\n"
|
|
"<td><select name=\"%s\">\r\n",
|
|
title,
|
|
name);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
/**
|
|
* Add an option line to a drop down selection box
|
|
*
|
|
* \param buffer where the output is appended
|
|
* \param name text displayed in the box
|
|
* \param value text returned in the form
|
|
* \param selected if this is the default selection to be displayed
|
|
*
|
|
* The browser will return name=value for the selection, using the name from
|
|
* the selection box and the value from the option selected.
|
|
*/
|
|
static void add_option(BUFFER* buffer, char* name, char* value, bool selected)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<option value=\"%s\"%s>%s</option>\r\n", value,
|
|
selected ? " selected=\"selected\"" : "",
|
|
name);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
/**
|
|
* Close out the selection, column and row of a drop down box
|
|
*
|
|
* \param buffer where the output is appended
|
|
*/
|
|
static void add_select_end(BUFFER* buffer)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"</select></td></tr>\r\n");
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
/**
|
|
* Add arbitrary text to a buffer and adjust the length
|
|
*
|
|
* \param buffer where the text is appended
|
|
*/
|
|
static void add_text(BUFFER* buffer, char* text)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length, "%s", text);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
/**
|
|
* Add a two-column row for an integer
|
|
*
|
|
* \param buffer where the text is appended
|
|
* \param title is displayed in column one
|
|
* \param name is returned by the browser
|
|
* \param value is displayed in column two and returned by the browser
|
|
*
|
|
* The title is displayed in column one and the integer in column two. The
|
|
* name=value is returned by the browser.
|
|
*/
|
|
static void add_int(BUFFER* buffer, char* title, char* name, int value)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>"
|
|
"<td><input type=\"text\" name=\"%s\" size=12 value=\"%d\"></td>"
|
|
"</tr>\r\n",
|
|
title,
|
|
name,
|
|
value);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
/**
|
|
* Add a two-column row for a double floating point
|
|
*
|
|
* \param buffer where the text is appended
|
|
* \param title is displayed in column one
|
|
* \param name is returned by the browser
|
|
* \param value is displayed in column two and returned by the browser
|
|
*
|
|
* The title is displayed in column one and the double in column two. The
|
|
* name=value is returned by the browser.
|
|
*/
|
|
static void add_double(BUFFER* buffer, char* title, char* name, double value)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>"
|
|
"<td><input type=\"text\" name=\"%s\" size=12 value=\"%.12g\"></td>"
|
|
"</tr>\r\n",
|
|
title,
|
|
name,
|
|
value);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
/**
|
|
* Add a two-column row for a counter value
|
|
*
|
|
* \param buffer where the text is appended
|
|
* \param title is displayed in column one
|
|
* \param name is returned by the browser
|
|
* \param value is displayed in column two and returned by the browser
|
|
*
|
|
* The title is displayed in column one and the counter value in column two.
|
|
* The name=value is returned by the browser.
|
|
*/
|
|
static void add_counter(BUFFER* buffer, char* title, char* name, uint64 value)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>"
|
|
"<td><input type=\"text\" name=\"%s\" size=12 value=\"%llu\"></td>"
|
|
"</tr>\r\n",
|
|
title,
|
|
name,
|
|
value);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
/**
|
|
* Display the counter control form on socket
|
|
*
|
|
* \param n index of socket
|
|
*
|
|
* The counter control form has fields to display and change counter control
|
|
* parameters. It contains buttons to update the counter parameters or reset
|
|
* them to the last displayed values.
|
|
*/
|
|
void put_form(int n)
|
|
{
|
|
dbg_printf(0, "put_form\n");
|
|
BUFFER html;
|
|
BUFFER buffer;
|
|
DEVICE* device = (DEVICE*) sock_device(n);
|
|
PARAMETERS* pp = &device->params;
|
|
char *bp;
|
|
buffer.length = 0;
|
|
bp = &buffer.body[buffer.length];
|
|
snprintf(bp, sizeof(buffer.body) - buffer.length,
|
|
"<html><head><title>Counter Form</title></head>\r\n"
|
|
"<body>\r\n"
|
|
"<form method=\"post\" action=\"/form\">\r\n"
|
|
"<table align=\"center\" border=\"0\">\r\n"
|
|
"<tr><th align=\"right\">Field</th>\r\n"
|
|
"<th align=\"left\">Value</th></tr>\r\n");
|
|
buffer.length += strlen(bp);
|
|
add_select_begin(&buffer, "Direction", "direction");
|
|
add_option(&buffer, "Up", "up", pp->direction == COUNT_UP);
|
|
add_option(&buffer, "Down", "down", !pp->direction == COUNT_UP);
|
|
add_select_end(&buffer);
|
|
add_int(&buffer, "Scan", "scan", pp->poll_period);
|
|
add_int(&buffer, "Sample", "sample", pp->sample_period);
|
|
add_int(&buffer, "Report", "report", pp->report_period);
|
|
add_counter(&buffer, "Initial", "initial", pp->initial_count);
|
|
add_counter(&buffer, "Terminal", "terminal", pp->terminal_count);
|
|
add_select_begin(&buffer, "Terminal Event", "te_check");
|
|
add_option(&buffer, "None", "none", pp->terminal_check_type == 0);
|
|
add_option(&buffer, "Counter", "counter", pp->terminal_check_type == 1);
|
|
add_option(&buffer, "Timer", "timer", pp->terminal_check_type == 2);
|
|
add_select_end(&buffer);
|
|
add_double(&buffer, "Range Low", "range_low", pp->range_low);
|
|
add_double(&buffer, "Range High", "range_high", pp->range_high);
|
|
add_select_begin(&buffer, "Range Event", "re_check");
|
|
add_option(&buffer, "Disabled", "disabled", pp->range_check_enable == false);
|
|
add_option(&buffer, "Enabled", "enabled", pp->range_check_enable == true);
|
|
add_select_end(&buffer);
|
|
add_select_begin(&buffer, "Range Gate", "range_gate");
|
|
add_option(&buffer, "Disabled", "disabled", pp->range_gate_enable == false);
|
|
add_option(&buffer, "Enabled", "enabled", pp->range_gate_enable == true);
|
|
add_select_end(&buffer);
|
|
add_select_begin(&buffer, "Range Mode", "range_mode");
|
|
add_option(&buffer, "Report", "0", pp->range_mode == 0);
|
|
add_option(&buffer, "Sample", "1", pp->range_mode == 1);
|
|
add_option(&buffer, "Poll", "2", pp->range_mode == 2);
|
|
add_select_end(&buffer);
|
|
add_select_begin(&buffer, "Source", "source");
|
|
add_option(&buffer, "External", "0", pp->source == 0);
|
|
add_option(&buffer, "Clock_1 20MHz", "1", pp->source == 1);
|
|
add_option(&buffer, "Clock_2 100KHz", "2", pp->source == 2);
|
|
add_option(&buffer, "Clock_3 80MHz", "3", pp->source == 3);
|
|
add_select_end(&buffer);
|
|
add_select_begin(&buffer, "Output Line", "output");
|
|
add_option(&buffer, "Disabled", "disabled", pp->output_line == 0);
|
|
add_option(&buffer, "Enabled", "enabled", pp->output_line == 1);
|
|
add_option(&buffer, "Inverted", "inverted", pp->output_line == 2);
|
|
add_select_end(&buffer);
|
|
add_select_begin(&buffer, "Sync", "sync");
|
|
add_option(&buffer, "Internal", "internal", pp->sync == false);
|
|
add_option(&buffer, "External", "external", pp->sync == true);
|
|
add_select_end(&buffer);
|
|
bp = &buffer.body[buffer.length];
|
|
snprintf(bp, sizeof(buffer.body) - buffer.length,
|
|
"<tr><td>\r\n"
|
|
"<input type=\"submit\" name=\"Send\" size=9 value=\"Update\">\r\n"
|
|
"</td><td>"
|
|
"<input type=\"reset\" name=\"Reset\" size=9 value=\"Reset\">\r\n"
|
|
"</td></tr></table>\r\n"
|
|
"</form>\r\n"
|
|
"</body>\r\n"
|
|
"</html>\r\n" );
|
|
buffer.length += strlen(bp);
|
|
bp = &buffer.body[buffer.length];
|
|
html.length = 0;
|
|
bp = &html.body[html.length];
|
|
snprintf(bp, sizeof(html.body) - html.length,
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"\r\n",
|
|
buffer.length);
|
|
strcat(html.body, buffer.body);
|
|
html.length = strlen(html.body);
|
|
sock_send(n, &html);
|
|
}
|
|
|
|
static void show_text(BUFFER* buffer, const char* title, const char* value)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>"
|
|
"<td>%s</td>"
|
|
"</tr>\r\n",
|
|
title,
|
|
value);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
static void show_int(BUFFER* buffer, char* title, int value)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>"
|
|
"<td>%d</td>"
|
|
"</tr>\r\n",
|
|
title,
|
|
value);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
static void show_real(BUFFER* buffer, char* title, double value)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>"
|
|
"<td>%.2f</td>"
|
|
"</tr>\r\n",
|
|
title,
|
|
value);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
static void show_counter(BUFFER* buffer, char* title, unsigned long long value)
|
|
{
|
|
char* bp = &buffer->body[buffer->length];
|
|
snprintf(bp, sizeof(buffer->body) - buffer->length,
|
|
"<tr><td>%s</td>"
|
|
"<td>%llu</td>"
|
|
"</tr>\r\n",
|
|
title,
|
|
value);
|
|
buffer->length += strlen(bp);
|
|
}
|
|
|
|
static void show_time(BUFFER* buffer,
|
|
char* title,
|
|
struct timeval* value,
|
|
bool days_flag)
|
|
{
|
|
char time_str[40];
|
|
time_str[0] = '\0';
|
|
if (days_flag)
|
|
{
|
|
snprintf(time_str, sizeof(time_str),
|
|
"%ld ",
|
|
value->tv_sec / (24 * 3600));
|
|
}
|
|
strcat(time_str, make_timestamp(value));
|
|
show_text(buffer, title, time_str);
|
|
}
|
|
|
|
/**
|
|
* Display the counter display page on socket
|
|
*
|
|
* \param n index of socket
|
|
*
|
|
* The counter display page shows the state of the counter and contains
|
|
* buttons which allow commands to be issued to the counter. It will be
|
|
* periodically refreshed.
|
|
*/
|
|
void put_page(int n)
|
|
{
|
|
dbg_printf(0, "put_page\n");
|
|
BUFFER html;
|
|
BUFFER buffer;
|
|
DEVICE* device = (DEVICE*) sock_device(n);
|
|
PARAMETERS* pp = &device->params;
|
|
SAMPLE* sp;
|
|
char *bp;
|
|
int refresh;
|
|
#if 1
|
|
{
|
|
refresh = (int) device_time_to_next_report(device) + 1;
|
|
}
|
|
#else
|
|
make_report(device);
|
|
refresh = (pp->poll_period * pp->sample_period * pp->report_period + 500) / 1000;
|
|
#endif
|
|
if (refresh < MIN_REFRESH)
|
|
refresh = MIN_REFRESH;
|
|
if (refresh > MAX_REFRESH)
|
|
refresh = MAX_REFRESH;
|
|
sp = &device->report;
|
|
buffer.length = 0;
|
|
bp = &buffer.body[buffer.length];
|
|
snprintf(bp, sizeof(buffer.body) - buffer.length,
|
|
"<html><head><title>Counter Page</title></head>\r\n"
|
|
"<body>\r\n"
|
|
"<table align=\"center\" border=\"0\"><tr><td>\r\n"
|
|
"<table align=\"center\" border=\"0\">\r\n"
|
|
"<tr><th align=\"right\">Field</th>\r\n"
|
|
"<th align=\"left\">Value</th></tr>\r\n");
|
|
buffer.length += strlen(bp);
|
|
show_text(&buffer, "State", device->state == counter_stopped ? "STOPPED" :
|
|
device->state == counter_running ? "RUNNING" :
|
|
device->state == counter_paused ? "PAUSED" : "IDLE");
|
|
show_text(&buffer, "Direction", pp->direction == COUNT_UP ? "UP" : "DOWN");
|
|
show_int(&buffer, "Scan", pp->poll_period);
|
|
show_int(&buffer, "Sample", pp->sample_period);
|
|
show_int(&buffer, "Report", pp->report_period);
|
|
show_time(&buffer, "Start Time", &device->start_time, false);
|
|
show_time(&buffer, "Current Time", &device->current_time, false);
|
|
{
|
|
struct timeval tv = device->stop_time;
|
|
if (device->state == counter_running || device->state == counter_paused)
|
|
{
|
|
tv = device->current_time;
|
|
}
|
|
time_sub(&tv, &device->start_time);
|
|
show_time(&buffer, "Elapsed", &tv, true);
|
|
}
|
|
show_time(&buffer, "Runtime", &device->accumulated, true);
|
|
show_time(&buffer, "Report Time", &sp->timestamp, false);
|
|
show_counter(&buffer, "Counter", sp->counter_value);
|
|
show_int(&buffer, "Num Polls", sp->num_polls);
|
|
show_int(&buffer, "Poll Number", sp->poll_counter);
|
|
show_int(&buffer, "Sample Number", sp->sample_counter);
|
|
show_real(&buffer, "Rate", sp->counter_rate);
|
|
show_real(&buffer, "Min", sp->minimum_rate);
|
|
show_real(&buffer, "Ave", sp->average_rate);
|
|
show_real(&buffer, "Max", sp->maximum_rate);
|
|
if (pp->range_check_enable)
|
|
{
|
|
char* result;
|
|
if (device->range_error == 1)
|
|
result = "<font color=\"BLUE\">LOW</font>";
|
|
else if (device->range_error == 2)
|
|
result = "<font color=\"RED\">HIGH</font>";
|
|
else
|
|
result = "<font color=\"GREEN\">OK</font>";
|
|
show_text(&buffer, "Range Check", result);
|
|
}
|
|
else
|
|
show_text(&buffer, "Range Check", "Disabled");
|
|
add_text(&buffer, "</table></td><td valign=\"top\"><table>\r\n");
|
|
add_text(&buffer, "<tr><td><a href=\"/form\">\r\n"
|
|
"<button>Form</button>\r\n"
|
|
"</a></td></tr>\r\n");
|
|
add_text(&buffer, "<tr><td><a href=\"/cmd=start\">\r\n"
|
|
"<button>Start</button>\r\n"
|
|
"</a></td></tr>\r\n");
|
|
add_text(&buffer, "<tr><td><a href=\"/cmd=stop\">\r\n"
|
|
"<button>Stop</button>\r\n"
|
|
"</a></td></tr>\r\n");
|
|
add_text(&buffer, "<tr><td><a href=\"/cmd=pause\">\r\n"
|
|
"<button>Pause</button>\r\n"
|
|
"</a></td></tr>\r\n");
|
|
add_text(&buffer, "<tr><td><a href=\"/cmd=continue\">\r\n"
|
|
"<button>Continue</button>\r\n"
|
|
"</a></td></tr>\r\n");
|
|
add_text(&buffer, "</table></td></tr>\r\n");
|
|
add_text(&buffer, "</table>\r\n"
|
|
"</body>\r\n"
|
|
"</html>\r\n");
|
|
html.length = 0;
|
|
bp = &html.body[html.length];
|
|
snprintf(bp, sizeof(html.body) - html.length,
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"Refresh: %d\r\n"
|
|
"\r\n",
|
|
buffer.length,
|
|
refresh);
|
|
strcat(html.body, buffer.body);
|
|
html.length = strlen(html.body);
|
|
sock_send(n, &html);
|
|
}
|
|
|
|
/**
|
|
* Process the control form in the buffer on the socket
|
|
*
|
|
* \param n index of socket
|
|
* \param bp buffer containing form input
|
|
*
|
|
* The form is sent by a browser and contains name=value pairs which are used
|
|
* to set the counter parameters.
|
|
*/
|
|
void process_form(int n, BUFFER* bp)
|
|
{
|
|
dbg_printf(0, "process_form\n");
|
|
DEVICE* device = (DEVICE*) sock_device(n);
|
|
int i, j;
|
|
int state;
|
|
char name[80];
|
|
char value[80];
|
|
char hex_str[3];
|
|
unsigned int hex_val;
|
|
char* tp;
|
|
state = 0;
|
|
j = 0;
|
|
for (i = 0; i < bp->length; ++i)
|
|
{
|
|
tp = &bp->body[i];
|
|
if (state == 0)
|
|
{
|
|
if (*tp == '=')
|
|
{
|
|
name[j++] = '\0';
|
|
j = 0;
|
|
state = 1;
|
|
}
|
|
else if (j < 80 - 1)
|
|
name[j++] = tolower(*tp);
|
|
}
|
|
else if (state == 1)
|
|
{
|
|
if (*tp == '&')
|
|
{
|
|
value[j++] = '\0';
|
|
j = 0;
|
|
state = 9;
|
|
}
|
|
else if (*tp == '%')
|
|
{
|
|
hex_str[0] = '\0';
|
|
state = 2;
|
|
}
|
|
else if (j < 80 - 1)
|
|
value[j++] = tolower(*tp);
|
|
}
|
|
else if (state == 2)
|
|
{
|
|
hex_str[0] = tolower(*tp);
|
|
state = 3;
|
|
}
|
|
else if (state == 3)
|
|
{
|
|
hex_str[1] = tolower(*tp);
|
|
hex_str[2] = '\0';
|
|
hex_val = strtoul(hex_str, NULL, 16);
|
|
if (hex_val < ' ' || hex_val > '~')
|
|
hex_val = '?';
|
|
if (j < 80 - 1)
|
|
value[j++] = tolower(hex_val);
|
|
state = 1;
|
|
}
|
|
if (state == 9)
|
|
{
|
|
dbg_printf(0, "name=\"%s\", value=\"%s\"\n", name, value);
|
|
if (param_set(&device->params, name, value))
|
|
;
|
|
else if (strcmp(name, "xxx"))
|
|
{
|
|
}
|
|
state = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cause the browser to refresh the page
|
|
*
|
|
* \param n index of socket
|
|
*
|
|
* Used after a command button to redirect to the display page. Uses
|
|
* HTTP 303 REDIRECT to get the browser to display the page.
|
|
*/
|
|
void put_page_refresh(int n)
|
|
{
|
|
dbg_printf(0, "put_page_refresh\n");
|
|
BUFFER html;
|
|
BUFFER buffer;
|
|
char* bp;
|
|
DEVICE* device = (DEVICE*) sock_device(n);
|
|
|
|
int refresh;
|
|
#if 1
|
|
{
|
|
refresh = (int) device_time_to_next_report(device) + 1;
|
|
}
|
|
#else
|
|
PARAMETERS* pp = &device->params;
|
|
make_report(device);
|
|
refresh = (pp->poll_period * pp->sample_period * pp->report_period + 500) / 1000;
|
|
#endif
|
|
if (refresh < MIN_REFRESH)
|
|
refresh = MIN_REFRESH;
|
|
if (refresh > MAX_REFRESH)
|
|
refresh = MAX_REFRESH;
|
|
|
|
buffer.length = 0;
|
|
add_text(&buffer, "<html>\r\n"
|
|
"<head>\r\n"
|
|
"<title>Title</title>\r\n"
|
|
"</head>\r\n"
|
|
"<body>\r\n");
|
|
add_text(&buffer, "</body>\r\n"
|
|
"</html>\r\n");
|
|
html.length = 0;
|
|
bp = &html.body[html.length];
|
|
snprintf(bp, sizeof(html.body) - html.length,
|
|
"HTTP/1.1 303 REDIRECT\r\n"
|
|
"Location: page\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"\r\n",
|
|
buffer.length);
|
|
strcat(html.body, buffer.body);
|
|
html.length = strlen(html.body);
|
|
sock_send(n, &html);
|
|
}
|
|
|
|
/**
|
|
* Cause the browser to refresh the form
|
|
*
|
|
* \param n index of socket
|
|
*
|
|
* Used after a command button to redirect to the control form. Uses
|
|
* HTTP 303 REDIRECT to get the browser to display the form.
|
|
*/
|
|
void put_form_refresh(int n)
|
|
{
|
|
dbg_printf(0, "put_form_refresh\n");
|
|
DEVICE* device = (DEVICE*) sock_device(n);
|
|
BUFFER html;
|
|
BUFFER buffer;
|
|
char* bp;
|
|
|
|
int refresh;
|
|
#if 1
|
|
{
|
|
refresh = (int) device_time_to_next_report(device) + 1;
|
|
}
|
|
#else
|
|
PARAMETERS* pp = &device->params;
|
|
make_report(device);
|
|
refresh = (pp->poll_period * pp->sample_period * pp->report_period + 500) / 1000;
|
|
#endif
|
|
if (refresh < MIN_REFRESH)
|
|
refresh = MIN_REFRESH;
|
|
if (refresh > MAX_REFRESH)
|
|
refresh = MAX_REFRESH;
|
|
|
|
buffer.length = 0;
|
|
add_text(&buffer, "<html>\r\n"
|
|
"<head>\r\n"
|
|
"<title>Title</title>\r\n"
|
|
"</head>\r\n"
|
|
"<body>\r\n");
|
|
add_text(&buffer, "</body>\r\n"
|
|
"</html>\r\n");
|
|
html.length = 0;
|
|
bp = &html.body[html.length];
|
|
snprintf(bp, sizeof(html.body) - html.length,
|
|
"HTTP/1.1 303 REDIRECT\r\n"
|
|
"Location: form\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"\r\n",
|
|
buffer.length);
|
|
strcat(html.body, buffer.body);
|
|
html.length = strlen(html.body);
|
|
sock_send(n, &html);
|
|
}
|
|
|
|
/**
|
|
* Process the command in the buffer on the socket
|
|
*
|
|
* \param n index of socket
|
|
* \param bp buffer containing command
|
|
*
|
|
* Handles non-browser commands like SICS commands.
|
|
*/
|
|
void process_command(int n, BUFFER* bp)
|
|
{
|
|
dbg_printf(0, "process_command(%d, %s)\n", n, bp->body);
|
|
DEVICE* device = (DEVICE*) sock_device(n);
|
|
bool sics = false;
|
|
int error = 1;
|
|
char command[80];
|
|
char param[80];
|
|
int len = 0;
|
|
char* tp = bp->body;
|
|
while (isspace(*tp))
|
|
++tp;
|
|
len = 0;
|
|
while (*tp && !isspace(*tp))
|
|
{
|
|
if (len < 80 - 1)
|
|
command[len++] = *tp;
|
|
++tp;
|
|
}
|
|
command[len] = '\0';
|
|
if (strcasecmp(command, "SICS") == 0)
|
|
{
|
|
sics = true;
|
|
while (isspace(*tp))
|
|
++tp;
|
|
len = 0;
|
|
while (*tp && !isspace(*tp))
|
|
{
|
|
if (len < 80 - 1)
|
|
command[len++] = *tp;
|
|
++tp;
|
|
}
|
|
command[len] = '\0';
|
|
}
|
|
while (isspace(*tp))
|
|
++tp;
|
|
if (strcasecmp(command, "START") == 0)
|
|
error = device_start(device);
|
|
else if (strcasecmp(command, "STOP") == 0)
|
|
error = device_stop(device);
|
|
else if (strcasecmp(command, "PAUSE") == 0)
|
|
error = device_pause(device);
|
|
else if (strcasecmp(command, "RESUME") == 0)
|
|
error = device_resume(device);
|
|
else if (strcasecmp(command, "REPORT") == 0)
|
|
{
|
|
int match = 1;
|
|
error = 0;
|
|
if (sics)
|
|
match = 2;
|
|
len = 0;
|
|
while (*tp && !isspace(*tp))
|
|
{
|
|
if (len < 80 - 1)
|
|
param[len++] = *tp;
|
|
++tp;
|
|
}
|
|
param[len] = '\0';
|
|
if (strcasecmp(param, "OFF") == 0)
|
|
match = 0;
|
|
sock_set_match(n, match);
|
|
}
|
|
else if (strcasecmp(command, "SET") == 0)
|
|
{
|
|
/* set parameter */
|
|
dbg_printf(0, "SET %s\n", tp);
|
|
if (param_set_cmd(&device->params, tp))
|
|
error = 0;
|
|
}
|
|
else if (strcasecmp(command, "GET") == 0)
|
|
{
|
|
/* get parameter */
|
|
param_get_cmd(&device->params, tp, n);
|
|
return;
|
|
}
|
|
else if (strcasecmp(command, "READ") == 0)
|
|
{
|
|
device_read(device, n);
|
|
return;
|
|
}
|
|
else if (!sics)
|
|
{
|
|
device_send(device, n);
|
|
return;
|
|
}
|
|
if (error == 0)
|
|
sock_ok(n);
|
|
else
|
|
sock_err(n);
|
|
}
|