static BaseType_t prvTcpWork( xTcpServer_t *pxTcpServer ) { BaseType_t lBytes, lReturned, lMayWrite; lMayWrite = FreeRTOS_maywrite( pxTcpServer->xSocket ); if( lMayWrite < 0 ) return lMayWrite; while( lMayWrite > 0 ) { lReturned = prvTcpSend( pxTcpServer ); if( lReturned < 0 ) return lReturned; if( lReturned == 0 ) break; lMayWrite = FreeRTOS_maywrite( pxTcpServer->xSocket ); if( lMayWrite < 0 ) return lMayWrite; } for( ; ; ) { /* Zero out the receive array so there is NULL at the end of the string when it is printed out. */ memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); /* Receive data on the socket. */ lBytes = FreeRTOS_recv( pxTcpServer->xSocket, cReceivedString, sizeof( cReceivedString ), 0 ); if( lBytes <= 0 ) return lBytes; /* Return the received characters. */ if( lMayWrite > 0 && sbGetSize( pxTcpServer->pxSendData ) == 0 ) { /* The cirular buffer is empty, send the received data directly */ lReturned = FreeRTOS_send( pxTcpServer->xSocket, cReceivedString, lBytes, 0 ); if( lReturned < 0 ) { return -1; } if( lBytes > lReturned ) { /* Not all dta could be delivered, save them for later * FD_SET( eSELECT_WRITE ) will be called */ sbAdd( pxTcpServer->pxSendData, 0, cReceivedString + lReturned, lBytes - lReturned ); } lMayWrite = FreeRTOS_maywrite( pxTcpServer->xSocket ); if( lMayWrite < 0 ) return lMayWrite; } else { sbAdd( pxTcpServer->pxSendData, 0, cReceivedString, lBytes ); } } }
static void prvGracefulShutdown( Socket_t xSocket ) { TickType_t xTimeOnShutdown; /* Initiate a shutdown in case it has not already been initiated. */ FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR ); /* Wait for the shutdown to take effect, indicated by FreeRTOS_recv() returning an error. */ xTimeOnShutdown = xTaskGetTickCount(); do { char c; if( FreeRTOS_recv( xSocket, &c,1, 0 ) < 0 ) { break; } } while( ( xTaskGetTickCount() - xTimeOnShutdown ) < pdMS_TO_TICKS(5000) ); /* Finished with the socket and the task. */ FreeRTOS_closesocket( xSocket ); }
int FreeRTOS_read(Network* n, unsigned char* buffer, int len, uint32_t timeout_ms) { portTickType xTicksToWait = timeout_ms / portTICK_RATE_MS; /* convert milliseconds to ticks */ xTimeOutType xTimeOut; int recvLen = 0; vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */ FreeRTOS_setsockopt(n->my_socket, SOL_SOCKET, FREERTOS_SO_RCVTIMEO, &timeout_ms, sizeof(timeout_ms)); do { int rc = 0; rc = FreeRTOS_recv(n->my_socket, buffer + recvLen, len - recvLen, 0); if (rc > 0) recvLen += rc; else if (rc < 0) { recvLen = rc; break; } } while (recvLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE); return recvLen; }
void prvTCPCpmIOTask( void *ram ) { BaseType_t iosize; char cRxedChar, cInputIndex = 0; struct freertos_sockaddr xClient; Socket_t xListeningSocket; socklen_t xSize = sizeof( xClient ); cpminq = xQueueCreate(81, sizeof( CHAR)); while(FreeRTOS_IsNetworkUp() == pdFALSE) vTaskDelay(3000); /* Create the socket. */ xSocketRDisk = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); /* Check the socket was created. */ configASSERT( xSocketRDisk != FREERTOS_INVALID_SOCKET ); for( ;; ) { /* Attempt to open the socket. The port number is passed in the task parameter. The strange casting is to remove compiler warnings on 32-bit machines. NOTE: The FREERTOS_SO_REUSE_LISTEN_SOCKET option is used, so the listening and connecting socket are the same - meaning only one connection will be accepted at a time, and that xListeningSocket must be created on each iteration. */ xListeningSocket = prvOpenTCPServerSocket( RDSK_PORT); /* Nothing for this task to do if the socket cannot be created. */ if( xListeningSocket == FREERTOS_INVALID_SOCKET ) { vTaskDelete( NULL ); } /* Wait for an incoming connection. */ xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize ); /* The FREERTOS_SO_REUSE_LISTEN_SOCKET option is set, so the connected and listening socket should be the same socket. */ configASSERT( xConnectedSocket == xListeningSocket ); xRDiskAddress.sin_addr = xClient.sin_addr; xRDiskAddress.sin_port = FreeRTOS_htons( RDSK_PORT ); iosize = xTaskCreate( CPM22Task, "CPM22Task", configMINIMAL_STACK_SIZE*5, ram, PRIO_CPM22,&thcpm); if(iosize != pdPASS) { prvGracefulShutdown( xListeningSocket ); vTaskDelete( NULL ); } /* Send the welcome message. */ iosize = FreeRTOS_send( xConnectedSocket, ( void * ) pcWelcomeMessage, strlen( pcWelcomeMessage ), 0 ); xQueueReset(cpminq); /* Process the socket as long as it remains connected. */ while( iosize >= 0 ) { char c; /* Receive data on the socket. */ iosize = FreeRTOS_recv( xConnectedSocket, &c, 1, 0 ); if( iosize >= 0 ) { xQueueSend(cpminq,&c,0); } else { /* Socket closed? */ break; } } /* Close the socket correctly. */ prvGracefulShutdown( xListeningSocket ); } }
static void prvServerConnectionInstance( void *pvParameters ) { int32_t lBytes, lSent, lTotalSent; uint8_t cReceivedString[ ipconfigTCP_MSS ]; xSocket_t xConnectedSocket; static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 ); static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 5000 ); TickType_t xTimeOnShutdown; ulConnectionCount++; xConnectedSocket = ( xSocket_t ) pvParameters; FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) ); for( ;; ) { /* Zero out the receive array so there is NULL at the end of the string when it is printed out. */ memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); /* Receive data on the socket. */ lBytes = FreeRTOS_recv( xConnectedSocket, cReceivedString, sizeof( cReceivedString ), 0 ); /* If data was received, echo it back. */ if( lBytes >= 0 ) { lSent = 0; lTotalSent = 0; /* Call send() until all the data has been sent. */ while( ( lSent >= 0 ) && ( lTotalSent < lBytes ) ) { lSent = FreeRTOS_send( xConnectedSocket, cReceivedString, lBytes - lTotalSent, 0 ); lTotalSent += lSent; } if( lSent < 0 ) { /* Socket closed? */ break; } } else { /* Socket closed? */ break; } } /* Initiate a shutdown in case it has not already been initiated. */ FreeRTOS_shutdown( xConnectedSocket, FREERTOS_SHUT_RDWR ); /* Wait for the shutdown to take effect, indicated by FreeRTOS_recv() returning an error. */ xTimeOnShutdown = xTaskGetTickCount(); do { if( FreeRTOS_recv( xConnectedSocket, cReceivedString, ipconfigTCP_MSS, 0 ) < 0 ) { break; } } while( ( xTaskGetTickCount() - xTimeOnShutdown ) < tcpechoSHUTDOWN_DELAY ); /* Finished with the socket and the task. */ FreeRTOS_closesocket( xConnectedSocket ); vTaskDelete( NULL ); }
BaseType_t xHTTPClientWork( xTCPClient *pxTCPClient ) { BaseType_t xRc; xHTTPClient *pxClient = ( xHTTPClient * ) pxTCPClient; if( pxClient->pxFileHandle != NULL ) { prvSendFile( pxClient ); } xRc = FreeRTOS_recv( pxClient->xSocket, ( void * )pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 ); if( xRc > 0 ) { BaseType_t xIndex; const char *pcEndOfCmd; const struct xWEB_COMMAND *curCmd; char *pcBuffer = pcCOMMAND_BUFFER; if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) ) { pcBuffer[ xRc ] = '\0'; } while( xRc && ( pcBuffer[ xRc - 1 ] == 13 || pcBuffer[ xRc - 1 ] == 10 ) ) { pcBuffer[ --xRc ] = '\0'; } pcEndOfCmd = pcBuffer + xRc; curCmd = xWebCommands; pxClient->pcUrlData = pcBuffer; /* Pointing to "/index.html HTTP/1.1" */ pxClient->pcRestData = pcEmptyString; /* Pointing to "HTTP/1.1" */ // Last entry is "ECMD_UNK" for( xIndex = 0; xIndex < WEB_CMD_COUNT - 1; xIndex++, curCmd++ ) { BaseType_t xLength; xLength = curCmd->xCommandLength; if( ( xRc >= xLength ) && ( memcmp( curCmd->pcCommandName, pcBuffer, xLength ) == 0 ) ) { char *pcLastPtr; pxClient->pcUrlData += xLength + 1; for( pcLastPtr = (char *)pxClient->pcUrlData; pcLastPtr < pcEndOfCmd; pcLastPtr++ ) { char ch = *pcLastPtr; if( ( ch == '\0' ) || ( strchr( "\n\r \t", ch ) != NULL ) ) { *pcLastPtr = '\0'; pxClient->pcRestData = pcLastPtr + 1; break; } } break; } } xRc = prvProcessCmd( pxClient, xIndex ); } else if( xRc < 0 ) { /* The connection will be closed and the client will be deleted */ FreeRTOS_printf( ( "xHTTPClientWork: rc = %ld\n", xRc ) ); } return xRc; }
static void prvEchoClientTask( void *pvParameters ) { Socket_t xSocket; struct freertos_sockaddr xEchoServerAddress; int32_t lLoopCount = 0UL; const int32_t lMaxLoopCount = 1; volatile uint32_t ulTxCount = 0UL; BaseType_t xReceivedBytes, xReturned, xInstance; BaseType_t lTransmitted, lStringLength; char *pcTransmittedString, *pcReceivedString; WinProperties_t xWinProps; TickType_t xTimeOnEntering; /* Fill in the buffer and window sizes that will be used by the socket. */ xWinProps.lTxBufSize = 6 * ipconfigTCP_MSS; xWinProps.lTxWinSize = 3; xWinProps.lRxBufSize = 6 * ipconfigTCP_MSS; xWinProps.lRxWinSize = 3; /* This task can be created a number of times. Each instance is numbered to enable each instance to use a different Rx and Tx buffer. The number is passed in as the task's parameter. */ xInstance = ( BaseType_t ) pvParameters; /* Point to the buffers to be used by this instance of this task. */ pcTransmittedString = &( cTxBuffers[ xInstance ][ 0 ] ); pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] ); /* Echo requests are sent to the echo server. The address of the echo server is configured by the constants configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 ); for( ;; ) { /* Create a TCP socket. */ xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); /* Set a time out so a missing reply does not cause the task to block indefinitely. */ FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); /* Set the window and buffer sizes. */ FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); /* Connect to the echo server. */ if( FreeRTOS_connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ) == 0 ) { ulConnections[ xInstance ]++; /* Send a number of echo requests. */ for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) { /* Create the string that is sent to the echo server. */ lStringLength = prvCreateTxData( pcTransmittedString, echoBUFFER_SIZES ); /* Add in some unique text at the front of the string. */ sprintf( pcTransmittedString, "TxRx message number %u", ulTxCount ); ulTxCount++; /* Send the string to the socket. */ lTransmitted = FreeRTOS_send( xSocket, /* The socket being sent to. */ ( void * ) pcTransmittedString, /* The data being sent. */ lStringLength, /* The length of the data being sent. */ 0 ); /* No flags. */ if( lTransmitted < 0 ) { /* Error? */ break; } /* Clear the buffer into which the echoed string will be placed. */ memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES ); xReceivedBytes = 0; /* Receive data echoed back to the socket. */ while( xReceivedBytes < lTransmitted ) { xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ &( pcReceivedString[ xReceivedBytes ] ),/* The buffer into which the received data will be written. */ lStringLength - xReceivedBytes, /* The size of the buffer provided to receive the data. */ 0 ); /* No flags. */ if( xReturned < 0 ) { /* Error occurred. Latch it so it can be detected below. */ xReceivedBytes = xReturned; break; } else if( xReturned == 0 ) { /* Timed out. */ break; } else { /* Keep a count of the bytes received so far. */ xReceivedBytes += xReturned; } } /* If an error occurred it will be latched in xReceivedBytes, otherwise xReceived bytes will be just that - the number of bytes received from the echo server. */ if( xReceivedBytes > 0 ) { /* Compare the transmitted string to the received string. */ configASSERT( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ); if( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ) { /* The echo reply was received without error. */ ulTxRxCycles[ xInstance ]++; } else { /* The received string did not match the transmitted string. */ ulTxRxFailures[ xInstance ]++; break; } } else if( xReceivedBytes < 0 ) { /* FreeRTOS_recv() returned an error. */ break; } else { /* Timed out without receiving anything? */ break; } } /* Finished using the connected socket, initiate a graceful close: FIN, FIN+ACK, ACK. */ FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR ); /* Expect FreeRTOS_recv() to return an error once the shutdown is complete. */ xTimeOnEntering = xTaskGetTickCount(); do { xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ &( pcReceivedString[ 0 ] ), /* The buffer into which the received data will be written. */ echoBUFFER_SIZES, /* The size of the buffer provided to receive the data. */ 0 ); if( xReturned < 0 ) { break; } } while( ( xTaskGetTickCount() - xTimeOnEntering ) < xReceiveTimeOut ); } /* Close this socket before looping back to create another. */ FreeRTOS_closesocket( xSocket ); /* Pause for a short while to ensure the network is not too congested. */ vTaskDelay( echoLOOP_DELAY ); } }