Hello,
I have an application in which I am creating a connection using the WIP package to a server and sending periodic data. When the server receives the data it sends an “OK”. I use a timeout for the response of the data and if I do not receive a response in a set period of time, I disconnect and reconnect to the server to guarantee that I do not take to long to realize when the server is not available.
The software when it reconnects retries every 30 seconds to reconnect , using the connect2server function below, and if I have no positive connection indication after 15 seconds, I disconnect using the closeConnection function below and then 30 seconds later, I try to reconnect again.
//open connection
void connect2Server(void)
{
adl_atSendResponse ( ADL_AT_UNS, “Try to connect to server\n”);
socket = wip_TCPClientCreateOpts ( TCP_PEER_DATUS, TCP_PEER_PORT, cbevh, NULL,
WIP_COPT_SND_BUFSIZE, 3000, WIP_COPT_MAXSEG, 1500, WIP_COPT_END );
if ( !socket ) //we will not do anything here, if there is an error we will retry later
{
adl_atSendResponse ( ADL_AT_UNS, “Error on create TCP socket\n”);
return;
}
}
//close connection
void closeConnection(void)
{
adl_atSendResponse ( ADL_AT_UNS, “close connection\n”);
wip_close(socket);
connected = 0; //indicates that we are not connected.
}
//connection handler
static void cbevh ( wip_event_t *ev, void *ctx )
{
//adl_atSendResponse ( ADL_AT_UNS, “\r\nEvent\r\n” );
switch ( ev->kind )
{
case WIP_CEV_DONE:
{
adl_atSendResponse ( ADL_AT_UNS, "Got Done from Socket\n");
break;
}
//this means that we have an open from the socket
case WIP_CEV_OPEN:
{
TRACE ( ( NORMAL_TRACE_LEVEL, "[SAMPLE] Connection established successfully" ) );
adl_atSendResponse ( ADL_AT_UNS, "Got Open from Socket\n");
setCanSend();
connected=1; //this I use to know that I am connected
break;
}
case WIP_CEV_READ:
{
//application specific read data logic
}
case WIP_CEV_WRITE:
{
//application specific write logic
}
//this indicates that we have an error from the socket in which case we close
//the socket
case WIP_CEV_ERROR:
{
reportError(ERR_TYPE_SERVER, ERR_SOCKET);
adl_atSendResponse ( ADL_AT_UNS, "Got Error from Socket\n");
TRACE ( ( ERROR_TRACE_LEVEL, "[SAMPLE] Error %i on socket. Closing.", ev->content.error.errnum ) );
closeConnection();
//wip_close ( ev->channel );
break;
}
//this indicates that the server closed the socket
case WIP_CEV_PEER_CLOSE:
{
reportError(ERR_TYPE_SERVER, ERR_SESSION_CLOSED_BY_SERVER);
adl_atSendResponse ( ADL_AT_UNS, "Got Peer Close from Socket\n");
TRACE ( ( NORMAL_TRACE_LEVEL, "[SAMPLE] Connection closed by peer" ) );
closeConnection();
//wip_close ( ev->channel );
break;
}
//there should be no default
default:
{
break;
}
}
}
The system above works quite well most of the time, however we have had some occasions where our server crashes (not a topic for this forum, but is why I have detected this situation) and does not do a clean disconnect. Even in this case the system normally works ok, but I occasionally have the modem arrive in a situation where the modem does the connect2server logic (without any indication of an error) and then returns to the closeConnection in 15 seconds without any error or connection indication arriving (neither at the modem or at the server). This gives
“Try to connect to server”
(15 seconds)
“close connection”
(15 seconds)
(repeat above indefinitely, at least for as long as I have had patience to let it continue)
If I stop the application software and restart it, all is well. I believe that I could do a reset using an AT+FUN=1 command to clean up the stack, but I am trying to avoid this as I am keeping a FIFO of data in the application and do not want to lose this data without sending it.
Any ideas of how to get out of the situation if it occurs, or any logic errors that I have in the above architecture?
Any help is appreciated,