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