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