1 #define xBUFFER_CACHE_SIZE 10
2 #define xMAX_FAULT_INJECTION_RATE 15
3 #define xMIN_FAULT_INJECTION_RATE 3
4 #define xNUM_FAULT_TYPES 1
5
6 static NetworkBufferDescriptor_t * xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
7
8 #define xFAULT_LOG_SIZE 2048
9 uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
10 uint32_t ulFaultLogIndex = 0;
11
prvCachePacket(NetworkBufferDescriptor_t * pxNetworkBufferIn)12 static BaseType_t prvCachePacket( NetworkBufferDescriptor_t * pxNetworkBufferIn )
13 {
14 BaseType_t x, xReturn = pdFALSE;
15
16 for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
17 {
18 if( xNetworkBufferCache[ x ] == NULL )
19 {
20 xNetworkBufferCache[ x ] = pxNetworkBufferIn;
21 xReturn = pdTRUE;
22 break;
23 }
24 }
25
26 return xReturn;
27 }
28 /*-----------------------------------------------------------*/
29
prvGetCachedPacket(void)30 static NetworkBufferDescriptor_t * prvGetCachedPacket( void )
31 {
32 BaseType_t x;
33 NetworkBufferDescriptor_t * pxReturn = NULL;
34
35 for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
36 {
37 if( xNetworkBufferCache[ x ] != NULL )
38 {
39 pxReturn = xNetworkBufferCache[ x ];
40 xNetworkBufferCache[ x ] = NULL;
41 break;
42 }
43 }
44
45 return pxReturn;
46 }
47 /*-----------------------------------------------------------*/
48
prvDuplicatePacket(NetworkBufferDescriptor_t * pxOriginalPacket,const uint8_t * pucPacketData)49 static NetworkBufferDescriptor_t * prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket,
50 const uint8_t * pucPacketData )
51 {
52 NetworkBufferDescriptor_t * pxReturn;
53
54 /* Obtain a new descriptor. */
55 pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
56
57 if( pxReturn != NULL )
58 {
59 /* Copy in the packet data. */
60 pxReturn->xDataLength = pxOriginalPacket->xDataLength;
61 memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
62 }
63
64 return pxReturn;
65 }
66 /*-----------------------------------------------------------*/
67
prvRxFaultInjection(NetworkBufferDescriptor_t * pxNetworkBufferIn,const uint8_t * pucPacketData)68 static NetworkBufferDescriptor_t * prvRxFaultInjection( NetworkBufferDescriptor_t * pxNetworkBufferIn,
69 const uint8_t * pucPacketData )
70 {
71 static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
72 NetworkBufferDescriptor_t * pxReturn = pxNetworkBufferIn;
73 IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
74 uint32_t ulFault;
75
76 return pxNetworkBufferIn;
77
78 ulCallCount++;
79
80 if( ulCallCount > ulNextFaultCallCount )
81 {
82 xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
83 ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
84
85 if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
86 {
87 ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
88 }
89
90 ulCallCount = 0;
91
92 xApplicationGetRandomNumber( &( ulFault ) );
93 ulFault = ulFault % xNUM_FAULT_TYPES;
94
95 if( ulFaultLogIndex < xFAULT_LOG_SIZE )
96 {
97 ulInjectedFault[ ulFaultLogIndex ] = ulFault;
98 ulFaultLogIndex++;
99 }
100
101 switch( ulFault )
102 {
103 case 0:
104 /* Just drop the packet. */
105 vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
106 pxReturn = NULL;
107 break;
108
109 case 1:
110
111 /* Store the packet in the cache for later. */
112 if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
113 {
114 /* The packet may get sent later, it is not being sent
115 * now. */
116 pxReturn = NULL;
117 }
118
119 break;
120
121 case 2:
122 /* Send a cached packet. */
123 pxReturn = prvGetCachedPacket();
124
125 if( pxReturn != NULL )
126 {
127 /* A cached packet was obtained so drop the original
128 * packet. */
129 vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
130 }
131 else
132 {
133 /* Could not obtain a packet from the cache so just return
134 * the packet that was passed in. */
135 pxReturn = pxNetworkBufferIn;
136 }
137
138 break;
139
140 case 4:
141
142 /* Send a duplicate of the packet right away. */
143 pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
144
145 /* Send the original packet to the stack. */
146 xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
147
148 if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
149 {
150 vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
151 }
152
153 break;
154
155 case 5:
156
157 /* Send both a cached packet and the current packet. */
158 xRxEvent.pvData = ( void * ) prvGetCachedPacket();
159
160 if( xRxEvent.pvData != NULL )
161 {
162 if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
163 {
164 vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
165 }
166 }
167
168 break;
169
170 case 6:
171 case 7:
172 case 8:
173
174 /* Store the packet in the cache for later. */
175 if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
176 {
177 /* The packet may get sent later, it is not being sent
178 * now. */
179 pxReturn = NULL;
180 }
181
182 break;
183 }
184 }
185
186 return pxReturn;
187 }
188 /*-----------------------------------------------------------*/
189