58d5d837b5cab175c291b4e1b0a925b3c2ee6645
[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
472   client = setup_multicast_client ();
473
474   /* simple SETUP with a valid URI and multicast and a specific dest,
475    * but ignore it  */
476   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
477           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
478   str = g_strdup_printf ("%d", cseq);
479   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
480   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
481       "RTP/AVP;multicast;destination=233.252.0.2;ttl=2;port=5001-5006;");
482
483   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
484       "ttl=1;port=5000-5001;mode=\"PLAY\"";
485   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
486       NULL, NULL);
487   fail_unless (gst_rtsp_client_handle_message (client,
488           &request) == GST_RTSP_OK);
489   gst_rtsp_message_unset (&request);
490   expected_transport = NULL;
491
492   g_object_unref (client);
493 }
494
495 GST_END_TEST;
496
497 static gboolean
498 test_setup_response_461 (GstRTSPClient * client,
499     GstRTSPMessage * response, gboolean close, gpointer user_data)
500 {
501   GstRTSPStatusCode code;
502   const gchar *reason;
503   GstRTSPVersion version;
504   gchar *str;
505
506   fail_unless (expected_transport == NULL);
507
508   fail_unless (gst_rtsp_message_get_type (response) ==
509       GST_RTSP_MESSAGE_RESPONSE);
510
511   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
512           &version)
513       == GST_RTSP_OK);
514   fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
515   fail_unless (g_str_equal (reason, "Unsupported transport"));
516   fail_unless (version == GST_RTSP_VERSION_1_0);
517
518   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
519           0) == GST_RTSP_OK);
520   fail_unless (atoi (str) == cseq++);
521
522
523   return TRUE;
524 }
525
526 GST_START_TEST (test_client_multicast_invalid_transport_specific)
527 {
528   GstRTSPClient *client;
529   GstRTSPMessage request = { 0, };
530   gchar *str;
531   GstRTSPSessionPool *session_pool;
532   GstRTSPContext ctx = { NULL };
533
534   client = setup_multicast_client ();
535
536   ctx.client = client;
537   ctx.auth = gst_rtsp_auth_new ();
538   ctx.token =
539       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
540       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
541       "user", NULL);
542   gst_rtsp_context_push_current (&ctx);
543
544   /* simple SETUP with a valid URI and multicast, but an invalid ip */
545   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
546           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
547   str = g_strdup_printf ("%d", cseq);
548   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
549   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
550       "RTP/AVP;multicast;destination=233.252.0.2;ttl=1;port=5000-5001;");
551
552   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
553   fail_unless (gst_rtsp_client_handle_message (client,
554           &request) == GST_RTSP_OK);
555   gst_rtsp_message_unset (&request);
556
557   session_pool = gst_rtsp_client_get_session_pool (client);
558   fail_unless (session_pool != NULL);
559   /* FIXME: There seems to be a leak of a session here ! */
560   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
561   g_object_unref (session_pool);
562
563
564
565   /* simple SETUP with a valid URI and multicast, but an invalid prt */
566   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
567           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
568   str = g_strdup_printf ("%d", cseq);
569   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
570   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
571       "RTP/AVP;multicast;destination=233.252.0.1;ttl=1;port=6000-6001;");
572
573   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
574   fail_unless (gst_rtsp_client_handle_message (client,
575           &request) == GST_RTSP_OK);
576   gst_rtsp_message_unset (&request);
577
578   session_pool = gst_rtsp_client_get_session_pool (client);
579   fail_unless (session_pool != NULL);
580   /* FIXME: There seems to be a leak of a session here ! */
581   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
582   g_object_unref (session_pool);
583
584
585
586   /* simple SETUP with a valid URI and multicast, but an invalid ttl */
587   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
588           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
589   str = g_strdup_printf ("%d", cseq);
590   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
591   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
592       "RTP/AVP;multicast;destination=233.252.0.1;ttl=2;port=5000-5001;");
593
594   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
595   fail_unless (gst_rtsp_client_handle_message (client,
596           &request) == GST_RTSP_OK);
597   gst_rtsp_message_unset (&request);
598
599   session_pool = gst_rtsp_client_get_session_pool (client);
600   fail_unless (session_pool != NULL);
601   /* FIXME: There seems to be a leak of a session here ! */
602   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
603   g_object_unref (session_pool);
604
605
606   g_object_unref (client);
607   g_object_unref (ctx.auth);
608   gst_rtsp_token_unref (ctx.token);
609   gst_rtsp_context_pop_current (&ctx);
610 }
611
612 GST_END_TEST;
613
614 GST_START_TEST (test_client_multicast_transport_specific)
615 {
616   GstRTSPClient *client;
617   GstRTSPMessage request = { 0, };
618   gchar *str;
619   GstRTSPSessionPool *session_pool;
620   GstRTSPContext ctx = { NULL };
621
622   client = setup_multicast_client ();
623
624   ctx.client = client;
625   ctx.auth = gst_rtsp_auth_new ();
626   ctx.token =
627       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
628       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
629       "user", NULL);
630   gst_rtsp_context_push_current (&ctx);
631
632   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
633       "ttl=1;port=5000-5001;mode=\"PLAY\"";
634
635   /* simple SETUP with a valid URI and multicast, but an invalid ip */
636   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
637           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
638   str = g_strdup_printf ("%d", cseq);
639   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
640   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
641       expected_transport);
642
643   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
644       NULL, NULL);
645   fail_unless (gst_rtsp_client_handle_message (client,
646           &request) == GST_RTSP_OK);
647   gst_rtsp_message_unset (&request);
648   expected_transport = NULL;
649
650   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
651       NULL, NULL);
652   session_pool = gst_rtsp_client_get_session_pool (client);
653   fail_unless (session_pool != NULL);
654   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
655   g_object_unref (session_pool);
656
657   g_object_unref (client);
658   g_object_unref (ctx.auth);
659   gst_rtsp_token_unref (ctx.token);
660   gst_rtsp_context_pop_current (&ctx);
661 }
662
663 GST_END_TEST;
664
665 static gboolean
666 test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response,
667     gboolean close, gpointer user_data)
668 {
669   guint8 *data;
670   guint size;
671   GstSDPMessage *sdp_msg;
672   const GstSDPMedia *sdp_media;
673   const GstSDPBandwidth *bw;
674   gint bandwidth_val = GPOINTER_TO_INT (user_data);
675
676   fail_unless (gst_rtsp_message_get_body (response, &data, &size)
677       == GST_RTSP_OK);
678   gst_sdp_message_new (&sdp_msg);
679   fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg)
680       == GST_SDP_OK);
681
682   /* session description */
683   /* v= */
684   fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL);
685   /* o= */
686   fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL);
687   /* s= */
688   fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL);
689   /* t=0 0 */
690   fail_unless (gst_sdp_message_times_len (sdp_msg) == 0);
691
692   /* verify number of medias */
693   fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1);
694
695   /* media description */
696   sdp_media = gst_sdp_message_get_media (sdp_msg, 0);
697   fail_unless (sdp_media != NULL);
698
699   /* m= */
700   fail_unless (gst_sdp_media_get_media (sdp_media) != NULL);
701
702   /* media bandwidth */
703   if (bandwidth_val) {
704     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1);
705     bw = gst_sdp_media_get_bandwidth (sdp_media, 0);
706     fail_unless (bw != NULL);
707     fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0);
708     fail_unless (bw->bandwidth == bandwidth_val);
709   } else {
710     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0);
711   }
712
713   gst_sdp_message_free (sdp_msg);
714
715   return TRUE;
716 }
717
718 static void
719 test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
720 {
721   GstRTSPClient *client;
722   GstRTSPMessage request = { 0, };
723   gchar *str;
724
725   /* simple DESCRIBE for an existing url */
726   client = setup_client (launch_line);
727   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
728           "rtsp://localhost/test") == GST_RTSP_OK);
729   str = g_strdup_printf ("%d", cseq);
730   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
731   g_free (str);
732
733   gst_rtsp_client_set_send_func (client, test_response_sdp,
734       (gpointer) bandwidth_val, NULL);
735   fail_unless (gst_rtsp_client_handle_message (client,
736           &request) == GST_RTSP_OK);
737   gst_rtsp_message_unset (&request);
738
739   g_object_unref (client);
740
741 }
742
743 GST_START_TEST (test_client_sdp_with_max_bitrate_tag)
744 {
745   test_client_sdp ("videotestsrc "
746       "! taginject tags=\"maximum-bitrate=(uint)50000000\" "
747       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
748       GUINT_TO_POINTER (50000));
749
750
751   /* max-bitrate=0: no bandwidth line */
752   test_client_sdp ("videotestsrc "
753       "! taginject tags=\"maximum-bitrate=(uint)0\" "
754       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
755       GUINT_TO_POINTER (0));
756 }
757
758 GST_END_TEST;
759
760 GST_START_TEST (test_client_sdp_with_bitrate_tag)
761 {
762   test_client_sdp ("videotestsrc "
763       "! taginject tags=\"bitrate=(uint)7000000\" "
764       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
765       GUINT_TO_POINTER (7000));
766
767   /* bitrate=0: no bandwdith line */
768   test_client_sdp ("videotestsrc "
769       "! taginject tags=\"bitrate=(uint)0\" "
770       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
771       GUINT_TO_POINTER (0));
772 }
773
774 GST_END_TEST;
775
776 GST_START_TEST (test_client_sdp_with_max_bitrate_and_bitrate_tags)
777 {
778   test_client_sdp ("videotestsrc "
779       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)50000000\" "
780       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
781       GUINT_TO_POINTER (50000));
782
783   /* max-bitrate is zero: fallback to bitrate */
784   test_client_sdp ("videotestsrc "
785       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)0\" "
786       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
787       GUINT_TO_POINTER (7000));
788
789   /* max-bitrate=bitrate=0o: no bandwidth line */
790   test_client_sdp ("videotestsrc "
791       "! taginject tags=\"bitrate=(uint)0,maximum-bitrate=(uint)0\" "
792       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
793       GUINT_TO_POINTER (0));
794 }
795
796 GST_END_TEST;
797
798 GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
799 {
800   test_client_sdp ("videotestsrc "
801       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96", NULL);
802 }
803
804 GST_END_TEST;
805
806 static Suite *
807 rtspclient_suite (void)
808 {
809   Suite *s = suite_create ("rtspclient");
810   TCase *tc = tcase_create ("general");
811
812   suite_add_tcase (s, tc);
813   tcase_set_timeout (tc, 20);
814   tcase_add_test (tc, test_request);
815   tcase_add_test (tc, test_options);
816   tcase_add_test (tc, test_describe);
817   tcase_add_test (tc, test_client_multicast_transport_404);
818   tcase_add_test (tc, test_client_multicast_transport);
819   tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
820   tcase_add_test (tc, test_client_multicast_invalid_transport_specific);
821   tcase_add_test (tc, test_client_multicast_transport_specific);
822   tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag);
823   tcase_add_test (tc, test_client_sdp_with_bitrate_tag);
824   tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags);
825   tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
826
827   return s;
828 }
829
830 GST_CHECK_MAIN (rtspclient);