Hello!
I wrote a program for CC3220SF LAUNCHXL based on the network terminal and cloud ota examples.
The program works as follows:
1. The client program running on the computer connects to LaunchPad server socket by WiFi and sends commands to the device
2. LaunchPad decodes and transmits commands to the device by UART
3. The device responds to commands by UART
4. LaunchPad encrypts and transmits data by WiFi to an client program
When there is only one connection to the LaunchPad, this program works stably and there is no reconnection for at least a day.
When there is more than one connection, client programs are periodically reconnected to the LaunchPad.
Reconnections become more frequent when connecting a new copy of the client program.
After a while, something stabilizes and reconnections become less frequent.
When connecting another copy of the client program, the situation repeats.
If I remove the line usleep(1000); after for(i = 0; i <16; i ++) , the number of reconnections increases dramatically.
The client program reconnects if there is no response from the server within 1 second.
Why client programs are reconnecting, when there is more than one connection?
Code Composer Studio 10.2.0, SimpleLink CC32xx SDK 4.30.00.06
Here's my source code regarding data exchange by WiFi:
int32_t TCPServerInit(sockAddr_t *sAddr, uint16_t port) { int32_t sock; int32_t status; int32_t nonBlocking = TRUE; /* Contains the local ip address and port */ SlSockAddr_t *sa; int32_t addrSize; /* filling the TCP server socket address */ sAddr->in4.sin_family = SL_AF_INET; /* Set the server's port: We'll receive connection requests on this port */ sAddr->in4.sin_port = sl_Htons(port); sAddr->in4.sin_addr.s_addr = SL_INADDR_ANY; sa = (SlSockAddr_t*)sAddr; addrSize = sizeof(SlSockAddrIn_t); /* * Open a TCP socket: * Since TCP is a connection oriented channel, * the opened socket would serve as 'welcome' socket, * on which we'll receive connection requests from clients. */ sock = sl_Socket(sa->sa_family, SL_SOCK_STREAM, TCP_PROTOCOL_FLAGS); ASSERT_ON_ERROR(sock, SL_SOCKET_ERROR); /* Bind socket to server's port */ status = sl_Bind(sock, sa, addrSize); if(status < 0) { UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status, SL_SOCKET_ERROR); sl_Close(sock); return(-1); } /* 'Listen' signify that wer'e ready to receive connection's from clients */ status = sl_Listen(sock, 0); if(status < 0) { UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status, SL_SOCKET_ERROR); sl_Close(sock); return(-1); } /* Set socket as non-blocking socket (if needed): * Non-blocking sockets allows user to handle other tasks rather than block * on socket API calls. * If an API call using the Non-blocking socket descriptor * returns 'SL_ERROR_BSD_EAGAIN' - * this indicate that the user should try the API again later. */ nonBlocking = TRUE; status = sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlocking, sizeof(nonBlocking)); if(status < 0) { UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status, SL_SOCKET_ERROR); return(-1); } return sock; } typedef union { uint32_t ipv4; /* Ipv4 Address */ uint8_t ipv6[16]; /* Ipv6 Address */ }ip_t; SlSockAddr_t *IP2SlSockAddr(uint8_t sl_fa, uint16_t portNumber, ip_t ipAddress, sockAddr_t *sAddr) { // filling the TCP server socket address sAddr->in4.sin_family = SL_AF_INET; // Since this is the client's side, // we must know beforehand the IP address // and the port of the server wer'e trying to connect. sAddr->in4.sin_port = sl_Htons((unsigned short)portNumber); sAddr->in4.sin_addr.s_addr = sl_Htonl((unsigned int)ipAddress.ipv4); return (SlSockAddr_t*)sAddr; } int32_t TCPClientInit(uint8_t sa_family) { int32_t sock; int32_t status; int32_t nonBlocking; // Get socket descriptor - this would be the // socket descriptor for the TCP session. sock = sl_Socket(sa_family, SL_SOCK_STREAM, TCP_PROTOCOL_FLAGS); ASSERT_ON_ERROR(sock, SL_SOCKET_ERROR); // Set socket as non-blocking socket (if needed): // Non-blocking sockets allows user to handle // other tasks rather than block // on socket API calls. // If an API call using the Non-blocking socket descriptor // returns 'SL_ERROR_BSD_EAGAIN' - // this indicate that the user should try the API again later. nonBlocking = TRUE; status = sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlocking, sizeof(nonBlocking)); if(status < 0) { UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status, SL_SOCKET_ERROR); sl_Close(sock); return(-1); } return sock; } void *appThread(void *arg0) { uint8_t run_first = 1; int32_t server_sock; /* Contains the ip address and port of the connected peer. */ static SlSockAddr_t *csa; static sockAddr_t sAddr; static int32_t addrSize; int32_t ret; uint32_t ans; int32_t newsock = -1; static uint8_t server_states[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t *psrvstate; uint32_t uart_send_size; uint32_t *pusendsz; #define server_state *psrvstate static uint32_t socket_sizes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint32_t *psocksz; #define socket_size *psocksz static uint32_t socket_flags[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint32_t *psockfl; #define socket_flag *psockfl int32_t status; static int32_t client_socks[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int32_t *pclsock; static uint8_t client_states[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t *pclstate; #define client_sock *pclsock #define client_state *pclstate uint8_t queue_state; uint16_t queue_size; uint8_t *queue_bufptr; static uint8_t queue_items[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; #define queue_item queue_items[i] ... while(1) { usleep(1000); if(run_first) { server_sock = TCPServerInit(&sAddr, 2612); csa = (SlSockAddr_t*)&sAddr; addrSize = sizeof(SlSockAddrIn_t); if(server_sock >= 0) run_first = 0; } else { newsock = sl_Accept(server_sock, csa, (SlSocklen_t*)&addrSize); if(newsock == SL_ERROR_BSD_EAGAIN) { //break; } else if(newsock < 0) { server_states[newsock] = 0; } else { UART_PRINT("Connected to client %d: ", newsock); sAddr.in4.sin_addr.s_addr = sl_Htonl(sAddr.in4.sin_addr.s_addr); PrintIPAddress(FALSE,(void*)&sAddr.in4.sin_addr); UART_PRINT(lineBreak); if(newsock < 16) { server_states[newsock] = 1; } } uint8_t i = 0; for(i = 0; i < 16; i++) { usleep(1000); socketBuf = sockbuf[i]; psrvstate = &server_states[i]; psocksz = &socket_sizes[i]; psockfl = &socket_flags[i]; switch(server_state) { case 0: // Not connected break; case 1: ret = sl_Recv(i, socketBuf, MAX_BUF_SIZE, 0); if(ret == SL_ERROR_BSD_EAGAIN) { break; } else if(ret < 0) { UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, ret, BSD_SOCKET_ERROR); UART_PRINT("Socket %d closed\n\r", i); sl_Close(i); server_state = 0; break; } else if(ret == 0) { UART_PRINT("TCP Client (socket %d) closed the connection \n\r", i); sl_Close(i); server_state = 0; break; } uart_send_size = ret; queue_item = AddToQueue(socketBuf, uart_send_size, socketBuf, 0); server_state = 2; break; case 2: queue_state = QueueState(queue_item); if(queue_state >= ready) { queue_size = QueueSize(queue_item); socket_size = queue_size; } else break; case 3: Encrypt((char*)socketBuf, (char*)socketBuf, socket_size); ret = sl_Send(i, socketBuf, socket_size, 0); if(ret == SL_ERROR_BSD_EAGAIN) { break; } else if(ret < 0) { UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, ret, SL_SOCKET_ERROR); UART_PRINT("Socket %d closed\n\r", i); sl_Close(i); server_state = 0; break; } server_state = 1; break; } } } } }
Also, sometimes there is an error Error [-2] at line [1531] in function [CheckLanConnection] in the file cloud_ota.c
Line 1531 corresponds to the code
/* Ping the GW */ retVal = sl_NetAppPing((SlNetAppPingCommand_t*)&pingParams, \ SL_AF_INET, (SlNetAppPingReport_t*)&pingReport, \ SimpleLinkPingReport); ASSERT_ON_ERROR(retVal);
When trying to update, the program rarely hangs on the line LOOP_FOREVER (); in the cloud_ota.c file
if(NULL != pEntry->p_evtHndl) { if(pEntry->p_evtHndl() < 0) { UART_PRINT("Event handler failed..!! \r\n"); LOOP_FOREVER(); } }