F1CTL/Core/Src/http_server.c
2024-12-15 10:41:36 +08:00

246 lines
7.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "http_server.h"
// HTML页面模板
const char* html_page = "<!DOCTYPE html>"
"<html><head>"
"<title>W5500 Configuration</title>"
"<style>"
" body {"
" font-family: Arial, sans-serif;"
" max-width: 800px;"
" margin: 20px auto;"
" padding: 20px;"
" background-color: #f5f5f5;"
" }"
" h2 {"
" color: #333;"
" text-align: center;"
" padding-bottom: 10px;"
" border-bottom: 2px solid #ddd;"
" }"
" form {"
" background: white;"
" padding: 20px;"
" border-radius: 8px;"
" box-shadow: 0 2px 4px rgba(0,0,0,0.1);"
" }"
" .form-group {"
" margin-bottom: 15px;"
" }"
" label {"
" display: inline-block;"
" width: 80px;"
" font-weight: bold;"
" color: #555;"
" }"
" input[type='text'] {"
" width: 200px;"
" padding: 8px;"
" border: 1px solid #ddd;"
" border-radius: 4px;"
" font-family: monospace;"
" }"
" input[type='submit'] {"
" background-color: #4CAF50;"
" color: white;"
" padding: 10px 20px;"
" border: none;"
" border-radius: 4px;"
" cursor: pointer;"
" font-size: 16px;"
" margin-top: 10px;"
" }"
" input[type='submit']:hover {"
" background-color: #45a049;"
" }"
" .status {"
" margin-top: 20px;"
" padding: 10px;"
" border-radius: 4px;"
" text-align: center;"
" }"
" .connected {"
" background-color: #dff0d8;"
" color: #3c763d;"
" border: 1px solid #d6e9c6;"
" }"
" .disconnected {"
" background-color: #f2dede;"
" color: #a94442;"
" border: 1px solid #ebccd1;"
" }"
"</style>"
"</head><body>"
"<h2>W5500 Network Configuration</h2>"
"<form method='post' action='/config'>"
" <div class='form-group'>"
" <label>MAC:</label>"
" <input type='text' name='mac' value='%02X:%02X:%02X:%02X:%02X:%02X'>"
" </div>"
" <div class='form-group'>"
" <label>IP:</label>"
" <input type='text' name='ip' value='%d.%d.%d.%d'>"
" </div>"
" <div class='form-group'>"
" <label>Subnet:</label>"
" <input type='text' name='subnet' value='%d.%d.%d.%d'>"
" </div>"
" <div class='form-group'>"
" <label>Gateway:</label>"
" <input type='text' name='gateway' value='%d.%d.%d.%d'>"
" </div>"
" <input type='submit' value='Save Configuration'>"
"</form>"
"<div class='status %s'>"
" Network Status: %s"
"</div>"
"</body></html>";
// 解析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,
"<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>",
strlen("<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>"));
}
}
}
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;
}
}