1 /* This case tests concurrent HTTPS sessions by launching several
2 * HTTPS clients in separate threads and using randomized delay to
3 * hit the server with repeated requests. */
4 #include "tx_api.h"
5 #include "nx_api.h"
6 #include "fx_api.h"
7 #include "nx_web_http_client.h"
8 #include "nx_web_http_server.h"
9
10
11 extern void test_control_return(UINT);
12
13 #if !defined(NX_DISABLE_IPV4)
14
15 #include "test_device_cert.c"
16 #include "test_ca_cert.c"
17 #define ca_cert_der test_ca_cert_der
18 #define ca_cert_der_len test_ca_cert_der_len
19
20 #define DEMO_STACK_SIZE 4096
21
22 /* Set up FileX and file memory resources. */
23 static CHAR ram_disk_memory[4096];
24 static FX_MEDIA ram_disk;
25 static UCHAR media_memory[4096];
26
27 static UCHAR server_stack[16000];
28
29 /* Define device drivers. */
30 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
31 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
32
33 /* Set up the HTTP client global variables. */
34
35 #define CLIENT_PACKET_SIZE (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
36
37 #define HTTP_CLIENT_THREADS 4
38 #define HTTP_CONCURRENT_TESTS 10
39
40 static TX_THREAD client_threads[HTTP_CLIENT_THREADS];
41 static UINT client_thread_index = 0;
42 static NX_PACKET_POOL client_pool;
43 static NX_WEB_HTTP_CLIENT my_clients[HTTP_CLIENT_THREADS];
44 static NX_IP client_ip;
45 static UINT error_counter;
46
47 /* Set up the HTTP server global variables */
48
49 #define SERVER_WAIT_TICKS (50)
50 #define SERVER_PACKET_SIZE (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
51
52 static NX_WEB_HTTP_SERVER my_server;
53 static NX_PACKET_POOL server_pool;
54 static TX_THREAD server_thread;
55 static NX_IP server_ip;
56 static NXD_ADDRESS server_ip_address;
57 static UINT http_server_start = 0;
58 static UINT http_client_stop = 0;
59
60 static void thread_client_entry(ULONG thread_input);
61 static void thread_server_entry(ULONG thread_input);
62
63 #define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4)
64 #define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5)
65
66 #ifdef NX_WEB_HTTPS_ENABLE
67 static UINT https_server_start = 0;
68 static UINT https_client_stop = 0;
69 static UINT loop = 2;
70 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
71 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
72 static CHAR crypto_metadata_client[HTTP_CLIENT_THREADS][20000];
73 static UCHAR tls_packet_buffer[NX_WEB_HTTP_SERVER_SESSION_MAX * 18500];
74 static UCHAR client_packet_buffer[HTTP_CLIENT_THREADS][18500];
75 static NX_SECURE_X509_CERT certificate;
76 static NX_SECURE_X509_CERT trusted_certificate;
77 static NX_SECURE_X509_CERT remote_certificates[HTTP_CLIENT_THREADS], remote_issuers[HTTP_CLIENT_THREADS];
78 static UCHAR remote_cert_buffers[HTTP_CLIENT_THREADS][2000];
79 static UCHAR remote_issuer_buffers[HTTP_CLIENT_THREADS][2000];
80
81 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session);
82 #else
83 static UINT loop = 1;
84 #endif /* NX_WEB_HTTPS_ENABLE */
85
86
87 #define PRINT_ERROR(error_code) _error_print(error_code, __LINE__)
88
_error_print(UINT error_code,UINT line)89 static void _error_print(UINT error_code, UINT line)
90 {
91 printf("Error on line %d, status: 0x%x\n", line, error_code);
92 error_counter++;
93 }
94
_print_trace(CHAR * message,...)95 static void _print_trace(CHAR *message, ...)
96 {
97 #if 0
98 va_list arg;
99
100 va_start (arg, message);
101 printf (message, arg);
102 va_end (arg);
103 #endif
104
105 }
106
107 static UINT authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
108 CHAR *resource, CHAR **name, CHAR **password, CHAR **realm);
109 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr);
110
111 #ifdef CTEST
test_application_define(void * first_unused_memory)112 VOID test_application_define(void *first_unused_memory)
113 #else
114 void netx_web_concurrent_sessions_test_application_define(void *first_unused_memory)
115 #endif
116 {
117 CHAR *pointer;
118 CHAR thread_name[100];
119 UINT i;
120 UINT status;
121
122
123 error_counter = 0;
124
125 /* Setup the working pointer. */
126 pointer = (CHAR *) first_unused_memory;
127
128 /* Create a helper thread for the server. */
129 tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
130 pointer, DEMO_STACK_SIZE,
131 NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
132
133 pointer = pointer + DEMO_STACK_SIZE;
134
135 /* Initialize the NetX system. */
136 nx_system_initialize();
137
138 /* Create the server packet pool. */
139 status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
140 pointer, SERVER_PACKET_SIZE*64);
141 pointer = pointer + SERVER_PACKET_SIZE * 64;
142 if (status)
143 PRINT_ERROR(status);
144
145 /* Create an IP instance. */
146 status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
147 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
148 pointer, 4096, 1);
149 pointer = pointer + 4096;
150 if (status)
151 PRINT_ERROR(status);
152
153 /* Enable ARP and supply ARP cache memory for the server IP instance. */
154 status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
155 pointer = pointer + 1024;
156 if (status)
157 PRINT_ERROR(status);
158
159
160 /* Enable TCP traffic. */
161 status = nx_tcp_enable(&server_ip);
162 if (status)
163 PRINT_ERROR(status);
164
165 /* Create the HTTP Client thread. */
166 for(i = 0; i < HTTP_CLIENT_THREADS; ++i)
167 {
168 snprintf(thread_name, 100, "HTTP Client %d", i);
169 status = tx_thread_create(&client_threads[i], thread_name, thread_client_entry, i,
170 pointer, DEMO_STACK_SIZE,
171 NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
172 pointer = pointer + DEMO_STACK_SIZE;
173 }
174 if (status)
175 PRINT_ERROR(status);
176
177 /* Create the Client packet pool. */
178 status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
179 pointer, CLIENT_PACKET_SIZE*16);
180 pointer = pointer + CLIENT_PACKET_SIZE * 16;
181 if (status)
182 PRINT_ERROR(status);
183
184 /* Create an IP instance. */
185 status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
186 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
187 pointer, 2048, 1);
188 pointer = pointer + 2048;
189 if (status)
190 PRINT_ERROR(status);
191
192 status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
193 pointer = pointer + 2048;
194 if (status)
195 PRINT_ERROR(status);
196
197 /* Enable TCP traffic. */
198 status = nx_tcp_enable(&client_ip);
199 if (status)
200 PRINT_ERROR(status);
201 }
202
203 #ifdef NX_WEB_HTTPS_ENABLE
204 /* Define the TLS setup callback function. */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)205 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
206 {
207 UINT status;
208
209 _print_trace("Setting up tls for thread: %s\n", client_ptr->nx_web_http_client_name);
210
211 /* Use counter from client name (set up when client is created. */
212 client_thread_index = client_ptr->nx_web_http_client_name[0] - '0';
213
214 /* Initialize and create TLS session. */
215 status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client[client_thread_index], sizeof(crypto_metadata_client[0]));
216
217 /* Check status. */
218 if (status)
219 {
220 return(status);
221 }
222
223 /* Allocate space for packet reassembly. */
224 status = nx_secure_tls_session_packet_buffer_set(tls_session, client_packet_buffer[client_thread_index], sizeof(client_packet_buffer[0]));
225
226 /* Check status. */
227 if (status)
228 {
229 return(status);
230 }
231
232 /* Add a CA Certificate to our trusted store for verifying incoming server certificates. */
233 nx_secure_x509_certificate_initialize(&trusted_certificate, ca_cert_der, ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
234 nx_secure_tls_trusted_certificate_add(tls_session, &trusted_certificate);
235
236 /* Need to allocate space for the certificate coming in from the remote host. */
237 nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificates[client_thread_index], remote_cert_buffers[client_thread_index], sizeof(remote_cert_buffers[0]));
238 nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuers[client_thread_index], remote_issuer_buffers[client_thread_index], sizeof(remote_issuer_buffers[0]));
239
240 /* Increment global counter. */
241 client_thread_index++;
242
243 return(NX_SUCCESS);
244 }
245 #endif /* NX_WEB_HTTPS_ENABLE */
246
http_response_callback(NX_WEB_HTTP_CLIENT * client_ptr,CHAR * field_name,UINT field_name_length,CHAR * field_value,UINT field_value_length)247 static VOID http_response_callback(NX_WEB_HTTP_CLIENT *client_ptr, CHAR *field_name, UINT field_name_length,
248 CHAR *field_value, UINT field_value_length)
249 {
250 if (memcmp(field_name, "Content-Type", field_name_length) == 0)
251 {
252 if (memcmp(field_value, "text/plain", field_value_length) != 0)
253 PRINT_ERROR(1);
254 }
255 else if(memcmp(field_name, "Content-Length", field_name_length) == 0)
256 {
257 if (memcmp(field_value, "12", field_value_length) != 0)
258 PRINT_ERROR(1);
259 }
260 else if(memcmp(field_name, "Connection", field_name_length) == 0)
261 {
262 if (memcmp(field_value, "keep-alive", field_value_length) != 0)
263 PRINT_ERROR(1);
264 }
265 }
266
thread_client_entry(ULONG thread_input)267 void thread_client_entry(ULONG thread_input)
268 {
269 UINT i;
270 UINT status;
271 UINT thread_index;
272 UCHAR client_name[100];
273 NX_PACKET *recv_packet;
274 NX_WEB_HTTP_CLIENT *my_client;
275 UINT num_tests;
276
277 /* Give IP task and driver a chance to initialize the system. */
278 tx_thread_sleep(NX_IP_PERIODIC_RATE);
279
280 /* Get the index of this thread. */
281 thread_index = (UINT)(thread_input);
282
283 /* Get the client for this thread. */
284 my_client = &my_clients[thread_index];
285
286 /* Set server IP address. */
287 server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
288 server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
289
290 /* First loop test HTTP, second loop test HTTPS. */
291 for (i = 1; i < loop ; i++)
292 {
293 _print_trace("Starting HTTP Client %d\n", thread_index);
294 for(num_tests = 0; num_tests < HTTP_CONCURRENT_TESTS; ++num_tests)
295 {
296 if (i == 0)
297 {
298
299 /* Wait HTTP server started. */
300 while(!http_server_start)
301 {
302 tx_thread_sleep(NX_IP_PERIODIC_RATE);
303 }
304 }
305 #ifdef NX_WEB_HTTPS_ENABLE
306 else
307 {
308
309 /* Wait HTTPS server started. */
310 while(!https_server_start)
311 {
312 tx_thread_sleep(NX_IP_PERIODIC_RATE);
313 }
314 }
315 #endif /* NX_WEB_HTTPS_ENABLE */
316
317 _print_trace("Starting HTTP Client %d, test number: %d\n", thread_index, num_tests);
318
319 /* Random start between 10ms and 1s so we hit during different states. */
320 tx_thread_sleep((rand() % 10) * 10);
321
322
323
324 /* Create an HTTP client instance. */
325 snprintf(client_name, 100, "%d HTTP Client", thread_index);
326 status = nx_web_http_client_create(my_client, client_name, &client_ip, &client_pool, 1536);
327
328 /* Check status. */
329 if (status)
330 PRINT_ERROR(status);
331
332 /* Set the header callback routine. */
333 nx_web_http_client_response_header_callback_set(my_client, http_response_callback);
334
335 /* Send a GET request. */
336 if (i == 0)
337 {
338 status = nx_web_http_client_get_start(my_client, &server_ip_address,
339 NX_WEB_HTTP_SERVER_PORT, "http://1.2.3.4/test.txt",
340 "1.2.3.4", "name", "password", NX_WAIT_FOREVER);
341 }
342 #ifdef NX_WEB_HTTPS_ENABLE
343 else
344 {
345 _print_trace("Starting secure get\n");
346 status = nx_web_http_client_get_secure_start(my_client, &server_ip_address,
347 NX_WEB_HTTPS_SERVER_PORT, "https://1.2.3.4/test.txt",
348 "1.2.3.4", "name", "password",
349 tls_setup_callback, NX_WAIT_FOREVER);
350 }
351 #endif /* NX_WEB_HTTPS_ENABLE */
352
353 /* Check status. */
354 if (status)
355 {
356 _print_trace("Error in connecting to server. Status: 0x%x, Thread index: %d\n", status, thread_index);
357 PRINT_ERROR(status);
358 }
359
360 /* Get response from server. */
361 status = nx_web_http_client_response_body_get(my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
362
363 /* Check status. */
364 if (status != NX_WEB_HTTP_GET_DONE)
365 {
366 _print_trace("Error in getting response body (check connection). Status: 0x%x, Thread: %d\n", status, thread_index);
367 PRINT_ERROR(status);
368 }
369 else
370 nx_packet_release(recv_packet);
371
372 status = nx_web_http_client_delete(my_client);
373 if (status)
374 PRINT_ERROR(status);
375
376 }
377
378 _print_trace("Ending HTTP Client %d\n", thread_index);
379
380 /* Set the flag. */
381 if (i == 0)
382 {
383 http_client_stop++;
384 }
385 #ifdef NX_WEB_HTTPS_ENABLE
386 else
387 {
388 https_client_stop++;
389 }
390 #endif
391
392 }
393 }
394
395 /* Define the helper HTTP server thread. */
thread_server_entry(ULONG thread_input)396 void thread_server_entry(ULONG thread_input)
397 {
398 UINT i;
399 UINT status;
400 FX_FILE my_file;
401 UINT server_port = NX_WEB_HTTP_SERVER_PORT;
402
403
404 /* Print out test information banner. */
405 printf("NetX Test: Web Concurrent Sessions Test..............................");
406
407 /* Check for earlier error. */
408 if(error_counter)
409 {
410 printf("ERROR!\n");
411 test_control_return(1);
412 }
413
414 fx_media_format(&ram_disk,
415 _fx_ram_driver, // Driver entry
416 ram_disk_memory, // RAM disk memory pointer
417 media_memory, // Media buffer pointer
418 sizeof(media_memory), // Media buffer size
419 "MY_RAM_DISK", // Volume Name
420 1, // Number of FATs
421 32, // Directory Entries
422 0, // Hidden sectors
423 256, // Total sectors
424 512, // Sector size
425 8, // Sectors per cluster
426 1, // Heads
427 1); // Sectors per track
428
429 /* Open the RAM disk. */
430 status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
431 status += fx_file_create(&ram_disk, "TEST.TXT");
432 status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
433 status += fx_file_write(&my_file, "https server", 12);
434 status += fx_file_close(&my_file);
435 if(status)
436 PRINT_ERROR(status);
437
438 /* Give NetX a chance to initialize the system. */
439 tx_thread_sleep(NX_IP_PERIODIC_RATE);
440
441 /* First loop test HTTP, second loop test HTTPS. */
442 for (i = 1; i < loop; i++)
443 {
444
445 if (i == 1)
446 {
447 server_port = NX_WEB_HTTPS_SERVER_PORT;
448 }
449
450 _print_trace("\nStarting server\n");
451
452 /* Create the HTTP Server. */
453 status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
454 &server_stack, sizeof(server_stack), &server_pool,
455 authentication_check, server_request_callback);
456 if (status)
457 PRINT_ERROR(status);
458
459 #ifdef NX_WEB_HTTPS_ENABLE
460 /* Set TLS for HTTPS. */
461 if (i == 1)
462 {
463 /* Initialize device certificate (used for all sessions in HTTPS server). */
464 memset(&certificate, 0, sizeof(certificate));
465 nx_secure_x509_certificate_initialize(&certificate, test_device_cert_der, test_device_cert_der_len, NX_NULL, 0, test_device_cert_key_der, test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
466
467 /* Setup TLS session data for the TCP server. */
468 status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
469 crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
470 &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
471 if (status)
472 PRINT_ERROR(status);
473 }
474 #endif /* NX_WEB_HTTPS_ENABLE */
475
476 /* OK to start the HTTP Server. */
477 status = nx_web_http_server_start(&my_server);
478 if (status)
479 PRINT_ERROR(status);
480
481 _print_trace("...Server started\n");
482
483 /* Set the flag. */
484 if (i == 0)
485 {
486 http_server_start = 1;
487
488 /* Wait HTTP test finished. */
489 while(http_client_stop < HTTP_CLIENT_THREADS)
490 {
491 tx_thread_sleep(NX_IP_PERIODIC_RATE);
492 }
493 }
494 #ifdef NX_WEB_HTTPS_ENABLE
495 else
496 {
497 https_server_start = 1;
498
499 /* Wait HTTPS test finished. */
500 while(https_client_stop < HTTP_CLIENT_THREADS)
501 {
502 tx_thread_sleep(NX_IP_PERIODIC_RATE);
503 }
504 }
505 #endif /* NX_WEB_HTTPS_ENABLE */
506
507 _print_trace("Stopping server...\n");
508
509 status = nx_web_http_server_stop(&my_server);
510 if (status)
511 PRINT_ERROR(status);
512
513 status = nx_web_http_server_delete(&my_server);
514 if (status)
515 PRINT_ERROR(status);
516 }
517
518 if(error_counter)
519 {
520 printf("ERROR!\n");
521 test_control_return(1);
522 }
523 else
524 {
525 printf("SUCCESS!\n");
526 test_control_return(0);
527 }
528 }
529
530 /* Define the application's authentication check. This is called by
531 the HTTP server whenever a new request is received. */
authentication_check(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm)532 static UINT authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
533 CHAR *resource, CHAR **name, CHAR **password, CHAR **realm)
534 {
535
536 /* Just use a simple name, password, and realm for all
537 requests and resources. */
538 *name = "name";
539 *password = "password";
540 *realm = "NetX Duo HTTP demo";
541
542 /* Request basic authentication. */
543 return(NX_WEB_HTTP_BASIC_AUTHENTICATE);
544 }
545
546 /* Define the server request callback function. */
server_request_callback(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr)547 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr)
548 {
549 ULONG offset, length;
550 NX_PACKET *response_pkt;
551 UCHAR buffer[4000];
552 UINT status;
553 CHAR response[] = "Test response from server - uploaded file contents:\n";
554
555
556 memset(buffer, 0, sizeof(buffer));
557 length = 0;
558
559 _print_trace("***************** Server recevied request..\n");
560
561 /* Process multipart data. */
562 if(request_type == NX_WEB_HTTP_SERVER_POST_REQUEST)
563 {
564
565 /* Get the content header. */
566 while(nx_web_http_server_get_entity_header(server_ptr, &packet_ptr, buffer,
567 sizeof(buffer)) == NX_SUCCESS)
568 {
569
570 /* Header obtained successfully. Get the content data location. */
571 while(nx_web_http_server_get_entity_content(server_ptr, &packet_ptr, &offset,
572 &length) == NX_SUCCESS)
573 {
574 /* make sure we don't overwrite our buffer! */
575 if(length > sizeof(buffer))
576 {
577 length = sizeof(buffer);
578 }
579
580 /* Write content data to buffer. */
581 nx_packet_data_extract_offset(packet_ptr, offset, buffer, length,
582 &length);
583 buffer[length] = 0;
584 }
585 }
586
587 /* Generate HTTP header. */
588 status = nx_web_http_server_callback_generate_response_header(server_ptr,
589 &response_pkt, NX_WEB_HTTP_STATUS_OK, 800, "text/html",
590 "Server: NetX HTTPS Experimental\r\n");
591
592 if(status)
593 {
594 return(status);
595 }
596
597 status = nx_packet_data_append(response_pkt, response, strlen(response),
598 &server_pool, SERVER_WAIT_TICKS);
599
600 if(length > 0)
601 {
602 /* Only send what is in the buffer. */
603 if(length > 4000)
604 {
605 length = 4000;
606 }
607 status = nx_packet_data_append(response_pkt, buffer, length,
608 &server_pool, SERVER_WAIT_TICKS);
609 }
610
611 if(status == NX_SUCCESS)
612 {
613 if(nx_web_http_server_callback_packet_send(server_ptr, response_pkt) != NX_SUCCESS)
614 {
615 nx_packet_release(response_pkt);
616 }
617 }
618 }
619 else
620 {
621 /* Indicate we have not processed the response to client yet. */
622 return(NX_SUCCESS);
623 }
624
625 /* Indicate the response to client is transmitted. */
626 return(NX_WEB_HTTP_CALLBACK_COMPLETED);
627 }
628 #else
629
630 #ifdef CTEST
test_application_define(void * first_unused_memory)631 VOID test_application_define(void *first_unused_memory)
632 #else
633 void netx_web_basic_test_application_define(void *first_unused_memory)
634 #endif
635 {
636
637 /* Print out test information banner. */
638 printf("NetX Test: Web Basic Test............................................N/A\n");
639
640 test_control_return(3);
641 }
642 #endif
643
644