This repository has been archived on 2023-07-17. You can view files and clone it, but cannot push or open issues or pull requests.
bl_mcu_sdk/examples/emac/lwip_tcp/tcp_server.c

330 lines
15 KiB
C

/**
* @file tcp_server.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
#include "lwip/api.h"
#include "lwip/arch.h"
#include "lwip/opt.h"
#include "lwip/inet.h"
#include "lwip/sockets.h"
#include "FreeRTOS.h"
#include "task.h"
#include "tcp_server.h"
#define USE_RAWAPI_TEST 0
#define USE_NETCONN_TEST 1
#define USE_SOCKET_TEST 2
#define TCP_TEST_SELECT USE_NETCONN_TEST
struct netif *tmpnetif;
static uint8_t iptxt[20];
static StackType_t tcp_server_stack[512];
static StaticTask_t tcp_server_handle;
#if (TCP_TEST_SELECT == USE_NETCONN_TEST)
#if LWIP_NETCONN
// clang-format off
static const uint8_t send_buf[1460] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
// clang-format on
void tcp_netconn_send_test(void)
{
struct netconn *conn, *newconn;
err_t err;
// creat tcp server
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, IP_ADDR_ANY, TCP_SERVER_TEST_PORT);
// set listen
netconn_listen(conn);
tmpnetif = netif_find("bl");
sprintf((char *)iptxt, "%s", ip4addr_ntoa(&tmpnetif->ip_addr));
MSG("Create server success, server ip & listen port:%s:%d\r\n", iptxt, TCP_SERVER_TEST_PORT);
while (1) {
// wait connect
err = netconn_accept(conn, &newconn);
MSG("server recv a connection!\r\n");
// process connect
if (err == ERR_OK) {
MSG("netconn send!\r\n");
while (1) {
netconn_write(newconn, send_buf, sizeof(send_buf), NETCONN_NOCOPY);
}
}
// delete connect
netconn_close(newconn);
// netconn_shutdown(newconn, 1, 1); // two-way port close
netconn_delete(newconn);
}
}
/**
* @brief implementing tcp loopback use the netconn api
*
*/
void tcp_server_netconn_test(void)
{
struct netconn *conn, *newconn;
err_t err;
// creat tcp server
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, IP_ADDR_ANY, TCP_SERVER_TEST_PORT);
// set listen
netconn_listen(conn);
tmpnetif = netif_find("bl");
sprintf((char *)iptxt, "%s", ip4addr_ntoa(&tmpnetif->ip_addr));
MSG("Create server success, server ip & listen port:%s:%d\r\n", iptxt, TCP_SERVER_TEST_PORT);
while (1) {
// wait connect
err = netconn_accept(conn, &newconn);
MSG("server recv a connection!\r\n");
// process connect
if (err == ERR_OK) {
struct netbuf *buf;
void *data;
uint16_t len;
// loopback recv data
while ((err = netconn_recv(newconn, &buf)) == ERR_OK) {
do {
netbuf_data(buf, &data, &len);
err = netconn_write(newconn, data, len, NETCONN_NOCOPY); // tcp echo
// if (err != ERR_OK) {
// MSG("write falied! err:%d\r\n", err);
// }
} while (netbuf_next(buf) >= 0);
netbuf_delete(buf);
}
}
// delete connect
netconn_close(newconn);
// netconn_shutdown(newconn, 1, 1); // two-way port close
netconn_delete(newconn);
}
}
#endif
/**
* @brief Initialize the tcp server (start its thread)
* @param none
* @retval None
*/
void tcp_server_init()
{
xTaskCreateStatic((void *)tcp_server_netconn_test, (char *)"tcp_server", sizeof(tcp_server_stack) / 4, NULL, osPriorityHigh, tcp_server_stack, &tcp_server_handle);
}
#endif
#if (TCP_TEST_SELECT == USE_SOCKET_TEST)
static unsigned char recv_buffer[2048];
/**
* @brief serve tcp connection
* @param conn: connection socket
* @retval None
*/
void tcp_server_process(int conn)
{
int buflen;
// int ret;
int flag;
setsockopt(conn, IPPROTO_TCP, TCP_NODELAY, (void *)&flag, sizeof(int));
while (1) {
buflen = recv(conn, recv_buffer, sizeof(recv_buffer), 0);
if (buflen <= 0) {
break;
}
write(conn, recv_buffer, buflen);
}
if (conn >= 0) {
closesocket(conn);
}
// /* Read in the request */
// ret = read(conn, recv_buffer, buflen);
// if (ret > 0) {
// write(conn, (const unsigned char *)(recv_buffer), (size_t)ret);
// }
// /* Close connection socket */
// close(conn);
}
/**
* @brief tcp server thread
* @param arg: pointer on argument(not used here)
* @retval None
*/
static void tcp_server_socket_thread(void *arg)
{
int sock, newconn, size;
struct sockaddr_in address, remotehost;
MSG("TCP Server create socket\r\n");
/* create a TCP socket */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return;
}
/* bind to test port at any interface */
address.sin_family = AF_INET;
address.sin_port = htons(TCP_SERVER_TEST_PORT);
address.sin_addr.s_addr = INADDR_ANY;
memset(&(address.sin_zero), 0, sizeof(address.sin_zero));
if (bind(sock, (struct sockaddr *)&address, sizeof(address)) < 0) {
return;
}
/* listen for incoming connections (TCP listen backlog = 5) */
listen(sock, 5);
tmpnetif = netif_find("bl");
sprintf((char *)iptxt, "%s", ip4addr_ntoa(&tmpnetif->ip_addr));
MSG("Create server success, server ip & listen port:%s:%d\r\n", iptxt, TCP_SERVER_TEST_PORT);
size = sizeof(remotehost);
while (1) {
newconn = accept(sock, (struct sockaddr *)&remotehost, (socklen_t *)&size);
MSG("TCP Server deal one client\r\n");
tcp_server_process(newconn);
if (newconn >= 0) {
closesocket(newconn);
newconn = -1;
}
}
}
/**
* @brief Initialize the tcp server (start its thread)
* @param none
* @retval None
*/
void tcp_server_init()
{
xTaskCreateStatic((void *)tcp_server_socket_thread, (char *)"tcp_server", sizeof(tcp_server_stack) / 4, NULL, 16, tcp_server_stack, &tcp_server_handle);
}
#endif
#if (TCP_TEST_SELECT == USE_RAWAPI_TEST)
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
static err_t tcp_echo_recv(void *arg, struct tcp_pcb *t_pcb, struct pbuf *p, err_t err)
{
if (p != NULL) {
// update wnd
tcp_recved(t_pcb, p->tot_len);
// recv data and write
tcp_write(t_pcb, p->payload, p->tot_len, NETCONN_COPY);
// memset(p->payload, 0, p->tot_len);
pbuf_free(p);
} else if (err == ERR_OK) {
return tcp_close(t_pcb);
}
return ERR_OK;
}
static err_t tcp_echo_process(void *arg, struct tcp_pcb *newpcb, err_t err)
{
tcp_recv(newpcb, tcp_echo_recv);
return ERR_OK;
}
void tcp_server_raw_init(void)
{
struct tcp_pcb *new_tcp = NULL;
err_t err;
// creat new tcp pcb
new_tcp = tcp_new();
if (new_tcp == NULL) {
MSG("new tcp pcb falied!\r\n");
}
// bind tcp pcb
err = tcp_bind(new_tcp, IP_ADDR_ANY, TCP_SERVER_TEST_PORT);
if (err != ERR_OK) {
MSG("tcp bind failed!\r\n");
}
// listen port
new_tcp = tcp_listen(new_tcp);
MSG("tcp listen ...\r\n");
// process some connect
tcp_accept(new_tcp, tcp_echo_process);
}
#endif