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