1 /* This case tests RTSP with RTP. */
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 #include    "netxtestcontrol.h"
5 
6 extern void test_control_return(UINT);
7 
8 #if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && (NX_MAX_PHYSICAL_INTERFACES > 1)
9 #include    "nx_rtp_sender.h"
10 #include    "nx_rtsp_server.h"
11 
12 #define     DEMO_STACK_SIZE         4096
13 #define     PACKET_SIZE             1536
14 
15 /* Define device drivers.  */
16 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
17 
18 static UCHAR rtsp_stack[DEMO_STACK_SIZE];
19 
20 static TX_THREAD           client_0_thread;
21 static TX_THREAD           client_1_thread;
22 static NX_PACKET_POOL      client_0_pool;
23 static NX_PACKET_POOL      client_1_pool;
24 static NX_IP               client_0_ip;
25 static NX_IP               client_1_ip;
26 static NX_TCP_SOCKET       rtsp_client_0;
27 static NX_TCP_SOCKET       rtsp_client_1;
28 static NX_UDP_SOCKET       rtp_client_0;
29 static NX_UDP_SOCKET       rtp_client_1;
30 
31 static TX_THREAD           server_thread;
32 static NX_PACKET_POOL      server_pool;
33 static NX_IP               server_ip;
34 static NX_RTSP_SERVER      rtsp_server;
35 static NX_RTP_SENDER       rtp_server;
36 static NX_RTP_SESSION      rtp_session_0;
37 static NX_RTP_SESSION      rtp_session_1;
38 
39 static UINT                error_counter;
40 
41 static TX_SEMAPHORE        semaphore_client_0_start;
42 static TX_SEMAPHORE        semaphore_client_1_start;
43 static TX_SEMAPHORE        semaphore_rtp_send_0;
44 static TX_SEMAPHORE        semaphore_rtp_send_1;
45 static TX_EVENT_FLAGS_GROUP events_play;
46 
47 
48 static void thread_client_0_entry(ULONG thread_input);
49 static void thread_client_1_entry(ULONG thread_input);
50 static void thread_server_entry(ULONG thread_input);
51 static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length);
52 static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr);
53 static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length);
54 static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length);
55 static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length);
56 static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length);
57 static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr);
58 
59 #define TEST_SERVER_ADDRESS    IP_ADDRESS(1,2,3,4)
60 #define TEST_SERVER_1_ADDRESS  IP_ADDRESS(10,3,3,4)
61 #define TEST_CLIENT_0_ADDRESS  IP_ADDRESS(1,2,3,5)
62 #define TEST_CLIENT_1_ADDRESS  IP_ADDRESS(10,3,3,5)
63 #define RTSP_SERVER_PORT       554
64 
65 #define RTSP_0_SESSION_ID    23754311
66 #define RTSP_1_SESSION_ID    23754312
67 #define RTP_0_RTP_PORT       49752
68 #define RTP_0_RTCP_PORT      49753
69 #define RTP_1_RTP_PORT       49754
70 #define RTP_1_RTCP_PORT      49755
71 
72 #define RTP_PAYLOAD_TYPE_0           96
73 #define RTP_PAYLOAD_TYPE_1           97
74 #define RTP_TIMESTAMP_INIT_VALUE     40
75 #define CNAME                        "AzureRTOS@microsoft.com"
76 #define TEST_MSW                     123
77 #define TEST_LSW                     456
78 
79 /* Define events for the server task */
80 #define ALL_EVENTS                   ((ULONG)0xFFFFFFFF)
81 #define PLAY_0_EVENT                 ((ULONG)0x00000001)
82 #define PLAY_1_EVENT                 ((ULONG)0x00000002)
83 #define DONE_0_EVENT                 ((ULONG)0x00000004)
84 #define DONE_1_EVENT                 ((ULONG)0x00000008)
85 
86 static UCHAR rtsp_0_option_request[] = "\
87 OPTIONS rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\
88 CSeq: 2\r\n\
89 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\
90 ";
91 
92 static UCHAR rtsp_1_option_request[] = "\
93 OPTIONS rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\
94 CSeq: 2\r\n\
95 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\
96 ";
97 
98 static UCHAR rtsp_0_describe_request[] = "\
99 DESCRIBE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\
100 CSeq: 3\r\n\
101 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
102 Accept: application/sdp\r\n\r\n\
103 ";
104 
105 static UCHAR rtsp_1_describe_request[] = "\
106 DESCRIBE rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\
107 CSeq: 3\r\n\
108 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
109 Accept: application/sdp\r\n\r\n\
110 ";
111 
112 static UCHAR rtsp_0_setup_request[] = "\
113 SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\
114 CSeq: 4\r\n\
115 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
116 Transport: RTP/AVP;unicast;client_port=49752-49753\r\n\r\n\
117 ";
118 
119 static UCHAR rtsp_1_setup_request[] = "\
120 SETUP rtsp://10.3.3.4:554/live.stream/trackID=1 RTSP/1.0\r\n\
121 CSeq: 4\r\n\
122 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
123 Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\r\n\
124 ";
125 
126 static UCHAR rtsp_0_play_request[] = "\
127 PLAY rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\
128 CSeq: 6\r\n\
129 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
130 Session: 23754311\r\n\
131 Range: npt=0.000-\r\n\r\n\
132 ";
133 
134 static UCHAR rtsp_1_play_request[] = "\
135 PLAY rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\
136 CSeq: 6\r\n\
137 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
138 Session: 23754312\r\n\
139 Range: npt=0.000-\r\n\r\n\
140 ";
141 
142 static UCHAR rtsp_0_pause_request[] = "\
143 PAUSE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\
144 CSeq: 7\r\n\
145 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
146 Session: 23754311\r\n\r\n\
147 ";
148 
149 static UCHAR rtsp_1_pause_request[] = "\
150 PAUSE rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\
151 CSeq: 7\r\n\
152 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
153 Session: 23754312\r\n\r\n\
154 ";
155 
156 static UCHAR rtsp_0_teardown_request[] = "\
157 TEARDOWN rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\
158 CSeq: 8\r\n\
159 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
160 Session: 23754311\r\n\r\n\
161 ";
162 
163 static UCHAR rtsp_1_teardown_request[] = "\
164 TEARDOWN rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\
165 CSeq: 8\r\n\
166 User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\
167 Session: 23754312\r\n\r\n\
168 ";
169 
170 typedef enum
171 {
172     OPTION_INDEX,
173     DESCRIBE_INDEX,
174     SETUP_INDEX,
175     PLAY_INDEX,
176     TEARDOWN_INDEX
177 }REQUEST_INDEX;
178 
179 static UCHAR *client_0_rtsp_request_list[] =
180 {
181 rtsp_0_option_request,
182 rtsp_0_describe_request,
183 rtsp_0_setup_request,
184 rtsp_0_play_request,
185 rtsp_0_teardown_request,
186 };
187 
188 static UCHAR *client_1_rtsp_request_list[] =
189 {
190 rtsp_1_option_request,
191 rtsp_1_describe_request,
192 rtsp_1_setup_request,
193 rtsp_1_play_request,
194 rtsp_1_teardown_request,
195 };
196 
197 static UINT client_0_rtsp_request_size[] =
198 {
199 sizeof(rtsp_0_option_request) - 1,
200 sizeof(rtsp_0_describe_request) - 1,
201 sizeof(rtsp_0_setup_request) - 1,
202 sizeof(rtsp_0_play_request) - 1,
203 sizeof(rtsp_0_teardown_request) - 1,
204 };
205 
206 static UINT client_1_rtsp_request_size[] =
207 {
208 sizeof(rtsp_1_option_request) - 1,
209 sizeof(rtsp_1_describe_request) - 1,
210 sizeof(rtsp_1_setup_request) - 1,
211 sizeof(rtsp_1_play_request) - 1,
212 sizeof(rtsp_1_teardown_request) - 1,
213 };
214 
215 static UINT client_0_rtsp_request_num = sizeof(client_0_rtsp_request_size) / sizeof(UINT);
216 static UINT client_1_rtsp_request_num = sizeof(client_1_rtsp_request_size) / sizeof(UINT);
217 
218 static UCHAR rtp_data[] = "rtp data for test";
219 
220 static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\
221 m=video 0 RTP/AVP 96\r\n\
222 a=rtpmap:96 H264/90000\r\n\
223 a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\
224 a=control:trackID=0\r\n\
225 m=audio 0 RTP/AVP 97\r\n\
226 a=rtpmap:97 mpeg4-generic/44100/1\r\n\
227 a=fmtp:97 SizeLength=13\r\n\
228 a=control:trackID=1\r\n";
229 
230 static UINT seq_0 = 0, seq_1 = 0;
231 
232 #ifdef CTEST
test_application_define(void * first_unused_memory)233 VOID test_application_define(void *first_unused_memory)
234 #else
235 void    netx_rtp_multi_interfaces_test_application_define(void *first_unused_memory)
236 #endif
237 {
238 CHAR    *pointer;
239 UINT    status;
240 
241 
242     error_counter = 0;
243 
244     /* Setup the working pointer.  */
245     pointer =  (CHAR *) first_unused_memory;
246 
247     /* Create a helper thread for the server. */
248     tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0,
249                      pointer, DEMO_STACK_SIZE,
250                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
251 
252     pointer =  pointer + DEMO_STACK_SIZE;
253 
254     /* Initialize the NetX system.  */
255     nx_system_initialize();
256 
257     /* Create the server packet pool.  */
258     status =  nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE,
259                                     pointer, PACKET_SIZE * 8);
260     pointer = pointer + PACKET_SIZE * 8;
261     CHECK_STATUS(0, status);
262 
263     /* Create an IP instance.  */
264     status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS,
265                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
266                           pointer, 2048, 1);
267     pointer =  pointer + 2048;
268     CHECK_STATUS(0, status);
269 
270     /* Attach a new ip interface to server ip. */
271     status = nx_ip_interface_attach(&server_ip, "Test Server IP 1 Interface", TEST_SERVER_1_ADDRESS,
272                                     0xFFFFFF00UL, _nx_ram_network_driver_1024);
273     pointer = pointer + 2048;
274     CHECK_STATUS(0, status);
275 
276     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
277     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
278     pointer = pointer + 1024;
279     CHECK_STATUS(0, status);
280 
281 
282      /* Enable TCP traffic.  */
283     status = nx_tcp_enable(&server_ip);
284     CHECK_STATUS(0, status);
285 
286     /* Enable UDP processing for both IP instances.  */
287     status = nx_udp_enable(&server_ip);
288     CHECK_STATUS(0, status);
289 
290     /* Create the Test Client thread. */
291     status = tx_thread_create(&client_0_thread, "Test Client 0", thread_client_0_entry, 0,
292                               pointer, DEMO_STACK_SIZE,
293                               6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
294     pointer =  pointer + DEMO_STACK_SIZE;
295     CHECK_STATUS(0, status);
296     status = tx_thread_create(&client_1_thread, "Test Client 1", thread_client_1_entry, 0,
297                               pointer, DEMO_STACK_SIZE,
298                               6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
299     pointer =  pointer + DEMO_STACK_SIZE;
300     CHECK_STATUS(0, status);
301 
302     /* Create the Client packet pool.  */
303     status =  nx_packet_pool_create(&client_0_pool, "Test Client Packet Pool", PACKET_SIZE,
304                                     pointer, PACKET_SIZE * 8);
305     pointer = pointer + PACKET_SIZE * 8;
306     CHECK_STATUS(0, status);
307     status =  nx_packet_pool_create(&client_1_pool, "Test Client Packet Pool", PACKET_SIZE,
308                                     pointer, PACKET_SIZE * 8);
309     pointer = pointer + PACKET_SIZE * 8;
310     CHECK_STATUS(0, status);
311 
312     /* Create an IP instance.  */
313     status = nx_ip_create(&client_0_ip, "Test Client IP 0", TEST_CLIENT_0_ADDRESS,
314                           0xFFFFFF00UL, &client_0_pool, _nx_ram_network_driver_1024,
315                           pointer, 2048, 1);
316     pointer =  pointer + 2048;
317     CHECK_STATUS(0, status);
318 
319     /* Create an IP instance.  */
320     status = nx_ip_create(&client_1_ip, "Test Client IP 1", TEST_CLIENT_1_ADDRESS,
321                           0xFFFFFF00UL, &client_1_pool, _nx_ram_network_driver_1024,
322                           pointer, 2048, 1);
323     pointer =  pointer + 2048;
324     CHECK_STATUS(0, status);
325 
326     /* Enable arp */
327     status  = nx_arp_enable(&client_0_ip, (void *) pointer, 1024);
328     pointer =  pointer + 1024;
329     CHECK_STATUS(0, status);
330     status  = nx_arp_enable(&client_1_ip, (void *) pointer, 1024);
331     pointer =  pointer + 1024;
332     CHECK_STATUS(0, status);
333 
334     /* Enable TCP traffic.  */
335     status = nx_tcp_enable(&client_0_ip);
336     CHECK_STATUS(0, status);
337     status = nx_tcp_enable(&client_1_ip);
338     CHECK_STATUS(0, status);
339 
340     /* Enable UDP processing for both IP instances.  */
341     status = nx_udp_enable(&client_0_ip);
342     CHECK_STATUS(0, status);
343     status = nx_udp_enable(&client_1_ip);
344     CHECK_STATUS(0, status);
345 
346     /* Create semaphores and events group.  */
347     tx_semaphore_create(&semaphore_client_0_start, "semaphore client 0 start", 0);
348     tx_semaphore_create(&semaphore_client_1_start, "semaphore client 1 start", 0);
349     tx_semaphore_create(&semaphore_rtp_send_0, "semaphore rtp send 0", 0);
350     tx_semaphore_create(&semaphore_rtp_send_1, "semaphore rtp send 1", 0);
351     status = tx_event_flags_create(&events_play, "events play");
352     CHECK_STATUS(0, status);
353 }
354 
thread_client_0_entry(ULONG thread_input)355 void thread_client_0_entry(ULONG thread_input)
356 {
357 UINT            i, status;
358 NX_PACKET       *packet_ptr;
359 NXD_ADDRESS     server_ip_address;
360 UCHAR           *buffer_ptr;
361 UCHAR           temp_string[256];
362 
363 
364     /* Give IP task and driver a chance to initialize the system.  */
365     tx_thread_sleep(NX_IP_PERIODIC_RATE);
366 
367     /* Set server IP address.  */
368     server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS;
369     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
370 
371     status = nx_tcp_socket_create(&client_0_ip, &rtsp_client_0, "Test Client 0 Socket",
372                                   NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
373                                   NX_NULL, NX_NULL);
374     CHECK_STATUS(0, status);
375 
376     /* Bind and connect to server.  */
377     status = nx_tcp_client_socket_bind(&rtsp_client_0, NX_ANY_PORT, NX_IP_PERIODIC_RATE);
378     CHECK_STATUS(0, status);
379 
380     /* Create the rtp client socket.  */
381     status = nx_udp_socket_create(&client_0_ip, &rtp_client_0, "RTCP Client 0 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
382     CHECK_STATUS(0, status);
383 
384     status =  nx_udp_socket_bind(&rtp_client_0, RTP_0_RTP_PORT, NX_IP_PERIODIC_RATE);
385     CHECK_STATUS(0, status);
386 
387     /* Wait test server started.  */
388     tx_semaphore_get(&semaphore_client_0_start, NX_WAIT_FOREVER);
389 
390     status = nxd_tcp_client_socket_connect(&rtsp_client_0, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE);
391     CHECK_STATUS(0, status);
392 
393     for ( i = 0; i < client_0_rtsp_request_num; i++)
394     {
395 
396         /* Send RTSP request data.  */
397         status = nx_packet_allocate(&client_0_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
398         CHECK_STATUS(0, status);
399 
400         status = nx_packet_data_append(packet_ptr, client_0_rtsp_request_list[i], client_0_rtsp_request_size[i], &client_0_pool, NX_IP_PERIODIC_RATE);
401         CHECK_STATUS(0, status);
402 
403         status = nx_tcp_socket_send(&rtsp_client_0, packet_ptr, NX_IP_PERIODIC_RATE);
404         CHECK_STATUS(0, status);
405 
406         /* Receive the response from RTSP server.  */
407         status = nx_tcp_socket_receive(&rtsp_client_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
408         CHECK_STATUS(0, status);
409 
410         /* Check response status code.  */
411         status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1);
412         CHECK_STATUS(0, status);
413 
414         /* Terminate the string.  */
415         *(packet_ptr -> nx_packet_append_ptr) = NX_NULL;
416         memset(temp_string, 0, sizeof(temp_string));
417 
418         if (i == DESCRIBE_INDEX)
419         {
420 
421             /* Check the SDP.  */
422             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n");
423             if (buffer_ptr == NX_NULL)
424             {
425                 error_counter++;
426                 CHECK_STATUS(0, error_counter);
427             }
428 
429             status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1);
430             CHECK_STATUS(0, status);
431 
432             nx_packet_release(packet_ptr);
433         }
434         else if (i == SETUP_INDEX)
435         {
436 
437             sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld",
438                     RTP_0_RTP_PORT, RTP_0_RTCP_PORT,
439                     rtp_server.nx_rtp_sender_rtp_port,
440                     rtp_server.nx_rtp_sender_rtcp_port,
441                     rtp_session_0.nx_rtp_session_ssrc);
442 
443             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport");
444             if (buffer_ptr == NX_NULL)
445             {
446                 error_counter++;
447                 CHECK_STATUS(0, error_counter);
448             }
449 
450             status = memcmp(buffer_ptr, temp_string, strlen(temp_string));
451             CHECK_STATUS(0, status);
452 
453             nx_packet_release(packet_ptr);
454         }
455         else if (i == PLAY_INDEX)
456         {
457 
458             sprintf(temp_string,
459                     "RTP-Info: url=rtsp://1.2.3.4:554/live.stream/trackID=0;seq=%d;rtptime=%d",
460                     seq_0, RTP_TIMESTAMP_INIT_VALUE);
461 
462             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info");
463             if (buffer_ptr == NX_NULL)
464             {
465                 error_counter++;
466                 CHECK_STATUS(0, error_counter);
467             }
468 
469             status = memcmp(buffer_ptr, temp_string, strlen(temp_string));
470             CHECK_STATUS(0, status);
471 
472             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range");
473             if (buffer_ptr == NX_NULL)
474             {
475                 error_counter++;
476                 CHECK_STATUS(0, error_counter);
477             }
478 
479             status = memcmp(buffer_ptr, "Range: npt=0.0-", sizeof("Range: npt=0.0-") - 1);
480             CHECK_STATUS(0, status);
481 
482             nx_packet_release(packet_ptr);
483 
484             tx_semaphore_get(&semaphore_rtp_send_0, NX_WAIT_FOREVER);
485 
486             /* Receive rtp data packet. */
487             status = nx_udp_socket_receive(&rtp_client_0, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND);
488             CHECK_STATUS(0, status);
489 
490             status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1);
491             CHECK_STATUS(0, status);
492 
493             nx_packet_release(packet_ptr);
494         }
495         else
496         {
497             nx_packet_release(packet_ptr);
498         }
499     }
500 
501     nx_tcp_socket_disconnect(&rtsp_client_0, NX_IP_PERIODIC_RATE);
502 
503     /* Set the flag.  */
504     tx_event_flags_set(&events_play, DONE_0_EVENT, TX_OR);
505     nx_tcp_client_socket_unbind(&rtsp_client_0);
506     nx_tcp_socket_delete(&rtsp_client_0);
507 }
508 
thread_client_1_entry(ULONG thread_input)509 void thread_client_1_entry(ULONG thread_input)
510 {
511 UINT            i, status;
512 NX_PACKET       *packet_ptr;
513 NXD_ADDRESS     server_ip_address;
514 UCHAR           *buffer_ptr;
515 UCHAR           temp_string[256];
516 
517 
518     /* Give IP task and driver a chance to initialize the system.  */
519     tx_thread_sleep(NX_IP_PERIODIC_RATE);
520 
521     /* Set server IP address.  */
522     server_ip_address.nxd_ip_address.v4 = TEST_SERVER_1_ADDRESS;
523     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
524 
525     status = nx_tcp_socket_create(&client_1_ip, &rtsp_client_1, "Test Client 1 Socket",
526                                   NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
527                                   NX_NULL, NX_NULL);
528     CHECK_STATUS(0, status);
529 
530     /* Bind and connect to server.  */
531     status = nx_tcp_client_socket_bind(&rtsp_client_1, NX_ANY_PORT, NX_IP_PERIODIC_RATE);
532     CHECK_STATUS(0, status);
533 
534     /* Create the rtp client socket.  */
535     status = nx_udp_socket_create(&client_1_ip, &rtp_client_1, "RTCP Client 1 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
536     CHECK_STATUS(0, status);
537 
538     status =  nx_udp_socket_bind(&rtp_client_1, RTP_1_RTP_PORT, NX_IP_PERIODIC_RATE);
539     CHECK_STATUS(0, status);
540 
541     /* Wait test server started.  */
542     tx_semaphore_get(&semaphore_client_1_start, NX_WAIT_FOREVER);
543 
544     status = nxd_tcp_client_socket_connect(&rtsp_client_1, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE);
545     CHECK_STATUS(0, status);
546 
547     for ( i = 0; i < client_1_rtsp_request_num; i++)
548     {
549 
550         /* Send RTSP request data.  */
551         status = nx_packet_allocate(&client_1_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
552         CHECK_STATUS(0, status);
553 
554         status = nx_packet_data_append(packet_ptr, client_1_rtsp_request_list[i], client_1_rtsp_request_size[i], &client_1_pool, NX_IP_PERIODIC_RATE);
555         CHECK_STATUS(0, status);
556 
557         status = nx_tcp_socket_send(&rtsp_client_1, packet_ptr, NX_IP_PERIODIC_RATE);
558         CHECK_STATUS(0, status);
559 
560         /* Receive the response from RTSP server.  */
561         status = nx_tcp_socket_receive(&rtsp_client_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
562         CHECK_STATUS(0, status);
563 
564         /* Check response status code.  */
565         status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1);
566         CHECK_STATUS(0, status);
567 
568         /* Terminate the string.  */
569         *(packet_ptr -> nx_packet_append_ptr) = NX_NULL;
570         memset(temp_string, 0, sizeof(temp_string));
571 
572         if (i == DESCRIBE_INDEX)
573         {
574 
575             /* Check the SDP.  */
576             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n");
577             if (buffer_ptr == NX_NULL)
578             {
579                 error_counter++;
580                 CHECK_STATUS(0, error_counter);
581             }
582 
583             status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1);
584             CHECK_STATUS(0, status);
585 
586             nx_packet_release(packet_ptr);
587         }
588         else if (i == SETUP_INDEX)
589         {
590 
591             sprintf(temp_string, "Transport: RTP/AVP;unicast;source=10.3.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld",
592                     RTP_1_RTP_PORT, RTP_1_RTCP_PORT,
593                     rtp_server.nx_rtp_sender_rtp_port,
594                     rtp_server.nx_rtp_sender_rtcp_port,
595                     rtp_session_1.nx_rtp_session_ssrc);
596 
597             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport");
598             if (buffer_ptr == NX_NULL)
599             {
600                 error_counter++;
601                 CHECK_STATUS(0, error_counter);
602             }
603 
604             status = memcmp(buffer_ptr, temp_string, strlen(temp_string));
605             CHECK_STATUS(0, status);
606 
607             nx_packet_release(packet_ptr);
608         }
609         else if (i == PLAY_INDEX)
610         {
611 
612             sprintf(temp_string,
613                     "RTP-Info: url=rtsp://10.3.3.4:554/live.stream/trackID=1;seq=%d;rtptime=%d",
614                     seq_1, RTP_TIMESTAMP_INIT_VALUE);
615 
616             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info");
617             if (buffer_ptr == NX_NULL)
618             {
619                 error_counter++;
620                 CHECK_STATUS(0, error_counter);
621             }
622 
623             status = memcmp(buffer_ptr, temp_string, strlen(temp_string));
624             CHECK_STATUS(0, status);
625 
626             buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range");
627             if (buffer_ptr == NX_NULL)
628             {
629                 error_counter++;
630                 CHECK_STATUS(0, error_counter);
631             }
632 
633             status = memcmp(buffer_ptr, "Range: npt=0.0-", sizeof("Range: npt=0.0-") - 1);
634             CHECK_STATUS(0, status);
635 
636             nx_packet_release(packet_ptr);
637 
638             tx_semaphore_get(&semaphore_rtp_send_1, NX_WAIT_FOREVER);
639 
640             /* Receive rtp data packet. */
641             status = nx_udp_socket_receive(&rtp_client_1, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND);
642             CHECK_STATUS(0, status);
643 
644             status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1);
645             CHECK_STATUS(0, status);
646 
647             nx_packet_release(packet_ptr);
648         }
649         else
650         {
651             nx_packet_release(packet_ptr);
652         }
653     }
654 
655     nx_tcp_socket_disconnect(&rtsp_client_1, NX_IP_PERIODIC_RATE);
656 
657     /* Set the flag.  */
658     tx_event_flags_set(&events_play, DONE_1_EVENT, TX_OR);
659     nx_tcp_client_socket_unbind(&rtsp_client_1);
660     nx_tcp_socket_delete(&rtsp_client_1);
661 }
662 
663 /* Define the helper Test server thread.  */
thread_server_entry(ULONG thread_input)664 void    thread_server_entry(ULONG thread_input)
665 {
666 UINT status;
667 NX_PACKET *packet_ptr;
668 ULONG events = 0;
669 USHORT client_0_done = NX_FALSE;
670 USHORT client_1_done = NX_FALSE;
671 
672     /* Print out test information banner.  */
673     printf("NetX Test:   RTSP RTP Multi Interfaces Test.......................................");
674 
675     /* Check for earlier error.  */
676     if (error_counter)
677     {
678         printf("ERROR!\n");
679         test_control_return(1);
680     }
681 
682     /* Give NetX a chance to initialize the system.  */
683     tx_thread_sleep(NX_IP_PERIODIC_RATE);
684 
685     /* Create RTSP server.  */
686     status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback);
687     CHECK_STATUS(0, status);
688 
689     status = nx_rtsp_server_delete(&rtsp_server);
690     CHECK_STATUS(0, status);
691 
692     status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback);
693     CHECK_STATUS(0, status);
694 
695     /* Set callback functions. */
696     nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback);
697     nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback);
698     nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback);
699     nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback);
700     nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback);
701     nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback);
702 
703     /* Start RTSP server. */
704     status = nx_rtsp_server_start(&rtsp_server);
705     CHECK_STATUS(0, status);
706 
707     status = nx_rtsp_server_stop(&rtsp_server);
708     CHECK_STATUS(0, status);
709 
710     status = nx_rtsp_server_start(&rtsp_server);
711     CHECK_STATUS(0, status);
712 
713     /* Create RTP sender.  */
714     status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1);
715     CHECK_STATUS(0, status);
716 
717     tx_semaphore_put(&semaphore_client_0_start);
718     tx_semaphore_put(&semaphore_client_1_start);
719 
720     while ((client_0_done) == (NX_FALSE) || (client_1_done == NX_FALSE))
721     {
722 
723         /* Wait for events to do */
724         tx_event_flags_get(&events_play, ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER);
725 
726         if (events & PLAY_0_EVENT)
727         {
728 
729             /* Allocate a packet */
730             status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
731             CHECK_STATUS(0, status);
732 
733             /* Copy payload data into the packet. */
734             status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE);
735             CHECK_STATUS(0, status);
736 
737             /* Send packet.  */
738             status = nx_rtp_sender_session_packet_send(&rtp_session_0, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1);
739             CHECK_STATUS(0, status);
740 
741             tx_semaphore_put(&semaphore_rtp_send_0);
742         }
743 
744         if (events & PLAY_1_EVENT)
745         {
746 
747             /* Allocate a packet */
748             status = nx_rtp_sender_session_packet_allocate(&rtp_session_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
749             CHECK_STATUS(0, status);
750 
751             /* Copy payload data into the packet. */
752             status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE);
753             CHECK_STATUS(0, status);
754 
755             /* Send packet.  */
756             status = nx_rtp_sender_session_packet_send(&rtp_session_1, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1);
757             CHECK_STATUS(0, status);
758 
759             tx_semaphore_put(&semaphore_rtp_send_1);
760         }
761 
762         if (events & DONE_0_EVENT)
763         {
764             client_0_done = NX_TRUE;
765         }
766 
767         if (events & DONE_1_EVENT)
768         {
769             client_1_done = NX_TRUE;
770         }
771     }
772 
773     /* Stop and delete rtsp server */
774     status = nx_rtsp_server_stop(&rtsp_server);
775     CHECK_STATUS(0, status);
776     status = nx_rtsp_server_delete(&rtsp_server);
777     CHECK_STATUS(0, status);
778 
779     /* Check packet pool.  */
780     CHECK_STATUS(server_pool.nx_packet_pool_available, server_pool.nx_packet_pool_total);
781     CHECK_STATUS(client_0_pool.nx_packet_pool_available, client_0_pool.nx_packet_pool_total);
782     CHECK_STATUS(client_1_pool.nx_packet_pool_available, client_1_pool.nx_packet_pool_total);
783 
784     if (error_counter)
785     {
786         printf("ERROR!\n");
787         test_control_return(1);
788     }
789     else
790     {
791         printf("SUCCESS!\n");
792         test_control_return(0);
793     }
794 }
795 
rtsp_describe_callback(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length)796 static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length)
797 {
798 UINT status;
799 
800     status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp));
801     return(status);
802 }
803 
rtsp_setup_callback(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,NX_RTSP_TRANSPORT * transport_ptr)804 static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr)
805 {
806 UINT status;
807 UINT rtp_port, rtcp_port;
808 
809     /* Get the created and found ports */
810     status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port);
811     if (status)
812     {
813         return(status);
814     }
815     transport_ptr -> server_rtp_port = rtp_port;
816     transport_ptr -> server_rtcp_port = rtcp_port;
817 
818     if (strstr(uri, "trackID=0"))
819     {
820         /* Setup rtp sender session */
821         status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_0, RTP_PAYLOAD_TYPE_0,
822                                               transport_ptr -> interface_index, &(transport_ptr -> client_ip_address),
823                                               transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port);
824         CHECK_STATUS(0, status);
825 
826         /* Obtain generated ssrc */
827         status = nx_rtp_sender_session_ssrc_get(&rtp_session_0, &(transport_ptr -> rtp_ssrc));
828         CHECK_STATUS(0, status);
829 
830         /* Set static session ID for test.  */
831         rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_0_SESSION_ID;
832     }
833     else if (strstr(uri, "trackID=1"))
834     {
835         /* Setup rtp sender session */
836         status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_1, RTP_PAYLOAD_TYPE_1,
837                                               transport_ptr -> interface_index, &(transport_ptr -> client_ip_address),
838                                               transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port);
839         CHECK_STATUS(0, status);
840 
841         /* Obtain generated ssrc */
842         status = nx_rtp_sender_session_ssrc_get(&rtp_session_1, &(transport_ptr -> rtp_ssrc));
843         CHECK_STATUS(0, status);
844 
845         /* Set static session ID for test.  */
846         rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_1_SESSION_ID;
847     }
848     else
849     {
850         status = NX_RTSP_SERVER_INVALID_REQUEST;
851     }
852 
853     return(status);
854 }
855 
rtsp_play_callback(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * range_ptr,UINT range_length)856 static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length)
857 {
858 UINT status;
859 
860 
861     if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr
862         == &(server_ip.nx_ip_interface[0]))
863     {
864 
865         /* Retrieve the sequence number through rtp sender functions */
866         nx_rtp_sender_session_sequence_number_get(&rtp_session_0, &seq_0);
867 
868         status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, seq_0, RTP_TIMESTAMP_INIT_VALUE);
869         CHECK_STATUS(0, status);
870 
871         status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 0, 30000);
872         CHECK_STATUS(0, status);
873 
874         tx_event_flags_set(&events_play, PLAY_0_EVENT, TX_OR);
875     }
876     else if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr
877              == &(server_ip.nx_ip_interface[1]))
878     {
879 
880         /* Retrieve the sequence number through rtp sender functions */
881         nx_rtp_sender_session_sequence_number_get(&rtp_session_1, &seq_1);
882 
883         status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=1", sizeof("trackID=1") - 1, seq_1, RTP_TIMESTAMP_INIT_VALUE);
884         CHECK_STATUS(0, status);
885 
886         tx_event_flags_set(&events_play, PLAY_1_EVENT, TX_OR);
887     }
888     else
889     {
890         status = NX_RTSP_SERVER_INVALID_REQUEST;
891     }
892 
893     return(status);
894 }
895 
rtsp_teardown_callback(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length)896 static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length)
897 {
898 
899     if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr
900         == &(server_ip.nx_ip_interface[0]))
901     {
902         nx_rtp_sender_session_delete(&rtp_session_0);
903     }
904     else if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr
905              == &(server_ip.nx_ip_interface[1]))
906     {
907         nx_rtp_sender_session_delete(&rtp_session_1);
908     }
909     else
910     {
911         return(NX_RTSP_SERVER_INVALID_REQUEST);
912     }
913 
914     return(NX_SUCCESS);
915 }
916 
rtsp_pause_callback(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * range_ptr,UINT range_length)917 static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length)
918 {
919     return(NX_SUCCESS);
920 }
921 
rtsp_set_parameter_callback(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * parameter_ptr,ULONG parameter_length)922 static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length)
923 {
924     return(NX_SUCCESS);
925 }
926 
rtsp_disconnect_callback(NX_RTSP_CLIENT * rtsp_client_ptr)927 static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr)
928 {
929     return(NX_SUCCESS);
930 }
931 
932 
933 #else
934 
935 #ifdef CTEST
test_application_define(void * first_unused_memory)936 VOID test_application_define(void *first_unused_memory)
937 #else
938 void    netx_rtp_multi_interfaces_test_application_define(void *first_unused_memory)
939 #endif
940 {
941 
942     /* Print out test information banner.  */
943     printf("NetX Test:   RTSP RTP Multi Interfaces Test.......................................N/A\n");
944 
945     test_control_return(3);
946 }
947 #endif
948 
949