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.

CC3100 - tcp/ip connection and disconnection cycle cause host MCU to reset

Other Parts Discussed in Thread: CC3100

Hi Everyone,

I set up CC3100 to AP mode, 3 tcp/ip servers: listen to port #23, #80, and #8080.

the host application call sl_accept to establish new connection and sl_close to close the client socket ID.

I have been using Teraterm and wrote a Teraterm macro script to test the connection and disconnection.  First client connect to port 8080, pause 250ms, disconnect, pause 250ms; secondly client connect to port #80, pause 250ms, disconnect, pause 250ms; Finaly client connect to port #23, pause 250ms, disconnect, pause 250ms. Then repeat the cycle.

The issue is the test runs for about 15 minutes then Host MCU reset.

Here is the Teraterm macro script:

while 1

connect '192.168.0.1:8080'
mpause 250

disconnect 0
mpause 250

connect '192.168.0.1:80'
mpause 250

disconnect 0
mpause 250

connect '192.168.0.1:23'
mpause 250

disconnect 0
mpause 250

endwhile

CC3100 has ip address of: 192.168.0.1, client has ip address of 192.168.0.100.

Why CC3100 caused the host to reset?

Thanks,

Dennis

  • Dennis,

    Which is your host platform? Can you please repeat the test w/ SLS? Meanwhile, I'll try to reproduce it on my setup here.

    -Praneet

  • Praneet,

    The host platform is Microchip PIC24EP512GU810. I set the server sockets to non blocking mode. It could be get in one of wait forever and my host cpu watchdog kicked in.

    Could you tell me what is SLS. I'm not using security.

    Thanks,

    Dennis

  • Dennis,

    I was referring to SimpleLink Studio, a windows based tool to aid development of n/w applications on desktop IDEs - CC3100-SDK has projcts for Visual-Studio and Eclipse. My request for you was to replicate the issue on this platform.

    -/Praneet

  • Praneet,

    I'm not using the SimpleLink Studio and don't have plan to use it. I think my host and the SimpleLink Studio will behave the same when using the SimpleLink library.

    Thanks and regards,

    Dennis

  • Hi Dennis,

    I have tried to run this test case on my setup with cc3100 and the test seems to run for a long time without any issue. I am using the service pack 1.0.0.1.2. What version of SDK and service pack are you using to test this issue?

    Can you please share the network/air capture logs if you have for this scenario? Sharing your code snippet will also be helpful in re-creating the issue.

    Regards,
    Raghavendra

  • Raghavendra,

    I am using service pack 1.0.0.1.2.

    Can you send me your test code? Here is my code:

    4380.cc3100_code_example.c
    _i32 wifi_service_socket(_i16 *serverSockID, _i16 *clientSockID,
                             WIFI_SOCKET_STATUS_E *sockStatus)
    {
        SlSockAddrIn_t  Addr;
        SlSockAddrIn_t  LocalAddr;
    
        _u16 idx = 0;
        _u16 AddrSize = 0;
    
        _i16 i = 0;
        _i32 Status = 0;
        _i16 recvSize = 0;
    
        *sockStatus = WIFI_SOCKET_INACTIVE;
    
        recvSize = BUF_SIZE;
        if (NETWORK_NO_SOCKET == *clientSockID) {
            *clientSockID = sl_Accept(*serverSockID, ( struct SlSockAddr_t *)&Addr,
                                      (SlSocklen_t*)&AddrSize);
    
            if (0 < *clientSockID) {
                *sockStatus = WIFI_SOCKET_CONNECT;
    
                return SUCCESS;
            }
        }
    
        if ((SL_EAGAIN == *clientSockID) ||
            (SL_ENSOCK == *clientSockID) ||
            (SL_POOL_IS_EMPTY == *clientSockID) ||
            (SL_INEXE == *clientSockID)) {
            CLI_Write(" [TCP Server] SL_EAGAIN\n\r");
            *clientSockID = NETWORK_NO_SOCKET;
        }
        else if (0 > *clientSockID) {
            sl_Close(*clientSockID);
            *serverSockID = NETWORK_NO_SOCKET;
    
            send_uart_string_hex(SERIALIN, (char *)clientSockID, 1);
            CLI_Write(" [TCP Server] Accept connection Error \n\r");
            ASSERT_ON_ERROR(*clientSockID);
        }
        else {
    
            /* Connection had been made */
            Status = sl_Recv(*clientSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), recvSize, 0);
            if (0 < Status) {
    
                /* There is data */
                *sockStatus = WIFI_SOCKET_DATA;
                g_recvSize  = Status;
    
            }
            else if ((Status != SL_EAGAIN) && (Status != SL_POOL_IS_EMPTY)) {
                /* connection closed */
                CLI_Write("status == 0\n\r");
    
                /* Already disconnected */
                Status = sl_Close(*clientSockID);
                *clientSockID = NETWORK_NO_SOCKET;
    
                *sockStatus = WIFI_SOCKET_DISCONNECT;
            }
            else {
                /* Timeout ??? */
                *sockStatus = WIFI_SOCKET_TIMEOUT;
            }
        }
    
        return SUCCESS;
    }
    
    void telnet_server_service_request(void)
    {
        signed short retVal = 0;
    
        WIFI_SOCKET_STATUS_E sockStatus = 0;
    
        __eds__ unsigned char *temp_data_out_ptr = NULL;
        TELNET_SERVER_CB *telnet_cb_ptr, *top_telnet_ptr;
    
    
        top_telnet_ptr = &telnet_server_cb[TELNET_PORT_CT];
        for (telnet_cb_ptr = &telnet_server_cb[0];
            telnet_cb_ptr < top_telnet_ptr; telnet_cb_ptr++) {
    
            wifi_service_socket(&g_telnet_SockID,
                                &telnet_cb_ptr->tcp_socket_index,
                                &sockStatus);
    
            switch (sockStatus) {
                case WIFI_SOCKET_CONNECT:
                    /* Connected */
                    send_uart_string(SERIALIN, "TN Conn\r\n", 9);
                    telnet_cb_ptr->telnet_session_state = TELNET_CONNECTED;
    
                    ImsNetConnected = TRUE;
    
                    break;
                case WIFI_SOCKET_DISCONNECT:
                    /* Disconnected */
                    reset_single_telnet_cb(telnet_cb_ptr);
    
                    // if no telnet connect ???
                    ImsNetConnected = FALSE;
                    break;
                case WIFI_SOCKET_DATA:
    
                    if (TELNET_CONNECTED == telnet_cb_ptr->telnet_session_state) {
                        /* Has data */
                        wifi_read_data_eds(&telnet_cb_ptr->cmd_in_ptr,
                                           telnet_cb_ptr->cmd_top,
                                           telnet_cb_ptr->cmd_base,
                                           &telnet_cb_ptr->cmd_ct);
                    }
                    else {
                        telnet_cb_ptr->telnet_session_state = TELNET_DISCONN_REQUESTED;
                    }
    
                    break;
                case WIFI_SOCKET_TIMEOUT:
                    /* Timeout */
                    break;
                case WIFI_SOCKET_INACTIVE:
                    break;
    
                default:
                    break;
            }
    
            switch (telnet_cb_ptr->telnet_session_state) {
                case TELNET_CONNECTED:
                    if (0 < telnet_cb_ptr->cmd_ct) {
    
                        telnet_process_cmd(telnet_cb_ptr);
                    }
    
                    if (telnet_cb_ptr->data_ct) {
    
                        retVal = wifi_write_data_eds(telnet_cb_ptr->data_out_ptr,
                                                     telnet_cb_ptr->data_top,
                                                     telnet_cb_ptr->data_base,
                                                     telnet_cb_ptr->data_ct,
                                                     telnet_cb_ptr->tcp_socket_index);
    
                        if (0 < retVal) {
                            telnet_cb_ptr->data_ct -= retVal;
    
                            temp_data_out_ptr = telnet_cb_ptr->data_out_ptr + retVal;
                            if (temp_data_out_ptr >= telnet_cb_ptr->data_top) {
                                telnet_cb_ptr->data_out_ptr = telnet_cb_ptr->data_base +
                                                              (retVal -
                                                               (telnet_cb_ptr->data_top - telnet_cb_ptr->data_out_ptr));
                            }
                            else {
                                telnet_cb_ptr->data_out_ptr = temp_data_out_ptr;
                            }
                        }
                        else {
                            //????
                            telnet_cb_ptr->data_ct = 0;
                        }
                    }
                    break;
    
                case TELNET_DISCONN_REQUESTED:
                    if (0 == telnet_cb_ptr->data_ct) {
                        retVal = sl_Close(telnet_cb_ptr->tcp_socket_index);
                        if (0 == retVal) {
                            telnet_cb_ptr->telnet_session_state = TELNET_DISCONN_SENT;
                            telnet_cb_ptr->telnetTmrTick = TEN_S_PER_TEN_MS;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
    
    _i32 wifi_write_data_eds(__eds__ _u8 *src_ptr, __eds__ _u8 *top_ptr,
                             __eds__ _u8 *base_ptr, _u16 dataLength,
                             _i16 clientSockID)
    {
        _i32 retVal = -1;
        _i16 i = 0;
        _u8 *dstDataPtr = NULL;
    
        dstDataPtr = &uBuf.BsdBuf[0];
    
        for (i = 0; i < BUF_SIZE && i < dataLength; i++, dstDataPtr++) {
    
            *dstDataPtr = *src_ptr;
    
            src_ptr++;
            if (src_ptr == top_ptr) {
                src_ptr = base_ptr;
            }
        }
    
        retVal = sl_Send(clientSockID, &(uBuf.BsdBuf[0]), i, 0);
    
        return retVal;
    }
    
    

    Thanks,

    Dennis

  • Hi Dennis,

    For this scenario, I am using the sample SDK example of "tcp_socket".


    The changes to this application are:

    1. Added changes to start in AP mode.

    2. I am disabling the internal HTTP server.

    3. I have made the socket non-blocking.

    4. I am exercising the function 'BsdTcpServer' in a loop as shown below. I am using this application with a TCP client as you have described above, and I have never encountered a Reset.

    while(1)
    {
    	retVal = BsdTcpServer(8080);
    	if(retVal < 0)
    		CLI_Write(" Failure on port 8080\n\r");
    	else
    		CLI_Write(" Success on port 8080 \n\r");
    
    	retVal = BsdTcpServer(80);
    	if(retVal < 0)
    		CLI_Write(" Failure on port 80\n\r");
    	else
    		CLI_Write(" Success on port 80 \n\r");
    
    	retVal = BsdTcpServer(23);
    	if(retVal < 0)
    		CLI_Write(" Failure on port 23 \n\r");
    	else
    		CLI_Write(" Success on port 23 \n\r");
    }

    Regards,
    Raghavendra

  • Hi Dennis,

    Can you please answer below queries?

    1. How are you powering the CC3100?

    2. Is it a custom board that you are using? Or are you connecting the CC3100 to the MCU using jumper wires?

    3. In your sample application, can you please check the return value of the Status = sl_Close(*clientSockID); when you get SL_EAGAIN for sl_Recv?

    Regards,
    Raghavendra

  • Hi Raghavendra,

    1. I used both methods: method 1 - use power from my board: 3.3v and 5v. method 2: USB

    2. I'm using CC3100BoosterPack with jumper wires.

    3. I don't call sl_close() function when sl_recv return SL_AGAIN.

    Here is part of the code:

    Status = sl_Recv(*clientSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), recvSize, 0);
    if (0 < Status) {
        /* Echo test */
        //sl_Send(*clientSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), Status, 0);
    }
    else if ((Status != SL_EAGAIN) && (Status != SL_POOL_IS_EMPTY)) {
          CLI_Write("status < 0\n\r");
    
        /* Already disconnected */
        Status = sl_Close(*clientSockID);
        *clientSockID = 0;
    }
    else {
        /* Timeout ??? */
    }
    

    Regards,

    Dennis

  • Hi Raghavendra,

    Have you modified the BsdTcpServer() function. If yes, could you post your code?

    In my case, I don't close the server socket. I setup the 23, 80, and 8080 servers once.

    During the test, servers accept connection, read data, and disconnect, here is part of the code:

    static _i32 BsdTcpServerRun(TCP_SERVER_TYPE server_type)
    {
        SlSockAddrIn_t  Addr;
        SlSockAddrIn_t  LocalAddr;
    
        _u16 idx = 0;
        _u16 AddrSize = 0;
    
        _i16 i = 0;
        _i32 Status = 0;
        _i16 recvSize = 0;
    
        _i16 *serverSockID = NULL;
        _i16 *clientSockID = NULL;
        _u16 maxConn = 0;
    
        switch (server_type) {
            case TELNET_TCP_SERVER_TYPE:
                serverSockID = &g_telnet_SockID;
                clientSockID = &g_telnet_cltSockID[0];
                maxConn = TELNET_MAX_CONN;
                break;
    
            case HTTP_TCP_SERVER_TYPE:
                serverSockID = &g_http_SockID;
                clientSockID = &g_http_cltSockID[0];
                maxConn = HTTP_MAX_CONN;
                break;
    
            case WS_TCP_SERVER_TYPE:
                serverSockID = &g_ws_SockID;
                clientSockID = &g_ws_cltSockID[0];
                maxConn = WS_MAX_CONN;
                break;
            default:
                ASSERT_ON_ERROR(server_type);
                break;
        }
    
        for (i = 0; (i < maxConn) && (0 < *serverSockID); i++, clientSockID++) {
            recvSize = BUF_SIZE;
            if (0 == *clientSockID) {
                *clientSockID = sl_Accept(*serverSockID, ( struct SlSockAddr_t *)&Addr,
                                              (SlSocklen_t*)&AddrSize);
            }
            if(SL_EAGAIN == *clientSockID) {
                //CLI_Write(" [TCP Server] SL_EAGAIN\n\r");
                *clientSockID = 0;
            }
    
            else if(SL_ENSOCK == *clientSockID) {
                CLI_Write(" [TCP Server] SL_ENSOCK\n\r");
                *clientSockID = 0;
            }
            else if(SL_POOL_IS_EMPTY == *clientSockID) {
                CLI_Write(" [TCP Server] SL_POOL_IS_EMPTY\n\r");
                *clientSockID = 0;
            }
    
            else if(SL_INEXE == *clientSockID) {
                CLI_Write(" [TCP Server] SL_INEXE\n\r");
                *clientSockID = 0;
            }
    
            else if (0 > *clientSockID) {
                sl_Close(*serverSockID);
                *serverSockID = 0;
    
                send_uart_string_hex(SERIALIN, (char *)clientSockID, 1);
                CLI_Write(" [TCP Server] Accept connection Error \n\r");
                ASSERT_ON_ERROR(*clientSockID);
            }
    
            else {
                /* Connection had been made */
                Status = sl_Recv(*clientSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), recvSize, 0);
                if(0 < Status) {
                    /* Echo test */
                    //sl_Send(*clientSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), Status, 0);
                }
                else if((Status != SL_EAGAIN) && (Status != SL_POOL_IS_EMPTY)) {
                    CLI_Write("Client Closing\n\r");
    
                    /* Already disconnected */
                    Status = sl_Close(*clientSockID);
                    *clientSockID = 0;
                }
                else {
                    /* Timeout ??? */
                }
            }
        }
    
        return SUCCESS;
    }
    

    Regards,

    Dennis

  • Hi Dennis,

    Thanks for updating your code here. I will try with this code and update you on my findings. There are minor modifications in my code, I will update you with my version after testing.

    Can you please update me on below the below?

    1. How do you call 'sl_Listen' on these server sockets?
    2. Is your server socket non-blocking?

    Regards,
    Raghavendra
  • 
    

    Hi Raghavedra,

    1. Here is how i call sl_Listen() function, I try to use backlog parameter but it is not supported. I will come back when number of listening socket is supported

    Status = sl_Listen(SockID, maxConn);

    if( Status < 0 )
    {
    sl_Close(SockID);
    ASSERT_ON_ERROR(Status);
    }

    2. Yes, server sockets are non-blocking.

    Here is the code

    _i32 BsdTcpServerInit(_u16 Port, _i16 *SockID_ptr, _u16 maxConn)
    {
        SlSockAddrIn_t  Addr;
        SlSockAddrIn_t  LocalAddr;
    
        _u16          idx = 0;
        _u16          AddrSize = 0;
    
        _i16          SockID = 0;
    
        _i32          Status = 0;
        _u16          LoopCount = 0;
        _i16          recvSize = 0;
        _i16 nonBlockingValue = 1;
    
        LocalAddr.sin_family = SL_AF_INET;
        LocalAddr.sin_port = sl_Htons((_u16)Port);
        LocalAddr.sin_addr.s_addr = 0;
    
        SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, SL_IPPROTO_TCP);
        if( SockID < 0 )
        {
            ASSERT_ON_ERROR(SockID);
        }
        nonBlockingValue = 1;
        Status = sl_SetSockOpt(SockID, SL_SOL_SOCKET, SL_SO_NONBLOCKING,
                               &nonBlockingValue, sizeof(nonBlockingValue)) ;
        if( Status < 0 )
        {
            sl_Close(SockID);
            ASSERT_ON_ERROR(Status);
        }
    
        AddrSize = sizeof(SlSockAddrIn_t);
        Status = sl_Bind(SockID, (SlSockAddr_t *)&LocalAddr, AddrSize);
        if( Status < 0 )
        {
            sl_Close(SockID);
            ASSERT_ON_ERROR(Status);
        }
    
        Status = sl_Listen(SockID, maxConn);
        if( Status < 0 )
        {
            sl_Close(SockID);
            ASSERT_ON_ERROR(Status);
        }
    
        *SockID_ptr = SockID;
    
        return SUCCESS;
    }
    

    Regards,

    Dennis