mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-22 14:31:59 -04:00
Notes: - header has version 2.2.0. - This sync did not bring in ./test directory, though we should. - New NetworkInterfaces are introduced by this merge. - Keil compiler support. - FreeRTOS_IP.h new API xApplicationGetRandomNumber(). - FreeRTOS_IP_Private.h new eIPEvent_t eNetworkTxEvent. - FreeRTOS_Stream_Buffer.h removing static xStreamBufferIsEmpty() and xStreamBufferIsFull(). - FreeRTOSConfigDefaults.h provides default ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS. - other type changes.
176 lines
4.6 KiB
C
176 lines
4.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;
|
|
}
|
|
/*-----------------------------------------------------------*/
|