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, ¤t_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, ¤t_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