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.

268 lines
6.9 KiB

2 months ago
/******************************************************************************
(C), 2018-2099, Radkil
******************************************************************************
: My_Lwip.c
: 稿
: Radkil
: 2026521
:
: LWIP中间层
:
1. : 2026521
: Radkil
:
******************************************************************************/
#include "common.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 1024 // 接收缓冲区大小
#define IAC 255
#define WILL 251
#define DO 253
#define ECHO 1
#define SGA 3
2 months ago
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, ...)
{
static char temp[RECV_SIZE];
2 months ago
va_list args;
va_start(args, fmt);
int len = vsprintf(temp, fmt, args);
2 months ago
va_end(args);
if (len > 0 && connect_fd >= 0)
{
// 将 \n 转换为 \r\n,分段发送
int start = 0;
for (int i = 0; i < len; i++)
{
if (temp[i] == '\n')
{
if (i > start)
write(connect_fd, &temp[start], i - start);
write(connect_fd, "\r\n", 2);
start = i + 1;
}
}
if (start < len)
write(connect_fd, &temp[start], len - start);
}
2 months ago
}
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);
// 发送telnet协商:服务端负责回显,进入字符模式
unsigned char telnet_neg[] = {
IAC, WILL, ECHO,
IAC, WILL, SGA
};
write(connect_fd, telnet_neg, sizeof(telnet_neg));
2 months ago
#endif
// 打印连接的客户端 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, 1);
2 months ago
#else
write(connect_fd, temp, ret);
#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