1 /* This is a small demo of HTTP on the high-performance NetX TCP/IP stack.
2    This demo relies on ThreadX, NetX, and FileX to show a simple HTML
3    transfer from the client and then back from the server.  */
4 
5 #include  "tx_api.h"
6 #include  "fx_api.h"
7 #include  "nx_api.h"
8 #include  "nx_web_http_client.h"
9 #include  "nx_web_http_server.h"
10 #include  "test_utility.h"
11 #define     DEMO_STACK_SIZE         4096
12 
13 /* Define the ThreadX and NetX object control blocks...  */
14 
15 TX_THREAD               thread_0;
16 TX_THREAD               thread_1;
17 NX_PACKET_POOL          pool_0;
18 NX_PACKET_POOL          pool_1;
19 NX_IP                   ip_0;
20 NX_IP                   ip_1;
21 FX_MEDIA                ram_disk;
22 
23 /* Define HTTP objects.  */
24 
25 NX_WEB_HTTP_SERVER      my_server;
26 NX_WEB_HTTPS_CLIENT      my_client;
27 
28 /* Define the counters used in the demo application...  */
29 
30 ULONG                   error_counter;
31 
32 
33 /* Define the RAM disk memory.  */
34 
35 UCHAR                   ram_disk_memory[32000];
36 
37 
38 /* Define function prototypes.  */
39 
40 void    thread_0_entry(ULONG thread_input);
41 VOID    _fx_ram_driver(FX_MEDIA *media_ptr) ;
42 void    _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
43 
44 /* Define the application's authentication check.  This is called by
45    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)46 static UINT  authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
47             CHAR *resource, CHAR **name, CHAR **password, CHAR **realm)
48 {
49 
50     /* Just use a simple name, password, and realm for all
51        requests and resources.  */
52     *name =     "name";
53     *password = "password";
54     *realm =    "NetX HTTP demo";
55 
56     /* Request basic authentication.  */
57     return(NX_WEB_HTTP_BASIC_AUTHENTICATE);
58 }
59 
60 
61 /* Define what the initial system looks like.  */
62 #ifdef CTEST
test_application_define(void * first_unused_memory)63 VOID test_application_define(void *first_unused_memory)
64 #else
65 void    netx_web_http_demo_test_application_define(void *first_unused_memory)
66 #endif
67 {
68 
69 CHAR    *pointer;
70 UINT    status;
71 
72 
73     /* Setup the working pointer.  */
74     pointer =  (CHAR *) first_unused_memory;
75 
76     /* Create the main thread.  */
77     tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
78             pointer, DEMO_STACK_SIZE,
79             2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
80     pointer =  pointer + DEMO_STACK_SIZE;
81 
82     /* Initialize the NetX system.  */
83     nx_system_initialize();
84 
85     /* Create packet pool.  */
86     nx_packet_pool_create(&pool_0, "NetX Packet Pool 0", 640, pointer, 8192);
87     pointer = pointer + 8192;
88 
89     /* Create an IP instance.  */
90     nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4),
91                         0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
92                         pointer, 4096, 1);
93     pointer =  pointer + 4096;
94 
95     /* Create another packet pool. */
96     nx_packet_pool_create(&pool_1, "NetX Packet Pool 1", 640, pointer, 8192);
97     pointer = pointer + 8192;
98 
99     /* Create another IP instance.  */
100     nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5),
101                         0xFFFFFF00UL, &pool_1, _nx_ram_network_driver,
102                         pointer, 4096, 1);
103     pointer = pointer + 4096;
104 
105     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
106     nx_arp_enable(&ip_0, (void *) pointer, 1024);
107     pointer = pointer + 1024;
108 
109     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
110     nx_arp_enable(&ip_1, (void *) pointer, 1024);
111     pointer = pointer + 1024;
112 
113     /* Enable TCP processing for both IP instances.  */
114     nx_tcp_enable(&ip_0);
115     nx_tcp_enable(&ip_1);
116 
117     /* Open the RAM disk.  */
118     /* Format the media.  This needs to be done before opening it!  */
119     status =  fx_media_format(&ram_disk,
120                             _fx_ram_driver,         // Driver entry
121                             ram_disk_memory,        // RAM disk memory pointer
122                             pointer,           // Media buffer pointer
123                             4096,             // Media buffer size
124                             "MY_RAM_DISK",          // Volume Name
125                             1,                      // Number of FATs
126                             32,                     // Directory Entries
127                             0,                      // Hidden sectors
128                             511,                    // Total sectors
129                             128,                    // Sector size
130                             1,                      // Sectors per cluster
131                             1,                      // Heads
132                             1);                     // Sectors per track
133     EXPECT_EQ(0, status);
134 
135     status = fx_media_open(&ram_disk, "RAM DISK",
136                     _fx_ram_driver, ram_disk_memory, pointer, 4096) ;
137     EXPECT_EQ(0, status);
138     pointer += 4096;
139 
140     /* Create the NetX HTTP Server.  */
141     status = nx_web_http_server_create(&my_server, "My HTTP Server", &ip_1, &ram_disk,
142                 pointer, 4096, &pool_1, authentication_check, NX_NULL);
143     EXPECT_EQ(NX_SUCCESS, status);
144     pointer =  pointer + 4096;
145 
146     /* Start the HTTP Server.  */
147     status = nx_web_http_server_start(&my_server);
148     EXPECT_EQ(NX_SUCCESS, status);
149 }
150 
151 
152 /* Define the test thread.  */
thread_0_entry(ULONG thread_input)153 void    thread_0_entry(ULONG thread_input)
154 {
155 
156 NX_PACKET   *my_packet;
157 UINT        status;
158 NXD_ADDRESS server_ip_address;
159 UCHAR       buffer[100];
160 ULONG       bytes_received;
161 
162 
163     printf("NetX Test:   Web HTTP Demo Test........................................");
164 
165     /* Create an HTTP client instance.  */
166     status = nx_web_http_client_create(&my_client, "My Client", &ip_0,
167                                                             &pool_0, 600);
168     EXPECT_EQ(NX_SUCCESS, status);
169 
170     /* Prepare to send the simple 5-byte HTML file to the Server.  */
171     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
172     server_ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5);
173     status = nx_web_http_client_put_start(&my_client, &server_ip_address,
174                             "/test.htm", "name", "password", 5, 50);
175 #if 0
176     status = nx_web_http_client_put_start(&my_client, &server_ip_address,
177                             "/test.htm", "", "", 5, 50);
178 #endif
179     EXPECT_EQ(NX_SUCCESS, status);
180 
181     /* Allocate a packet.  */
182     status =  nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET,
183                                                         NX_WAIT_FOREVER);
184     EXPECT_EQ(NX_SUCCESS, status);
185 
186     /* Build a simple 103-byte HTML page.  */
187     nx_packet_data_append(my_packet, "hello", 5, &pool_0, NX_WAIT_FOREVER);
188 
189     /* Complete the PUT by writing the total length.  */
190     status =  nx_web_http_client_put_packet(&my_client, my_packet, 50);
191     EXPECT_EQ(NX_SUCCESS, status);
192 
193     /* Now GET the file back!  */
194     status =  nx_web_http_client_get_start(&my_client, &server_ip_address,
195                     "/test.htm", NX_NULL, 0, "name", "password", 50);
196 #if 0
197     status =  nx_web_http_client_get_start(&my_client, &server_ip_address,
198                     "/test.htm", NX_NULL, 0, "", "", 50);
199 #endif
200     EXPECT_EQ(NX_SUCCESS, status);
201 
202     /* Get a packet.  */
203     status =  nx_web_http_client_get_packet(&my_client, &my_packet, 20);
204     EXPECT_EQ(NX_SUCCESS, status);
205 
206     status = nx_packet_data_extract_offset(my_packet, 0, buffer, 100, &bytes_received);
207     EXPECT_EQ(NX_SUCCESS, status);
208     EXPECT_EQ((UINT)bytes_received, 5);
209     EXPECT_EQ(buffer[0], 'h');
210     EXPECT_EQ(buffer[1], 'e');
211     EXPECT_EQ(buffer[2], 'l');
212     EXPECT_EQ(buffer[3], 'l');
213     EXPECT_EQ(buffer[4], 'o');
214     nx_packet_release(my_packet);
215 
216     /* Flush the media.  */
217     fx_media_flush(&ram_disk);
218 
219     printf("SUCCESS!\n");
220     test_control_return(0);
221 }
222