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