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