1
0
mirror of https://github.com/FreeRTOS/FreeRTOS-Plus-TCP synced 2025-10-22 16:37:41 +08:00
Files
FreeRTOS-Plus-TCP/source/portable/NetworkInterface/WinPCap/FaultInjection.c
Aniruddha Kanhere a4124602cc Merge changes to main.
This commit brings in the refactoring and restructuring changes
from IntegrationTesting1 branch to the main branch.
It also includes additional unit tests for 100% coverage.
The rationale behind not creating a PR is that the conflicts were too
huge to be resolved correctly. Thus, a force push to the main branch is
being done.
2022-05-26 12:42:45 -07:00

189 lines
5.6 KiB
C

#define xBUFFER_CACHE_SIZE 10
#define xMAX_FAULT_INJECTION_RATE 15
#define xMIN_FAULT_INJECTION_RATE 3
#define xNUM_FAULT_TYPES 1
static NetworkBufferDescriptor_t * xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
#define xFAULT_LOG_SIZE 2048
uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
uint32_t ulFaultLogIndex = 0;
static BaseType_t prvCachePacket( NetworkBufferDescriptor_t * pxNetworkBufferIn )
{
BaseType_t x, xReturn = pdFALSE;
for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
{
if( xNetworkBufferCache[ x ] == NULL )
{
xNetworkBufferCache[ x ] = pxNetworkBufferIn;
xReturn = pdTRUE;
break;
}
}
return xReturn;
}
/*-----------------------------------------------------------*/
static NetworkBufferDescriptor_t * prvGetCachedPacket( void )
{
BaseType_t x;
NetworkBufferDescriptor_t * pxReturn = NULL;
for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
{
if( xNetworkBufferCache[ x ] != NULL )
{
pxReturn = xNetworkBufferCache[ x ];
xNetworkBufferCache[ x ] = NULL;
break;
}
}
return pxReturn;
}
/*-----------------------------------------------------------*/
static NetworkBufferDescriptor_t * prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket,
const uint8_t * pucPacketData )
{
NetworkBufferDescriptor_t * pxReturn;
/* Obtain a new descriptor. */
pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
if( pxReturn != NULL )
{
/* Copy in the packet data. */
pxReturn->xDataLength = pxOriginalPacket->xDataLength;
memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
}
return pxReturn;
}
/*-----------------------------------------------------------*/
static NetworkBufferDescriptor_t * prvRxFaultInjection( NetworkBufferDescriptor_t * pxNetworkBufferIn,
const uint8_t * pucPacketData )
{
static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
NetworkBufferDescriptor_t * pxReturn = pxNetworkBufferIn;
IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
uint32_t ulFault;
return pxNetworkBufferIn;
ulCallCount++;
if( ulCallCount > ulNextFaultCallCount )
{
xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
{
ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
}
ulCallCount = 0;
xApplicationGetRandomNumber( &( ulFault ) );
ulFault = ulFault % xNUM_FAULT_TYPES;
if( ulFaultLogIndex < xFAULT_LOG_SIZE )
{
ulInjectedFault[ ulFaultLogIndex ] = ulFault;
ulFaultLogIndex++;
}
switch( ulFault )
{
case 0:
/* Just drop the packet. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
pxReturn = NULL;
break;
case 1:
/* Store the packet in the cache for later. */
if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
{
/* The packet may get sent later, it is not being sent
* now. */
pxReturn = NULL;
}
break;
case 2:
/* Send a cached packet. */
pxReturn = prvGetCachedPacket();
if( pxReturn != NULL )
{
/* A cached packet was obtained so drop the original
* packet. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
}
else
{
/* Could not obtain a packet from the cache so just return
* the packet that was passed in. */
pxReturn = pxNetworkBufferIn;
}
break;
case 4:
/* Send a duplicate of the packet right away. */
pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
/* Send the original packet to the stack. */
xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
{
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
}
break;
case 5:
/* Send both a cached packet and the current packet. */
xRxEvent.pvData = ( void * ) prvGetCachedPacket();
if( xRxEvent.pvData != NULL )
{
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
{
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
}
}
break;
case 6:
case 7:
case 8:
/* Store the packet in the cache for later. */
if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
{
/* The packet may get sent later, it is not being sent
* now. */
pxReturn = NULL;
}
break;
}
}
return pxReturn;
}
/*-----------------------------------------------------------*/