1
2 #include "tx_api.h"
3 #include "nx_api.h"
4 #include "nxd_dhcp_client.h"
5 #include "nxd_dhcp_server.h"
6
7 extern void test_control_return(UINT status);
8
9 #if !defined(NX_DISABLE_IPV4)
10
11 #define DEMO_STACK_SIZE 4096
12 #define NX_PACKET_SIZE 1536
13 #define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8
14
15 #define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1)
16 #define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10)
17 #define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19)
18
19 #define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0)
20 #define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1)
21 #define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1)
22
23 /* If defined, the host requests a (previous) client IP address. */
24 /*
25 #define REQUEST_CLIENT_IP
26 */
27
28 /* If defined the client requests to jump to the boot state and skip the DISCOVER message.
29 If REQUEST_CLIENT_IP is not defined, this has no effect. */
30 /*
31 #define SKIP_DISCOVER_MESSAGE
32 */
33
34 /* Define the ThreadX and NetX object control blocks... */
35 static TX_THREAD client_thread;
36 static NX_PACKET_POOL client_pool;
37 static NX_IP client_ip;
38 static NX_DHCP dhcp_client;
39
40 static TX_THREAD server_thread;
41 static NX_PACKET_POOL server_pool;
42 static NX_IP server_ip;
43 static NX_DHCP_SERVER dhcp_server;
44
45 /* Define the counters used in the demo application... */
46
47 static ULONG state_changes;
48 static ULONG error_counter;
49 static CHAR *pointer;
50
51 static UCHAR message[50] = "My Ping Request!" ;
52
53
54 /* Define thread prototypes. */
55
56 static void server_thread_entry(ULONG thread_input);
57 static void client_thread_entry(ULONG thread_input);
58 static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state);
59
60 /******** Optionally substitute your Ethernet driver here. ***********/
61 extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req);
62
63 /* Define what the initial system looks like. */
64
65 #ifdef CTEST
test_application_define(void * first_unused_memory)66 VOID test_application_define(void *first_unused_memory)
67 #else
68 void netx_dhcp_basic_test_application_define(void *first_unused_memory)
69 #endif
70 {
71
72 UINT status;
73
74
75 /* Setup the working pointer. */
76 pointer = (CHAR *) first_unused_memory;
77
78 /* Create the client thread. */
79 tx_thread_create(&client_thread, "thread client", client_thread_entry, 0,
80 pointer, DEMO_STACK_SIZE,
81 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
82 pointer = pointer + DEMO_STACK_SIZE;
83
84 /* Create the server thread. */
85 tx_thread_create(&server_thread, "thread server", server_thread_entry, 0,
86 pointer, DEMO_STACK_SIZE,
87 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
88 pointer = pointer + DEMO_STACK_SIZE;
89
90 /* Initialize the NetX system. */
91 nx_system_initialize();
92
93 /* Create the client packet pool. */
94 status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE);
95 pointer = pointer + NX_PACKET_POOL_SIZE;
96
97 /* Check for pool creation error. */
98 if (status)
99 error_counter++;
100
101 /* Create the server packet pool. */
102 status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE);
103 pointer = pointer + NX_PACKET_POOL_SIZE;
104
105 /* Check for pool creation error. */
106 if (status)
107 error_counter++;
108
109 /* Create an IP instance for the DHCP Client. */
110 status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1);
111
112 pointer = pointer + 2048;
113
114 /* Check for IP create errors. */
115 if (status)
116 error_counter++;
117
118 /* Create an IP instance for the DHCP Server. */
119 status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1);
120
121 pointer = pointer + 2048;
122
123 /* Check for IP create errors. */
124 if (status)
125 error_counter++;
126
127 /* Enable ARP and supply ARP cache memory for DHCP Client IP. */
128 status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
129 pointer = pointer + 1024;
130
131 /* Check for ARP enable errors. */
132 if (status)
133 error_counter++;
134
135 /* Enable ARP and supply ARP cache memory for DHCP Server IP. */
136 status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
137 pointer = pointer + 1024;
138
139 /* Check for ARP enable errors. */
140 if (status)
141 error_counter++;
142
143 /* Enable UDP traffic. */
144 status = nx_udp_enable(&client_ip);
145
146 /* Check for UDP enable errors. */
147 if (status)
148 error_counter++;
149
150 /* Enable UDP traffic. */
151 status = nx_udp_enable(&server_ip);
152
153 /* Check for UDP enable errors. */
154 if (status)
155 error_counter++;
156
157 /* Enable ICMP. */
158 status = nx_icmp_enable(&client_ip);
159
160 /* Check for errors. */
161 if (status)
162 error_counter++;
163
164 /* Enable ICMP. */
165 status = nx_icmp_enable(&server_ip);
166
167 /* Check for errors. */
168 if (status)
169 error_counter++;
170
171 return;
172 }
173
174 /* Define the test threads. */
175
server_thread_entry(ULONG thread_input)176 void server_thread_entry(ULONG thread_input)
177 {
178
179 UINT status;
180 UINT iface_index;
181 UINT addresses_added;
182
183 printf("NetX Test: DHCP Basic Test...........................................");
184
185 /* Create the DHCP Server. */
186 status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE,
187 "DHCP Server", &server_pool);
188
189 pointer = pointer + DEMO_STACK_SIZE;
190
191 /* Check for errors creating the DHCP Server. */
192 if (status)
193 error_counter++;
194
195 /* Load the assignable DHCP IP addresses for the first interface. */
196 iface_index = 0;
197
198 status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0,
199 END_IP_ADDRESS_LIST_0, &addresses_added);
200
201 /* Check for errors creating the list. */
202 if (status)
203 {
204 error_counter++;
205 }
206
207 /* Verify all the addresses were added to the list. */
208 if (addresses_added != 10)
209 {
210 error_counter++;
211 }
212
213 status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0,
214 NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0);
215
216 /* Check for errors setting network parameters. */
217 if (status)
218 {
219 error_counter++;
220 }
221
222 /* Start DHCP Server task. */
223 status = nx_dhcp_server_start(&dhcp_server);
224
225 /* Check for errors starting up the DHCP server. */
226 if (status)
227 {
228 error_counter++;
229 }
230
231 tx_thread_sleep(20 * NX_IP_PERIODIC_RATE);
232
233 if(error_counter)
234 {
235 printf("ERROR!\n");
236 test_control_return(1);
237 }
238 else
239 {
240 printf("SUCCESS!\n");
241 test_control_return(0);
242 }
243
244 return;
245 }
246
247 UINT length;
248
249 #if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER)
packet_filter_extended(NX_IP * ip_ptr,NX_PACKET * packet_ptr,UINT direction)250 static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction)
251 {
252 if ((direction == NX_IP_PACKET_OUT) &&
253 ((packet_ptr -> nx_packet_ip_header == NX_NULL) ||
254 (packet_ptr -> nx_packet_ip_header_length == 0)))
255 {
256 error_counter++;
257 }
258 return(NX_SUCCESS);
259 }
260 #endif
261
262 /* Define the test threads. */
263
client_thread_entry(ULONG thread_input)264 void client_thread_entry(ULONG thread_input)
265 {
266
267 UINT status;
268 NX_PACKET *my_packet;
269 UCHAR buffer[4];
270 UINT buffer_size = 4;
271 ULONG *long_ptr;
272
273 #ifdef REQUEST_CLIENT_IP
274 ULONG requested_ip;
275 UINT skip_discover_message = NX_FALSE;
276 #endif
277
278
279 /* Create the DHCP instance. */
280 status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client");
281 if (status)
282 error_counter++;
283
284 #ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL
285 status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool);
286 if (status)
287 error_counter++;
288 #endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */
289
290 #if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER)
291 client_ip.nx_ip_packet_filter_extended = packet_filter_extended;
292 #endif
293
294 /* Set the client IP if the host is configured to do so. */
295 #ifdef REQUEST_CLIENT_IP
296
297 requested_ip = (ULONG)CLIENT_IP_ADDRESS;
298
299 /* Request a specific IP address using the DHCP client address option. */
300 status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message);
301 if (status)
302 error_counter++;
303
304 #endif
305
306 /* Register state change variable. */
307 status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change);
308 if (status)
309 error_counter++;
310
311 /* Start the DHCP Client. */
312 status = nx_dhcp_start(&dhcp_client);
313 if (status)
314 error_counter++;
315
316 /* Check for address resolution. */
317 status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE);
318
319 /* Check status. */
320 if (status)
321 error_counter++;
322
323 /* Get the DNS Server address. */
324 status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size);
325
326 /* Check status. */
327 if (status == NX_SUCCESS)
328 {
329
330 /* Set the pointer. */
331 long_ptr = (ULONG *)(buffer);
332
333 /* Check the DNS address. */
334 if (*long_ptr != NX_DHCP_DNS_SERVER_0)
335 error_counter++;
336 }
337 else
338 {
339 error_counter++;
340 }
341
342 /* Get the lease time value. */
343 status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size);
344
345 /* Check status. */
346 if (status == NX_SUCCESS)
347 {
348
349 /* Set the pointer. */
350 long_ptr = (ULONG *)(buffer);
351
352 /* Check the lease time value. */
353 if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME)
354 error_counter++;
355 }
356 else
357 {
358 error_counter++;
359 }
360
361 length = sizeof(message);
362
363 /* Send pings to another host on the network... */
364 status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE);
365 if (status)
366 error_counter++;
367 else
368 nx_packet_release(my_packet);
369
370 /* Stopping the DHCP client. */
371 nx_dhcp_stop(&dhcp_client);
372
373 /* All done. Return resources to NetX and ThreadX. */
374 nx_dhcp_delete(&dhcp_client);
375
376 return;
377 }
378
379
dhcp_state_change(NX_DHCP * dhcp_ptr,UCHAR new_state)380 void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state)
381 {
382
383 /* Increment state changes counter. */
384 state_changes++;
385
386 return;
387 }
388 #else
389
390 #ifdef CTEST
test_application_define(void * first_unused_memory)391 VOID test_application_define(void *first_unused_memory)
392 #else
393 void netx_dhcp_basic_test_application_define(void *first_unused_memory)
394 #endif
395 {
396
397 /* Print out test information banner. */
398 printf("NetX Test: NetX DHCP Basic Test......................................N/A\n");
399
400 test_control_return(3);
401 }
402 #endif
403