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; }