W801_SDK_dev_env/app/nano_shell_server_task.c
2022-11-01 18:22:10 +01:00

198 lines
5.7 KiB
C

#include "string.h"
#include "lwip/netif.h"
#include "wm_include.h"
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "nano_shell_server_task.h"
#include "nano_shell_interface.h"
#include "app_common.h"
extern void network_rx_callback(u16 len, char *data);
tls_os_mutex_t *socket_mutex = NULL;
int nano_shell_srv_sock = 0, client_sock = 0;
const char greeting_buffer[] = "\r\n"
" _ _ ____ _ _ _\r\n"
"| \\ | | __ _ _ __ ___ / ___|| |__ ___| | |\r\n"
"| \\| |/ _` | '_ \\ / _ \\ \\___ \\| '_ \\ / _ \\ | |\r\n"
"| |\\ | (_| | | | | (_) | ___) | | | | __/ | |\r\n"
"|_| \\_|\\__,_|_| |_|\\___/ |____/|_| |_|\\___|_|_|\r\n"
"\r\n"
"Welcome to Nano-Shell remote access\r\n"
"\r\n"
" * Source: https://github.com/lebinlv/nano-shell\r\n"
" * Copyright: (c) Liber 2020\r\n"
"\r\n";
char identity_buffer[250] = "";
bool network_write_char(const char c)
{
bool toReturn = false;
tls_os_mutex_acquire(socket_mutex, 0);
if(client_sock > 0)
{
if(send(client_sock, &c, 1, 0) < 0)
{
// Failed to send data to client because he probably disconnected
// or the connection broke
client_sock = 0;
}
else
{
toReturn = true;
}
}
tls_os_mutex_release(socket_mutex);
return toReturn;
}
bool network_write_string(const char *str, size_t size)
{
bool toReturn = false;
if(client_sock > 0)
{
tls_os_mutex_acquire(socket_mutex, 0);
if(send(client_sock, str, size, 0) < 0)
{
// Failed to send data to client because he probably disconnected
// or the connection broke
client_sock = 0;
}
else
{
toReturn = true;
}
tls_os_mutex_release(socket_mutex);
}
return toReturn;
}
bool disconnect_client(void)
{
bool toReturn = false;
if(client_sock > 0)
{
if(shutdown(client_sock, SHUT_WR) < 0)
{
}
else
{
toReturn = true;
}
client_sock = 0;
}
return toReturn;
}
void nano_shell_server_task(void* param)
{
(void)param;
bool setup_error = false;
char recv_buffer[256] = "";
struct sockaddr_in nano_shell_srv_addr = { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(NANO_SHELL_SERVER_PORT)}, client_addr;
socklen_t sockaddr_in_len = sizeof(struct sockaddr_in);
//We initialize the mutex
if(tls_os_mutex_create(0, &socket_mutex) != TLS_OS_SUCCESS)
{
shell_printf("Failed to create the mutex."NEW_LINE);
setup_error = true;
}
//We setup the listening socket :
if((nano_shell_srv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
shell_printf("Failed to create nano_shell listening socket."NEW_LINE);
setup_error = true;
}
if(bind(nano_shell_srv_sock, (struct sockaddr *) &nano_shell_srv_addr, sockaddr_in_len) < 0)
{
shell_printf("Failed to bind nano_shell listening socket to addr."NEW_LINE);
setup_error = true;
}
//We only wait for one connection at a time because the nano_shell is not multi user anyway
if(listen(nano_shell_srv_sock, 0) < 0)
{
shell_printf("Failed to mark nano_shell_sock as a listening socket."NEW_LINE);
setup_error = true;
}
if(setup_error)
{
for(;;)
tls_os_time_delay(portMAX_DELAY);
}
for(;;)
{
client_sock = accept(nano_shell_srv_sock, (struct sockaddr *)&client_addr, &sockaddr_in_len);
if(client_sock < 0)
{
shell_printf("Failed to accept incoming connection."NEW_LINE);
}
if(!network_write_string(greeting_buffer, sizeof greeting_buffer))
{
shell_printf("Failed to send greetings to client - errno(%d)."NEW_LINE, errno);
}
sprintf(identity_buffer, "Connected from : %u.%u.%u.%u:%u"NEW_LINE NEW_LINE,((u8 *)&client_addr.sin_addr)[0],
((u8 *)&client_addr.sin_addr)[1],
((u8 *)&client_addr.sin_addr)[2],
((u8 *)&client_addr.sin_addr)[3],
ntohs(client_addr.sin_port));
if(!network_write_string(identity_buffer, strlen(identity_buffer)))
{
shell_printf("Failed to send greetings to client - errno(%d)."NEW_LINE, errno);
}
for(;client_sock > 0;)
{
int result = recv(client_sock, recv_buffer, 255, 0);
if(result < 0)
{
shell_printf("Failed to receive data from client - errno(%d)."NEW_LINE"Closing connection."NEW_LINE, errno);
if(close(client_sock) < 0)
{
shell_printf("Failed to close socket - errno(%d)."NEW_LINE, errno);
}
client_sock = 0;
}
else if(result == 0)
{
shell_printf("Client disconnected."NEW_LINE);
if(close(client_sock) < 0)
{
shell_printf("Failed to close socket - errno(%d)."NEW_LINE, errno);
}
client_sock = 0;
}
else //We pass the received data to the nano shell process
{
//Need to remove the \n at the end
char *pos = strchr(recv_buffer, '\r');
if(pos)
{
*pos = '\n';
result = pos + 1 - recv_buffer;
}
network_rx_callback(result, recv_buffer);
}
}
}
}