tests: Test to setup two sessions on one connection
[platform/upstream/gstreamer.git] / tests / check / gst / rtspserver.c
1 /* GStreamer
2  *
3  * unit test for GstRTSPServer
4  *
5  * Copyright (C) 2012 Axis Communications <dev-gstreamer at axis dot com>
6  * @author David Svensson Fors <davidsf at axis dot com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include <gst/check/gstcheck.h>
25 #include <gst/sdp/gstsdpmessage.h>
26 #include <gst/rtp/gstrtpbuffer.h>
27 #include <gst/rtp/gstrtcpbuffer.h>
28
29 #include <stdio.h>
30 #include <netinet/in.h>
31
32 #include "rtsp-server.h"
33
34 #define VIDEO_PIPELINE "videotestsrc ! " \
35   "video/x-raw,width=352,height=288 ! " \
36   "rtpgstpay name=pay0 pt=96"
37 #define AUDIO_PIPELINE "audiotestsrc ! " \
38   "audio/x-raw,rate=8000 ! " \
39   "rtpgstpay name=pay1 pt=97"
40
41 #define TEST_MOUNT_POINT  "/test"
42 #define TEST_PROTO        "RTP/AVP"
43 #define TEST_PROTO_TCP    "RTP/AVP/TCP"
44 #define TEST_ENCODING     "X-GST"
45 #define TEST_CLOCK_RATE   "90000"
46
47 /* tested rtsp server */
48 static GstRTSPServer *server = NULL;
49
50 /* tcp port that the test server listens for rtsp requests on */
51 static gint test_port = 0;
52
53 /* id of the server's source within the GMainContext */
54 static guint source_id;
55
56 /* iterate the default main loop until there are no events to dispatch */
57 static void
58 iterate (void)
59 {
60   while (g_main_context_iteration (NULL, FALSE)) {
61     GST_DEBUG ("iteration");
62   }
63 }
64
65 static void
66 get_client_ports_full (GstRTSPRange * range, GSocket ** rtp_socket,
67     GSocket ** rtcp_socket)
68 {
69   GSocket *rtp = NULL;
70   GSocket *rtcp = NULL;
71   gint rtp_port = 0;
72   gint rtcp_port;
73   GInetAddress *anyaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
74   GSocketAddress *sockaddr;
75   gboolean bound;
76
77   for (;;) {
78     if (rtp_port != 0)
79       rtp_port += 2;
80
81     rtp = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
82         G_SOCKET_PROTOCOL_UDP, NULL);
83     fail_unless (rtp != NULL);
84
85     sockaddr = g_inet_socket_address_new (anyaddr, rtp_port);
86     fail_unless (sockaddr != NULL);
87     bound = g_socket_bind (rtp, sockaddr, FALSE, NULL);
88     g_object_unref (sockaddr);
89     if (!bound) {
90       g_object_unref (rtp);
91       continue;
92     }
93
94     sockaddr = g_socket_get_local_address (rtp, NULL);
95     fail_unless (sockaddr != NULL && G_IS_INET_SOCKET_ADDRESS (sockaddr));
96     rtp_port =
97         g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (sockaddr));
98     g_object_unref (sockaddr);
99
100     if (rtp_port % 2 != 0) {
101       rtp_port += 1;
102       g_object_unref (rtp);
103       continue;
104     }
105
106     rtcp_port = rtp_port + 1;
107
108     rtcp = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
109         G_SOCKET_PROTOCOL_UDP, NULL);
110     fail_unless (rtcp != NULL);
111
112     sockaddr = g_inet_socket_address_new (anyaddr, rtcp_port);
113     fail_unless (sockaddr != NULL);
114     bound = g_socket_bind (rtcp, sockaddr, FALSE, NULL);
115     g_object_unref (sockaddr);
116     if (!bound) {
117       g_object_unref (rtp);
118       g_object_unref (rtcp);
119       continue;
120     }
121
122     sockaddr = g_socket_get_local_address (rtcp, NULL);
123     fail_unless (sockaddr != NULL && G_IS_INET_SOCKET_ADDRESS (sockaddr));
124     fail_unless (rtcp_port ==
125         g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (sockaddr)));
126     g_object_unref (sockaddr);
127
128     break;
129   }
130
131   range->min = rtp_port;
132   range->max = rtcp_port;
133   if (rtp_socket)
134     *rtp_socket = rtp;
135   else
136     g_object_unref (rtp);
137   if (rtcp_socket)
138     *rtcp_socket = rtcp;
139   else
140     g_object_unref (rtcp);
141   GST_DEBUG ("client_port=%d-%d", range->min, range->max);
142   g_object_unref (anyaddr);
143 }
144
145 /* get a free rtp/rtcp client port pair */
146 static void
147 get_client_ports (GstRTSPRange * range)
148 {
149   get_client_ports_full (range, NULL, NULL);
150 }
151
152 /* start the tested rtsp server */
153 static void
154 start_server (void)
155 {
156   GstRTSPMountPoints *mounts;
157   gchar *service;
158   GstRTSPMediaFactory *factory;
159
160   mounts = gst_rtsp_server_get_mount_points (server);
161
162   factory = gst_rtsp_media_factory_new ();
163
164   gst_rtsp_media_factory_set_launch (factory,
165       "( " VIDEO_PIPELINE "  " AUDIO_PIPELINE " )");
166   gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
167   g_object_unref (mounts);
168
169   /* set port to any */
170   gst_rtsp_server_set_service (server, "0");
171
172   /* attach to default main context */
173   source_id = gst_rtsp_server_attach (server, NULL);
174   fail_if (source_id == 0);
175
176   /* get port */
177   service = gst_rtsp_server_get_service (server);
178   test_port = atoi (service);
179   fail_unless (test_port != 0);
180   g_free (service);
181
182   GST_DEBUG ("rtsp server listening on port %d", test_port);
183 }
184
185 /* stop the tested rtsp server */
186 static void
187 stop_server (void)
188 {
189   g_source_remove (source_id);
190   source_id = 0;
191
192   GST_DEBUG ("rtsp server stopped");
193 }
194
195 /* create an rtsp connection to the server on test_port */
196 static GstRTSPConnection *
197 connect_to_server (gint port, const gchar * mount_point)
198 {
199   GstRTSPConnection *conn = NULL;
200   gchar *address;
201   gchar *uri_string;
202   GstRTSPUrl *url = NULL;
203
204   address = gst_rtsp_server_get_address (server);
205   uri_string = g_strdup_printf ("rtsp://%s:%d%s", address, port, mount_point);
206   g_free (address);
207   fail_unless (gst_rtsp_url_parse (uri_string, &url) == GST_RTSP_OK);
208   g_free (uri_string);
209
210   fail_unless (gst_rtsp_connection_create (url, &conn) == GST_RTSP_OK);
211   gst_rtsp_url_free (url);
212
213   fail_unless (gst_rtsp_connection_connect (conn, NULL) == GST_RTSP_OK);
214
215   return conn;
216 }
217
218 /* create an rtsp request */
219 static GstRTSPMessage *
220 create_request (GstRTSPConnection * conn, GstRTSPMethod method,
221     const gchar * control)
222 {
223   GstRTSPMessage *request = NULL;
224   gchar *base_uri;
225   gchar *full_uri;
226
227   base_uri = gst_rtsp_url_get_request_uri (gst_rtsp_connection_get_url (conn));
228   full_uri = g_strdup_printf ("%s/%s", base_uri, control ? control : "");
229   g_free (base_uri);
230   if (gst_rtsp_message_new_request (&request, method, full_uri) != GST_RTSP_OK) {
231     GST_DEBUG ("failed to create request object");
232     g_free (full_uri);
233     return NULL;
234   }
235   g_free (full_uri);
236   return request;
237 }
238
239 /* send an rtsp request */
240 static gboolean
241 send_request (GstRTSPConnection * conn, GstRTSPMessage * request)
242 {
243   if (gst_rtsp_connection_send (conn, request, NULL) != GST_RTSP_OK) {
244     GST_DEBUG ("failed to send request");
245     return FALSE;
246   }
247   return TRUE;
248 }
249
250 /* read rtsp response. response must be freed by the caller */
251 static GstRTSPMessage *
252 read_response (GstRTSPConnection * conn)
253 {
254   GstRTSPMessage *response = NULL;
255
256   if (gst_rtsp_message_new (&response) != GST_RTSP_OK) {
257     GST_DEBUG ("failed to create response object");
258     return NULL;
259   }
260   if (gst_rtsp_connection_receive (conn, response, NULL) != GST_RTSP_OK) {
261     GST_DEBUG ("failed to read response");
262     gst_rtsp_message_free (response);
263     return NULL;
264   }
265   fail_unless (gst_rtsp_message_get_type (response) ==
266       GST_RTSP_MESSAGE_RESPONSE);
267   return response;
268 }
269
270 /* send an rtsp request and receive response. gchar** parameters are out
271  * parameters that have to be freed by the caller */
272 static GstRTSPStatusCode
273 do_request_full (GstRTSPConnection * conn, GstRTSPMethod method,
274     const gchar * control, const gchar * session_in, const gchar * transport_in,
275     const gchar * range_in, const gchar * require_in,
276     gchar ** content_type, gchar ** content_base, gchar ** body,
277     gchar ** session_out, gchar ** transport_out, gchar ** range_out,
278     gchar ** unsupported_out)
279 {
280   GstRTSPMessage *request;
281   GstRTSPMessage *response;
282   GstRTSPStatusCode code;
283   gchar *value;
284
285   /* create request */
286   request = create_request (conn, method, control);
287
288   /* add headers */
289   if (session_in) {
290     gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session_in);
291   }
292   if (transport_in) {
293     gst_rtsp_message_add_header (request, GST_RTSP_HDR_TRANSPORT, transport_in);
294   }
295   if (range_in) {
296     gst_rtsp_message_add_header (request, GST_RTSP_HDR_RANGE, range_in);
297   }
298   if (require_in) {
299     gst_rtsp_message_add_header (request, GST_RTSP_HDR_REQUIRE, require_in);
300   }
301
302   /* send request */
303   fail_unless (send_request (conn, request));
304   gst_rtsp_message_free (request);
305
306   iterate ();
307
308   /* read response */
309   response = read_response (conn);
310
311   /* check status line */
312   gst_rtsp_message_parse_response (response, &code, NULL, NULL);
313   if (code != GST_RTSP_STS_OK) {
314     if (unsupported_out != NULL && code == GST_RTSP_STS_OPTION_NOT_SUPPORTED) {
315       gst_rtsp_message_get_header (response, GST_RTSP_HDR_UNSUPPORTED,
316           &value, 0);
317       *unsupported_out = g_strdup (value);
318     }
319     gst_rtsp_message_free (response);
320     return code;
321   }
322
323   /* get information from response */
324   if (content_type) {
325     gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_TYPE,
326         &value, 0);
327     *content_type = g_strdup (value);
328   }
329   if (content_base) {
330     gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
331         &value, 0);
332     *content_base = g_strdup (value);
333   }
334   if (body) {
335     *body = g_malloc (response->body_size + 1);
336     strncpy (*body, (gchar *) response->body, response->body_size);
337   }
338   if (session_out) {
339     gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &value, 0);
340
341     value = g_strdup (value);
342
343     /* Remove the timeout */
344     if (value) {
345       char *pos = strchr (value, ';');
346       if (pos)
347         *pos = 0;
348     }
349     if (session_in) {
350       /* check that we got the same session back */
351       fail_unless (!g_strcmp0 (value, session_in));
352     }
353     *session_out = value;
354   }
355   if (transport_out) {
356     gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &value, 0);
357     *transport_out = g_strdup (value);
358   }
359   if (range_out) {
360     gst_rtsp_message_get_header (response, GST_RTSP_HDR_RANGE, &value, 0);
361     *range_out = g_strdup (value);
362   }
363
364   gst_rtsp_message_free (response);
365   return code;
366 }
367
368 /* send an rtsp request and receive response. gchar** parameters are out
369  * parameters that have to be freed by the caller */
370 static GstRTSPStatusCode
371 do_request (GstRTSPConnection * conn, GstRTSPMethod method,
372     const gchar * control, const gchar * session_in,
373     const gchar * transport_in, const gchar * range_in,
374     gchar ** content_type, gchar ** content_base, gchar ** body,
375     gchar ** session_out, gchar ** transport_out, gchar ** range_out)
376 {
377   return do_request_full (conn, method, control, session_in, transport_in,
378       range_in, NULL, content_type, content_base, body, session_out,
379       transport_out, range_out, NULL);
380 }
381
382 /* send an rtsp request with a method and a session, and receive response */
383 static GstRTSPStatusCode
384 do_simple_request (GstRTSPConnection * conn, GstRTSPMethod method,
385     const gchar * session)
386 {
387   return do_request (conn, method, NULL, session, NULL, NULL, NULL,
388       NULL, NULL, NULL, NULL, NULL);
389 }
390
391 /* send a DESCRIBE request and receive response. returns a received
392  * GstSDPMessage that must be freed by the caller */
393 static GstSDPMessage *
394 do_describe (GstRTSPConnection * conn, const gchar * mount_point)
395 {
396   GstSDPMessage *sdp_message;
397   gchar *content_type;
398   gchar *content_base;
399   gchar *body;
400   gchar *address;
401   gchar *expected_content_base;
402
403   /* send DESCRIBE request */
404   fail_unless (do_request (conn, GST_RTSP_DESCRIBE, NULL, NULL, NULL, NULL,
405           &content_type, &content_base, &body, NULL, NULL, NULL) ==
406       GST_RTSP_STS_OK);
407
408   /* check response values */
409   fail_unless (!g_strcmp0 (content_type, "application/sdp"));
410   address = gst_rtsp_server_get_address (server);
411   expected_content_base =
412       g_strdup_printf ("rtsp://%s:%d%s/", address, test_port, mount_point);
413   fail_unless (!g_strcmp0 (content_base, expected_content_base));
414
415   /* create sdp message */
416   fail_unless (gst_sdp_message_new (&sdp_message) == GST_SDP_OK);
417   fail_unless (gst_sdp_message_parse_buffer ((guint8 *) body,
418           strlen (body), sdp_message) == GST_SDP_OK);
419
420   /* clean up */
421   g_free (content_type);
422   g_free (content_base);
423   g_free (body);
424   g_free (address);
425   g_free (expected_content_base);
426
427   return sdp_message;
428 }
429
430 /* send a SETUP request and receive response. if *session is not NULL,
431  * it is used in the request. otherwise, *session is set to a returned
432  * session string that must be freed by the caller. the returned
433  * transport must be freed by the caller. */
434 static GstRTSPStatusCode
435 do_setup_full (GstRTSPConnection * conn, const gchar * control,
436     gboolean use_tcp_transport, const GstRTSPRange * client_ports,
437     const gchar * require, gchar ** session, GstRTSPTransport ** transport,
438     gchar ** unsupported)
439 {
440   GstRTSPStatusCode code;
441   gchar *session_in = NULL;
442   gchar *transport_string_in = NULL;
443   gchar **session_out = NULL;
444   gchar *transport_string_out = NULL;
445
446   /* prepare and send SETUP request */
447   if (session) {
448     if (*session) {
449       session_in = *session;
450     } else {
451       session_out = session;
452     }
453   }
454
455   if (use_tcp_transport) {
456     transport_string_in =
457       g_strdup_printf (TEST_PROTO_TCP ";unicast");
458   } else {
459     transport_string_in =
460       g_strdup_printf (TEST_PROTO ";unicast;client_port=%d-%d",
461       client_ports->min, client_ports->max);
462   }
463   code =
464       do_request_full (conn, GST_RTSP_SETUP, control, session_in,
465       transport_string_in, NULL, require, NULL, NULL, NULL, session_out,
466       &transport_string_out, NULL, unsupported);
467   g_free (transport_string_in);
468
469   if (transport_string_out) {
470     /* create transport */
471     fail_unless (gst_rtsp_transport_new (transport) == GST_RTSP_OK);
472     fail_unless (gst_rtsp_transport_parse (transport_string_out,
473             *transport) == GST_RTSP_OK);
474     g_free (transport_string_out);
475   }
476   GST_INFO ("code=%d", code);
477   return code;
478 }
479
480 /* send a SETUP request and receive response. if *session is not NULL,
481  * it is used in the request. otherwise, *session is set to a returned
482  * session string that must be freed by the caller. the returned
483  * transport must be freed by the caller. */
484 static GstRTSPStatusCode
485 do_setup (GstRTSPConnection * conn, const gchar * control,
486     const GstRTSPRange * client_ports, gchar ** session,
487     GstRTSPTransport ** transport)
488 {
489   return do_setup_full (conn, control, FALSE, client_ports, NULL, session,
490       transport, NULL);
491 }
492
493 /* send a SETUP request and receive response. if *session is not NULL,
494  * it is used in the request. otherwise, *session is set to a returned
495  * session string that must be freed by the caller. the returned
496  * transport must be freed by the caller. */
497 static GstRTSPStatusCode
498 do_setup_tcp (GstRTSPConnection * conn, const gchar * control,
499     gchar ** session, GstRTSPTransport ** transport)
500 {
501   return do_setup_full (conn, control, TRUE, NULL, NULL, session, transport,
502       NULL);
503 }
504
505 /* fixture setup function */
506 static void
507 setup (void)
508 {
509   server = gst_rtsp_server_new ();
510 }
511
512 /* fixture clean-up function */
513 static void
514 teardown (void)
515 {
516   if (server) {
517     g_object_unref (server);
518     server = NULL;
519   }
520   test_port = 0;
521 }
522
523 GST_START_TEST (test_connect)
524 {
525   GstRTSPConnection *conn;
526
527   start_server ();
528
529   /* connect to server */
530   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
531
532   /* clean up */
533   gst_rtsp_connection_free (conn);
534   stop_server ();
535
536   /* iterate so the clean-up can finish */
537   iterate ();
538 }
539
540 GST_END_TEST;
541
542 GST_START_TEST (test_describe)
543 {
544   GstRTSPConnection *conn;
545   GstSDPMessage *sdp_message = NULL;
546   const GstSDPMedia *sdp_media;
547   gint32 format;
548   gchar *expected_rtpmap;
549   const gchar *rtpmap;
550   const gchar *control_video;
551   const gchar *control_audio;
552
553   start_server ();
554
555   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
556
557   /* send DESCRIBE request */
558   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
559
560   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
561
562   /* check video sdp */
563   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
564   fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
565   fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
566   sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
567       &format);
568   expected_rtpmap =
569       g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
570   rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
571   fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
572   g_free (expected_rtpmap);
573   control_video = gst_sdp_media_get_attribute_val (sdp_media, "control");
574   fail_unless (!g_strcmp0 (control_video, "stream=0"));
575
576   /* check audio sdp */
577   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
578   fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
579   fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
580   sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
581       &format);
582   expected_rtpmap =
583       g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
584   rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
585   fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
586   g_free (expected_rtpmap);
587   control_audio = gst_sdp_media_get_attribute_val (sdp_media, "control");
588   fail_unless (!g_strcmp0 (control_audio, "stream=1"));
589
590   /* clean up and iterate so the clean-up can finish */
591   gst_sdp_message_free (sdp_message);
592   gst_rtsp_connection_free (conn);
593   stop_server ();
594   iterate ();
595 }
596
597 GST_END_TEST;
598
599 GST_START_TEST (test_describe_non_existing_mount_point)
600 {
601   GstRTSPConnection *conn;
602
603   start_server ();
604
605   /* send DESCRIBE request for a non-existing mount point
606    * and check that we get a 404 Not Found */
607   conn = connect_to_server (test_port, "/non-existing");
608   fail_unless (do_simple_request (conn, GST_RTSP_DESCRIBE, NULL)
609       == GST_RTSP_STS_NOT_FOUND);
610
611   /* clean up and iterate so the clean-up can finish */
612   gst_rtsp_connection_free (conn);
613   stop_server ();
614   iterate ();
615 }
616
617 GST_END_TEST;
618
619 GST_START_TEST (test_setup)
620 {
621   GstRTSPConnection *conn;
622   GstSDPMessage *sdp_message = NULL;
623   const GstSDPMedia *sdp_media;
624   const gchar *video_control;
625   const gchar *audio_control;
626   GstRTSPRange client_ports;
627   gchar *session = NULL;
628   GstRTSPTransport *video_transport = NULL;
629   GstRTSPTransport *audio_transport = NULL;
630
631   start_server ();
632
633   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
634
635   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
636
637   /* get control strings from DESCRIBE response */
638   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
639   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
640   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
641   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
642   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
643
644   get_client_ports (&client_ports);
645
646   /* send SETUP request for video */
647   fail_unless (do_setup (conn, video_control, &client_ports, &session,
648           &video_transport) == GST_RTSP_STS_OK);
649   GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
650
651   /* check response from SETUP */
652   fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
653   fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
654   fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
655   fail_unless (video_transport->mode_play);
656   gst_rtsp_transport_free (video_transport);
657
658   /* send SETUP request for audio */
659   fail_unless (do_setup (conn, audio_control, &client_ports, &session,
660           &audio_transport) == GST_RTSP_STS_OK);
661   GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
662
663   /* check response from SETUP */
664   fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
665   fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
666   fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
667   fail_unless (audio_transport->mode_play);
668   gst_rtsp_transport_free (audio_transport);
669
670   /* send TEARDOWN request and check that we get 200 OK */
671   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
672           session) == GST_RTSP_STS_OK);
673
674   /* clean up and iterate so the clean-up can finish */
675   g_free (session);
676   gst_sdp_message_free (sdp_message);
677   gst_rtsp_connection_free (conn);
678   stop_server ();
679   iterate ();
680 }
681
682 GST_END_TEST;
683
684 GST_START_TEST (test_setup_tcp)
685 {
686   GstRTSPConnection *conn;
687   GstSDPMessage *sdp_message = NULL;
688   const GstSDPMedia *sdp_media;
689   const gchar *video_control;
690   const gchar *audio_control;
691   gchar *session = NULL;
692   GstRTSPTransport *video_transport = NULL;
693   GstRTSPTransport *audio_transport = NULL;
694
695   start_server ();
696
697   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
698
699   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
700
701   /* get control strings from DESCRIBE response */
702   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
703   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
704   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
705   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
706   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
707
708   /* send SETUP request for video */
709   fail_unless (do_setup_tcp (conn, video_control, &session,
710           &video_transport) == GST_RTSP_STS_OK);
711   GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
712
713   /* check response from SETUP */
714   fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
715   fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
716   fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_TCP);
717   fail_unless (video_transport->mode_play);
718   gst_rtsp_transport_free (video_transport);
719
720   /* send SETUP request for audio */
721   fail_unless (do_setup_tcp (conn, audio_control, &session,
722           &audio_transport) == GST_RTSP_STS_OK);
723   GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
724
725   /* check response from SETUP */
726   fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
727   fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
728   fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_TCP);
729   fail_unless (audio_transport->mode_play);
730   gst_rtsp_transport_free (audio_transport);
731
732   /* send TEARDOWN request and check that we get 200 OK */
733   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
734           session) == GST_RTSP_STS_OK);
735
736   /* clean up and iterate so the clean-up can finish */
737   g_free (session);
738   gst_sdp_message_free (sdp_message);
739   gst_rtsp_connection_free (conn);
740   stop_server ();
741   iterate ();
742 }
743
744 GST_END_TEST;
745
746 GST_START_TEST (test_setup_twice)
747 {
748   GstRTSPConnection *conn;
749   GstSDPMessage *sdp_message;
750   const GstSDPMedia *sdp_media;
751   const gchar *video_control;
752   GstRTSPRange client_ports;
753   GstRTSPTransport *video_transport = NULL;
754   gchar *session1 = NULL;
755   gchar *session2 = NULL;
756
757   start_server ();
758
759   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
760
761   /* we wan't more than one session for this connection */
762   gst_rtsp_connection_set_remember_session_id (conn, FALSE);
763
764   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
765
766   /* get the control url */
767   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
768   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
769   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
770
771   get_client_ports (&client_ports);
772
773   /* send SETUP request for one session */
774   fail_unless (do_setup (conn, video_control, &client_ports, &session1,
775           &video_transport) == GST_RTSP_STS_OK);
776   GST_DEBUG ("set up video %s, got session '%s'", video_control, session1);
777
778   /* check response from SETUP */
779   fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
780   fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
781   fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
782   fail_unless (video_transport->mode_play);
783   gst_rtsp_transport_free (video_transport);
784
785   /* send SETUP request for another session */
786   fail_unless (do_setup (conn, video_control, &client_ports, &session2,
787           &video_transport) == GST_RTSP_STS_OK);
788   GST_DEBUG ("set up video %s, got session '%s'", video_control, session2);
789
790   /* check response from SETUP */
791   fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
792   fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
793   fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
794   fail_unless (video_transport->mode_play);
795   gst_rtsp_transport_free (video_transport);
796
797   /* session can not be the same */
798   fail_unless (strcmp (session1, session2));
799
800   /* send TEARDOWN request for the first session*/
801   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
802           session1) == GST_RTSP_STS_OK);
803
804   /* send TEARDOWN request for the second session */
805   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
806           session2) == GST_RTSP_STS_OK);
807
808   g_free (session1);
809   g_free (session2);
810   gst_sdp_message_free (sdp_message);
811   gst_rtsp_connection_free (conn);
812   stop_server ();
813   iterate ();
814 }
815
816 GST_END_TEST;
817
818 GST_START_TEST (test_setup_with_require_header)
819 {
820   GstRTSPConnection *conn;
821   GstSDPMessage *sdp_message = NULL;
822   const GstSDPMedia *sdp_media;
823   const gchar *video_control;
824   GstRTSPRange client_ports;
825   gchar *session = NULL;
826   gchar *unsupported = NULL;
827   GstRTSPTransport *video_transport = NULL;
828
829   start_server ();
830
831   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
832
833   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
834
835   /* get control strings from DESCRIBE response */
836   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
837   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
838   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
839
840   get_client_ports (&client_ports);
841
842   /* send SETUP request for video, with single Require header */
843   fail_unless_equals_int (do_setup_full (conn, video_control, FALSE,
844           &client_ports, "funky-feature", &session, &video_transport,
845           &unsupported), GST_RTSP_STS_OPTION_NOT_SUPPORTED);
846   fail_unless_equals_string (unsupported, "funky-feature");
847   g_free (unsupported);
848   unsupported = NULL;
849
850   /* send SETUP request for video, with multiple Require headers */
851   fail_unless_equals_int (do_setup_full (conn, video_control, FALSE,
852           &client_ports, "funky-feature, foo-bar, superburst", &session,
853           &video_transport, &unsupported), GST_RTSP_STS_OPTION_NOT_SUPPORTED);
854   fail_unless_equals_string (unsupported, "funky-feature, foo-bar, superburst");
855   g_free (unsupported);
856   unsupported = NULL;
857
858   /* ok, just do a normal setup then (make sure that still works) */
859   fail_unless_equals_int (do_setup (conn, video_control, &client_ports,
860           &session, &video_transport), GST_RTSP_STS_OK);
861
862   GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
863
864   /* check response from SETUP */
865   fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
866   fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
867   fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
868   fail_unless (video_transport->mode_play);
869   gst_rtsp_transport_free (video_transport);
870
871   /* send TEARDOWN request and check that we get 200 OK */
872   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
873           session) == GST_RTSP_STS_OK);
874
875   /* clean up and iterate so the clean-up can finish */
876   g_free (session);
877   gst_sdp_message_free (sdp_message);
878   gst_rtsp_connection_free (conn);
879   stop_server ();
880   iterate ();
881 }
882
883 GST_END_TEST;
884
885 GST_START_TEST (test_setup_non_existing_stream)
886 {
887   GstRTSPConnection *conn;
888   GstRTSPRange client_ports;
889
890   start_server ();
891
892   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
893
894   get_client_ports (&client_ports);
895
896   /* send SETUP request with a non-existing stream and check that we get a
897    * 404 Not Found */
898   fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
899           NULL) == GST_RTSP_STS_NOT_FOUND);
900
901   /* clean up and iterate so the clean-up can finish */
902   gst_rtsp_connection_free (conn);
903   stop_server ();
904   iterate ();
905 }
906
907 GST_END_TEST;
908
909 static void
910 receive_rtp (GSocket * socket, GSocketAddress ** addr)
911 {
912   GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
913
914   for (;;) {
915     gssize bytes;
916     GstMapInfo map = GST_MAP_INFO_INIT;
917     GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
918
919     gst_buffer_map (buffer, &map, GST_MAP_WRITE);
920     bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
921         map.maxsize, NULL, NULL);
922     fail_unless (bytes > 0);
923     gst_buffer_unmap (buffer, &map);
924     gst_buffer_set_size (buffer, bytes);
925
926     if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer)) {
927       gst_rtp_buffer_unmap (&rtpbuffer);
928       break;
929     }
930
931     if (addr)
932       g_clear_object (addr);
933   }
934
935   gst_buffer_unref (buffer);
936 }
937
938 static void
939 receive_rtcp (GSocket * socket, GSocketAddress ** addr, GstRTCPType type)
940 {
941   GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
942
943   for (;;) {
944     gssize bytes;
945     GstMapInfo map = GST_MAP_INFO_INIT;
946
947     gst_buffer_map (buffer, &map, GST_MAP_WRITE);
948     bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
949         map.maxsize, NULL, NULL);
950     fail_unless (bytes > 0);
951     gst_buffer_unmap (buffer, &map);
952     gst_buffer_set_size (buffer, bytes);
953
954     if (gst_rtcp_buffer_validate (buffer)) {
955       GstRTCPBuffer rtcpbuffer = GST_RTCP_BUFFER_INIT;
956       GstRTCPPacket packet;
957
958       if (type) {
959         fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcpbuffer));
960         fail_unless (gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet));
961         do {
962           if (gst_rtcp_packet_get_type (&packet) == type) {
963             gst_rtcp_buffer_unmap (&rtcpbuffer);
964             goto done;
965           }
966         } while (gst_rtcp_packet_move_to_next (&packet));
967         gst_rtcp_buffer_unmap (&rtcpbuffer);
968       } else {
969         break;
970       }
971     }
972
973     if (addr)
974       g_clear_object (addr);
975   }
976
977 done:
978
979   gst_buffer_unref (buffer);
980 }
981
982 static void
983 do_test_play (const gchar * range)
984 {
985   GstRTSPConnection *conn;
986   GstSDPMessage *sdp_message = NULL;
987   const GstSDPMedia *sdp_media;
988   const gchar *video_control;
989   const gchar *audio_control;
990   GstRTSPRange client_port;
991   gchar *session = NULL;
992   GstRTSPTransport *video_transport = NULL;
993   GstRTSPTransport *audio_transport = NULL;
994   GSocket *rtp_socket, *rtcp_socket;
995   gchar *range_out = NULL;
996
997   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
998
999   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1000
1001   /* get control strings from DESCRIBE response */
1002   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1003   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1004   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1005   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1006   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1007
1008   get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
1009
1010   /* do SETUP for video and audio */
1011   fail_unless (do_setup (conn, video_control, &client_port, &session,
1012           &video_transport) == GST_RTSP_STS_OK);
1013   fail_unless (do_setup (conn, audio_control, &client_port, &session,
1014           &audio_transport) == GST_RTSP_STS_OK);
1015
1016   /* send PLAY request and check that we get 200 OK */
1017   fail_unless (do_request (conn, GST_RTSP_PLAY, NULL, session, NULL, range,
1018           NULL, NULL, NULL, NULL, NULL, &range_out) == GST_RTSP_STS_OK);
1019   if (range)
1020     fail_unless_equals_string (range, range_out);
1021   g_free (range_out);
1022
1023   receive_rtp (rtp_socket, NULL);
1024   receive_rtcp (rtcp_socket, NULL, 0);
1025
1026   /* send TEARDOWN request and check that we get 200 OK */
1027   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1028           session) == GST_RTSP_STS_OK);
1029
1030   /* FIXME: The rtsp-server always disconnects the transport before
1031    * sending the RTCP BYE
1032    * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
1033    */
1034
1035   /* clean up and iterate so the clean-up can finish */
1036   g_object_unref (rtp_socket);
1037   g_object_unref (rtcp_socket);
1038   g_free (session);
1039   gst_rtsp_transport_free (video_transport);
1040   gst_rtsp_transport_free (audio_transport);
1041   gst_sdp_message_free (sdp_message);
1042   gst_rtsp_connection_free (conn);
1043 }
1044
1045
1046 GST_START_TEST (test_play)
1047 {
1048   start_server ();
1049
1050   do_test_play (NULL);
1051
1052   stop_server ();
1053   iterate ();
1054 }
1055
1056 GST_END_TEST;
1057
1058 GST_START_TEST (test_play_without_session)
1059 {
1060   GstRTSPConnection *conn;
1061
1062   start_server ();
1063
1064   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1065
1066   /* send PLAY request without a session and check that we get a
1067    * 454 Session Not Found */
1068   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1069           NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
1070
1071   /* clean up and iterate so the clean-up can finish */
1072   gst_rtsp_connection_free (conn);
1073   stop_server ();
1074   iterate ();
1075 }
1076
1077 GST_END_TEST;
1078
1079 GST_START_TEST (test_bind_already_in_use)
1080 {
1081   GstRTSPServer *serv;
1082   GSocketService *service;
1083   GError *error = NULL;
1084   guint16 port;
1085   gchar *port_str;
1086
1087   serv = gst_rtsp_server_new ();
1088   service = g_socket_service_new ();
1089
1090   /* bind service to port */
1091   port =
1092       g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL,
1093       &error);
1094   g_assert_no_error (error);
1095
1096   port_str = g_strdup_printf ("%d\n", port);
1097
1098   /* try to bind server to the same port */
1099   g_object_set (serv, "service", port_str, NULL);
1100   g_free (port_str);
1101
1102   /* attach to default main context */
1103   fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
1104
1105   /* cleanup */
1106   g_object_unref (serv);
1107   g_socket_service_stop (service);
1108   g_object_unref (service);
1109 }
1110
1111 GST_END_TEST;
1112
1113
1114 GST_START_TEST (test_play_multithreaded)
1115 {
1116   GstRTSPThreadPool *pool;
1117
1118   pool = gst_rtsp_server_get_thread_pool (server);
1119   gst_rtsp_thread_pool_set_max_threads (pool, 2);
1120   g_object_unref (pool);
1121
1122   start_server ();
1123
1124   do_test_play (NULL);
1125
1126   stop_server ();
1127   iterate ();
1128 }
1129
1130 GST_END_TEST;
1131
1132 enum
1133 {
1134   BLOCK_ME,
1135   BLOCKED,
1136   UNBLOCK
1137 };
1138
1139
1140 static void
1141 media_constructed_block (GstRTSPMediaFactory * factory,
1142     GstRTSPMedia * media, gpointer user_data)
1143 {
1144   gint *block_state = user_data;
1145
1146   g_mutex_lock (&check_mutex);
1147
1148   *block_state = BLOCKED;
1149   g_cond_broadcast (&check_cond);
1150
1151   while (*block_state != UNBLOCK)
1152     g_cond_wait (&check_cond, &check_mutex);
1153   g_mutex_unlock (&check_mutex);
1154 }
1155
1156
1157 GST_START_TEST (test_play_multithreaded_block_in_describe)
1158 {
1159   GstRTSPConnection *conn;
1160   GstRTSPMountPoints *mounts;
1161   GstRTSPMediaFactory *factory;
1162   gint block_state = BLOCK_ME;
1163   GstRTSPMessage *request;
1164   GstRTSPMessage *response;
1165   GstRTSPStatusCode code;
1166   GstRTSPThreadPool *pool;
1167
1168   pool = gst_rtsp_server_get_thread_pool (server);
1169   gst_rtsp_thread_pool_set_max_threads (pool, 2);
1170   g_object_unref (pool);
1171
1172   mounts = gst_rtsp_server_get_mount_points (server);
1173   fail_unless (mounts != NULL);
1174   factory = gst_rtsp_media_factory_new ();
1175   gst_rtsp_media_factory_set_launch (factory,
1176       "( " VIDEO_PIPELINE "  " AUDIO_PIPELINE " )");
1177   g_signal_connect (factory, "media-constructed",
1178       G_CALLBACK (media_constructed_block), &block_state);
1179   gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT "2", factory);
1180   g_object_unref (mounts);
1181
1182   start_server ();
1183
1184   conn = connect_to_server (test_port, TEST_MOUNT_POINT "2");
1185   iterate ();
1186
1187   /* do describe, it will not return now as we've blocked it */
1188   request = create_request (conn, GST_RTSP_DESCRIBE, NULL);
1189   fail_unless (send_request (conn, request));
1190   gst_rtsp_message_free (request);
1191
1192   g_mutex_lock (&check_mutex);
1193   while (block_state != BLOCKED)
1194     g_cond_wait (&check_cond, &check_mutex);
1195   g_mutex_unlock (&check_mutex);
1196
1197   /* Do a second connection while the first one is blocked */
1198   do_test_play (NULL);
1199
1200   /* Now unblock the describe */
1201   g_mutex_lock (&check_mutex);
1202   block_state = UNBLOCK;
1203   g_cond_broadcast (&check_cond);
1204   g_mutex_unlock (&check_mutex);
1205
1206   response = read_response (conn);
1207   gst_rtsp_message_parse_response (response, &code, NULL, NULL);
1208   fail_unless (code == GST_RTSP_STS_OK);
1209   gst_rtsp_message_free (response);
1210
1211
1212   gst_rtsp_connection_free (conn);
1213   stop_server ();
1214   iterate ();
1215
1216 }
1217
1218 GST_END_TEST;
1219
1220
1221 static void
1222 new_session_timeout_one (GstRTSPClient * client,
1223     GstRTSPSession * session, gpointer user_data)
1224 {
1225   gst_rtsp_session_set_timeout (session, 1);
1226
1227   g_signal_handlers_disconnect_by_func (client, new_session_timeout_one,
1228       user_data);
1229 }
1230
1231 static void
1232 session_connected_new_session_cb (GstRTSPServer * server,
1233     GstRTSPClient * client, gpointer user_data)
1234 {
1235
1236   g_signal_connect (client, "new-session", user_data, NULL);
1237 }
1238
1239 GST_START_TEST (test_play_multithreaded_timeout_client)
1240 {
1241   GstRTSPConnection *conn;
1242   GstSDPMessage *sdp_message = NULL;
1243   const GstSDPMedia *sdp_media;
1244   const gchar *video_control;
1245   const gchar *audio_control;
1246   GstRTSPRange client_port;
1247   gchar *session = NULL;
1248   GstRTSPTransport *video_transport = NULL;
1249   GstRTSPTransport *audio_transport = NULL;
1250   GstRTSPSessionPool *pool;
1251   GstRTSPThreadPool *thread_pool;
1252
1253   thread_pool = gst_rtsp_server_get_thread_pool (server);
1254   gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1255   g_object_unref (thread_pool);
1256
1257   pool = gst_rtsp_server_get_session_pool (server);
1258   g_signal_connect (server, "client-connected",
1259       G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1260
1261   start_server ();
1262
1263
1264   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1265
1266   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1267
1268   /* get control strings from DESCRIBE response */
1269   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1270   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1271   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1272   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1273   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1274
1275   get_client_ports (&client_port);
1276
1277   /* do SETUP for video and audio */
1278   fail_unless (do_setup (conn, video_control, &client_port, &session,
1279           &video_transport) == GST_RTSP_STS_OK);
1280   fail_unless (do_setup (conn, audio_control, &client_port, &session,
1281           &audio_transport) == GST_RTSP_STS_OK);
1282
1283   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1284
1285   /* send PLAY request and check that we get 200 OK */
1286   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1287           session) == GST_RTSP_STS_OK);
1288
1289   sleep (7);
1290
1291   fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1292   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 0);
1293
1294   /* clean up and iterate so the clean-up can finish */
1295   g_object_unref (pool);
1296   g_free (session);
1297   gst_rtsp_transport_free (video_transport);
1298   gst_rtsp_transport_free (audio_transport);
1299   gst_sdp_message_free (sdp_message);
1300   gst_rtsp_connection_free (conn);
1301
1302   stop_server ();
1303   iterate ();
1304 }
1305
1306 GST_END_TEST;
1307
1308
1309 GST_START_TEST (test_play_multithreaded_timeout_session)
1310 {
1311   GstRTSPConnection *conn;
1312   GstSDPMessage *sdp_message = NULL;
1313   const GstSDPMedia *sdp_media;
1314   const gchar *video_control;
1315   const gchar *audio_control;
1316   GstRTSPRange client_port;
1317   gchar *session1 = NULL;
1318   gchar *session2 = NULL;
1319   GstRTSPTransport *video_transport = NULL;
1320   GstRTSPTransport *audio_transport = NULL;
1321   GstRTSPSessionPool *pool;
1322   GstRTSPThreadPool *thread_pool;
1323
1324   thread_pool = gst_rtsp_server_get_thread_pool (server);
1325   gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1326   g_object_unref (thread_pool);
1327
1328   pool = gst_rtsp_server_get_session_pool (server);
1329   g_signal_connect (server, "client-connected",
1330       G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1331
1332   start_server ();
1333
1334
1335   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1336
1337   gst_rtsp_connection_set_remember_session_id (conn, FALSE);
1338
1339   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1340
1341   /* get control strings from DESCRIBE response */
1342   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1343   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1344   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1345   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1346   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1347
1348   get_client_ports (&client_port);
1349
1350   /* do SETUP for video and audio */
1351   fail_unless (do_setup (conn, video_control, &client_port, &session1,
1352           &video_transport) == GST_RTSP_STS_OK);
1353   fail_unless (do_setup (conn, audio_control, &client_port, &session2,
1354           &audio_transport) == GST_RTSP_STS_OK);
1355
1356   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 2);
1357
1358   /* send PLAY request and check that we get 200 OK */
1359   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1360           session1) == GST_RTSP_STS_OK);
1361   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1362           session2) == GST_RTSP_STS_OK);
1363
1364   sleep (7);
1365
1366   fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1367
1368   /* send TEARDOWN request and check that we get 454 Session Not found */
1369   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1370           session1) == GST_RTSP_STS_SESSION_NOT_FOUND);
1371
1372   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1373           session2) == GST_RTSP_STS_OK);
1374
1375   /* clean up and iterate so the clean-up can finish */
1376   g_object_unref (pool);
1377   g_free (session1);
1378   g_free (session2);
1379   gst_rtsp_transport_free (video_transport);
1380   gst_rtsp_transport_free (audio_transport);
1381   gst_sdp_message_free (sdp_message);
1382   gst_rtsp_connection_free (conn);
1383
1384   stop_server ();
1385   iterate ();
1386 }
1387
1388 GST_END_TEST;
1389
1390
1391 GST_START_TEST (test_play_disconnect)
1392 {
1393   GstRTSPConnection *conn;
1394   GstSDPMessage *sdp_message = NULL;
1395   const GstSDPMedia *sdp_media;
1396   const gchar *video_control;
1397   const gchar *audio_control;
1398   GstRTSPRange client_port;
1399   gchar *session = NULL;
1400   GstRTSPTransport *video_transport = NULL;
1401   GstRTSPTransport *audio_transport = NULL;
1402   GstRTSPSessionPool *pool;
1403
1404   pool = gst_rtsp_server_get_session_pool (server);
1405   g_signal_connect (server, "client-connected",
1406       G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1407
1408   start_server ();
1409
1410   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1411
1412   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1413
1414   /* get control strings from DESCRIBE response */
1415   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1416   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1417   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1418   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1419   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1420
1421   get_client_ports (&client_port);
1422
1423   /* do SETUP for video and audio */
1424   fail_unless (do_setup (conn, video_control, &client_port, &session,
1425           &video_transport) == GST_RTSP_STS_OK);
1426   fail_unless (do_setup (conn, audio_control, &client_port, &session,
1427           &audio_transport) == GST_RTSP_STS_OK);
1428
1429   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1430
1431   /* send PLAY request and check that we get 200 OK */
1432   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1433           session) == GST_RTSP_STS_OK);
1434
1435   gst_rtsp_connection_free (conn);
1436
1437   sleep (7);
1438
1439   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1440   fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1441
1442
1443   /* clean up and iterate so the clean-up can finish */
1444   g_object_unref (pool);
1445   g_free (session);
1446   gst_rtsp_transport_free (video_transport);
1447   gst_rtsp_transport_free (audio_transport);
1448   gst_sdp_message_free (sdp_message);
1449
1450   stop_server ();
1451   iterate ();
1452 }
1453
1454 GST_END_TEST;
1455
1456 /* Only different with test_play is the specific ports selected */
1457
1458 GST_START_TEST (test_play_specific_server_port)
1459 {
1460   GstRTSPMountPoints *mounts;
1461   gchar *service;
1462   GstRTSPMediaFactory *factory;
1463   GstRTSPAddressPool *pool;
1464   GstRTSPConnection *conn;
1465   GstSDPMessage *sdp_message = NULL;
1466   const GstSDPMedia *sdp_media;
1467   const gchar *video_control;
1468   GstRTSPRange client_port;
1469   gchar *session = NULL;
1470   GstRTSPTransport *video_transport = NULL;
1471   GSocket *rtp_socket, *rtcp_socket;
1472   GSocketAddress *rtp_address, *rtcp_address;
1473   guint16 rtp_port, rtcp_port;
1474
1475   mounts = gst_rtsp_server_get_mount_points (server);
1476
1477   factory = gst_rtsp_media_factory_new ();
1478   pool = gst_rtsp_address_pool_new ();
1479   gst_rtsp_address_pool_add_range (pool, GST_RTSP_ADDRESS_POOL_ANY_IPV4,
1480       GST_RTSP_ADDRESS_POOL_ANY_IPV4, 7770, 7780, 0);
1481   gst_rtsp_media_factory_set_address_pool (factory, pool);
1482   g_object_unref (pool);
1483   gst_rtsp_media_factory_set_launch (factory, "( " VIDEO_PIPELINE " )");
1484   gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
1485   g_object_unref (mounts);
1486
1487   /* set port to any */
1488   gst_rtsp_server_set_service (server, "0");
1489
1490   /* attach to default main context */
1491   source_id = gst_rtsp_server_attach (server, NULL);
1492   fail_if (source_id == 0);
1493
1494   /* get port */
1495   service = gst_rtsp_server_get_service (server);
1496   test_port = atoi (service);
1497   fail_unless (test_port != 0);
1498   g_free (service);
1499
1500   GST_DEBUG ("rtsp server listening on port %d", test_port);
1501
1502
1503   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1504
1505   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1506
1507   /* get control strings from DESCRIBE response */
1508   fail_unless (gst_sdp_message_medias_len (sdp_message) == 1);
1509   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1510   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1511
1512   get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
1513
1514   /* do SETUP for video */
1515   fail_unless (do_setup (conn, video_control, &client_port, &session,
1516           &video_transport) == GST_RTSP_STS_OK);
1517
1518   /* send PLAY request and check that we get 200 OK */
1519   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1520           session) == GST_RTSP_STS_OK);
1521
1522   receive_rtp (rtp_socket, &rtp_address);
1523   receive_rtcp (rtcp_socket, &rtcp_address, 0);
1524
1525   fail_unless (G_IS_INET_SOCKET_ADDRESS (rtp_address));
1526   fail_unless (G_IS_INET_SOCKET_ADDRESS (rtcp_address));
1527   rtp_port =
1528       g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_address));
1529   rtcp_port =
1530       g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtcp_address));
1531   fail_unless (rtp_port >= 7770 && rtp_port <= 7780 && rtp_port % 2 == 0);
1532   fail_unless (rtcp_port >= 7770 && rtcp_port <= 7780 && rtcp_port % 2 == 1);
1533   fail_unless (rtp_port + 1 == rtcp_port);
1534
1535   g_object_unref (rtp_address);
1536   g_object_unref (rtcp_address);
1537
1538   /* send TEARDOWN request and check that we get 200 OK */
1539   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1540           session) == GST_RTSP_STS_OK);
1541
1542   /* FIXME: The rtsp-server always disconnects the transport before
1543    * sending the RTCP BYE
1544    * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
1545    */
1546
1547   /* clean up and iterate so the clean-up can finish */
1548   g_object_unref (rtp_socket);
1549   g_object_unref (rtcp_socket);
1550   g_free (session);
1551   gst_rtsp_transport_free (video_transport);
1552   gst_sdp_message_free (sdp_message);
1553   gst_rtsp_connection_free (conn);
1554
1555
1556   stop_server ();
1557   iterate ();
1558 }
1559
1560 GST_END_TEST;
1561
1562
1563 GST_START_TEST (test_play_smpte_range)
1564 {
1565   start_server ();
1566
1567   do_test_play ("npt=5-");
1568   do_test_play ("smpte=0:00:00-");
1569   do_test_play ("smpte=1:00:00-");
1570   do_test_play ("smpte=1:00:03-");
1571   do_test_play ("clock=20120321T152256Z-");
1572
1573   stop_server ();
1574   iterate ();
1575 }
1576
1577 GST_END_TEST;
1578
1579
1580 static Suite *
1581 rtspserver_suite (void)
1582 {
1583   Suite *s = suite_create ("rtspserver");
1584   TCase *tc = tcase_create ("general");
1585
1586   suite_add_tcase (s, tc);
1587   tcase_add_checked_fixture (tc, setup, teardown);
1588   tcase_set_timeout (tc, 120);
1589   tcase_add_test (tc, test_connect);
1590   tcase_add_test (tc, test_describe);
1591   tcase_add_test (tc, test_describe_non_existing_mount_point);
1592   tcase_add_test (tc, test_setup);
1593   tcase_add_test (tc, test_setup_tcp);
1594   tcase_add_test (tc, test_setup_twice);
1595   tcase_add_test (tc, test_setup_with_require_header);
1596   tcase_add_test (tc, test_setup_non_existing_stream);
1597   tcase_add_test (tc, test_play);
1598   tcase_add_test (tc, test_play_without_session);
1599   tcase_add_test (tc, test_bind_already_in_use);
1600   tcase_add_test (tc, test_play_multithreaded);
1601   tcase_add_test (tc, test_play_multithreaded_block_in_describe);
1602   tcase_add_test (tc, test_play_multithreaded_timeout_client);
1603   tcase_add_test (tc, test_play_multithreaded_timeout_session);
1604   tcase_add_test (tc, test_play_disconnect);
1605   tcase_add_test (tc, test_play_specific_server_port);
1606   tcase_add_test (tc, test_play_smpte_range);
1607   return s;
1608 }
1609
1610 GST_CHECK_MAIN (rtspserver);