My current setup requires a listener on the CC3200 which accepts any connection, receives the data, and acts on it. If the client disconnects, it goes back to the accept state. Concurrently, if I press a button on the CC3200 launchpad, it should spawn a client socket, send a message to a server socket elsewhere and close the client socket. However the button pressing event is asynchronous, hence I have implemented it using the Button_IF api. I've tried creating a socket during the ISR, but it gets blocked due to the Accept/Recv chain in the main function.
So I modified the ISR to set a flag value, and made the listener non-blocking. However, the listener stops accepting (returns -11) after the first disconnection from the client.
My code is:
int PAN_Prog(void) { /*********** Initial Code for TCP Server Start *****************/ SlSockAddrIn_t sAddr; SlSockAddrIn_t sLocalAddr; int iCounter; int iAddrSize; int iSockID; int iStatus; int iNewSockID; long lNonBlocking = 1; int iTestBufLen; unsigned short usPort= g_uiPortNum; // filling the buffer for (iCounter=0 ; iCounter<BUF_SIZE ; iCounter++) { g_cBsdBuf[iCounter] = (char)(iCounter % 10); } iTestBufLen = BUF_SIZE; sl_NetCfgGet(SL_MAC_ADDRESS_GET,NULL,&macAddressLen,(unsigned char *)macAddressVal); //filling the TCP server socket address sLocalAddr.sin_family = SL_AF_INET; sLocalAddr.sin_port = sl_Htons((unsigned short)usPort); sLocalAddr.sin_addr.s_addr = 0; // creating a TCP socket iSockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); if( iSockID < 0 ) { // error ASSERT_ON_ERROR(SOCKET_CREATE_ERROR); } iAddrSize = sizeof(SlSockAddrIn_t); // binding the TCP socket to the TCP server address iStatus = sl_Bind(iSockID, (SlSockAddr_t *)&sLocalAddr, iAddrSize); if( iStatus < 0 ) { // error sl_Close(iSockID); ASSERT_ON_ERROR(BIND_ERROR); } // putting the socket for listening to the incoming TCP connection iStatus = sl_Listen(iSockID, 0); if( iStatus < 0 ) { sl_Close(iSockID); ASSERT_ON_ERROR(LISTEN_ERROR); } // setting socket option to make the socket as non blocking iStatus = sl_SetSockOpt(iSockID, SL_SOL_SOCKET, SL_SO_NONBLOCKING,&lNonBlocking, sizeof(lNonBlocking)); if( iStatus < 0 ) { sl_Close(iSockID); ASSERT_ON_ERROR(SOCKET_OPT_ERROR); } iNewSockID = SL_EAGAIN; /*********** Initial Code for TCP Server End *****************/ /** While Loop for Command Processing **/ while (1) { if(send_flag==0) { iNewSockID = sl_Accept(iSockID, ( struct SlSockAddr_t *)&sAddr, (SlSocklen_t*)&iAddrSize); memset(g_cBsdBuf,0,strlen(g_cBsdBuf)); while(1) { memset(g_cBsdBuf,0,strlen(g_cBsdBuf)); iStatus = sl_Recv(iNewSockID, g_cBsdBuf, iTestBufLen, 0); if(iStatus < 0) { /* Error */ MAP_UtilsDelay(10000); break; } else if(iStatus == 0) { /* Client disconnected */ sl_Close(iNewSockID); break; } //Process the buffer } } else { BsdTcpClient(); send_flag=0; } } // close the connected socket after receiving from connected TCP client iStatus = sl_Close(iNewSockID); ASSERT_ON_ERROR(iStatus); // close the listening socket iStatus = sl_Close(iSockID); ASSERT_ON_ERROR(iStatus); return SUCCESS; }
void Send_Start_Msg(void) { //ISR for switch sw2 send_flag=1; Button_IF_EnableInterrupt(SW2); }
int BsdTcpClient() { short sTestBufLen; SlSockAddrIn_t sclAddr; int iclAddrSize; int iclSockID; int iclStatus; unsigned short usPort = 5005; sTestBufLen = BUF_SIZE; //filling the TCP server socket address sclAddr.sin_family = SL_AF_INET; sclAddr.sin_port = sl_Htons((unsigned short)usPort); sclAddr.sin_addr.s_addr = sl_Htonl((unsigned int)g_ulDestinationIp); iclAddrSize = sizeof(SlSockAddrIn_t); // creating a TCP socket iclSockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); if( iclSockID < 0 ) { ASSERT_ON_ERROR(SOCKET_CREATE_ERROR); } // connecting to TCP server iclStatus = sl_Connect(iclSockID, ( SlSockAddr_t *)&sclAddr, iclAddrSize); if( iclStatus < 0 ) { // error sl_Close(iclSockID); ASSERT_ON_ERROR(CONNECT_ERROR); } // sending packet iclStatus = sl_Send(iclSockID, g_cBsdBuf, sTestBufLen, 0 ); if( iclStatus < 0 ) { // error sl_Close(iclSockID); ASSERT_ON_ERROR(SEND_ERROR); } Report("Sent packet successfully\n\r"); iclStatus = sl_Close(iclSockID); //closing the socket after sending 1 packets ASSERT_ON_ERROR(iclStatus); return SUCCESS; }