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