From 956689eb6adc7406d31c112c664b38a1a0ece859 Mon Sep 17 00:00:00 2001 From: Ondrej Wisniewski Date: Fri, 12 Aug 2016 14:30:11 +0200 Subject: [PATCH] Modified file stream handling as temporary workaround for web server connection issue on some systems (OpenWRT) --- src/crelay.c | 232 ++++++++++++++++++++++++++++----------------------- 1 file changed, 129 insertions(+), 103 deletions(-) diff --git a/src/crelay.c b/src/crelay.c index 3be44fe..d2ea67c 100644 --- a/src/crelay.c +++ b/src/crelay.c @@ -57,7 +57,7 @@ #include "config.h" #include "relay_drv.h" -#define VERSION "0.10" +#define VERSION "0.10.1" #define DATE "2016" /* HTTP server defines */ @@ -269,7 +269,7 @@ void web_page_footer(FILE *f) fprintf(f, "\r\n"); fprintf(f, "\r\n", VERSION, DATE); - fprintf(f, "
crelay | version %s | %s
\r\n"); + fprintf(f, "\r\n"); } @@ -369,8 +369,9 @@ int read_httpget_data(char* buf, char* data) * Parameters: * *********************************************************/ -int process_http_request(FILE *f) +int process_http_request(int sock) { + FILE *fin, *fout; char buf[256]; char *method; char *url; @@ -384,145 +385,169 @@ int process_http_request(FILE *f) relay_state_t nstate=INVALID; formdata[0]=0; + + /* Open file for input */ + fin = fdopen(sock, "r"); /* Read first line of request header which contains * the request method and url seperated by a space */ - if (!fgets(buf, sizeof(buf), f)) return -1; + if (!fgets(buf, sizeof(buf), fin)) + { + fclose(fin); + return -1; + } //printf("********** Raw data ***********\n"); //printf("%s", buf); method = strtok(buf, " "); - if (!method) return -1; + if (!method) + { + fclose(fin); + return -1; + } //printf("method: %s\n", method); url = strtok(NULL, " "); - if (!url) return -2; + if (!url) + { + fclose(fin); + return -2; + } //printf("url: %s\n", url); - fseek(f, 0, SEEK_CUR); // Force change of stream direction - /* Check the request method we are dealing with */ if (strcasecmp(method, "POST") == 0) { - read_httppost_data(f, formdata); + read_httppost_data(fin, formdata); } else if (strcasecmp(method, "GET") == 0) { read_httpget_data(url, formdata); } else + { + fclose(fin); return -3; + } //printf("DBG: form data: %s\n", formdata); + /* Open file for output */ + fout = fdopen(sock, "w"); + /* Check if a relay card is present */ if (detect_relay_card(com_port, &last_relay) == -1) { if (strstr(url, API_URL)) { /* HTTP API request, send response */ - send_headers(f, 200, "OK", NULL, "text/html", -1, -1); - fprintf(f, "ERROR: No compatible device detected !\r\n"); + send_headers(fout, 200, "OK", NULL, "text/html", -1, -1); + fprintf(fout, "ERROR: No compatible device detected !\r\n"); } else { /* Web page request */ - web_page_header(f); - web_page_error(f); - web_page_footer(f); + web_page_header(fout); + web_page_error(fout); + web_page_footer(fout); } - return -1; } - - /* Process form data */ - if (strlen(formdata)>0) - { - /* Get values from form data */ - datastr = strstr(formdata, RELAY_TAG); - if (datastr) - relay = atoi(datastr+strlen(RELAY_TAG)+1); - datastr = strstr(formdata, STATE_TAG); - if (datastr) - nstate = atoi(datastr+strlen(STATE_TAG)+1); - - //printf("DBG: Found data: relay=%d, state=%d\n\n", relay, nstate); - - if ((relay != 0) && (nstate != INVALID)) + else + { + /* Process form data */ + if (strlen(formdata)>0) { - /* Perform the requested action here */ - if (nstate==PULSE) + /* Get values from form data */ + datastr = strstr(formdata, RELAY_TAG); + if (datastr) + relay = atoi(datastr+strlen(RELAY_TAG)+1); + datastr = strstr(formdata, STATE_TAG); + if (datastr) + nstate = atoi(datastr+strlen(STATE_TAG)+1); + + //printf("DBG: Found data: relay=%d, state=%d\n\n", relay, nstate); + + if ((relay != 0) && (nstate != INVALID)) { - /* Generate pulse on relay switch */ - get_relay(com_port, relay, &rstate[relay-1]); - if (rstate[relay-1] == ON) + /* Perform the requested action here */ + if (nstate==PULSE) { - set_relay(com_port, relay, OFF); - sleep(1); - set_relay(com_port, relay, ON); + /* Generate pulse on relay switch */ + get_relay(com_port, relay, &rstate[relay-1]); + if (rstate[relay-1] == ON) + { + set_relay(com_port, relay, OFF); + sleep(1); + set_relay(com_port, relay, ON); + } + else + { + set_relay(com_port, relay, ON); + sleep(1); + set_relay(com_port, relay, OFF); + } } else { - set_relay(com_port, relay, ON); - sleep(1); - set_relay(com_port, relay, OFF); + /* Switch relay on/off */ + set_relay(com_port, relay, nstate); } } - else - { - /* Switch relay on/off */ - set_relay(com_port, relay, nstate); - } } - } - /* Read current state for all relays */ - for (i=FIRST_RELAY; i<=last_relay; i++) - { - get_relay(com_port, i, &rstate[i-1]); - } - - /* Send response to client */ - if (strstr(url, API_URL)) - { - /* HTTP API request, send response */ - send_headers(f, 200, "OK", NULL, "text/html", -1, -1); + /* Read current state for all relays */ for (i=FIRST_RELAY; i<=last_relay; i++) { - fprintf(f, "Relay %d:%d
", i, rstate[i-1]); + get_relay(com_port, i, &rstate[i-1]); } - } - else - { - /* Web request */ - char cname[MAX_RELAY_CARD_NAME_LEN]; - get_relay_card_name(get_relay_card_type(), cname); - - web_page_header(f); - - /* Display relay status and controls on web page */ - fprintf(f, "\"Card\r\n"); - fprintf(f, "\r\n"); - fprintf(f, "\r\n"); - fprintf(f, "\r\n", - cname, com_port); - fprintf(f, "\r\n"); - for (i=FIRST_RELAY; i<=last_relay; i++) + + /* Send response to client */ + if (strstr(url, API_URL)) { - fprintf(f, "\r\n"); - fprintf(f, "\r\n", - i, rlabels[i-1]); - fprintf(f, "\r\n", - rstate[i-1]==ON?"red":"lightgrey", rstate[i-1]==ON?"ON":"OFF"); - fprintf(f, "\r\n", - RELAY_TAG, i, STATE_TAG, rstate[i-1]==ON?0:1, rstate[i-1]==ON?"off":"on"); - fprintf(f, "\r\n", - RELAY_TAG, i, STATE_TAG); + /* HTTP API request, send response */ + send_headers(fout, 200, "OK", NULL, "text/html", -1, -1); + for (i=FIRST_RELAY; i<=last_relay; i++) + { + fprintf(fout, "Relay %d:%d
", i, rstate[i-1]); + } + } + else + { + /* Web request */ + char cname[MAX_RELAY_CARD_NAME_LEN]; + get_relay_card_name(get_relay_card_type(), cname); + + web_page_header(fout); + + /* Display relay status and controls on web page */ + fprintf(fout, "\"Card\r\n"); + fprintf(fout, "
%s
on %s
Relay %d
%s
%s
\r\n"); + fprintf(fout, "\r\n"); + fprintf(fout, "\r\n", + cname, com_port); + fprintf(fout, "\r\n"); + for (i=FIRST_RELAY; i<=last_relay; i++) + { + fprintf(fout, "\r\n"); + fprintf(fout, "\r\n", + i, rlabels[i-1]); + fprintf(fout, "\r\n", + rstate[i-1]==ON?"red":"lightgrey", rstate[i-1]==ON?"ON":"OFF"); + fprintf(fout, "\r\n", + RELAY_TAG, i, STATE_TAG, rstate[i-1]==ON?0:1, rstate[i-1]==ON?"off":"on"); + fprintf(fout, "\r\n", + RELAY_TAG, i, STATE_TAG); + } + fprintf(fout, "
%s
on %s
Relay %d
%s
%s

\r\n"); + + web_page_footer(fout); } - fprintf(f, "
\r\n"); - - web_page_footer(f); } + + fclose(fout); + fclose(fin); + return 0; } @@ -538,10 +563,11 @@ int process_http_request(FILE *f) void print_usage() { relay_type_t rtype; - char cname[30]; + char cname[60]; + printf("crelay, version %s\n\n", VERSION); printf("This utility provides a unified way of controlling different types of relay cards.\n"); - printf("Currently supported relay cards:\n"); + printf("Supported relay cards:\n"); for(rtype=NO_RELAY_TYPE+1; rtype