diff --git a/source/FreeRTOS_ND.c b/source/FreeRTOS_ND.c index 43c68cd6a..439c5038a 100644 --- a/source/FreeRTOS_ND.c +++ b/source/FreeRTOS_ND.c @@ -573,6 +573,7 @@ IPv6_Address_t xTargetIPAddress; MACAddress_t xMultiCastMacAddress; NetworkBufferDescriptor_t * pxDescriptor = pxNetworkBuffer; + NetworkBufferDescriptor_t * pxNewDescriptor = NULL; if( ( pxEndPoint != NULL ) && ( pxEndPoint->bits.bIPv6 != pdFALSE_UNSIGNED ) ) { @@ -580,7 +581,9 @@ if( pxDescriptor->xDataLength < uxNeededSize ) { - pxDescriptor = pxDuplicateNetworkBufferWithDescriptor( pxDescriptor, uxNeededSize ); + pxNewDescriptor = pxDuplicateNetworkBufferWithDescriptor( pxDescriptor, uxNeededSize ); + vReleaseNetworkBufferAndDescriptor( pxDescriptor ); + pxDescriptor = pxNewDescriptor; } if( pxDescriptor != NULL ) diff --git a/source/FreeRTOS_RA.c b/source/FreeRTOS_RA.c index c98094752..e36d8aea0 100644 --- a/source/FreeRTOS_RA.c +++ b/source/FreeRTOS_RA.c @@ -138,6 +138,7 @@ NetworkBufferDescriptor_t * pxDescriptor = pxNetworkBuffer; IPv6_Address_t xSourceAddress; BaseType_t xHasLocal; + NetworkBufferDescriptor_t * pxNewDescriptor = NULL; configASSERT( pxEndPoint != NULL ); configASSERT( pxEndPoint->bits.bIPv6 != pdFALSE_UNSIGNED ); @@ -156,7 +157,9 @@ if( pxDescriptor->xDataLength < uxNeededSize ) { - pxDescriptor = pxDuplicateNetworkBufferWithDescriptor( pxDescriptor, uxNeededSize ); + pxNewDescriptor = pxDuplicateNetworkBufferWithDescriptor( pxDescriptor, uxNeededSize ); + vReleaseNetworkBufferAndDescriptor( pxDescriptor ); + pxDescriptor = pxNewDescriptor; } if( pxDescriptor != NULL ) diff --git a/source/FreeRTOS_Routing.c b/source/FreeRTOS_Routing.c index d0dfbbb3d..65304fc49 100644 --- a/source/FreeRTOS_Routing.c +++ b/source/FreeRTOS_Routing.c @@ -594,8 +594,8 @@ struct xIPv6_Couple /* This was only for debugging. */ if( pxEndPoint == NULL ) { - FreeRTOS_printf( ( "FreeRTOS_FindEndPointOnNetMask[%d]: No match for %xip\n", - ( unsigned ) ulWhere, ( unsigned ) FreeRTOS_ntohl( ulIPAddress ) ) ); + FreeRTOS_debug_printf( ( "FreeRTOS_FindEndPointOnNetMask[%d]: No match for %xip\n", + ( unsigned ) ulWhere, ( unsigned ) FreeRTOS_ntohl( ulIPAddress ) ) ); } return pxEndPoint; @@ -766,9 +766,9 @@ struct xIPv6_Couple if( xGatewayTarget == pdTRUE ) { - FreeRTOS_printf( ( " GW address %pip to %pip\n", - pxIPAddressFrom->xIP_IPv6.ucBytes, - pxIPAddressTo->xIP_IPv6.ucBytes ) ); + FreeRTOS_debug_printf( ( " GW address %pip to %pip\n", + pxIPAddressFrom->xIP_IPv6.ucBytes, + pxIPAddressTo->xIP_IPv6.ucBytes ) ); } xTargetGlobal = ( xIPv6_GetIPType( &( pxIPAddressTo->xIP_IPv6 ) ) == eIPv6_Global ) ? pdTRUE : pdFALSE; @@ -872,13 +872,13 @@ struct xIPv6_Couple pcBufferFrom, sizeof( pcBufferFrom ) ); - FreeRTOS_printf( ( "EasyFit[%x]: %d %d %d ( %s ->%s ) BAD\n", - usFrameType, - ( unsigned ) xCount[ 0 ], - ( unsigned ) xCount[ 1 ], - ( unsigned ) xCount[ 2 ], - ( xRetNtopFrom == NULL ) ? "INVALID" : pcBufferFrom, - ( xRetNtopTo == NULL ) ? "INVALID" : pcBufferTo ) ); + FreeRTOS_debug_printf( ( "EasyFit[%x]: %d %d %d ( %s ->%s ) BAD\n", + usFrameType, + ( unsigned ) xCount[ 0 ], + ( unsigned ) xCount[ 1 ], + ( unsigned ) xCount[ 2 ], + ( xRetNtopFrom == NULL ) ? "INVALID" : pcBufferFrom, + ( xRetNtopTo == NULL ) ? "INVALID" : pcBufferTo ) ); } #endif /* ( ipconfigHAS_PRINTF != 0 ) */ @@ -984,7 +984,7 @@ struct xIPv6_Couple /* do nothing, coverity happy */ } - FreeRTOS_printf( ( "pxEasyFit: ARP %xip -> %xip\n", ( unsigned ) FreeRTOS_ntohl( xIPAddressFrom.ulIP_IPv4 ), ( unsigned ) FreeRTOS_ntohl( xIPAddressTo.ulIP_IPv4 ) ) ); + FreeRTOS_debug_printf( ( "pxEasyFit: ARP %xip -> %xip\n", ( unsigned ) FreeRTOS_ntohl( xIPAddressFrom.ulIP_IPv4 ), ( unsigned ) FreeRTOS_ntohl( xIPAddressTo.ulIP_IPv4 ) ) ); } xDoProcessPacket = pdTRUE; #endif /* ( ipconfigUSE_IPv4 != 0 ) */ diff --git a/source/portable/NetworkInterface/STM32Fxx/NetworkInterface.c b/source/portable/NetworkInterface/STM32Fxx/NetworkInterface.c index 0b20602ec..1ca0f186e 100644 --- a/source/portable/NetworkInterface/STM32Fxx/NetworkInterface.c +++ b/source/portable/NetworkInterface/STM32Fxx/NetworkInterface.c @@ -994,7 +994,7 @@ static BaseType_t xMayAcceptPacket( uint8_t * pucEthernetBuffer ) #endif ( *ipLOCAL_IP_ADDRESS_POINTER != 0 ) ) { - FreeRTOS_printf( ( "Drop IP %lxip\n", FreeRTOS_ntohl( ulDestinationIPAddress ) ) ); + FreeRTOS_debug_printf( ( "Drop IP %lxip\n", FreeRTOS_ntohl( ulDestinationIPAddress ) ) ); return pdFALSE; } @@ -1503,9 +1503,9 @@ static void prvEMACHandlerTask( void * pvParameters ) #if ( ipconfigSUPPORT_NETWORK_DOWN_EVENT != 0 ) { - if( xGetPhyLinkStatus() == pdFALSE ) + if( xGetPhyLinkStatus( pxMyInterface ) == pdFALSE ) { - FreeRTOS_NetworkDown(); + FreeRTOS_NetworkDown( pxMyInterface ); } } #endif /* ( ipconfigSUPPORT_NETWORK_DOWN_EVENT != 0 ) */ diff --git a/source/portable/NetworkInterface/libslirp/MBuffNetifBackendLibslirp.c b/source/portable/NetworkInterface/libslirp/MBuffNetifBackendLibslirp.c index e2af82077..17ef28f8c 100644 --- a/source/portable/NetworkInterface/libslirp/MBuffNetifBackendLibslirp.c +++ b/source/portable/NetworkInterface/libslirp/MBuffNetifBackendLibslirp.c @@ -250,6 +250,12 @@ void vMBuffNetifBackendInit( MessageBufferHandle_t * pxSendMsgBuffer, else { pvContextBuffer = pvPortMalloc( sizeof( SlirpBackendContext_t ) ); + + if( pvContextBuffer == NULL ) + { + FreeRTOS_printf( ( "Failed to allocate memory for pvContextBuffer" ) ); + configASSERT( 0 ); + } } if( pvContextBuffer != NULL ) @@ -472,6 +478,12 @@ static void vEnsurePollfdSize( SlirpBackendContext_t * pxCtx, if( pxCtx->pxPollFdArray == NULL ) { pxCtx->pxPollFdArray = ( struct pollfd * ) malloc( xNewSize * sizeof( struct pollfd ) ); + + if( pxCtx->pxPollFdArray == NULL ) + { + FreeRTOS_printf( ( "Failed to allocate memory for pxCtx->pxPollFdArray" ) ); + configASSERT( 0 ); + } } else { @@ -518,6 +530,10 @@ static inline int lSlirpEventsToNativePollEvents( int lSlirpPollFlags ) lPosixPollFlags |= POLLHUP; } + #if defined( _WIN32 ) + lPosixPollFlags &= ~( POLLPRI | POLLERR | POLLHUP ); + #endif + return lPosixPollFlags; } diff --git a/source/portable/NetworkInterface/libslirp/MBuffNetworkInterface.c b/source/portable/NetworkInterface/libslirp/MBuffNetworkInterface.c index 201092ff7..fcc8210d9 100644 --- a/source/portable/NetworkInterface/libslirp/MBuffNetworkInterface.c +++ b/source/portable/NetworkInterface/libslirp/MBuffNetworkInterface.c @@ -77,76 +77,92 @@ extern void vMBuffNetifBackendDeInit( void * pvBackendContext ); static void vNetifReceiveTask( void * pvParameters ); -MBuffNetDriverContext_t xDriverCtx = { 0 }; - /** * @brief Initialize the MessageBuffer backed network interface. * * @return BaseType_t pdTRUE on success */ -BaseType_t xNetworkInterfaceInitialise( void ) +BaseType_t xNetworkInterfaceInitialise( NetworkInterface_t * pxNetif ) { BaseType_t xResult = pdTRUE; - if( xDriverCtx.xInterfaceState == pdFALSE ) + pxNetif->pvArgument = pvPortMalloc( sizeof( MBuffNetDriverContext_t ) ); + + if( pxNetif->pvArgument == NULL ) { - xDriverCtx.xInterfaceState = pdFALSE; + FreeRTOS_printf( ( "Failed to allocate memory for pxNetif->pvArgument" ) ); + configASSERT( 0 ); + } + + MBuffNetDriverContext_t * pxDriverCtx = ( MBuffNetDriverContext_t * ) pxNetif->pvArgument; + + if( pxDriverCtx->xInterfaceState == pdFALSE ) + { + pxDriverCtx->xInterfaceState = pdFALSE; #if defined( _WIN32 ) - xDriverCtx.pvSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL ); + pxDriverCtx->pvSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL ); #else - xDriverCtx.pvSendEvent = ( void * ) event_create(); + pxDriverCtx->pvSendEvent = ( void * ) event_create(); #endif - if( xDriverCtx.pvSendEvent == NULL ) + if( pxDriverCtx->pvSendEvent == NULL ) { xResult = pdFALSE; } else { - vMBuffNetifBackendInit( &( xDriverCtx.xSendMsgBuffer ), - &( xDriverCtx.xRecvMsgBuffer ), - xDriverCtx.pvSendEvent, - &( xDriverCtx.pvBackendContext ) ); + vMBuffNetifBackendInit( &( pxDriverCtx->xSendMsgBuffer ), + &( pxDriverCtx->xRecvMsgBuffer ), + pxDriverCtx->pvSendEvent, + &( pxDriverCtx->pvBackendContext ) ); - if( xDriverCtx.pvBackendContext == NULL ) + if( pxDriverCtx->pvBackendContext == NULL ) { xResult = pdFALSE; #if defined( _WIN32 ) - ( void ) CloseHandle( xDriverCtx.pvSendEvent ); + ( void ) CloseHandle( pxDriverCtx->pvSendEvent ); #else - ( void ) event_delete( xDriverCtx.pvSendEvent ); + ( void ) event_delete( pxDriverCtx->pvSendEvent ); #endif } } - if( xResult == pdTRUE ) + static BaseType_t xReceiveTaskCreated = pdFALSE; + + if( ( xResult == pdTRUE ) && ( xReceiveTaskCreated == pdFALSE ) ) { xResult = xTaskCreate( vNetifReceiveTask, "NetRX", - configMINIMAL_STACK_SIZE, NULL, + configMINIMAL_STACK_SIZE, + pxNetif, tskIDLE_PRIORITY, - &( xDriverCtx.xRecvTask ) ); + &( pxDriverCtx->xRecvTask ) ); + + if( xResult == pdPASS ) + { + xReceiveTaskCreated = pdTRUE; + } } /* Cleanup on failure */ if( xResult != pdTRUE ) { - if( xDriverCtx.pvSendEvent != NULL ) + if( pxDriverCtx->pvSendEvent != NULL ) { #if defined( _WIN32 ) - ( void ) CloseHandle( xDriverCtx.pvSendEvent ); + ( void ) CloseHandle( pxDriverCtx->pvSendEvent ); #else - event_delete( xDriverCtx.pvSendEvent ); + event_delete( pxDriverCtx->pvSendEvent ); #endif } - if( xDriverCtx.pvBackendContext != NULL ) + if( pxDriverCtx->pvBackendContext != NULL ) { - vMBuffNetifBackendDeInit( xDriverCtx.pvBackendContext ); + vMBuffNetifBackendDeInit( pxDriverCtx->pvBackendContext ); } } - xDriverCtx.xInterfaceState = xResult; + pxDriverCtx->xInterfaceState = xResult; } return xResult; @@ -157,15 +173,21 @@ BaseType_t xNetworkInterfaceInitialise( void ) * * @return BaseType_t pdTRUE */ -BaseType_t xNetworkInterfaceDeInitialise( void ) +BaseType_t xNetworkInterfaceDeInitialise( NetworkInterface_t * pxNetif ) { + MBuffNetDriverContext_t * pxDriverCtx = ( MBuffNetDriverContext_t * ) pxNetif->pvArgument; + #if defined( _WIN32 ) - ( void ) CloseHandle( xDriverCtx.pvSendEvent ); + ( void ) CloseHandle( pxDriverCtx->pvSendEvent ); #else - event_delete( xDriverCtx.pvSendEvent ); + event_delete( pxDriverCtx->pvSendEvent ); #endif - vTaskDelete( xDriverCtx.xRecvTask ); + vTaskDelete( pxDriverCtx->xRecvTask ); + + vMBuffNetifBackendDeInit( pxDriverCtx->pvBackendContext ); + + vPortFree( pxNetif->pvArgument ); return pdTRUE; } @@ -177,8 +199,9 @@ BaseType_t xNetworkInterfaceDeInitialise( void ) static void vNetifReceiveTask( void * pvParameters ) { NetworkBufferDescriptor_t * pxDescriptor = NULL; + NetworkInterface_t * pxNetif = ( NetworkInterface_t * ) pvParameters; - ( void ) pvParameters; + MBuffNetDriverContext_t * pxDriverCtx = ( MBuffNetDriverContext_t * ) pxNetif->pvArgument; for( ; ; ) { @@ -192,7 +215,7 @@ static void vNetifReceiveTask( void * pvParameters ) } /* Read an incoming frame */ - uxMessageLen = xMessageBufferReceive( xDriverCtx.xRecvMsgBuffer, + uxMessageLen = xMessageBufferReceive( pxDriverCtx->xRecvMsgBuffer, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, portMAX_DELAY ); @@ -213,6 +236,9 @@ static void vNetifReceiveTask( void * pvParameters ) uxMessageLen, xFrameProcess ) ); } + pxDescriptor->pxInterface = pxNetif; + pxDescriptor->pxEndPoint = FreeRTOS_MatchingEndpoint( pxNetif, pxDescriptor->pucEthernetBuffer ); + xRxEvent.eEventType = eNetworkRxEvent; xRxEvent.pvData = ( void * ) pxDescriptor; @@ -241,25 +267,30 @@ static void vNetifReceiveTask( void * pvParameters ) } /*! - * @brief API call, called from reeRTOS_IP.c to send a network packet over the + * @brief API call, called from FreeRTOS_IP.c to send a network packet over the * selected interface * @return pdTRUE if successful else pdFALSE */ -BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, +BaseType_t xNetworkInterfaceOutput( NetworkInterface_t * pxNetif, + NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend ) { BaseType_t xResult = pdFALSE; - configASSERT( pxNetworkBuffer != NULL ); - configASSERT( pxNetworkBuffer->pucEthernetBuffer != NULL ); - configASSERT( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) ); + MBuffNetDriverContext_t * pxDriverCtx = ( MBuffNetDriverContext_t * ) pxNetif->pvArgument; - if( xDriverCtx.xInterfaceState == pdTRUE ) + FreeRTOS_debug_printf( ( "xNetworkInterfaceOutput: %p:%p\n", pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer ) ); + + if( pxDriverCtx->xInterfaceState == pdTRUE ) { - if( xMessageBufferSpacesAvailable( xDriverCtx.xSendMsgBuffer ) > pxNetworkBuffer->xDataLength + 4U ) + configASSERT( pxNetworkBuffer != NULL ); + configASSERT( pxNetworkBuffer->pucEthernetBuffer != NULL ); + configASSERT( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) ); + + if( xMessageBufferSpacesAvailable( pxDriverCtx->xSendMsgBuffer ) > pxNetworkBuffer->xDataLength + 4U ) { size_t uxBytesSent; - uxBytesSent = xMessageBufferSend( xDriverCtx.xSendMsgBuffer, + uxBytesSent = xMessageBufferSend( pxDriverCtx->xSendMsgBuffer, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, 0U ); @@ -283,9 +314,9 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkB if( xResult == pdTRUE ) { #if defined( _WIN32 ) - SetEvent( xDriverCtx.pvSendEvent ); + SetEvent( pxDriverCtx->pvSendEvent ); #else - event_signal( xDriverCtx.pvSendEvent ); + event_signal( pxDriverCtx->pvSendEvent ); #endif } } @@ -335,3 +366,38 @@ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkB } } } + +BaseType_t xGetPhyLinkStatus( NetworkInterface_t * pxNetif ) +{ + BaseType_t xResult = pdFALSE; + + MBuffNetDriverContext_t * pxDriverCtx = ( MBuffNetDriverContext_t * ) pxNetif->pvArgument; + + if( pxDriverCtx->xInterfaceState == pdTRUE ) + { + xResult = pdTRUE; + } + + return xResult; +} + +NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) +{ + configASSERT( pxInterface != NULL ); + static char pcName[ 17 ]; + + snprintf( pcName, sizeof( pcName ), "eth%ld", xEMACIndex ); + + memset( pxInterface, 0, sizeof( NetworkInterface_t ) ); + + pxInterface->pcName = pcName; /* Just for logging, debugging. */ + pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ + pxInterface->pfInitialise = xNetworkInterfaceInitialise; + pxInterface->pfOutput = xNetworkInterfaceOutput; + pxInterface->pfGetPhyLinkStatus = xGetPhyLinkStatus; + + FreeRTOS_AddNetworkInterface( pxInterface ); + + return pxInterface; +} diff --git a/test/unit-test/FreeRTOS_ND/FreeRTOS_ND_utest.c b/test/unit-test/FreeRTOS_ND/FreeRTOS_ND_utest.c index f0d0ddf93..d15d77445 100644 --- a/test/unit-test/FreeRTOS_ND/FreeRTOS_ND_utest.c +++ b/test/unit-test/FreeRTOS_ND/FreeRTOS_ND_utest.c @@ -722,6 +722,8 @@ void test_vNDAgeCache_NSIncorrectDataLen( void ) pxDuplicateNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); + vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer ); + vNDAgeCache(); TEST_ASSERT_EQUAL( xNDCache[ xUseEntry ].ucAge, xAgeDefault - 1 ); diff --git a/test/unit-test/FreeRTOS_RA/FreeRTOS_RA_utest.c b/test/unit-test/FreeRTOS_RA/FreeRTOS_RA_utest.c index d50af6b65..0d77637d7 100644 --- a/test/unit-test/FreeRTOS_RA/FreeRTOS_RA_utest.c +++ b/test/unit-test/FreeRTOS_RA/FreeRTOS_RA_utest.c @@ -149,6 +149,8 @@ void test_vNDSendRouterSolicitation_xHasLocal0( void ) pxDuplicateNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); + vReleaseNetworkBufferAndDescriptor_Expect( pxNetworkBuffer ); + vNDSendRouterSolicitation( pxNetworkBuffer, &xIPAddress ); } @@ -188,6 +190,8 @@ void test_vNDSendRouterSolicitation_xHasLocal1( void ) pxDuplicateNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); + vReleaseNetworkBufferAndDescriptor_Expect( pxNetworkBuffer ); + vNDSendRouterSolicitation( pxNetworkBuffer, &xIPAddress ); } @@ -223,6 +227,8 @@ void test_vNDSendRouterSolicitation_NullDesc( void ) pxDuplicateNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL ); + vReleaseNetworkBufferAndDescriptor_Expect( pxNetworkBuffer ); + vNDSendRouterSolicitation( pxNetworkBuffer, &xIPAddress ); } @@ -1017,6 +1023,8 @@ void test_vRAProcess_eRAStateApply2( void ) /*usGenerateProtocolChecksum_ExpectAnyArgsAndReturn( ipCORRECT_CRC ); */ /*vReturnEthernetFrame_ExpectAnyArgs(); */ + vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer ); + vDHCP_RATimerReload_ExpectAnyArgs(); /* pdFALSE for vRAProcessInit */