1 /* This NetX test concentrates on the IGMP loopback operation.  */
2 
3 #include   "tx_api.h"
4 #include   "nx_api.h"
5 
6 extern void    test_control_return(UINT status);
7 
8 #if !defined(NX_DISABLE_IGMP_INFO) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4)
9 
10 #define     DEMO_STACK_SIZE         2048
11 
12 #define     TEST_INTERFACE          1
13 
14 
15 /* Define the ThreadX and NetX object control blocks...  */
16 
17 static TX_THREAD               ntest_0;
18 
19 static NX_PACKET_POOL          pool_0;
20 static NX_IP                   ip_0;
21 static NX_UDP_SOCKET           socket_0;
22 static NX_UDP_SOCKET           socket_1;
23 
24 
25 /* Define the counters used in the test application...  */
26 
27 static ULONG                   error_counter;
28 
29 /* Define thread prototypes.  */
30 
31 static void    ntest_0_entry(ULONG thread_input);
32 
33 extern void    _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
34 
35 /* Define what the initial system looks like.  */
36 
37 #ifdef CTEST
test_application_define(void * first_unused_memory)38 VOID test_application_define(void *first_unused_memory)
39 #else
40 void    netx_igmp_loopback_test_application_define(void *first_unused_memory)
41 #endif
42 {
43 
44 CHAR    *pointer;
45 UINT    status;
46 
47 
48     /* Setup the working pointer.  */
49     pointer =  (CHAR *) first_unused_memory;
50 
51     error_counter =  0;
52 
53     /* Create the main thread.  */
54     tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
55             pointer, DEMO_STACK_SIZE,
56             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
57     pointer =  pointer + DEMO_STACK_SIZE;
58 
59     /* Initialize the NetX system.  */
60     nx_system_initialize();
61 
62     /* Create a packet pool.  */
63     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192);
64     pointer = pointer + 8192;
65 
66     if (status)
67         error_counter++;
68 
69     /* Create an IP instance.  */
70     status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
71                     pointer, 2048, 1);
72     pointer =  pointer + 2048;
73 
74     status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL,  _nx_ram_network_driver_256);
75 
76     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
77     status =  nx_arp_enable(&ip_0, (void *) pointer, 1024);
78     pointer = pointer + 1024;
79     if (status)
80         error_counter++;
81 
82     /* Enable IGMP processing for both this IP instance.  */
83     status =  nx_igmp_enable(&ip_0);
84 
85     /* Check enable status.  */
86     if (status)
87         error_counter++;
88 
89     /* Enable UDP processing for this IP instance.  */
90     status =  nx_udp_enable(&ip_0);
91 
92     /* Check enable status.  */
93     if (status)
94         error_counter++;
95 }
96 
97 
98 
99 /* Define the test threads.  */
100 
ntest_0_entry(ULONG thread_input)101 static void    ntest_0_entry(ULONG thread_input)
102 {
103 
104 UINT        status;
105 NX_PACKET   *my_packet;
106 ULONG       igmp_reports_sent;
107 ULONG       igmp_queries_received;
108 ULONG       igmp_checksum_errors;
109 ULONG       current_groups_joined;
110 #ifdef __PRODUCT_NETXDUO__
111 NXD_ADDRESS dest_address;
112 #endif
113 
114 
115     /* Print out test information banner.  */
116     printf("NetX Test:   IGMP Loopback Operation Test..............................");
117 
118     /* Check for earlier error.  */
119     if (error_counter)
120     {
121 
122         printf("ERROR!\n");
123         test_control_return(1);
124     }
125 
126 #ifdef NX_ENABLE_INTERFACE_CAPABILITY
127     /* Enable all TX checksum capability. */
128     nx_ip_interface_capability_set(&ip_0, TEST_INTERFACE, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM |
129             NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM |
130             NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM |
131             NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM |
132             NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM |
133             NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM);
134 
135 #endif /* NX_ENABLE_INTERFACE_CAPABILITY */
136 
137     /* Enable IGMP loopback.  */
138     status =  nx_igmp_loopback_enable(&ip_0);
139 
140     /* Perform 7 IGMP join operations.  */
141     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,1),TEST_INTERFACE);
142     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,2),TEST_INTERFACE);
143     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,3),TEST_INTERFACE);
144     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE);
145     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,5),TEST_INTERFACE);
146     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,6),TEST_INTERFACE);
147     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,7),TEST_INTERFACE);
148 
149     /* Join one group another 4 times to test the counting operation.  */
150     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE);
151     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE);
152     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE);
153     status +=  nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE);
154 
155     /* Determine if there is an error.  */
156     if (status)
157     {
158 
159         printf("ERROR!\n");
160         test_control_return(1);
161     }
162 
163     /* Sleep 2 seconds to let IGMP packets be sent. */
164     tx_thread_sleep(2 * NX_IP_PERIODIC_RATE);
165 
166     /* Call the IGMP information get routine to see if all the groups are there.  */
167     status =  nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, &current_groups_joined);
168 
169     /* Check for status.  */
170     if ((status) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 7))
171     {
172 
173         printf("ERROR!\n");
174         test_control_return(1);
175     }
176 
177     /* Create and bind two UDP sockets.  */
178     status =   nx_udp_socket_create(&ip_0, &socket_0, "Sending Socket", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 5);
179     status +=  nx_udp_socket_create(&ip_0, &socket_1, "Receiving Socket", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 5);
180     status +=  nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER);
181     status +=  nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER);
182 
183     /* Determine if there is an error.  */
184     if (status)
185     {
186 
187         printf("ERROR!\n");
188         test_control_return(1);
189     }
190 
191     /* Allocate a packet.  */
192     status =  nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
193 
194     /* Determine if there is an error.  */
195     if (status)
196     {
197 
198         printf("ERROR!\n");
199         test_control_return(1);
200     }
201 
202     /* Write ABCs into the packet payload!  */
203     memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ  ", 28);
204 
205     /* Adjust the write pointer.  */
206     my_packet -> nx_packet_length =  28;
207     my_packet -> nx_packet_append_ptr =  my_packet -> nx_packet_prepend_ptr + 28;
208 
209 #ifdef __PRODUCT_NETXDUO__
210     dest_address.nxd_ip_address.v4 =IP_ADDRESS(224, 0, 0, 4);
211     dest_address.nxd_ip_version = 4;
212 
213     /* Send the UDP packet.  */
214     status =  nxd_udp_socket_interface_send(&socket_0, my_packet, &dest_address, 0x89, TEST_INTERFACE);
215 #else
216 
217     /* Send the UDP packet.  */
218     status =  nx_udp_socket_interface_send(&socket_0, my_packet, IP_ADDRESS(224, 0, 0, 4), 0x89, TEST_INTERFACE);
219 #endif
220 
221     /* Determine if there is an error.  */
222     if (status)
223     {
224 
225         printf("ERROR!\n");
226         test_control_return(1);
227     }
228 
229     /* Receive the UDP packet.  */
230     status =  nx_udp_socket_receive(&socket_1, &my_packet, NX_IP_PERIODIC_RATE);
231 
232     /* Determine if there is an error.  */
233     if (status)
234     {
235 
236         printf("ERROR!\n");
237         test_control_return(1);
238     }
239 
240     /* Disable the IGMP loopback.  */
241     status =  nx_igmp_loopback_disable(&ip_0);
242 
243 #ifdef NX_ENABLE_INTERFACE_CAPABILITY
244     /* Disable all interface capability. */
245     nx_ip_interface_capability_set(&ip_0, TEST_INTERFACE, 0);
246 #endif /* NX_ENABLE_INTERFACE_CAPABILITY */
247 
248     /* Now leave all the groups to make sure that processing works properly.  */
249 #ifdef __PRODUCT_NETXDUO__
250     status =   nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,1), TEST_INTERFACE);
251     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,2), TEST_INTERFACE);
252     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,3), TEST_INTERFACE);
253     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE);
254     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,5), TEST_INTERFACE);
255     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,6), TEST_INTERFACE);
256     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,7), TEST_INTERFACE);
257     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE);
258     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE);
259     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE);
260     status +=  nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE);
261 #else
262 
263     status =   nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1));
264     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,2));
265     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,3));
266     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4));
267     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,5));
268     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,6));
269     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,7));
270     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4));
271     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4));
272     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4));
273     status +=  nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4));
274 #endif
275     /* Determine if there is an error.  */
276     if (status)
277     {
278 
279         printf("ERROR!\n");
280         test_control_return(1);
281     }
282 
283     /* Call the IGMP information get routine to see if all the groups are there.  */
284     status =  nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, &current_groups_joined);
285 
286     /* Check for status.  */
287     if ((status) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined))
288     {
289 
290         printf("ERROR!\n");
291         test_control_return(1);
292     }
293     else
294     {
295 
296         printf("SUCCESS!\n");
297         test_control_return(0);
298     }
299 }
300 #else
301 #ifdef CTEST
test_application_define(void * first_unused_memory)302 VOID test_application_define(void *first_unused_memory)
303 #else
304 void    netx_igmp_loopback_test_application_define(void *first_unused_memory)
305 #endif
306 {
307 
308     printf("NetX Test:   IGMP Loopback Operation Test..............................N/A\n");
309     test_control_return(3);
310 
311 }
312 #endif /* NX_DISABLE_IGMP_INFO */
313