Initial release including wifi display based on gst-rtsp-server-1.4.1
[platform/upstream/gst-rtsp-server.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   /* FIXME: There seems to be a leak of a session here ! */
658   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0);
659   g_object_unref (session_pool);
660
661
662
663   /* simple SETUP with a valid URI and multicast, but an invalid prt */
664   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
665           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
666   str = g_strdup_printf ("%d", cseq);
667   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
668   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
669       "RTP/AVP;multicast;destination=233.252.0.1;ttl=1;port=6000-6001;");
670
671   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
672   fail_unless (gst_rtsp_client_handle_message (client,
673           &request) == GST_RTSP_OK);
674   gst_rtsp_message_unset (&request);
675
676   session_pool = gst_rtsp_client_get_session_pool (client);
677   fail_unless (session_pool != NULL);
678   /* FIXME: There seems to be a leak of a session here ! */
679   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0);
680   g_object_unref (session_pool);
681
682
683
684   /* simple SETUP with a valid URI and multicast, but an invalid ttl */
685   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
686           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
687   str = g_strdup_printf ("%d", cseq);
688   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
689   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
690       "RTP/AVP;multicast;destination=233.252.0.1;ttl=2;port=5000-5001;");
691
692   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
693   fail_unless (gst_rtsp_client_handle_message (client,
694           &request) == GST_RTSP_OK);
695   gst_rtsp_message_unset (&request);
696
697   session_pool = gst_rtsp_client_get_session_pool (client);
698   fail_unless (session_pool != NULL);
699   /* FIXME: There seems to be a leak of a session here ! */
700   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0);
701   g_object_unref (session_pool);
702
703
704   teardown_client (client);
705   g_object_unref (ctx.auth);
706   gst_rtsp_token_unref (ctx.token);
707   gst_rtsp_context_pop_current (&ctx);
708 }
709
710 GST_END_TEST;
711
712 GST_START_TEST (test_client_multicast_transport_specific)
713 {
714   GstRTSPClient *client;
715   GstRTSPMessage request = { 0, };
716   gchar *str;
717   GstRTSPSessionPool *session_pool;
718   GstRTSPContext ctx = { NULL };
719
720   client = setup_multicast_client ();
721
722   ctx.client = client;
723   ctx.auth = gst_rtsp_auth_new ();
724   ctx.token =
725       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
726       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
727       "user", NULL);
728   gst_rtsp_context_push_current (&ctx);
729
730   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
731       "ttl=1;port=5000-5001;mode=\"PLAY\"";
732
733   /* simple SETUP with a valid URI and multicast, but an invalid ip */
734   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
735           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
736   str = g_strdup_printf ("%d", cseq);
737   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
738   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
739       expected_transport);
740
741   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
742       NULL, NULL);
743   fail_unless (gst_rtsp_client_handle_message (client,
744           &request) == GST_RTSP_OK);
745   gst_rtsp_message_unset (&request);
746   expected_transport = NULL;
747
748   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
749       NULL, NULL);
750   session_pool = gst_rtsp_client_get_session_pool (client);
751   fail_unless (session_pool != NULL);
752   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
753   g_object_unref (session_pool);
754
755   send_teardown (client);
756
757   teardown_client (client);
758   g_object_unref (ctx.auth);
759   gst_rtsp_token_unref (ctx.token);
760   gst_rtsp_context_pop_current (&ctx);
761 }
762
763 GST_END_TEST;
764
765 static gboolean
766 test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response,
767     gboolean close, gpointer user_data)
768 {
769   guint8 *data;
770   guint size;
771   GstSDPMessage *sdp_msg;
772   const GstSDPMedia *sdp_media;
773   const GstSDPBandwidth *bw;
774   gint bandwidth_val = GPOINTER_TO_INT (user_data);
775
776   fail_unless (gst_rtsp_message_get_body (response, &data, &size)
777       == GST_RTSP_OK);
778   gst_sdp_message_new (&sdp_msg);
779   fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg)
780       == GST_SDP_OK);
781
782   /* session description */
783   /* v= */
784   fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL);
785   /* o= */
786   fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL);
787   /* s= */
788   fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL);
789   /* t=0 0 */
790   fail_unless (gst_sdp_message_times_len (sdp_msg) == 0);
791
792   /* verify number of medias */
793   fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1);
794
795   /* media description */
796   sdp_media = gst_sdp_message_get_media (sdp_msg, 0);
797   fail_unless (sdp_media != NULL);
798
799   /* m= */
800   fail_unless (gst_sdp_media_get_media (sdp_media) != NULL);
801
802   /* media bandwidth */
803   if (bandwidth_val) {
804     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1);
805     bw = gst_sdp_media_get_bandwidth (sdp_media, 0);
806     fail_unless (bw != NULL);
807     fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0);
808     fail_unless (bw->bandwidth == bandwidth_val);
809   } else {
810     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0);
811   }
812
813   gst_sdp_message_free (sdp_msg);
814
815   return TRUE;
816 }
817
818 static void
819 test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
820 {
821   GstRTSPClient *client;
822   GstRTSPMessage request = { 0, };
823   gchar *str;
824
825   /* simple DESCRIBE for an existing url */
826   client = setup_client (launch_line);
827   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
828           "rtsp://localhost/test") == GST_RTSP_OK);
829   str = g_strdup_printf ("%d", cseq);
830   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
831   g_free (str);
832
833   gst_rtsp_client_set_send_func (client, test_response_sdp,
834       (gpointer) bandwidth_val, NULL);
835   fail_unless (gst_rtsp_client_handle_message (client,
836           &request) == GST_RTSP_OK);
837   gst_rtsp_message_unset (&request);
838
839   teardown_client (client);
840 }
841
842 GST_START_TEST (test_client_sdp_with_max_bitrate_tag)
843 {
844   test_client_sdp ("videotestsrc "
845       "! taginject tags=\"maximum-bitrate=(uint)50000000\" "
846       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
847       GUINT_TO_POINTER (50000));
848
849
850   /* max-bitrate=0: no bandwidth line */
851   test_client_sdp ("videotestsrc "
852       "! taginject tags=\"maximum-bitrate=(uint)0\" "
853       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
854       GUINT_TO_POINTER (0));
855 }
856
857 GST_END_TEST;
858
859 GST_START_TEST (test_client_sdp_with_bitrate_tag)
860 {
861   test_client_sdp ("videotestsrc "
862       "! taginject tags=\"bitrate=(uint)7000000\" "
863       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
864       GUINT_TO_POINTER (7000));
865
866   /* bitrate=0: no bandwdith line */
867   test_client_sdp ("videotestsrc "
868       "! taginject tags=\"bitrate=(uint)0\" "
869       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
870       GUINT_TO_POINTER (0));
871 }
872
873 GST_END_TEST;
874
875 GST_START_TEST (test_client_sdp_with_max_bitrate_and_bitrate_tags)
876 {
877   test_client_sdp ("videotestsrc "
878       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)50000000\" "
879       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
880       GUINT_TO_POINTER (50000));
881
882   /* max-bitrate is zero: fallback to bitrate */
883   test_client_sdp ("videotestsrc "
884       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)0\" "
885       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
886       GUINT_TO_POINTER (7000));
887
888   /* max-bitrate=bitrate=0o: no bandwidth line */
889   test_client_sdp ("videotestsrc "
890       "! taginject tags=\"bitrate=(uint)0,maximum-bitrate=(uint)0\" "
891       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
892       GUINT_TO_POINTER (0));
893 }
894
895 GST_END_TEST;
896
897 GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
898 {
899   test_client_sdp ("videotestsrc "
900       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96", NULL);
901 }
902
903 GST_END_TEST;
904
905 static Suite *
906 rtspclient_suite (void)
907 {
908   Suite *s = suite_create ("rtspclient");
909   TCase *tc = tcase_create ("general");
910
911   suite_add_tcase (s, tc);
912   tcase_set_timeout (tc, 20);
913   tcase_add_test (tc, test_request);
914   tcase_add_test (tc, test_options);
915   tcase_add_test (tc, test_describe);
916   tcase_add_test (tc, test_client_multicast_transport_404);
917   tcase_add_test (tc, test_client_multicast_transport);
918   tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
919   tcase_add_test (tc, test_client_multicast_invalid_transport_specific);
920   tcase_add_test (tc, test_client_multicast_transport_specific);
921   tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag);
922   tcase_add_test (tc, test_client_sdp_with_bitrate_tag);
923   tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags);
924   tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
925
926   return s;
927 }
928
929 GST_CHECK_MAIN (rtspclient);