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