Jump to content
43oh

CC3200 : How to reduce TCP Connect Timeout when there's no internet?


Recommended Posts

Hello,

 

In the case there's no internet and I'm trying to connect to a TCP Server on the CC3200 using the following statement

tcp.connect(remote_ip, remote_port)    // WiFiClient.connect

My program hangs for 30 SECONDS on the above statement.

 

Is there a library file where I can reduce this timeout to something more reasonable like 5 seconds?

 

Thanks!

Link to post
Share on other sites
  • 2 years later...

This is currently not supported as posted in this thread: https://e2e.ti.com/support/wireless_connectivity/simplelink_wifi_cc31xx_cc32xx/f/968/p/465212/1670436#1670436

 

What you can do is to change WiFiClient.ccp's connect function to make the connect non-blocking with sl_SetSockOpt(socketHandle, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &enableOption, sizeof(enableOption)); sl_Connect will then return immediately regardless of successful connection. Then change the code after connect to something like posted here: https://e2e.ti.com/support/wireless_connectivity/simplelink_wifi_cc31xx_cc32xx/f/968/t/473029

 

It might be a good idea for the WiFi library to support a connect() with optional timeout. Unfortunately I won't be able to get to that in the near future.

Link to post
Share on other sites

Hi,

 

I tried that code mentioned in the above link. But something is not matching. I made changes in my wificlient.cpp file but did not get any fruitful result.

Can you or anyone from your engineering team provide me the code for connect() function in nonblocking mode? 
Link to post
Share on other sites

Below is the replacement WiFiClient::connect() function. Right now the timeout is hardcoded but you can add an extra parameter for the timeout.

Please not that if you call WiFiClient::connect(const char* host, uint16_t port) a host lookup is done which eventually results in calling sl_NetAppDnsGetHostByName() this call seems to timeout after 20 sec if you do not have an internet connection (e.g. WAN cable unplugged from the router). Unfortunately this function does not feature a timeout. So to have control over the timeout, use the ip address of the host in the connect rather than the hostname.

int WiFiClient::connect(IPAddress ip, uint16_t port)
{
    int iRet = 0;
    //
    //this function should only be called once and only on the client side
    //
    if (_socketIndex != NO_SOCKET_AVAIL) {
        return false;
    }
    
    //
    //get a socket index and attempt to create a socket
    //note that the socket is intentionally left as BLOCKING. This allows an
    //abusive user to send as many requests as they want as fast as they can try
    //and it won't overload simplelink.
    //
    int socketIndex = WiFiClass::getSocket();
    if (socketIndex == NO_SOCKET_AVAIL) {
        return false;
    }

    int socketHandle = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_IPPROTO_TCP);
    if (socketHandle < 0) {
        return false;
    }

    //
    //connect the socket to the requested IP address and port. Check for success
    //

    long nonBlocking  = 1;
    iRet = sl_SetSockOpt(socketHandle, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlocking, sizeof(nonBlocking));

    SlSockAddrIn_t server = {0};
    server.sin_family = SL_AF_INET;
    server.sin_port = sl_Htons(port);
    server.sin_addr.s_addr = ip;
    iRet = sl_Connect(socketHandle, (SlSockAddr_t*)&server, sizeof(SlSockAddrIn_t));

    Serial.print("iRet = ");
    Serial.println(iRet);

    if (iRet < 0) {
        if (iRet != SL_EALREADY)
        {
            sl_Close(socketHandle);
            return false;
        }

       SlTimeval_t timeout;
       timeout.tv_sec = 10;
       timeout.tv_usec = 500;
 
       SlFdSet_t WriteFds;
       SL_FD_ZERO(&WriteFds);
       SL_FD_SET(socketHandle, &WriteFds);
       iRet = sl_Select(socketHandle + 1, NULL, &WriteFds, NULL, &timeout);

       if (iRet > 0) {
           if (SL_FD_ISSET(socketHandle, &WriteFds)) {
                iRet = sl_Connect(socketHandle, (SlSockAddr_t*)&server, sizeof(SlSockAddrIn_t));
                if(iRet < 0) {
                    sl_Close(socketHandle);
                    return false;
                } else {
                   // Success. Nothing to do.
                }
           }
       } else if(iRet == 0) {
           // Timeout
           sl_Close(socketHandle);
           return false;
       } else {
           // Connection error
           sl_Close(socketHandle);
           return false;
       }
    }

    int enableOption = 1;
    sl_SetSockOpt(socketHandle, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &enableOption, sizeof(enableOption));
    sl_SetSockOpt(socketHandle, SL_SOL_SOCKET, SL_SO_KEEPALIVE, &enableOption, sizeof(enableOption));

    //
    //we've successfully created a socket and connected, so store the
    //information in the arrays provided by WiFiClass
    //
    _socketIndex = socketIndex;
    WiFiClass::_handleArray[socketIndex] = socketHandle;
    WiFiClass::_typeArray[socketIndex] = TYPE_TCP_CLIENT;
    WiFiClass::_portArray[socketIndex] = port;
    return true;
}

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...