/* Include Unity header */ #include "unity.h" /* Include standard libraries */ #include #include #include #include "mock_FreeRTOS_IP.h" #include "mock_FreeRTOS_IP_Timers.h" #include "mock_FreeRTOS_IP_Private.h" #include "mock_FreeRTOS_Sockets.h" #include "mock_FreeRTOS_UDP_IP.h" #include "mock_FreeRTOS_ARP.h" #include "mock_task.h" #include "mock_NetworkBufferManagement.h" #include "mock_FreeRTOS_DHCP_mock.h" #include "mock_FreeRTOS_IP_Common.h" #include "FreeRTOS_DHCP.h" #include "FreeRTOS_DHCP_stubs.c" #include "catch_assert.h" #include "FreeRTOSIPConfig.h" /*-------------------------------------Extern Variables--------------------------*/ extern Socket_t xDHCPv4Socket; extern DHCPData_t xDHCPData; extern NetworkInterface_t xInterfaces[ 1 ]; extern BaseType_t xDHCPSocketUserCount; static const char * pcHostName = "Unit-Test"; extern eDHCPCallbackPhase_t eStubExpectedDHCPPhase; extern struct xNetworkEndPoint * pxStubExpectedEndPoint; extern uint32_t ulStubExpectedIPAddress; extern eDHCPCallbackAnswer_t eStubExpectedReturn; extern uint8_t * ucGenericPtr; extern int32_t ulGenericLength; extern NetworkBufferDescriptor_t * pxGlobalNetworkBuffer[ 10 ]; extern uint8_t GlobalBufferCounter; extern uint8_t pucUDPBuffer[]; extern uint8_t DHCP_header[]; /*---------------------------------------Test Cases--------------------------*/ void test_xIsDHCPSocket( void ) { BaseType_t xReturn; struct xSOCKET xTestSocket; xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /************************************/ /* Test by NOT giving DHCP socket. */ xReturn = xIsDHCPSocket( NULL ); TEST_ASSERT_EQUAL( pdFALSE, xReturn ); /************************************/ /* Test by giving DHCP socket. */ xReturn = xIsDHCPSocket( xDHCPv4Socket ); TEST_ASSERT_EQUAL( pdTRUE, xReturn ); xDHCPv4Socket = NULL; } void test_eGetDHCPState( void ) { DHCPData_t xTestData; eDHCPState_t eReturn; int i; struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; for( i = 0; i < sizeof( xTestData.eDHCPState ); i++ ) { /* Modify the global state. */ pxEndPoint->xDHCPData.eDHCPState = i; eReturn = eGetDHCPState( &xEndPoint ); TEST_ASSERT_EQUAL( i, eReturn ); } } void test_vDHCPProcess_AssertChecks( void ) { struct xNetworkEndPoint xEndPoint = { 0 }; xEndPoint.bits.bIPv6 = 1; catch_assert( vDHCPProcess( pdFALSE, NULL ) ); catch_assert( vDHCPProcess( pdFALSE, &xEndPoint ) ); } void test_vDHCPProcess_NotResetAndIncorrectState( void ) { struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; vDHCPProcess( pdFALSE, pxEndPoint ); /* Since the expected state is incorrect, the state * should remain the same. */ TEST_ASSERT_EQUAL( eSendDHCPRequest, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_ResetAndIncorrectStateWithRNGFail( void ) { struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Make random number generation fail. */ xApplicationGetRandomNumber_ExpectAndReturn( &( pxEndPoint->xDHCPData.ulTransactionId ), pdFALSE ); vDHCPProcess( pdTRUE, pxEndPoint ); /* Expected state is incorrect, but we are trying to reset * the DHCP the state machine. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_ResetAndInvalidSocket( void ) { NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; xDHCPv4Socket = NULL; /* Put any state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = 0; /* This should be reset to 0. */ pxEndPoint->xDHCPData.xUseBroadcast = 1; /* This should be reset as well */ pxEndPoint->xDHCPData.ulOfferedIPAddress = 0xAAAAAAAA; /* And this too. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = 0xABABABAB; /* Make random number generation pass. */ xApplicationGetRandomNumber_ExpectAndReturn( &( pxEndPoint->xDHCPData.ulTransactionId ), pdTRUE ); /* return an invalid socket. */ FreeRTOS_socket_ExpectAndReturn( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP, FREERTOS_INVALID_SOCKET ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); catch_assert( vDHCPProcess( pdTRUE, pxEndPoint ) ); } void test_vDHCPProcess_ResetAndIncorrectStateWithRNGSuccessSocketCreationFail( void ) { NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Test all the valid and invalid entries. */ for( int i = 0; i < ( eNotUsingLeasedAddress * 2 ); i++ ) { /* This should get assigned to a given value. */ xDHCPv4Socket = NULL; /* Put any state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = i; /* This should be reset to 0. */ pxEndPoint->xDHCPData.xUseBroadcast = 1; /* This should be reset as well */ pxEndPoint->xDHCPData.ulOfferedIPAddress = 0xAAAAAAAA; /* And this too. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = 0xABABABAB; /* Make random number generation pass. */ xApplicationGetRandomNumber_ExpectAndReturn( &( pxEndPoint->xDHCPData.ulTransactionId ), pdTRUE ); /* return an invalid socket. */ FreeRTOS_socket_ExpectAndReturn( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP, FREERTOS_INVALID_SOCKET ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); /* See if the timer is reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpINITIAL_TIMER_PERIOD ); /* Try all kinds of states. */ vDHCPProcess( pdTRUE, pxEndPoint ); /* Expected state is incorrect, but we are trying to reset * the DHCP the state machine. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.xUseBroadcast ); /* This should be reset as well */ TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.ulOfferedIPAddress ); /* And this too. */ TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.ulDHCPServerAddress ); } } void test_vDHCPProcess_ResetAndIncorrectStateWithRNGSuccessSocketSuccess( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Test all the valid and invalid entries. */ for( int i = 0; i < ( eNotUsingLeasedAddress * 2 ); i++ ) { /* This should get assigned to a given value. */ xDHCPv4Socket = NULL; /* Put any state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = i; /* This should be reset to 0. */ pxEndPoint->xDHCPData.xUseBroadcast = 1; /* This should be reset as well */ pxEndPoint->xDHCPData.ulOfferedIPAddress = 0xAAAAAAAA; /* And this too. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = 0xABABABAB; /* Make random number generation pass. */ xApplicationGetRandomNumber_ExpectAndReturn( &( pxEndPoint->xDHCPData.ulTransactionId ), pdTRUE ); /* Return a valid socket. */ FreeRTOS_socket_ExpectAndReturn( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP, &xTestSocket ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Ignore the inputs to setting the socket options. */ FreeRTOS_setsockopt_ExpectAnyArgsAndReturn( pdPASS ); FreeRTOS_setsockopt_ExpectAnyArgsAndReturn( pdPASS ); /* Make sure that binding passes. Return zero. */ vSocketBind_ExpectAnyArgsAndReturn( 0 ); /* See if the timer is reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpINITIAL_TIMER_PERIOD ); /* Try all kinds of states. */ vDHCPProcess( pdTRUE, pxEndPoint ); /* Expected state is incorrect, but we are trying to reset * the DHCP the state machine. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.xUseBroadcast ); /* This should be reset as well */ TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.ulOfferedIPAddress ); /* And this too. */ TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.ulDHCPServerAddress ); } } void test_vDHCPProcess_ResetAndIncorrectStateWithRNGSuccessSocketBindFail( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Test all the valid and invalid entries. */ for( int i = 0; i < ( eNotUsingLeasedAddress * 2 ); i++ ) { /* This should remain unchanged. */ xDHCPv4Socket = NULL; /* Put any state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = i; /* This should be reset to 0. */ pxEndPoint->xDHCPData.xUseBroadcast = 1; /* This should be reset as well */ pxEndPoint->xDHCPData.ulOfferedIPAddress = 0xAAAAAAAA; /* And this too. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = 0xABABABAB; /* Make random number generation pass. */ xApplicationGetRandomNumber_ExpectAndReturn( &( pxEndPoint->xDHCPData.ulTransactionId ), pdTRUE ); /* Return a valid socket. */ FreeRTOS_socket_ExpectAndReturn( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP, &xTestSocket ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Ignore the inputs to setting the socket options. */ FreeRTOS_setsockopt_ExpectAnyArgsAndReturn( pdPASS ); FreeRTOS_setsockopt_ExpectAnyArgsAndReturn( pdPASS ); /* Make sure that binding fails. Return anything except zero. */ vSocketBind_ExpectAnyArgsAndReturn( 1 ); /* Expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* See if the timer is reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpINITIAL_TIMER_PERIOD ); /* Try all kinds of states. */ vDHCPProcess( pdTRUE, pxEndPoint ); } } void test_vDHCPProcess_ResetAndIncorrectStateWithSocketAlreadyCreated( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Test all the valid and invalid entries. */ for( int i = 0; i < ( eNotUsingLeasedAddress * 2 ); i++ ) { /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put any state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = i; /* This should be reset to 0. */ pxEndPoint->xDHCPData.xUseBroadcast = 1; /* This should be reset as well */ pxEndPoint->xDHCPData.ulOfferedIPAddress = 0xAAAAAAAA; /* And this too. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = 0xABABABAB; /* And this should be updated. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 0; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make random number generation pass. */ xApplicationGetRandomNumber_ExpectAndReturn( &( pxEndPoint->xDHCPData.ulTransactionId ), pdTRUE ); /* See if the timer is reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpINITIAL_TIMER_PERIOD ); /* Try all kinds of states. */ vDHCPProcess( pdTRUE, pxEndPoint ); /* Expected state is incorrect, but we are trying to reset * the DHCP the state machine. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( xDHCPv4Socket, &xTestSocket ); TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.xUseBroadcast ); /* This should be reset as well */ TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.ulOfferedIPAddress ); /* And this too. */ TEST_ASSERT_EQUAL( 0, pxEndPoint->xDHCPData.ulDHCPServerAddress ); /* This should be updated. */ TEST_ASSERT_EQUAL( dhcpINITIAL_DHCP_TX_PERIOD, pxEndPoint->xDHCPData.xDHCPTxPeriod ); } } void test_vDHCPProcess_CorrectStateDHCPHookFailsDHCPSocketNULL( void ) { NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* The DHCP socket is NULL. */ xDHCPv4Socket = NULL; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ pxEndPoint->ipv4_defaults.ulIPAddress = 0x12345678; /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = ( eDHCPContinue + eDHCPUseDefaults ) << 2; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Expect the timer to be disabled. */ vIPSetDHCP_RATimerEnableState_Expect( &xEndPoint, pdFALSE ); vIPNetworkUpCalls_Ignore(); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* The state should indicate that we are not using leased address. */ TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that the Endpoint IP address pointer indicates that. */ /*TEST_ASSERT_EQUAL( pxEndPoint->ipv4_defaults.ulIPAddress, *ipLOCAL_IP_ADDRESS_POINTER ); */ TEST_ASSERT_EQUAL( pxEndPoint->ipv4_defaults.ulIPAddress, pxEndPoint->ipv4_settings.ulIPAddress ); } void test_vDHCPProcess_CorrectStateDHCPHookFailsDHCPSocketNonNULL( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ pxEndPoint->ipv4_defaults.ulIPAddress = 0x12345678; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = ( eDHCPContinue + eDHCPUseDefaults ) << 2; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Expect the timer to be disabled. */ vIPSetDHCP_RATimerEnableState_Expect( &xEndPoint, pdFALSE ); /* Ignore the call. */ vIPNetworkUpCalls_Ignore(); /* Expect the socket to be closed. */ vSocketClose_ExpectAndReturn( xDHCPv4Socket, NULL ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* The state should indicate that we are not using leased address. */ TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that the local IP address pointer indicates that. */ TEST_ASSERT_EQUAL( pxEndPoint->ipv4_defaults.ulIPAddress, pxEndPoint->ipv4_settings.ulIPAddress ); } void test_vDHCPProcess_CorrectStateDHCPHookDefaultReturn( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPUseDefaults; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Expect the timer to be disabled. */ vIPSetDHCP_RATimerEnableState_Expect( &xEndPoint, pdFALSE ); /* Ignore the call. */ vIPNetworkUpCalls_Ignore(); /* Expect the socket to be closed. */ vSocketClose_ExpectAndReturn( xDHCPv4Socket, NULL ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* The state should indicate that we are not using leased address. */ TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that the network addressing struct is updated to show that. */ TEST_ASSERT_EQUAL_MEMORY( &pxEndPoint->ipv4_defaults, &pxEndPoint->ipv4_settings, sizeof( IPV4Parameters_t ) ); /* Make sure that the local IP address pointer indicates that. */ TEST_ASSERT_EQUAL( pxEndPoint->ipv4_defaults.ulIPAddress, pxEndPoint->ipv4_settings.ulIPAddress ); } /* GNW = getNetworkBufferWithDescriptor */ void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnDHCPSocketNotNULLButGNWFails( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); xTaskGetTickCount_ExpectAndReturn( 100 ); pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning NULL will mean the prvSendDHCPDiscover fail. */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we are not using leased address. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnDHCPSocketNotNULLButHostNameNULL( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); xTaskGetTickCount_ExpectAndReturn( 100 ); pcApplicationHostnameHook_ExpectAndReturn( NULL ); /* Returning NULL will mean the prvSendDHCPDiscover fail. */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we are not using leased address. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnDHCPSocketNULL( void ) { NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = NULL; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Expect the timer to be disabled. */ vIPSetDHCP_RATimerEnableState_Expect( &xEndPoint, pdFALSE ); /* Ignore the call. */ vIPNetworkUpCalls_Ignore(); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* The state should indicate that we are not using leased address. */ TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnSendFailsNoBroadcast( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Not using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Return the time value. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Make the call to FreeRTOS_send fail. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 0 ); /* Since the send failed, a call to release the buffer should be there. */ FreeRTOS_ReleaseUDPPayloadBuffer_Stub( ReleaseUDPBuffer ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); /* The time value should be as expected. */ TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); } void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnSendFailsNoBroadcast_NULLHostName( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Not using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Return the time value. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname = NULL. */ pcApplicationHostnameHook_ExpectAndReturn( NULL ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Make the call to FreeRTOS_send fail. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 0 ); /* Since the send failed, a call to release the buffer should be there. */ FreeRTOS_ReleaseUDPPayloadBuffer_Stub( ReleaseUDPBuffer ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); /* The time value should be as expected. */ TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); } void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnSendFailsUseBroadCast( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Not using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdTRUE; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Return the time value. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); /* Make the call to FreeRTOS_send fail. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 0 ); /* Since the send failed, a call to release the buffer should be there. */ FreeRTOS_ReleaseUDPPayloadBuffer_Stub( ReleaseUDPBuffer ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingSendFirstDiscover, pxEndPoint->xDHCPData.eDHCPState ); /* The time value should be as expected. */ TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); } void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnSendSucceedsUseBroadCast( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdTRUE; pxEndPoint->xDHCPData.ulPreferredIPAddress = 0x00; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Return the time value. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Make the call to FreeRTOS_send succeed. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); /* The time value should be as expected. */ TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); /* Free the allocated memory. */ ReleaseNetworkBuffer(); } void test_vDHCPProcess_CorrectStateDHCPHookContinueReturnSendSucceedsUseBroadCast1( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingSendFirstDiscover; pxEndPoint->xDHCPData.eExpectedState = eWaitingSendFirstDiscover; /* Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdTRUE; pxEndPoint->xDHCPData.ulPreferredIPAddress = 0x01; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that the user indicates anything else than the desired options. */ eStubExpectedDHCPPhase = eDHCPPhasePreDiscover; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = pxEndPoint->ipv4_defaults.ulIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Return the time value. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Make the call to FreeRTOS_send succeed. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); /* The time value should be as expected. */ TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); /* Free the allocated memory. */ ReleaseNetworkBuffer(); } void test_vDHCPProcess_eSendDHCPRequestCorrectStateGNWFails( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = eSendDHCPRequest; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Return NULL network buffer. */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be NULL */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eSendDHCPRequest, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eSendDHCPRequestCorrectStateGNWSucceedsSendFails( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = eSendDHCPRequest; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Send fails. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 0 ); /* ReleaseUDPPayloadBuffer will be called. */ FreeRTOS_ReleaseUDPPayloadBuffer_Stub( ReleaseUDPBuffer ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be still allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eSendDHCPRequest, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eSendDHCPRequestCorrectStateGNWSucceedsSendSucceeds( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eSendDHCPRequest; pxEndPoint->xDHCPData.eExpectedState = eSendDHCPRequest; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Send succeeds. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); /* Return the time value. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be still allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); TEST_ASSERT_EQUAL( dhcpINITIAL_DHCP_TX_PERIOD, pxEndPoint->xDHCPData.xDHCPTxPeriod ); } void test_vDHCPProcess_eWaitingOfferRecvfromFailsNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be still allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromFailsTimeoutGiveUp( void ) /* prvCloseDHCPSocket */ { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we exceed the period - and give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = ipconfigMAXIMUM_DISCOVER_TX_PERIOD; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that there is timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference greater than the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Time will be stored in DHCP state machine. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Make all calls to the RNG succeed. */ xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); /* Closing the DHCP socket. */ vSocketClose_ExpectAndReturn( xDHCPv4Socket, 0 ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); /* Ignore the call to this function. */ vARPSendGratuitous_Ignore(); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eGetLinkLayerAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromFailsTimeoutDontGiveUpRNGFail( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) - 1; /* Expect these arguments. Return a 0 to fail. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that there is timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference greater than the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Make all calls to the RNG fail. */ xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdFALSE ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); /* make sure that the period is increased by a factor of two. */ TEST_ASSERT_EQUAL( ( ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) - 1 ) << 1, pxEndPoint->xDHCPData.xDHCPTxPeriod ); } void test_vDHCPProcess_eWaitingOfferRecvfromFailsTimeoutDontGiveUpRNGPassUseBroadcast( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) - 1; /* Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdTRUE; /* Expect these arguments. Return a 0 to fail. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that there is timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference greater than the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Make all calls to the RNG succeed. */ xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Send succeeds. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); /* make sure that the period is increased by a factor of two. */ TEST_ASSERT_EQUAL( ( ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) - 1 ) << 1, pxEndPoint->xDHCPData.xDHCPTxPeriod ); } void test_vDHCPProcess_eWaitingOfferRecvfromFailsTimeoutDontGiveUpRNGPassNoBroadcast( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) - 1; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Expect these arguments. Return a 0 to fail. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); /* Make sure that there is timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference greater than the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Make all calls to the RNG succeed. */ xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a NULL network buffer. */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); vDHCPProcess( pdFALSE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eInitialWait, pxEndPoint->xDHCPData.eDHCPState ); /* make sure that the period is increased by a factor of two. */ TEST_ASSERT_EQUAL( ( ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) - 1 ) << 1, pxEndPoint->xDHCPData.xDHCPTxPeriod ); } /** *@brief This function ensures if bytes is received in the next UDP message */ void test_vDHCPProcess_eLeasedAddress_CorrectState_ValidBytesInMessage( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_CorrectState_ValidBytesInMessage_NullEndPoint( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = NULL; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_CorrectState_ValidBytesInMessage_TransactionIDMismatch( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; /* make sure the transaction ID does not match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEE; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint; pxNetworkEndPoints->pxNext = NULL; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_CorrectState_ValidBytesInMessage_TwoFlagOptions_nullbytes( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage_TwoFlagOptions_nullbytes ); FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_CorrectState_ValidBytesInMessage_TwoFlagOptions_nullbuffer( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage_TwoFlagOptions_nullbuffer ); FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_IncorrectDHCPCookie_ValidBytesInMessage( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage_IncorrectDHCPCookie ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_IncorrectOpCode_ValidBytesInMessage( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage_IncorrectOpCode ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } /** *@brief This function ensures if bytes is received in the next UDP message * when DHCP state is eWaitingOffer */ void test_vDHCPProcess_eWaitingOffer_CorrectState_ValidBytesInMessage_MatchingEndPoint( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage ); FreeRTOS_ReleaseUDPPayloadBuffer_Ignore(); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } /** *@brief This function ensures if bytes is received in the next UDP message * when DHCP state is eWaitingAcknowledge */ void test_vDHCPProcess_eWaitingAcknowledge_CorrectState_ValidBytesInMessage_diffEndPoint( void ) { struct xSOCKET xTestSocket; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; NetworkEndPoint_t xEndPoint_2 = { 0 }, * pxEndPoint_2 = &xEndPoint_2; uint8_t * pucUDPPayload; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Make sure that the local IP address is uninitialised. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) ); /* Put the required state. */ pxEndPoint_2->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint_2->xDHCPData.eExpectedState = eWaitingAcknowledge; pxEndPoint_2->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the local IP address is uninitialised. */ pxEndPoint_2->ipv4_settings.ulIPAddress = 0; /* Put a verifiable value. */ memset( &pxEndPoint_2->ipv4_settings, 0xBB, sizeof( IPV4Parameters_t ) ); /* Put a verifiable value. */ memset( &pxEndPoint_2->ipv4_defaults, 0xAA, sizeof( IPV4Parameters_t ) ); pxNetworkEndPoints = pxEndPoint_2; pxEndPoint->xDHCPData.xDHCPTxTime = 100; pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Expect these arguments. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_ResetAndIncorrectStateWithSocketAlreadyCreated_validUDPmessage_TwoFlagOptions_nullbytes ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime ); vDHCPProcess( pdFALSE, pxEndPoint ); TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcessEndPoint_NullEndPoint( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; pxEndPoint->xDHCPData.ulTransactionId = 0; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSucceedsFalseCookieNoTimeout ); catch_assert( vDHCPProcessEndPoint( pdFALSE, pdTRUE, NULL ) ); } void test_vDHCPProcessEndPoint_eWaitingOfferNullUDPBuffer( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; pxEndPoint->xDHCPData.ulTransactionId = 0; pxNetworkEndPoints = pxEndPoint; FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY, NULL, NULL, 1 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); } void test_vDHCPProcessEndPoint_eWaitingOfferDHCPReply_NullUDPmessage( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; pxEndPoint->xDHCPData.ulTransactionId = 0; pxNetworkEndPoints = pxEndPoint; /* Expect these arguments. */ FreeRTOS_recvfrom_ExpectAndReturn( xDHCPv4Socket, NULL, 0UL, FREERTOS_ZERO_COPY, NULL, NULL, 0 ); /* Ignore the buffer argument though. */ FreeRTOS_recvfrom_IgnoreArg_pvBuffer(); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); } void test_vDHCPProcess_eWaitingOfferRecvfromSucceedsFalseCookieNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; pxEndPoint->xDHCPData.ulTransactionId = 0; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSucceedsFalseCookieNoTimeout ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSucceedsFalseOpcodeNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSucceedsFalseOpcodeNoTimeout ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSucceedsCorrectCookieAndOpcodeNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which won't match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSucceedsCorrectCookieAndOpcodeNoTimeout ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromLessBytesNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which won't match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromLessBytesNoTimeout ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSuccessCorrectTxID( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSuccessCorrectTxID ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSuccess_CorrectAddrType( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSuccess_CorrectAddrType ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSuccess_CorrectAddrLen_BroadcastAddress( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSuccess_CorrectAddrLen ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSuccess_CorrectAddrLen_LocalHostAddress( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSuccess_LocalHostAddr ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSuccess_CorrectAddrLen_NonLocalHostAddress( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSuccess_NonLocalHostAddr ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferRecvfromSuccess_CorrectAddrLen_LocalMACNotmatching( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; MACAddress_t xBackup; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; memcpy( &xBackup, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memset( ipLOCAL_MAC_ADDRESS, 0xAA, sizeof( MACAddress_t ) ); /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_eWaitingOfferRecvfromSuccess_LocalMACAddrNotMatching ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); memcpy( ipLOCAL_MAC_ADDRESS, &xBackup, sizeof( MACAddress_t ) ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageWithoutOptionsNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; uint8_t DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageIncorrectOptionsNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 3U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Now add options which will be processed. */ /* Add a closing flag at the end. */ DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageMissingLengthByteNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U + 1U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageIncorrectLengthByteNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U + 3U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add incorrect length. */ DHCPOption[ 1 ] = 100; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageGetNACKNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U + 3U + 1U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_NACK; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageGetNACKNoTimeout_MatchingMACAddress( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U + 3U + 1U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_NACK; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Set the MAC address that matches. */ memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageGetACKNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U + 3U + 1U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageOneOptionNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U + 3U + 1U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_OFFER; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; memcpy( pxEndPoint->xMACAddress.ucBytes, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageOneOptionNoTimeout2( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U + 3U + 1U; uint8_t DHCPMsg[ xTotalLength ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_DNS_SERVER_OPTIONS_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = 12; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ /*xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); */ vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that we still in the state from where we started. */ TEST_ASSERT_EQUAL( eWaitingOffer, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageTwoOptionsSendFails( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.ulOfferedIPAddress = DHCPServerAddress; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_OFFER; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the address matches. */ memcpy( pxEndPoint->xMACAddress.ucBytes, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Return continue. */ eStubExpectedDHCPPhase = eDHCPPhasePreRequest; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = ulClientIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Make the hook return correct value. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning NULL will mean the prvSendDHCPRequest fails. */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that sending failed. */ TEST_ASSERT_EQUAL( eSendDHCPRequest, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageTwoOptionsSendSucceeds( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.ulOfferedIPAddress = DHCPServerAddress; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_OFFER; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Return continue. */ eStubExpectedDHCPPhase = eDHCPPhasePreRequest; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = ulClientIPAddress; eStubExpectedReturn = eDHCPContinue; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Make the hook return correct value. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Make the call to FreeRTOS_send succeed. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* The state should indicate that sending failed. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); /* The time should be updated. */ TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageTwoOptionsDHCPHookReturnDefaultSendSucceeds( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.ulOfferedIPAddress = DHCPServerAddress; /* Rest the network addressing values. */ memset( &( pxEndPoint->ipv4_settings ), 0, sizeof( IPV4Parameters_t ) ); /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_OFFER; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; pxNetworkEndPoints = pxEndPoint; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Return continue. */ eStubExpectedDHCPPhase = eDHCPPhasePreRequest; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = ulClientIPAddress; eStubExpectedReturn = eDHCPUseDefaults; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Expect the timer to be disabled. */ vIPSetDHCP_RATimerEnableState_Expect( &xEndPoint, pdFALSE ); vIPNetworkUpCalls_Ignore(); /* Expect the socket to be closed. */ vSocketClose_ExpectAndReturn( xDHCPv4Socket, NULL ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* The state should indicate that sending failed. */ TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL_MEMORY( &( pxEndPoint->ipv4_settings ), &( pxEndPoint->ipv4_defaults ), sizeof( IPV4Parameters_t ) ); } void test_vDHCPProcess_eWaitingOfferCorrectDHCPMessageTwoOptionsDHCPHookReturnErrorSendSucceeds( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint8_t testMemory[ sizeof( IPV4Parameters_t ) ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; pxEndPoint->xDHCPData.ulOfferedIPAddress = DHCPServerAddress; /* Rest the network addressing values. */ memset( &( xEndPoint ), 0, sizeof( NetworkEndPoint_t ) ); memset( &( testMemory ), 0, sizeof( IPV4Parameters_t ) ); /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_OFFER; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer; pxEndPoint->xDHCPData.eExpectedState = eWaitingOffer; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Make sure that the address matches. */ memcpy( pxEndPoint->xMACAddress.ucBytes, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Return continue. */ eStubExpectedDHCPPhase = eDHCPPhasePreRequest; pxStubExpectedEndPoint = pxEndPoint; ulStubExpectedIPAddress = ulClientIPAddress; eStubExpectedReturn = ( eDHCPContinue + eDHCPUseDefaults ) << 1; xApplicationDHCPHook_Multi_Stub( xStubApplicationDHCPHook_Multi ); /* Expect the timer to be disabled. */ vIPSetDHCP_RATimerEnableState_Expect( &xEndPoint, pdFALSE ); vIPNetworkUpCalls_Ignore(); /* Expect the socket to be closed. */ vSocketClose_ExpectAndReturn( xDHCPv4Socket, NULL ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* The state should indicate that sending failed. */ TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL_MEMORY( &( pxEndPoint->ipv4_settings ), &( testMemory ), sizeof( IPV4Parameters_t ) ); } void test_vDHCPProcess_eWaitingAcknowledgeTwoOptionsIncorrectServerNoTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint8_t testMemory[ sizeof( IPV4Parameters_t ) ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Rest the network addressing values. */ memset( &( pxEndPoint->ipv4_settings ), 0, sizeof( IPV4Parameters_t ) ); memset( &( testMemory ), 0, sizeof( IPV4Parameters_t ) ); /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put incorrect address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress + 1234; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Still waiting on acknowledge. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL_MEMORY( &( pxEndPoint->ipv4_settings ), &( testMemory ), sizeof( IPV4Parameters_t ) ); } void test_vDHCPProcess_eWaitingAcknowledgeTwoOptionsIncorrectServerTimeoutGNBfails( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint8_t testMemory[ sizeof( IPV4Parameters_t ) ]; DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Rest the network addressing values. */ memset( &( pxEndPoint->ipv4_settings ), 0, sizeof( IPV4Parameters_t ) ); memset( &( testMemory ), 0, sizeof( IPV4Parameters_t ) ); /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put incorrect address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress + 1234; /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Return time second time which can be verified. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a NULL so that prvSendDHCPRequest fails. */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Still waiting on acknowledge. */ TEST_ASSERT_EQUAL( eSendDHCPRequest, pxEndPoint->xDHCPData.eDHCPState ); /* The time value should be stored in the state machine. */ TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); TEST_ASSERT_EQUAL_MEMORY( &( pxEndPoint->ipv4_settings ), &( testMemory ), sizeof( IPV4Parameters_t ) ); } void test_vDHCPProcess_eWaitingAcknowledgeTwoOptionsIncorrectServerTimeoutGNBsucceeds( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put incorrect address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress + 1234; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Return time second time which can be verified. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Send succeeds. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Still waiting on acknowledge. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); } void test_vDHCPProcess_eWaitingAcknowledgeTwoOptionsIncorrectServerTimeoutPeriodLess( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure we exceed the period - and thus, give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) + 1; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put incorrect address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress + 1234; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Period exceeded. We should now be in initial state. */ TEST_ASSERT_EQUAL( eInitialWait, pxEndPoint->xDHCPData.eDHCPState ); /* Period exceeded, should have initial value */ TEST_ASSERT_EQUAL( 100, pxEndPoint->xDHCPData.xDHCPTxTime ); } void test_vDHCPProcess_eWaitingAcknowledgeTwoOptionsIncorrectServerTimeoutPeriodLessTimeout( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure we exceed the period - and thus, give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = ( ipconfigMAXIMUM_DISCOVER_TX_PERIOD >> 1 ) + 1; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put incorrect address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress + 1234; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Make sure that there is timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference equal to the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod ); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Period exceeded. We should now be in initial state. */ /* Period exceeded, should have initial value */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( 100, pxEndPoint->xDHCPData.xDHCPTxTime ); } void test_vDHCPProcess_eWaitingAcknowledgeTwoOptionsCorrectServerLeaseTimeZero( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Make sure that the address matches. */ memcpy( pxEndPoint->xMACAddress.ucBytes, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Reset the lease time so that it will be set to default * value later. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpDEFAULT_LEASE_TIME ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingAcknowledgeTwoOptionsCorrectServerLeaseTimeLessThanMinConfig( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time so that it will be set to minimum * value later. */ pxEndPoint->xDHCPData.ulLeaseTime = dhcpMINIMUM_LEASE_TIME - 10; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpMINIMUM_LEASE_TIME ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( dhcpMINIMUM_LEASE_TIME, pxEndPoint->xDHCPData.ulLeaseTime ); } void test_vDHCPProcess_eWaitingAcknowledge_TwoOptions_CorrectServer_AptLeaseTime( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time to an appropriate value. */ pxEndPoint->xDHCPData.ulLeaseTime = dhcpMINIMUM_LEASE_TIME + 10; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpMINIMUM_LEASE_TIME + 10 ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( dhcpMINIMUM_LEASE_TIME + 10, pxEndPoint->xDHCPData.ulLeaseTime ); } void test_vDHCPProcess_eWaitingAcknowledge_TwoOptions_NACK( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_NACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time to an appropriate value. */ pxEndPoint->xDHCPData.ulLeaseTime = dhcpMINIMUM_LEASE_TIME + 10; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Should now be reset after NACK. */ TEST_ASSERT_EQUAL( eInitialWait, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingAcknowledge_TwoOptions_OFFER( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_OFFER; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time to an appropriate value. */ pxEndPoint->xDHCPData.ulLeaseTime = dhcpMINIMUM_LEASE_TIME + 10; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Should not be reset after OFFER. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingAcknowledge_AllOptionsCorrectLength( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 6U /* DNS server */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ uint32_t ulDNSServer = 0xC0010101; /* 192.1.1.1 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; IPV4Parameters_t * xIPv4Addressing = &( pxEndPoint->ipv4_settings ); DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_DNS_SERVER_OPTIONS_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulDNSServer; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ) ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ), pxEndPoint->xDHCPData.ulLeaseTime ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulGatewayAddress, ulGateway ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulNetMask, ulSubnetMask ); } void test_vDHCPProcess_eWaitingAcknowledge_AllOptionsCorrectLength2( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 6U /* DNS server */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ uint32_t ulDNSServer = 0xC0010101; /* 192.1.1.1 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; IPV4Parameters_t * xIPv4Addressing = &( pxEndPoint->ipv4_settings ); DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_DNS_SERVER_OPTIONS_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulDNSServer; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ) ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ), pxEndPoint->xDHCPData.ulLeaseTime ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulGatewayAddress, ulGateway ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulNetMask, ulSubnetMask ); } void test_vDHCPProcess_eWaitingAcknowledge_DNSIncorrectLength( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 6U /* DNS server */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ uint32_t ulDNSServer = 0xC0010101; /* 192.1.1.1 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; IPV4Parameters_t * xIPv4Addressing = &( pxEndPoint->ipv4_settings ); DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_DNS_SERVER_OPTIONS_CODE; /* Add length. */ DHCPOption[ 1 ] = 3; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulDNSServer; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ) ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ), pxEndPoint->xDHCPData.ulLeaseTime ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulGatewayAddress, ulGateway ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulNetMask, ulSubnetMask ); } void test_vDHCPProcess_eWaitingAcknowledge_DNSIncorrectLength2( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 24U /* DNS server */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ uint32_t ulDNSServer = 0xC0010101; /* 192.1.1.1 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; IPV4Parameters_t * xIPv4Addressing = &( pxEndPoint->ipv4_settings ); DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_DNS_SERVER_OPTIONS_CODE; /* Add length. */ DHCPOption[ 1 ] = 24; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulDNSServer; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ) + 100; /* ulGenericLength is incremented by 100 to have uxDNSCount > ipconfigENDPOINT_DNS_ADDRESS_COUNT scenario */ /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ) ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ), pxEndPoint->xDHCPData.ulLeaseTime ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulGatewayAddress, ulGateway ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulNetMask, ulSubnetMask ); } void test_vDHCPProcess_eWaitingAcknowledge_IncorrectDNSServerAddress( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 6U /* DNS server */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ uint32_t ulDNSServer = 0xC0010101; /* 192.1.1.1 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; IPV4Parameters_t * xIPv4Addressing = &( pxEndPoint->ipv4_settings ); DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_DNS_SERVER_OPTIONS_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = FREERTOS_INADDR_ANY; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ) ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ), pxEndPoint->xDHCPData.ulLeaseTime ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulGatewayAddress, ulGateway ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulNetMask, ulSubnetMask ); } void test_vDHCPProcess_eWaitingAcknowledge_IncorrectDNSServerAddress2( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 6U /* DNS server */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ uint32_t ulDNSServer = 0xC0010101; /* 192.1.1.1 */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; IPV4Parameters_t * xIPv4Addressing = &( pxEndPoint->ipv4_settings ); DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_DNS_SERVER_OPTIONS_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ipBROADCAST_IP_ADDRESS; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ) ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( configTICK_RATE_HZ * ( FreeRTOS_ntohl( ulLeaseTime ) >> 1 ), pxEndPoint->xDHCPData.ulLeaseTime ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulGatewayAddress, ulGateway ); TEST_ASSERT_EQUAL( xIPv4Addressing->ulNetMask, ulSubnetMask ); } void test_vDHCPProcess_eWaitingAcknowledge_IPv4ServerIncorrectLength( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 3; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Ignore(); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( dhcpDEFAULT_LEASE_TIME, pxEndPoint->xDHCPData.ulLeaseTime ); } void test_vDHCPProcess_eWaitingAcknowledge_SubnetMaskIncorrectLength( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add incorrect length. */ DHCPOption[ 1 ] = 3; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Ignore(); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( dhcpDEFAULT_LEASE_TIME, pxEndPoint->xDHCPData.ulLeaseTime ); } void test_vDHCPProcess_eWaitingAcknowledge_GatewayIncorrectLength( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add incorrect length. */ DHCPOption[ 1 ] = 2; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Ignore(); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( dhcpDEFAULT_LEASE_TIME, pxEndPoint->xDHCPData.ulLeaseTime ); } void test_vDHCPProcess_eWaitingAcknowledge_LeaseTimeIncorrectLength( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add incorrect length. */ DHCPOption[ 1 ] = 3; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); /* Expect this function to be called since we now have * successfully acquired an IP address. */ vIPNetworkUpCalls_Expect( &xEndPoint ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); /* Expect ARP to begin. */ vARPSendGratuitous_Expect(); /* Expect the timer to be reloaded. */ vDHCP_RATimerReload_Ignore(); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* DHCP socket should be unallocated */ TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); /* Make sure that this is not changed. */ TEST_ASSERT_EQUAL( dhcpDEFAULT_LEASE_TIME, pxEndPoint->xDHCPData.ulLeaseTime ); } void test_vDHCPProcess_eWaitingAcknowledge_LeaseTimeIncorrectLength2( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 1U /* Padding */ + 3U /* DHCP offer */ + 6U /* Server IP address */ + 6U /* Subnet Mask */ + 6U /* Gateway */ + 6U /* Lease time */ + 1U /* End */; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Leave one byte for the padding. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) + 1 ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 1; /* Add the offer byte. */ DHCPOption[ 2 ] = dhcpMESSAGE_TYPE_ACK; DHCPOption += 4; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = DHCPServerAddress + 0x1234; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_SUBNET_MASK_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulSubnetMask; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_GATEWAY_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 4; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulGateway; DHCPOption += 6; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_LEASE_TIME_OPTION_CODE; /* Add incorrect length. */ DHCPOption[ 1 ] = 3; /* Add the offer byte. */ *( ( uint32_t * ) &DHCPOption[ 2 ] ) = ulLeaseTime; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Release the UDP buffer. */ FreeRTOS_ReleaseUDPPayloadBuffer_Expect( DHCPMsg ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* Should now be using leased address. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eWaitingAcknowledge_IncorrectLengthofpacket( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; /* Create a bit longer DHCP message but keep it empty. */ const BaseType_t xTotalLength = sizeof( struct xDHCPMessage_IPv4 ) + 2U; uint8_t DHCPMsg[ xTotalLength ]; uint32_t DHCPServerAddress = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulClientIPAddress = 0xC0A8000A; /* 192.168.0.10 */ uint32_t ulSubnetMask = 0xFFFFF100; /* 255.255.241.0 */ uint32_t ulGateway = 0xC0A80001; /* 192.168.0.1 */ uint32_t ulLeaseTime = 0x00000096; /* 150 seconds */ DHCPMessage_IPv4_t * pxDHCPMessage = ( DHCPMessage_IPv4_t * ) DHCPMsg; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; DHCPMsg[ xTotalLength - 1U ] = 0xFF; /* Set the header - or at least the start of DHCP message. */ memset( DHCPMsg, 0, sizeof( DHCPMsg ) ); /* Copy the header here. */ memcpy( DHCPMsg, DHCP_header, sizeof( DHCP_header ) ); /* Make sure that the address matches. */ memcpy( pxDHCPMessage->ucClientHardwareAddress, ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); memcpy( &( pxEndPoint->xMACAddress.ucBytes ), ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ); /* Add the expected cookie. */ pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE; /* Set the client IP address. */ pxDHCPMessage->ulYourIPAddress_yiaddr = ulClientIPAddress; /* Get pointer to the end. */ uint8_t * DHCPOption = &DHCPMsg[ sizeof( struct xDHCPMessage_IPv4 ) ]; /* Add Message type code. */ DHCPOption[ 0 ] = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; /* Add length. */ DHCPOption[ 1 ] = 0; /* Put the information in global variables to be returned by * the FreeRTOS_recvrom. */ ucGenericPtr = DHCPMsg; ulGenericLength = sizeof( DHCPMsg ); /* This should remain unchanged. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge; pxEndPoint->xDHCPData.eExpectedState = eWaitingAcknowledge; /* Not Using broadcast. */ pxEndPoint->xDHCPData.xUseBroadcast = pdFALSE; /* Set the transaction ID which will match. */ pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF; /* Put correct address. */ pxEndPoint->xDHCPData.ulDHCPServerAddress = DHCPServerAddress; /* Reset the lease time. */ pxEndPoint->xDHCPData.ulLeaseTime = 0; /* Put some time values. */ pxEndPoint->xDHCPData.xDHCPTxTime = 100; /* Make sure that we don't exceed the period - and thus, don't give up. */ pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Reset this value so that it can be verified later. */ pxEndPoint->ipv4_settings.ulIPAddress = 0; /* Get a stub. */ FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_Generic ); /* Make sure that there is no timeout. The expression is: xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod */ /* Return a value which makes the difference just equal to the period. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxTime + pxEndPoint->xDHCPData.xDHCPTxPeriod + 100 ); /* Return time second time which can be verified. */ xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Get the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Send succeeds. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); /* DHCP socket should be allocated */ TEST_ASSERT_EQUAL( &xTestSocket, xDHCPv4Socket ); /* Should still be stuck in waiting for ack state. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eGetLinkLayerAddress_Timeout_NoARPIPClash( void ) { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.xDHCPTxTime = 100; pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eGetLinkLayerAddress; pxEndPoint->xDHCPData.eExpectedState = eGetLinkLayerAddress; xARPHadIPClash = pdFALSE; xDHCPv4Socket = NULL; xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxPeriod + pxEndPoint->xDHCPData.xDHCPTxTime + 100 ); vIPNetworkUpCalls_Expect( &xEndPoint ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eGetLinkLayerAddress_Timeout_ARPIPClash( void ) /* prvPrepareLinkLayerIPLookUp + prvCloseDHCPSocket */ { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.xDHCPTxTime = 100; pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eGetLinkLayerAddress; pxEndPoint->xDHCPData.eExpectedState = eGetLinkLayerAddress; /* This should be nullified. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; xARPHadIPClash = pdTRUE; xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxPeriod + pxEndPoint->xDHCPData.xDHCPTxTime + 100 ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); /* Then expect the socket to be closed. */ vSocketClose_ExpectAndReturn( &xTestSocket, NULL ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); vARPSendGratuitous_Expect(); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); TEST_ASSERT_EQUAL( eGetLinkLayerAddress, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); } void test_vDHCPProcess_eGetLinkLayerAddress_Timeout_ARPIPClash_NoSocketInUse( void ) /* prvPrepareLinkLayerIPLookUp + prvCloseDHCPSocket */ { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.xDHCPTxTime = 100; pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eGetLinkLayerAddress; pxEndPoint->xDHCPData.eExpectedState = eGetLinkLayerAddress; /* This should be nullified. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 0; xARPHadIPClash = pdTRUE; xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxPeriod + pxEndPoint->xDHCPData.xDHCPTxTime + 100 ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); /* Then expect the socket to be closed. */ xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); vARPSendGratuitous_Expect(); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); TEST_ASSERT_EQUAL( eGetLinkLayerAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eGetLinkLayerAddress_Timeout_ARPIPClash_TwoSocketsInUse( void ) /* prvPrepareLinkLayerIPLookUp + prvCloseDHCPSocket */ { struct xSOCKET xTestSocket; TickType_t xTimeValue = 1234; struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.xDHCPTxTime = 100; pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eGetLinkLayerAddress; pxEndPoint->xDHCPData.eExpectedState = eGetLinkLayerAddress; /* This should be nullified. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 2; xARPHadIPClash = pdTRUE; xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxPeriod + pxEndPoint->xDHCPData.xDHCPTxTime + 100 ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); vARPSendGratuitous_Expect(); vDHCPProcessEndPoint( pdFALSE, pdFALSE, pxEndPoint ); TEST_ASSERT_EQUAL( eGetLinkLayerAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eGetLinkLayerAddress_NoTimeout( void ) { struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; pxEndPoint->xDHCPData.xDHCPTxTime = 100; pxEndPoint->xDHCPData.xDHCPTxPeriod = 100; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eGetLinkLayerAddress; pxEndPoint->xDHCPData.eExpectedState = eGetLinkLayerAddress; xDHCPv4Socket = NULL; xARPHadIPClash = pdTRUE; /* Make it so that there is no timeout. */ xTaskGetTickCount_ExpectAndReturn( pxEndPoint->xDHCPData.xDHCPTxPeriod + pxEndPoint->xDHCPData.xDHCPTxTime ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); TEST_ASSERT_EQUAL( eGetLinkLayerAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_EndPointDown( void ) { NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; struct xSOCKET xTestSocket; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE ); /* Expect the DHCP timer to be reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, pdMS_TO_TICKS( 5000U ) ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* Still in this phase. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_eLeasedAddress_NetworkUp_SokcetCreated_RNGPass_GNBfail( void ) { struct xSOCKET xTestSocket; BaseType_t xTimeValue = 300; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Socket is already created. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdTRUE ); xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Return the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning NULL will mean the prvSendDHCPDiscover fail. */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); /* Expect the timer to be set. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpINITIAL_TIMER_PERIOD ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* Need to send DHCP request. */ TEST_ASSERT_EQUAL( eSendDHCPRequest, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); TEST_ASSERT_EQUAL( dhcpINITIAL_DHCP_TX_PERIOD, pxEndPoint->xDHCPData.xDHCPTxPeriod ); } void test_vDHCPProcess_eLeasedAddress_NetworkUp_SokcetCreated_RNGFail( void ) { struct xSOCKET xTestSocket; BaseType_t xTimeValue = 300; NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Socket is already created. */ xDHCPv4Socket = &xTestSocket; xDHCPSocketUserCount = 1; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdTRUE ); /* Make RNG fail. */ xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdFALSE ); xTaskGetTickCount_ExpectAndReturn( xTimeValue ); /* Return the hostname. */ pcApplicationHostnameHook_ExpectAndReturn( pcHostName ); /* Returning a proper network buffer. */ pxGetNetworkBufferWithDescriptor_Stub( GetNetworkBuffer ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); /* Make the call to FreeRTOS_send succeed. */ FreeRTOS_sendto_ExpectAnyArgsAndReturn( 1 ); /* Expect the timer to be set. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpINITIAL_TIMER_PERIOD ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* Sent DHCP request - waiting ACK. */ TEST_ASSERT_EQUAL( eWaitingAcknowledge, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( xTimeValue, pxEndPoint->xDHCPData.xDHCPTxTime ); TEST_ASSERT_EQUAL( dhcpINITIAL_DHCP_TX_PERIOD, pxEndPoint->xDHCPData.xDHCPTxPeriod ); } void test_vDHCPProcess_eLeasedAddress_NetworkUp_SocketNotCreated_RNGPass_GNBfail( void ) { struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Socket not created. */ xDHCPv4Socket = NULL; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress; FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdTRUE ); /* Return invalid socket. */ FreeRTOS_socket_ExpectAnyArgsAndReturn( FREERTOS_INVALID_SOCKET ); xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); vDHCPProcess( pdFALSE, pxEndPoint ); /* Still here. */ TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); TEST_ASSERT_EQUAL( NULL, xDHCPv4Socket ); } void test_vDHCPProcess_eNotUsingLeasedAddress( void ) { NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Put the required state. */ pxEndPoint->xDHCPData.eDHCPState = eNotUsingLeasedAddress; pxEndPoint->xDHCPData.eExpectedState = eNotUsingLeasedAddress; /* Expect the timer to be disabled. */ vIPSetDHCP_RATimerEnableState_Expect( &xEndPoint, pdFALSE ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* Continue not using DHCP. */ TEST_ASSERT_EQUAL( eNotUsingLeasedAddress, pxEndPoint->xDHCPData.eDHCPState ); } void test_vDHCPProcess_IncorrectState( void ) { struct xNetworkEndPoint xEndPoint = { 0 }, * pxEndPoint = &xEndPoint; /* Put a non-existent state. */ pxEndPoint->xDHCPData.eDHCPState = ( eNotUsingLeasedAddress << 1 ); pxEndPoint->xDHCPData.eExpectedState = ( eNotUsingLeasedAddress << 1 ); vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxEndPoint ); /* Continue not using DHCP. */ TEST_ASSERT_EQUAL( ( eNotUsingLeasedAddress << 1 ), pxEndPoint->xDHCPData.eDHCPState ); } /* * @brief Check static function , in case of malformed packet , where length byte is zero. */ void test_xProcessCheckOption_LengthByteZero( void ) { BaseType_t xResult; ProcessSet_t xSet; uint8_t ucUDPPayload[ 1 ]; memset( &( ucUDPPayload ), 0, sizeof( ucUDPPayload ) ); memset( &( xSet ), 0, sizeof( xSet ) ); xSet.ulProcessed = 0U; xSet.ucOptionCode = dhcpIPv4_MESSAGE_TYPE_OPTION_CODE; xSet.pucByte = ucUDPPayload; xSet.uxIndex = 0; xSet.uxPayloadDataLength = 2; xResult = xProcessCheckOption( &xSet ); TEST_ASSERT_EQUAL( -1, xResult ); }