This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3100MOD: Problem with TCP socket, SL_ENOTCONN

Part Number: CC3100MOD
Other Parts Discussed in Thread: CC3100, MSP430F5529, CC3100BOOST,

Hello,

I have a problem with sending data from device to PC over TCP socket.

Everything is working fine except one thing: I'm getting series of SL_ENOTCONN errors with my socket being hardly disconnected.

When I met this problem first, there was huge load on the wi-fi network with many delays. When I started to dig inside this problem I tried to run SpeedTest.Net on my mobile phone. It gave me 100% chance to get SL_ENOTCONN. After this I simply made a program, in which I may stop receiving data from the socket. Then I found that if I continuously send data from CC3100 device to software, and software is not receiving them from the socket, I get SL_ENOTCONN error in 10 seconds.

This situation is stable, no matter I use blocking or non-blocking sockets. I tried sl_Select - no difference.

Also I have tried to look at g_pCB->g_pCB->FlowContCB.TxPoolCnt. But even if only one Tx block is busy and can not be sent in 10 seconds I will get SL_ENOTCONN. I have tried with different block size from 10 to 1000 bytes - no result.

I have tried different Service Packs: 1.0.0.10.0 (NWP 2.0.4.2),  1.0.1.11 (NWP 2.10.0.0), 1.0.1.13 (NWP 2.11.0.1).

I am using SDK 1.20 but tried with 1.30 also - they differ very slightly.

The questions are: What to do with this situation and why TCP socket breaks? Is there some method to keep the TCP socket alive?

Thank you for any help!!!

Here is the code:

#include "simplelink.h"
#include "sl_common.h"
#include "types.h"
#include "stdlib.h"
#include "cli_uart.h"
#include "board.h"
#include "protocol.h"
#include "driver.h"

#define APPLICATION_VERSION "1.2.0"

#define SL_STOP_TIMEOUT        0xFF

#define PORT_NUM        5001            /* Port number to be used */

int sl_Role;

_u8 g_Status = 0;
_u32 Wifi_Ip = 0;
_u32 g_GatewayIP = 0;

#define SL_WIFI_BUFFER_SIZE 1400
static BYTE Wifi_Buffer[SL_WIFI_BUFFER_SIZE];

static int initializeAppVariables();

void CLI_ip (PBYTE cString, _u32 ip);
void CLI_addr (PBYTE cString, SlSockAddrIn_t* Addr);


void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
{
    CLI_Write("WLAN EVENT - ");
    if(pWlanEvent == NULL)
    {
        CLI_Write(" [WLAN EVENT] NULL Pointer Error \n\r");
        return;
    }

    switch(pWlanEvent->Event)
    {
    case SL_WLAN_CONNECT_EVENT:
        {
            CLI_Write("SL_WLAN_CONNECT_EVENT\n\r");
            SET_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION);

            /*
             * Information about the connected AP (like name, MAC etc) will be
             * available in 'slWlanConnectAsyncResponse_t' - Applications
             * can use it if required
             *
             * slWlanConnectAsyncResponse_t *pEventData = NULL;
             * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected;
             *
             */
        }
        break;

    case SL_WLAN_DISCONNECT_EVENT:
        {
            slWlanConnectAsyncResponse_t*  pEventData = NULL;

            CLR_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION);
            CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);

            pEventData = &pWlanEvent->EventData.STAandP2PModeDisconnected;

            /* If the user has initiated 'Disconnect' request, 'reason_code' is
             * SL_USER_INITIATED_DISCONNECTION */
            if(SL_USER_INITIATED_DISCONNECTION == pEventData->reason_code)
            {
                CLI_Write(" Device disconnected from the AP on application's request \n\r");
            }
            else
            {
                CLI_Write(" Device disconnected from the AP on an ERROR!! \n\r");
            }
        }
        break;

    case SL_WLAN_STA_CONNECTED_EVENT:
        {
            SET_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED);
            CLI_Write("SL_WLAN_STA_CONNECTED_EVENT\r\n");
        }
        break;

    case SL_WLAN_STA_DISCONNECTED_EVENT:
        {
            CLR_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED);
            CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED);
            CLI_Write ("SL_WLAN_STA_DISCONNECTED_EVENT\r\n");
        }
        break;

    case SL_WLAN_SMART_CONFIG_COMPLETE_EVENT:
        {
            CLI_Write("SL_WLAN_SMART_CONFIG_COMPLETE_EVENT\r\n");
        }
        break;

    case SL_WLAN_SMART_CONFIG_STOP_EVENT:
        {
            CLI_Write("SL_WLAN_SMART_CONFIG_STOP_EVENT\r\n");
        }
        break;

    case SL_WLAN_P2P_DEV_FOUND_EVENT:
        {
            CLI_Write("SL_WLAN_P2P_DEV_FOUND_EVENT\r\n");
        }
        break;

    case SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT:
        {
            CLI_Write("SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT\r\n");
        }
        break;

    case SL_WLAN_CONNECTION_FAILED_EVENT:
        {
            CLI_Write("SL_WLAN_CONNECTION_FAILED_EVENT\r\n");
            CLI_msg("status = ",pWlanEvent->EventData.P2PModewlanConnectionFailure.status);
        }
        break;

    default:
        {
            CLI_Write("[WLAN EVENT] Unexpected event \n\r");
        }
        break;
    }
}


void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
{
    CLI_Write ("NET APP EVENT - ");
    if(pNetAppEvent == NULL)
    {
        CLI_Write(" [NETAPP EVENT] NULL Pointer Error \n\r");
        return;
    }

    switch(pNetAppEvent->Event)
    {
    case SL_NETAPP_IPV4_IPACQUIRED_EVENT:
        {
            CLI_Write("SL_NETAPP_IPV4_IPACQUIRED_EVENT\r\n");
            SlIpV4AcquiredAsync_t *pEventData = NULL;
            SET_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);

            /*
             * Information about the connection (like IP, gateway address etc)
             * will be available in 'SlIpV4AcquiredAsync_t'
             * Applications can use it if required
             *
             * SlIpV4AcquiredAsync_t *pEventData = NULL;
             * pEventData = &pNetAppEvent->EventData.ipAcquiredV4;
             *
             */
            pEventData = &pNetAppEvent->EventData.ipAcquiredV4;
            g_GatewayIP = pEventData->gateway;
            Wifi_Ip = pEventData->ip;
            CLI_ip("Gateway: ",g_GatewayIP);
            CLI_ip("Ip: ",Wifi_Ip);
        }
        break;

    case SL_NETAPP_IP_LEASED_EVENT:
        {
            CLI_Write("SL_NETAPP_IP_LEASED_EVENT\r\n");
            SET_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED);
            CLI_ip("Station ip is ",pNetAppEvent->EventData.ipLeased.ip_address);
        }
        break;

    case SL_NETAPP_IP_RELEASED_EVENT:
        {
            CLI_Write("SL_NETAPP_IP_RELEASED_EVENT\r\n");
        }
        break;

        default:
        {
            CLI_Write("[NETAPP EVENT] Unexpected event \n\r");
        }
        break;
    }
}


void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pEvent,
                                  SlHttpServerResponse_t *pResponse)
{
    CLI_Write ("[HTTP EVENT]\n\r");
    if(pEvent == NULL || pResponse == NULL)
    {
        CLI_Write(" [HTTP EVENT] NULL Pointer Error \n\r");
        return;
    }
}


void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
{
    /*
     * Most of the general errors are not FATAL are are to be handled
     * appropriately by the application
     */
    CLI_Write(" [GENERAL EVENT] \n\r");
}


void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
{
    if(pSock == NULL)
    {
        CLI_Write(" [SOCK EVENT] NULL Pointer Error \n\r");
        return;
    }

    switch( pSock->Event )
    {
        case SL_SOCKET_TX_FAILED_EVENT:
            /*
             * TX Failed
             *
             * Information about the socket descriptor and status will be
             * available in 'SlSockEventData_t' - Applications can use it if
             * required
             *
            * SlSockEventData_u *pEventData = NULL;
            * pEventData = & pSock->socketAsyncEvent;
             */
            switch( pSock->socketAsyncEvent.SockTxFailData.status )
            {
                case SL_ECLOSE:
                    CLI_Write(" [SOCK EVENT] Close socket operation, failed to transmit all queued packets\n\r");
                    break;
                default:
                    CLI_msg(" [SOCK EVENT] Unexpected TX fail event ",pSock->socketAsyncEvent.SockTxFailData.status);
                    break;
            }
            break;

        case SL_SOCKET_ASYNC_EVENT:
            CLI_Write (" [SOCK EVENT] Socket async event\r\n");
            CLI_msg (" SockAsyncData.sd = ",pSock->socketAsyncEvent.SockAsyncData.sd);
            CLI_msg (" SockAsyncData.type = ",pSock->socketAsyncEvent.SockAsyncData.type);
            CLI_msg (" SockAsyncData.val = ",pSock->socketAsyncEvent.SockAsyncData.val);
            break;

        default:
            CLI_msg(" [SOCK EVENT] Unexpected event ",pSock->Event);
            break;
    }
}


int __low_level_init()
{
    stopWDT();
    return 1;
}


void setVcoreUp(WORD level)
{
    // Open PMM registers for write
    PMMCTL0_H = PMMPW_H;
    // Set SVS/SVM high side new level
    SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
    // Set SVM low side to new level
    SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
    // Wait till SVM is settled
    while ((PMMIFG & SVSMLDLYIFG) == 0);
    // Clear already set flags
    PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
    // Set VCore to new level
    PMMCTL0_L = PMMCOREV0 * level;
    // Wait till new level reached
    if (PMMIFG & SVMLIFG)
        while ((PMMIFG & SVMLVLRIFG) == 0);
    // Set SVS/SVM low side to new level
    SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
    // Lock PMM registers for write access
    PMMCTL0_H = 0x00;
}


int SwitchToXT2();
void InitClock()
{
    SwitchToXT2();
}


void main()
{
    __disable_interrupt();

    int retVal = initializeAppVariables();

    InitClock();

    CLI_Configure();
    
    __enable_interrupt();

    CLI_Write("\r\n\r\n****\r\nTCP socket test application\r\nSL_ENOTCONN issue\r\n*****\r\n");
    
Start:    
    sl_Role = sl_Start(0,0,0);
    if (sl_Role != ROLE_STA) {
        sl_WlanSetMode(ROLE_STA);
        sl_Stop(200);
        sl_Role = sl_Start(0,0,0);
    }
   
    sl_WlanProfileDel(0xff);
    
    char const ssid[] = "SOMENETWORK";
    char const key[] = "12345678";
    SlSecParams_t sec_params;
    sec_params.Type = SL_SEC_TYPE_WPA_WPA2;
    sec_params.Key = (_i8*)key;
    sec_params.KeyLen = strlen(key);
    sl_WlanProfileAdd((_i8*)ssid,strlen(ssid),0,&sec_params,0,0,0);

    // Enable DHCP client
    _u8 val = 1;
    sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val);

    // Set Tx power level for station mode
    _u8 power = 0;
    sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (_u8 *)&power);

    // Set PM policy to normal
    sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);

    // Unregister mDNS services
    sl_NetAppMDNSUnRegisterService(0, 0);

    // Remove  all 64 filters (8*8)
    _WlanRxFilterOperationCommandBuff_t  RxFilterIdMask = {0};
    memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
    sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask,sizeof(_WlanRxFilterOperationCommandBuff_t));
    
    sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 0), NULL, 0);
   
    while (1) {
        sl_Task();
        if ((IS_CONNECTED(g_Status)) && (IS_IP_ACQUIRED(g_Status))) {
            CLI_Write(" Connection established w/ AP and IP is acquired\r\n");
            CLI_ip("IP address: ",Wifi_Ip);
            CLI_ip("Gateway: ",g_GatewayIP);
            break;
        }
    }

    CLI_Write("Connection to AP established\r\n");
    
    SlSockAddrIn_t LocalAddr;
    SlSocklen_t AddrSize;
    int Status;

    int TcpSockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
    
    SlInAddr_t ClientIpAddr = {0};
    int ClientSockID = -1;

    LocalAddr.sin_family = SL_AF_INET;
    LocalAddr.sin_port = sl_Htons((_u16)5001);
    LocalAddr.sin_addr.s_addr = 0;

    AddrSize = sizeof(SlSockAddrIn_t);
    Status = sl_Bind(TcpSockID, (SlSockAddr_t *)&LocalAddr, AddrSize);
    if( Status < 0 ) {
        CLI_msg("sl_Bind error ",Status);
        sl_Close(TcpSockID);
        TcpSockID = -1;
        LOOP_FOREVER();
    }
    CLI_Write ("Tcp socket bound\r\n");

    Status = sl_Listen(TcpSockID, 0);
    if( Status < 0 ) {
        CLI_msg("sl_Listen error ",Status);
        sl_Close(TcpSockID);
        TcpSockID = -1;
        LOOP_FOREVER();
    }
    
Reconnect:
    CLI_Write ("Listening on port 5001...\r\n");

    SlSockAddrIn_t TcpAddrIn;
    AddrSize = sizeof(TcpAddrIn);
    Status = sl_Accept(TcpSockID, (SlSockAddr_t *)&TcpAddrIn, &AddrSize);
    if (Status > 0) {
        ClientSockID = Status;
        ClientIpAddr = TcpAddrIn.sin_addr;
        CLI_ip("Connected client ", ClientIpAddr.s_addr);
    } else {
        CLI_msg("sl_Accept error ",Status);
        LOOP_FOREVER();
    }

    int BufSize = 1000;
    BYTE value;
    
    while (1) {
        sl_Task();
        value = ((value - 0x1f) & 0x3f) + 0x20;
        for (int i = 0; i < BufSize; i++) {
            Wifi_Buffer[i] = value;
        }
        Wifi_Buffer[BufSize-1] = 0x0d;
        Wifi_Buffer[BufSize-2] = 0x0a;
        Status = sl_Send(ClientSockID, (PBYTE)&Wifi_Buffer,BufSize,0);
        if (Status < 0) {
            CLI_msg("sl_Send error ",Status);
            break;
        }
        if (Status == 0) {
            break;
        }
        if (Status != BufSize) {
            CLI_msg("Wrote less bytes - ",Status);
        }
        CLI_msg("TxPoolCnt = ",g_pCB->FlowContCB.TxPoolCnt);
    }
    
    sl_Close(ClientSockID);
    ClientSockID = -1;
    CLI_Write("Socket closed\r\n");
    //sl_Close(TcpSockID);
    goto Reconnect;
}


static int initializeAppVariables()
{
    g_Status = 0;
    return SUCCESS;
}

  • Hello,

    The error you're getting indicates the socket never establishes connection. What host MCU are you using? Are you able to successfully connect to an AP? You should stick to SDK 1.3.0 and service pack 1.0.1.13-2.11.0.1.

    Jesu
  • hi Yuri
    Jan is correct even I tested your code but have to do changes in it then only it worked for me.
  • Hello,

    thanks for answer!

    My hardware now is TI's launchpad MSP430F5529. I'm using launchpad with CC3100BOOST pcb.

    Yes, I can successfully connect to AP, I can connect to TCP port and receive data. All is working fine. The question is following:

    if I just STOP doing recv() in my software, all unsent packets are stored in CC3100MOD's Tx buffer pool, and after 10 seconds the module gives me SL_ENOTCONN several time and socket becomes dead. After this I can close the socket (with more SL_ENOTCONNs), connect to it without disconnecting from network and continue to send data again. I don't like this RECONNECT stage, because software is unable to see that the socket is broken and continues to wait for data.

    The device is pingable all the time.

    Yuri

  • Hi Yuri,

    I'm confused I thought you said all is working fine? I do not see what your question is.

    Jesu
  • Hi again,
    The question is: why CC3100MOD breaks the socket in 10 seconds if unsent packets are still waiting for transmission? Is it normal or not?
  • Hello,

    Have you tried checking the SimpleLink event handlers to see if the NWP notified the host of any failures? Maybe you get a disconnect event from wlan event handler during normal operation or something from the sock event handler. Try also checking if you get something in netapp event handler.

    Jesu
  • Hello,
    I do not receive any other events except SL_SOCKET_TX_FAILED_EVENT with status SL_ENOTCONN.
    Wifi connection is staying alive and my TcpSocket is successfully listening, as you can see from the code.
    Only one socket, that I create with sl_Accept() is broken.
    Yuri
  • Yuri,

    Could you provide console log of what your program is outputting? I do not see anything concerning in your code at first glance.

    Jesu