#include "http_server.h" // HTML页面模板 #include "html_files.h" // 解析HTTP请求 static void parse_http_request(uint8_t* buffer, uint16_t length, http_request* req) { char* method = strtok((char*)buffer, " "); char* uri = strtok(NULL, " "); if(strcmp(method, "GET") == 0) { req->method = HTTP_GET; } else if(strcmp(method, "POST") == 0) { req->method = HTTP_POST; } else { req->method = HTTP_UNKNOWN; } strncpy(req->uri, uri, MAX_URI_SIZE); // 如果是POST请求,查找请求体 if(req->method == HTTP_POST) { char* body = strstr((char*)buffer, "\r\n\r\n"); if(body) { body += 4; req->body = (uint8_t*)body; req->body_length = length - (body - (char*)buffer); } } } // 发送HTTP响应 static int send_all(uint8_t sn, const uint8_t* data, uint16_t length) { int total_sent = 0; while (total_sent < length) { int sent = send(sn, data + total_sent, length - total_sent); if (sent <= 0) { return -1; // 发送错误 } total_sent += sent; } return total_sent; } static void send_chunked_response_header(uint8_t sn) { const char* header = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Transfer-Encoding: chunked\r\n" "\r\n"; send_all(sn, (uint8_t*)header, strlen(header)); } static void send_chunk(uint8_t sn, const char* data, uint16_t length) { char chunk_header[10]; sprintf(chunk_header, "%X\r\n", length); send_all(sn, (uint8_t*)chunk_header, strlen(chunk_header)); send_all(sn, (uint8_t*)data, length); send_all(sn, (uint8_t*)"\r\n", 2); } static void send_chunk_end(uint8_t sn) { send_all(sn, (uint8_t*)"0\r\n\r\n", 5); } #define CHUNK_SIZE 512 // 处理配置页面请求 static void handle_config_page(uint8_t sn) { char buffer[CHUNK_SIZE]; bool is_connected = (wizphy_getphylink() == PHY_LINK_ON); char* link_status = is_connected ? "Connected" : "Disconnected"; char* status_class = is_connected ? "connected" : "disconnected"; // 先将完整的HTML内容格式化到一个临时缓冲区 char full_page[8192]; // 确保足够大 int total_len = sprintf(full_page, index_html, gWIZNETINFO.mac[0], gWIZNETINFO.mac[1], gWIZNETINFO.mac[2], gWIZNETINFO.mac[3], gWIZNETINFO.mac[4], gWIZNETINFO.mac[5], gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], gWIZNETINFO.sn[0], gWIZNETINFO.sn[1], gWIZNETINFO.sn[2], gWIZNETINFO.sn[3], gWIZNETINFO.gw[0], gWIZNETINFO.gw[1], gWIZNETINFO.gw[2], gWIZNETINFO.gw[3], status_class, link_status); // 发送响应头 send_chunked_response_header(sn); // 分块发送内容 int sent = 0; while (sent < total_len) { int chunk_len = (total_len - sent) > CHUNK_SIZE ? CHUNK_SIZE : (total_len - sent); memcpy(buffer, full_page + sent, chunk_len); send_chunk(sn, buffer, chunk_len); sent += chunk_len; } // 发送结束块 send_chunk_end(sn); } // 解析并更新网络配置 static void update_network_config(const char* body) { char mac[18], ip[16], subnet[16], gateway[16]; uint32_t mac_values[6], ip_values[4], subnet_values[4], gateway_values[4]; if(sscanf(body, "mac=%02X%%3A%02X%%3A%02X%%3A%02X%%3A%02X%%3A%02X&" "ip=%d.%d.%d.%d&" "subnet=%d.%d.%d.%d&" "gateway=%d.%d.%d.%d", &mac_values[0], &mac_values[1], &mac_values[2], &mac_values[3], &mac_values[4], &mac_values[5], &ip_values[0], &ip_values[1], &ip_values[2], &ip_values[3], &subnet_values[0], &subnet_values[1], &subnet_values[2], &subnet_values[3], &gateway_values[0], &gateway_values[1], &gateway_values[2], &gateway_values[3]) == 18) { // 更新MAC地址 for(int i = 0; i < 6; i++) { gWIZNETINFO.mac[i] = (uint8_t)mac_values[i]; } // 更新IP地址 for(int i = 0; i < 4; i++) { gWIZNETINFO.ip[i] = (uint8_t)ip_values[i]; gWIZNETINFO.sn[i] = (uint8_t)subnet_values[i]; gWIZNETINFO.gw[i] = (uint8_t)gateway_values[i]; } // 应用新的网络配置 wizchip_setnetinfo(&gWIZNETINFO); } } void http_server_init(void) { // 创建服务器socket socket(HTTP_SERVER_SOCKET, Sn_MR_TCP, HTTP_SERVER_PORT, 0); listen(HTTP_SERVER_SOCKET); } void http_server_task(void) { uint8_t buffer[2048]; uint16_t size; uint8_t status = getSn_SR(HTTP_SERVER_SOCKET); switch(status) { case SOCK_LISTEN: // 等待连接 break; case SOCK_ESTABLISHED: { // 接收数据 if((size = getSn_RX_RSR(HTTP_SERVER_SOCKET)) > 0) { size = recv(HTTP_SERVER_SOCKET, buffer, sizeof(buffer)); if(size > 0) { http_request req; parse_http_request(buffer, size, &req); if(req.method == HTTP_GET) { handle_config_page(HTTP_SERVER_SOCKET); } else if(req.method == HTTP_POST && strcmp(req.uri, "/config") == 0) { update_network_config((char*)req.body); // 重定向回配置页面 send_chunked_response_header(HTTP_SERVER_SOCKET); send_chunk(HTTP_SERVER_SOCKET, "
", strlen("")); send_chunk_end(HTTP_SERVER_SOCKET); } } } break; } case SOCK_CLOSE_WAIT: disconnect(HTTP_SERVER_SOCKET); break; case SOCK_CLOSED: socket(HTTP_SERVER_SOCKET, Sn_MR_TCP, HTTP_SERVER_PORT, 0); listen(HTTP_SERVER_SOCKET); break; } }