]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c
8e64a40cc4e36aac7b85c4cc2fbf49797eaa96da
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / WinPCap / FaultInjection.c
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
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
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
49 static NetworkBufferDescriptor_t *prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket, const uint8_t *pucPacketData )
50 {
51 NetworkBufferDescriptor_t *pxReturn;
52
53         /* Obtain a new descriptor. */
54         pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
55
56         if( pxReturn != NULL )
57         {
58                 /* Copy in the packet data. */
59                 pxReturn->xDataLength = pxOriginalPacket->xDataLength;
60                 memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
61         }
62
63         return pxReturn;
64 }
65 /*-----------------------------------------------------------*/
66
67 static NetworkBufferDescriptor_t *prvRxFaultInjection( NetworkBufferDescriptor_t *pxNetworkBufferIn, const uint8_t *pucPacketData )
68 {
69 static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
70 NetworkBufferDescriptor_t *pxReturn = pxNetworkBufferIn;
71 IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
72 uint32_t ulFault;
73
74 return pxNetworkBufferIn;
75
76         ulCallCount++;
77
78         if( ulCallCount > ulNextFaultCallCount )
79         {
80                 xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
81                 ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
82                 if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
83                 {
84                         ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
85                 }
86
87                 ulCallCount = 0;
88
89                 xApplicationGetRandomNumber( &( ulFault ) );
90                 ulFault = ulFault % xNUM_FAULT_TYPES;
91
92                 if( ulFaultLogIndex < xFAULT_LOG_SIZE )
93                 {
94                         ulInjectedFault[ ulFaultLogIndex ] = ulFault;
95                         ulFaultLogIndex++;
96                 }
97
98                 switch( ulFault )
99                 {
100                         case 0:
101                                 /* Just drop the packet. */
102                                 vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
103                                 pxReturn = NULL;
104                                 break;
105
106                         case 1:
107                                 /* Store the packet in the cache for later. */
108                                 if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
109                                 {
110                                         /* The packet may get sent later, it is not being sent
111                                         now. */
112                                         pxReturn = NULL;
113                                 }
114                                 break;
115
116                         case 2:
117                                 /* Send a cached packet. */
118                                 pxReturn = prvGetCachedPacket();
119                                 if( pxReturn != NULL )
120                                 {
121                                         /* A cached packet was obtained so drop the original
122                                         packet. */
123                                         vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
124                                 }
125                                 else
126                                 {
127                                         /* Could not obtain a packet from the cache so just return
128                                         the packet that was passed in. */
129                                         pxReturn = pxNetworkBufferIn;
130                                 }
131                                 break;
132
133                         case 4:
134
135                                 /* Send a duplicate of the packet right away. */
136                                 pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
137
138                                 /* Send the original packet to the stack. */
139                                 xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
140                                 if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
141                                 {
142                                         vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
143                                 }
144                                 break;
145
146                         case 5:
147
148                                 /* Send both a cached packet and the current packet. */
149                                 xRxEvent.pvData = ( void * ) prvGetCachedPacket();
150                                 if( xRxEvent.pvData != NULL )
151                                 {
152                                         if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
153                                         {
154                                                 vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
155                                         }
156                                 }
157                                 break;
158
159                         case 6:
160                         case 7:
161                         case 8:
162                                 /* Store the packet in the cache for later. */
163                                 if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
164                                 {
165                                         /* The packet may get sent later, it is not being sent
166                                         now. */
167                                         pxReturn = NULL;
168                                 }
169                                 break;
170                 }
171         }
172
173         return pxReturn;
174 }
175 /*-----------------------------------------------------------*/