/*\r
- * FreeRTOS+TCP V2.0.11\r
+ * FreeRTOS+TCP V2.2.0\r
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy of\r
#define socketNEXT_UDP_PORT_NUMBER_INDEX 0\r
#define socketNEXT_TCP_PORT_NUMBER_INDEX 1\r
\r
+/* Some helper macro's for defining the 20/80 % limits of uxLittleSpace / uxEnoughSpace. */\r
+#define sock20_PERCENT 20\r
+#define sock80_PERCENT 80\r
+#define sock100_PERCENT 100\r
+\r
\r
/*-----------------------------------------------------------*/\r
\r
}\r
}\r
\r
- return ( SocketSet_t * ) pxSocketSet;\r
+ return ( SocketSet_t ) pxSocketSet;\r
}\r
\r
#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */\r
}\r
taskEXIT_CRITICAL();\r
\r
- /* The returned value is the data length, which may have been capped to\r
- the receive buffer size. */\r
- lReturn = ( int32_t ) pxNetworkBuffer->xDataLength;\r
+ /* The returned value is the length of the payload data, which is\r
+ calculated at the total packet size minus the headers.\r
+ The validity of `xDataLength` prvProcessIPPacket has been confirmed\r
+ in 'prvProcessIPPacket()'. */\r
+ lReturn = ( int32_t ) ( pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ) );\r
\r
if( pxSourceAddress != NULL )\r
{\r
\r
if( pxNetworkBuffer != NULL )\r
{\r
- pxNetworkBuffer->xDataLength = xTotalDataLength;\r
+ /* xDataLength is the size of the total packet, including the Ethernet header. */\r
+ pxNetworkBuffer->xDataLength = xTotalDataLength + sizeof( UDPPacket_t );\r
pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;\r
pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_PORT( pxSocket );\r
pxNetworkBuffer->ulIPAddress = pxDestinationAddress->sin_addr;\r
{\r
if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleSent ) )\r
{\r
- pxSocket->u.xUDP.pxHandleSent( (Socket_t *)pxSocket, xTotalDataLength );\r
+ pxSocket->u.xUDP.pxHandleSent( ( Socket_t )pxSocket, xTotalDataLength );\r
}\r
}\r
#endif /* ipconfigUSE_CALLBACKS */\r
break;\r
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */\r
\r
+ case FREERTOS_SO_SET_LOW_HIGH_WATER:\r
+ {\r
+ LowHighWater_t *pxLowHighWater = ( LowHighWater_t * ) pvOptionValue;\r
+\r
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )\r
+ {\r
+ /* It is not allowed to access 'pxSocket->u.xTCP'. */\r
+ FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: wrong socket type\n" ) );\r
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */\r
+ }\r
+ if( ( pxLowHighWater->uxLittleSpace >= pxLowHighWater->uxEnoughSpace ) ||\r
+ ( pxLowHighWater->uxEnoughSpace > pxSocket->u.xTCP.uxRxStreamSize ) )\r
+ {\r
+ /* Impossible values. */\r
+ FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: bad values\n" ) );\r
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */\r
+ }\r
+ /* Send a STOP when buffer space drops below 'uxLittleSpace' bytes. */\r
+ pxSocket->u.xTCP.uxLittleSpace = pxLowHighWater->uxLittleSpace;\r
+ /* Send a GO when buffer space grows above 'uxEnoughSpace' bytes. */\r
+ pxSocket->u.xTCP.uxEnoughSpace = pxLowHighWater->uxEnoughSpace;\r
+ xReturn = 0;\r
+ }\r
+ break;\r
+\r
case FREERTOS_SO_SNDBUF: /* Set the size of the send buffer, in units of MSS (TCP only) */\r
case FREERTOS_SO_RCVBUF: /* Set the size of the receive buffer, in units of MSS (TCP only) */\r
{\r
}\r
\r
pxProps = ( ( WinProperties_t * ) pvOptionValue );\r
- FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) );\r
- FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) );\r
+\r
+ if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) ) != 0 )\r
+ {\r
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */\r
+ }\r
+\r
+ if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) ) != 0 )\r
+ {\r
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */\r
+ }\r
+\r
#if( ipconfigUSE_TCP_WIN == 1 )\r
{\r
pxSocket->u.xTCP.uxRxWinSize = ( uint32_t )pxProps->lRxWinSize; /* Fixed value: size of the TCP reception window */\r
uint16_t usIterations = usEphemeralPortCount;\r
uint32_t ulRandomSeed = 0;\r
uint16_t usResult = 0;\r
-BaseType_t xGotZeroOnce = pdFALSE;\r
const List_t *pxList;\r
\r
#if ipconfigUSE_TCP == 1\r
point. */\r
do\r
{\r
- /* Generate a random seed. */\r
- ulRandomSeed = ipconfigRAND32( );\r
-\r
/* Only proceed if the random number generator succeeded. */\r
- if( 0 == ulRandomSeed )\r
+ if( xApplicationGetRandomNumber( &( ulRandomSeed ) ) == pdFALSE )\r
{\r
- if( pdFALSE == xGotZeroOnce )\r
- {\r
- xGotZeroOnce = pdTRUE;\r
- continue;\r
- }\r
- else\r
- {\r
- break;\r
- }\r
+ break;\r
}\r
\r
/* Map the random to a candidate port. */\r
{\r
xResult = -pdFREERTOS_ERRNO_ENOMEM;\r
}\r
- else if( pxSocket->u.xTCP.ucTCPState == eCLOSED )\r
+ else if( pxSocket->u.xTCP.ucTCPState == eCLOSED ||\r
+ pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ||\r
+ pxSocket->u.xTCP.ucTCPState == eCLOSING )\r
{\r
xResult = -pdFREERTOS_ERRNO_ENOTCONN;\r
}\r
'*pxLength' will contain the number of bytes that may be written. */\r
uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength )\r
{\r
- uint8_t *pucReturn;\r
+ uint8_t *pucReturn = NULL;\r
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;\r
- StreamBuffer_t *pxBuffer = pxSocket->u.xTCP.txStream;\r
+ StreamBuffer_t *pxBuffer = NULL;\r
\r
- if( pxBuffer != NULL )\r
- {\r
- BaseType_t xSpace = ( BaseType_t ) uxStreamBufferGetSpace( pxBuffer );\r
- BaseType_t xRemain = ( BaseType_t ) ( pxBuffer->LENGTH - pxBuffer->uxHead );\r
+ *pxLength = 0;\r
\r
- *pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );\r
- pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;\r
- }\r
- else\r
- {\r
- *pxLength = 0;\r
- pucReturn = NULL;\r
+ /* Confirm that this is a TCP socket before dereferencing structure\r
+ member pointers. */\r
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )\r
+ {\r
+ pxBuffer = pxSocket->u.xTCP.txStream;\r
+ if( pxBuffer != NULL )\r
+ {\r
+ BaseType_t xSpace = ( BaseType_t )uxStreamBufferGetSpace( pxBuffer );\r
+ BaseType_t xRemain = ( BaseType_t )( pxBuffer->LENGTH - pxBuffer->uxHead );\r
+\r
+ *pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );\r
+ pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;\r
+ }\r
}\r
\r
return pucReturn;\r
\r
#if( ipconfigUSE_TCP == 1 )\r
\r
- const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )\r
- {\r
- FreeRTOS_Socket_t *pxSocket = (FreeRTOS_Socket_t *)xSocket;\r
+ const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )\r
+ {\r
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;\r
+ struct xSTREAM_BUFFER *pxReturn = NULL;\r
\r
- return pxSocket->u.xTCP.rxStream;\r
- }\r
+ /* Confirm that this is a TCP socket before dereferencing structure\r
+ member pointers. */\r
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )\r
+ {\r
+ pxReturn = pxSocket->u.xTCP.rxStream;\r
+ }\r
+\r
+ return pxReturn;\r
+ }\r
\r
#endif /* ipconfigUSE_TCP */\r
/*-----------------------------------------------------------*/\r
\r
if( pxSocket->u.xTCP.uxLittleSpace == 0ul )\r
{\r
- pxSocket->u.xTCP.uxLittleSpace = ( 1ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why divide by 5? Can this be changed to a #define? */\r
+ pxSocket->u.xTCP.uxLittleSpace = ( sock20_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;\r
}\r
\r
if( pxSocket->u.xTCP.uxEnoughSpace == 0ul )\r
{\r
- pxSocket->u.xTCP.uxEnoughSpace = ( 4ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why multiply by 4? Maybe sock80_PERCENT?*/\r
+ pxSocket->u.xTCP.uxEnoughSpace = ( sock80_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;\r
}\r
}\r
else\r
break;\r
}\r
\r
- pxSocket->u.xTCP.pxHandleReceive( (Socket_t *)pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );\r
+ pxSocket->u.xTCP.pxHandleReceive( ( Socket_t )pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );\r
uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );\r
}\r
} else\r