#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;
}
/*-----------------------------------------------------------*/
