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