]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
Sync FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP with the version in GitHub at (23665258ca...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / FreeRTOS_Sockets.c
index ce03f613692b5872250fae9d4235a10a2c59a86c..e15834849ef2dd590f8671223d17e3d639a13dc8 100644 (file)
@@ -1,5 +1,5 @@
 /*\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
@@ -89,6 +89,11 @@ respectively. */
 #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
@@ -380,7 +385,7 @@ Socket_t xReturn;
                        }\r
                }\r
 \r
-               return ( SocketSet_t ) pxSocketSet;\r
+               return ( SocketSet_t ) pxSocketSet;\r
        }\r
 \r
 #endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */\r
@@ -697,9 +702,11 @@ EventBits_t xEventBits = ( EventBits_t ) 0;
                }\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
@@ -828,7 +835,8 @@ FreeRTOS_Socket_t *pxSocket;
 \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
@@ -849,7 +857,7 @@ FreeRTOS_Socket_t *pxSocket;
                                        {\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
@@ -1428,6 +1436,31 @@ FreeRTOS_Socket_t *pxSocket;
                                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
@@ -1481,8 +1514,17 @@ FreeRTOS_Socket_t *pxSocket;
                                        }\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
@@ -1615,7 +1657,6 @@ const uint16_t usEphemeralPortCount =
 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
@@ -1636,21 +1677,10 @@ const List_t *pxList;
        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
@@ -2373,7 +2403,9 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
                {\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
@@ -2412,22 +2444,25 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
        '*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
@@ -2860,12 +2895,20 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
 \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
@@ -2886,12 +2929,12 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
 \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
@@ -3029,7 +3072,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
                                                        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