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