初始创建FTP服务器

This commit is contained in:
2026-07-21 22:08:11 +08:00
parent d48be81478
commit 6d404d136e
10 changed files with 265 additions and 357 deletions

View File

@@ -16,8 +16,8 @@
#include "nand.h"
#include "map.h"
/* FTL 分区起始地址(块 1024偏移 128MB */
#define FTL_FATFS_OFFSET (128U * 1024U * 1024U)
/* FTL 分区起始地址(块 0偏移 0占用全部 256MB */
#define FTL_FATFS_OFFSET 0U
/* 调试输出配置 */
#define DBG_TAG "[NAND_FTL]"

View File

@@ -37,6 +37,7 @@
static net_sock_t s_net_socks[NET_MAX_SOCKETS]; /* Socket 控制块数组 */
static int s_net_errno = 0; /* 最后错误码 */
static uint8_t s_net_initialized = 0; /* 初始化标志 */
static uint8_t s_local_ip[4]; /* 本机 IP 缓存网络序net_getsockname 用) */
/*
* 消息队列 - 线程安全核心
@@ -131,6 +132,8 @@ int net_init(const char *ip, const char *mask, const char *gateway) {
parse_ip_string(mask, mask_arr);
parse_ip_string(gateway, gw_arr);
memcpy(s_local_ip, ip_arr, 4);
ch395f_set_ip_addr(ip_arr);
ch395f_set_gwip_addr(gw_arr);
ch395f_set_mask_addr(mask_arr);
@@ -1337,9 +1340,28 @@ static int alloc_socket(void) {
* 函数功能处理连接事<E68EA5>? */
static void handle_connect_event(net_sock_t *p_sock) {
if (p_sock->state == NET_SOCK_STATE_LISTENING) {
/* 多连接模式:监听 Socket 收到 CONNECT 中断 = 有新连接被分配到数据 Socket
* Socket 0 自身保持 LISTENING不需要改变状<E58F98>?*/
fire_event(p_sock, NET_EVENT_CONNECTED);
if (p_sock->standalone_accept) {
/* 独立监听模式PASV收到 CONNECT 中断 = 自身有连接到达,转为 ESTABLISHED */
DBG_INFO("sock%d standalone accept", p_sock->ch395_sock);
uint8_t remote[6];
ch395f_get_remot_ipp(p_sock->ch395_sock, remote);
memcpy(p_sock->remote_ip_arr, remote, 4);
p_sock->remote_ip = ((uint32_t)remote[0]) |
((uint32_t)remote[1] << 8) |
((uint32_t)remote[2] << 16) |
((uint32_t)remote[3] << 24);
p_sock->remote_port = (uint16_t)(remote[4] | (remote[5] << 8));
p_sock->state = NET_SOCK_STATE_ESTABLISHED;
p_sock->send_ready = 1;
ch395f_set_keepalive_enable(p_sock->ch395_sock, 1);
fire_event(p_sock, NET_EVENT_CONNECTED);
} else {
/* 多连接模式:监听 Socket 收到 CONNECT 中断 = 有新连接被分配到数据 Socket
* Socket 0 自身保持 LISTENING不需要改变状态 */
fire_event(p_sock, NET_EVENT_CONNECTED);
}
}
else if (!p_sock->in_use) {
/* CH395F 自动打开的数<E79A84>?Socket多连接模式首次收到 CONNECT 中断 */
@@ -1450,12 +1472,21 @@ static void handle_timeout_event(net_sock_t *p_sock) {
p_sock->state = NET_SOCK_STATE_CREATED;
}
else if (p_sock->state == NET_SOCK_STATE_ESTABLISHED) {
/* 多连接模式:数据 Socket 超时,恢复为 TCP_ACCEPT 等待新连<E696B0>?*/
DBG_INFO("sock%d TIMEOUT, back to ACCEPT", p_sock->ch395_sock);
memset(p_sock->remote_ip_arr, 0, 4);
p_sock->remote_port = 0;
p_sock->send_ready = 1;
p_sock->state = NET_SOCK_STATE_TCP_ACCEPT;
if (p_sock->standalone_accept) {
/* 独立监听模式PASV断开后释放 Socket不清零整个控制块net_recv 中的任务仍需读 state */
DBG_INFO("sock%d DISCONNECTED, releasing", p_sock->ch395_sock);
p_sock->state = NET_SOCK_STATE_CLOSED;
p_sock->in_use = 0;
fire_event(p_sock, NET_EVENT_DISCONNECTED);
} else {
/* CH395F 自动关闭了 Socket恢复为未使用状态 */
DBG_INFO("sock%d DISCONNECTED, back to idle", p_sock->ch395_sock);
memset(p_sock->remote_ip_arr, 0, 4);
p_sock->remote_port = 0;
p_sock->send_ready = 1;
p_sock->state = NET_SOCK_STATE_TCP_ACCEPT;
fire_event(p_sock, NET_EVENT_DISCONNECTED);
}
}
else if (p_sock->state == NET_SOCK_STATE_LISTENING) {
/* 监听超时(异常情况) */
@@ -1510,3 +1541,42 @@ net_sock_t *net_get_sock(int sockfd) {
return &s_net_socks[sockfd];
}
/*
* 函数功能:获取 Socket 本地地址IP + Port
* 入口参数sockfd - socket 描述符 int
* addr - 输出:本地地址 struct net_sockaddr *
* addrlen - 输入输出:地址结构体长度 int *
* 返回值0 - 成功,-1 - 失败 int
* 限定条件socket 已创建或已绑定
* 函数说明:返回 sin_family + sin_port网络序+ sin_addr网络序从 net_init 缓存的 s_local_ip
*/
int net_getsockname(int sockfd, struct net_sockaddr *addr, int *addrlen) {
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
s_net_errno = NET_ERR_BADF;
return -1;
}
net_sock_t *p_sock = &s_net_socks[sockfd];
if (!p_sock->in_use && p_sock->state == NET_SOCK_STATE_CLOSED) {
s_net_errno = NET_ERR_BADF;
return -1;
}
if (addr == NULL || addrlen == NULL || *addrlen < (int)sizeof(struct net_sockaddr_in)) {
s_net_errno = NET_ERR_INVAL;
return -1;
}
struct net_sockaddr_in *p_addr_in = (struct net_sockaddr_in *)addr;
memset(p_addr_in, 0, sizeof(struct net_sockaddr_in));
p_addr_in->sin_family = NET_AF_INET;
p_addr_in->sin_port = net_htons(p_sock->local_port);
p_addr_in->sin_addr.s_addr = ((uint32_t)s_local_ip[0]) |
((uint32_t)s_local_ip[1] << 8) |
((uint32_t)s_local_ip[2] << 16) |
((uint32_t)s_local_ip[3] << 24);
*addrlen = sizeof(struct net_sockaddr_in);
return 0;
}

View File

@@ -287,6 +287,16 @@ void net_process_messages(void);
*/
net_sock_t *net_get_sock(int sockfd);
/*
* 函数功能:获取 Socket 本地地址IP + Port
* 入口参数sockfd - socket 描述符
* addr - 输出:本地地址
* addrlen - 输入输出:地址结构体长度
* 返回值0 成功,-1 失败
* 限定条件socket 已创建或已绑定
*/
int net_getsockname(int sockfd, struct net_sockaddr *addr, int *addrlen);
/*
* 内部 API需在 netTask 上下文中调用,绕过消息队列)
*/