/*
** ****************
** Library includes
** ****************
*/
#include < mqx.h >
#include < bsp.h >
#include < rtcs.h >
#include < ipcfg.h >
#include < string.h >
/*
** ****************
** Project includes
** ****************
*/
#include "ProjectInclude.h"
#include "Initializations.h"
/*
** **************************
** Local functions prototypes
** **************************
*/
void InitRTCS()
{
IPCFG_IP_ADDRESS_DATA ip_data;
_enet_address mac_address;
uint_32 error;
// For multi socket connection (doesn't work)
_RTCSPCB_init = 4;
_RTCSPCB_grow = 2;
_RTCSPCB_max = 20;
_RTCS_msgpool_init = 4;
_RTCS_msgpool_grow = 2;
_RTCS_msgpool_max = 20;
_RTCS_socket_part_init = 4;
_RTCS_socket_part_grow = 2;
_RTCS_socket_part_max = 20;
error = RTCS_create();
if (error != RTCS_OK)
{
printf("\n[TCPServer]: Failed to create RTCS");
_task_block();
}
ip_data.ip = IPADDR(200, 200, 200, 200);
ip_data.mask = IPADDR(255, 255, 255, 0);
ip_data.gateway = IPADDR(0, 0, 0, 0);
ENET_get_mac_address(BSP_DEFAULT_ENET_DEVICE, ip_data.ip, mac_address);
ipcfg_init_device(BSP_DEFAULT_ENET_DEVICE, mac_address);
error = ipcfg_bind_staticip(BSP_DEFAULT_ENET_DEVICE, & ip_data);
if (error != RTCS_OK)
{
printf("\n[TCPServer]: Failed to bind static ip");
_task_block();
}
else
{
_task_create(0, TCPS_MAIN_TASK, 0); // TCPServer()
}
}
void TCPServer()
{
uint_32 error;
uint_32 sock, listensock;
sockaddr_in addr, client;
uint_16 client_len = sizeof(client);
// Create a socket //
listensock = socket(AF_INET, SOCK_STREAM, 0);
if (listensock == RTCS_SOCKET_ERROR)
{
printf("\n[TCPServer]: Failed to create the stream socket.");
_task_block();
}
addr.sin_family = AF_INET;
addr.sin_port = 17;
addr.sin_addr.s_addr = INADDR_ANY;
// Bind the socket //
error = bind(listensock, & addr, sizeof(addr));
if (error == RTCS_ERROR)
{
printf("\n[TCPServer]: Failed to bind the stream socket - 0x%lx", error);
_task_block();
}
// Start listening //
error = listen(listensock, 0);
if (error == RTCS_ERROR)
{
printf("\n[TCPServer]: listen() failed - 0x%lx", error);
_task_block();
}
while (1)
{
// Accept the connection //
sock = accept(listensock, & client, & client_len);
if (sock != RTCS_SOCKET_ERROR)
{
// Create sub thread to service client's request //
_task_create(0, TCPS_COMM_TASK, sock); // TCPCommunication()
}
else
{
error = RTCS_geterror(listensock);
// ? When will accept return RTCS_SOCKET_ERROR & RTCS_OK ?
if (error == RTCS_OK)
{
shutdown(listensock, FLAG_ABORT_CONNECTION);
printf("\n[TCPServer]: Connection reset by peer.");
printf("\n[TCPServer]: Closed.");
break;
}
else
{
printf("\n[TCPServer]: Failed to accept, CODE = 0x%x", error);
_task_block();
}
}
}
}
void TCPCommunication(uint_32 temp)
{
uint_32 error;
uint_8 recv_buffer[54];
uint_32 sock = temp;
uint_32 opt_val;
uint_32 opt_len;
// set receive push to FALSE, recv will return only if buffer is full, and timeout if set.
//opt_val = FALSE;
opt_val = TRUE;
opt_len = sizeof(uint_32);
error = setsockopt(sock, SOL_TCP, OPT_RECEIVE_PUSH, & opt_val, opt_len);
if (error != RTCS_OK)
{
printf("\n[TCPServer]: Failed to setsockopt for OPT_RECEIVE_PUSH, CODE = 0x%x.", error);
_task_block();
}
// set receive timeout to 60s, recv will return received n bytes if timeout occur
opt_val = 60 * 1000;
error = setsockopt(sock, SOL_TCP, OPT_RECEIVE_TIMEOUT, & opt_val, opt_len);
if (error != RTCS_OK)
{
printf("\n[TCPServer]: Failed to setsockopt for OPT_RECEIVE_TIMEOUT, CODE = 0x%x.", error);
_task_block();
}
opt_val = 54;
error = setsockopt(sock, SOL_TCP, OPT_RBSIZE, & opt_val, opt_len);
if (error != RTCS_OK)
{
printf("\n[TCPServer]: Failed to setsockopt for OPT_RBSIZE, CODE = 0x%x.", error);
_task_block();
}
// Clean the buffers to '\0' //
memset(recv_buffer, 0, 54);
while (TRUE)
{
if (recv(sock, recv_buffer, 54, 0) == RTCS_ERROR)
{
error = RTCS_geterror(sock);
// Close TCPServer if TCPClient close first.
if (error == RTCSERR_TCP_CONN_CLOSING)
{
shutdown(sock, FLAG_ABORT_CONNECTION);
printf("\n[TCPServer]: TCPClient Closed (Socket = 0x%x).", sock);
break;
}
// Close TCPServer if TCPClient abort.
else if (error == RTCSERR_TCP_CONN_RESET)
{
shutdown(sock, FLAG_ABORT_CONNECTION);
printf("\n[TCPServer]: Connection reset by peer.");
printf("\n[TCPServer]: TCPClient Closed (Socket = 0x%x).", sock);
break;
}
// Timeout occur if zero char received.
else if (error == RTCSERR_TCP_TIMED_OUT)
{
printf("\n[TCPServer]: recv Timeout.");
if (send(sock, "TCPServer recv Timeout.", strlen("TCPServer recv Timeout.") + 1, 0) == RTCS_ERROR)
{
printf("\n[TCPServer]: Failed to send, CODE = 0x%x.", RTCS_geterror(sock));
_task_block();
}
}
else
{
printf("\n[TCPServer]: Failed to recv, CODE = 0x%x.", error);
_task_block();
}
}
else
{
if (send(sock, recv_buffer, sizeof(recv_buffer), 0) == RTCS_ERROR)
{
printf("\n[TCPServer]: Failed to send, CODE = 0x%x.", RTCS_geterror(sock));
_task_block();
}
// clean buffer to ensure '\0' filled for next recv.
memset(recv_buffer, 0, 54);
}
}
}