Hi Carlos,
the forum (or the pc) does not allow me to answer correctly and attach the file so i copy the code here.
this code shows the problem of the retransmissions.
to run this example i have this pc lan setting ip:192.168.11.1 ; subnet 255.255.255.0; gateway 192.168.11.1.
the board is connected to the pc throught a rj45 lan cable. when the application is running i use hercules to connect to the device: i choose TCP client, i set the ip of the device 192.168.11.202 , 8000 port; i set hercules to log the received info in a file because it break sometimes. when the transfer start i see in wireshark a correct communication for few seconds, then i start to see the retransmissions packets.
the code is:
#include <mqx.h>
#include <bsp.h>
#include <rtcs.h>
#if !PLATFORM_SDK_ENABLED
#include <enet.h>
#endif
#include <ipcfg.h>
#include <lwevent.h>
#include <mutex.h>
#ifndef DEMO_PORT
#define DEMO_PORT IPPORT_TELNET
#endif
#if MQX_USE_IO_OLD
#define SERIAL_DEVICE BSP_DEFAULT_IO_CHANNEL
#else
#define SERIAL_DEVICE "tty:"
#endif
/* EOF */
#define DEMOCFG_USE_WIFI BSP_ENET_WIFI_ENABLED /* USE WIFI Interface */
#define SERIAL_SOCKET_BUFFER_SIZE 1460
#ifndef ENET_IPADDR
#define ENET_IPADDR IPADDR(192,168,11,202)
#endif
#ifndef ENET_IPMASK
#define ENET_IPMASK IPADDR(255,255,255,0)
#endif
#ifndef ENET_IPGATEWAY
#define ENET_IPGATEWAY IPADDR(192,168,11,1)
#endif
#define REMOTE_PORT 50001
#ifndef ENET_MAC
#define ENET_MAC {0x00,0xA7,0xC5,0xF1,0x11,0x90}
#endif
#if PLATFORM_SDK_ENABLED
#include "app_mqx.h"
#else
#if ! BSPCFG_ENABLE_IO_SUBSYSTEM
#error This application requires BSPCFG_ENABLE_IO_SUBSYSTEM defined non-zero in user_config.h. Please recompile BSP with this option.
#endif
#ifndef BSP_DEFAULT_IO_CHANNEL_DEFINED
#error This application requires BSP_DEFAULT_IO_CHANNEL to be not NULL. Please set corresponding BSPCFG_ENABLE_ITTYx to non-zero in user_config.h and recompile BSP with this option.
#endif
#define MAIN_TASK_INDEX 1
#define RX_TASK_INDEX 2
#define TX_TASK_INDEX 3
#define WRITE_BUFFER_TASK_INDEX 4
#endif
#define SOCKET_WELCOME_MESSAGE "Ethernet <-> Serial bridge\n\r"
#define SERIAL_WELCOME_MESSAGE "Serial <-> Ethernet bridge\n\r"
#define RX_BUFFER_SIZE 128
#define TX_BUFFER_SIZE 128
#define TCP2SER_TRANSPARENT_SERVER_TASK_ID 0x3001
#define TCP2SER_TRANSPARENT_SERVER_TX_TASK_ID 0x3002
#define TCP2SER_CTRL_TASK_ID 0x3003
#define TCP2SERIAL_SERVER_PORT 8000
#define TCP2SERIAL_RESET_SOCK_TIME 300000
#define TCP2SERIAL_MAX_CLIENT_CONNECTIONS 3
#define TCP2SER_SOCKETS_NUMBER (1+TCP2SERIAL_MAX_CLIENT_CONNECTIONS+1) //server socket + client sockets + temp socket
#define TCP2SER_RX_BUF_SIZE 24
#define SER2TCP_BUF_SIZE 2920//128
#define PRINTF_DEBUG_TCP2SER if(1)fprintf
//tx
#define PRINTF_DEBUG_REMOTE_CLIENT if(1)fprintf
#define REM_CMD_BUF_MAX_SIZE 48
#define PREAMBLE_BUFF_SIZE (31)
/* Structure with sockets used for listening */
typedef struct socket_s
{
uint32_t sock6; // socket for IPv6
uint32_t sock4; // socket for IPv4
}SOCKETS_STRUCT, * SOCKETS_STRUCT_PTR;
/* Paramter for tasks */
typedef struct t_param
{
uint32_t sock;
unsigned char i;
}TASK_PARAMS, * TASK_PARAMS_PTR;
FILE_PTR debug_uart;
#if !PLATFORM_SDK_ENABLED
//MUTEX_STRUCT tcp2sersockets_mutex;
uint32_t TCP2SERsockets[TCP2SER_SOCKETS_NUMBER]={0};
sockaddr TCP2SERaddresses[TCP2SER_SOCKETS_NUMBER]={0};
uint16_t sockaddr_len;
#define TCP2SERservsock TCP2SERsockets[0]
#define TCP2SERservaddress TCP2SERaddresses[0]
#define TCP2SERVtempsock TCP2SERsockets[TCP2SER_SOCKETS_NUMBER-1]
#define TCP2SERVtempaddress TCP2SERaddresses[TCP2SER_SOCKETS_NUMBER-1]
#define TCP2SERclientsocks(x) TCP2SERsockets[x+1]
MUTEX_STRUCT SER2TCPbuf_mutex;
unsigned char SER2TCPbuf[SER2TCP_BUF_SIZE];
uint16_t SER2TCPbuf_read_index;
uint16_t SER2TCPbuf_write_index;
uint16_t SER2TCPbuf_bytes_avail;
rtcs_fd_set sock_set;
_task_id ctrl_tid[TCP2SER_SOCKETS_NUMBER];
TASK_PARAMS task_p;
unsigned char remote_client_connected=0;
uint32_t tcpclientsock=0;
IPCFG_IP_ADDRESS_DATA my_ip_data;
LWEVENT_STRUCT SER2TCPbuf_events;
/*
** MQX initialization information
*/
void main_task (uint32_t);
void rx_task (uint32_t param);
void tx_task (uint32_t param);
void ctrl_activity_task (uint32_t param);
void write_buffer_task (uint32_t param);
//function
uint32_t chiudisocket(uint32_t sock, uint32_t abort);
void start_server_sock(void);
void SER2TCPWrite(unsigned char *buf, int len);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time Slice */
{MAIN_TASK_INDEX, main_task, 5000, 9, "Bridge", MQX_AUTO_START_TASK, 0, 0 },
{RX_TASK_INDEX, rx_task, 5000, 10, "rxtask", 0, 0, 0 },
{TCP2SER_CTRL_TASK_ID, ctrl_activity_task, 5000, 11, "TCP2SerialControlActivityTask", 0, 0, 0 },
{WRITE_BUFFER_TASK_INDEX, write_buffer_task, 5000, 10, "wbtask", 0, 0, 0 },
{0}
};
typedef uint32_t task_param_t;
#endif
void main_task( task_param_t init_data )
{
IPCFG_IP_ADDRESS_DATA ip_data;
//uint32_t error;
_enet_address enet_addr = ENET_MAC;
uint32_t retval = 0;
_task_id rx_tid,wb_tid;
_task_id tx_tid;
int32_t err;
unsigned char i;
unsigned char t;
_mqx_uint error;
uint8_t j=0;
debug_uart = fopen(SERIAL_DEVICE, "w");
if(debug_uart==NULL){
//_task_block();
}
_io_set_handle(IO_STDERR,debug_uart);
/* Initialize RTCS */
//_RTCSTASK_priority=3;
_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)
{
fputs("Fatal Error: RTCS initialization failed.", stderr);
_task_block();
}
ip_data.ip = ENET_IPADDR;
ip_data.mask = ENET_IPMASK;
ip_data.gateway = ENET_IPGATEWAY;
/* Initialize ethernet */
error = ipcfg_init_device(BSP_DEFAULT_ENET_DEVICE, enet_addr);
if (error != IPCFG_OK)
{
fprintf(stderr, "Fatal Error 0x%X: Network device initialization failed.\n", error);
}
/* Bind static IP address */
error = ipcfg_bind_staticip(BSP_DEFAULT_ENET_DEVICE, &ip_data);
if (error != IPCFG_OK)
{
fprintf(stderr, "Fatal Error 0x%X: IP address binding failed.", error);
}
if(ipcfg_get_ip(BSP_DEFAULT_ENET_DEVICE,&my_ip_data)){
fprintf(debug_uart,"\n\n\rethernet Bound with IP %08X\n", my_ip_data.ip);
}
_mutex_init(&SER2TCPbuf_mutex,NULL);
_lwevent_create(&SER2TCPbuf_events,0);
start_server_sock();
RTCS_FD_ZERO(&sock_set);
RTCS_FD_SET(TCP2SERservsock,&sock_set);
rx_tid=_task_create(0,RX_TASK_INDEX,0);
wb_tid=_task_create(0,WRITE_BUFFER_TASK_INDEX,0);
/*while(1){
_time_delay(1000);
}*/
while(1){
err=select(1,&sock_set,NULL,NULL, 0);//err=RTCS_selectset(TCP2SERsockets,TCP2SER_SOCKETS_NUMBER,0);
if(err==RTCS_ERROR){
//manage error
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 RTCS error");
err=RTCS_get_errno();
PRINTF_DEBUG_TCP2SER(debug_uart, ": %X\n\r",err);
_task_abort(tx_tid);
for (i=0;i<TCP2SER_SOCKETS_NUMBER;i++) {
if (TCP2SERsockets[i]!=0) {
err=chiudisocket(TCP2SERsockets[i],0);//shutdown(TCP2SERsockets[i],FLAG_CLOSE_TX);
if(err!=RTCS_OK){
fprintf(debug_uart, "\n\rtrasparent_8000: rtcs shutdown %d err: 0x%X\n\r",i,err);
//manage
}
RTCS_FD_CLR(TCP2SERsockets[i],&sock_set);
TCP2SERsockets[i]=0;
if (i!=0) {
if (_task_abort(ctrl_tid[i])==MQX_OK) {
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 trasp, rtcs_err aborting ctrl task %d", i);
}
}
}
}
_time_delay(200);
start_server_sock();
RTCS_FD_ZERO(&sock_set);
RTCS_FD_SET(TCP2SERservsock,&sock_set);
}
else if(err==0){//timeout
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 RTCS timeout 8000:");
}
else{//activity
if(RTCS_FD_ISSET(TCP2SERservsock, &sock_set)){//if(err==TCP2SERservsock){//new connection request
//fprintf(stderr,"\n\rtrasparent_8000 Server activity\n\r");
sockaddr_len=sizeof(TCP2SERVtempaddress);
TCP2SERVtempsock=accept(TCP2SERservsock, &TCP2SERVtempaddress, &sockaddr_len);
if(TCP2SERVtempsock==RTCS_SOCKET_ERROR){
fprintf(stderr,"\n\rtrasparent_8000 Server error\n\r");
retval = RTCS_geterror(TCP2SERservsock);
if (retval == RTCS_OK) {
printf("\n\rtrasparent_8000 Connection reset by peer");
} else {
printf("\n\rtrasparent_8000 Error, accept() failed with error code %x",retval);
}
}
else{
for(i=1;i<=TCP2SERIAL_MAX_CLIENT_CONNECTIONS;i++){
if(TCP2SERsockets[i]==0){
break;
}
}
if(i>TCP2SERIAL_MAX_CLIENT_CONNECTIONS){//no connections available
//refuse connection
chiudisocket(TCP2SERVtempsock,0);//shutdown(TCP2SERVtempsock,FLAG_CLOSE_TX);
TCP2SERVtempsock=0;
fprintf(stderr,"\n\rtrasparent_8000 Connection refused\n\r");
}
else{
//Connection is maintained and handle saved
t=TRUE;
setsockopt(TCP2SERVtempsock,SOL_TCP,OPT_RECEIVE_NOWAIT,&t,1);
TCP2SERsockets[i]=TCP2SERVtempsock;
TCP2SERaddresses[i]=TCP2SERVtempaddress;
TCP2SERVtempsock=0;
fprintf(stderr,"\n\rtrasparent_8000 : Accepted connection by %08X, port %d\n\r",TCP2SERaddresses[i].sin_addr.s_addr,TCP2SERaddresses[i].sin_port);
task_p.i = i;
task_p.sock = TCP2SERsockets[i];
ctrl_tid[i]=_task_create(0,TCP2SER_CTRL_TASK_ID, &task_p);
if (ctrl_tid == MQX_NULL_TASK_ID){
fprintf(stderr, "\n\rtrasparent_8000 Impossible to start ctrl task");
}
}
}
}
}
_time_delay(1);
}
}
void rx_task (uint32_t param)
{
unsigned char i;
int32_t ret;
int32_t len;
unsigned char tx_buf[(SER2TCP_BUF_SIZE/2)]={0};
uint16_t tx_buf_index=0;
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 trasparent task on");
_mqx_uint error;
while(1){
//_lwevent_wait_ticks(&SER2TCPbuf_events,0x02,TRUE,200);
_mutex_lock(&SER2TCPbuf_mutex);
tx_buf_index=0;
while(SER2TCPbuf_bytes_avail>0){
tx_buf[tx_buf_index++]=SER2TCPbuf[SER2TCPbuf_read_index++];
SER2TCPbuf_bytes_avail--;
if(SER2TCPbuf_read_index>=SER2TCP_BUF_SIZE){
SER2TCPbuf_read_index=0;
}
if(tx_buf_index>=(SER2TCP_BUF_SIZE/2)){//64){
break;
}
}
_mutex_unlock(&SER2TCPbuf_mutex);
for(i=0;i<TCP2SERIAL_MAX_CLIENT_CONNECTIONS;i++){
if(TCP2SERclientsocks(i)!=0){
ret=send(TCP2SERclientsocks(i),tx_buf,tx_buf_index,0);
if (tx_buf_index!=0) {
PRINTF_DEBUG_TCP2SER(debug_uart,"\n\rtcp2ser SENT:%d bytes to TCP", tx_buf_index);
}
if(ret==RTCS_ERROR){
ret=RTCS_geterror(TCP2SERclientsocks(i));
chiudisocket(TCP2SERclientsocks(i),0);
//if(ret==RTCSERR_SOCK_INVALID){
TCP2SERclientsocks(i)=0;
//}
fprintf(stderr,"tcp2ser trasp tx, RTCS ERR: %x",ret);
}
}
}
_time_delay(1);
}
}
uint32_t chiudisocket(uint32_t sock, uint32_t abort){
struct linger l_options = {0};
uint32_t ret=0;
int32_t mode=0;
int32_t err=0;
//hard close
mode=(int32_t)abort;
// Set linger options for RST flag sending.
l_options.l_onoff = mode;//1=abort, 0=graceful
//l_options.l_linger_ms = 0;
err=setsockopt(sock, SOL_SOCKET, SO_LINGER, (const void*)&l_options, sizeof(l_options));
if (err == RTCS_OK) {
err=closesocket(sock);
}
ret=(uint32_t)err;
return(ret);
}
void start_server_sock(void) {
uint32_t errval;
TCP2SERservsock=socket(PF_INET, SOCK_STREAM, 0);
if (TCP2SERservsock == RTCS_SOCKET_ERROR){
fputs("\n\rtrasparent_8000 Error: Unable to create socket for IPv4 connections.", stderr);
//_task_block();
}
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 created srv sock 0x%X", TCP2SERservsock);
((sockaddr_in*) &TCP2SERservaddress)->sin_family = AF_INET;
((sockaddr_in*) &TCP2SERservaddress)->sin_port = TCP2SERIAL_SERVER_PORT;
((sockaddr_in*) &TCP2SERservaddress)->sin_addr.s_addr = INADDR_ANY;
errval = bind(TCP2SERservsock, &TCP2SERservaddress, sizeof(TCP2SERservaddress));
if(errval != RTCS_OK){
//_task_block();
}
errval = listen(TCP2SERservsock, 0);
if (errval == RTCS_OK){
fprintf(stderr,"\n\rtrasparent_8000 SERV listening on 8000\n\r");
}
else{
//_task_block();
}
}
void ctrl_activity_task (uint32_t param) {
uint32_t sockets_array[2] = {0};
uint32_t err = 0;
unsigned char j = 0;
rtcs_fd_set sock_ctrl_set;
unsigned char tcp_rx_buf[TCP2SER_RX_BUF_SIZE];
j = ((TASK_PARAMS_PTR)param)->i;
sockets_array[0] = ((TASK_PARAMS_PTR)param)->sock;
RTCS_FD_ZERO(&sock_ctrl_set);
RTCS_FD_SET(sockets_array[0],&sock_ctrl_set);
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 start ctrl task for %d sock 0x%x ", j, sockets_array[0]);
while(1){
err=select(1,&sock_ctrl_set,NULL,NULL,TCP2SERIAL_RESET_SOCK_TIME);//err=RTCS_selectset(sockets_array, 1 , TCP2SERIAL_RESET_SOCK_TIME);
if(err==RTCS_ERROR){
//manage error
err = RTCS_get_errno();
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 ctrl rtcs error is: 0x%x ", err);
err=chiudisocket(sockets_array[0],0);
if(err!=RTCS_OK){
fprintf(debug_uart, "\n\rtrasparent_8000 ctrl: Shutdown %d err: 0x%X\n\r",j,err);
//manage
} else {
PRINTF_DEBUG_TCP2SER (debug_uart, "\n\rtrasparent_8000 ctrl: Shutdown sock %d: 0x%X\n\r",j,err);
TCP2SERsockets[j]=0;
}
//End of operations - task kills itself
_task_abort(_task_get_id());
}
else if(err==0){//timeout
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 ctrl RTCS timeout 8000:");
err=chiudisocket(sockets_array[0],0);
if(err!=RTCS_OK){
fprintf(debug_uart, "\n\rtrasparent_8000 ctrl: Shutdown %d err: 0x%X\n\r",j,err);
//manage
} else {
PRINTF_DEBUG_TCP2SER (debug_uart, "\n\rtrasparent_8000 ctrl: Shutdown sock %d: 0x%X\n\r",j,err);
TCP2SERsockets[j]=0;
}
_task_abort(_task_get_id());
} else {
if (RTCS_FD_ISSET(sockets_array[0], &sock_ctrl_set)){
err=recv(sockets_array[0], tcp_rx_buf, TCP2SER_RX_BUF_SIZE, 0);
if(err==RTCS_ERROR){
err = RTCS_geterror(sockets_array[0]);
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 ctrl: recv error for sock %X, is: 0x%x ",sockets_array[0], err);
fprintf(stderr,"\n\rtrasparent_8000 ctrl: Shutting down sock %d",j);
err=chiudisocket(sockets_array[0],0);
if(err!=RTCS_OK){
fprintf(debug_uart, "\n\rtrasparent_8000 ctrl: Shutdown %d err: 0x%X\n\r",j,err);
//manage
}
TCP2SERsockets[j]=0;
_task_abort(_task_get_id());
}
else if(err!=0){
fprintf(debug_uart, "\n\rtrasparent.8000 ctrl Received %d bytes\n",err);
//SerialTxTransparent(tcp_rx_buf,err);
} else if (err==0){
PRINTF_DEBUG_TCP2SER (debug_uart,"\n\rtrasparent_8000 ctrl, err=0");
}
}
}
_time_delay(1);
}
}
void write_buffer_task (uint32_t param){
unsigned char source_buf[SER2TCP_BUF_SIZE]={0};
int buf_len=10;
uint8_t val=0;
uint16_t count=0;
source_buf[1]=0x01;
fprintf(debug_uart, "\n\rstart write buffer task");
while(1){
for (uint8_t l=0;l<10;l++){
for (uint8_t k=0;k<12;k++){
SER2TCPWrite(source_buf,buf_len);
//_time_delay(50);
}
_time_delay(100);
}
fprintf(debug_uart, "\n\rwrite buffer cycle");
_time_delay(100);
}
}
void SER2TCPWrite(unsigned char *buf, int len){
int n;
_mutex_lock(&SER2TCPbuf_mutex);
for(n=0;n<len;n++){
SER2TCPbuf[SER2TCPbuf_write_index++]=buf[n];
if(SER2TCPbuf_write_index>=SER2TCP_BUF_SIZE){
SER2TCPbuf_write_index=0;
}
if(SER2TCPbuf_bytes_avail<SER2TCP_BUF_SIZE){
SER2TCPbuf_bytes_avail++;
}
else{//buffer is already full - overwrites older bytes
SER2TCPbuf_read_index++;
if(SER2TCPbuf_read_index>=SER2TCP_BUF_SIZE){
SER2TCPbuf_read_index=0;
}
}
}
if(SER2TCPbuf_bytes_avail>0){
_lwevent_set(&SER2TCPbuf_events,0x01);
}
if(SER2TCPbuf_bytes_avail>=16){
_lwevent_set(&SER2TCPbuf_events,0x02);
}
_mutex_unlock(&SER2TCPbuf_mutex);
}