rtsp-client: Avoid reuse of channel numbers for interleaved
[platform/upstream/gstreamer.git] / tests / check / gst / client.c
1 /* GStreamer
2  * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include <gst/check/gstcheck.h>
21
22 #include <rtsp-client.h>
23
24 #define VIDEO_PIPELINE "videotestsrc ! " \
25   "video/x-raw,width=352,height=288 ! " \
26   "rtpgstpay name=pay0 pt=96"
27 #define AUDIO_PIPELINE "audiotestsrc ! " \
28   "audio/x-raw,rate=8000 ! " \
29   "rtpgstpay name=pay1 pt=97"
30
31 static gchar *session_id;
32 static gint cseq;
33 static guint expected_session_timeout = 60;
34 static const gchar *expected_unsupported_header;
35
36 static gboolean
37 test_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
38     gboolean close, gpointer user_data)
39 {
40   GstRTSPStatusCode code;
41   const gchar *reason;
42   GstRTSPVersion version;
43
44   fail_unless (gst_rtsp_message_get_type (response) ==
45       GST_RTSP_MESSAGE_RESPONSE);
46
47   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
48           &version)
49       == GST_RTSP_OK);
50   fail_unless (code == GST_RTSP_STS_OK);
51   fail_unless (g_str_equal (reason, "OK"));
52   fail_unless (version == GST_RTSP_VERSION_1_0);
53
54   return TRUE;
55 }
56
57 static gboolean
58 test_response_400 (GstRTSPClient * client, GstRTSPMessage * response,
59     gboolean close, gpointer user_data)
60 {
61   GstRTSPStatusCode code;
62   const gchar *reason;
63   GstRTSPVersion version;
64
65   fail_unless (gst_rtsp_message_get_type (response) ==
66       GST_RTSP_MESSAGE_RESPONSE);
67
68   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
69           &version)
70       == GST_RTSP_OK);
71   fail_unless (code == GST_RTSP_STS_BAD_REQUEST);
72   fail_unless (g_str_equal (reason, "Bad Request"));
73   fail_unless (version == GST_RTSP_VERSION_1_0);
74
75   return TRUE;
76 }
77
78 static gboolean
79 test_response_404 (GstRTSPClient * client, GstRTSPMessage * response,
80     gboolean close, gpointer user_data)
81 {
82   GstRTSPStatusCode code;
83   const gchar *reason;
84   GstRTSPVersion version;
85
86   fail_unless (gst_rtsp_message_get_type (response) ==
87       GST_RTSP_MESSAGE_RESPONSE);
88
89   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
90           &version)
91       == GST_RTSP_OK);
92   fail_unless (code == GST_RTSP_STS_NOT_FOUND);
93   fail_unless (g_str_equal (reason, "Not Found"));
94   fail_unless (version == GST_RTSP_VERSION_1_0);
95
96   return TRUE;
97 }
98
99 static gboolean
100 test_response_454 (GstRTSPClient * client, GstRTSPMessage * response,
101     gboolean close, gpointer user_data)
102 {
103   GstRTSPStatusCode code;
104   const gchar *reason;
105   GstRTSPVersion version;
106
107   fail_unless (gst_rtsp_message_get_type (response) ==
108       GST_RTSP_MESSAGE_RESPONSE);
109
110   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
111           &version)
112       == GST_RTSP_OK);
113   fail_unless (code == GST_RTSP_STS_SESSION_NOT_FOUND);
114   fail_unless (g_str_equal (reason, "Session Not Found"));
115   fail_unless (version == GST_RTSP_VERSION_1_0);
116
117   return TRUE;
118 }
119
120 static gboolean
121 test_response_551 (GstRTSPClient * client, GstRTSPMessage * response,
122     gboolean close, gpointer user_data)
123 {
124   GstRTSPStatusCode code;
125   const gchar *reason;
126   GstRTSPVersion version;
127   gchar *options;
128
129   fail_unless (gst_rtsp_message_get_type (response) ==
130       GST_RTSP_MESSAGE_RESPONSE);
131
132   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
133           &version)
134       == GST_RTSP_OK);
135   fail_unless (code == GST_RTSP_STS_OPTION_NOT_SUPPORTED);
136   fail_unless (g_str_equal (reason, "Option not supported"));
137   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_UNSUPPORTED,
138           &options, 0) == GST_RTSP_OK);
139   fail_unless (!g_strcmp0 (expected_unsupported_header, options));
140   fail_unless (version == GST_RTSP_VERSION_1_0);
141
142   return TRUE;
143 }
144
145 static void
146 create_connection (GstRTSPConnection ** conn)
147 {
148   GSocket *sock;
149   GError *error = NULL;
150
151   sock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
152       G_SOCKET_PROTOCOL_TCP, &error);
153   g_assert_no_error (error);
154   fail_unless (gst_rtsp_connection_create_from_socket (sock, "127.0.0.1", 444,
155           NULL, conn) == GST_RTSP_OK);
156   g_object_unref (sock);
157 }
158
159 static GstRTSPClient *
160 setup_client (const gchar * launch_line)
161 {
162   GstRTSPClient *client;
163   GstRTSPSessionPool *session_pool;
164   GstRTSPMountPoints *mount_points;
165   GstRTSPMediaFactory *factory;
166   GstRTSPThreadPool *thread_pool;
167
168   client = gst_rtsp_client_new ();
169
170   session_pool = gst_rtsp_session_pool_new ();
171   gst_rtsp_client_set_session_pool (client, session_pool);
172
173   mount_points = gst_rtsp_mount_points_new ();
174   factory = gst_rtsp_media_factory_new ();
175   if (launch_line == NULL)
176     gst_rtsp_media_factory_set_launch (factory,
177         "( " VIDEO_PIPELINE "  " AUDIO_PIPELINE " )");
178   else
179     gst_rtsp_media_factory_set_launch (factory, launch_line);
180
181   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
182   gst_rtsp_client_set_mount_points (client, mount_points);
183
184   thread_pool = gst_rtsp_thread_pool_new ();
185   gst_rtsp_client_set_thread_pool (client, thread_pool);
186
187   g_object_unref (mount_points);
188   g_object_unref (session_pool);
189   g_object_unref (thread_pool);
190
191   return client;
192 }
193
194 static void
195 teardown_client (GstRTSPClient * client)
196 {
197   gst_rtsp_client_set_thread_pool (client, NULL);
198   g_object_unref (client);
199 }
200
201 static gchar *
202 check_requirements_cb (GstRTSPClient * client, GstRTSPContext * ctx,
203     gchar ** req, gpointer user_data)
204 {
205   int index = 0;
206   GString *result = g_string_new ("");
207
208   while (req[index] != NULL) {
209     if (g_strcmp0 (req[index], "test-requirements")) {
210       if (result->len > 0)
211         g_string_append (result, ", ");
212       g_string_append (result, req[index]);
213     }
214     index++;
215   }
216
217   return g_string_free (result, FALSE);
218 }
219
220 GST_START_TEST (test_require)
221 {
222   GstRTSPClient *client;
223   GstRTSPMessage request = { 0, };
224   gchar *str;
225
226   client = gst_rtsp_client_new ();
227
228   /* require header without handler */
229   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
230           "rtsp://localhost/test") == GST_RTSP_OK);
231   str = g_strdup_printf ("test-not-supported1");
232   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
233   g_free (str);
234
235   expected_unsupported_header = "test-not-supported1";
236   gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
237   fail_unless (gst_rtsp_client_handle_message (client,
238           &request) == GST_RTSP_OK);
239   gst_rtsp_message_unset (&request);
240
241   g_signal_connect (G_OBJECT (client), "check-requirements",
242       G_CALLBACK (check_requirements_cb), NULL);
243
244   /* one supported option */
245   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
246           "rtsp://localhost/test") == GST_RTSP_OK);
247   str = g_strdup_printf ("test-requirements");
248   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
249   g_free (str);
250
251   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
252   fail_unless (gst_rtsp_client_handle_message (client,
253           &request) == GST_RTSP_OK);
254   gst_rtsp_message_unset (&request);
255
256   /* unsupported option */
257   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
258           "rtsp://localhost/test") == GST_RTSP_OK);
259   str = g_strdup_printf ("test-not-supported1");
260   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
261   g_free (str);
262
263   expected_unsupported_header = "test-not-supported1";
264   gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
265   fail_unless (gst_rtsp_client_handle_message (client,
266           &request) == GST_RTSP_OK);
267   gst_rtsp_message_unset (&request);
268
269   /* more than one unsupported options */
270   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
271           "rtsp://localhost/test") == GST_RTSP_OK);
272   str = g_strdup_printf ("test-not-supported1");
273   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
274   g_free (str);
275   str = g_strdup_printf ("test-not-supported2");
276   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
277   g_free (str);
278
279   expected_unsupported_header = "test-not-supported1, test-not-supported2";
280   gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
281   fail_unless (gst_rtsp_client_handle_message (client,
282           &request) == GST_RTSP_OK);
283   gst_rtsp_message_unset (&request);
284
285   /* supported and unsupported together */
286   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
287           "rtsp://localhost/test") == GST_RTSP_OK);
288   str = g_strdup_printf ("test-not-supported1");
289   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
290   g_free (str);
291   str = g_strdup_printf ("test-requirements");
292   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
293   g_free (str);
294   str = g_strdup_printf ("test-not-supported2");
295   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
296   g_free (str);
297
298   expected_unsupported_header = "test-not-supported1, test-not-supported2";
299   gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
300   fail_unless (gst_rtsp_client_handle_message (client,
301           &request) == GST_RTSP_OK);
302   gst_rtsp_message_unset (&request);
303
304   g_object_unref (client);
305 }
306
307 GST_END_TEST;
308
309 GST_START_TEST (test_request)
310 {
311   GstRTSPClient *client;
312   GstRTSPMessage request = { 0, };
313   gchar *str;
314   GstRTSPConnection *conn;
315
316   client = gst_rtsp_client_new ();
317
318   /* OPTIONS with invalid url */
319   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
320           "foopy://padoop/") == GST_RTSP_OK);
321   str = g_strdup_printf ("%d", cseq);
322   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
323   g_free (str);
324
325   gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
326   fail_unless (gst_rtsp_client_handle_message (client,
327           &request) == GST_RTSP_OK);
328
329   gst_rtsp_message_unset (&request);
330
331   /* OPTIONS with unknown session id */
332   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
333           "rtsp://localhost/test") == GST_RTSP_OK);
334   str = g_strdup_printf ("%d", cseq);
335   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
336   g_free (str);
337   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, "foobar");
338
339   gst_rtsp_client_set_send_func (client, test_response_454, NULL, NULL);
340   fail_unless (gst_rtsp_client_handle_message (client,
341           &request) == GST_RTSP_OK);
342
343   gst_rtsp_message_unset (&request);
344
345   /* OPTIONS with an absolute path instead of an absolute url */
346   /* set host information */
347   create_connection (&conn);
348   fail_unless (gst_rtsp_client_set_connection (client, conn));
349   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
350           "/test") == GST_RTSP_OK);
351   str = g_strdup_printf ("%d", cseq);
352   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
353   g_free (str);
354
355   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
356   fail_unless (gst_rtsp_client_handle_message (client,
357           &request) == GST_RTSP_OK);
358   gst_rtsp_message_unset (&request);
359
360   /* OPTIONS with an absolute path instead of an absolute url with invalid
361    * host information */
362   g_object_unref (client);
363   client = gst_rtsp_client_new ();
364   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
365           "/test") == GST_RTSP_OK);
366   str = g_strdup_printf ("%d", cseq);
367   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
368   g_free (str);
369
370   gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
371   fail_unless (gst_rtsp_client_handle_message (client,
372           &request) == GST_RTSP_OK);
373   gst_rtsp_message_unset (&request);
374
375   g_object_unref (client);
376 }
377
378 GST_END_TEST;
379
380 static gboolean
381 test_option_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
382     gboolean close, gpointer user_data)
383 {
384   GstRTSPStatusCode code;
385   const gchar *reason;
386   GstRTSPVersion version;
387   gchar *str;
388   GstRTSPMethod methods;
389
390   fail_unless (gst_rtsp_message_get_type (response) ==
391       GST_RTSP_MESSAGE_RESPONSE);
392
393   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
394           &version)
395       == GST_RTSP_OK);
396   fail_unless (code == GST_RTSP_STS_OK);
397   fail_unless (g_str_equal (reason, "OK"));
398   fail_unless (version == GST_RTSP_VERSION_1_0);
399
400   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
401           0) == GST_RTSP_OK);
402   fail_unless (atoi (str) == cseq++);
403
404   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_PUBLIC, &str,
405           0) == GST_RTSP_OK);
406
407   methods = gst_rtsp_options_from_text (str);
408   fail_if (methods == 0);
409   fail_unless (methods == (GST_RTSP_DESCRIBE |
410           GST_RTSP_ANNOUNCE |
411           GST_RTSP_OPTIONS |
412           GST_RTSP_PAUSE |
413           GST_RTSP_PLAY |
414           GST_RTSP_RECORD |
415           GST_RTSP_SETUP |
416           GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN));
417
418   return TRUE;
419 }
420
421 GST_START_TEST (test_options)
422 {
423   GstRTSPClient *client;
424   GstRTSPMessage request = { 0, };
425   gchar *str;
426
427   client = gst_rtsp_client_new ();
428
429   /* simple OPTIONS */
430   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
431           "rtsp://localhost/test") == GST_RTSP_OK);
432   str = g_strdup_printf ("%d", cseq);
433   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
434   g_free (str);
435
436   gst_rtsp_client_set_send_func (client, test_option_response_200, NULL, NULL);
437   fail_unless (gst_rtsp_client_handle_message (client,
438           &request) == GST_RTSP_OK);
439   gst_rtsp_message_unset (&request);
440
441   g_object_unref (client);
442 }
443
444 GST_END_TEST;
445
446 GST_START_TEST (test_describe)
447 {
448   GstRTSPClient *client;
449   GstRTSPMessage request = { 0, };
450   gchar *str;
451
452   client = gst_rtsp_client_new ();
453
454   /* simple DESCRIBE for non-existing url */
455   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
456           "rtsp://localhost/test") == GST_RTSP_OK);
457   str = g_strdup_printf ("%d", cseq);
458   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
459   g_free (str);
460
461   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
462   fail_unless (gst_rtsp_client_handle_message (client,
463           &request) == GST_RTSP_OK);
464   gst_rtsp_message_unset (&request);
465
466   g_object_unref (client);
467
468   /* simple DESCRIBE for an existing url */
469   client = setup_client (NULL);
470   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
471           "rtsp://localhost/test") == GST_RTSP_OK);
472   str = g_strdup_printf ("%d", cseq);
473   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
474   g_free (str);
475
476   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
477   fail_unless (gst_rtsp_client_handle_message (client,
478           &request) == GST_RTSP_OK);
479   gst_rtsp_message_unset (&request);
480
481   teardown_client (client);
482 }
483
484 GST_END_TEST;
485
486 static const gchar *expected_transport = NULL;
487
488 static gboolean
489 test_setup_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
490     gboolean close, gpointer user_data)
491 {
492   GstRTSPStatusCode code;
493   const gchar *reason;
494   GstRTSPVersion version;
495   gchar *str;
496   gchar *pattern;
497   GstRTSPSessionPool *session_pool;
498   GstRTSPSession *session;
499   gchar **session_hdr_params;
500
501   fail_unless (expected_transport != NULL);
502
503   fail_unless_equals_int (gst_rtsp_message_get_type (response),
504       GST_RTSP_MESSAGE_RESPONSE);
505
506   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
507           &version)
508       == GST_RTSP_OK);
509   fail_unless_equals_int (code, GST_RTSP_STS_OK);
510   fail_unless_equals_string (reason, "OK");
511   fail_unless_equals_int (version, GST_RTSP_VERSION_1_0);
512
513   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
514           0) == GST_RTSP_OK);
515   fail_unless (atoi (str) == cseq++);
516
517   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT,
518           &str, 0) == GST_RTSP_OK);
519
520   pattern = g_strdup_printf ("^%s$", expected_transport);
521   fail_unless (g_regex_match_simple (pattern, str, 0, 0),
522       "Transport '%s' doesn't match pattern '%s'", str, pattern);
523   g_free (pattern);
524
525   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION,
526           &str, 0) == GST_RTSP_OK);
527   session_hdr_params = g_strsplit (str, ";", -1);
528
529   /* session-id value */
530   fail_unless (session_hdr_params[0] != NULL);
531
532   if (expected_session_timeout != 60) {
533     /* session timeout param */
534     gchar *timeout_str = g_strdup_printf ("timeout=%u",
535         expected_session_timeout);
536
537     fail_unless (session_hdr_params[1] != NULL);
538     g_strstrip (session_hdr_params[1]);
539     fail_unless (g_strcmp0 (session_hdr_params[1], timeout_str) == 0);
540     g_free (timeout_str);
541   }
542
543   session_pool = gst_rtsp_client_get_session_pool (client);
544   fail_unless (session_pool != NULL);
545
546   session = gst_rtsp_session_pool_find (session_pool, session_hdr_params[0]);
547   g_strfreev (session_hdr_params);
548
549   /* remember session id to be able to send teardown */
550   if (session_id)
551     g_free (session_id);
552   session_id = g_strdup (gst_rtsp_session_get_sessionid (session));
553   fail_unless (session_id != NULL);
554
555   fail_unless (session != NULL);
556   g_object_unref (session);
557
558   g_object_unref (session_pool);
559
560
561   return TRUE;
562 }
563
564 static gboolean
565 test_setup_response_461 (GstRTSPClient * client,
566     GstRTSPMessage * response, gboolean close, gpointer user_data)
567 {
568   GstRTSPStatusCode code;
569   const gchar *reason;
570   GstRTSPVersion version;
571   gchar *str;
572
573   fail_unless (expected_transport == NULL);
574
575   fail_unless (gst_rtsp_message_get_type (response) ==
576       GST_RTSP_MESSAGE_RESPONSE);
577
578   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
579           &version)
580       == GST_RTSP_OK);
581   fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
582   fail_unless (g_str_equal (reason, "Unsupported transport"));
583   fail_unless (version == GST_RTSP_VERSION_1_0);
584
585   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
586           0) == GST_RTSP_OK);
587   fail_unless (atoi (str) == cseq++);
588
589
590   return TRUE;
591 }
592
593 static gboolean
594 test_teardown_response_200 (GstRTSPClient * client,
595     GstRTSPMessage * response, gboolean close, gpointer user_data)
596 {
597   GstRTSPStatusCode code;
598   const gchar *reason;
599   GstRTSPVersion version;
600
601   fail_unless (gst_rtsp_message_get_type (response) ==
602       GST_RTSP_MESSAGE_RESPONSE);
603
604   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
605           &version)
606       == GST_RTSP_OK);
607   fail_unless (code == GST_RTSP_STS_OK);
608   fail_unless (g_str_equal (reason, "OK"));
609   fail_unless (version == GST_RTSP_VERSION_1_0);
610
611   return TRUE;
612 }
613
614 static void
615 send_teardown (GstRTSPClient * client)
616 {
617   GstRTSPMessage request = { 0, };
618   gchar *str;
619
620   fail_unless (session_id != NULL);
621   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_TEARDOWN,
622           "rtsp://localhost/test") == GST_RTSP_OK);
623   str = g_strdup_printf ("%d", cseq);
624   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
625   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
626   gst_rtsp_client_set_send_func (client, test_teardown_response_200,
627       NULL, NULL);
628   fail_unless (gst_rtsp_client_handle_message (client,
629           &request) == GST_RTSP_OK);
630   gst_rtsp_message_unset (&request);
631   g_free (session_id);
632   session_id = NULL;
633 }
634
635 GST_START_TEST (test_setup_tcp)
636 {
637   GstRTSPClient *client;
638   GstRTSPConnection *conn;
639   GstRTSPMessage request = { 0, };
640   gchar *str;
641
642   client = setup_client (NULL);
643   create_connection (&conn);
644   fail_unless (gst_rtsp_client_set_connection (client, conn));
645
646   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
647           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
648   str = g_strdup_printf ("%d", cseq);
649   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
650   g_free (str);
651   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
652       "RTP/AVP/TCP;unicast");
653
654   gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
655   expected_transport =
656       "RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=.*;mode=\"PLAY\"";
657   fail_unless (gst_rtsp_client_handle_message (client,
658           &request) == GST_RTSP_OK);
659
660   gst_rtsp_message_unset (&request);
661
662   send_teardown (client);
663   teardown_client (client);
664 }
665
666 GST_END_TEST;
667
668 GST_START_TEST (test_setup_tcp_two_streams_same_channels)
669 {
670   GstRTSPClient *client;
671   GstRTSPConnection *conn;
672   GstRTSPMessage request = { 0, };
673   gchar *str;
674
675   client = setup_client (NULL);
676   create_connection (&conn);
677   fail_unless (gst_rtsp_client_set_connection (client, conn));
678
679   /* test SETUP of a video stream with 0-1 as interleaved channels */
680   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
681           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
682   str = g_strdup_printf ("%d", cseq);
683   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
684   g_free (str);
685   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
686       "RTP/AVP/TCP;unicast;interleaved=0-1");
687   gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
688   expected_transport =
689       "RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=.*;mode=\"PLAY\"";
690   fail_unless (gst_rtsp_client_handle_message (client,
691           &request) == GST_RTSP_OK);
692   gst_rtsp_message_unset (&request);
693
694   /* test SETUP of an audio stream with *the same* interleaved channels.
695    * we expect the server to allocate new channel numbers */
696   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
697           "rtsp://localhost/test/stream=1") == GST_RTSP_OK);
698   str = g_strdup_printf ("%d", cseq);
699   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
700   g_free (str);
701   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
702       "RTP/AVP/TCP;unicast;interleaved=0-1");
703   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
704   gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
705   expected_transport =
706       "RTP/AVP/TCP;unicast;interleaved=2-3;ssrc=.*;mode=\"PLAY\"";
707   fail_unless (gst_rtsp_client_handle_message (client,
708           &request) == GST_RTSP_OK);
709   gst_rtsp_message_unset (&request);
710
711   send_teardown (client);
712   teardown_client (client);
713 }
714
715 GST_END_TEST;
716
717 static GstRTSPClient *
718 setup_multicast_client (guint max_ttl)
719 {
720   GstRTSPClient *client;
721   GstRTSPSessionPool *session_pool;
722   GstRTSPMountPoints *mount_points;
723   GstRTSPMediaFactory *factory;
724   GstRTSPAddressPool *address_pool;
725   GstRTSPThreadPool *thread_pool;
726
727   client = gst_rtsp_client_new ();
728
729   session_pool = gst_rtsp_session_pool_new ();
730   gst_rtsp_client_set_session_pool (client, session_pool);
731
732   mount_points = gst_rtsp_mount_points_new ();
733   factory = gst_rtsp_media_factory_new ();
734   gst_rtsp_media_factory_set_launch (factory,
735       "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
736   address_pool = gst_rtsp_address_pool_new ();
737   fail_unless (gst_rtsp_address_pool_add_range (address_pool,
738           "233.252.0.1", "233.252.0.1", 5000, 5010, 1));
739   gst_rtsp_media_factory_set_address_pool (factory, address_pool);
740   gst_rtsp_media_factory_add_role (factory, "user",
741       "media.factory.access", G_TYPE_BOOLEAN, TRUE,
742       "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
743   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
744   gst_rtsp_client_set_mount_points (client, mount_points);
745   gst_rtsp_media_factory_set_max_mcast_ttl (factory, max_ttl);
746
747   thread_pool = gst_rtsp_thread_pool_new ();
748   gst_rtsp_client_set_thread_pool (client, thread_pool);
749
750   g_object_unref (mount_points);
751   g_object_unref (session_pool);
752   g_object_unref (address_pool);
753   g_object_unref (thread_pool);
754
755   return client;
756 }
757
758 GST_START_TEST (test_client_multicast_transport_404)
759 {
760   GstRTSPClient *client;
761   GstRTSPMessage request = { 0, };
762   gchar *str;
763
764   client = setup_multicast_client (1);
765
766   /* simple SETUP for non-existing url */
767   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
768           "rtsp://localhost/test2/stream=0") == GST_RTSP_OK);
769   str = g_strdup_printf ("%d", cseq);
770   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
771   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
772       "RTP/AVP;multicast");
773
774   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
775   fail_unless (gst_rtsp_client_handle_message (client,
776           &request) == GST_RTSP_OK);
777   gst_rtsp_message_unset (&request);
778
779   teardown_client (client);
780 }
781
782 GST_END_TEST;
783
784 static void
785 new_session_cb (GObject * client, GstRTSPSession * session, gpointer user_data)
786 {
787   GST_DEBUG ("%p: new session %p", client, session);
788   gst_rtsp_session_set_timeout (session, expected_session_timeout);
789 }
790
791 GST_START_TEST (test_client_multicast_transport)
792 {
793   GstRTSPClient *client;
794   GstRTSPMessage request = { 0, };
795   gchar *str;
796
797   client = setup_multicast_client (1);
798
799   expected_session_timeout = 20;
800   g_signal_connect (G_OBJECT (client), "new-session",
801       G_CALLBACK (new_session_cb), NULL);
802
803   /* simple SETUP with a valid URI and multicast */
804   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
805           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
806   str = g_strdup_printf ("%d", cseq);
807   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
808   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
809       "RTP/AVP;multicast");
810
811   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
812       "ttl=1;port=5000-5001;mode=\"PLAY\"";
813   gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
814   fail_unless (gst_rtsp_client_handle_message (client,
815           &request) == GST_RTSP_OK);
816   gst_rtsp_message_unset (&request);
817   expected_transport = NULL;
818   expected_session_timeout = 60;
819
820   send_teardown (client);
821
822   teardown_client (client);
823 }
824
825 GST_END_TEST;
826
827 GST_START_TEST (test_client_multicast_ignore_transport_specific)
828 {
829   GstRTSPClient *client;
830   GstRTSPMessage request = { 0, };
831   gchar *str;
832
833   client = setup_multicast_client (1);
834
835   /* simple SETUP with a valid URI and multicast and a specific dest,
836    * but ignore it  */
837   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
838           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
839   str = g_strdup_printf ("%d", cseq);
840   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
841   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
842       "RTP/AVP;multicast;destination=233.252.0.2;ttl=2;port=5001-5006;");
843
844   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
845       "ttl=1;port=5000-5001;mode=\"PLAY\"";
846   gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
847   fail_unless (gst_rtsp_client_handle_message (client,
848           &request) == GST_RTSP_OK);
849   gst_rtsp_message_unset (&request);
850   expected_transport = NULL;
851
852   send_teardown (client);
853
854   teardown_client (client);
855 }
856
857 GST_END_TEST;
858
859 static void
860 multicast_transport_specific (void)
861 {
862   GstRTSPClient *client;
863   GstRTSPMessage request = { 0, };
864   gchar *str;
865   GstRTSPSessionPool *session_pool;
866   GstRTSPContext ctx = { NULL };
867
868   client = setup_multicast_client (1);
869
870   ctx.client = client;
871   ctx.auth = gst_rtsp_auth_new ();
872   ctx.token =
873       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
874       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
875       "user", NULL);
876   gst_rtsp_context_push_current (&ctx);
877
878   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
879       "ttl=1;port=5000-5001;mode=\"PLAY\"";
880
881   /* simple SETUP with a valid URI */
882   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
883           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
884   str = g_strdup_printf ("%d", cseq);
885   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
886   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
887       expected_transport);
888
889   gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
890   fail_unless (gst_rtsp_client_handle_message (client,
891           &request) == GST_RTSP_OK);
892   gst_rtsp_message_unset (&request);
893
894   gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
895   session_pool = gst_rtsp_client_get_session_pool (client);
896   fail_unless (session_pool != NULL);
897   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
898   g_object_unref (session_pool);
899
900   /* send PLAY request */
901   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
902           "rtsp://localhost/test") == GST_RTSP_OK);
903   str = g_strdup_printf ("%d", cseq);
904   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
905   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
906   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
907   fail_unless (gst_rtsp_client_handle_message (client,
908           &request) == GST_RTSP_OK);
909   gst_rtsp_message_unset (&request);
910
911   send_teardown (client);
912   teardown_client (client);
913   g_object_unref (ctx.auth);
914   gst_rtsp_token_unref (ctx.token);
915   gst_rtsp_context_pop_current (&ctx);
916 }
917
918 /* CASE: multicast address requested by the client exists in the address pool */
919 GST_START_TEST (test_client_multicast_transport_specific)
920 {
921   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
922       "ttl=1;port=5000-5001;mode=\"PLAY\"";
923   multicast_transport_specific ();
924   expected_transport = NULL;
925 }
926
927 GST_END_TEST;
928
929 /* CASE: multicast address requested by the client does not exist in the address pool */
930 GST_START_TEST (test_client_multicast_transport_specific_no_address_in_pool)
931 {
932   expected_transport = "RTP/AVP;multicast;destination=234.252.0.3;"
933       "ttl=1;port=6000-6001;mode=\"PLAY\"";
934   multicast_transport_specific ();
935   expected_transport = NULL;
936 }
937
938 GST_END_TEST;
939
940 static gboolean
941 test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response,
942     gboolean close, gpointer user_data)
943 {
944   guint8 *data;
945   guint size;
946   GstSDPMessage *sdp_msg;
947   const GstSDPMedia *sdp_media;
948   const GstSDPBandwidth *bw;
949   gint bandwidth_val = GPOINTER_TO_INT (user_data);
950
951   fail_unless (gst_rtsp_message_get_body (response, &data, &size)
952       == GST_RTSP_OK);
953   gst_sdp_message_new (&sdp_msg);
954   fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg)
955       == GST_SDP_OK);
956
957   /* session description */
958   /* v= */
959   fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL);
960   /* o= */
961   fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL);
962   /* s= */
963   fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL);
964   /* t=0 0 */
965   fail_unless (gst_sdp_message_times_len (sdp_msg) == 0);
966
967   /* verify number of medias */
968   fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1);
969
970   /* media description */
971   sdp_media = gst_sdp_message_get_media (sdp_msg, 0);
972   fail_unless (sdp_media != NULL);
973
974   /* m= */
975   fail_unless (gst_sdp_media_get_media (sdp_media) != NULL);
976
977   /* media bandwidth */
978   if (bandwidth_val) {
979     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1);
980     bw = gst_sdp_media_get_bandwidth (sdp_media, 0);
981     fail_unless (bw != NULL);
982     fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0);
983     fail_unless (bw->bandwidth == bandwidth_val);
984   } else {
985     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0);
986   }
987
988   gst_sdp_message_free (sdp_msg);
989
990   return TRUE;
991 }
992
993 static void
994 test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
995 {
996   GstRTSPClient *client;
997   GstRTSPMessage request = { 0, };
998   gchar *str;
999
1000   /* simple DESCRIBE for an existing url */
1001   client = setup_client (launch_line);
1002   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
1003           "rtsp://localhost/test") == GST_RTSP_OK);
1004   str = g_strdup_printf ("%d", cseq);
1005   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
1006   g_free (str);
1007
1008   gst_rtsp_client_set_send_func (client, test_response_sdp,
1009       (gpointer) bandwidth_val, NULL);
1010   fail_unless (gst_rtsp_client_handle_message (client,
1011           &request) == GST_RTSP_OK);
1012   gst_rtsp_message_unset (&request);
1013
1014   teardown_client (client);
1015 }
1016
1017 GST_START_TEST (test_client_sdp_with_max_bitrate_tag)
1018 {
1019   test_client_sdp ("videotestsrc "
1020       "! taginject tags=\"maximum-bitrate=(uint)50000000\" "
1021       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1022       GUINT_TO_POINTER (50000));
1023
1024
1025   /* max-bitrate=0: no bandwidth line */
1026   test_client_sdp ("videotestsrc "
1027       "! taginject tags=\"maximum-bitrate=(uint)0\" "
1028       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1029       GUINT_TO_POINTER (0));
1030 }
1031
1032 GST_END_TEST;
1033
1034 GST_START_TEST (test_client_sdp_with_bitrate_tag)
1035 {
1036   test_client_sdp ("videotestsrc "
1037       "! taginject tags=\"bitrate=(uint)7000000\" "
1038       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1039       GUINT_TO_POINTER (7000));
1040
1041   /* bitrate=0: no bandwdith line */
1042   test_client_sdp ("videotestsrc "
1043       "! taginject tags=\"bitrate=(uint)0\" "
1044       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1045       GUINT_TO_POINTER (0));
1046 }
1047
1048 GST_END_TEST;
1049
1050 GST_START_TEST (test_client_sdp_with_max_bitrate_and_bitrate_tags)
1051 {
1052   test_client_sdp ("videotestsrc "
1053       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)50000000\" "
1054       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1055       GUINT_TO_POINTER (50000));
1056
1057   /* max-bitrate is zero: fallback to bitrate */
1058   test_client_sdp ("videotestsrc "
1059       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)0\" "
1060       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1061       GUINT_TO_POINTER (7000));
1062
1063   /* max-bitrate=bitrate=0o: no bandwidth line */
1064   test_client_sdp ("videotestsrc "
1065       "! taginject tags=\"bitrate=(uint)0,maximum-bitrate=(uint)0\" "
1066       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1067       GUINT_TO_POINTER (0));
1068 }
1069
1070 GST_END_TEST;
1071
1072 GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
1073 {
1074   test_client_sdp ("videotestsrc "
1075       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96", NULL);
1076 }
1077
1078 GST_END_TEST;
1079
1080 static void
1081 mcast_transport_two_clients (gboolean shared, const gchar * transport1,
1082     const gchar * expected_transport1, const gchar * addr1,
1083     const gchar * transport2, const gchar * expected_transport2,
1084     const gchar * addr2)
1085 {
1086   GstRTSPClient *client1, *client2;
1087   GstRTSPMessage request = { 0, };
1088   gchar *str;
1089   GstRTSPSessionPool *session_pool;
1090   GstRTSPContext ctx = { NULL };
1091   GstRTSPContext ctx2 = { NULL };
1092   GstRTSPMountPoints *mount_points;
1093   GstRTSPMediaFactory *factory;
1094   GstRTSPAddressPool *address_pool;
1095   GstRTSPThreadPool *thread_pool;
1096   gchar *session_id1;
1097   gchar *client_addr = NULL;
1098
1099   mount_points = gst_rtsp_mount_points_new ();
1100   factory = gst_rtsp_media_factory_new ();
1101   if (shared)
1102     gst_rtsp_media_factory_set_shared (factory, TRUE);
1103   gst_rtsp_media_factory_set_max_mcast_ttl (factory, 5);
1104   gst_rtsp_media_factory_set_launch (factory,
1105       "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
1106   address_pool = gst_rtsp_address_pool_new ();
1107   fail_unless (gst_rtsp_address_pool_add_range (address_pool,
1108           "233.252.0.1", "233.252.0.1", 5000, 5001, 1));
1109   gst_rtsp_media_factory_set_address_pool (factory, address_pool);
1110   gst_rtsp_media_factory_add_role (factory, "user",
1111       "media.factory.access", G_TYPE_BOOLEAN, TRUE,
1112       "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
1113   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
1114   session_pool = gst_rtsp_session_pool_new ();
1115   thread_pool = gst_rtsp_thread_pool_new ();
1116
1117   /* first multicast client with transport specific request */
1118   client1 = gst_rtsp_client_new ();
1119   gst_rtsp_client_set_session_pool (client1, session_pool);
1120   gst_rtsp_client_set_mount_points (client1, mount_points);
1121   gst_rtsp_client_set_thread_pool (client1, thread_pool);
1122
1123   ctx.client = client1;
1124   ctx.auth = gst_rtsp_auth_new ();
1125   ctx.token =
1126       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
1127       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
1128       "user", NULL);
1129   gst_rtsp_context_push_current (&ctx);
1130
1131   expected_transport = expected_transport1;
1132
1133   /* send SETUP request */
1134   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
1135           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
1136   str = g_strdup_printf ("%d", cseq);
1137   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1138   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, transport1);
1139
1140   gst_rtsp_client_set_send_func (client1, test_setup_response_200, NULL, NULL);
1141   fail_unless (gst_rtsp_client_handle_message (client1,
1142           &request) == GST_RTSP_OK);
1143   gst_rtsp_message_unset (&request);
1144   expected_transport = NULL;
1145
1146   /* send PLAY request */
1147   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
1148           "rtsp://localhost/test") == GST_RTSP_OK);
1149   str = g_strdup_printf ("%d", cseq);
1150   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1151   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
1152   gst_rtsp_client_set_send_func (client1, test_response_200, NULL, NULL);
1153   fail_unless (gst_rtsp_client_handle_message (client1,
1154           &request) == GST_RTSP_OK);
1155   gst_rtsp_message_unset (&request);
1156
1157   /* check address */
1158   client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx.stream);
1159   fail_if (client_addr == NULL);
1160   fail_unless (g_str_equal (client_addr, addr1));
1161   g_free (client_addr);
1162
1163   gst_rtsp_context_pop_current (&ctx);
1164   session_id1 = g_strdup (session_id);
1165
1166   /* second multicast client with transport specific request */
1167   cseq = 0;
1168   client2 = gst_rtsp_client_new ();
1169   gst_rtsp_client_set_session_pool (client2, session_pool);
1170   gst_rtsp_client_set_mount_points (client2, mount_points);
1171   gst_rtsp_client_set_thread_pool (client2, thread_pool);
1172
1173   ctx2.client = client2;
1174   ctx2.auth = gst_rtsp_auth_new ();
1175   ctx2.token =
1176       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
1177       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
1178       "user", NULL);
1179   gst_rtsp_context_push_current (&ctx2);
1180
1181   expected_transport = expected_transport2;
1182
1183   /* send SETUP request */
1184   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
1185           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
1186   str = g_strdup_printf ("%d", cseq);
1187   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1188   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, transport2);
1189
1190   gst_rtsp_client_set_send_func (client2, test_setup_response_200, NULL, NULL);
1191   fail_unless (gst_rtsp_client_handle_message (client2,
1192           &request) == GST_RTSP_OK);
1193   gst_rtsp_message_unset (&request);
1194   expected_transport = NULL;
1195
1196   /* send PLAY request */
1197   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
1198           "rtsp://localhost/test") == GST_RTSP_OK);
1199   str = g_strdup_printf ("%d", cseq);
1200   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1201   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
1202   gst_rtsp_client_set_send_func (client2, test_response_200, NULL, NULL);
1203   fail_unless (gst_rtsp_client_handle_message (client2,
1204           &request) == GST_RTSP_OK);
1205   gst_rtsp_message_unset (&request);
1206
1207   /* check addresses */
1208   client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx2.stream);
1209   fail_if (client_addr == NULL);
1210   if (shared) {
1211     if (g_str_equal (addr1, addr2)) {
1212       fail_unless (g_str_equal (client_addr, addr1));
1213     } else {
1214       gchar *addr_str = g_strdup_printf ("%s,%s", addr2, addr1);
1215       fail_unless (g_str_equal (client_addr, addr_str));
1216       g_free (addr_str);
1217     }
1218   } else {
1219     fail_unless (g_str_equal (client_addr, addr2));
1220   }
1221   g_free (client_addr);
1222
1223   send_teardown (client2);
1224   gst_rtsp_context_pop_current (&ctx2);
1225
1226   gst_rtsp_context_push_current (&ctx);
1227   session_id = session_id1;
1228   send_teardown (client1);
1229   gst_rtsp_context_pop_current (&ctx);
1230
1231   teardown_client (client1);
1232   teardown_client (client2);
1233   g_object_unref (ctx.auth);
1234   g_object_unref (ctx2.auth);
1235   gst_rtsp_token_unref (ctx.token);
1236   gst_rtsp_token_unref (ctx2.token);
1237   g_object_unref (mount_points);
1238   g_object_unref (session_pool);
1239   g_object_unref (address_pool);
1240   g_object_unref (thread_pool);
1241 }
1242
1243 /* test if two multicast clients can choose different transport settings
1244  * CASE: media is shared */
1245 GST_START_TEST
1246     (test_client_multicast_transport_specific_two_clients_shared_media) {
1247   const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1248       "ttl=1;port=5000-5001;mode=\"PLAY\"";
1249   const gchar *expected_transport_1 = transport_client_1;
1250   const gchar *addr_client_1 = "233.252.0.1:5000";
1251
1252   const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1253       "ttl=1;port=5002-5003;mode=\"PLAY\"";
1254   const gchar *expected_transport_2 = transport_client_2;
1255   const gchar *addr_client_2 = "233.252.0.2:5002";
1256
1257   mcast_transport_two_clients (TRUE, transport_client_1,
1258       expected_transport_1, addr_client_1, transport_client_2,
1259       expected_transport_2, addr_client_2);
1260 }
1261
1262 GST_END_TEST;
1263
1264 /* test if two multicast clients can choose different transport settings
1265  * CASE: media is not shared */
1266 GST_START_TEST (test_client_multicast_transport_specific_two_clients)
1267 {
1268   const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1269       "ttl=1;port=5000-5001;mode=\"PLAY\"";
1270   const gchar *expected_transport_1 = transport_client_1;
1271   const gchar *addr_client_1 = "233.252.0.1:5000";
1272
1273   const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1274       "ttl=1;port=5002-5003;mode=\"PLAY\"";
1275   const gchar *expected_transport_2 = transport_client_2;
1276   const gchar *addr_client_2 = "233.252.0.2:5002";
1277
1278   mcast_transport_two_clients (FALSE, transport_client_1,
1279       expected_transport_1, addr_client_1, transport_client_2,
1280       expected_transport_2, addr_client_2);
1281 }
1282
1283 GST_END_TEST;
1284
1285 /* test if two multicast clients can choose the same transport settings.
1286  * CASE: media is shared */
1287 GST_START_TEST
1288     (test_client_multicast_transport_specific_two_clients_shared_media_same_transport)
1289 {
1290
1291   const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1292       "ttl=1;port=5000-5001;mode=\"PLAY\"";
1293   const gchar *expected_transport_1 = transport_client_1;
1294   const gchar *addr_client_1 = "233.252.0.1:5000";
1295
1296   const gchar *transport_client_2 = transport_client_1;
1297   const gchar *expected_transport_2 = expected_transport_1;
1298   const gchar *addr_client_2 = addr_client_1;
1299
1300   mcast_transport_two_clients (TRUE, transport_client_1,
1301       expected_transport_1, addr_client_1, transport_client_2,
1302       expected_transport_2, addr_client_2);
1303 }
1304
1305 GST_END_TEST;
1306
1307 /* test if two multicast clients get the same transport settings without
1308  * requesting specific transport.
1309  * CASE: media is shared */
1310 GST_START_TEST (test_client_multicast_two_clients_shared_media)
1311 {
1312   const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\"";
1313   const gchar *expected_transport_1 =
1314       "RTP/AVP;multicast;destination=233.252.0.1;"
1315       "ttl=1;port=5000-5001;mode=\"PLAY\"";
1316   const gchar *addr_client_1 = "233.252.0.1:5000";
1317
1318   const gchar *transport_client_2 = transport_client_1;
1319   const gchar *expected_transport_2 = expected_transport_1;
1320   const gchar *addr_client_2 = addr_client_1;
1321
1322   mcast_transport_two_clients (TRUE, transport_client_1,
1323       expected_transport_1, addr_client_1, transport_client_2,
1324       expected_transport_2, addr_client_2);
1325 }
1326
1327 GST_END_TEST;
1328
1329 /* test if two multicast clients get the different transport settings: the first client 
1330  * requests the specific transport configuration while the second client lets
1331  * the server select the multicast address and the ports.
1332  * CASE: media is shared */
1333 GST_START_TEST
1334     (test_client_multicast_two_clients_first_specific_transport_shared_media) {
1335   const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1336       "ttl=1;port=5000-5001;mode=\"PLAY\"";
1337   const gchar *expected_transport_1 = transport_client_1;
1338   const gchar *addr_client_1 = "233.252.0.1:5000";
1339
1340   const gchar *transport_client_2 = "RTP/AVP;multicast;mode=\"PLAY\"";
1341   const gchar *expected_transport_2 = expected_transport_1;
1342   const gchar *addr_client_2 = addr_client_1;
1343
1344   mcast_transport_two_clients (TRUE, transport_client_1,
1345       expected_transport_1, addr_client_1, transport_client_2,
1346       expected_transport_2, addr_client_2);
1347 }
1348
1349 GST_END_TEST;
1350 /* test if two multicast clients get the different transport settings: the first client lets
1351  * the server select the multicast address and the ports while the second client requests 
1352  * the specific transport configuration.
1353  * CASE: media is shared */
1354 GST_START_TEST
1355     (test_client_multicast_two_clients_second_specific_transport_shared_media) {
1356   const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\"";
1357   const gchar *expected_transport_1 =
1358       "RTP/AVP;multicast;destination=233.252.0.1;"
1359       "ttl=1;port=5000-5001;mode=\"PLAY\"";
1360   const gchar *addr_client_1 = "233.252.0.1:5000";
1361
1362   const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1363       "ttl=2;port=5004-5005;mode=\"PLAY\"";
1364   const gchar *expected_transport_2 = transport_client_2;
1365   const gchar *addr_client_2 = "233.252.0.2:5004";
1366
1367   mcast_transport_two_clients (TRUE, transport_client_1,
1368       expected_transport_1, addr_client_1, transport_client_2,
1369       expected_transport_2, addr_client_2);
1370 }
1371
1372 GST_END_TEST;
1373
1374 /* test if the maximum ttl multicast value is chosen by the server
1375  * CASE: the first client provides the highest ttl value */
1376 GST_START_TEST (test_client_multicast_max_ttl_first_client)
1377 {
1378   const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1379       "ttl=3;port=5000-5001;mode=\"PLAY\"";
1380   const gchar *expected_transport_1 = transport_client_1;
1381   const gchar *addr_client_1 = "233.252.0.1:5000";
1382
1383   const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1384       "ttl=1;port=5002-5003;mode=\"PLAY\"";
1385   const gchar *expected_transport_2 =
1386       "RTP/AVP;multicast;destination=233.252.0.2;"
1387       "ttl=3;port=5002-5003;mode=\"PLAY\"";
1388   const gchar *addr_client_2 = "233.252.0.2:5002";
1389
1390   mcast_transport_two_clients (TRUE, transport_client_1,
1391       expected_transport_1, addr_client_1, transport_client_2,
1392       expected_transport_2, addr_client_2);
1393 }
1394
1395 GST_END_TEST;
1396
1397 /* test if the maximum ttl multicast value is chosen by the server
1398  * CASE: the second client provides the highest ttl value */
1399 GST_START_TEST (test_client_multicast_max_ttl_second_client)
1400 {
1401   const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1402       "ttl=2;port=5000-5001;mode=\"PLAY\"";
1403   const gchar *expected_transport_1 = transport_client_1;
1404   const gchar *addr_client_1 = "233.252.0.1:5000";
1405
1406   const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1407       "ttl=4;port=5002-5003;mode=\"PLAY\"";
1408   const gchar *expected_transport_2 = transport_client_2;
1409   const gchar *addr_client_2 = "233.252.0.2:5002";
1410
1411   mcast_transport_two_clients (TRUE, transport_client_1,
1412       expected_transport_1, addr_client_1, transport_client_2,
1413       expected_transport_2, addr_client_2);
1414 }
1415
1416 GST_END_TEST;
1417 GST_START_TEST (test_client_multicast_invalid_ttl)
1418 {
1419   GstRTSPClient *client;
1420   GstRTSPMessage request = { 0, };
1421   gchar *str;
1422   GstRTSPSessionPool *session_pool;
1423   GstRTSPContext ctx = { NULL };
1424
1425   client = setup_multicast_client (3);
1426
1427   ctx.client = client;
1428   ctx.auth = gst_rtsp_auth_new ();
1429   ctx.token =
1430       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
1431       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
1432       "user", NULL);
1433   gst_rtsp_context_push_current (&ctx);
1434
1435   /* simple SETUP with an invalid ttl=0 */
1436   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
1437           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
1438   str = g_strdup_printf ("%d", cseq);
1439   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1440   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
1441       "RTP/AVP;multicast;destination=233.252.0.1;ttl=0;port=5000-5001;");
1442
1443   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
1444   fail_unless (gst_rtsp_client_handle_message (client,
1445           &request) == GST_RTSP_OK);
1446   gst_rtsp_message_unset (&request);
1447
1448   session_pool = gst_rtsp_client_get_session_pool (client);
1449   fail_unless (session_pool != NULL);
1450   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0);
1451   g_object_unref (session_pool);
1452
1453   teardown_client (client);
1454   g_object_unref (ctx.auth);
1455   gst_rtsp_token_unref (ctx.token);
1456   gst_rtsp_context_pop_current (&ctx);
1457 }
1458
1459 GST_END_TEST;
1460
1461 static Suite *
1462 rtspclient_suite (void)
1463 {
1464   Suite *s = suite_create ("rtspclient");
1465   TCase *tc = tcase_create ("general");
1466
1467   suite_add_tcase (s, tc);
1468   tcase_set_timeout (tc, 20);
1469   tcase_add_test (tc, test_require);
1470   tcase_add_test (tc, test_request);
1471   tcase_add_test (tc, test_options);
1472   tcase_add_test (tc, test_describe);
1473   tcase_add_test (tc, test_setup_tcp);
1474   tcase_add_test (tc, test_setup_tcp_two_streams_same_channels);
1475   tcase_add_test (tc, test_client_multicast_transport_404);
1476   tcase_add_test (tc, test_client_multicast_transport);
1477   tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
1478   tcase_add_test (tc, test_client_multicast_transport_specific);
1479   tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag);
1480   tcase_add_test (tc, test_client_sdp_with_bitrate_tag);
1481   tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags);
1482   tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
1483   tcase_add_test (tc,
1484       test_client_multicast_transport_specific_two_clients_shared_media);
1485   tcase_add_test (tc, test_client_multicast_transport_specific_two_clients);
1486   tcase_add_test (tc,
1487       test_client_multicast_transport_specific_two_clients_shared_media_same_transport);
1488   tcase_add_test (tc, test_client_multicast_two_clients_shared_media);
1489   tcase_add_test (tc,
1490       test_client_multicast_two_clients_first_specific_transport_shared_media);
1491   tcase_add_test (tc,
1492       test_client_multicast_two_clients_second_specific_transport_shared_media);
1493   tcase_add_test (tc,
1494       test_client_multicast_transport_specific_no_address_in_pool);
1495   tcase_add_test (tc, test_client_multicast_max_ttl_first_client);
1496   tcase_add_test (tc, test_client_multicast_max_ttl_second_client);
1497   tcase_add_test (tc, test_client_multicast_invalid_ttl);
1498
1499   return s;
1500 }
1501
1502 GST_CHECK_MAIN (rtspclient);