#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_index_page(uint8_t sn) { // 发送分块传输的响应头 send_chunked_response_header(sn); // 分段发送HTML内容 // const int CHUNK_SIZE = 512; // 每个块的大小 int total_len = strlen(index_html); int sent = 0; while (sent < total_len) { // 计算当前块的大小 int chunk_len = ((total_len - sent) > CHUNK_SIZE) ? CHUNK_SIZE : (total_len - sent); // 发送数据块 send_chunk(sn, index_html + sent, chunk_len); sent += chunk_len; } // 发送结束块 send_chunk_end(sn); // 等待数据发送完成 HAL_Delay(1); // 关闭连接 disconnect(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); } // 发送JSON响应头 static void send_json_response_header(uint8_t sn) { const char* header = "HTTP/1.1 200 OK\r\n" "Content-Type: application/json\r\n" "Access-Control-Allow-Origin: *\r\n" "Connection: close\r\n" // 明确指示关闭连接 "Cache-Control: no-cache, no-store\r\n" // 禁止缓存 "\r\n"; send_all(sn, (uint8_t*)header, strlen(header)); } // 处理状态请求 static void handle_status_request(uint8_t sn) { char json_buffer[512]; // DeviceStatus deviceStatus; // 确保能访问到deviceStatus变量 // 构建JSON响应 int len = sprintf(json_buffer, "{" "\"deviceStatus\":%d," "\"valves\":{" "\"angle1\":%d," "\"angle2\":%d" "}," "\"pumps\":{" "\"status1\":%d," "\"status2\":%d," "\"speed1\":%d," "\"speed2\":%d" "}," "\"bubbleStatus\":%d," "\"stopStatus\":%d," "\"errorCode\":%d," "\"initStatus\":%d" "}", deviceStatus.deviceStatus, deviceStatus.valves.angle1, deviceStatus.valves.angle2, deviceStatus.pumps.status1, deviceStatus.pumps.status2, deviceStatus.pumps.speed1, deviceStatus.pumps.speed2, deviceStatus.bubbleStatus, deviceStatus.stopStatus, deviceStatus.errorCode, deviceStatus.initStatus ); // 发送响应 send_json_response_header(sn); send_all(sn, (uint8_t*)json_buffer, len); // 发送完成后主动关闭连接 disconnect(sn); printf("send status success!\r\n"); } // 处理网络配置请求 static void handle_netconfig_request(uint8_t sn) { char json_buffer[256]; // 构建JSON响应 int len = sprintf(json_buffer, "{" "\"mac\":[%d,%d,%d,%d,%d,%d]," "\"ip\":[%d,%d,%d,%d]," "\"sn\":[%d,%d,%d,%d]," "\"gw\":[%d,%d,%d,%d]" "}", 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] ); // 发送响应 send_json_response_header(sn); send_all(sn, (uint8_t*)json_buffer, len); // 发送完成后主动关闭连接 disconnect(sn); } void http_server_task(void) { uint8_t buffer[256]; uint16_t size; uint8_t status = getSn_SR(HTTP_SERVER_SOCKET); switch(status) { case SOCK_INIT: listen(HTTP_SERVER_SOCKET); break; 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) { if(strcmp(req.uri, "/status") == 0) { handle_status_request(HTTP_SERVER_SOCKET); } else if(strcmp(req.uri, "/netconfig") == 0) { handle_netconfig_request(HTTP_SERVER_SOCKET); } else { handle_index_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); break; } }