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