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