mirror of
https://github.com/dimoniche/solarium.vlad.git
synced 2026-01-30 21:13:31 +03:00
1138 lines
36 KiB
C
1138 lines
36 KiB
C
#include "httpd.h"
|
||
#include "httpd-fs.h"
|
||
#include "httpd-fsdata.h"
|
||
#include "httpd-cgi.h"
|
||
#include "http-strings.h"
|
||
#include "fram_map.h"
|
||
#include "fram.h"
|
||
#include "mode.h"
|
||
#include "app_serv.h"
|
||
#include "version.h"
|
||
#include <string.h>
|
||
#include <stdio.h>
|
||
#include <stddef.h>
|
||
|
||
HttpdState httpd_state;
|
||
extern char message_lines[2][128];
|
||
|
||
extern CPU_INT32U SystemTime;
|
||
extern CPU_INT32U http_last_status_time;
|
||
|
||
#define STATE_WAITING 0
|
||
#define STATE_OUTPUT 1
|
||
|
||
#define ISO_nl 0x0a
|
||
#define ISO_space 0x20
|
||
#define ISO_bang 0x21
|
||
#define ISO_percent 0x25
|
||
#define ISO_period 0x2e
|
||
#define ISO_slash 0x2f
|
||
#define ISO_colon 0x3a
|
||
|
||
int net_reconfigure_flag = 0;
|
||
|
||
static TDataDescStruct const* param_ptr = NULL;
|
||
static CPU_INT32U param_ind = -1;
|
||
|
||
|
||
static int http_replace_tag(char** template_ptr, char* buf, char* tag, char* value)
|
||
{
|
||
int len = 0;
|
||
char *tag_ptr = strstr(*template_ptr, tag);
|
||
if (tag_ptr)
|
||
{
|
||
len = tag_ptr - *template_ptr;
|
||
memcpy(buf, *template_ptr, len);
|
||
strcpy(&buf[len], value);
|
||
len += strlen(value);
|
||
}
|
||
*template_ptr = &tag_ptr[strlen(tag)];
|
||
return len;
|
||
}
|
||
|
||
///
|
||
static int http_prepare_file(char *filename)
|
||
{
|
||
if (strncmp(filename, "/index.html", strlen("/index.html")) == 0)
|
||
{
|
||
char *page_template = (char*)&data_index_html_template[strlen(data_index_html_template) + 1];
|
||
char *page_buffer = (char*)&data_html_page_buffer;
|
||
|
||
memset(data_html_page_buffer, 0, sizeof(data_html_page_buffer));
|
||
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$version}", DEVICE_FW_VERSION);
|
||
strcpy(page_buffer, page_template);
|
||
|
||
((struct httpd_fsdata_file_noconst*)&file_index_html)->len = strlen(data_html_page_buffer);
|
||
httpd_state.file.len = ((struct httpd_fsdata_file_noconst*)&file_index_html)->len;
|
||
}
|
||
else if (strncmp(filename, "/network.html", strlen("/network.html")) == 0)
|
||
{
|
||
NET_ERR err;
|
||
char *page_template = (char*)&data_network_html_template[strlen(data_network_html_template) + 1];
|
||
char *page_buffer = (char*)&data_html_page_buffer;
|
||
NET_IP_ADDR ip_addr;
|
||
CPU_INT08U mac_addr[6];
|
||
char str_value[32];
|
||
|
||
memset(data_html_page_buffer, 0, sizeof(data_html_page_buffer));
|
||
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$version}", DEVICE_FW_VERSION);
|
||
|
||
ReadArrayFram(offsetof(TFramMap, ip), sizeof(CPU_INT32U), (unsigned char*)&ip_addr);
|
||
NetASCII_IP_to_Str(ip_addr, (CPU_CHAR*)str_value, DEF_NO, &err);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$ip_addr}", str_value);
|
||
|
||
ReadArrayFram(offsetof(TFramMap, netmask), sizeof(CPU_INT32U), (unsigned char*)&ip_addr);
|
||
NetASCII_IP_to_Str(ip_addr, (CPU_CHAR*)str_value, DEF_NO, &err);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$net_mask}", str_value);
|
||
|
||
ReadArrayFram(offsetof(TFramMap, gateway), sizeof(CPU_INT32U), (unsigned char*)&ip_addr);
|
||
NetASCII_IP_to_Str(ip_addr, (CPU_CHAR*)str_value, DEF_NO, &err);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$gateway}", str_value);
|
||
|
||
ReadArrayFram(offsetof(TFramMap, mac_addr), 6, (unsigned char*)&mac_addr[0]);
|
||
NetASCII_MAC_to_Str((CPU_INT08U*)&mac_addr[0], (CPU_CHAR*)str_value, DEF_NO, &err);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$mac}", str_value);
|
||
|
||
strcpy(page_buffer, page_template);
|
||
((struct httpd_fsdata_file_noconst*)&file_network_html)->len = strlen(data_html_page_buffer);
|
||
httpd_state.file.len = ((struct httpd_fsdata_file_noconst*)&file_network_html)->len;
|
||
}
|
||
else if (strncmp(filename, "/reboot.html", strlen("/reboot.html")) == 0)
|
||
{
|
||
NET_ERR err;
|
||
char *page_template = (char*)&data_reboot_html_template[strlen(data_reboot_html_template) + 1];
|
||
char *page_buffer = (char*)&data_html_page_buffer;
|
||
NET_IP_ADDR ip_addr;
|
||
char str_value[32];
|
||
|
||
memset(data_html_page_buffer, 0, sizeof(data_html_page_buffer));
|
||
|
||
ReadArrayFram(offsetof(TFramMap, ip), sizeof(CPU_INT32U), (unsigned char*)&ip_addr);
|
||
NetASCII_IP_to_Str(ip_addr, (CPU_CHAR*)str_value, DEF_NO, &err);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$ip_addr}", str_value);
|
||
|
||
strcpy(page_buffer, page_template);
|
||
((struct httpd_fsdata_file_noconst*)&file_reboot_html)->len = strlen(data_html_page_buffer);
|
||
httpd_state.file.len = ((struct httpd_fsdata_file_noconst*)&file_reboot_html)->len;
|
||
}
|
||
else if (strncmp(filename, "/status.csv", strlen("/status.csv")) == 0)
|
||
{
|
||
char *page_template = (char*)&data_status_csv_template[strlen(data_status_csv_template) + 1];
|
||
char *page_buffer = (char*)&data_html_page_buffer;
|
||
char str[32];
|
||
|
||
memset(data_html_page_buffer, 0, sizeof(data_html_page_buffer));
|
||
|
||
strcpy(str, AppStatusStr(app_state.state));
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$state}", str);
|
||
sprintf(str, "%d", app_state.timetoend);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$timetoend}", str);
|
||
sprintf(str, "%d", app_state.userinputtime);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$timeinput}", str);
|
||
sprintf(str, "%d", app_state.userinputmoney);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$moneyinput}", str);
|
||
|
||
strcpy(page_buffer, page_template);
|
||
((struct httpd_fsdata_file_noconst*)&file_status_csv)->len = strlen(data_html_page_buffer);
|
||
httpd_state.file.len = ((struct httpd_fsdata_file_noconst*)&file_status_csv)->len;
|
||
|
||
http_last_status_time = SystemTime;
|
||
}
|
||
else if (strncmp(filename, "/param.csv", strlen("/param.csv")) == 0)
|
||
{
|
||
char *page_template = (char*)&data_param_csv_template[strlen(data_param_csv_template) + 1];
|
||
char *page_buffer = (char*)&data_html_page_buffer;
|
||
char str[48];
|
||
|
||
memset(data_html_page_buffer, 0, sizeof(data_html_page_buffer));
|
||
|
||
if (param_ptr != NULL)
|
||
{
|
||
GetDescIdStr((TDataDescStruct const*)param_ptr, str);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$param}", str);
|
||
sprintf(str, "%d", param_ind);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$index}", str);
|
||
GetDataStr((TDataDescStruct const*)param_ptr, (CPU_INT08U*)str, param_ind, DATA_FLAG_DIRECT_INDEX);
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$value}", str);
|
||
}
|
||
else
|
||
{
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$param}", "NULL");
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$index}", "0");
|
||
page_buffer += http_replace_tag(&page_template, page_buffer, "{$value}", "0");
|
||
}
|
||
|
||
strcpy(page_buffer, page_template);
|
||
((struct httpd_fsdata_file_noconst*)&file_param_csv)->len = strlen(data_html_page_buffer);
|
||
httpd_state.file.len = ((struct httpd_fsdata_file_noconst*)&file_param_csv)->len;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
///
|
||
static int http_process_post_request(char* path, char *post_data, int len)
|
||
{
|
||
static const char cmd_header1[] = "Command;Password;User_ID;BalanceTime;BalanceMoney\r\n";
|
||
static const char cmd_header2[] = "Command;Password;User_ID;Line1;Line2\r\n";
|
||
static const char cmd_header2_[] = "Command;Password;User_ID\r\n";
|
||
static const char cmd_header3[] = "Command;Password;Param;Index;Value\r\n";
|
||
static const char cmd_header4[] = "Command;Password;Param;Index\r\n";
|
||
static const char cmd_header5[] = "Command;Password\r\n";
|
||
static const char user_req_time_cmd[] = "user_req_time";
|
||
static const char start_cmd[] = "start";
|
||
static const char cansel_cmd[] = "cansel";
|
||
static const char abort_cmd[] = "abort";
|
||
static const char get_param_cmd[] = "get_param";
|
||
static const char set_param_cmd[] = "set_param";
|
||
|
||
if ((strcmp(path, "/command") == 0) || (strcmp(path, "/command ") == 0))
|
||
{
|
||
char *ptr;
|
||
|
||
// "Command;Password;User_ID;BalanceTime;BalanceMoney\r\n"
|
||
ptr = strstr(post_data, cmd_header1);
|
||
if (ptr == post_data)
|
||
{
|
||
ptr = post_data + strlen(cmd_header1);
|
||
|
||
if (strncmp(ptr, user_req_time_cmd, strlen(user_req_time_cmd)) == 0)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int pass, user_id, time, money;
|
||
|
||
if ((GetMode() != MODE_WORK) && (app_state.state != APP_STATE_IDLE))
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (sscanf(ptr, "user_req_time;%d;%d;%d;%d\r\n", &pass, &user_id, &time, &money) == 4)
|
||
{
|
||
CPU_INT32U pass_ee;
|
||
GetData(&PassDesc, &pass_ee, 0, DATA_FLAG_SYSTEM_INDEX);
|
||
|
||
if (pass_ee != pass)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (time > 0 || money > 0)
|
||
{
|
||
app_state.user_id = user_id;
|
||
app_state.timefromserver = time;
|
||
app_state.moneyfromserver = money;
|
||
PostUserEvent(EVENT_REQUEST_USER_INPUT);
|
||
OSTimeDly(10);
|
||
strcpy(path, "/status");
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
PostUserEvent(EVENT_SHOW_ZERO_MONEY);
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// "Command;Password;User_ID;Line1;Line2\r\n"
|
||
ptr = strstr(post_data, cmd_header2);
|
||
if (ptr == post_data)
|
||
{
|
||
ptr = post_data + strlen(cmd_header2);
|
||
|
||
if (strncmp(ptr, cansel_cmd, strlen(cansel_cmd)) == 0)
|
||
{
|
||
int pass, user_id;
|
||
|
||
if (app_state.state != APP_STATE_WAITING_ACK)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (strlen(ptr) > 128)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (sscanf(ptr, "cansel;%d;%d;%s\r\n", &pass, &user_id, message_lines[0]) == 3)
|
||
{
|
||
CPU_INT32U pass_ee;
|
||
GetData(&PassDesc, &pass_ee, 0, DATA_FLAG_SYSTEM_INDEX);
|
||
|
||
if (pass_ee != pass)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
ptr = strstr(message_lines[0], ";");
|
||
if (!ptr)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
*ptr++ = '\0';
|
||
strncpy(message_lines[1], ptr, 32);
|
||
|
||
app_state.user_id = user_id;
|
||
PostUserEvent(EVENT_NACK_USER_INPUT);
|
||
OSTimeDly(10);
|
||
strcpy(path, "/status");
|
||
return 0;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// "Command;Password;User_ID\r\n"
|
||
ptr = strstr(post_data, cmd_header2_);
|
||
if (ptr == post_data)
|
||
{
|
||
ptr = post_data + strlen(cmd_header2_);
|
||
|
||
if (strncmp(ptr, start_cmd, strlen(start_cmd)) == 0)
|
||
{
|
||
int pass, user_id;
|
||
|
||
if (app_state.state != APP_STATE_WAITING_ACK)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (sscanf(ptr, "start;%d;%d\r\n", &pass, &user_id) == 2)
|
||
{
|
||
CPU_INT32U pass_ee;
|
||
GetData(&PassDesc, &pass_ee, 0, DATA_FLAG_SYSTEM_INDEX);
|
||
|
||
if (pass_ee != pass)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
app_state.user_id = user_id;
|
||
PostUserEvent(EVENT_ACK_USER_INPUT);
|
||
OSTimeDly(10);
|
||
strcpy(path, "/status");
|
||
return 0;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// "Command;Password;Param;Index;Value\r\n"
|
||
ptr = strstr(post_data, cmd_header3);
|
||
if (ptr == post_data)
|
||
{
|
||
ptr = post_data + strlen(cmd_header3);
|
||
|
||
if (strncmp(ptr, set_param_cmd, strlen(set_param_cmd)) == 0)
|
||
{
|
||
int pass;
|
||
int p_ind;
|
||
char p_str[64];
|
||
char value_str[32];
|
||
char *ptmp;
|
||
if (sscanf(ptr, "set_param;%d;%s\r\n", &pass, p_str) == 2)
|
||
{
|
||
CPU_INT32U pass_ee;
|
||
GetData(&PassDesc, &pass_ee, 0, DATA_FLAG_SYSTEM_INDEX);
|
||
|
||
if (pass_ee != pass)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
ptmp = strchr(p_str, ';');
|
||
if (!ptmp)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (sscanf(ptmp, ";%d;%s", &p_ind, value_str) != 2)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
TDataDescStruct const* desc;
|
||
ptmp = strchr(p_str, ';');
|
||
if (!ptmp)
|
||
{
|
||
return -1;
|
||
}
|
||
*ptmp = '\0';
|
||
GetDescByIdStr(p_str, (TDataDescStruct const**)&desc);
|
||
if (desc != NULL)
|
||
{
|
||
CPU_INT32U tmp_ind = GetDataValidIndex(desc, p_ind);
|
||
if (tmp_ind == p_ind)
|
||
{
|
||
if (SetDataFromStr(desc, value_str, p_ind, DATA_FLAG_DIRECT_INDEX) != DATA_OK)
|
||
{
|
||
param_ptr = NULL;
|
||
param_ind = 0;
|
||
return -1;
|
||
}
|
||
}
|
||
param_ptr = desc;
|
||
param_ind = tmp_ind;
|
||
}
|
||
else
|
||
{
|
||
param_ptr = NULL;
|
||
param_ind = 0;
|
||
}
|
||
|
||
strcpy(path, "/param.csv");
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
// "Command;Password;Param;Index\r\n"
|
||
ptr = strstr(post_data, cmd_header4);
|
||
if (ptr == post_data)
|
||
{
|
||
ptr = post_data + strlen(cmd_header4);
|
||
|
||
if (strncmp(ptr, get_param_cmd, strlen(get_param_cmd)) == 0)
|
||
{
|
||
int pass;
|
||
int p_ind;
|
||
char p_str[64];
|
||
char *ptmp;
|
||
|
||
if (sscanf(ptr, "get_param;%d;%s", &pass, p_str) == 2)
|
||
{
|
||
CPU_INT32U pass_ee;
|
||
GetData(&PassDesc, &pass_ee, 0, DATA_FLAG_SYSTEM_INDEX);
|
||
|
||
if (pass_ee != pass)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
ptmp = strchr(p_str, ';');
|
||
if (!ptmp)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (sscanf(ptmp, ";%d", &p_ind) != 1)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
*ptmp = '\0';
|
||
|
||
TDataDescStruct const* desc;
|
||
GetDescByIdStr(p_str, (TDataDescStruct const**)&desc);
|
||
if (desc != NULL)
|
||
{
|
||
param_ptr = desc;
|
||
param_ind = GetDataValidIndex(desc, p_ind);
|
||
}
|
||
else
|
||
{
|
||
param_ptr = NULL;
|
||
param_ind = 0;
|
||
}
|
||
|
||
strcpy(path, "/param.csv");
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
// "Command;Password\r\n"
|
||
ptr = strstr(post_data, cmd_header5);
|
||
if (ptr == post_data)
|
||
{
|
||
ptr = post_data + strlen(cmd_header5);
|
||
|
||
if (strncmp(ptr, abort_cmd, strlen(abort_cmd)) == 0)
|
||
{
|
||
int pass;
|
||
|
||
if (sscanf(ptr, "abort;%d\r\n", &pass) == 1)
|
||
{
|
||
CPU_INT32U pass_ee;
|
||
GetData(&PassDesc, &pass_ee, 0, DATA_FLAG_SYSTEM_INDEX);
|
||
|
||
if (pass_ee != pass)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
PostUserEvent(EVENT_ABORT_OPERATIONS);
|
||
OSTimeDly(10);
|
||
strcpy(path, "/status");
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
if ((strcmp(path, "/netsettings") == 0) || (strcmp(path, "/netsettings ") == 0))
|
||
{
|
||
int ip0, ip1, ip2, ip3;
|
||
CPU_INT32U new_ip, new_mask, new_gw;
|
||
CPU_INT08U new_mac[6];
|
||
|
||
if (strstr(post_data, "ApplyButton=") == NULL)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
ReadArrayFram(offsetof(TFramMap, mac_addr), 6, (unsigned char*)&new_mac[0]);
|
||
ReadArrayFram(offsetof(TFramMap, ip), sizeof(CPU_INT32U), (unsigned char*)&new_ip);
|
||
ReadArrayFram(offsetof(TFramMap, netmask), sizeof(CPU_INT32U), (unsigned char*)&new_mask);
|
||
ReadArrayFram(offsetof(TFramMap, gateway), sizeof(CPU_INT32U), (unsigned char*)&new_gw);
|
||
|
||
char *pch = strstr(post_data, "ipAddrField=");
|
||
if (pch)
|
||
{
|
||
if (sscanf(&pch[strlen("ipAddrField=")], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3) != 4)
|
||
{
|
||
return -1;
|
||
}
|
||
if ((ip0 >= 0) && (ip0 <= 255) && (ip1 >= 0) && (ip1 <= 255) && (ip2 >= 0) && (ip2 <= 255) && (ip3 >= 0) && (ip3 <= 255))
|
||
{
|
||
new_ip = ((CPU_INT32U)ip0 << 24) | ((CPU_INT32U)ip1 << 16) | ((CPU_INT32U)ip2 << 8) | ((CPU_INT32U)ip3 << 0);
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
pch = strstr(post_data, "NetMask=");
|
||
if (pch)
|
||
{
|
||
if (sscanf(&pch[strlen("NetMask=")], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3) != 4)
|
||
{
|
||
return -1;
|
||
}
|
||
if ((ip0 >= 0) && (ip0 <= 255) && (ip1 >= 0) && (ip1 <= 255) && (ip2 >= 0) && (ip2 <= 255) && (ip3 >= 0) && (ip3 <= 255))
|
||
{
|
||
new_mask = ((CPU_INT32U)ip0 << 24) | ((CPU_INT32U)ip1 << 16) | ((CPU_INT32U)ip2 << 8) | ((CPU_INT32U)ip3 << 0);
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
pch = strstr(post_data, "Gateway=");
|
||
if (pch)
|
||
{
|
||
if (sscanf(&pch[strlen("Gateway=")], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3) != 4)
|
||
{
|
||
return -1;
|
||
}
|
||
if ((ip0 >= 0) && (ip0 <= 255) && (ip1 >= 0) && (ip1 <= 255) && (ip2 >= 0) && (ip2 <= 255) && (ip3 >= 0) && (ip3 <= 255))
|
||
{
|
||
new_gw = ((CPU_INT32U)ip0 << 24) | ((CPU_INT32U)ip1 << 16) | ((CPU_INT32U)ip2 << 8) | ((CPU_INT32U)ip3 << 0);
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
pch = strstr(post_data, "MAC=");
|
||
if (pch)
|
||
{
|
||
NET_ERR err;
|
||
char mac_str[48];
|
||
strncpy(mac_str, &pch[strlen("MAC=")], 48);
|
||
char *ptmp = strstr(mac_str, "%3A");
|
||
while (ptmp)
|
||
{
|
||
*ptmp = ':';
|
||
strcpy(ptmp + 1, ptmp + strlen("%3A"));
|
||
ptmp = strstr(ptmp, "%3A");
|
||
}
|
||
mac_str[17] = '\0';
|
||
NetASCII_Str_to_MAC((CPU_CHAR*)mac_str, &new_mac[0], &err);
|
||
if (err != NET_ASCII_ERR_NONE)
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
WriteArrayFram(offsetof(TFramMap, ip), sizeof(CPU_INT32U), (unsigned char*)&new_ip);
|
||
WriteArrayFram(offsetof(TFramMap, netmask), sizeof(CPU_INT32U), (unsigned char*)&new_mask);
|
||
WriteArrayFram(offsetof(TFramMap, gateway), sizeof(CPU_INT32U), (unsigned char*)&new_gw);
|
||
WriteArrayFram(offsetof(TFramMap, mac_addr), 6, (unsigned char*)&new_mac[0]);
|
||
|
||
net_reconfigure_flag = 1;
|
||
strcpy(path, "/reboot.html");
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
///
|
||
int httpd_write_socket_data(void *state, char* data, int len)
|
||
{
|
||
CPU_INT32U time_stamp = OSTimeGet();
|
||
HttpdState *s = (HttpdState*)state;
|
||
int tx_ctr = 0;
|
||
while (tx_ctr < len)
|
||
{
|
||
NET_ERR err;
|
||
int tx_size = NetSock_TxData(s->sock_req, &data[tx_ctr], len - tx_ctr, NET_SOCK_FLAG_TX_NO_BLOCK, &err);
|
||
switch (err)
|
||
{
|
||
case NET_SOCK_ERR_NONE:
|
||
tx_ctr += tx_size;
|
||
time_stamp = OSTimeGet();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
OSTimeDly(1);
|
||
if (OSTimeGet() - time_stamp > 1000)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
return tx_ctr;
|
||
}
|
||
|
||
///
|
||
static unsigned short generate_part_of_file(void *state)
|
||
{
|
||
HttpdState *s = (HttpdState*)state;
|
||
|
||
if (s->file.len > HTTPD_OUTPUT_BUF_SIZE)
|
||
{
|
||
s->len = HTTPD_OUTPUT_BUF_SIZE;
|
||
}
|
||
else
|
||
{
|
||
s->len = s->file.len;
|
||
}
|
||
memcpy(&s->outputbuf, s->file.data, s->len);
|
||
|
||
return s->len;
|
||
}
|
||
|
||
///
|
||
static char send_file(void *state)
|
||
{
|
||
HttpdState *s = (HttpdState*)state;
|
||
do
|
||
{
|
||
if (generate_part_of_file(state) <= 0) break;
|
||
if (httpd_write_socket_data(s, s->outputbuf, s->len) != s->len) break;
|
||
s->file.len -= s->len;
|
||
s->file.data += s->len;
|
||
} while(s->file.len > 0);
|
||
return 0;
|
||
}
|
||
|
||
///
|
||
static char send_part_of_file(void *state)
|
||
{
|
||
HttpdState *s = (HttpdState*)state;
|
||
httpd_write_socket_data(s, s->file.data, s->len);
|
||
return 0;
|
||
}
|
||
|
||
///
|
||
static void next_scriptstate(HttpdState *s)
|
||
{
|
||
char *p;
|
||
p = strchr(s->scriptptr, ISO_nl) + 1;
|
||
s->scriptlen -= (unsigned short)(p - s->scriptptr);
|
||
s->scriptptr = p;
|
||
}
|
||
|
||
///
|
||
static char handle_script(HttpdState *s)
|
||
{
|
||
char *ptr;
|
||
|
||
while(s->file.len > 0)
|
||
{
|
||
|
||
// Check if we should start executing a script.
|
||
if (*s->file.data == ISO_percent && *(s->file.data + 1) == ISO_bang)
|
||
{
|
||
s->scriptptr = s->file.data + 3;
|
||
s->scriptlen = s->file.len - 3;
|
||
if(*(s->scriptptr - 1) == ISO_colon)
|
||
{
|
||
httpd_fs_open(s->scriptptr + 1, &s->file);
|
||
send_file(s);
|
||
}
|
||
else
|
||
{
|
||
//httpd_cgi(s->scriptptr)(s, s->scriptptr);
|
||
}
|
||
next_scriptstate(s);
|
||
|
||
// The script is over, so we reset the pointers and continue sending the rest of the file.
|
||
s->file.data = s->scriptptr;
|
||
s->file.len = s->scriptlen;
|
||
}
|
||
else
|
||
{
|
||
// See if we find the start of script marker in the block of HTML to be sent.
|
||
if(s->file.len > HTTPD_OUTPUT_BUF_SIZE)
|
||
{
|
||
s->len = HTTPD_OUTPUT_BUF_SIZE;
|
||
}
|
||
else
|
||
{
|
||
s->len = s->file.len;
|
||
}
|
||
|
||
if (*s->file.data == ISO_percent)
|
||
{
|
||
ptr = strchr(s->file.data + 1, ISO_percent);
|
||
}
|
||
else
|
||
{
|
||
ptr = strchr(s->file.data, ISO_percent);
|
||
}
|
||
|
||
if (ptr != NULL && ptr != s->file.data)
|
||
{
|
||
s->len = (int)(ptr - s->file.data);
|
||
if (s->len >= HTTPD_OUTPUT_BUF_SIZE)
|
||
{
|
||
s->len = HTTPD_OUTPUT_BUF_SIZE;
|
||
}
|
||
}
|
||
send_part_of_file(s);
|
||
s->file.data += s->len;
|
||
s->file.len -= s->len;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
static char send_headers(HttpdState *s, const char *statushdr)
|
||
{
|
||
char *ptr;
|
||
|
||
httpd_write_socket_data(s, (char *)statushdr, strlen(statushdr));
|
||
|
||
ptr = strrchr(s->filename, ISO_period);
|
||
if (ptr == NULL)
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_binary, strlen(http_content_type_binary));
|
||
}
|
||
else if (strncmp(http_html, ptr, 5) == 0 || strncmp(http_shtml, ptr, 6) == 0)
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_html, strlen(http_content_type_html));
|
||
}
|
||
else if (strncmp(http_css, ptr, 4) == 0)
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_css, strlen(http_content_type_css));
|
||
}
|
||
else if (strncmp(http_png, ptr, 4) == 0)
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_png, strlen(http_content_type_png));
|
||
}
|
||
else if (strncmp(http_gif, ptr, 4) == 0)
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_gif, strlen(http_content_type_gif));
|
||
}
|
||
else if (strncmp(http_csv, ptr, 4) == 0)
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_csv, strlen(http_content_type_csv));
|
||
}
|
||
else if (strncmp(http_jpg, ptr, 4) == 0)
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_jpg, strlen(http_content_type_jpg));
|
||
}
|
||
else
|
||
{
|
||
httpd_write_socket_data(s, (char *)http_content_type_plain, strlen(http_content_type_plain));
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
///
|
||
void httpd_close_socket(HttpdState *s)
|
||
{
|
||
NET_ERR err;
|
||
//OSTimeDly(10);
|
||
NetSock_Close(s->sock_req, &err);
|
||
NetSock_Close(s->sock_listen, &err);
|
||
}
|
||
|
||
///
|
||
static char handle_output(HttpdState *s)
|
||
{
|
||
char *ptr;
|
||
|
||
if ((strcmp(s->filename, "/status") == 0) || (strcmp(s->filename, "/status ") == 0))
|
||
{
|
||
strcpy(s->filename, "/status.csv");
|
||
}
|
||
|
||
if (!httpd_fs_open(s->filename, &s->file))
|
||
{
|
||
httpd_fs_open(http_404_html, &s->file);
|
||
strcpy(s->filename, http_404_html);
|
||
send_headers(s, http_header_404);
|
||
send_file(s);
|
||
}
|
||
else
|
||
{
|
||
send_headers(s, http_header_200);
|
||
http_prepare_file(s->filename);
|
||
ptr = strchr(s->filename, ISO_period);
|
||
if (ptr != NULL && strncmp(ptr, http_shtml, 6) == 0)
|
||
{
|
||
handle_script(s);
|
||
}
|
||
else
|
||
{
|
||
send_file(s);
|
||
}
|
||
}
|
||
OSTimeDly(5);
|
||
httpd_close_socket(s);
|
||
return 0;
|
||
}
|
||
|
||
///
|
||
static NET_ERR socket_read_char(HttpdState *s, char* c, int timeout)
|
||
{
|
||
NET_ERR err = NET_SOCK_ERR_NONE;
|
||
CPU_INT32U time_stamp = OSTimeGet();
|
||
|
||
do
|
||
{
|
||
NET_SOCK_RTN_CODE ret_code;
|
||
|
||
if (NetNIC_ConnStatusGet() != DEF_ON)
|
||
{
|
||
return NET_SOCK_ERR_FAULT;
|
||
}
|
||
|
||
if (s->inputbuf_ctr > 0)
|
||
{
|
||
*c = s->inputbuf_raw[s->inputbuf_ptr++];
|
||
s->inputbuf_ctr--;
|
||
return NET_SOCK_ERR_NONE;
|
||
}
|
||
|
||
ret_code = NetSock_RxData(s->sock_req, s->inputbuf_raw, HTTPD_INPUT_BUF_SIZE, NET_SOCK_FLAG_RX_NO_BLOCK, &err);
|
||
switch (err)
|
||
{
|
||
case NET_SOCK_ERR_NONE:
|
||
if ((ret_code > 0) &&(ret_code <= HTTPD_INPUT_BUF_SIZE))
|
||
{
|
||
s->inputbuf_ctr = ret_code;
|
||
s->inputbuf_ptr = 0;
|
||
}
|
||
break;
|
||
case NET_SOCK_ERR_RX_Q_EMPTY:
|
||
if (OSTimeGet() - time_stamp < timeout)
|
||
{
|
||
err = NET_SOCK_ERR_NONE;
|
||
}
|
||
OSTimeDly(1);
|
||
break;
|
||
case NET_SOCK_ERR_INVALID_DATA_SIZE:
|
||
case NET_ERR_INIT_INCOMPLETE:
|
||
case NET_SOCK_ERR_NULL_PTR:
|
||
case NET_SOCK_ERR_NULL_SIZE:
|
||
case NET_SOCK_ERR_NOT_USED:
|
||
case NET_SOCK_ERR_CLOSED:
|
||
case NET_SOCK_ERR_FAULT:
|
||
case NET_SOCK_ERR_INVALID_SOCK:
|
||
case NET_SOCK_ERR_INVALID_FAMILY:
|
||
case NET_SOCK_ERR_INVALID_PROTOCOL:
|
||
case NET_SOCK_ERR_INVALID_TYPE:
|
||
case NET_SOCK_ERR_INVALID_STATE:
|
||
case NET_SOCK_ERR_INVALID_OP:
|
||
case NET_SOCK_ERR_INVALID_FLAG:
|
||
case NET_SOCK_ERR_INVALID_ADDR_LEN:
|
||
case NET_SOCK_ERR_RX_Q_CLOSED:
|
||
case NET_ERR_RX:
|
||
case NET_CONN_ERR_INVALID_CONN:
|
||
case NET_CONN_ERR_NOT_USED:
|
||
case NET_CONN_ERR_NULL_PTR:
|
||
case NET_CONN_ERR_INVALID_ADDR_LEN:
|
||
case NET_CONN_ERR_ADDR_NOT_USED:
|
||
case NET_OS_ERR_LOCK:
|
||
break;
|
||
default:
|
||
err = NET_ERR_RX;
|
||
break;
|
||
}
|
||
|
||
if (OSTimeGet() - time_stamp >= timeout)
|
||
{
|
||
return NET_SOCK_ERR_RX_Q_EMPTY;
|
||
}
|
||
|
||
} while (err == NET_SOCK_ERR_NONE);
|
||
|
||
return err;
|
||
}
|
||
|
||
///
|
||
static int socket_read_to(HttpdState *s, char sym, int timeout)
|
||
{
|
||
char c;
|
||
int ctr = 0;
|
||
while (socket_read_char(s, &c, timeout) == NET_SOCK_ERR_NONE)
|
||
{
|
||
s->inputbuf[ctr++] = c;
|
||
if (c == sym)
|
||
{
|
||
s->inputbuf[ctr] = 0;
|
||
return 0;
|
||
}
|
||
if (ctr >= HTTPD_INPUT_BUF_SIZE - 1)
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
///
|
||
static int socket_read(HttpdState *s, int len, int timeout)
|
||
{
|
||
char c;
|
||
int ctr = 0;
|
||
while (socket_read_char(s, &c, timeout) == NET_SOCK_ERR_NONE)
|
||
{
|
||
s->inputbuf[ctr++] = c;
|
||
if (ctr >= len)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
return ctr;
|
||
}
|
||
|
||
///
|
||
static char handle_input(HttpdState *s)
|
||
{
|
||
int post_req = 0;
|
||
int has_content = 0;
|
||
int content_len = 0;
|
||
|
||
socket_read_to(s, ISO_space, HTTPS_RX_TIMEOUT);
|
||
|
||
if (strncmp(s->inputbuf, http_post, 5) == 0)
|
||
{
|
||
post_req = 1;
|
||
}
|
||
|
||
if ((!post_req) && (strncmp(s->inputbuf, http_get, 4) != 0))
|
||
{
|
||
httpd_close_socket(s);
|
||
return -1;
|
||
}
|
||
|
||
socket_read_to(s, ISO_space, 0);
|
||
|
||
if (s->inputbuf[0] != ISO_slash)
|
||
{
|
||
httpd_close_socket(s);
|
||
return -1;
|
||
}
|
||
|
||
if (s->inputbuf[1] == ISO_space)
|
||
{
|
||
strncpy(s->filename, http_index_html, sizeof(s->filename));
|
||
}
|
||
else
|
||
{
|
||
strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
|
||
}
|
||
|
||
s->state = STATE_OUTPUT;
|
||
|
||
while (1)
|
||
{
|
||
if (socket_read_to(s, ISO_nl, 0) != 0)
|
||
{
|
||
break;
|
||
}
|
||
|
||
if (post_req)
|
||
{
|
||
if (strncmp(s->inputbuf, http_content_lenght, 16) == 0)
|
||
{
|
||
if (sscanf(&s->inputbuf[16], "%d\r\n", &content_len) == 1)
|
||
{
|
||
has_content = 1;
|
||
if (content_len >= HTTPD_INPUT_BUF_SIZE - 1)
|
||
{
|
||
httpd_close_socket(s);
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
else if (strncmp(s->inputbuf, "\r\n", 2) == 0)
|
||
{
|
||
if (has_content && content_len)
|
||
{
|
||
if (socket_read(s, content_len, HTTPS_RX_TIMEOUT) != content_len)
|
||
{
|
||
httpd_close_socket(s);
|
||
return -1;
|
||
}
|
||
s->inputbuf[content_len] = 0;
|
||
if (http_process_post_request(s->filename, s->inputbuf, content_len) == 0)
|
||
{
|
||
|
||
}
|
||
else
|
||
{
|
||
strncpy(s->filename, "error", sizeof(s->filename));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
///
|
||
static void handle_connection(HttpdState *s)
|
||
{
|
||
handle_input(s);
|
||
if (s->state == STATE_OUTPUT)
|
||
{
|
||
handle_output(s);
|
||
}
|
||
}
|
||
|
||
///
|
||
void HttpdTask(void *p_arg)
|
||
{
|
||
NET_SOCK_ADDR_IP server_sock_addr_ip;
|
||
NET_SOCK_ADDR_LEN server_sock_addr_ip_size;
|
||
NET_SOCK_ADDR_IP client_sock_addr_ip;
|
||
NET_SOCK_ADDR_LEN client_sock_addr_ip_size;
|
||
CPU_BOOLEAN attempt_conn;
|
||
NET_ERR err;
|
||
|
||
while (1)
|
||
{
|
||
OSTimeDly(1);
|
||
|
||
if (NetNIC_ConnStatusGet() != DEF_ON)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
httpd_state.sock_listen = NetSock_Open( NET_SOCK_ADDR_FAMILY_IP_V4, NET_SOCK_TYPE_STREAM, NET_SOCK_PROTOCOL_TCP, &err);
|
||
if (err != NET_SOCK_ERR_NONE)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
server_sock_addr_ip_size = sizeof(server_sock_addr_ip);
|
||
Mem_Clr((void*)&server_sock_addr_ip, (CPU_SIZE_T)server_sock_addr_ip_size);
|
||
server_sock_addr_ip.Family = NET_SOCK_ADDR_FAMILY_IP_V4;
|
||
server_sock_addr_ip.Addr = NET_UTIL_HOST_TO_NET_32(NET_SOCK_ADDR_IP_WILD_CARD);
|
||
server_sock_addr_ip.Port = NET_UTIL_HOST_TO_NET_16(80);
|
||
|
||
NetSock_Bind((NET_SOCK_ID )httpd_state.sock_listen, (NET_SOCK_ADDR *)&server_sock_addr_ip, (NET_SOCK_ADDR_LEN)NET_SOCK_ADDR_SIZE, (NET_ERR *)&err);
|
||
if (err != NET_SOCK_ERR_NONE)
|
||
{
|
||
NetSock_Close(httpd_state.sock_listen, &err);
|
||
httpd_state.sock_listen = -1;
|
||
continue;
|
||
}
|
||
|
||
NetSock_Listen(httpd_state.sock_listen, 1, &err);
|
||
if (err != NET_SOCK_ERR_NONE)
|
||
{
|
||
NetSock_Close(httpd_state.sock_listen, &err);
|
||
httpd_state.sock_listen = -1;
|
||
continue;
|
||
}
|
||
|
||
do
|
||
{
|
||
client_sock_addr_ip_size = sizeof(client_sock_addr_ip);
|
||
|
||
if (NetNIC_ConnStatusGet() != DEF_ON)
|
||
{
|
||
err = NET_SOCK_ERR_NONE_AVAIL;
|
||
break;
|
||
}
|
||
|
||
OSTimeDly(1);
|
||
|
||
httpd_state.sock_req = NetSock_Accept((NET_SOCK_ID )httpd_state.sock_listen, (NET_SOCK_ADDR *)&client_sock_addr_ip, (NET_SOCK_ADDR_LEN *)&client_sock_addr_ip_size, (NET_ERR *)&err);
|
||
switch (err)
|
||
{
|
||
case NET_SOCK_ERR_NONE:
|
||
attempt_conn = DEF_NO;
|
||
break;
|
||
case NET_ERR_INIT_INCOMPLETE:
|
||
case NET_SOCK_ERR_NULL_PTR:
|
||
case NET_SOCK_ERR_NONE_AVAIL:
|
||
case NET_SOCK_ERR_CONN_ACCEPT_Q_NONE_AVAIL:
|
||
case NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT:
|
||
case NET_OS_ERR_LOCK:
|
||
attempt_conn = DEF_YES;
|
||
break;
|
||
|
||
default:
|
||
attempt_conn = DEF_NO;
|
||
break;
|
||
}
|
||
} while (attempt_conn == DEF_YES);
|
||
|
||
if (err != NET_SOCK_ERR_NONE)
|
||
{
|
||
httpd_close_socket(&httpd_state);
|
||
memset(&httpd_state, 0 , sizeof(httpd_state));
|
||
httpd_state.sock_req = -1;
|
||
httpd_state.sock_listen = -1;
|
||
continue;
|
||
}
|
||
|
||
httpd_state.state = STATE_WAITING;
|
||
handle_connection(&httpd_state);
|
||
memset(&httpd_state, 0 , sizeof(httpd_state));
|
||
httpd_state.sock_req = -1;
|
||
httpd_state.sock_listen = -1;
|
||
|
||
if (net_reconfigure_flag)
|
||
{
|
||
PostUserEvent(EVENT_SYSTEM_REBOOT);
|
||
}
|
||
}
|
||
}
|
||
|
||
///
|
||
void httpd_init(void)
|
||
{
|
||
INT8U err;
|
||
static OS_STK HttpdTaskStk[HTTPD_TASK_STK_SIZE];
|
||
|
||
memset(&httpd_state, 0 , sizeof(httpd_state));
|
||
httpd_state.sock_req = -1;
|
||
httpd_state.sock_listen = -1;
|
||
|
||
OSTaskCreate(HttpdTask, (void *)0, (OS_STK *)&HttpdTaskStk[HTTPD_TASK_STK_SIZE-1], HTTPD_TASK_PRIO);
|
||
OSTaskNameSet(HTTPD_TASK_PRIO, "HTTPD Task", &err);
|
||
}
|