/* * FreeRTOS+TCP <DEVELOPMENT BRANCH> * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * http://aws.amazon.com/freertos * http://www.FreeRTOS.org */ /* Include Unity header */ #include "unity.h" /* Include standard libraries */ #include <stdlib.h> #include <string.h> #include <stdint.h> /*#include "mock_task.h" */ #include "mock_TCP_IP_list_macros.h" /* This must come after list.h is included (in this case, indirectly * by mock_list.h). */ #include "mock_queue.h" #include "mock_task.h" #include "mock_event_groups.h" #include "mock_list.h" #include "mock_FreeRTOS_IP.h" #include "mock_FreeRTOS_IP_Utils.h" #include "mock_NetworkBufferManagement.h" #include "mock_NetworkInterface.h" #include "mock_FreeRTOS_Sockets.h" #include "mock_FreeRTOS_Stream_Buffer.h" #include "mock_FreeRTOS_TCP_WIN.h" #include "mock_FreeRTOS_TCP_State_Handling.h" #include "mock_FreeRTOS_UDP_IP.h" #include "mock_FreeRTOS_TCP_Transmission.h" #include "mock_FreeRTOS_TCP_Reception.h" #include "mock_TCP_IP_list_macros.h" #include "catch_assert.h" #include "FreeRTOSIPConfig.h" #include "FreeRTOS_TCP_IP_stubs.c" #include "FreeRTOS_TCP_IP.h" /* =========================== EXTERN VARIABLES =========================== */ FreeRTOS_Socket_t xSocket, * pxSocket; NetworkBufferDescriptor_t xNetworkBuffer, * pxNetworkBuffer; extern BaseType_t xTCPWindowLoggingLevel; extern FreeRTOS_Socket_t * xSocketToClose; extern FreeRTOS_Socket_t * xSocketToListen; uint8_t ucEthernetBuffer[ ipconfigNETWORK_MTU ] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34, 0x15, 0xc2, 0x40, 0x00, 0x40, 0x06, 0xa8, 0x8e, 0xc0, 0xa8, 0x00, 0x08, 0xac, 0xd9, 0x0e, 0xea, 0xea, 0xfe, 0x01, 0xbb, 0x8b, 0xaf, 0x8a, 0x24, 0xdc, 0x96, 0x95, 0x7a, 0x80, 0x10, 0x01, 0xf5, 0x7c, 0x9a, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xb8, 0x53, 0x57, 0x27, 0xb2, 0xce, 0xc3, 0x17 }; /* ============================== Test Cases ============================== */ /** * @brief Test the functionality when socket is NULL. */ void test_vSocketCloseNextTime_Null_Socket( void ) { vSocketCloseNextTime( NULL ); } /** * @brief Test the functionality to not close the * socket. */ void test_vSocketCloseNextTime_Not_Close_Socket( void ) { memset( &xSocket, 0, sizeof( xSocket ) ); vSocketCloseNextTime( &xSocket ); } /** * @brief Test the functionality to not close the * same socket. */ void test_vSocketCloseNextTime_Not_Close_Same_Socket( void ) { memset( &xSocket, 0, sizeof( xSocket ) ); vSocketCloseNextTime( &xSocket ); } /** * @brief Test the functionality to close the * same socket. */ /* test vSocketCloseNextTime function */ void test_vSocketCloseNextTime_Close_Previous_Socket( void ) { FreeRTOS_Socket_t NewSocket; vSocketClose_ExpectAnyArgsAndReturn( NULL ); vSocketCloseNextTime( &NewSocket ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls. */ void test_vSocketListenNextTime( void ) { FreeRTOS_Socket_t xSocket = { 0 }; xSocketToListen = NULL; vSocketListenNextTime( &xSocket ); TEST_ASSERT_EQUAL( &xSocket, xSocketToListen ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls. */ void test_vSocketListenNextTime1( void ) { FreeRTOS_Socket_t xSocket = { 0 }; xSocketToListen = &xSocket; FreeRTOS_listen_ExpectAndReturn( ( Socket_t ) xSocketToListen, xSocketToListen->u.xTCP.usBacklog, 0 ); vSocketListenNextTime( NULL ); TEST_ASSERT_EQUAL( NULL, xSocketToListen ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls. */ void test_vSocketListenNextTime2( void ) { FreeRTOS_Socket_t xSocket = { 0 }; xSocketToListen = &xSocket; vSocketListenNextTime( xSocketToListen ); TEST_ASSERT_EQUAL( &xSocket, xSocketToListen ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls * when all inputs are set to zero. */ void test_xTCPSocketCheck_AllInputsZero1( void ) { BaseType_t xReturn, xToReturn = 0xAABBCCDD; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdTRUE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &xDelayReturn ); prvTCPStatusAgeCheck_ExpectAnyArgsAndReturn( xToReturn ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls * when the tcp state is set to eESTABLISHED. */ void test_xTCPSocketCheck_StateEstablished( void ) { BaseType_t xReturn, xToReturn = 0xAABBCCDD; FreeRTOS_Socket_t xSocket = { 0 }; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eESTABLISHED; prvTCPSendPacket_ExpectAndReturn( &xSocket, 0 ); xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdTRUE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &xDelayReturn ); prvTCPStatusAgeCheck_ExpectAnyArgsAndReturn( xToReturn ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls * when the tcp state is set to eESTABLISHED * and tcp stream is NULL. */ void test_xTCPSocketCheck_StateEstablished_TxStreamNonNull( void ) { BaseType_t xReturn, xToReturn = 0xAABBCCDD; FreeRTOS_Socket_t xSocket = { 0 }; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.txStream = ( void * ) &xSocket; prvTCPAddTxData_Expect( &xSocket ); prvTCPSendPacket_ExpectAndReturn( &xSocket, 0 ); xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdTRUE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &xDelayReturn ); prvTCPStatusAgeCheck_ExpectAnyArgsAndReturn( xToReturn ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls * when the tcp state is set to eESTABLISHED * and a valid TCP stream. */ void test_xTCPSocketCheck_StateEstablished_TxStreamNonNull1( void ) { BaseType_t xReturn, xToReturn = 0xAABBCCDD; FreeRTOS_Socket_t xSocket = { 0 }; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.txStream = ( void * ) &xSocket; xSocket.u.xTCP.pxAckMessage = ( void * ) &xSocket; prvTCPAddTxData_Expect( &xSocket ); uxIPHeaderSizeSocket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); prvTCPReturnPacket_Expect( &xSocket, xSocket.u.xTCP.pxAckMessage, ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER, ipconfigZERO_COPY_TX_DRIVER ); xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdTRUE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &xDelayReturn ); vReleaseNetworkBufferAndDescriptor_Expect( xSocket.u.xTCP.pxAckMessage ); prvTCPSendPacket_ExpectAndReturn( &xSocket, 0 ); prvTCPStatusAgeCheck_ExpectAndReturn( &xSocket, xToReturn ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxAckMessage ); TEST_ASSERT_EQUAL( 1U, xSocket.u.xTCP.usTimeout ); } /** * @brief Test the functionality to Postpone a call * to FreeRTOS_listen() to avoid recursive calls * when the tcp state is set to eESTABLISHED. */ void test_xTCPSocketCheck_StateEstablished_TxStreamNonNull_BufferFreed( void ) { BaseType_t xReturn, xToReturn = 0xAABBCCDD; FreeRTOS_Socket_t xSocket = { 0 }; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.txStream = ( void * ) &xSocket; xSocket.u.xTCP.pxAckMessage = ( void * ) &xSocket; prvTCPAddTxData_Expect( &xSocket ); uxIPHeaderSizeSocket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); prvTCPReturnPacket_Stub( prvTCPReturnPacket_StubReturnNULL ); xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdTRUE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &xDelayReturn ); prvTCPSendPacket_ExpectAndReturn( &xSocket, 0 ); prvTCPStatusAgeCheck_ExpectAndReturn( &xSocket, xToReturn ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxAckMessage ); TEST_ASSERT_EQUAL( 1U, xSocket.u.xTCP.usTimeout ); } /** * @brief Test functionality when the stream is non-NULL and the * time out is non-zero. */ void test_xTCPSocketCheck_StateEstablished_TxStreamNonNull1_NonZeroTimeout( void ) { BaseType_t xReturn, xToReturn = 0; FreeRTOS_Socket_t xSocket = { 0 }; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.txStream = ( void * ) &xSocket; xSocket.u.xTCP.pxAckMessage = ( void * ) &xSocket; xSocket.u.xTCP.usTimeout = 100; prvTCPAddTxData_Expect( &xSocket ); uxIPHeaderSizeSocket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); prvTCPReturnPacket_Expect( &xSocket, xSocket.u.xTCP.pxAckMessage, ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER, ipconfigZERO_COPY_TX_DRIVER ); vReleaseNetworkBufferAndDescriptor_Expect( xSocket.u.xTCP.pxAckMessage ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxAckMessage ); TEST_ASSERT_EQUAL( 100U, xSocket.u.xTCP.usTimeout ); } /** * @brief Test functionality when the stream is non-NULL and the * time out is non-zero. The port number cannot be allowed to issue log * messages. */ void test_xTCPSocketCheck_StateEstablished_TxStreamNonNull1_NonZeroTimeout_NoLogPort( void ) { BaseType_t xReturn, xToReturn = 0, xBackup; FreeRTOS_Socket_t xSocket = { 0 }; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.txStream = ( void * ) &xSocket; xSocket.u.xTCP.pxAckMessage = ( void * ) &xSocket; xSocket.u.xTCP.usTimeout = 100; xSocket.usLocalPort = 23U; xBackup = xTCPWindowLoggingLevel; xTCPWindowLoggingLevel = 2; prvTCPAddTxData_Expect( &xSocket ); uxIPHeaderSizeSocket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); prvTCPReturnPacket_Expect( &xSocket, xSocket.u.xTCP.pxAckMessage, ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER, ipconfigZERO_COPY_TX_DRIVER ); vReleaseNetworkBufferAndDescriptor_Expect( xSocket.u.xTCP.pxAckMessage ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxAckMessage ); TEST_ASSERT_EQUAL( 100U, xSocket.u.xTCP.usTimeout ); xTCPWindowLoggingLevel = xBackup; } /** * @brief Test functionality when the stream is non-NULL and the * time out is non-zero. The port number cannot be allowed to issue log * messages. */ void test_xTCPSocketCheck_StateCLOSED_TxStreamNonNull1_NonZeroTimeout( void ) { BaseType_t xReturn, xToReturn = 0; FreeRTOS_Socket_t xSocket = { 0 }; TickType_t xDelayReturn = 0; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.txStream = ( void * ) &xSocket; xSocket.u.xTCP.pxAckMessage = ( void * ) &xSocket; xSocket.u.xTCP.usTimeout = 100; xSocket.usLocalPort = 23U; xTCPWindowLoggingLevel = 2; vReleaseNetworkBufferAndDescriptor_Expect( xSocket.u.xTCP.pxAckMessage ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxAckMessage ); TEST_ASSERT_EQUAL( 100U, xSocket.u.xTCP.usTimeout ); xTCPWindowLoggingLevel = 1; } /** * @brief Test functionality when the stream is non-NULL and the * time out is non-zero. Additionally, the user has requested to shutdown * the socket. */ void test_xTCPSocketCheck_StateeCONNECT_SYN_TxStreamNonNull_UserShutdown( void ) { BaseType_t xReturn, xToReturn = 0; FreeRTOS_Socket_t xSocket = { 0 }; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eCONNECT_SYN; xSocket.u.xTCP.txStream = ( void * ) &xSocket; xSocket.u.xTCP.pxAckMessage = ( void * ) &xSocket; xSocket.u.xTCP.usTimeout = 100; xSocket.u.xTCP.bits.bUserShutdown = pdTRUE_UNSIGNED; vReleaseNetworkBufferAndDescriptor_Expect( xSocket.u.xTCP.pxAckMessage ); prvTCPSendPacket_ExpectAndReturn( &xSocket, 0 ); prvTCPStatusAgeCheck_ExpectAndReturn( &xSocket, xToReturn ); xReturn = xTCPSocketCheck( &xSocket ); TEST_ASSERT_EQUAL( xToReturn, xReturn ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxAckMessage ); /* ARP phase. Check every half second. */ TEST_ASSERT_EQUAL( 500U, xSocket.u.xTCP.usTimeout ); } /** * @brief Test to validate 'Touching' the socket * to keep it alive/updated. */ void test_prvTCPTouchSocket( void ) { FreeRTOS_Socket_t xSocket = { 0 }; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0xAA, sizeof( xSocket ) ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); prvTCPTouchSocket( &xSocket ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eCONNECT_SYN. */ void test_prvTCPNextTimeout_ConnSyn_State_Not_Active( void ) { TickType_t Return = 0; pxSocket = &xSocket; pxSocket->u.xTCP.eTCPState = eCONNECT_SYN; pxSocket->u.xTCP.bits.bConnPrepared = pdFALSE; pxSocket->u.xTCP.ucRepCount = 0; Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( 500, Return ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eCONNECT_SYN and connection * is prepared. */ void test_prvTCPNextTimeout_ConnSyn_State_Active_Rep0( void ) { TickType_t Return = 0; pxSocket = &xSocket; pxSocket->u.xTCP.eTCPState = eCONNECT_SYN; pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE; pxSocket->u.xTCP.ucRepCount = 0; Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( 1, Return ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eCONNECT_SYN and rep count * is less than 3. */ void test_prvTCPNextTimeout_ConnSyn_State_Active_Rep1( void ) { TickType_t Return = 0; pxSocket = &xSocket; pxSocket->u.xTCP.eTCPState = eCONNECT_SYN; pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE; pxSocket->u.xTCP.ucRepCount = 1; Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( 3000, Return ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eCONNECT_SYN and rep count * is 3. */ void test_prvTCPNextTimeout_ConnSyn_State_Active_Rep3( void ) { TickType_t Return = 0; pxSocket = &xSocket; pxSocket->u.xTCP.eTCPState = eCONNECT_SYN; pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE; pxSocket->u.xTCP.ucRepCount = 3; Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( 11000, Return ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eESTABLISHED and an active * time out being set. */ void test_prvTCPNextTimeout_Established_State_Active_Timeout_Set( void ) { TickType_t Return = 0; pxSocket = &xSocket; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.usTimeout = 5000; pxSocket->u.xTCP.ucRepCount = 3; Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( 5000, Return ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eESTABLISHED and an active * time out is not set but has timeout delay. */ void test_prvTCPNextTimeout_Established_State_Active_Timeout_Not_Set_Has_Data_With_Delay( void ) { TickType_t Return = 0; pxSocket = &xSocket; TickType_t TxWinReturn = 1000; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.usTimeout = 0; pxSocket->u.xTCP.ucRepCount = 3; xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdTRUE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &TxWinReturn ); Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( 1000, Return ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eESTABLISHED valid with TX data * and no timeout delay. */ void test_prvTCPNextTimeout_Established_State_Active_Timeout_Not_Set_Has_Data_Without_Delay( void ) { TickType_t Return = 0; pxSocket = &xSocket; TickType_t TxWinReturn = 0; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.usTimeout = 0; pxSocket->u.xTCP.ucRepCount = 3; xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdTRUE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &TxWinReturn ); Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( 1, Return ); } /** * @brief Test to validate Calculate after how much * time this socket needs to be checked again * when tcp state is eESTABLISHED valid with no * TX data and no timeout delay. */ void test_prvTCPNextTimeout_Established_State_Active_Timeout_Not_Set_No_Data_Without_Delay( void ) { TickType_t Return = 0; pxSocket = &xSocket; TickType_t TxWinReturn = 0; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.usTimeout = 0; pxSocket->u.xTCP.ucRepCount = 3; xTCPWindowTxHasData_ExpectAnyArgsAndReturn( pdFALSE ); xTCPWindowTxHasData_ReturnThruPtr_pulDelay( &TxWinReturn ); Return = prvTCPNextTimeout( pxSocket ); TEST_ASSERT_EQUAL( tcpMAXIMUM_TCP_WAKEUP_TIME_MS, Return ); } /** * @brief Test functionality when the state to be reached and the * current state equal to closed state. */ void test_vTCPStateChange_ClosedState( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSED; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached is closed wait * and current state is equal to connect syn. */ void test_vTCPStateChange_ClosedWaitState_PrvStateSyn( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.eTCPState = eCONNECT_SYN; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached is closed wait * and current state is equal to syn first. */ void test_vTCPStateChange_ClosedWaitState_PrvStateSynFirst( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.eTCPState = eSYN_FIRST; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached is closed wait * and current state is equal to syn first. */ void test_vTCPStateChange_ClosedWaitState_CurrentStateSynFirstNextStateCloseWait( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocketToListen = NULL; xSocket.u.xTCP.eTCPState = eSYN_FIRST; xSocket.u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( &xSocket, xSocketToListen ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached is closed wait * and current state is equal to syn received. */ void test_vTCPStateChange_ClosedWaitState_PrvStateSynRecvd( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.eTCPState = eSYN_RECEIVED; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. */ void test_vTCPStateChange_ClosedWaitState( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. Socket bIsIPv6 bit is set * indicating IPv6 socket. */ void test_vTCPStateChange_ClosedWaitState_bIsIPv6( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.bits.bIsIPv6 = 1; eTCPState = eCLOSE_WAIT; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. Socket bIsIPv6 bit is set * indicating IPv6 socket and port set as 23 as ipconfigTCP_MAY_LOG_PORT * definition will not generate log messages for ports 23. */ void test_vTCPStateChange_ClosedWaitState_IncorrectPort( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.usLocalPort = 23U; eTCPState = eCLOSE_WAIT; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. Additionally, the pass queued * bit is set and the function is being called from IP task. */ void test_vTCPStateChange_ClosedWaitState_CallingFromIPTask( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); xSocket.u.xTCP.eTCPState = eCLOSE_WAIT; eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xIsCallingFromIPTask_ExpectAndReturn( pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. Additionally, the pass queued * bit is set and the function is not being called from IP task. */ void test_vTCPStateChange_ClosedWaitState_NotCallingFromIPTask( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xIsCallingFromIPTask_ExpectAndReturn( pdFALSE ); catch_assert( vTCPStateChange( &xSocket, eTCPState ) ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. Additionally, the pass accept * bit is set and the function is being called from IP task. */ void test_vTCPStateChange_ClosedWaitState_CallingFromIPTask1( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xIsCallingFromIPTask_ExpectAndReturn( pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. Additionally, the pass accept * bit is set and the function is not being called from IP task. */ void test_vTCPStateChange_ClosedWaitState_NotCallingFromIPTask1( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xIsCallingFromIPTask_ExpectAndReturn( pdFALSE ); catch_assert( vTCPStateChange( &xSocket, eTCPState ) ); } /** * @brief Test functionality when the state to be reached and the * current state equal to close wait state. Additionally, the pass accept * and reuse socket bits are set. */ void test_vTCPStateChange_ClosedWaitState_ReuseSocket( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSE_WAIT; xSocket.u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED; xSocket.u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED; vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSE_WAIT, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); } /** * @brief Test functionality when the state to be reached and the * current state equal to established state. Additionally, the pass accept * and reuse socket bits are set. */ void test_vTCPStateChange_EstablishedState_ReuseSocket( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED; xSocket.u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED; xBackup = xTCPWindowLoggingLevel; xTCPWindowLoggingLevel = -1; xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eESTABLISHED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); xTCPWindowLoggingLevel = xBackup; } /** * @brief Test functionality when the state to be reached is closed and the * current state is established state. Additionally, the pass accept * and reuse socket bits are set. */ void test_vTCPStateChange_EstablishedToClosedState_SocketInactive( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSED; xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.usTimeout = 100; xBackup = xTCPWindowLoggingLevel; xTCPWindowLoggingLevel = 2; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, 0 ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_CLOSED, xSocket.xEventBits ); xTCPWindowLoggingLevel = xBackup; } /** * @brief Test functionality when the state to be reached is closed and the * current state is established state. */ void test_vTCPStateChange_EstablishedToClosedState_SocketActive( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSED; xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.usTimeout = 100; xSocket.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; xBackup = xTCPWindowLoggingLevel; xTCPWindowLoggingLevel = 2; xHandleConnectedSocket = &xSocket; xHandleConnectedLength = 0; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_CLOSED, xSocket.xEventBits ); xTCPWindowLoggingLevel = xBackup; } /** * @brief Test functionality when the state to be reached is closed and the * current state is established state. Socket select bit is set to select except. */ void test_vTCPStateChange_EstablishedToClosedState_SocketActive_SelectExcept( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eCLOSED; xSocket.u.xTCP.eTCPState = eESTABLISHED; xSocket.u.xTCP.usTimeout = 100; xSocket.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; xSocket.xSelectBits = eSELECT_EXCEPT; xBackup = xTCPWindowLoggingLevel; xTCPWindowLoggingLevel = 2; xHandleConnectedSocket = &xSocket; xHandleConnectedLength = 0; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eCLOSED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_CLOSED | ( eSELECT_EXCEPT << SOCKET_EVENT_BIT_COUNT ), xSocket.xEventBits ); xTCPWindowLoggingLevel = xBackup; } /** * @brief Test functionality when the state to be reached is established and the * current state is closed. Socket select bit is set to select except. */ void test_vTCPStateChange_ClosedToEstablishedState_SocketActive_SelectExcept( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.usTimeout = 100; xSocket.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; xSocket.xSelectBits = eSELECT_EXCEPT; xHandleConnectedSocket = &xSocket; /* Expect the connected field to be set. */ xHandleConnectedLength = 1; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eESTABLISHED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_CONNECT, xSocket.xEventBits ); } /** * @brief Test functionality when the state to be reached is established and the * current state is closed. Socket select bit is set to select write. */ void test_vTCPStateChange_ClosedToEstablishedState_SocketActive_SelectWrite( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.usTimeout = 100; xSocket.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; xSocket.xSelectBits = eSELECT_WRITE; xHandleConnectedSocket = &xSocket; /* Expect the connected field to be set. */ xHandleConnectedLength = 1; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eESTABLISHED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_CONNECT | ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT ), xSocket.xEventBits ); } /** * @brief Test functionality when the state to be reached is established and the * current state is closed. Socket select bit is set to select write. Also, this socket * is an orphan. Since parent socket is NULL and reuse bit is not set, it will hit an * assertion. */ void test_vTCPStateChange_ClosedToEstablishedState_SelectWrite_QueuedBitSet( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.usTimeout = 100; xSocket.xSelectBits = eSELECT_WRITE; /* if bPassQueued is true, this socket is an orphan until it gets connected. */ xSocket.u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; catch_assert( vTCPStateChange( &xSocket, eTCPState ) ); } /** * @brief Test functionality when the state to be reached is established and the * current state is closed. Socket select bit is set to select write. Also, this socket * is an orphan. Parent socket is non-NULL and reuse bit is not set. */ void test_vTCPStateChange_ClosedToEstablishedState_SelectWrite_QueuedBitSet_ParentNonNULL( void ) { FreeRTOS_Socket_t xSocket, xParentSock; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); memset( &xParentSock, 0, sizeof( xParentSock ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.usTimeout = 100; xSocket.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; xSocket.xSelectBits = eSELECT_WRITE; /* if bPassQueued is true, this socket is an orphan until it gets connected. */ xSocket.u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; xSocket.u.xTCP.pxPeerSocket = &xParentSock; xHandleConnectedSocket = &xSocket; /* Expect the connected field to be set. */ xHandleConnectedLength = 1; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xParentSock ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eESTABLISHED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_ACCEPT, xParentSock.xEventBits ); TEST_ASSERT_EQUAL( &xSocket, xParentSock.u.xTCP.pxPeerSocket ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxPeerSocket ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bPassQueued ); TEST_ASSERT_EQUAL( pdTRUE_UNSIGNED, xSocket.u.xTCP.bits.bPassAccept ); } /** * @brief Test functionality when the state to be reached is established and the * current state is closed. Socket select bit is set to select write. Also, this socket * is an orphan. Parent socket is non-NULL and reuse bit is not set. Additionally, the * parent socket has a connected handler. */ void test_vTCPStateChange_ClosedToEstablishedState_QueuedBitSet_ParentNonNULL_HasHandler( void ) { FreeRTOS_Socket_t xSocket, xParentSock; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); memset( &xParentSock, 0, sizeof( xParentSock ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.usTimeout = 100; xParentSock.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; /* if bPassQueued is true, this socket is an orphan until it gets connected. */ xSocket.u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; xSocket.u.xTCP.pxPeerSocket = &xParentSock; xHandleConnectedSocket = &xParentSock; /* Expect the connected field to be set. */ xHandleConnectedLength = 1; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xParentSock ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eESTABLISHED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_ACCEPT, xParentSock.xEventBits ); TEST_ASSERT_EQUAL( &xSocket, xParentSock.u.xTCP.pxPeerSocket ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxPeerSocket ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bPassQueued ); TEST_ASSERT_EQUAL( pdTRUE_UNSIGNED, xSocket.u.xTCP.bits.bPassAccept ); } /** * @brief Test functionality when the state to be reached is established and the * current state is closed. Socket select bit is set to select write. Also, this socket * is an orphan. Parent socket is non-NULL and reuse bit is not set. Additionally, the * parent socket has a connected handler. */ void test_vTCPStateChange_ClosedToEstablishedState_QueuedBitSet_ParentNonNULL_HasHandler1( void ) { FreeRTOS_Socket_t xSocket, xParentSock; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); memset( &xParentSock, 0, sizeof( xParentSock ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.usTimeout = 100; xParentSock.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; xSocket.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; /* if bPassQueued is true, this socket is an orphan until it gets connected. */ xSocket.u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; xSocket.u.xTCP.pxPeerSocket = &xParentSock; xParentSock.u.xTCP.pxPeerSocket = &xSocket; xHandleConnectedSocket = &xParentSock; /* Expect the connected field to be set. */ xHandleConnectedLength = 1; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xParentSock ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eESTABLISHED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( eSOCKET_ACCEPT, xParentSock.xEventBits ); TEST_ASSERT_EQUAL( &xSocket, xParentSock.u.xTCP.pxPeerSocket ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxPeerSocket ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bPassQueued ); TEST_ASSERT_EQUAL( pdTRUE_UNSIGNED, xSocket.u.xTCP.bits.bPassAccept ); } /** * @brief Test functionality when the state to be reached is established and the * current state is closed. Socket select bit is set to select read. Also, this socket * is an orphan. Parent socket is NULL and reuse bit is set. */ void test_vTCPStateChange_ClosedToEstablishedState_SelectRead_QueuedBitSet_ParentNULLReuse( void ) { FreeRTOS_Socket_t xSocket = { 0 }; enum eTCP_STATE eTCPState; BaseType_t xTickCountAck = 0xAABBEEDD; BaseType_t xTickCountAlive = 0xAABBEFDD; BaseType_t xBackup; memset( &xSocket, 0, sizeof( xSocket ) ); eTCPState = eESTABLISHED; xSocket.u.xTCP.eTCPState = eCLOSED; xSocket.u.xTCP.usTimeout = 100; xSocket.u.xTCP.pxHandleConnected = ( FOnConnected_t ) HandleConnected; xSocket.xSelectBits = eSELECT_READ; /* if bPassQueued is true, this socket is an orphan until it gets connected. */ xSocket.u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; xSocket.u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED; xHandleConnectedSocket = &xSocket; /* Expect the connected field to be set. */ xHandleConnectedLength = 1; prvTCPSocketIsActive_ExpectAndReturn( xSocket.u.xTCP.eTCPState, pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTickCountAck ); xTaskGetTickCount_ExpectAndReturn( xTickCountAlive ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( &xSocket ); vTCPStateChange( &xSocket, eTCPState ); TEST_ASSERT_EQUAL( eESTABLISHED, xSocket.u.xTCP.eTCPState ); TEST_ASSERT_EQUAL( xTickCountAck, xSocket.u.xTCP.xLastActTime ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bWaitKeepAlive ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bSendKeepAlive ); TEST_ASSERT_EQUAL( 0, xSocket.u.xTCP.ucKeepRepCount ); TEST_ASSERT_EQUAL( xTickCountAlive, xSocket.u.xTCP.xLastAliveTime ); TEST_ASSERT_EQUAL( 100, xSocket.u.xTCP.usTimeout ); TEST_ASSERT_EQUAL( NULL, xSocket.u.xTCP.pxPeerSocket ); TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, xSocket.u.xTCP.bits.bPassQueued ); TEST_ASSERT_EQUAL( pdTRUE_UNSIGNED, xSocket.u.xTCP.bits.bPassAccept ); TEST_ASSERT_EQUAL( eSOCKET_ACCEPT | ( eSELECT_READ << SOCKET_EVENT_BIT_COUNT ), xSocket.xEventBits ); } /** * @brief This function catch assert when received a TCP packet * with NULL descriptor. */ void test_xProcessReceivedTCPPacket_Null_Descriptor( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxNetworkBuffer->xDataLength = 40; catch_assert( xProcessReceivedTCPPacket( NULL ) ); } /** * @brief This function catch assert when received a TCP packet * with NULL buffer. */ void test_xProcessReceivedTCPPacket_Null_Buffer( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = NULL; pxNetworkBuffer->xDataLength = 40; catch_assert( xProcessReceivedTCPPacket( pxNetworkBuffer ) ); } /** * @brief This function validates received a TCP packet of * frame type IPv6 and process the packet. */ void test_xProcessReceivedTCPPacket_IPv6_FrameType( void ) { BaseType_t Return = pdFALSE; EthernetHeader_t xEthHeader; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xEthHeader; xEthHeader.usFrameType = ipIPv6_FRAME_TYPE; pxNetworkBuffer->xDataLength = 40; Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdTRUE, Return ); } /** * @brief This function validates handling of a TCP packet of * invalid frame type. */ void test_xProcessReceivedTCPPacket_Incorrect_FrameType( void ) { BaseType_t Return = pdFALSE; EthernetHeader_t xEthHeader; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xEthHeader; xEthHeader.usFrameType = 0; pxNetworkBuffer->xDataLength = 40; Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet as data length check fails. */ void test_xProcessReceivedTCPPacket_Minimal_Data_Length( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxNetworkBuffer->xDataLength = 40; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet as socket is NULL. */ void test_xProcessReceivedTCPPacket_No_Socket( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_ACK; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( NULL ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet where there is no active socket. */ void test_xProcessReceivedTCPPacket_No_Active_Socket( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eCLOSE_WAIT; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdFALSE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when there is no active socket and there is a send reset. */ void test_xProcessReceivedTCPPacket_No_Active_Socket_Send_Reset( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eCLOSE_WAIT; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_ACK | tcpTCP_FLAG_FIN; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdFALSE ); prvTCPSendReset_ExpectAnyArgsAndReturn( pdTRUE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eTCP_LISTEN. */ void test_xProcessReceivedTCPPacket_Listen_State_Not_Syn_No_Rst( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eTCP_LISTEN; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eTCP_LISTEN. */ void test_xProcessReceivedTCPPacket_Listen_State_Not_Syn_Rst( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eTCP_LISTEN; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_ACK; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); prvTCPSendReset_ExpectAnyArgsAndReturn( pdTRUE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eTCP_LISTEN and socket is NULL socket. */ void test_xProcessReceivedTCPPacket_Listen_State_Syn_Null_Socket( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eTCP_LISTEN; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_SYN; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); prvHandleListen_ExpectAnyArgsAndReturn( NULL ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates success in processing received TCP * packet when tcp state is eTCP_LISTEN. */ void test_xProcessReceivedTCPPacket_Listen_State_Syn_NoOp_Sent_Something( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eTCP_LISTEN; pxSocket->u.xTCP.usTimeout = 1000; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_SYN; pxProtocolHeaders->xTCPHeader.ucTCPOffset = 0x50; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); prvHandleListen_ExpectAnyArgsAndReturn( pxSocket ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); prvTCPHandleState_ExpectAnyArgsAndReturn( 70 ); prvTCPSendRepeated_ExpectAnyArgsAndReturn( 70 ); vReleaseNetworkBufferAndDescriptor_ExpectAnyArgs(); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdTRUE, Return ); } /** * @brief This function validates success in processing received TCP * packet when tcp state is eTCP_LISTEN. */ void test_xProcessReceivedTCPPacket_Listen_State_Syn_NoOp_Sent_None( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eTCP_LISTEN; pxSocket->u.xTCP.usTimeout = 1000; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_SYN; pxProtocolHeaders->xTCPHeader.ucTCPOffset = 0x50; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); prvHandleListen_ExpectAnyArgsAndReturn( pxSocket ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); prvTCPHandleState_ExpectAnyArgsAndReturn( 0 ); vReleaseNetworkBufferAndDescriptor_ExpectAnyArgs(); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdTRUE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eTCP_LISTEN. */ void test_xProcessReceivedTCPPacket_Listen_State_Syn_With_Op_Check_Failed( void ) { BaseType_t Return = pdFALSE; NetworkBufferDescriptor_t * pNullBuffer = NULL; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eTCP_LISTEN; pxSocket->u.xTCP.usTimeout = 1000; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_SYN; pxProtocolHeaders->xTCPHeader.ucTCPOffset = 0x80; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); prvHandleListen_ExpectAnyArgsAndReturn( pxSocket ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); prvCheckOptions_ExpectAnyArgsAndReturn( pdFALSE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates success in processing received TCP * packet when tcp state is eTCP_LISTEN. */ void test_xProcessReceivedTCPPacket_Listen_State_Syn_With_Op_Sent_Something_Buffer_Gone( void ) { BaseType_t Return = pdFALSE; NetworkBufferDescriptor_t * pNullBuffer = NULL; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eTCP_LISTEN; pxSocket->u.xTCP.usTimeout = 1000; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_SYN; pxProtocolHeaders->xTCPHeader.ucTCPOffset = 0x80; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); prvHandleListen_ExpectAnyArgsAndReturn( pxSocket ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); prvCheckOptions_ExpectAnyArgsAndReturn( pdTRUE ); prvTCPHandleState_ExpectAnyArgsAndReturn( 70 ); prvTCPSendRepeated_ExpectAnyArgsAndReturn( 70 ); prvTCPSendRepeated_ReturnThruPtr_ppxNetworkBuffer( &pNullBuffer ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdTRUE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_Establish_State_Syn( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_SYN; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_ConnectSyn_State_Rst_Change_State( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eCONNECT_SYN; pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = 0; pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 1 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( pxSocket ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); TEST_ASSERT_EQUAL( eCLOSED, pxSocket->u.xTCP.eTCPState ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_ConnectSyn_State_Rst_SeqNo_Wrong( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eCONNECT_SYN; pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = 0; pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 100 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates success in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_SynReceived_State_Rst( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eSYN_RECEIVED; pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 1000; pxProtocolHeaders->xTCPHeader.ucTCPOffset = 0x50; pxProtocolHeaders->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( 1001 ); pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 100 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_SYN; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); uxIPHeaderSizeSocket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); prvTCPHandleState_ExpectAnyArgsAndReturn( 0 ); vReleaseNetworkBufferAndDescriptor_ExpectAnyArgs(); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdTRUE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_Establish_State_Rst_Change_State( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 1000; pxProtocolHeaders->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( 1000 ); pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 100 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); vTaskSuspendAll_Expect(); xTaskResumeAll_ExpectAndReturn( 0 ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); FreeRTOS_inet_ntop_ExpectAnyArgsAndReturn( NULL ); vSocketWakeUpUser_Expect( pxSocket ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); TEST_ASSERT_EQUAL( eCLOSED, pxSocket->u.xTCP.eTCPState ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_Establish_State_Rst_Seq_InRange( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 1000; pxProtocolHeaders->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( 1001 ); pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 100 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); xSequenceGreaterThan_ExpectAnyArgsAndReturn( pdTRUE ); xSequenceLessThan_ExpectAnyArgsAndReturn( pdTRUE ); prvTCPSendChallengeAck_ExpectAnyArgsAndReturn( pdTRUE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_Establish_State_Rst_Seq_OutRange1( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 1000; pxProtocolHeaders->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( 1001 ); pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 100 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); xSequenceGreaterThan_ExpectAnyArgsAndReturn( pdTRUE ); xSequenceLessThan_ExpectAnyArgsAndReturn( pdFALSE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates failure in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_Establish_State_Rst_Seq_OutRange2( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 1000; pxProtocolHeaders->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( 1001 ); pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 100 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_RST; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); xSequenceGreaterThan_ExpectAnyArgsAndReturn( pdFALSE ); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdFALSE, Return ); } /** * @brief This function validates success in processing received TCP * packet when tcp state is eESTABLISHED. */ void test_xProcessReceivedTCPPacket_Establish_State_Ack( void ) { BaseType_t Return = pdFALSE; pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; pxSocket = &xSocket; ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); pxNetworkBuffer->xDataLength = 100; pxSocket->u.xTCP.eTCPState = eESTABLISHED; pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 1000; pxProtocolHeaders->xTCPHeader.ucTCPOffset = 0x50; pxProtocolHeaders->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( 1001 ); pxProtocolHeaders->xTCPHeader.ulAckNr = FreeRTOS_htonl( 100 ); pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_ACK; uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); uxIPHeaderSizePacket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); pxTCPSocketLookup_ExpectAnyArgsAndReturn( pxSocket ); prvTCPSocketIsActive_ExpectAnyArgsAndReturn( pdTRUE ); uxIPHeaderSizeSocket_ExpectAnyArgsAndReturn( ipSIZE_OF_IPv4_HEADER ); xTaskGetTickCount_ExpectAndReturn( 1000 ); xTaskGetTickCount_ExpectAndReturn( 1500 ); prvTCPHandleState_ExpectAnyArgsAndReturn( 0 ); vReleaseNetworkBufferAndDescriptor_ExpectAnyArgs(); Return = xProcessReceivedTCPPacket( pxNetworkBuffer ); TEST_ASSERT_EQUAL( pdTRUE, Return ); } static void test_Helper_ListInitialise( List_t * const pxList ) { /* The list structure contains a list item which is used to mark the * end of the list. To initialise the list the list end is inserted * as the only list entry. */ pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ /* The list end value is the highest possible value in the list to * ensure it remains at the end of the list. */ pxList->xListEnd.xItemValue = portMAX_DELAY; /* The list end next and previous pointers point to itself so we know * when the list is empty. */ pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->uxNumberOfItems = ( UBaseType_t ) 0U; /* Write known values into the list if * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); } static void test_Helper_ListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) { ListItem_t * const pxIndex = pxList->pxIndex; /* Only effective when configASSERT() is also defined, these tests may catch * the list data structures being overwritten in memory. They will not catch * data errors caused by incorrect configuration or use of FreeRTOS. */ listTEST_LIST_INTEGRITY( pxList ); listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); /* Insert a new list item into pxList, but rather than sort the list, * makes the new list item the last item to be removed by a call to * listGET_OWNER_OF_NEXT_ENTRY(). */ pxNewListItem->pxNext = pxIndex; pxNewListItem->pxPrevious = pxIndex->pxPrevious; /* Only used during decision coverage testing. */ mtCOVERAGE_TEST_DELAY(); pxIndex->pxPrevious->pxNext = pxNewListItem; pxIndex->pxPrevious = pxNewListItem; /* Remember which list the item is in. */ pxNewListItem->pxContainer = pxList; ( pxList->uxNumberOfItems )++; } /** * @brief This function validates not finding a new client * in case the list to iterate through is empty. */ void test_xTCPCheckNewClient_Empty_List( void ) { BaseType_t Return = pdFALSE; pxSocket = &xSocket; List_t * pSocketList = &xBoundTCPSocketsList; MiniListItem_t EndItem; test_Helper_ListInitialise( pSocketList ); pxSocket->usLocalPort = 40000; Return = xTCPCheckNewClient( pxSocket ); TEST_ASSERT_EQUAL( pdFALSE, Return ); TEST_ASSERT_EQUAL( NULL, pxSocket->u.xTCP.pxPeerSocket ); } /** * @brief This function validates not finding a new client * with a given port. */ void test_xTCPCheckNewClient_Not_Found_No_Port( void ) { BaseType_t Return = pdFALSE; pxSocket = &xSocket; List_t * pSocketList = &xBoundTCPSocketsList; ListItem_t NewEntry; pxSocket->xBoundSocketListItem.xItemValue = 443; test_Helper_ListInitialise( pSocketList ); test_Helper_ListInsertEnd( &xBoundTCPSocketsList, &( pxSocket->xBoundSocketListItem ) ); pxSocket->usLocalPort = FreeRTOS_ntohs( 40000 ); Return = xTCPCheckNewClient( pxSocket ); TEST_ASSERT_EQUAL( pdFALSE, Return ); TEST_ASSERT_EQUAL( NULL, pxSocket->u.xTCP.pxPeerSocket ); } /** * @brief This function validates not finding a new client * in of UDP protocol. */ void test_xTCPCheckNewClient_Not_Found_Not_TCP( void ) { BaseType_t Return = pdFALSE; pxSocket = &xSocket; List_t * pSocketList = &xBoundTCPSocketsList; ListItem_t NewEntry; pxSocket->xBoundSocketListItem.xItemValue = 40000; pxSocket->xBoundSocketListItem.pvOwner = pxSocket; pxSocket->ucProtocol = FREERTOS_IPPROTO_UDP; pxSocket->u.xTCP.bits.bPassAccept = pdTRUE; test_Helper_ListInitialise( pSocketList ); test_Helper_ListInsertEnd( &xBoundTCPSocketsList, &( pxSocket->xBoundSocketListItem ) ); pxSocket->usLocalPort = FreeRTOS_ntohs( 40000 ); Return = xTCPCheckNewClient( pxSocket ); TEST_ASSERT_EQUAL( pdFALSE, Return ); TEST_ASSERT_EQUAL( NULL, pxSocket->u.xTCP.pxPeerSocket ); } /** * @brief This function validates not finding a new client * in case bPassAccept is not set. */ void test_xTCPCheckNewClient_Not_Found_Not_Aceept( void ) { BaseType_t Return = pdFALSE; pxSocket = &xSocket; List_t * pSocketList = &xBoundTCPSocketsList; ListItem_t NewEntry; pxSocket->xBoundSocketListItem.xItemValue = 40000; pxSocket->xBoundSocketListItem.pvOwner = pxSocket; pxSocket->ucProtocol = FREERTOS_IPPROTO_TCP; pxSocket->u.xTCP.bits.bPassAccept = pdFALSE; test_Helper_ListInitialise( pSocketList ); test_Helper_ListInsertEnd( &xBoundTCPSocketsList, &( pxSocket->xBoundSocketListItem ) ); pxSocket->usLocalPort = FreeRTOS_ntohs( 40000 ); Return = xTCPCheckNewClient( pxSocket ); TEST_ASSERT_EQUAL( pdFALSE, Return ); TEST_ASSERT_EQUAL( NULL, pxSocket->u.xTCP.pxPeerSocket ); } /** * @brief This function validates the case of finding * a new client. */ void test_xTCPCheckNewClient_Found( void ) { BaseType_t Return = pdFALSE; pxSocket = &xSocket; List_t * pSocketList = &xBoundTCPSocketsList; ListItem_t NewEntry; pxSocket->xBoundSocketListItem.xItemValue = 40000; pxSocket->xBoundSocketListItem.pvOwner = pxSocket; pxSocket->ucProtocol = FREERTOS_IPPROTO_TCP; pxSocket->u.xTCP.bits.bPassAccept = pdTRUE; test_Helper_ListInitialise( pSocketList ); test_Helper_ListInsertEnd( &xBoundTCPSocketsList, &( pxSocket->xBoundSocketListItem ) ); pxSocket->usLocalPort = FreeRTOS_ntohs( 40000 ); Return = xTCPCheckNewClient( pxSocket ); TEST_ASSERT_EQUAL( pdTRUE, Return ); TEST_ASSERT_EQUAL_PTR( pxSocket, pxSocket->u.xTCP.pxPeerSocket ); }