You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
7.1 KiB
264 lines
7.1 KiB
/******************************************************************************
|
|
|
|
版权所有 (C), 2018-2099, Radkil
|
|
|
|
******************************************************************************
|
|
文 件 名 : My_Lwip.c
|
|
版 本 号 : 初稿
|
|
作 者 : Radkil
|
|
生成日期 : 2026年5月21日
|
|
最近修改 :
|
|
功能描述 : LWIP中间层
|
|
|
|
修改历史 :
|
|
1.日 期 : 2026年5月21日
|
|
作 者 : Radkil
|
|
修改内容 : 创建文件
|
|
|
|
******************************************************************************/
|
|
#include "bsp_config.h"
|
|
#ifdef USE_LWIP
|
|
#include "lwip/sockets.h"
|
|
#include "lwip/netdb.h"
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "common.h"
|
|
#include "ringbuffer.h"
|
|
#include "semphr.h"
|
|
#include "lua_base.h"
|
|
#include <stdarg.h>
|
|
|
|
/*----------------------------------------------*
|
|
* 外部变量说明 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 外部函数原型说明 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 内部函数原型说明 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 全局变量 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 模块级变量 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 常量定义 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 宏定义 *
|
|
*----------------------------------------------*/
|
|
#define PORT 23 // 监听的端口号
|
|
#define RECV_SIZE 256 // 接收缓冲区大小
|
|
static int connect_fd = -1; //socket套接字
|
|
|
|
#if 0
|
|
static rd_ringbuf_t *g_rb_handle = NULL;
|
|
SemaphoreHandle_t xSemaphore;
|
|
StaticSemaphore_t xSemaphoreBuffer;
|
|
SemaphoreHandle_t xMutex;
|
|
StaticSemaphore_t xMutexBuffer;
|
|
|
|
void Myprint_Init(void)
|
|
{
|
|
g_rb_handle = rd_RingbufferCreate(RECV_SIZE);
|
|
rd_RingbufferReset(g_rb_handle);
|
|
xSemaphore = xSemaphoreCreateCountingStatic(5, 0, &xSemaphoreBuffer);
|
|
xMutex = xSemaphoreCreateMutexStatic(&xMutexBuffer);
|
|
return;
|
|
}
|
|
|
|
void Myprint_timer(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void Myprint_IRQHandler(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int Myprint_putchar(uint8_t ch)
|
|
{
|
|
if (connect_fd < 0) return 0;
|
|
char tx_buf[2];
|
|
if (ch == '\n')
|
|
{
|
|
tx_buf[0] = '\r';
|
|
tx_buf[1] = '\n';
|
|
if (write(connect_fd, tx_buf, 2) < 0) return EOF;
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
tx_buf[0] = ch;
|
|
if (write(connect_fd, tx_buf, 1) < 0) return EOF;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void Myprint_getchar(char *ch)
|
|
{
|
|
while (1)
|
|
{
|
|
int ret;
|
|
|
|
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE)
|
|
{
|
|
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
|
|
{
|
|
ret = rd_RingbufferGet(g_rb_handle, ch, 1);
|
|
xSemaphoreGive(xMutex);
|
|
if (ret > 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void ShowLWIPstate(void)
|
|
{
|
|
stats_display();
|
|
}
|
|
|
|
void luaprint_talnet(const char *fmt, ...)
|
|
{
|
|
char temp[RECV_SIZE];
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
vsprintf(temp, fmt, args);
|
|
write(connect_fd, &temp, strlen(temp));
|
|
va_end(args);
|
|
}
|
|
|
|
void vTCPServer_Task(void *pvParameters)
|
|
{
|
|
int listen_fd;
|
|
struct sockaddr_in server_addr, client_addr;
|
|
char temp[RECV_SIZE];
|
|
int ret;
|
|
socklen_t addr_len = sizeof(struct sockaddr_in);
|
|
|
|
// 1. 创建 socket (AF_INET表示IPv4, SOCK_STREAM表示TCP)
|
|
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (listen_fd < 0)
|
|
{
|
|
log_e("Socket create failed!\r\n");
|
|
vTaskDelete(NULL);
|
|
return;
|
|
}
|
|
|
|
// 2. 绑定 IP 和端口 (INADDR_ANY 表示绑定本地所有网卡IP)
|
|
memset(&server_addr, 0, sizeof(server_addr));
|
|
server_addr.sin_family = AF_INET;
|
|
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
server_addr.sin_port = htons(PORT);
|
|
|
|
if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
|
|
{
|
|
log_e("Bind failed!\r\n");
|
|
close(listen_fd);
|
|
vTaskDelete(NULL);
|
|
return;
|
|
}
|
|
|
|
// 3. 开始监听,最大排队连接数为 5
|
|
if (listen(listen_fd, 5) < 0)
|
|
{
|
|
log_e("Listen failed!\r\n");
|
|
close(listen_fd);
|
|
vTaskDelete(NULL);
|
|
return;
|
|
}
|
|
|
|
log_i("TCP Server is running on port %d...\r\n", PORT);
|
|
|
|
while (1)
|
|
{
|
|
// 4. 阻塞等待客户端连接
|
|
connect_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &addr_len);
|
|
if (connect_fd < 0)
|
|
{
|
|
log_w("Accept failed!\r\n");
|
|
continue;
|
|
}
|
|
|
|
#ifdef USE_TALNET
|
|
lua_init(luaprint_talnet);
|
|
#endif
|
|
// // 第一条指令:要求客户端关闭本地回显,交由服务器处理
|
|
// unsigned char cmd_echo[] = { 255, 254, 1 };
|
|
// // IAC(255) DO(253) ECHO(1)
|
|
//
|
|
// // 第二条指令:禁用“前进抑制”,强制进入实时字符流模式
|
|
// unsigned char cmd_sga[] = { 255, 254, 3 };
|
|
// // IAC(255) DO(253) SUPPRESS-GO-AHEAD(3)
|
|
//
|
|
// write(connect_fd, cmd_echo, sizeof(cmd_echo));
|
|
// write(connect_fd, cmd_sga, sizeof(cmd_sga));
|
|
|
|
// int enable = 1; // 1 表示启用 TCP_NODELAY(即禁用 Nagle 算法)
|
|
// setsockopt(connect_fd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
|
// 打印连接的客户端 IP 和端口
|
|
log_i("New client connected: %s:%d\r\n",
|
|
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
|
|
// 5. 循环接收并回显数据
|
|
|
|
// char *welcome = "\n> ";
|
|
// write(connect_fd, welcome, strlen(welcome));
|
|
|
|
while (1)
|
|
{
|
|
// 阻塞接收数据
|
|
ret = read(connect_fd, &temp, RECV_SIZE);
|
|
|
|
if (ret > 0)
|
|
{
|
|
#ifdef USE_TALNET
|
|
lua_repl(temp, ret, 0);
|
|
#else
|
|
write(connect_fd, temp, ret);
|
|
#endif
|
|
#if 0
|
|
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
|
|
{
|
|
int iLen = rd_RingbufferPutForce(g_rb_handle, &temp, ret);
|
|
xSemaphoreGive(xMutex);
|
|
if (iLen > 0)
|
|
{
|
|
xSemaphoreGive(xSemaphore);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
else if (ret == 0)
|
|
{
|
|
// 客户端正常断开连接
|
|
log_i("Client disconnected.\r\n");
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// 接收出错
|
|
log_e("Read data error!\r\n");
|
|
break;
|
|
}
|
|
}
|
|
// 关闭与当前客户端的连接
|
|
close(connect_fd);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|