1 /* This case tests the condition when multi websocket instances are working at the same time. */
2 #include "tx_api.h"
3 #include "nx_api.h"
4
5 extern void test_control_return(UINT);
6
7 #if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN)
8 #include "nx_websocket_client.h"
9 #include "netx_websocket_common_process.c"
10
11 #define DEMO_STACK_SIZE 4096
12 #define PACKET_SIZE 1536
13 #define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024
14
15 /* Define device drivers. */
16 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
17
18 /* ---- Variables for the first instance ---- */
19 static UINT test_done = NX_FALSE;
20
21 static TX_THREAD client_thread;
22 static NX_PACKET_POOL client_pool;
23 static NX_TCP_SOCKET test_client;
24 static NX_IP client_ip;
25
26 static NX_TCP_SOCKET test_server;
27 static NX_PACKET_POOL server_pool;
28 static TX_THREAD server_thread;
29 static NX_IP server_ip;
30 static UINT test_server_start = 0;
31 static UINT test_client_stop = 0;
32
33 /* Set up the websocket global variables */
34 static NX_WEBSOCKET_CLIENT client_websocket;
35 static UCHAR *client_websocket_host;
36 static UINT client_websocket_host_length;
37 static UCHAR *client_websocket_uri_path;
38 static UINT client_websocket_uri_path_length;
39
40
41 static void thread_client_entry(ULONG thread_input);
42 static void thread_server_entry(ULONG thread_input);
43
44 #define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4)
45 #define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5)
46 #define TEST_SERVER_PORT 80
47
48 #define TEST_HOST_NAME "1.2.3.4"
49 #define TEST_URI_PATH "/test"
50 #define TEST_PROTOCOL "test"
51
52 static UCHAR server_switch_101[] =
53 {
54 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, // HTTP1.1/
55 0x31, 0x30, 0x31, 0x20, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x20, // 101 Switching
56 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x0d, 0x0a, // Protocols\r\n
57 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, // Upgrade:
58 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, // WebSocket\r\n
59 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, // Connection:
60 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, // Upgrade\r\n
61 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, // Sec-WebSocket-Protocol:
62 0x74, 0x2d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x3a, 0x20,
63 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, // test
64 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, // Sec-WebSocket-Accept:
65 0x65, 0x74, 0x2d, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
66 0x35, 0x75, 0x31, 0x6c, 0x55, 0x72, 0x32, 0x57, 0x68, 0x70, 0x34, 0x64, 0x44, 0x57, 0x6e, // 5u1lUr2Whp4dDWnskk9JcJZobO0=
67 0x73, 0x6b, 0x6b, 0x39, 0x4a, 0x63, 0x4a, 0x5a, 0x6f, 0x62, 0x4f, 0x30, 0x3d, 0x0d, 0x0a,
68 0x0d, 0x0a,
69 };
70
71 static UCHAR server_response[] =
72 {
73 0x82, 0x04, 0x01, 0x02, 0x03, 0x04,
74 0x82, 0x04, 0x01, 0x02, 0x03, 0x04, // The second frame will be on the processing packet list
75 };
76
77 static UCHAR client_test_data[] =
78 {
79 0x11, 0x22, 0x33, 0x44,
80 };
81
82 /* ---- Variables for the second instance ---- */
83 static UINT test1_done = NX_FALSE;
84
85 static TX_THREAD client1_thread;
86 static NX_TCP_SOCKET test_client1;
87
88 static NX_TCP_SOCKET test_server1;
89 static TX_THREAD server1_thread;
90 static UINT test_server1_start = 0;
91 static UINT test_client1_stop = 0;
92
93 /* Set up the websocket global variables */
94 static NX_WEBSOCKET_CLIENT client1_websocket;
95 static UCHAR *client1_websocket_host;
96 static UINT client1_websocket_host_length;
97 static UCHAR *client1_websocket_uri_path;
98 static UINT client1_websocket_uri_path_length;
99
100 static void thread_client1_entry(ULONG thread_input);
101 static void thread_server1_entry(ULONG thread_input);
102
103 #define TEST_CLIENT1_ADDRESS IP_ADDRESS(1,2,3,6)
104 #define TEST_SERVER1_PORT 81
105
106 #define TEST1_HOST_NAME "1.2.3.5"
107 #define TEST1_URI_PATH "/test"
108 #define TEST1_PROTOCOL "test"
109
110 static UCHAR server1_switch_101[] =
111 {
112 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, // HTTP1.1/
113 0x31, 0x30, 0x31, 0x20, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x20, // 101 Switching
114 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x0d, 0x0a, // Protocols\r\n
115 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, // Upgrade:
116 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, // WebSocket\r\n
117 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, // Connection:
118 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, // Upgrade\r\n
119 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, // Sec-WebSocket-Protocol:
120 0x74, 0x2d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x3a, 0x20,
121 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, // test
122 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, // Sec-WebSocket-Accept:
123 0x65, 0x74, 0x2d, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
124 0x35, 0x75, 0x31, 0x6c, 0x55, 0x72, 0x32, 0x57, 0x68, 0x70, 0x34, 0x64, 0x44, 0x57, 0x6e, // 5u1lUr2Whp4dDWnskk9JcJZobO0=
125 0x73, 0x6b, 0x6b, 0x39, 0x4a, 0x63, 0x4a, 0x5a, 0x6f, 0x62, 0x4f, 0x30, 0x3d, 0x0d, 0x0a,
126 0x0d, 0x0a,
127 };
128
129 static UCHAR server1_response[] =
130 {
131 0x82, 0x04, 0x01, 0x02, 0x03, 0x04,
132 0x82, 0x04, 0x01, 0x02, 0x03, 0x04, // The second frame will be on the processing packet list
133 };
134
135 static UCHAR client1_test_data[] =
136 {
137 0x11, 0x22, 0x33, 0x44,
138 };
139
140 static ULONG error_counter;
141 static ULONG error1_counter;
142
143 extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number);
144
145 #define TEST_LOOP 2
146
147 #ifdef CTEST
test_application_define(void * first_unused_memory)148 VOID test_application_define(void *first_unused_memory)
149 #else
150 void netx_websocket_multi_instance_test_application_define(void *first_unused_memory)
151 #endif
152 {
153 CHAR *pointer;
154 UINT status;
155
156
157 error_counter = 0;
158 error1_counter = 0;
159
160 /* Setup the working pointer. */
161 pointer = (CHAR *) first_unused_memory;
162
163 /* Create a helper thread for the server. */
164 tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0,
165 pointer, DEMO_STACK_SIZE,
166 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
167
168 pointer = pointer + DEMO_STACK_SIZE;
169
170 /* Create a helper thread for the server1. */
171 tx_thread_create(&server1_thread, "Test Server1 thread", thread_server1_entry, 0,
172 pointer, DEMO_STACK_SIZE,
173 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
174
175 pointer = pointer + DEMO_STACK_SIZE;
176
177 /* Initialize the NetX system. */
178 nx_system_initialize();
179
180 /* Create the server packet pool. */
181 status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE,
182 pointer, PACKET_SIZE * 10);
183 pointer = pointer + PACKET_SIZE * 10;
184 if (status)
185 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
186
187 /* Create an IP instance. */
188 status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS,
189 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
190 pointer, 2048, 1);
191 pointer = pointer + 2048;
192 if (status)
193 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
194
195 /* Enable ARP and supply ARP cache memory for the server IP instance. */
196 status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
197 pointer = pointer + 1024;
198 if (status)
199 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
200
201 /* Enable TCP traffic. */
202 status = nx_tcp_enable(&server_ip);
203 if (status)
204 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
205
206 /* Create the Test Client thread. */
207 status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0,
208 pointer, DEMO_STACK_SIZE,
209 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
210 pointer = pointer + DEMO_STACK_SIZE;
211 if (status)
212 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
213
214 /* Create the Test Client1 thread. */
215 status = tx_thread_create(&client1_thread, "Test Client1", thread_client1_entry, 0,
216 pointer, DEMO_STACK_SIZE,
217 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
218 pointer = pointer + DEMO_STACK_SIZE;
219 if (status)
220 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
221
222 /* Create the Client packet pool. */
223 status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE,
224 pointer, PACKET_SIZE * 10);
225 pointer = pointer + PACKET_SIZE * 10;
226 if (status)
227 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
228
229 /* Create an IP instance. */
230 status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS,
231 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
232 pointer, 2048, 1);
233 pointer = pointer + 2048;
234 if (status)
235 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
236
237 status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
238 pointer = pointer + 1024;
239 if (status)
240 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
241
242 /* Enable TCP traffic. */
243 status = nx_tcp_enable(&client_ip);
244 if (status)
245 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
246 }
247
thread_client_entry(ULONG thread_input)248 void thread_client_entry(ULONG thread_input)
249 {
250 UINT i, status;
251 NX_PACKET *packet_ptr;
252 NXD_ADDRESS server_ip_address;
253 UINT code;
254
255 /* Create client socket. */
256 status = nx_tcp_socket_create(&client_ip, &test_client, "Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY,
257 NX_IP_TIME_TO_LIVE, 1000, NX_NULL, NX_NULL);
258 if (status)
259 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
260
261 /* Create WebSocket. */
262 status = nx_websocket_client_create(&client_websocket, (UCHAR *)" ", &client_ip, &client_pool);
263
264 /* Check status. */
265 if (status || client_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
266 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
267
268 /* Give IP task and driver a chance to initialize the system. */
269 tx_thread_sleep(NX_IP_PERIODIC_RATE);
270
271 /* Bind and connect to server. */
272 status = nx_tcp_client_socket_bind(&test_client, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE);
273 if (status)
274 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
275
276 /* Wait test server started. */
277 while(!test_server_start)
278 {
279 tx_thread_sleep(NX_IP_PERIODIC_RATE);
280 }
281
282 /* Set server IP address. */
283 server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS;
284 server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
285
286 /* Connect to the server */
287 status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_WAIT_FOREVER);
288 if (status)
289 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
290
291 /* Upgrade to websocket */
292 status = nx_websocket_client_connect(&client_websocket, &test_client,
293 TEST_HOST_NAME, sizeof(TEST_HOST_NAME) - 1,
294 (UCHAR *)TEST_URI_PATH, sizeof(TEST_URI_PATH) - 1,
295 (UCHAR *)TEST_PROTOCOL, sizeof(TEST_PROTOCOL) - 1,
296 NX_WAIT_FOREVER);
297
298 if (status || client_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
299 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
300 else
301 {
302 status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
303 if (status)
304 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
305
306 /* Append and send data. */
307 status = nx_packet_data_append(packet_ptr, client_test_data, sizeof(client_test_data), &client_pool, NX_IP_PERIODIC_RATE);
308 if (status)
309 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
310 status = nx_websocket_client_send(&client_websocket, packet_ptr, NX_WEBSOCKET_OPCODE_BINARY_FRAME, NX_TRUE, NX_WAIT_FOREVER);
311 if (status || client_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
312 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
313
314 /* Only receive and parse the first frame from server. */
315 status = nx_websocket_client_receive(&client_websocket, &packet_ptr, &code, 5 * NX_IP_PERIODIC_RATE);
316 if (status || client_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
317 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
318 if (packet_ptr -> nx_packet_length != 4)
319 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
320 nx_packet_release(packet_ptr);
321 }
322
323 nx_tcp_client_socket_unbind(&test_client);
324 nx_tcp_socket_delete(&test_client);
325
326 nx_websocket_client_delete(&client_websocket);
327 if (client_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
328 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
329
330 test_done = NX_TRUE;
331 }
332
333 /* Define the helper Test server thread. */
thread_server_entry(ULONG thread_input)334 void thread_server_entry(ULONG thread_input)
335 {
336 UINT i, status;
337 NX_PACKET *packet_ptr;
338
339
340 /* Print out test information banner. */
341 printf("NetX Test: Websocket Multi-instance Test.....................................");
342
343 /* Check for earlier error. */
344 if (error_counter)
345 {
346 printf("ERROR!\n");
347 test_control_return(1);
348 }
349
350 /* Give NetX a chance to initialize the system. */
351 tx_thread_sleep(NX_IP_PERIODIC_RATE);
352
353 status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket",
354 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
355 NX_NULL, NX_NULL);
356
357 status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL);
358 if (status)
359 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
360
361 /* Set the flag. */
362 test_server_start = 1;
363
364 /* Accept a connection from test client. */
365 status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE);
366 if (status)
367 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
368
369 for (i = 0; i < TEST_LOOP; i++)
370 {
371 /* Receive client data. */
372 status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
373 if (status)
374 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
375 else
376 {
377 /* Response data. */
378 switch (i)
379 {
380 case 0:
381 /* Update the value in the field Sec-Protocol-Accept since it is calculated based on a random value */
382 _server_connect_response_process(packet_ptr);
383 memcpy(&server_switch_101[127], connect_key, 28);
384
385 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
386 packet_ptr -> nx_packet_length = 0;
387 nx_packet_data_append(packet_ptr, server_switch_101, sizeof(server_switch_101), &server_pool, NX_IP_PERIODIC_RATE);
388 status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE);
389 if (status)
390 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
391 break;
392 case 1:
393 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
394 packet_ptr -> nx_packet_length = 0;
395 nx_packet_data_append(packet_ptr, server_response, sizeof(server_response), &server_pool, NX_IP_PERIODIC_RATE);
396 status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE);
397 if (status)
398 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
399 break;
400 default:
401 break;
402 }
403 }
404 }
405
406 /* Wait for test done. */
407 while (test_done == NX_FALSE || test1_done == NX_FALSE)
408 {
409 tx_thread_sleep(NX_IP_PERIODIC_RATE);
410 }
411
412 nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT);
413 nx_tcp_socket_delete(&test_server);
414
415 if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
416 {
417 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
418 }
419 else if (client_pool.nx_packet_pool_invalid_releases)
420 {
421 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
422 }
423
424 if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
425 {
426 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
427 }
428
429 if (error_counter || error1_counter)
430 {
431 printf("ERROR!\n");
432 test_control_return(1);
433 }
434 else
435 {
436 printf("SUCCESS!\n");
437 test_control_return(0);
438 }
439 }
440
thread_client1_entry(ULONG thread_input)441 void thread_client1_entry(ULONG thread_input)
442 {
443 UINT i, status;
444 NX_PACKET *packet_ptr;
445 NXD_ADDRESS server_ip_address;
446 UINT code;
447
448 /* Create client socket. */
449 status = nx_tcp_socket_create(&client_ip, &test_client1, "Client1 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY,
450 NX_IP_TIME_TO_LIVE, 1000, NX_NULL, NX_NULL);
451 if (status)
452 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
453
454 /* Create WebSocket. */
455 status = nx_websocket_client_create(&client1_websocket, (UCHAR *)" ", &client_ip, &client_pool);
456
457 /* Check status. */
458 if (status || client1_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
459 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
460
461 /* Give IP task and driver a chance to initialize the system. */
462 tx_thread_sleep(NX_IP_PERIODIC_RATE);
463
464 /* Bind and connect to server. */
465 status = nx_tcp_client_socket_bind(&test_client1, TEST_SERVER1_PORT, NX_IP_PERIODIC_RATE);
466 if (status)
467 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
468
469 /* Wait test server started. */
470 while(!test_server1_start)
471 {
472 tx_thread_sleep(NX_IP_PERIODIC_RATE);
473 }
474
475 /* Set server IP address. */
476 server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS;
477 server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
478
479 /* Connect to the server */
480 status = nxd_tcp_client_socket_connect(&test_client1, &server_ip_address, TEST_SERVER1_PORT, NX_WAIT_FOREVER);
481 if (status)
482 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
483
484 /* Upgrade to websocket */
485 status = nx_websocket_client_connect(&client1_websocket, &test_client1,
486 TEST1_HOST_NAME, sizeof(TEST1_HOST_NAME) - 1,
487 (UCHAR *)TEST1_URI_PATH, sizeof(TEST1_URI_PATH) - 1,
488 (UCHAR *)TEST1_PROTOCOL, sizeof(TEST1_PROTOCOL) - 1,
489 NX_WAIT_FOREVER);
490
491 if (status || client1_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
492 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
493 else
494 {
495 status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
496 if (status)
497 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
498
499 /* Append and send data. */
500 status = nx_packet_data_append(packet_ptr, client1_test_data, sizeof(client1_test_data), &client_pool, NX_IP_PERIODIC_RATE);
501 if (status)
502 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
503 status = nx_websocket_client_send(&client1_websocket, packet_ptr, NX_WEBSOCKET_OPCODE_BINARY_FRAME, NX_TRUE, NX_WAIT_FOREVER);
504 if (status || client1_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
505 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
506
507 /* Only receive and parse the first frame from server. */
508 status = nx_websocket_client_receive(&client1_websocket, &packet_ptr, &code, 5 * NX_IP_PERIODIC_RATE);
509 if (status || client1_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
510 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
511 if (packet_ptr -> nx_packet_length != 4)
512 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
513 nx_packet_release(packet_ptr);
514 }
515
516 nx_tcp_client_socket_unbind(&test_client1);
517 nx_tcp_socket_delete(&test_client1);
518
519 nx_websocket_client_delete(&client1_websocket);
520 if (client1_websocket.nx_websocket_client_mutex.tx_mutex_ownership_count != 0)
521 SET_ERROR_COUNTER(&error1_counter, __FILE__, __LINE__);
522
523 test1_done = NX_TRUE;
524 }
525
526 /* Define the helper Test server thread. */
thread_server1_entry(ULONG thread_input)527 void thread_server1_entry(ULONG thread_input)
528 {
529 UINT i, status;
530 NX_PACKET *packet_ptr;
531
532
533 /* Check for earlier error. */
534 if (error_counter)
535 {
536 printf("ERROR!\n");
537 test_control_return(1);
538 }
539
540 /* Give NetX a chance to initialize the system. */
541 tx_thread_sleep(NX_IP_PERIODIC_RATE);
542
543 status = nx_tcp_socket_create(&server_ip, &test_server1, "Test Server1 Socket",
544 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
545 NX_NULL, NX_NULL);
546
547 status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER1_PORT, &test_server1, 5, NX_NULL);
548 if (status)
549 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
550
551 /* Set the flag. */
552 test_server1_start = 1;
553
554 /* Accept a connection from test client. */
555 status = nx_tcp_server_socket_accept(&test_server1, 5 * NX_IP_PERIODIC_RATE);
556 if (status)
557 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
558
559 for (i = 0; i < TEST_LOOP; i++)
560 {
561 /* Receive client data. */
562 status = nx_tcp_socket_receive(&test_server1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
563 if (status)
564 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
565 else
566 {
567 /* Response data. */
568 switch (i)
569 {
570 case 0:
571 /* Update the value in the field Sec-Protocol-Accept since it is calculated based on a random value */
572 _server_connect_response_process(packet_ptr);
573 memcpy(&server1_switch_101[127], connect_key, 28);
574
575 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
576 packet_ptr -> nx_packet_length = 0;
577 nx_packet_data_append(packet_ptr, server1_switch_101, sizeof(server1_switch_101), &server_pool, NX_IP_PERIODIC_RATE);
578 status = nx_tcp_socket_send(&test_server1, packet_ptr, NX_IP_PERIODIC_RATE);
579 if (status)
580 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
581 break;
582 case 1:
583 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
584 packet_ptr -> nx_packet_length = 0;
585 nx_packet_data_append(packet_ptr, server1_response, sizeof(server1_response), &server_pool, NX_IP_PERIODIC_RATE);
586 status = nx_tcp_socket_send(&test_server1, packet_ptr, NX_IP_PERIODIC_RATE);
587 if (status)
588 SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__);
589 break;
590 default:
591 break;
592 }
593 }
594 }
595
596 /* Wait for test done. */
597 while (test1_done == NX_FALSE)
598 {
599 tx_thread_sleep(NX_IP_PERIODIC_RATE);
600 }
601
602 nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER1_PORT);
603 nx_tcp_socket_delete(&test_server1);
604 }
605
606 #else
607
608 #ifdef CTEST
test_application_define(void * first_unused_memory)609 VOID test_application_define(void *first_unused_memory)
610 #else
611 void netx_websocket_multi_instance_test_application_define(void *first_unused_memory)
612 #endif
613 {
614
615 /* Print out test information banner. */
616 printf("NetX Test: Websocket Multi-instance Test.....................................N/A\n");
617
618 test_control_return(3);
619 }
620 #endif
621
622