1 
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 #include    "fx_api.h"
5 #include    "nxd_http_client.h"
6 #include    "nxd_http_server.h"
7 
8 extern void test_control_return(UINT);
9 
10 #if !defined(NX_DISABLE_IPV4)
11 
12 #define     DEMO_STACK_SIZE         4096
13 
14 /* Set up FileX and file memory resources. */
15 static CHAR             *ram_disk_memory;
16 static FX_MEDIA         ram_disk;
17 static unsigned char    media_memory[512];
18 
19 /* Define device drivers.  */
20 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
21 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
22 
23 /* Set up the HTTP client global variables. */
24 
25 #define         CLIENT_PACKET_SIZE  (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2)
26 
27 static TX_THREAD       client_thread;
28 static NX_PACKET_POOL  client_pool;
29 static NX_HTTP_CLIENT  my_client;
30 static NX_IP           client_ip;
31 static UINT            error_counter;
32 
33 /* Set up the HTTP server global variables */
34 
35 #define         SERVER_PACKET_SIZE  (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2)
36 
37 static NX_HTTP_SERVER  my_server;
38 static NX_PACKET_POOL  server_pool;
39 static TX_THREAD       server_thread;
40 static NX_IP           server_ip;
41 #ifdef __PRODUCT_NETXDUO__
42 static NXD_ADDRESS     server_ip_address;
43 #else
44 static ULONG           server_ip_address;
45 #endif
46 
47 
48 static void thread_client_entry(ULONG thread_input);
49 static void thread_server_entry(ULONG thread_input);
50 
51 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
52 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
53 
54 
55 /* Define the application's authentication check.  This is called by
56    the HTTP server whenever a new request is received.  */
authentication_check(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm)57 static UINT  authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type,
58             CHAR *resource, CHAR **name, CHAR **password, CHAR **realm)
59 {
60 
61     /* Just use a simple name, password, and realm for all
62        requests and resources.  */
63     *name =     "name";
64     *password = "password";
65     *realm =    "NetX Duo HTTP demo";
66 
67     /* Request basic authentication.  */
68     return(NX_HTTP_BASIC_AUTHENTICATE);
69 }
70 
71 #ifdef CTEST
test_application_define(void * first_unused_memory)72 VOID test_application_define(void *first_unused_memory)
73 #else
74 void    netx_http_basic_test_application_define(void *first_unused_memory)
75 #endif
76 {
77 
78 CHAR    *pointer;
79 UINT    status;
80 
81     error_counter = 0;
82 
83     /* Setup the working pointer.  */
84     pointer =  (CHAR *) first_unused_memory;
85 
86     /* Create a helper thread for the server. */
87     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
88                      pointer, DEMO_STACK_SIZE,
89                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
90 
91     pointer =  pointer + DEMO_STACK_SIZE;
92 
93     /* Initialize the NetX system.  */
94     nx_system_initialize();
95 
96     /* Create the server packet pool.  */
97     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
98                                     pointer, SERVER_PACKET_SIZE*8);
99     pointer = pointer + SERVER_PACKET_SIZE * 8;
100     if (status)
101         error_counter++;
102 
103     /* Create an IP instance.  */
104     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
105                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
106                           pointer, 4096, 1);
107     pointer =  pointer + 4096;
108     if (status)
109         error_counter++;
110 
111     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
112     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
113     pointer = pointer + 1024;
114     if (status)
115         error_counter++;
116 
117 
118      /* Enable TCP traffic.  */
119     status = nx_tcp_enable(&server_ip);
120     if (status)
121         error_counter++;
122 
123     /* Set up the server's IPv4 address here. */
124 #ifdef __PRODUCT_NETXDUO__
125     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
126     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
127 #else
128     server_ip_address = HTTP_SERVER_ADDRESS;
129 #endif
130 
131     /* Create the HTTP Server.  */
132     status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk,
133                           pointer, 2048, &server_pool, authentication_check, NX_NULL);
134     pointer =  pointer + 2048;
135     if (status)
136         error_counter++;
137 
138     /* Save the memory pointer for the RAM disk.  */
139     ram_disk_memory =  pointer;
140 
141     /* Create the HTTP Client thread. */
142     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
143                      pointer, DEMO_STACK_SIZE,
144                      6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
145     pointer =  pointer + DEMO_STACK_SIZE;
146     if (status)
147         error_counter++;
148 
149     /* Create the Client packet pool.  */
150     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
151                                     pointer, CLIENT_PACKET_SIZE*8);
152     pointer = pointer + CLIENT_PACKET_SIZE * 8;
153     if (status)
154         error_counter++;
155 
156     /* Create an IP instance.  */
157     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
158                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
159                           pointer, 2048, 1);
160     pointer =  pointer + 2048;
161     if (status)
162         error_counter++;
163 
164     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
165     pointer =  pointer + 2048;
166     if (status)
167         error_counter++;
168 
169      /* Enable TCP traffic.  */
170     status = nx_tcp_enable(&client_ip);
171     if (status)
172         error_counter++;
173 }
174 
175 
thread_client_entry(ULONG thread_input)176 void thread_client_entry(ULONG thread_input)
177 {
178 
179 UINT            status;
180 NX_PACKET       *send_packet;
181 NX_PACKET       *recv_packet;
182 
183     /* Format the RAM disk - the memory for the RAM disk was setup in
184       tx_application_define above.  This must be set up before the client(s) start
185       sending requests. */
186     status = fx_media_format(&ram_disk,
187                             _fx_ram_driver,         /* Driver entry               */
188                             ram_disk_memory,        /* RAM disk memory pointer    */
189                             media_memory,           /* Media buffer pointer       */
190                             sizeof(media_memory),   /* Media buffer size          */
191                             "MY_RAM_DISK",          /* Volume Name                */
192                             1,                      /* Number of FATs             */
193                             32,                     /* Directory Entries          */
194                             0,                      /* Hidden sectors             */
195                             256,                    /* Total sectors              */
196                             128,                    /* Sector size                */
197                             1,                      /* Sectors per cluster        */
198                             1,                      /* Heads                      */
199                             1);                     /* Sectors per track          */
200 
201     /* Check the media format status.  */
202     if (status != FX_SUCCESS)
203         error_counter++;
204 
205     /* Open the RAM disk.  */
206     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory));
207 
208     /* Check the media open status.  */
209     if (status != FX_SUCCESS)
210         error_counter++;
211 
212     /* Create an HTTP client instance.  */
213     status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600);
214 
215     /* Check status.  */
216     if (status)
217         error_counter++;
218 
219 #ifdef __PRODUCT_NETXDUO__
220 
221     /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */
222     status =  nxd_http_client_put_start(&my_client, &server_ip_address, "/client_test.htm",
223                                             "name", "password", 103, 5 * NX_IP_PERIODIC_RATE);
224 #else
225 
226     /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */
227     status =  nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm",
228                                    "name", "password", 103, 5 * NX_IP_PERIODIC_RATE);
229 #endif
230 
231     /* Check status.  */
232     if (status)
233         error_counter++;
234 
235     /* Allocate a packet.  */
236     status =  nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
237 
238     /* Check status.  */
239     if(status)
240         error_counter++;
241 
242     /* Build a simple 103-byte HTML page.  */
243     nx_packet_data_append(send_packet, "<HTML>\r\n", 8,
244                         &client_pool, NX_WAIT_FOREVER);
245     nx_packet_data_append(send_packet,
246                  "<HEAD><TITLE>NetX HTTP Test</TITLE></HEAD>\r\n", 44,
247                         &client_pool, NX_WAIT_FOREVER);
248     nx_packet_data_append(send_packet, "<BODY>\r\n", 8,
249                         &client_pool, NX_WAIT_FOREVER);
250     nx_packet_data_append(send_packet, "<H1>Another NetX Test Page!</H1>\r\n", 25,
251                         &client_pool, NX_WAIT_FOREVER);
252     nx_packet_data_append(send_packet, "</BODY>\r\n", 9,
253                         &client_pool, NX_WAIT_FOREVER);
254     nx_packet_data_append(send_packet, "</HTML>\r\n", 9,
255                         &client_pool, NX_WAIT_FOREVER);
256 
257     /* Complete the PUT by writing the total length.  */
258     status =  nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE);
259     if(status)
260         error_counter++;
261 
262     /* Now GET the test file  */
263 
264 #ifdef __PRODUCT_NETXDUO__
265 
266     /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */
267     status =  nxd_http_client_get_start(&my_client, &server_ip_address,
268                                         "/client_test.htm", NX_NULL, 0, "name", "password", 50);
269 #else
270 
271     /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */
272     status =  nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm",
273                                        NX_NULL, 0, "name", "password", 50);
274 #endif  /* USE_DUO */
275 
276     if(status)
277         error_counter++;
278 
279     while (1)
280     {
281         status = nx_http_client_get_packet(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
282 
283         if (status == NX_HTTP_GET_DONE)
284             break;
285 
286         if (status)
287             error_counter++;
288         else
289             nx_packet_release(recv_packet);
290     }
291 
292 #ifdef __PRODUCT_NETXDUO__
293 
294     /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */
295     status =  nxd_http_client_put_start_extended(&my_client, &server_ip_address, "/client_test_extended.htm", 25,
296                                                  "name", 4, "password", 8, 103, 5 * NX_IP_PERIODIC_RATE);
297 #else
298 
299     /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */
300     status =  nx_http_client_put_start_extended(&my_client, HTTP_SERVER_ADDRESS, "/client_test_extended.htm", 25,
301                                                 "name", 4, "password", 8, 103, 5 * NX_IP_PERIODIC_RATE);
302 #endif
303 
304     /* Check status.  */
305     if (status)
306         error_counter++;
307 
308     /* Allocate a packet.  */
309     status =  nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
310 
311     /* Check status.  */
312     if(status)
313         error_counter++;
314 
315     /* Build a simple 103-byte HTML page.  */
316     nx_packet_data_append(send_packet, "<HTML>\r\n", 8,
317                         &client_pool, NX_WAIT_FOREVER);
318     nx_packet_data_append(send_packet,
319                  "<HEAD><TITLE>NetX HTTP Test</TITLE></HEAD>\r\n", 44,
320                         &client_pool, NX_WAIT_FOREVER);
321     nx_packet_data_append(send_packet, "<BODY>\r\n", 8,
322                         &client_pool, NX_WAIT_FOREVER);
323     nx_packet_data_append(send_packet, "<H1>Another NetX Test Page!</H1>\r\n", 25,
324                         &client_pool, NX_WAIT_FOREVER);
325     nx_packet_data_append(send_packet, "</BODY>\r\n", 9,
326                         &client_pool, NX_WAIT_FOREVER);
327     nx_packet_data_append(send_packet, "</HTML>\r\n", 9,
328                         &client_pool, NX_WAIT_FOREVER);
329 
330     /* Complete the PUT by writing the total length.  */
331     status =  nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE);
332     if(status)
333         error_counter++;
334 
335     /* Now GET the test file  */
336 
337 #ifdef __PRODUCT_NETXDUO__
338 
339     /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */
340     status =  nxd_http_client_get_start_extended(&my_client, &server_ip_address,
341                                                  "/client_test_extended.htm", 25, NX_NULL, 0, "name", 4, "password", 8, 50);
342 #else
343 
344     /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */
345     status =  nx_http_client_get_start_extended(&my_client, HTTP_SERVER_ADDRESS, "/client_test_extended.htm", 25,
346                                                 NX_NULL, 0, "name", 4, "password", 8, 50);
347 #endif  /* USE_DUO */
348 
349     if(status)
350         error_counter++;
351 
352     while (1)
353     {
354         status = nx_http_client_get_packet(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
355 
356         if (status == NX_HTTP_GET_DONE)
357             break;
358 
359         if (status)
360             error_counter++;
361         else
362             nx_packet_release(recv_packet);
363     }
364 
365     status = nx_http_client_delete(&my_client);
366     if(status)
367         error_counter++;
368 
369     tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
370 
371     if(error_counter)
372     {
373         printf("ERROR!\n");
374         test_control_return(1);
375     }
376     else
377     {
378         printf("SUCCESS!\n");
379         test_control_return(0);
380     }
381 
382 }
383 
384 
385 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)386 void    thread_server_entry(ULONG thread_input)
387 {
388 
389 UINT            status;
390 
391     /* Print out test information banner.  */
392     printf("NetX Test:   HTTP Basic Test...........................................");
393 
394     /* Check for earlier error. */
395     if(error_counter)
396     {
397         printf("ERROR!\n");
398         test_control_return(1);
399     }
400 
401     /* OK to start the HTTP Server.   */
402     status = nx_http_server_start(&my_server);
403     if(status)
404         error_counter++;
405 
406     /* Restart HTTP server. */
407     status = nx_http_server_stop(&my_server);
408     status += nx_http_server_start(&my_server);
409     if(status)
410         error_counter++;
411 
412     tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
413 
414     status = nx_http_server_delete(&my_server);
415     if(status)
416         error_counter++;
417 
418 }
419 #else
420 
421 #ifdef CTEST
test_application_define(void * first_unused_memory)422 VOID test_application_define(void *first_unused_memory)
423 #else
424 void    netx_http_basic_test_application_define(void *first_unused_memory)
425 #endif
426 {
427 
428     /* Print out test information banner.  */
429     printf("NetX Test:   HTTP Basic Test...........................................N/A\n");
430 
431     test_control_return(3);
432 }
433 #endif
434 
435