#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 #include #include 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) { // перейти к запросу времени у пользователя 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); }