198 lines
5.7 KiB
C
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);
|
|
}
|
|
}
|
|
}
|
|
} |