tests: add unit test for correct handling of Require headers
[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   /* clean up and iterate so the clean-up can finish */
651   g_free (session);
652   gst_sdp_message_free (sdp_message);
653   gst_rtsp_connection_free (conn);
654   stop_server ();
655   iterate ();
656 }
657
658 GST_END_TEST;
659
660 GST_START_TEST (test_setup_with_require_header)
661 {
662   GstRTSPConnection *conn;
663   GstSDPMessage *sdp_message = NULL;
664   const GstSDPMedia *sdp_media;
665   const gchar *video_control;
666   GstRTSPRange client_ports;
667   gchar *session = NULL;
668   gchar *unsupported = NULL;
669   GstRTSPTransport *video_transport = NULL;
670
671   start_server ();
672
673   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
674
675   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
676
677   /* get control strings from DESCRIBE response */
678   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
679   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
680   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
681
682   get_client_ports (&client_ports);
683
684   /* send SETUP request for video, with single Require header */
685   fail_unless_equals_int (do_setup_full (conn, video_control, &client_ports,
686           "funky-feature", &session, &video_transport, &unsupported),
687       GST_RTSP_STS_OPTION_NOT_SUPPORTED);
688   fail_unless_equals_string (unsupported, "funky-feature");
689   g_free (unsupported);
690   unsupported = NULL;
691
692   /* send SETUP request for video, with multiple Require headers */
693   fail_unless_equals_int (do_setup_full (conn, video_control, &client_ports,
694           "funky-feature, foo-bar, superburst", &session, &video_transport,
695           &unsupported), GST_RTSP_STS_OPTION_NOT_SUPPORTED);
696   fail_unless_equals_string (unsupported, "funky-feature, foo-bar, superburst");
697   g_free (unsupported);
698   unsupported = NULL;
699
700   /* ok, just do a normal setup then (make sure that still works) */
701   fail_unless_equals_int (do_setup (conn, video_control, &client_ports,
702           &session, &video_transport), GST_RTSP_STS_OK);
703
704   GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
705
706   /* check response from SETUP */
707   fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
708   fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
709   fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
710   fail_unless (video_transport->mode_play);
711   gst_rtsp_transport_free (video_transport);
712
713   /* clean up and iterate so the clean-up can finish */
714   g_free (session);
715   gst_sdp_message_free (sdp_message);
716   gst_rtsp_connection_free (conn);
717   stop_server ();
718   iterate ();
719 }
720
721 GST_END_TEST;
722
723 GST_START_TEST (test_setup_non_existing_stream)
724 {
725   GstRTSPConnection *conn;
726   GstRTSPRange client_ports;
727
728   start_server ();
729
730   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
731
732   get_client_ports (&client_ports);
733
734   /* send SETUP request with a non-existing stream and check that we get a
735    * 404 Not Found */
736   fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
737           NULL) == GST_RTSP_STS_NOT_FOUND);
738
739   /* clean up and iterate so the clean-up can finish */
740   gst_rtsp_connection_free (conn);
741   stop_server ();
742   iterate ();
743 }
744
745 GST_END_TEST;
746
747 static void
748 receive_rtp (GSocket * socket, GSocketAddress ** addr)
749 {
750   GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
751
752   for (;;) {
753     gssize bytes;
754     GstMapInfo map = GST_MAP_INFO_INIT;
755     GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
756
757     gst_buffer_map (buffer, &map, GST_MAP_WRITE);
758     bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
759         map.maxsize, NULL, NULL);
760     fail_unless (bytes > 0);
761     gst_buffer_unmap (buffer, &map);
762     gst_buffer_set_size (buffer, bytes);
763
764     if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer)) {
765       gst_rtp_buffer_unmap (&rtpbuffer);
766       break;
767     }
768
769     if (addr)
770       g_clear_object (addr);
771   }
772
773   gst_buffer_unref (buffer);
774 }
775
776 static void
777 receive_rtcp (GSocket * socket, GSocketAddress ** addr, GstRTCPType type)
778 {
779   GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
780
781   for (;;) {
782     gssize bytes;
783     GstMapInfo map = GST_MAP_INFO_INIT;
784
785     gst_buffer_map (buffer, &map, GST_MAP_WRITE);
786     bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
787         map.maxsize, NULL, NULL);
788     fail_unless (bytes > 0);
789     gst_buffer_unmap (buffer, &map);
790     gst_buffer_set_size (buffer, bytes);
791
792     if (gst_rtcp_buffer_validate (buffer)) {
793       GstRTCPBuffer rtcpbuffer = GST_RTCP_BUFFER_INIT;
794       GstRTCPPacket packet;
795
796       if (type) {
797         fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcpbuffer));
798         fail_unless (gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet));
799         do {
800           if (gst_rtcp_packet_get_type (&packet) == type) {
801             gst_rtcp_buffer_unmap (&rtcpbuffer);
802             goto done;
803           }
804         } while (gst_rtcp_packet_move_to_next (&packet));
805         gst_rtcp_buffer_unmap (&rtcpbuffer);
806       } else {
807         break;
808       }
809     }
810
811     if (addr)
812       g_clear_object (addr);
813   }
814
815 done:
816
817   gst_buffer_unref (buffer);
818 }
819
820 static void
821 do_test_play (const gchar * range)
822 {
823   GstRTSPConnection *conn;
824   GstSDPMessage *sdp_message = NULL;
825   const GstSDPMedia *sdp_media;
826   const gchar *video_control;
827   const gchar *audio_control;
828   GstRTSPRange client_port;
829   gchar *session = NULL;
830   GstRTSPTransport *video_transport = NULL;
831   GstRTSPTransport *audio_transport = NULL;
832   GSocket *rtp_socket, *rtcp_socket;
833   gchar *range_out = NULL;
834
835   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
836
837   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
838
839   /* get control strings from DESCRIBE response */
840   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
841   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
842   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
843   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
844   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
845
846   get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
847
848   /* do SETUP for video and audio */
849   fail_unless (do_setup (conn, video_control, &client_port, &session,
850           &video_transport) == GST_RTSP_STS_OK);
851   fail_unless (do_setup (conn, audio_control, &client_port, &session,
852           &audio_transport) == GST_RTSP_STS_OK);
853
854   /* send PLAY request and check that we get 200 OK */
855   fail_unless (do_request (conn, GST_RTSP_PLAY, NULL, session, NULL, range,
856           NULL, NULL, NULL, NULL, NULL, &range_out) == GST_RTSP_STS_OK);
857   if (range)
858     fail_unless_equals_string (range, range_out);
859   g_free (range_out);
860
861   receive_rtp (rtp_socket, NULL);
862   receive_rtcp (rtcp_socket, NULL, 0);
863
864   /* send TEARDOWN request and check that we get 200 OK */
865   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
866           session) == GST_RTSP_STS_OK);
867
868   /* FIXME: The rtsp-server always disconnects the transport before
869    * sending the RTCP BYE
870    * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
871    */
872
873   /* clean up and iterate so the clean-up can finish */
874   g_object_unref (rtp_socket);
875   g_object_unref (rtcp_socket);
876   g_free (session);
877   gst_rtsp_transport_free (video_transport);
878   gst_rtsp_transport_free (audio_transport);
879   gst_sdp_message_free (sdp_message);
880   gst_rtsp_connection_free (conn);
881 }
882
883
884 GST_START_TEST (test_play)
885 {
886   start_server ();
887
888   do_test_play (NULL);
889
890   stop_server ();
891   iterate ();
892 }
893
894 GST_END_TEST;
895
896 GST_START_TEST (test_play_without_session)
897 {
898   GstRTSPConnection *conn;
899
900   start_server ();
901
902   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
903
904   /* send PLAY request without a session and check that we get a
905    * 454 Session Not Found */
906   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
907           NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
908
909   /* clean up and iterate so the clean-up can finish */
910   gst_rtsp_connection_free (conn);
911   stop_server ();
912   iterate ();
913 }
914
915 GST_END_TEST;
916
917 GST_START_TEST (test_bind_already_in_use)
918 {
919   GstRTSPServer *serv;
920   GSocketService *service;
921   GError *error = NULL;
922   guint16 port;
923   gchar *port_str;
924
925   serv = gst_rtsp_server_new ();
926   service = g_socket_service_new ();
927
928   /* bind service to port */
929   port =
930       g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL,
931       &error);
932   g_assert_no_error (error);
933
934   port_str = g_strdup_printf ("%d\n", port);
935
936   /* try to bind server to the same port */
937   g_object_set (serv, "service", port_str, NULL);
938   g_free (port_str);
939
940   /* attach to default main context */
941   fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
942
943   /* cleanup */
944   g_object_unref (serv);
945   g_socket_service_stop (service);
946   g_object_unref (service);
947 }
948
949 GST_END_TEST;
950
951
952 GST_START_TEST (test_play_multithreaded)
953 {
954   GstRTSPThreadPool *pool;
955
956   pool = gst_rtsp_server_get_thread_pool (server);
957   gst_rtsp_thread_pool_set_max_threads (pool, 2);
958   g_object_unref (pool);
959
960   start_server ();
961
962   do_test_play (NULL);
963
964   stop_server ();
965   iterate ();
966 }
967
968 GST_END_TEST;
969
970 enum
971 {
972   BLOCK_ME,
973   BLOCKED,
974   UNBLOCK
975 };
976
977
978 static void
979 media_constructed_block (GstRTSPMediaFactory * factory,
980     GstRTSPMedia * media, gpointer user_data)
981 {
982   gint *block_state = user_data;
983
984   g_mutex_lock (&check_mutex);
985
986   *block_state = BLOCKED;
987   g_cond_broadcast (&check_cond);
988
989   while (*block_state != UNBLOCK)
990     g_cond_wait (&check_cond, &check_mutex);
991   g_mutex_unlock (&check_mutex);
992 }
993
994
995 GST_START_TEST (test_play_multithreaded_block_in_describe)
996 {
997   GstRTSPConnection *conn;
998   GstRTSPMountPoints *mounts;
999   GstRTSPMediaFactory *factory;
1000   gint block_state = BLOCK_ME;
1001   GstRTSPMessage *request;
1002   GstRTSPMessage *response;
1003   GstRTSPStatusCode code;
1004   GstRTSPThreadPool *pool;
1005
1006   pool = gst_rtsp_server_get_thread_pool (server);
1007   gst_rtsp_thread_pool_set_max_threads (pool, 2);
1008   g_object_unref (pool);
1009
1010   mounts = gst_rtsp_server_get_mount_points (server);
1011   fail_unless (mounts != NULL);
1012   factory = gst_rtsp_media_factory_new ();
1013   gst_rtsp_media_factory_set_launch (factory,
1014       "( " VIDEO_PIPELINE "  " AUDIO_PIPELINE " )");
1015   g_signal_connect (factory, "media-constructed",
1016       G_CALLBACK (media_constructed_block), &block_state);
1017   gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT "2", factory);
1018   g_object_unref (mounts);
1019
1020   start_server ();
1021
1022   conn = connect_to_server (test_port, TEST_MOUNT_POINT "2");
1023   iterate ();
1024
1025   /* do describe, it will not return now as we've blocked it */
1026   request = create_request (conn, GST_RTSP_DESCRIBE, NULL);
1027   fail_unless (send_request (conn, request));
1028   gst_rtsp_message_free (request);
1029
1030   g_mutex_lock (&check_mutex);
1031   while (block_state != BLOCKED)
1032     g_cond_wait (&check_cond, &check_mutex);
1033   g_mutex_unlock (&check_mutex);
1034
1035   /* Do a second connection while the first one is blocked */
1036   do_test_play (NULL);
1037
1038   /* Now unblock the describe */
1039   g_mutex_lock (&check_mutex);
1040   block_state = UNBLOCK;
1041   g_cond_broadcast (&check_cond);
1042   g_mutex_unlock (&check_mutex);
1043
1044   response = read_response (conn);
1045   gst_rtsp_message_parse_response (response, &code, NULL, NULL);
1046   fail_unless (code == GST_RTSP_STS_OK);
1047   gst_rtsp_message_free (response);
1048
1049
1050   gst_rtsp_connection_free (conn);
1051   stop_server ();
1052   iterate ();
1053
1054 }
1055
1056 GST_END_TEST;
1057
1058
1059 static void
1060 new_session_timeout_one (GstRTSPClient * client,
1061     GstRTSPSession * session, gpointer user_data)
1062 {
1063   gst_rtsp_session_set_timeout (session, 1);
1064
1065   g_signal_handlers_disconnect_by_func (client, new_session_timeout_one,
1066       user_data);
1067 }
1068
1069 static void
1070 session_connected_new_session_cb (GstRTSPServer * server,
1071     GstRTSPClient * client, gpointer user_data)
1072 {
1073
1074   g_signal_connect (client, "new-session", user_data, NULL);
1075 }
1076
1077 GST_START_TEST (test_play_multithreaded_timeout_client)
1078 {
1079   GstRTSPConnection *conn;
1080   GstSDPMessage *sdp_message = NULL;
1081   const GstSDPMedia *sdp_media;
1082   const gchar *video_control;
1083   const gchar *audio_control;
1084   GstRTSPRange client_port;
1085   gchar *session = NULL;
1086   GstRTSPTransport *video_transport = NULL;
1087   GstRTSPTransport *audio_transport = NULL;
1088   GstRTSPSessionPool *pool;
1089   GstRTSPThreadPool *thread_pool;
1090
1091   thread_pool = gst_rtsp_server_get_thread_pool (server);
1092   gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1093   g_object_unref (thread_pool);
1094
1095   pool = gst_rtsp_server_get_session_pool (server);
1096   g_signal_connect (server, "client-connected",
1097       G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1098
1099   start_server ();
1100
1101
1102   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1103
1104   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1105
1106   /* get control strings from DESCRIBE response */
1107   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1108   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1109   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1110   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1111   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1112
1113   get_client_ports (&client_port);
1114
1115   /* do SETUP for video and audio */
1116   fail_unless (do_setup (conn, video_control, &client_port, &session,
1117           &video_transport) == GST_RTSP_STS_OK);
1118   fail_unless (do_setup (conn, audio_control, &client_port, &session,
1119           &audio_transport) == GST_RTSP_STS_OK);
1120
1121   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1122
1123   /* send PLAY request and check that we get 200 OK */
1124   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1125           session) == GST_RTSP_STS_OK);
1126
1127   sleep (7);
1128
1129   fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1130   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 0);
1131
1132   /* clean up and iterate so the clean-up can finish */
1133   g_object_unref (pool);
1134   g_free (session);
1135   gst_rtsp_transport_free (video_transport);
1136   gst_rtsp_transport_free (audio_transport);
1137   gst_sdp_message_free (sdp_message);
1138   gst_rtsp_connection_free (conn);
1139
1140   stop_server ();
1141   iterate ();
1142 }
1143
1144 GST_END_TEST;
1145
1146
1147 GST_START_TEST (test_play_multithreaded_timeout_session)
1148 {
1149   GstRTSPConnection *conn;
1150   GstSDPMessage *sdp_message = NULL;
1151   const GstSDPMedia *sdp_media;
1152   const gchar *video_control;
1153   const gchar *audio_control;
1154   GstRTSPRange client_port;
1155   gchar *session1 = NULL;
1156   gchar *session2 = NULL;
1157   GstRTSPTransport *video_transport = NULL;
1158   GstRTSPTransport *audio_transport = NULL;
1159   GstRTSPSessionPool *pool;
1160   GstRTSPThreadPool *thread_pool;
1161
1162   thread_pool = gst_rtsp_server_get_thread_pool (server);
1163   gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1164   g_object_unref (thread_pool);
1165
1166   pool = gst_rtsp_server_get_session_pool (server);
1167   g_signal_connect (server, "client-connected",
1168       G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1169
1170   start_server ();
1171
1172
1173   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1174
1175   gst_rtsp_connection_set_remember_session_id (conn, FALSE);
1176
1177   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1178
1179   /* get control strings from DESCRIBE response */
1180   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1181   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1182   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1183   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1184   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1185
1186   get_client_ports (&client_port);
1187
1188   /* do SETUP for video and audio */
1189   fail_unless (do_setup (conn, video_control, &client_port, &session1,
1190           &video_transport) == GST_RTSP_STS_OK);
1191   fail_unless (do_setup (conn, audio_control, &client_port, &session2,
1192           &audio_transport) == GST_RTSP_STS_OK);
1193
1194   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 2);
1195
1196   /* send PLAY request and check that we get 200 OK */
1197   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1198           session1) == GST_RTSP_STS_OK);
1199   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1200           session2) == GST_RTSP_STS_OK);
1201
1202   sleep (7);
1203
1204   fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1205
1206   /* send TEARDOWN request and check that we get 454 Session Not found */
1207   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1208           session1) == GST_RTSP_STS_SESSION_NOT_FOUND);
1209
1210   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1211           session2) == GST_RTSP_STS_OK);
1212
1213   /* clean up and iterate so the clean-up can finish */
1214   g_object_unref (pool);
1215   g_free (session1);
1216   g_free (session2);
1217   gst_rtsp_transport_free (video_transport);
1218   gst_rtsp_transport_free (audio_transport);
1219   gst_sdp_message_free (sdp_message);
1220   gst_rtsp_connection_free (conn);
1221
1222   stop_server ();
1223   iterate ();
1224 }
1225
1226 GST_END_TEST;
1227
1228
1229 GST_START_TEST (test_play_disconnect)
1230 {
1231   GstRTSPConnection *conn;
1232   GstSDPMessage *sdp_message = NULL;
1233   const GstSDPMedia *sdp_media;
1234   const gchar *video_control;
1235   const gchar *audio_control;
1236   GstRTSPRange client_port;
1237   gchar *session = NULL;
1238   GstRTSPTransport *video_transport = NULL;
1239   GstRTSPTransport *audio_transport = NULL;
1240   GstRTSPSessionPool *pool;
1241
1242   pool = gst_rtsp_server_get_session_pool (server);
1243   g_signal_connect (server, "client-connected",
1244       G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1245
1246   start_server ();
1247
1248   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1249
1250   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1251
1252   /* get control strings from DESCRIBE response */
1253   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1254   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1255   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1256   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1257   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1258
1259   get_client_ports (&client_port);
1260
1261   /* do SETUP for video and audio */
1262   fail_unless (do_setup (conn, video_control, &client_port, &session,
1263           &video_transport) == GST_RTSP_STS_OK);
1264   fail_unless (do_setup (conn, audio_control, &client_port, &session,
1265           &audio_transport) == GST_RTSP_STS_OK);
1266
1267   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1268
1269   /* send PLAY request and check that we get 200 OK */
1270   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1271           session) == GST_RTSP_STS_OK);
1272
1273   gst_rtsp_connection_free (conn);
1274
1275   sleep (7);
1276
1277   fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1278   fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1279
1280
1281   /* clean up and iterate so the clean-up can finish */
1282   g_object_unref (pool);
1283   g_free (session);
1284   gst_rtsp_transport_free (video_transport);
1285   gst_rtsp_transport_free (audio_transport);
1286   gst_sdp_message_free (sdp_message);
1287
1288   stop_server ();
1289   iterate ();
1290 }
1291
1292 GST_END_TEST;
1293
1294 /* Only different with test_play is the specific ports selected */
1295
1296 GST_START_TEST (test_play_specific_server_port)
1297 {
1298   GstRTSPMountPoints *mounts;
1299   gchar *service;
1300   GstRTSPMediaFactory *factory;
1301   GstRTSPAddressPool *pool;
1302   GstRTSPConnection *conn;
1303   GstSDPMessage *sdp_message = NULL;
1304   const GstSDPMedia *sdp_media;
1305   const gchar *video_control;
1306   GstRTSPRange client_port;
1307   gchar *session = NULL;
1308   GstRTSPTransport *video_transport = NULL;
1309   GSocket *rtp_socket, *rtcp_socket;
1310   GSocketAddress *rtp_address, *rtcp_address;
1311   guint16 rtp_port, rtcp_port;
1312
1313   mounts = gst_rtsp_server_get_mount_points (server);
1314
1315   factory = gst_rtsp_media_factory_new ();
1316   pool = gst_rtsp_address_pool_new ();
1317   gst_rtsp_address_pool_add_range (pool, GST_RTSP_ADDRESS_POOL_ANY_IPV4,
1318       GST_RTSP_ADDRESS_POOL_ANY_IPV4, 7770, 7780, 0);
1319   gst_rtsp_media_factory_set_address_pool (factory, pool);
1320   g_object_unref (pool);
1321   gst_rtsp_media_factory_set_launch (factory, "( " VIDEO_PIPELINE " )");
1322   gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
1323   g_object_unref (mounts);
1324
1325   /* set port to any */
1326   gst_rtsp_server_set_service (server, "0");
1327
1328   /* attach to default main context */
1329   source_id = gst_rtsp_server_attach (server, NULL);
1330   fail_if (source_id == 0);
1331
1332   /* get port */
1333   service = gst_rtsp_server_get_service (server);
1334   test_port = atoi (service);
1335   fail_unless (test_port != 0);
1336   g_free (service);
1337
1338   GST_DEBUG ("rtsp server listening on port %d", test_port);
1339
1340
1341   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1342
1343   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1344
1345   /* get control strings from DESCRIBE response */
1346   fail_unless (gst_sdp_message_medias_len (sdp_message) == 1);
1347   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1348   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1349
1350   get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
1351
1352   /* do SETUP for video */
1353   fail_unless (do_setup (conn, video_control, &client_port, &session,
1354           &video_transport) == GST_RTSP_STS_OK);
1355
1356   /* send PLAY request and check that we get 200 OK */
1357   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1358           session) == GST_RTSP_STS_OK);
1359
1360   receive_rtp (rtp_socket, &rtp_address);
1361   receive_rtcp (rtcp_socket, &rtcp_address, 0);
1362
1363   fail_unless (G_IS_INET_SOCKET_ADDRESS (rtp_address));
1364   fail_unless (G_IS_INET_SOCKET_ADDRESS (rtcp_address));
1365   rtp_port =
1366       g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_address));
1367   rtcp_port =
1368       g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtcp_address));
1369   fail_unless (rtp_port >= 7770 && rtp_port <= 7780 && rtp_port % 2 == 0);
1370   fail_unless (rtcp_port >= 7770 && rtcp_port <= 7780 && rtcp_port % 2 == 1);
1371   fail_unless (rtp_port + 1 == rtcp_port);
1372
1373   g_object_unref (rtp_address);
1374   g_object_unref (rtcp_address);
1375
1376   /* send TEARDOWN request and check that we get 200 OK */
1377   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1378           session) == GST_RTSP_STS_OK);
1379
1380   /* FIXME: The rtsp-server always disconnects the transport before
1381    * sending the RTCP BYE
1382    * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
1383    */
1384
1385   /* clean up and iterate so the clean-up can finish */
1386   g_object_unref (rtp_socket);
1387   g_object_unref (rtcp_socket);
1388   g_free (session);
1389   gst_rtsp_transport_free (video_transport);
1390   gst_sdp_message_free (sdp_message);
1391   gst_rtsp_connection_free (conn);
1392
1393
1394   stop_server ();
1395   iterate ();
1396 }
1397
1398 GST_END_TEST;
1399
1400
1401 GST_START_TEST (test_play_smpte_range)
1402 {
1403   start_server ();
1404
1405   do_test_play ("npt=5-");
1406   do_test_play ("smpte=0:00:00-");
1407   do_test_play ("smpte=1:00:00-");
1408   do_test_play ("smpte=1:00:03-");
1409   do_test_play ("clock=20120321T152256Z-");
1410
1411   stop_server ();
1412   iterate ();
1413 }
1414
1415 GST_END_TEST;
1416
1417
1418 static Suite *
1419 rtspserver_suite (void)
1420 {
1421   Suite *s = suite_create ("rtspserver");
1422   TCase *tc = tcase_create ("general");
1423
1424   suite_add_tcase (s, tc);
1425   tcase_add_checked_fixture (tc, setup, teardown);
1426   tcase_set_timeout (tc, 20);
1427   tcase_add_test (tc, test_connect);
1428   tcase_add_test (tc, test_describe);
1429   tcase_add_test (tc, test_describe_non_existing_mount_point);
1430   tcase_add_test (tc, test_setup);
1431   tcase_add_test (tc, test_setup_with_require_header);
1432   tcase_add_test (tc, test_setup_non_existing_stream);
1433   tcase_add_test (tc, test_play);
1434   tcase_add_test (tc, test_play_without_session);
1435   tcase_add_test (tc, test_bind_already_in_use);
1436   tcase_add_test (tc, test_play_multithreaded);
1437   tcase_add_test (tc, test_play_multithreaded_block_in_describe);
1438   tcase_add_test (tc, test_play_multithreaded_timeout_client);
1439   tcase_add_test (tc, test_play_multithreaded_timeout_session);
1440   tcase_add_test (tc, test_play_disconnect);
1441   tcase_add_test (tc, test_play_specific_server_port);
1442   tcase_add_test (tc, test_play_smpte_range);
1443   return s;
1444 }
1445
1446 GST_CHECK_MAIN (rtspserver);