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