client: fix test
[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 gint cseq;
25 static guint expected_session_timeout = 60;
26
27 static gboolean
28 test_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
29     gboolean close, gpointer user_data)
30 {
31   GstRTSPStatusCode code;
32   const gchar *reason;
33   GstRTSPVersion version;
34
35   fail_unless (gst_rtsp_message_get_type (response) ==
36       GST_RTSP_MESSAGE_RESPONSE);
37
38   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
39           &version)
40       == GST_RTSP_OK);
41   fail_unless (code == GST_RTSP_STS_OK);
42   fail_unless (g_str_equal (reason, "OK"));
43   fail_unless (version == GST_RTSP_VERSION_1_0);
44
45   return TRUE;
46 }
47
48 static gboolean
49 test_response_400 (GstRTSPClient * client, GstRTSPMessage * response,
50     gboolean close, gpointer user_data)
51 {
52   GstRTSPStatusCode code;
53   const gchar *reason;
54   GstRTSPVersion version;
55
56   fail_unless (gst_rtsp_message_get_type (response) ==
57       GST_RTSP_MESSAGE_RESPONSE);
58
59   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
60           &version)
61       == GST_RTSP_OK);
62   fail_unless (code == GST_RTSP_STS_BAD_REQUEST);
63   fail_unless (g_str_equal (reason, "Bad Request"));
64   fail_unless (version == GST_RTSP_VERSION_1_0);
65
66   return TRUE;
67 }
68
69 static gboolean
70 test_response_404 (GstRTSPClient * client, GstRTSPMessage * response,
71     gboolean close, gpointer user_data)
72 {
73   GstRTSPStatusCode code;
74   const gchar *reason;
75   GstRTSPVersion version;
76
77   fail_unless (gst_rtsp_message_get_type (response) ==
78       GST_RTSP_MESSAGE_RESPONSE);
79
80   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
81           &version)
82       == GST_RTSP_OK);
83   fail_unless (code == GST_RTSP_STS_NOT_FOUND);
84   fail_unless (g_str_equal (reason, "Not Found"));
85   fail_unless (version == GST_RTSP_VERSION_1_0);
86
87   return TRUE;
88 }
89
90 static gboolean
91 test_response_454 (GstRTSPClient * client, GstRTSPMessage * response,
92     gboolean close, gpointer user_data)
93 {
94   GstRTSPStatusCode code;
95   const gchar *reason;
96   GstRTSPVersion version;
97
98   fail_unless (gst_rtsp_message_get_type (response) ==
99       GST_RTSP_MESSAGE_RESPONSE);
100
101   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
102           &version)
103       == GST_RTSP_OK);
104   fail_unless (code == GST_RTSP_STS_SESSION_NOT_FOUND);
105   fail_unless (g_str_equal (reason, "Session Not Found"));
106   fail_unless (version == GST_RTSP_VERSION_1_0);
107
108   return TRUE;
109 }
110
111 static GstRTSPClient *
112 setup_client (const gchar * launch_line)
113 {
114   GstRTSPClient *client;
115   GstRTSPSessionPool *session_pool;
116   GstRTSPMountPoints *mount_points;
117   GstRTSPMediaFactory *factory;
118   GstRTSPThreadPool *thread_pool;
119
120   client = gst_rtsp_client_new ();
121
122   session_pool = gst_rtsp_session_pool_new ();
123   gst_rtsp_client_set_session_pool (client, session_pool);
124
125   mount_points = gst_rtsp_mount_points_new ();
126   factory = gst_rtsp_media_factory_new ();
127   if (launch_line == NULL)
128     gst_rtsp_media_factory_set_launch (factory,
129         "videotestsrc ! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96");
130   else
131     gst_rtsp_media_factory_set_launch (factory, launch_line);
132
133   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
134   gst_rtsp_client_set_mount_points (client, mount_points);
135
136   thread_pool = gst_rtsp_thread_pool_new ();
137   gst_rtsp_client_set_thread_pool (client, thread_pool);
138
139   g_object_unref (mount_points);
140   g_object_unref (session_pool);
141   g_object_unref (thread_pool);
142
143   return client;
144 }
145
146 GST_START_TEST (test_request)
147 {
148   GstRTSPClient *client;
149   GstRTSPMessage request = { 0, };
150   gchar *str;
151
152   client = gst_rtsp_client_new ();
153
154   /* OPTIONS with invalid url */
155   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
156           "foopy://padoop/") == GST_RTSP_OK);
157   str = g_strdup_printf ("%d", cseq);
158   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
159   g_free (str);
160
161   gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
162   fail_unless (gst_rtsp_client_handle_message (client,
163           &request) == GST_RTSP_OK);
164
165   gst_rtsp_message_unset (&request);
166
167   /* OPTIONS with unknown session id */
168   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
169           "rtsp://localhost/test") == GST_RTSP_OK);
170   str = g_strdup_printf ("%d", cseq);
171   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
172   g_free (str);
173   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, "foobar");
174
175   gst_rtsp_client_set_send_func (client, test_response_454, NULL, NULL);
176   fail_unless (gst_rtsp_client_handle_message (client,
177           &request) == GST_RTSP_OK);
178
179   gst_rtsp_message_unset (&request);
180
181   g_object_unref (client);
182 }
183
184 GST_END_TEST;
185
186 static gboolean
187 test_option_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
188     gboolean close, gpointer user_data)
189 {
190   GstRTSPStatusCode code;
191   const gchar *reason;
192   GstRTSPVersion version;
193   gchar *str;
194   GstRTSPMethod methods;
195
196   fail_unless (gst_rtsp_message_get_type (response) ==
197       GST_RTSP_MESSAGE_RESPONSE);
198
199   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
200           &version)
201       == GST_RTSP_OK);
202   fail_unless (code == GST_RTSP_STS_OK);
203   fail_unless (g_str_equal (reason, "OK"));
204   fail_unless (version == GST_RTSP_VERSION_1_0);
205
206   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
207           0) == GST_RTSP_OK);
208   fail_unless (atoi (str) == cseq++);
209
210   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_PUBLIC, &str,
211           0) == GST_RTSP_OK);
212
213   methods = gst_rtsp_options_from_text (str);
214   fail_if (methods == 0);
215   fail_unless (methods == (GST_RTSP_DESCRIBE |
216           GST_RTSP_OPTIONS |
217           GST_RTSP_PAUSE |
218           GST_RTSP_PLAY |
219           GST_RTSP_SETUP |
220           GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN));
221
222   return TRUE;
223 }
224
225 GST_START_TEST (test_options)
226 {
227   GstRTSPClient *client;
228   GstRTSPMessage request = { 0, };
229   gchar *str;
230
231   client = gst_rtsp_client_new ();
232
233   /* simple OPTIONS */
234   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
235           "rtsp://localhost/test") == GST_RTSP_OK);
236   str = g_strdup_printf ("%d", cseq);
237   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
238   g_free (str);
239
240   gst_rtsp_client_set_send_func (client, test_option_response_200, NULL, NULL);
241   fail_unless (gst_rtsp_client_handle_message (client,
242           &request) == GST_RTSP_OK);
243   gst_rtsp_message_unset (&request);
244
245   g_object_unref (client);
246 }
247
248 GST_END_TEST;
249
250 GST_START_TEST (test_describe)
251 {
252   GstRTSPClient *client;
253   GstRTSPMessage request = { 0, };
254   gchar *str;
255
256   client = gst_rtsp_client_new ();
257
258   /* simple DESCRIBE for non-existing url */
259   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
260           "rtsp://localhost/test") == GST_RTSP_OK);
261   str = g_strdup_printf ("%d", cseq);
262   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
263   g_free (str);
264
265   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
266   fail_unless (gst_rtsp_client_handle_message (client,
267           &request) == GST_RTSP_OK);
268   gst_rtsp_message_unset (&request);
269
270   g_object_unref (client);
271
272   /* simple DESCRIBE for an existing url */
273   client = setup_client (NULL);
274   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
275           "rtsp://localhost/test") == GST_RTSP_OK);
276   str = g_strdup_printf ("%d", cseq);
277   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
278   g_free (str);
279
280   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
281   fail_unless (gst_rtsp_client_handle_message (client,
282           &request) == GST_RTSP_OK);
283   gst_rtsp_message_unset (&request);
284
285   g_object_unref (client);
286 }
287
288 GST_END_TEST;
289
290 gchar *expected_transport = NULL;;
291
292 static gboolean
293 test_setup_response_200_multicast (GstRTSPClient * client,
294     GstRTSPMessage * response, gboolean close, gpointer user_data)
295 {
296   GstRTSPStatusCode code;
297   const gchar *reason;
298   GstRTSPVersion version;
299   gchar *str;
300   GstRTSPSessionPool *session_pool;
301   GstRTSPSession *session;
302   gchar **session_hdr_params;
303
304   fail_unless (expected_transport != NULL);
305
306   fail_unless (gst_rtsp_message_get_type (response) ==
307       GST_RTSP_MESSAGE_RESPONSE);
308
309   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
310           &version)
311       == GST_RTSP_OK);
312   fail_unless (code == GST_RTSP_STS_OK);
313   fail_unless (g_str_equal (reason, "OK"));
314   fail_unless (version == GST_RTSP_VERSION_1_0);
315
316   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
317           0) == GST_RTSP_OK);
318   fail_unless (atoi (str) == cseq++);
319
320   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT,
321           &str, 0) == GST_RTSP_OK);
322
323   fail_unless (!strcmp (str, expected_transport));
324
325   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION,
326           &str, 0) == GST_RTSP_OK);
327   session_hdr_params = g_strsplit (str, ";", -1);
328
329   /* session-id value */
330   fail_unless (session_hdr_params[0] != NULL);
331
332   if (expected_session_timeout != 60) {
333     /* session timeout param */
334     gchar *timeout_str = g_strdup_printf ("timeout=%u",
335         expected_session_timeout);
336
337     fail_unless (session_hdr_params[1] != NULL);
338     g_strstrip (session_hdr_params[1]);
339     fail_unless (g_strcmp0 (session_hdr_params[1], timeout_str) == 0);
340     g_free (timeout_str);
341   }
342
343   session_pool = gst_rtsp_client_get_session_pool (client);
344   fail_unless (session_pool != NULL);
345
346   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
347   session = gst_rtsp_session_pool_find (session_pool, session_hdr_params[0]);
348   g_strfreev (session_hdr_params);
349
350   fail_unless (session != NULL);
351   g_object_unref (session);
352
353   g_object_unref (session_pool);
354
355
356   return TRUE;
357 }
358
359 static GstRTSPClient *
360 setup_multicast_client (void)
361 {
362   GstRTSPClient *client;
363   GstRTSPSessionPool *session_pool;
364   GstRTSPMountPoints *mount_points;
365   GstRTSPMediaFactory *factory;
366   GstRTSPAddressPool *address_pool;
367   GstRTSPThreadPool *thread_pool;
368
369   client = gst_rtsp_client_new ();
370
371   session_pool = gst_rtsp_session_pool_new ();
372   gst_rtsp_client_set_session_pool (client, session_pool);
373
374   mount_points = gst_rtsp_mount_points_new ();
375   factory = gst_rtsp_media_factory_new ();
376   gst_rtsp_media_factory_set_launch (factory,
377       "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
378   address_pool = gst_rtsp_address_pool_new ();
379   fail_unless (gst_rtsp_address_pool_add_range (address_pool,
380           "233.252.0.1", "233.252.0.1", 5000, 5010, 1));
381   gst_rtsp_media_factory_set_address_pool (factory, address_pool);
382   gst_rtsp_media_factory_add_role (factory, "user",
383       "media.factory.access", G_TYPE_BOOLEAN, TRUE,
384       "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
385   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
386   gst_rtsp_client_set_mount_points (client, mount_points);
387
388   thread_pool = gst_rtsp_thread_pool_new ();
389   gst_rtsp_client_set_thread_pool (client, thread_pool);
390
391   g_object_unref (mount_points);
392   g_object_unref (session_pool);
393   g_object_unref (address_pool);
394   g_object_unref (thread_pool);
395
396   return client;
397 }
398
399 GST_START_TEST (test_client_multicast_transport_404)
400 {
401   GstRTSPClient *client;
402   GstRTSPMessage request = { 0, };
403   gchar *str;
404
405   client = setup_multicast_client ();
406
407   /* simple SETUP for non-existing url */
408   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
409           "rtsp://localhost/test2/stream=0") == GST_RTSP_OK);
410   str = g_strdup_printf ("%d", cseq);
411   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
412   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
413       "RTP/AVP;multicast");
414
415   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
416   fail_unless (gst_rtsp_client_handle_message (client,
417           &request) == GST_RTSP_OK);
418   gst_rtsp_message_unset (&request);
419
420   g_object_unref (client);
421 }
422
423 GST_END_TEST;
424
425 static void
426 new_session_cb (GObject * client, GstRTSPSession * session, gpointer user_data)
427 {
428   GST_DEBUG ("%p: new session %p", client, session);
429   gst_rtsp_session_set_timeout (session, expected_session_timeout);
430 }
431
432 GST_START_TEST (test_client_multicast_transport)
433 {
434   GstRTSPClient *client;
435   GstRTSPMessage request = { 0, };
436   gchar *str;
437
438   client = setup_multicast_client ();
439
440   expected_session_timeout = 20;
441   g_signal_connect (G_OBJECT (client), "new-session",
442       G_CALLBACK (new_session_cb), NULL);
443
444   /* simple SETUP with a valid URI and multicast */
445   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
446           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
447   str = g_strdup_printf ("%d", cseq);
448   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
449   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
450       "RTP/AVP;multicast");
451
452   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
453       "ttl=1;port=5000-5001;mode=\"PLAY\"";
454   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
455       NULL, NULL);
456   fail_unless (gst_rtsp_client_handle_message (client,
457           &request) == GST_RTSP_OK);
458   gst_rtsp_message_unset (&request);
459   expected_transport = NULL;
460   expected_session_timeout = 60;
461   g_object_unref (client);
462 }
463
464 GST_END_TEST;
465
466 GST_START_TEST (test_client_multicast_ignore_transport_specific)
467 {
468   GstRTSPClient *client;
469   GstRTSPMessage request = { 0, };
470   gchar *str;
471   GstRTSPClientState state = { NULL };
472
473   client = setup_multicast_client ();
474
475   state.client = client;
476   state.auth = gst_rtsp_auth_new ();
477   state.token =
478       gst_rtsp_token_new ("media.factory.role", G_TYPE_STRING, "user", NULL);
479   gst_rtsp_client_state_push_current (&state);
480
481   /* simple SETUP with a valid URI and multicast and a specific dest,
482    * but ignore it  */
483   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
484           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
485   str = g_strdup_printf ("%d", cseq);
486   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
487   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
488       "RTP/AVP;multicast;destination=233.252.0.2;ttl=2;port=5001-5006;");
489
490   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
491       "ttl=1;port=5000-5001;mode=\"PLAY\"";
492   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
493       NULL, NULL);
494   fail_unless (gst_rtsp_client_handle_message (client,
495           &request) == GST_RTSP_OK);
496   gst_rtsp_message_unset (&request);
497   expected_transport = NULL;
498
499   g_object_unref (client);
500   g_object_unref (state.auth);
501   gst_rtsp_token_unref (state.token);
502   gst_rtsp_client_state_pop_current (&state);
503 }
504
505 GST_END_TEST;
506
507 static gboolean
508 test_setup_response_461 (GstRTSPClient * client,
509     GstRTSPMessage * response, gboolean close, gpointer user_data)
510 {
511   GstRTSPStatusCode code;
512   const gchar *reason;
513   GstRTSPVersion version;
514   gchar *str;
515
516   fail_unless (expected_transport == NULL);
517
518   fail_unless (gst_rtsp_message_get_type (response) ==
519       GST_RTSP_MESSAGE_RESPONSE);
520
521   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
522           &version)
523       == GST_RTSP_OK);
524   fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
525   fail_unless (g_str_equal (reason, "Unsupported transport"));
526   fail_unless (version == GST_RTSP_VERSION_1_0);
527
528   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
529           0) == GST_RTSP_OK);
530   fail_unless (atoi (str) == cseq++);
531
532
533   return TRUE;
534 }
535
536 GST_START_TEST (test_client_multicast_invalid_transport_specific)
537 {
538   GstRTSPClient *client;
539   GstRTSPMessage request = { 0, };
540   gchar *str;
541   GstRTSPSessionPool *session_pool;
542   GstRTSPClientState state = { NULL };
543
544   client = setup_multicast_client ();
545
546   state.client = client;
547   state.auth = gst_rtsp_auth_new ();
548   state.token =
549       gst_rtsp_token_new (GST_RTSP_TRANSPORT_PERM_CLIENT_SETTINGS,
550       G_TYPE_BOOLEAN, TRUE, "media.factory.role", G_TYPE_STRING, "user", NULL);
551   gst_rtsp_client_state_push_current (&state);
552
553 #if 0
554   gst_rtsp_client_set_use_client_settings (client, TRUE);
555   fail_unless (gst_rtsp_client_get_use_client_settings (client));
556 #endif
557
558   /* simple SETUP with a valid URI and multicast, but an invalid ip */
559   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
560           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
561   str = g_strdup_printf ("%d", cseq);
562   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
563   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
564       "RTP/AVP;multicast;destination=233.252.0.2;ttl=1;port=5000-5001;");
565
566   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
567   fail_unless (gst_rtsp_client_handle_message (client,
568           &request) == GST_RTSP_OK);
569   gst_rtsp_message_unset (&request);
570
571   session_pool = gst_rtsp_client_get_session_pool (client);
572   fail_unless (session_pool != NULL);
573   /* FIXME: There seems to be a leak of a session here ! */
574   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
575   g_object_unref (session_pool);
576
577
578
579   /* simple SETUP with a valid URI and multicast, but an invalid prt */
580   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
581           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
582   str = g_strdup_printf ("%d", cseq);
583   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
584   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
585       "RTP/AVP;multicast;destination=233.252.0.1;ttl=1;port=6000-6001;");
586
587   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
588   fail_unless (gst_rtsp_client_handle_message (client,
589           &request) == GST_RTSP_OK);
590   gst_rtsp_message_unset (&request);
591
592   session_pool = gst_rtsp_client_get_session_pool (client);
593   fail_unless (session_pool != NULL);
594   /* FIXME: There seems to be a leak of a session here ! */
595   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
596   g_object_unref (session_pool);
597
598
599
600   /* simple SETUP with a valid URI and multicast, but an invalid ttl */
601   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
602           "rtsp://localhost/test/stream=0") == 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_TRANSPORT,
606       "RTP/AVP;multicast;destination=233.252.0.1;ttl=2;port=5000-5001;");
607
608   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
609   fail_unless (gst_rtsp_client_handle_message (client,
610           &request) == GST_RTSP_OK);
611   gst_rtsp_message_unset (&request);
612
613   session_pool = gst_rtsp_client_get_session_pool (client);
614   fail_unless (session_pool != NULL);
615   /* FIXME: There seems to be a leak of a session here ! */
616   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
617   g_object_unref (session_pool);
618
619
620   g_object_unref (client);
621   g_object_unref (state.auth);
622   gst_rtsp_token_unref (state.token);
623   gst_rtsp_client_state_pop_current (&state);
624 }
625
626 GST_END_TEST;
627
628 GST_START_TEST (test_client_multicast_transport_specific)
629 {
630   GstRTSPClient *client;
631   GstRTSPMessage request = { 0, };
632   gchar *str;
633   GstRTSPSessionPool *session_pool;
634   GstRTSPClientState state = { NULL };
635
636   client = setup_multicast_client ();
637
638   state.client = client;
639   state.auth = gst_rtsp_auth_new ();
640   state.token =
641       gst_rtsp_token_new (GST_RTSP_TRANSPORT_PERM_CLIENT_SETTINGS,
642       G_TYPE_BOOLEAN, TRUE, "media.factory.role", G_TYPE_STRING, "user", NULL);
643   gst_rtsp_client_state_push_current (&state);
644
645 #if 0
646   gst_rtsp_client_set_use_client_settings (client, TRUE);
647   fail_unless (gst_rtsp_client_get_use_client_settings (client));
648 #endif
649
650   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
651       "ttl=1;port=5000-5001;mode=\"PLAY\"";
652
653   /* simple SETUP with a valid URI and multicast, but an invalid ip */
654   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
655           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
656   str = g_strdup_printf ("%d", cseq);
657   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
658   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
659       expected_transport);
660
661   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
662       NULL, NULL);
663   fail_unless (gst_rtsp_client_handle_message (client,
664           &request) == GST_RTSP_OK);
665   gst_rtsp_message_unset (&request);
666   expected_transport = NULL;
667
668   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
669       NULL, NULL);
670   session_pool = gst_rtsp_client_get_session_pool (client);
671   fail_unless (session_pool != NULL);
672   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
673   g_object_unref (session_pool);
674
675   g_object_unref (client);
676   g_object_unref (state.auth);
677   gst_rtsp_token_unref (state.token);
678   gst_rtsp_client_state_pop_current (&state);
679 }
680
681 GST_END_TEST;
682
683 static gboolean
684 test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response,
685     gboolean close, gpointer user_data)
686 {
687   guint8 *data;
688   guint size;
689   GstSDPMessage *sdp_msg;
690   const GstSDPMedia *sdp_media;
691   const GstSDPBandwidth *bw;
692   gint bandwidth_val = GPOINTER_TO_INT (user_data);
693
694   fail_unless (gst_rtsp_message_get_body (response, &data, &size)
695       == GST_RTSP_OK);
696   gst_sdp_message_new (&sdp_msg);
697   fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg)
698       == GST_SDP_OK);
699
700   /* session description */
701   /* v= */
702   fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL);
703   /* o= */
704   fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL);
705   /* s= */
706   fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL);
707   /* t=0 0 */
708   fail_unless (gst_sdp_message_times_len (sdp_msg) == 0);
709
710   /* verify number of medias */
711   fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1);
712
713   /* media description */
714   sdp_media = gst_sdp_message_get_media (sdp_msg, 0);
715   fail_unless (sdp_media != NULL);
716
717   /* m= */
718   fail_unless (gst_sdp_media_get_media (sdp_media) != NULL);
719
720   /* media bandwidth */
721   if (bandwidth_val) {
722     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1);
723     bw = gst_sdp_media_get_bandwidth (sdp_media, 0);
724     fail_unless (bw != NULL);
725     fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0);
726     fail_unless (bw->bandwidth == bandwidth_val);
727   } else {
728     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0);
729   }
730
731   gst_sdp_message_free (sdp_msg);
732
733   return TRUE;
734 }
735
736 static void
737 test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
738 {
739   GstRTSPClient *client;
740   GstRTSPMessage request = { 0, };
741   gchar *str;
742
743   /* simple DESCRIBE for an existing url */
744   client = setup_client (launch_line);
745   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
746           "rtsp://localhost/test") == GST_RTSP_OK);
747   str = g_strdup_printf ("%d", cseq);
748   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
749   g_free (str);
750
751   gst_rtsp_client_set_send_func (client, test_response_sdp,
752       (gpointer) bandwidth_val, NULL);
753   fail_unless (gst_rtsp_client_handle_message (client,
754           &request) == GST_RTSP_OK);
755   gst_rtsp_message_unset (&request);
756
757   g_object_unref (client);
758
759 }
760
761 GST_START_TEST (test_client_sdp_with_max_bitrate_tag)
762 {
763   test_client_sdp ("videotestsrc "
764       "! taginject tags=\"maximum-bitrate=(uint)50000000\" "
765       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
766       GUINT_TO_POINTER (50000));
767
768
769   /* max-bitrate=0: no bandwidth line */
770   test_client_sdp ("videotestsrc "
771       "! taginject tags=\"maximum-bitrate=(uint)0\" "
772       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
773       GUINT_TO_POINTER (0));
774 }
775
776 GST_END_TEST;
777
778 GST_START_TEST (test_client_sdp_with_bitrate_tag)
779 {
780   test_client_sdp ("videotestsrc "
781       "! taginject tags=\"bitrate=(uint)7000000\" "
782       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
783       GUINT_TO_POINTER (7000));
784
785   /* bitrate=0: no bandwdith line */
786   test_client_sdp ("videotestsrc "
787       "! taginject tags=\"bitrate=(uint)0\" "
788       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
789       GUINT_TO_POINTER (0));
790 }
791
792 GST_END_TEST;
793
794 GST_START_TEST (test_client_sdp_with_max_bitrate_and_bitrate_tags)
795 {
796   test_client_sdp ("videotestsrc "
797       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)50000000\" "
798       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
799       GUINT_TO_POINTER (50000));
800
801   /* max-bitrate is zero: fallback to bitrate */
802   test_client_sdp ("videotestsrc "
803       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)0\" "
804       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
805       GUINT_TO_POINTER (7000));
806
807   /* max-bitrate=bitrate=0o: no bandwidth line */
808   test_client_sdp ("videotestsrc "
809       "! taginject tags=\"bitrate=(uint)0,maximum-bitrate=(uint)0\" "
810       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
811       GUINT_TO_POINTER (0));
812 }
813
814 GST_END_TEST;
815
816 GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
817 {
818   test_client_sdp ("videotestsrc "
819       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96", NULL);
820 }
821
822 GST_END_TEST;
823
824 static Suite *
825 rtspclient_suite (void)
826 {
827   Suite *s = suite_create ("rtspclient");
828   TCase *tc = tcase_create ("general");
829
830   suite_add_tcase (s, tc);
831   tcase_set_timeout (tc, 20);
832   tcase_add_test (tc, test_request);
833   tcase_add_test (tc, test_options);
834   tcase_add_test (tc, test_describe);
835   tcase_add_test (tc, test_client_multicast_transport_404);
836   tcase_add_test (tc, test_client_multicast_transport);
837   tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
838   tcase_add_test (tc, test_client_multicast_invalid_transport_specific);
839   tcase_add_test (tc, test_client_multicast_transport_specific);
840   tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag);
841   tcase_add_test (tc, test_client_sdp_with_bitrate_tag);
842   tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags);
843   tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
844
845   return s;
846 }
847
848 GST_CHECK_MAIN (rtspclient);