diff --git a/Core/Inc/http_server.h b/Core/Inc/http_server.h new file mode 100644 index 0000000..94d3791 --- /dev/null +++ b/Core/Inc/http_server.h @@ -0,0 +1,43 @@ +#ifndef __HTTP_SERVER_H +#define __HTTP_SERVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "socket.h" +#include "w5500_init.h" +#include +#include +#include + +#define HTTP_SERVER_PORT 80 +#define HTTP_SERVER_SOCKET 1 +#define MAX_URI_SIZE 128 + +// HTTP请求方法 +typedef enum { + HTTP_GET, + HTTP_POST, + HTTP_UNKNOWN +} http_method; + +// HTTP请求结构 +typedef struct { + http_method method; + char uri[MAX_URI_SIZE]; + uint8_t* body; + uint16_t body_length; +} http_request; + +// 初始化HTTP服务器 +void http_server_init(void); + +// 处理HTTP服务器任务 +void http_server_task(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __HTTP_SERVER_H */ \ No newline at end of file diff --git a/Core/Src/http_server.c b/Core/Src/http_server.c new file mode 100644 index 0000000..f393bab --- /dev/null +++ b/Core/Src/http_server.c @@ -0,0 +1,246 @@ +#include "http_server.h" + +// HTML页面模板 +const char* html_page = "" +"" +"W5500 Configuration" +"" +"" +"

W5500 Network Configuration

" +"
" +"
" +" " +" " +"
" +"
" +" " +" " +"
" +"
" +" " +" " +"
" +"
" +" " +" " +"
" +" " +"
" +"
" +" Network Status: %s" +"
" +""; + +// 解析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 void send_response(uint8_t sn, const char* content, uint16_t length) +{ + char header[128]; + sprintf(header, + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %d\r\n" + "\r\n", length); + + send(sn, (uint8_t*)header, strlen(header)); + send(sn, (uint8_t*)content, length); +} + +// 处理配置页面请求 +static void handle_config_page(uint8_t sn) +{ + char page[4096]; // 增加缓冲区大小以适应新的HTML内容 + bool is_connected = (wizphy_getphylink() == PHY_LINK_ON); + char* link_status = is_connected ? "Connected" : "Disconnected"; + char* status_class = is_connected ? "connected" : "disconnected"; + + sprintf(page, html_page, + 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_response(sn, page, strlen(page)); +} + +// 解析并更新网络配置 +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_response(HTTP_SERVER_SOCKET, + "", + strlen("")); + } + } + } + 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; + } +} \ No newline at end of file diff --git a/Core/Src/main.c b/Core/Src/main.c index e411141..add30d4 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -26,7 +26,8 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "w5500_init.h" -#include "http_test.h" +#include "http_client.h" +#include "http_server.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -103,7 +104,10 @@ int main(void) } } - // 执行HTTP测试 + // 初始化HTTP服务器 + http_server_init(); + + // 执行一次HTTP客户端测试 http_test_request(); /* USER CODE END 2 */ @@ -114,6 +118,7 @@ int main(void) /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ + http_server_task(); HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); HAL_Delay(500); }