| /* GStreamer unit tests for the srtp elements |
| * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net> |
| * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org> |
| * Copyright (C) 2016 Collabora Ltd <vincent.penquerch@collabora.co.uk> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| # include "config.h" |
| #endif |
| |
| #ifdef HAVE_VALGRIND |
| # include <valgrind/valgrind.h> |
| #endif |
| |
| #include <gst/check/gstcheck.h> |
| |
| #include <gst/check/gstharness.h> |
| |
| GST_START_TEST (test_create_and_unref) |
| { |
| GstElement *e; |
| |
| e = gst_element_factory_make ("dtlsenc", NULL); |
| fail_unless (e != NULL); |
| gst_element_set_state (e, GST_STATE_NULL); |
| gst_object_unref (e); |
| |
| e = gst_element_factory_make ("dtlsdec", NULL); |
| fail_unless (e != NULL); |
| gst_element_set_state (e, GST_STATE_NULL); |
| gst_object_unref (e); |
| } |
| |
| GST_END_TEST; |
| |
| static GMutex key_lock; |
| static GCond key_cond; |
| static int key_count; |
| |
| static void |
| _on_key_received (GstElement * element, gpointer user_data) |
| { |
| g_mutex_lock (&key_lock); |
| key_count++; |
| g_cond_broadcast (&key_cond); |
| g_mutex_unlock (&key_lock); |
| } |
| |
| static void |
| _wait_for_key_count_to_reach (int n) |
| { |
| g_mutex_lock (&key_lock); |
| while (key_count < n) |
| g_cond_wait (&key_cond, &key_lock); |
| g_mutex_unlock (&key_lock); |
| } |
| |
| static gchar data[] = { |
| 0x00, 0x01, 0x02, 0x03, |
| }; |
| |
| GST_START_TEST (test_data_transfer) |
| { |
| GstHarness *server, *client; |
| GstElement *s_enc, *s_dec, *c_enc, *c_dec, *s_bin, *c_bin; |
| GstPad *target, *ghost; |
| GstBuffer *buffer, *buf2; |
| |
| /* setup a server and client for dtls negotiation */ |
| s_bin = gst_bin_new (NULL); |
| c_bin = gst_bin_new (NULL); |
| |
| /* XXX: the element set states are needed to avoid a runtime warning: |
| * |
| * 'gst_dtls_connection_process: runtime check failed: (!priv->bio_buffer)' |
| * |
| * where the encoder needs to be started (and SSL initialized) before the |
| * associated decoder receives any data and calls gst_dtls_connection_process(). |
| */ |
| s_dec = gst_element_factory_make ("dtlsdec", "server_dec"); |
| g_object_set (s_dec, "connection-id", "server", NULL); |
| g_signal_connect (s_dec, "on-key-received", G_CALLBACK (_on_key_received), |
| NULL); |
| gst_element_set_state (s_dec, GST_STATE_PAUSED); |
| gst_bin_add (GST_BIN (s_bin), s_dec); |
| |
| s_enc = gst_element_factory_make ("dtlsenc", "server_enc"); |
| g_object_set (s_enc, "connection-id", "server", NULL); |
| g_signal_connect (s_enc, "on-key-received", G_CALLBACK (_on_key_received), |
| NULL); |
| gst_element_set_state (s_enc, GST_STATE_PAUSED); |
| gst_bin_add (GST_BIN (c_bin), s_enc); |
| |
| c_dec = gst_element_factory_make ("dtlsdec", "client_dec"); |
| g_object_set (c_dec, "connection-id", "client", NULL); |
| g_signal_connect (c_dec, "on-key-received", G_CALLBACK (_on_key_received), |
| NULL); |
| gst_element_set_state (c_dec, GST_STATE_PAUSED); |
| gst_bin_add (GST_BIN (c_bin), c_dec); |
| |
| c_enc = gst_element_factory_make ("dtlsenc", "client_enc"); |
| g_object_set (c_enc, "connection-id", "client", "is-client", TRUE, NULL); |
| g_signal_connect (c_enc, "on-key-received", G_CALLBACK (_on_key_received), |
| NULL); |
| gst_element_set_state (c_enc, GST_STATE_PAUSED); |
| gst_bin_add (GST_BIN (s_bin), c_enc); |
| |
| gst_element_link_pads (s_enc, "src", c_dec, "sink"); |
| gst_element_link_pads (c_enc, "src", s_dec, "sink"); |
| |
| target = gst_element_get_request_pad (c_dec, "src"); |
| ghost = gst_ghost_pad_new ("src", target); |
| gst_element_add_pad (s_bin, ghost); |
| gst_object_unref (target); |
| |
| target = gst_element_get_request_pad (s_enc, "sink"); |
| ghost = gst_ghost_pad_new ("sink", target); |
| gst_element_add_pad (s_bin, ghost); |
| gst_object_unref (target); |
| |
| target = gst_element_get_request_pad (s_dec, "src"); |
| ghost = gst_ghost_pad_new ("src", target); |
| gst_element_add_pad (c_bin, ghost); |
| gst_object_unref (target); |
| |
| target = gst_element_get_request_pad (c_enc, "sink"); |
| ghost = gst_ghost_pad_new ("sink", target); |
| gst_element_add_pad (c_bin, ghost); |
| gst_object_unref (target); |
| |
| server = gst_harness_new_with_element (s_bin, "sink", "src"); |
| client = gst_harness_new_with_element (c_bin, "sink", "src"); |
| |
| gst_harness_set_src_caps_str (server, "application/data"); |
| gst_harness_set_src_caps_str (client, "application/data"); |
| |
| _wait_for_key_count_to_reach (4); |
| |
| buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, data, |
| G_N_ELEMENTS (data), 0, G_N_ELEMENTS (data), NULL, NULL); |
| gst_harness_push (server, gst_buffer_ref (buffer)); |
| buf2 = gst_harness_pull (server); |
| fail_unless_equals_int (0, gst_buffer_memcmp (buf2, 0, data, |
| G_N_ELEMENTS (data))); |
| gst_buffer_unref (buf2); |
| |
| gst_harness_play (client); |
| gst_harness_push (client, gst_buffer_ref (buffer)); |
| buf2 = gst_harness_pull (client); |
| fail_unless_equals_int (0, gst_buffer_memcmp (buf2, 0, data, |
| G_N_ELEMENTS (data))); |
| gst_buffer_unref (buf2); |
| |
| gst_object_unref (s_bin); |
| gst_object_unref (c_bin); |
| |
| gst_buffer_unref (buffer); |
| gst_harness_teardown (server); |
| gst_harness_teardown (client); |
| } |
| |
| GST_END_TEST; |
| |
| static Suite * |
| dtls_suite (void) |
| { |
| Suite *s = suite_create ("dtls"); |
| TCase *tc_chain = tcase_create ("general"); |
| |
| suite_add_tcase (s, tc_chain); |
| tcase_add_test (tc_chain, test_create_and_unref); |
| tcase_add_test (tc_chain, test_data_transfer); |
| |
| return s; |
| } |
| |
| GST_CHECK_MAIN (dtls); |