/* dtls_srtp.c generated by valac 0.56.19, the Vala compiler
 * generated from dtls_srtp.vala, do not modify */

#include "ice.h"
#include <glib.h>
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>
#include "crypto-vala.h"
#include <gnutls/x509.h>
#include <gnutls/gnutls.h>
#include <time.h>
#include <gio/gio.h>
#include "xmpp-vala.h"
#include <float.h>
#include <math.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define _gnutls_x509_privkey_deinit0(var) ((var == NULL) ? NULL : (var = (gnutls_x509_privkey_deinit (var), NULL)))
typedef struct _DinoPluginsIceDtlsSrtpParamSpecCredentialsCapsule DinoPluginsIceDtlsSrtpParamSpecCredentialsCapsule;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _dino_plugins_ice_dtls_srtp_credentials_capsule_unref0(var) ((var == NULL) ? NULL : (var = (dino_plugins_ice_dtls_srtp_credentials_capsule_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _crypto_srtp_session_unref0(var) ((var == NULL) ? NULL : (var = (crypto_srtp_session_unref (var), NULL)))
#define _g_bytes_unref0(var) ((var == NULL) ? NULL : (var = (g_bytes_unref (var), NULL)))
#define _g_date_time_unref0(var) ((var == NULL) ? NULL : (var = (g_date_time_unref (var), NULL)))
#define _gnutls_x509_crt_deinit0(var) ((var == NULL) ? NULL : (var = (gnutls_x509_crt_deinit (var), NULL)))
#define _dino_plugins_ice_dtls_srtp_handler_unref0(var) ((var == NULL) ? NULL : (var = (dino_plugins_ice_dtls_srtp_handler_unref (var), NULL)))
typedef struct _Block1Data Block1Data;
#define _g_main_context_unref0(var) ((var == NULL) ? NULL : (var = (g_main_context_unref (var), NULL)))
#define _g_source_unref0(var) ((var == NULL) ? NULL : (var = (g_source_unref (var), NULL)))
#define _g_thread_unref0(var) ((var == NULL) ? NULL : (var = (g_thread_unref (var), NULL)))
typedef struct _DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData;
#define _gnutls_certificate_free_credentials0(var) ((var == NULL) ? NULL : (var = (gnutls_certificate_free_credentials (var), NULL)))
#define _gnutls_deinit0(var) ((var == NULL) ? NULL : (var = (gnutls_deinit (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _DinoPluginsIceDtlsSrtpParamSpecHandler DinoPluginsIceDtlsSrtpParamSpecHandler;
enum  {
	DINO_PLUGINS_ICE_DTLS_SRTP_HANDLER_SEND_DATA_SIGNAL,
	DINO_PLUGINS_ICE_DTLS_SRTP_HANDLER_NUM_SIGNALS
};
static guint dino_plugins_ice_dtls_srtp_handler_signals[DINO_PLUGINS_ICE_DTLS_SRTP_HANDLER_NUM_SIGNALS] = {0};
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

struct _DinoPluginsIceDtlsSrtpParamSpecCredentialsCapsule {
	GParamSpec parent_instance;
};

struct _DinoPluginsIceDtlsSrtpHandlerPrivate {
	DinoPluginsIceDtlsSrtpMode _mode;
	guint8* _own_fingerprint;
	gint _own_fingerprint_length1;
	gint __own_fingerprint_size_;
	guint8* _peer_fingerprint;
	gint _peer_fingerprint_length1;
	gint __peer_fingerprint_size_;
	gchar* _peer_fp_algo;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* credentials;
	GCond buffer_cond;
	GMutex buffer_mutex;
	GeeLinkedList* buffer_queue;
	gboolean running;
	gboolean stop;
	gboolean restart;
	CryptoSrtpSession* srtp_session;
};

struct _Block1Data {
	int _ref_count_;
	DinoPluginsIceDtlsSrtpHandler* self;
	GMainContext* context;
	gpointer _async_data_;
};

struct _DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	DinoPluginsIceDtlsSrtpHandler* self;
	XmppXepJingleContentEncryption* result;
	Block1Data* _data1_;
	GSource* _tmp0_;
	GMainContext* _tmp1_;
	GMainContext* _tmp2_;
	GThread* thread;
	GThread* _tmp3_;
	GThread* _tmp4_;
	gpointer _tmp5_;
};

struct _DinoPluginsIceDtlsSrtpParamSpecHandler {
	GParamSpec parent_instance;
};

static gpointer dino_plugins_ice_dtls_srtp_credentials_capsule_parent_class = NULL;
static gint DinoPluginsIceDtlsSrtpHandler_private_offset;
static gpointer dino_plugins_ice_dtls_srtp_handler_parent_class = NULL;

static void dino_plugins_ice_dtls_srtp_credentials_capsule_finalize (DinoPluginsIceDtlsSrtpCredentialsCapsule * obj);
static GType dino_plugins_ice_dtls_srtp_credentials_capsule_get_type_once (void);
static void dino_plugins_ice_dtls_srtp_handler_set_own_fingerprint (DinoPluginsIceDtlsSrtpHandler* self,
                                                             guint8* value,
                                                             gint value_length1);
static guint8* _vala_array_dup1 (guint8* self,
                          gssize length);
static guint8* _vala_array_dup2 (guint8* self,
                          gssize length);
VALA_EXTERN DinoPluginsIceDtlsSrtpCredentialsCapsule* dino_plugins_ice_dtls_srtp_handler_generate_credentials (GError** error);
VALA_EXTERN guint8* dino_plugins_ice_dtls_srtp_get_fingerprint (struct gnutls_x509_crt_int* certificate,
                                                    gnutls_digest_algorithm_t digest_algo,
                                                    gint* result_length1);
static guint8* _vala_array_dup3 (guint8* self,
                          gssize length);
static void dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_data_free (gpointer _data);
static gboolean dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_co (DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData* _data_);
static Block1Data* block1_data_ref (Block1Data* _data1_);
static void block1_data_unref (void * _userdata_);
static XmppXepJingleContentEncryption* __lambda4_ (Block1Data* _data1_);
static XmppXepJingleContentEncryption* dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_thread (DinoPluginsIceDtlsSrtpHandler* self);
static gboolean _dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_co_gsource_func (gpointer self);
static gpointer ___lambda4__gthread_func (gpointer self);
static gssize dino_plugins_ice_dtls_srtp_handler_pull_function (void* transport_ptr,
                                                         guint8* buffer,
                                                         gint buffer_length1);
static gssize _dino_plugins_ice_dtls_srtp_handler_pull_function_gnutls_pull_func (void* transport_ptr,
                                                                           void* array,
                                                                           size_t array_length1);
static gint dino_plugins_ice_dtls_srtp_handler_pull_timeout_function (void* transport_ptr,
                                                               guint ms);
static gint _dino_plugins_ice_dtls_srtp_handler_pull_timeout_function_gnutls_pull_timeout_func (void* transport_ptr,
                                                                                         guint ms);
static gssize dino_plugins_ice_dtls_srtp_handler_push_function (void* transport_ptr,
                                                         guint8* buffer,
                                                         gint buffer_length1);
static gssize _dino_plugins_ice_dtls_srtp_handler_push_function_gnutls_push_func (void* transport_ptr,
                                                                           void* array,
                                                                           size_t array_length1);
static gint dino_plugins_ice_dtls_srtp_handler_verify_function (struct gnutls_session_int* session);
static gint _dino_plugins_ice_dtls_srtp_handler_verify_function_gnutls_certificate_verify_function (struct gnutls_session_int* session);
static gnutls_datum_t* _gnutls_datum_dup (gnutls_datum_t* self);
static gboolean dino_plugins_ice_dtls_srtp_handler_verify_peer_cert (DinoPluginsIceDtlsSrtpHandler* self,
                                                              struct gnutls_session_int* session,
                                                              GError** error);
VALA_EXTERN gchar* dino_plugins_ice_dtls_srtp_format_fingerprint (guint8* fingerprint,
                                                      gint fingerprint_length1);
static guint8* _vala_array_dup4 (guint8* self,
                          gssize length);
static guint8* _vala_array_dup5 (guint8* self,
                          gssize length);
static void g_cclosure_user_marshal_VOID__POINTER_INT (GClosure * closure,
                                                GValue * return_value,
                                                guint n_param_values,
                                                const GValue * param_values,
                                                gpointer invocation_hint,
                                                gpointer marshal_data);
static void dino_plugins_ice_dtls_srtp_handler_finalize (DinoPluginsIceDtlsSrtpHandler * obj);
static GType dino_plugins_ice_dtls_srtp_handler_get_type_once (void);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static void _vala_clear_GMutex (GMutex * mutex);
static void _vala_clear_GRecMutex (GRecMutex * mutex);
static void _vala_clear_GRWLock (GRWLock * mutex);
static void _vala_clear_GCond (GCond * mutex);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

DinoPluginsIceDtlsSrtpCredentialsCapsule*
dino_plugins_ice_dtls_srtp_credentials_capsule_construct (GType object_type)
{
	DinoPluginsIceDtlsSrtpCredentialsCapsule* self = NULL;
	self = (DinoPluginsIceDtlsSrtpCredentialsCapsule*) g_type_create_instance (object_type);
	return self;
}

DinoPluginsIceDtlsSrtpCredentialsCapsule*
dino_plugins_ice_dtls_srtp_credentials_capsule_new (void)
{
	return dino_plugins_ice_dtls_srtp_credentials_capsule_construct (DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE);
}

static void
dino_plugins_ice_dtls_srtp_value_credentials_capsule_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
dino_plugins_ice_dtls_srtp_value_credentials_capsule_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		dino_plugins_ice_dtls_srtp_credentials_capsule_unref (value->data[0].v_pointer);
	}
}

static void
dino_plugins_ice_dtls_srtp_value_credentials_capsule_copy_value (const GValue* src_value,
                                                                 GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = dino_plugins_ice_dtls_srtp_credentials_capsule_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
dino_plugins_ice_dtls_srtp_value_credentials_capsule_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
dino_plugins_ice_dtls_srtp_value_credentials_capsule_collect_value (GValue* value,
                                                                    guint n_collect_values,
                                                                    GTypeCValue* collect_values,
                                                                    guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		DinoPluginsIceDtlsSrtpCredentialsCapsule * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = dino_plugins_ice_dtls_srtp_credentials_capsule_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
dino_plugins_ice_dtls_srtp_value_credentials_capsule_lcopy_value (const GValue* value,
                                                                  guint n_collect_values,
                                                                  GTypeCValue* collect_values,
                                                                  guint collect_flags)
{
	DinoPluginsIceDtlsSrtpCredentialsCapsule ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = dino_plugins_ice_dtls_srtp_credentials_capsule_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
dino_plugins_ice_dtls_srtp_param_spec_credentials_capsule (const gchar* name,
                                                           const gchar* nick,
                                                           const gchar* blurb,
                                                           GType object_type,
                                                           GParamFlags flags)
{
	DinoPluginsIceDtlsSrtpParamSpecCredentialsCapsule* spec;
	g_return_val_if_fail (g_type_is_a (object_type, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

gpointer
dino_plugins_ice_dtls_srtp_value_get_credentials_capsule (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE), NULL);
	return value->data[0].v_pointer;
}

void
dino_plugins_ice_dtls_srtp_value_set_credentials_capsule (GValue* value,
                                                          gpointer v_object)
{
	DinoPluginsIceDtlsSrtpCredentialsCapsule * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		dino_plugins_ice_dtls_srtp_credentials_capsule_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dino_plugins_ice_dtls_srtp_credentials_capsule_unref (old);
	}
}

void
dino_plugins_ice_dtls_srtp_value_take_credentials_capsule (GValue* value,
                                                           gpointer v_object)
{
	DinoPluginsIceDtlsSrtpCredentialsCapsule * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dino_plugins_ice_dtls_srtp_credentials_capsule_unref (old);
	}
}

static void
dino_plugins_ice_dtls_srtp_credentials_capsule_class_init (DinoPluginsIceDtlsSrtpCredentialsCapsuleClass * klass,
                                                           gpointer klass_data)
{
	dino_plugins_ice_dtls_srtp_credentials_capsule_parent_class = g_type_class_peek_parent (klass);
	((DinoPluginsIceDtlsSrtpCredentialsCapsuleClass *) klass)->finalize = dino_plugins_ice_dtls_srtp_credentials_capsule_finalize;
}

static void
dino_plugins_ice_dtls_srtp_credentials_capsule_instance_init (DinoPluginsIceDtlsSrtpCredentialsCapsule * self,
                                                              gpointer klass)
{
	self->ref_count = 1;
}

static void
dino_plugins_ice_dtls_srtp_credentials_capsule_finalize (DinoPluginsIceDtlsSrtpCredentialsCapsule * obj)
{
	DinoPluginsIceDtlsSrtpCredentialsCapsule * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_CREDENTIALS_CAPSULE, DinoPluginsIceDtlsSrtpCredentialsCapsule);
	g_signal_handlers_destroy (self);
	self->own_fingerprint = (g_free (self->own_fingerprint), NULL);
	self->own_cert = (_vala_array_free (self->own_cert, self->own_cert_length1, (GDestroyNotify) gnutls_x509_crt_deinit), NULL);
	_gnutls_x509_privkey_deinit0 (self->private_key);
}

static GType
dino_plugins_ice_dtls_srtp_credentials_capsule_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { dino_plugins_ice_dtls_srtp_value_credentials_capsule_init, dino_plugins_ice_dtls_srtp_value_credentials_capsule_free_value, dino_plugins_ice_dtls_srtp_value_credentials_capsule_copy_value, dino_plugins_ice_dtls_srtp_value_credentials_capsule_peek_pointer, "p", dino_plugins_ice_dtls_srtp_value_credentials_capsule_collect_value, "p", dino_plugins_ice_dtls_srtp_value_credentials_capsule_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (DinoPluginsIceDtlsSrtpCredentialsCapsuleClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dino_plugins_ice_dtls_srtp_credentials_capsule_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DinoPluginsIceDtlsSrtpCredentialsCapsule), 0, (GInstanceInitFunc) dino_plugins_ice_dtls_srtp_credentials_capsule_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType dino_plugins_ice_dtls_srtp_credentials_capsule_type_id;
	dino_plugins_ice_dtls_srtp_credentials_capsule_type_id = g_type_register_fundamental (g_type_fundamental_next (), "DinoPluginsIceDtlsSrtpCredentialsCapsule", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return dino_plugins_ice_dtls_srtp_credentials_capsule_type_id;
}

GType
dino_plugins_ice_dtls_srtp_credentials_capsule_get_type (void)
{
	static volatile gsize dino_plugins_ice_dtls_srtp_credentials_capsule_type_id__once = 0;
	if (g_once_init_enter (&dino_plugins_ice_dtls_srtp_credentials_capsule_type_id__once)) {
		GType dino_plugins_ice_dtls_srtp_credentials_capsule_type_id;
		dino_plugins_ice_dtls_srtp_credentials_capsule_type_id = dino_plugins_ice_dtls_srtp_credentials_capsule_get_type_once ();
		g_once_init_leave (&dino_plugins_ice_dtls_srtp_credentials_capsule_type_id__once, dino_plugins_ice_dtls_srtp_credentials_capsule_type_id);
	}
	return dino_plugins_ice_dtls_srtp_credentials_capsule_type_id__once;
}

gpointer
dino_plugins_ice_dtls_srtp_credentials_capsule_ref (gpointer instance)
{
	DinoPluginsIceDtlsSrtpCredentialsCapsule * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
dino_plugins_ice_dtls_srtp_credentials_capsule_unref (gpointer instance)
{
	DinoPluginsIceDtlsSrtpCredentialsCapsule * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		DINO_PLUGINS_ICE_DTLS_SRTP_CREDENTIALS_CAPSULE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
dino_plugins_ice_dtls_srtp_handler_get_instance_private (DinoPluginsIceDtlsSrtpHandler* self)
{
	return G_STRUCT_MEMBER_P (self, DinoPluginsIceDtlsSrtpHandler_private_offset);
}

static gpointer
_dino_plugins_ice_dtls_srtp_credentials_capsule_ref0 (gpointer self)
{
	return self ? dino_plugins_ice_dtls_srtp_credentials_capsule_ref (self) : NULL;
}

DinoPluginsIceDtlsSrtpHandler*
dino_plugins_ice_dtls_srtp_handler_construct_with_cert (GType object_type,
                                                        DinoPluginsIceDtlsSrtpCredentialsCapsule* creds)
{
	DinoPluginsIceDtlsSrtpHandler* self = NULL;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp0_;
	guint8* _tmp1_;
	gint _tmp1__length1;
	g_return_val_if_fail (creds != NULL, NULL);
	self = (DinoPluginsIceDtlsSrtpHandler*) g_type_create_instance (object_type);
	_tmp0_ = _dino_plugins_ice_dtls_srtp_credentials_capsule_ref0 (creds);
	_dino_plugins_ice_dtls_srtp_credentials_capsule_unref0 (self->priv->credentials);
	self->priv->credentials = _tmp0_;
	_tmp1_ = creds->own_fingerprint;
	_tmp1__length1 = creds->own_fingerprint_length1;
	dino_plugins_ice_dtls_srtp_handler_set_own_fingerprint (self, _tmp1_, _tmp1__length1);
	return self;
}

DinoPluginsIceDtlsSrtpHandler*
dino_plugins_ice_dtls_srtp_handler_new_with_cert (DinoPluginsIceDtlsSrtpCredentialsCapsule* creds)
{
	return dino_plugins_ice_dtls_srtp_handler_construct_with_cert (DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER, creds);
}

static guint8*
_vala_array_dup1 (guint8* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (guint8));
	}
	return NULL;
}

guint8*
dino_plugins_ice_dtls_srtp_handler_process_incoming_data (DinoPluginsIceDtlsSrtpHandler* self,
                                                          guint component_id,
                                                          guint8* data,
                                                          gint data_length1,
                                                          gint* result_length1,
                                                          GError** error)
{
	guint8 _tmp0_;
	gboolean _tmp27_ = FALSE;
	gboolean _tmp28_ = FALSE;
	guint8* _tmp34_;
	gint _tmp34__length1;
	GError* _inner_error0_ = NULL;
	guint8* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = data[0];
	if (((gint) _tmp0_) >= 128) {
		CryptoSrtpSession* _tmp1_;
		gboolean _tmp2_;
		gboolean _tmp3_;
		_tmp1_ = self->priv->srtp_session;
		_tmp2_ = crypto_srtp_session_get_has_decrypt (_tmp1_);
		_tmp3_ = _tmp2_;
		if (!_tmp3_) {
			guint8* _tmp4_;
			gint _tmp4__length1;
			g_debug ("dtls_srtp.vala:43: Received data before SRTP session is ready, droppin" \
"g.");
			_tmp4_ = NULL;
			_tmp4__length1 = 0;
			if (result_length1) {
				*result_length1 = _tmp4__length1;
			}
			result = _tmp4_;
			return result;
		}
		if (component_id == ((guint) 1)) {
			gboolean _tmp5_ = FALSE;
			gboolean _tmp6_ = FALSE;
			guint8* _tmp15_ = NULL;
			CryptoSrtpSession* _tmp16_;
			gint _tmp17_ = 0;
			guint8* _tmp18_;
			gint _tmp15__length1;
			gint __tmp15__size_;
			guint8* _tmp19_;
			gint _tmp19__length1;
			guint8* _tmp20_;
			gint _tmp20__length1;
			if (data_length1 >= 2) {
				guint8 _tmp7_;
				_tmp7_ = data[1];
				_tmp6_ = ((gint) _tmp7_) >= 192;
			} else {
				_tmp6_ = FALSE;
			}
			if (_tmp6_) {
				guint8 _tmp8_;
				_tmp8_ = data[1];
				_tmp5_ = ((gint) _tmp8_) < 224;
			} else {
				_tmp5_ = FALSE;
			}
			if (_tmp5_) {
				guint8* _tmp9_ = NULL;
				CryptoSrtpSession* _tmp10_;
				gint _tmp11_ = 0;
				guint8* _tmp12_;
				gint _tmp9__length1;
				gint __tmp9__size_;
				guint8* _tmp13_;
				gint _tmp13__length1;
				guint8* _tmp14_;
				gint _tmp14__length1;
				_tmp10_ = self->priv->srtp_session;
				_tmp12_ = crypto_srtp_session_decrypt_rtcp (_tmp10_, data, (gint) data_length1, &_tmp11_, &_inner_error0_);
				_tmp9_ = _tmp12_;
				_tmp9__length1 = _tmp11_;
				__tmp9__size_ = _tmp9__length1;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					if (_inner_error0_->domain == CRYPTO_ERROR) {
						g_propagate_error (error, _inner_error0_);
						return NULL;
					} else {
						g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
						g_clear_error (&_inner_error0_);
						return NULL;
					}
				}
				_tmp13_ = _tmp9_;
				_tmp13__length1 = _tmp9__length1;
				_tmp9_ = NULL;
				_tmp9__length1 = 0;
				_tmp14_ = _tmp13_;
				_tmp14__length1 = _tmp13__length1;
				if (result_length1) {
					*result_length1 = _tmp14__length1;
				}
				result = _tmp14_;
				_tmp9_ = (g_free (_tmp9_), NULL);
				return result;
			}
			_tmp16_ = self->priv->srtp_session;
			_tmp18_ = crypto_srtp_session_decrypt_rtp (_tmp16_, data, (gint) data_length1, &_tmp17_, &_inner_error0_);
			_tmp15_ = _tmp18_;
			_tmp15__length1 = _tmp17_;
			__tmp15__size_ = _tmp15__length1;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == CRYPTO_ERROR) {
					g_propagate_error (error, _inner_error0_);
					return NULL;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
					g_clear_error (&_inner_error0_);
					return NULL;
				}
			}
			_tmp19_ = _tmp15_;
			_tmp19__length1 = _tmp15__length1;
			_tmp15_ = NULL;
			_tmp15__length1 = 0;
			_tmp20_ = _tmp19_;
			_tmp20__length1 = _tmp19__length1;
			if (result_length1) {
				*result_length1 = _tmp20__length1;
			}
			result = _tmp20_;
			_tmp15_ = (g_free (_tmp15_), NULL);
			return result;
		}
		if (component_id == ((guint) 2)) {
			guint8* _tmp21_ = NULL;
			CryptoSrtpSession* _tmp22_;
			gint _tmp23_ = 0;
			guint8* _tmp24_;
			gint _tmp21__length1;
			gint __tmp21__size_;
			guint8* _tmp25_;
			gint _tmp25__length1;
			guint8* _tmp26_;
			gint _tmp26__length1;
			_tmp22_ = self->priv->srtp_session;
			_tmp24_ = crypto_srtp_session_decrypt_rtcp (_tmp22_, data, (gint) data_length1, &_tmp23_, &_inner_error0_);
			_tmp21_ = _tmp24_;
			_tmp21__length1 = _tmp23_;
			__tmp21__size_ = _tmp21__length1;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == CRYPTO_ERROR) {
					g_propagate_error (error, _inner_error0_);
					return NULL;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
					g_clear_error (&_inner_error0_);
					return NULL;
				}
			}
			_tmp25_ = _tmp21_;
			_tmp25__length1 = _tmp21__length1;
			_tmp21_ = NULL;
			_tmp21__length1 = 0;
			_tmp26_ = _tmp25_;
			_tmp26__length1 = _tmp25__length1;
			if (result_length1) {
				*result_length1 = _tmp26__length1;
			}
			result = _tmp26_;
			_tmp21_ = (g_free (_tmp21_), NULL);
			return result;
		}
	}
	if (component_id == ((guint) 1)) {
		_tmp28_ = data_length1 >= 1;
	} else {
		_tmp28_ = FALSE;
	}
	if (_tmp28_) {
		gboolean _tmp29_ = FALSE;
		guint8 _tmp30_;
		_tmp30_ = data[0];
		if (((gint) _tmp30_) >= 20) {
			guint8 _tmp31_;
			_tmp31_ = data[0];
			_tmp29_ = ((gint) _tmp31_) < 64;
		} else {
			_tmp29_ = FALSE;
		}
		_tmp27_ = _tmp29_;
	} else {
		_tmp27_ = FALSE;
	}
	if (_tmp27_) {
		guint8* _tmp32_;
		gint _tmp32__length1;
		guint8* _tmp33_;
		gint _tmp33__length1;
		_tmp32_ = (data != NULL) ? _vala_array_dup1 (data, data_length1) : data;
		_tmp32__length1 = data_length1;
		dino_plugins_ice_dtls_srtp_handler_on_data_rec (self, _tmp32_, (gint) _tmp32__length1);
		_tmp33_ = NULL;
		_tmp33__length1 = 0;
		if (result_length1) {
			*result_length1 = _tmp33__length1;
		}
		result = _tmp33_;
		return result;
	}
	g_debug ("dtls_srtp.vala:58: Dropping unknown data from component %u", component_id);
	_tmp34_ = NULL;
	_tmp34__length1 = 0;
	if (result_length1) {
		*result_length1 = _tmp34__length1;
	}
	result = _tmp34_;
	return result;
}

guint8*
dino_plugins_ice_dtls_srtp_handler_process_outgoing_data (DinoPluginsIceDtlsSrtpHandler* self,
                                                          guint component_id,
                                                          guint8* data,
                                                          gint data_length1,
                                                          gint* result_length1,
                                                          GError** error)
{
	CryptoSrtpSession* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	guint8* _tmp25_;
	gint _tmp25__length1;
	GError* _inner_error0_ = NULL;
	guint8* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->srtp_session;
	_tmp1_ = crypto_srtp_session_get_has_encrypt (_tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		if (component_id == ((guint) 1)) {
			gboolean _tmp3_ = FALSE;
			gboolean _tmp4_ = FALSE;
			guint8* _tmp13_ = NULL;
			CryptoSrtpSession* _tmp14_;
			gint _tmp15_ = 0;
			guint8* _tmp16_;
			gint _tmp13__length1;
			gint __tmp13__size_;
			guint8* _tmp17_;
			gint _tmp17__length1;
			guint8* _tmp18_;
			gint _tmp18__length1;
			if (data_length1 >= 2) {
				guint8 _tmp5_;
				_tmp5_ = data[1];
				_tmp4_ = ((gint) _tmp5_) >= 192;
			} else {
				_tmp4_ = FALSE;
			}
			if (_tmp4_) {
				guint8 _tmp6_;
				_tmp6_ = data[1];
				_tmp3_ = ((gint) _tmp6_) < 224;
			} else {
				_tmp3_ = FALSE;
			}
			if (_tmp3_) {
				guint8* _tmp7_ = NULL;
				CryptoSrtpSession* _tmp8_;
				gint _tmp9_ = 0;
				guint8* _tmp10_;
				gint _tmp7__length1;
				gint __tmp7__size_;
				guint8* _tmp11_;
				gint _tmp11__length1;
				guint8* _tmp12_;
				gint _tmp12__length1;
				_tmp8_ = self->priv->srtp_session;
				_tmp10_ = crypto_srtp_session_encrypt_rtcp (_tmp8_, data, (gint) data_length1, &_tmp9_, &_inner_error0_);
				_tmp7_ = _tmp10_;
				_tmp7__length1 = _tmp9_;
				__tmp7__size_ = _tmp7__length1;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					if (_inner_error0_->domain == CRYPTO_ERROR) {
						g_propagate_error (error, _inner_error0_);
						return NULL;
					} else {
						g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
						g_clear_error (&_inner_error0_);
						return NULL;
					}
				}
				_tmp11_ = _tmp7_;
				_tmp11__length1 = _tmp7__length1;
				_tmp7_ = NULL;
				_tmp7__length1 = 0;
				_tmp12_ = _tmp11_;
				_tmp12__length1 = _tmp11__length1;
				if (result_length1) {
					*result_length1 = _tmp12__length1;
				}
				result = _tmp12_;
				_tmp7_ = (g_free (_tmp7_), NULL);
				return result;
			}
			_tmp14_ = self->priv->srtp_session;
			_tmp16_ = crypto_srtp_session_encrypt_rtp (_tmp14_, data, (gint) data_length1, &_tmp15_, &_inner_error0_);
			_tmp13_ = _tmp16_;
			_tmp13__length1 = _tmp15_;
			__tmp13__size_ = _tmp13__length1;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == CRYPTO_ERROR) {
					g_propagate_error (error, _inner_error0_);
					return NULL;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
					g_clear_error (&_inner_error0_);
					return NULL;
				}
			}
			_tmp17_ = _tmp13_;
			_tmp17__length1 = _tmp13__length1;
			_tmp13_ = NULL;
			_tmp13__length1 = 0;
			_tmp18_ = _tmp17_;
			_tmp18__length1 = _tmp17__length1;
			if (result_length1) {
				*result_length1 = _tmp18__length1;
			}
			result = _tmp18_;
			_tmp13_ = (g_free (_tmp13_), NULL);
			return result;
		}
		if (component_id == ((guint) 2)) {
			guint8* _tmp19_ = NULL;
			CryptoSrtpSession* _tmp20_;
			gint _tmp21_ = 0;
			guint8* _tmp22_;
			gint _tmp19__length1;
			gint __tmp19__size_;
			guint8* _tmp23_;
			gint _tmp23__length1;
			guint8* _tmp24_;
			gint _tmp24__length1;
			_tmp20_ = self->priv->srtp_session;
			_tmp22_ = crypto_srtp_session_encrypt_rtcp (_tmp20_, data, (gint) data_length1, &_tmp21_, &_inner_error0_);
			_tmp19_ = _tmp22_;
			_tmp19__length1 = _tmp21_;
			__tmp19__size_ = _tmp19__length1;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == CRYPTO_ERROR) {
					g_propagate_error (error, _inner_error0_);
					return NULL;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
					g_clear_error (&_inner_error0_);
					return NULL;
				}
			}
			_tmp23_ = _tmp19_;
			_tmp23__length1 = _tmp19__length1;
			_tmp19_ = NULL;
			_tmp19__length1 = 0;
			_tmp24_ = _tmp23_;
			_tmp24__length1 = _tmp23__length1;
			if (result_length1) {
				*result_length1 = _tmp24__length1;
			}
			result = _tmp24_;
			_tmp19_ = (g_free (_tmp19_), NULL);
			return result;
		}
	}
	_tmp25_ = NULL;
	_tmp25__length1 = 0;
	if (result_length1) {
		*result_length1 = _tmp25__length1;
	}
	result = _tmp25_;
	return result;
}

static guint8*
_vala_array_dup2 (guint8* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (guint8));
	}
	return NULL;
}

void
dino_plugins_ice_dtls_srtp_handler_on_data_rec (DinoPluginsIceDtlsSrtpHandler* self,
                                                guint8* data,
                                                gint data_length1)
{
	GeeLinkedList* _tmp0_;
	guint8* _tmp1_;
	gint _tmp1__length1;
	GBytes* _tmp2_;
	GBytes* _tmp3_;
	g_return_if_fail (self != NULL);
	g_mutex_lock (&self->priv->buffer_mutex);
	_tmp0_ = self->priv->buffer_queue;
	_tmp1_ = (data != NULL) ? _vala_array_dup2 (data, data_length1) : data;
	_tmp1__length1 = data_length1;
	_tmp2_ = g_bytes_new_take (_tmp1_, _tmp1__length1);
	_tmp3_ = _tmp2_;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp0_, _tmp3_);
	_g_bytes_unref0 (_tmp3_);
	g_cond_signal (&self->priv->buffer_cond);
	g_mutex_unlock (&self->priv->buffer_mutex);
	data = (g_free (data), NULL);
}

static void
gnutls_throw_if_error (gint err_int,
                       GError** error)
{
	int _error_ = 0;
	GError* _inner_error0_ = NULL;
	_error_ = (int) err_int;
	if (_error_ != GNUTLS_E_SUCCESS) {
		const gchar* _tmp0_ = NULL;
		const gchar* _tmp1_;
		GError* _tmp2_;
		if (gnutls_error_is_fatal (_error_)) {
			_tmp0_ = " fatal";
		} else {
			_tmp0_ = "";
		}
		_tmp1_ = gnutls_strerror (_error_);
		_tmp2_ = g_error_new ((GQuark) -1, (gint) _error_, "%s%s", _tmp1_, _tmp0_);
		_inner_error0_ = _tmp2_;
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static struct gnutls_x509_privkey_int*
gnutls_x509_privkey_create (GError** error)
{
	struct gnutls_x509_privkey_int* _result_ = NULL;
	gint ret = 0;
	struct gnutls_x509_privkey_int* _tmp0_ = NULL;
	gint _tmp1_;
	GError* _inner_error0_ = NULL;
	struct gnutls_x509_privkey_int* result;
	_tmp1_ = gnutls_x509_privkey_init (&_tmp0_);
	_gnutls_x509_privkey_deinit0 (_result_);
	_result_ = _tmp0_;
	ret = _tmp1_;
	gnutls_throw_if_error (ret, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_privkey_deinit0 (_result_);
		return NULL;
	}
	result = _result_;
	return result;
}

static struct gnutls_x509_crt_int*
gnutls_x509_crt_create (GError** error)
{
	struct gnutls_x509_crt_int* _result_ = NULL;
	gint ret = 0;
	struct gnutls_x509_crt_int* _tmp0_ = NULL;
	gint _tmp1_;
	GError* _inner_error0_ = NULL;
	struct gnutls_x509_crt_int* result;
	_tmp1_ = gnutls_x509_crt_init (&_tmp0_);
	_gnutls_x509_crt_deinit0 (_result_);
	_result_ = _tmp0_;
	ret = _tmp1_;
	gnutls_throw_if_error (ret, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (_result_);
		return NULL;
	}
	result = _result_;
	return result;
}

static void
gnutls_x509_crt_set_key_ (struct gnutls_x509_crt_int* self,
                          struct gnutls_x509_privkey_int* key,
                          GError** error)
{
	gint err = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (key != NULL);
	err = gnutls_x509_crt_set_key (self, key);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static void
gnutls_x509_crt_set_version_ (struct gnutls_x509_crt_int* self,
                              guint version,
                              GError** error)
{
	gint err = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	err = gnutls_x509_crt_set_version (self, version);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static void
gnutls_x509_crt_set_activation_time_ (struct gnutls_x509_crt_int* self,
                                      time_t act_time,
                                      GError** error)
{
	gint err = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	err = gnutls_x509_crt_set_activation_time (self, act_time);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static void
gnutls_x509_crt_set_expiration_time_ (struct gnutls_x509_crt_int* self,
                                      time_t exp_time,
                                      GError** error)
{
	gint err = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	err = gnutls_x509_crt_set_expiration_time (self, exp_time);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static void
gnutls_x509_crt_set_serial_ (struct gnutls_x509_crt_int* self,
                             void* serial,
                             gsize serial_size,
                             GError** error)
{
	gint err = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	err = gnutls_x509_crt_set_serial (self, serial, serial_size);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static void
gnutls_x509_crt_sign_ (struct gnutls_x509_crt_int* self,
                       struct gnutls_x509_crt_int* issuer,
                       struct gnutls_x509_privkey_int* issuer_key,
                       GError** error)
{
	gint err = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (issuer != NULL);
	g_return_if_fail (issuer_key != NULL);
	err = gnutls_x509_crt_sign (self, issuer, issuer_key);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static guint8*
_vala_array_dup3 (guint8* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (guint8));
	}
	return NULL;
}

DinoPluginsIceDtlsSrtpCredentialsCapsule*
dino_plugins_ice_dtls_srtp_handler_generate_credentials (GError** error)
{
	gint err = 0;
	struct gnutls_x509_privkey_int* private_key = NULL;
	struct gnutls_x509_privkey_int* _tmp0_;
	struct gnutls_x509_privkey_int* _tmp1_;
	GDateTime* start_time = NULL;
	GDateTime* _tmp2_;
	GDateTime* _tmp3_;
	GDateTime* _tmp4_;
	GDateTime* _tmp5_;
	GDateTime* end_time = NULL;
	GDateTime* _tmp6_;
	GDateTime* _tmp7_;
	struct gnutls_x509_crt_int* cert = NULL;
	struct gnutls_x509_crt_int* _tmp8_;
	struct gnutls_x509_crt_int* _tmp9_;
	struct gnutls_x509_privkey_int* _tmp10_;
	struct gnutls_x509_crt_int* _tmp11_;
	struct gnutls_x509_crt_int* _tmp12_;
	GDateTime* _tmp13_;
	struct gnutls_x509_crt_int* _tmp14_;
	GDateTime* _tmp15_;
	guint32 serial = 0U;
	struct gnutls_x509_crt_int* _tmp16_;
	struct gnutls_x509_crt_int* _tmp17_;
	struct gnutls_x509_crt_int* _tmp18_;
	struct gnutls_x509_privkey_int* _tmp19_;
	guint8* own_fingerprint = NULL;
	struct gnutls_x509_crt_int* _tmp20_;
	gint _tmp21_ = 0;
	guint8* _tmp22_;
	gint own_fingerprint_length1;
	gint _own_fingerprint_size_;
	struct gnutls_x509_crt_int** own_cert = NULL;
	struct gnutls_x509_crt_int* _tmp23_;
	struct gnutls_x509_crt_int** _tmp24_;
	gint own_cert_length1;
	gint _own_cert_size_;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* creds = NULL;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp25_;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp26_;
	guint8* _tmp27_;
	gint _tmp27__length1;
	guint8* _tmp28_;
	gint _tmp28__length1;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp29_;
	struct gnutls_x509_crt_int** _tmp30_;
	gint _tmp30__length1;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp31_;
	struct gnutls_x509_privkey_int* _tmp32_;
	GError* _inner_error0_ = NULL;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* result;
	err = 0;
	_tmp0_ = gnutls_x509_privkey_create (&_inner_error0_);
	private_key = _tmp0_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return NULL;
	}
	_tmp1_ = private_key;
	err = gnutls_x509_privkey_generate (_tmp1_, GNUTLS_PK_ECDSA, (guint) 256, (guint) 0);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	_tmp2_ = g_date_time_new_now_local ();
	_tmp3_ = _tmp2_;
	_tmp4_ = g_date_time_add_days (_tmp3_, -1);
	_tmp5_ = _tmp4_;
	_g_date_time_unref0 (_tmp3_);
	start_time = _tmp5_;
	_tmp6_ = start_time;
	_tmp7_ = g_date_time_add_days (_tmp6_, 2);
	end_time = _tmp7_;
	_tmp8_ = gnutls_x509_crt_create (&_inner_error0_);
	cert = _tmp8_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_date_time_unref0 (end_time);
		_g_date_time_unref0 (start_time);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	_tmp9_ = cert;
	_tmp10_ = private_key;
	gnutls_x509_crt_set_key_ (_tmp9_, _tmp10_, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (cert);
		_g_date_time_unref0 (end_time);
		_g_date_time_unref0 (start_time);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	_tmp11_ = cert;
	gnutls_x509_crt_set_version_ (_tmp11_, (guint) 1, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (cert);
		_g_date_time_unref0 (end_time);
		_g_date_time_unref0 (start_time);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	_tmp12_ = cert;
	_tmp13_ = start_time;
	gnutls_x509_crt_set_activation_time_ (_tmp12_, (time_t) g_date_time_to_unix (_tmp13_), &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (cert);
		_g_date_time_unref0 (end_time);
		_g_date_time_unref0 (start_time);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	_tmp14_ = cert;
	_tmp15_ = end_time;
	gnutls_x509_crt_set_expiration_time_ (_tmp14_, (time_t) g_date_time_to_unix (_tmp15_), &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (cert);
		_g_date_time_unref0 (end_time);
		_g_date_time_unref0 (start_time);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	serial = (guint32) 1;
	_tmp16_ = cert;
	gnutls_x509_crt_set_serial_ (_tmp16_, &serial, (gsize) sizeof (guint32), &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (cert);
		_g_date_time_unref0 (end_time);
		_g_date_time_unref0 (start_time);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	_tmp17_ = cert;
	_tmp18_ = cert;
	_tmp19_ = private_key;
	gnutls_x509_crt_sign_ (_tmp17_, _tmp18_, _tmp19_, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (cert);
		_g_date_time_unref0 (end_time);
		_g_date_time_unref0 (start_time);
		_gnutls_x509_privkey_deinit0 (private_key);
		return NULL;
	}
	_tmp20_ = cert;
	_tmp22_ = dino_plugins_ice_dtls_srtp_get_fingerprint (_tmp20_, GNUTLS_DIG_SHA256, &_tmp21_);
	own_fingerprint = _tmp22_;
	own_fingerprint_length1 = _tmp21_;
	_own_fingerprint_size_ = own_fingerprint_length1;
	_tmp23_ = cert;
	cert = NULL;
	_tmp24_ = g_new0 (struct gnutls_x509_crt_int*, 1 + 1);
	_tmp24_[0] = _tmp23_;
	own_cert = _tmp24_;
	own_cert_length1 = 1;
	_own_cert_size_ = own_cert_length1;
	_tmp25_ = dino_plugins_ice_dtls_srtp_credentials_capsule_new ();
	creds = _tmp25_;
	_tmp26_ = creds;
	_tmp27_ = own_fingerprint;
	_tmp27__length1 = own_fingerprint_length1;
	_tmp28_ = (_tmp27_ != NULL) ? _vala_array_dup3 (_tmp27_, _tmp27__length1) : _tmp27_;
	_tmp28__length1 = _tmp27__length1;
	_tmp26_->own_fingerprint = (g_free (_tmp26_->own_fingerprint), NULL);
	_tmp26_->own_fingerprint = _tmp28_;
	_tmp26_->own_fingerprint_length1 = _tmp28__length1;
	_tmp29_ = creds;
	_tmp30_ = own_cert;
	_tmp30__length1 = own_cert_length1;
	own_cert = NULL;
	own_cert_length1 = 0;
	_tmp29_->own_cert = (_vala_array_free (_tmp29_->own_cert, _tmp29_->own_cert_length1, (GDestroyNotify) gnutls_x509_crt_deinit), NULL);
	_tmp29_->own_cert = _tmp30_;
	_tmp29_->own_cert_length1 = _tmp30__length1;
	_tmp31_ = creds;
	_tmp32_ = private_key;
	private_key = NULL;
	_gnutls_x509_privkey_deinit0 (_tmp31_->private_key);
	_tmp31_->private_key = _tmp32_;
	result = creds;
	own_cert = (_vala_array_free (own_cert, own_cert_length1, (GDestroyNotify) gnutls_x509_crt_deinit), NULL);
	own_fingerprint = (g_free (own_fingerprint), NULL);
	_gnutls_x509_crt_deinit0 (cert);
	_g_date_time_unref0 (end_time);
	_g_date_time_unref0 (start_time);
	_gnutls_x509_privkey_deinit0 (private_key);
	return result;
}

void
dino_plugins_ice_dtls_srtp_handler_stop_dtls_connection (DinoPluginsIceDtlsSrtpHandler* self)
{
	g_return_if_fail (self != NULL);
	g_mutex_lock (&self->priv->buffer_mutex);
	self->priv->stop = TRUE;
	g_cond_signal (&self->priv->buffer_cond);
	g_mutex_unlock (&self->priv->buffer_mutex);
}

static void
dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_data_free (gpointer _data)
{
	DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->result);
	_dino_plugins_ice_dtls_srtp_handler_unref0 (_data_->self);
	g_slice_free (DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData, _data_);
}

static gpointer
_dino_plugins_ice_dtls_srtp_handler_ref0 (gpointer self)
{
	return self ? dino_plugins_ice_dtls_srtp_handler_ref (self) : NULL;
}

void
dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection (DinoPluginsIceDtlsSrtpHandler* self,
                                                          GAsyncReadyCallback _callback_,
                                                          gpointer _user_data_)
{
	DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData* _data_;
	DinoPluginsIceDtlsSrtpHandler* _tmp0_;
	g_return_if_fail (self != NULL);
	_data_ = g_slice_new0 (DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData);
	_data_->_async_result = g_task_new (NULL, NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_data_free);
	_tmp0_ = _dino_plugins_ice_dtls_srtp_handler_ref0 (self);
	_data_->self = _tmp0_;
	dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_co (_data_);
}

XmppXepJingleContentEncryption*
dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_finish (DinoPluginsIceDtlsSrtpHandler* self,
                                                                 GAsyncResult* _res_)
{
	XmppXepJingleContentEncryption* result;
	DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
	result = _data_->result;
	_data_->result = NULL;
	return result;
}

static Block1Data*
block1_data_ref (Block1Data* _data1_)
{
	g_atomic_int_inc (&_data1_->_ref_count_);
	return _data1_;
}

static void
block1_data_unref (void * _userdata_)
{
	Block1Data* _data1_;
	_data1_ = (Block1Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data1_->_ref_count_)) {
		DinoPluginsIceDtlsSrtpHandler* self;
		self = _data1_->self;
		_g_main_context_unref0 (_data1_->context);
		_dino_plugins_ice_dtls_srtp_handler_unref0 (self);
		g_slice_free (Block1Data, _data1_);
	}
}

static gpointer
_g_main_context_ref0 (gpointer self)
{
	return self ? g_main_context_ref (self) : NULL;
}

static gboolean
_dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_co_gsource_func (gpointer self)
{
	gboolean result;
	result = dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_co (self);
	return result;
}

static XmppXepJingleContentEncryption*
__lambda4_ (Block1Data* _data1_)
{
	DinoPluginsIceDtlsSrtpHandler* self;
	XmppXepJingleContentEncryption* res = NULL;
	XmppXepJingleContentEncryption* _tmp0_;
	GSource* source = NULL;
	GSource* _tmp1_;
	XmppXepJingleContentEncryption* result;
	self = _data1_->self;
	_tmp0_ = dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_thread (self);
	res = _tmp0_;
	_tmp1_ = g_idle_source_new ();
	source = _tmp1_;
	g_source_set_callback (source, _dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_co_gsource_func, _data1_->_async_data_, NULL);
	g_source_attach (source, _data1_->context);
	result = res;
	_g_source_unref0 (source);
	return result;
}

static gpointer
___lambda4__gthread_func (gpointer self)
{
	gpointer result;
	result = __lambda4_ (self);
	block1_data_unref (self);
	return result;
}

static gboolean
dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_co (DinoPluginsIceDtlsSrtpHandlerSetupDtlsConnectionData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_data1_ = g_slice_new0 (Block1Data);
	_data_->_data1_->_ref_count_ = 1;
	_data_->_data1_->self = dino_plugins_ice_dtls_srtp_handler_ref (_data_->self);
	_data_->_data1_->_async_data_ = _data_;
	_data_->_tmp0_ = g_main_current_source ();
	_data_->_tmp1_ = g_source_get_context (_data_->_tmp0_);
	_data_->_tmp2_ = _g_main_context_ref0 (_data_->_tmp1_);
	_data_->_data1_->context = _data_->_tmp2_;
	_data_->_tmp3_ = g_thread_new ("dtls-connection", ___lambda4__gthread_func, block1_data_ref (_data_->_data1_));
	_data_->thread = _data_->_tmp3_;
	_data_->_state_ = 1;
	return FALSE;
	_state_1:
	;
	_data_->_tmp4_ = _data_->thread;
	_data_->thread = NULL;
	_data_->_tmp5_ = g_thread_join (_data_->_tmp4_);
	_data_->result = (XmppXepJingleContentEncryption*) _data_->_tmp5_;
	_g_thread_unref0 (_data_->thread);
	block1_data_unref (_data_->_data1_);
	_data_->_data1_ = NULL;
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static struct gnutls_certificate_credentials_st*
gnutls_certificate_create (GError** error)
{
	struct gnutls_certificate_credentials_st* _result_ = NULL;
	gint ret = 0;
	struct gnutls_certificate_credentials_st* _tmp0_ = NULL;
	gint _tmp1_;
	GError* _inner_error0_ = NULL;
	struct gnutls_certificate_credentials_st* result;
	_tmp1_ = gnutls_certificate_allocate_credentials (&_tmp0_);
	_gnutls_certificate_free_credentials0 (_result_);
	_result_ = _tmp0_;
	ret = _tmp1_;
	gnutls_throw_if_error (ret, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_certificate_free_credentials0 (_result_);
		return NULL;
	}
	result = _result_;
	return result;
}

static struct gnutls_session_int*
gnutls_session_create (gint con_end,
                       GError** error)
{
	struct gnutls_session_int* _result_ = NULL;
	gint ret = 0;
	struct gnutls_session_int* _tmp0_ = NULL;
	gint _tmp1_;
	GError* _inner_error0_ = NULL;
	struct gnutls_session_int* result;
	_tmp1_ = gnutls_init (&_tmp0_, con_end);
	_gnutls_deinit0 (_result_);
	_result_ = _tmp0_;
	ret = _tmp1_;
	gnutls_throw_if_error (ret, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_gnutls_deinit0 (_result_);
		return NULL;
	}
	result = _result_;
	return result;
}

static void
gnutls_srtp_set_profile_direct_ (struct gnutls_session_int* self,
                                 const gchar* profiles,
                                 const gchar** err_pos,
                                 GError** error)
{
	const gchar* _vala_err_pos = NULL;
	gint err = 0;
	const gchar* _tmp0_ = NULL;
	gint _tmp1_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (profiles != NULL);
	_tmp1_ = gnutls_srtp_set_profile_direct (self, profiles, &_tmp0_);
	_vala_err_pos = _tmp0_;
	err = _tmp1_;
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	if (err_pos) {
		*err_pos = _vala_err_pos;
	}
}

static void
gnutls_credentials_set_ (struct gnutls_session_int* self,
                         gnutls_credentials_type_t type,
                         void* cred,
                         GError** error)
{
	gint err = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	err = gnutls_credentials_set (self, type, cred);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static void
gnutls_priority_set_direct_ (struct gnutls_session_int* self,
                             const gchar* priority,
                             const gchar** err_pos,
                             GError** error)
{
	const gchar* _vala_err_pos = NULL;
	gint err = 0;
	const gchar* _tmp0_ = NULL;
	gint _tmp1_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (priority != NULL);
	_tmp1_ = gnutls_priority_set_direct (self, priority, &_tmp0_);
	_vala_err_pos = _tmp0_;
	err = _tmp1_;
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	if (err_pos) {
		*err_pos = _vala_err_pos;
	}
}

static gssize
_dino_plugins_ice_dtls_srtp_handler_pull_function_gnutls_pull_func (void* transport_ptr,
                                                                    void* array,
                                                                    size_t array_length1)
{
	gssize result;
	result = dino_plugins_ice_dtls_srtp_handler_pull_function (transport_ptr, array, array_length1);
	return result;
}

static gint
_dino_plugins_ice_dtls_srtp_handler_pull_timeout_function_gnutls_pull_timeout_func (void* transport_ptr,
                                                                                    guint ms)
{
	gint result;
	result = dino_plugins_ice_dtls_srtp_handler_pull_timeout_function (transport_ptr, ms);
	return result;
}

static gssize
_dino_plugins_ice_dtls_srtp_handler_push_function_gnutls_push_func (void* transport_ptr,
                                                                    void* array,
                                                                    size_t array_length1)
{
	gssize result;
	result = dino_plugins_ice_dtls_srtp_handler_push_function (transport_ptr, array, array_length1);
	return result;
}

static gint
_dino_plugins_ice_dtls_srtp_handler_verify_function_gnutls_certificate_verify_function (struct gnutls_session_int* session)
{
	gint result;
	result = dino_plugins_ice_dtls_srtp_handler_verify_function (session);
	return result;
}

static void
gnutls_srtp_get_keys_ (struct gnutls_session_int* self,
                       void* key_material,
                       guint32 key_material_size,
                       gnutls_datum_t* client_key,
                       gnutls_datum_t* client_salt,
                       gnutls_datum_t* server_key,
                       gnutls_datum_t* server_salt,
                       GError** error)
{
	gnutls_datum_t _vala_client_key = {0};
	gnutls_datum_t _vala_client_salt = {0};
	gnutls_datum_t _vala_server_key = {0};
	gnutls_datum_t _vala_server_salt = {0};
	gnutls_datum_t _tmp0_ = {0};
	gnutls_datum_t _tmp1_ = {0};
	gnutls_datum_t _tmp2_ = {0};
	gnutls_datum_t _tmp3_ = {0};
	g_return_if_fail (self != NULL);
	gnutls_srtp_get_keys (self, key_material, key_material_size, &_tmp0_, &_tmp1_, &_tmp2_, &_tmp3_);
	_vala_client_key = _tmp0_;
	_vala_client_salt = _tmp1_;
	_vala_server_key = _tmp2_;
	_vala_server_salt = _tmp3_;
	if (client_key) {
		*client_key = _vala_client_key;
	}
	if (client_salt) {
		*client_salt = _vala_client_salt;
	}
	if (server_key) {
		*server_key = _vala_server_key;
	}
	if (server_salt) {
		*server_salt = _vala_server_salt;
	}
}

static gnutls_datum_t*
_gnutls_datum_dup (gnutls_datum_t* self)
{
	gnutls_datum_t* dup;
	dup = g_new0 (gnutls_datum_t, 1);
	memcpy (dup, self, sizeof (gnutls_datum_t));
	return dup;
}

static gpointer
__gnutls_datum_dup0 (gpointer self)
{
	return self ? _gnutls_datum_dup (self) : NULL;
}

static guint8*
gnutls_datum_extract (gnutls_datum_t self,
                      gint* result_length1)
{
	guint8* ret = NULL;
	guint8* _tmp0_;
	gint ret_length1;
	gint _ret_size_;
	guint8* _tmp6_;
	gint _tmp6__length1;
	guint8* result;
	_tmp0_ = g_new0 (guint8, self.size);
	ret = _tmp0_;
	ret_length1 = self.size;
	_ret_size_ = ret_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				guint8* _tmp3_;
				gint _tmp3__length1;
				guint8* _tmp4_;
				guint8 _tmp5_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = i;
					i = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(((guint) i) < self.size)) {
					break;
				}
				_tmp3_ = ret;
				_tmp3__length1 = ret_length1;
				_tmp4_ = self.data;
				_tmp5_ = _tmp4_[i];
				_tmp3_[i] = _tmp5_;
			}
		}
	}
	_tmp6_ = ret;
	_tmp6__length1 = ret_length1;
	if (result_length1) {
		*result_length1 = _tmp6__length1;
	}
	result = _tmp6_;
	return result;
}

static XmppXepJingleContentEncryption*
dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_thread (DinoPluginsIceDtlsSrtpHandler* self)
{
	gboolean _tmp0_ = FALSE;
	gnutls_init_flags_t _tmp3_ = 0U;
	DinoPluginsIceDtlsSrtpMode _tmp4_;
	gnutls_init_flags_t server_or_client = 0U;
	DinoPluginsIceDtlsSrtpMode _tmp5_;
	GEnumValue* _tmp6_;
	struct gnutls_certificate_credentials_st* cert_cred = NULL;
	struct gnutls_certificate_credentials_st* _tmp7_;
	gint err = 0;
	struct gnutls_certificate_credentials_st* _tmp8_;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp9_;
	struct gnutls_x509_crt_int** _tmp10_;
	gint _tmp10__length1;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp11_;
	struct gnutls_x509_privkey_int* _tmp12_;
	struct gnutls_session_int* session = NULL;
	struct gnutls_session_int* _tmp13_;
	struct gnutls_session_int* _tmp14_;
	struct gnutls_session_int* _tmp15_;
	struct gnutls_session_int* _tmp16_;
	struct gnutls_certificate_credentials_st* _tmp17_;
	struct gnutls_session_int* _tmp18_;
	struct gnutls_session_int* _tmp19_;
	struct gnutls_session_int* _tmp20_;
	struct gnutls_session_int* _tmp21_;
	struct gnutls_session_int* _tmp22_;
	struct gnutls_session_int* _tmp23_;
	struct gnutls_session_int* _tmp24_;
	GDateTime* maximum_time = NULL;
	GDateTime* _tmp25_;
	GDateTime* _tmp26_;
	GDateTime* _tmp27_;
	GDateTime* _tmp28_;
	guint8* km = NULL;
	guint8* _tmp37_;
	gint km_length1;
	gint _km_size_;
	gnutls_datum_t* client_key = NULL;
	gnutls_datum_t* client_salt = NULL;
	gnutls_datum_t* server_key = NULL;
	gnutls_datum_t* server_salt = NULL;
	struct gnutls_session_int* _tmp38_;
	guint8* _tmp39_;
	gint _tmp39__length1;
	guint8* _tmp40_;
	gint _tmp40__length1;
	gnutls_datum_t _tmp41_ = {0};
	gnutls_datum_t _tmp42_ = {0};
	gnutls_datum_t _tmp43_ = {0};
	gnutls_datum_t _tmp44_ = {0};
	gnutls_datum_t _tmp45_;
	gnutls_datum_t* _tmp46_;
	gnutls_datum_t _tmp47_;
	gnutls_datum_t* _tmp48_;
	gnutls_datum_t _tmp49_;
	gnutls_datum_t* _tmp50_;
	gnutls_datum_t _tmp51_;
	gnutls_datum_t* _tmp52_;
	gboolean _tmp53_ = FALSE;
	gboolean _tmp54_ = FALSE;
	gboolean _tmp55_ = FALSE;
	gnutls_datum_t* _tmp56_;
	DinoPluginsIceDtlsSrtpMode _tmp60_;
	GEnumValue* _tmp61_;
	DinoPluginsIceDtlsSrtpMode _tmp62_;
	DinoPluginsIceDtlsSrtpCredentialsCapsule* _tmp99_;
	guint8* _tmp100_;
	gint _tmp100__length1;
	guint8* _tmp101_;
	gint _tmp101__length1;
	gint _tmp102_ = 0;
	guint8* _tmp103_;
	gint _tmp103__length1;
	XmppXepJingleContentEncryption* _tmp104_;
	GError* _inner_error0_ = NULL;
	XmppXepJingleContentEncryption* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_mutex_lock (&self->priv->buffer_mutex);
	if (self->priv->stop) {
		self->priv->restart = TRUE;
		g_mutex_unlock (&self->priv->buffer_mutex);
		result = NULL;
		return result;
	}
	if (self->priv->running) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp1_;
		gboolean _tmp2_;
		_tmp1_ = dino_plugins_ice_dtls_srtp_handler_get_ready (self);
		_tmp2_ = _tmp1_;
		_tmp0_ = _tmp2_;
	}
	if (_tmp0_) {
		g_mutex_unlock (&self->priv->buffer_mutex);
		result = NULL;
		return result;
	}
	self->priv->running = TRUE;
	self->priv->restart = FALSE;
	g_mutex_unlock (&self->priv->buffer_mutex);
	_tmp4_ = self->priv->_mode;
	if (_tmp4_ == DINO_PLUGINS_ICE_DTLS_SRTP_MODE_SERVER) {
		_tmp3_ = GNUTLS_SERVER;
	} else {
		_tmp3_ = GNUTLS_CLIENT;
	}
	server_or_client = _tmp3_;
	_tmp5_ = self->priv->_mode;
	_tmp6_ = g_enum_get_value (g_type_class_ref (DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_MODE), _tmp5_);
	g_debug ("dtls_srtp.vala:150: Setting up DTLS connection. We're %s", (_tmp6_ != NULL) ? _tmp6_->value_name : NULL);
	_tmp7_ = gnutls_certificate_create (&_inner_error0_);
	cert_cred = _tmp7_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp8_ = cert_cred;
	_tmp9_ = self->priv->credentials;
	_tmp10_ = _tmp9_->own_cert;
	_tmp10__length1 = _tmp9_->own_cert_length1;
	_tmp11_ = self->priv->credentials;
	_tmp12_ = _tmp11_->private_key;
	err = gnutls_certificate_set_x509_key (_tmp8_, _tmp10_, (gint) _tmp10__length1, _tmp12_);
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_gnutls_certificate_free_credentials0 (cert_cred);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp13_ = gnutls_session_create ((gint) (server_or_client | GNUTLS_DATAGRAM), &_inner_error0_);
	session = _tmp13_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_gnutls_certificate_free_credentials0 (cert_cred);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp14_ = session;
	gnutls_heartbeat_enable (_tmp14_, (guint) 1);
	_tmp15_ = session;
	gnutls_srtp_set_profile_direct_ (_tmp15_, "SRTP_AES128_CM_HMAC_SHA1_80", NULL, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_gnutls_deinit0 (session);
		_gnutls_certificate_free_credentials0 (cert_cred);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp16_ = session;
	_tmp17_ = cert_cred;
	gnutls_credentials_set_ (_tmp16_, GNUTLS_CRD_CERTIFICATE, _tmp17_, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_gnutls_deinit0 (session);
		_gnutls_certificate_free_credentials0 (cert_cred);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp18_ = session;
	gnutls_certificate_server_set_request (_tmp18_, GNUTLS_CERT_REQUEST);
	_tmp19_ = session;
	gnutls_priority_set_direct_ (_tmp19_, "NORMAL:!VERS-TLS-ALL:+VERS-DTLS-ALL:+CTYPE-CLI-X509", NULL, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_gnutls_deinit0 (session);
		_gnutls_certificate_free_credentials0 (cert_cred);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp20_ = session;
	gnutls_transport_set_ptr (_tmp20_, self);
	_tmp21_ = session;
	gnutls_transport_set_pull_function (_tmp21_, _dino_plugins_ice_dtls_srtp_handler_pull_function_gnutls_pull_func);
	_tmp22_ = session;
	gnutls_transport_set_pull_timeout_function (_tmp22_, _dino_plugins_ice_dtls_srtp_handler_pull_timeout_function_gnutls_pull_timeout_func);
	_tmp23_ = session;
	gnutls_transport_set_push_function (_tmp23_, _dino_plugins_ice_dtls_srtp_handler_push_function_gnutls_push_func);
	_tmp24_ = session;
	gnutls_session_set_verify_function (_tmp24_, _dino_plugins_ice_dtls_srtp_handler_verify_function_gnutls_certificate_verify_function);
	_tmp25_ = g_date_time_new_now_utc ();
	_tmp26_ = _tmp25_;
	_tmp27_ = g_date_time_add_seconds (_tmp26_, (gdouble) 20);
	_tmp28_ = _tmp27_;
	_g_date_time_unref0 (_tmp26_);
	maximum_time = _tmp28_;
	{
		gboolean _tmp29_ = FALSE;
		_tmp29_ = TRUE;
		while (TRUE) {
			struct gnutls_session_int* _tmp31_;
			GDateTime* current_time = NULL;
			GDateTime* _tmp32_;
			GDateTime* _tmp33_;
			GDateTime* _tmp34_;
			if (!_tmp29_) {
				gboolean _tmp30_ = FALSE;
				if (err < 0) {
					_tmp30_ = !gnutls_error_is_fatal ((int) err);
				} else {
					_tmp30_ = FALSE;
				}
				if (!_tmp30_) {
					break;
				}
			}
			_tmp29_ = FALSE;
			_tmp31_ = session;
			err = gnutls_handshake (_tmp31_);
			_tmp32_ = g_date_time_new_now_utc ();
			current_time = _tmp32_;
			_tmp33_ = maximum_time;
			_tmp34_ = current_time;
			if (g_date_time_compare (_tmp33_, _tmp34_) < 0) {
				g_warning ("dtls_srtp.vala:175: DTLS handshake timeouted");
				err = (gint) (GNUTLS_E_APPLICATION_ERROR_MIN + 1);
				_g_date_time_unref0 (current_time);
				break;
			}
			if (self->priv->stop) {
				g_debug ("dtls_srtp.vala:180: DTLS handshake stopped");
				err = (gint) (GNUTLS_E_APPLICATION_ERROR_MIN + 2);
				_g_date_time_unref0 (current_time);
				break;
			}
			_g_date_time_unref0 (current_time);
		}
	}
	g_mutex_lock (&self->priv->buffer_mutex);
	if (self->priv->stop) {
		gboolean restart = FALSE;
		self->priv->stop = FALSE;
		self->priv->running = FALSE;
		restart = self->priv->restart;
		g_mutex_unlock (&self->priv->buffer_mutex);
		if (restart) {
			XmppXepJingleContentEncryption* _tmp35_;
			g_debug ("dtls_srtp.vala:193: Restarting DTLS handshake");
			_tmp35_ = dino_plugins_ice_dtls_srtp_handler_setup_dtls_connection_thread (self);
			result = _tmp35_;
			_g_date_time_unref0 (maximum_time);
			_gnutls_deinit0 (session);
			_gnutls_certificate_free_credentials0 (cert_cred);
			return result;
		}
		result = NULL;
		_g_date_time_unref0 (maximum_time);
		_gnutls_deinit0 (session);
		_gnutls_certificate_free_credentials0 (cert_cred);
		return result;
	}
	g_mutex_unlock (&self->priv->buffer_mutex);
	if (err != ((gint) GNUTLS_E_SUCCESS)) {
		const gchar* _tmp36_;
		_tmp36_ = gnutls_strerror ((int) err);
		g_warning ("dtls_srtp.vala:200: DTLS handshake failed: %s", _tmp36_);
		result = NULL;
		_g_date_time_unref0 (maximum_time);
		_gnutls_deinit0 (session);
		_gnutls_certificate_free_credentials0 (cert_cred);
		return result;
	}
	_tmp37_ = g_new0 (guint8, 150);
	km = _tmp37_;
	km_length1 = 150;
	_km_size_ = km_length1;
	_tmp38_ = session;
	_tmp39_ = km;
	_tmp39__length1 = km_length1;
	_tmp40_ = km;
	_tmp40__length1 = km_length1;
	gnutls_srtp_get_keys_ (_tmp38_, _tmp39_, (guint32) _tmp40__length1, &_tmp41_, &_tmp42_, &_tmp43_, &_tmp44_, &_inner_error0_);
	_g_free0 (client_key);
	_tmp45_ = _tmp41_;
	_tmp46_ = __gnutls_datum_dup0 (&_tmp45_);
	client_key = _tmp46_;
	_g_free0 (client_salt);
	_tmp47_ = _tmp42_;
	_tmp48_ = __gnutls_datum_dup0 (&_tmp47_);
	client_salt = _tmp48_;
	_g_free0 (server_key);
	_tmp49_ = _tmp43_;
	_tmp50_ = __gnutls_datum_dup0 (&_tmp49_);
	server_key = _tmp50_;
	_g_free0 (server_salt);
	_tmp51_ = _tmp44_;
	_tmp52_ = __gnutls_datum_dup0 (&_tmp51_);
	server_salt = _tmp52_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_free0 (server_salt);
		_g_free0 (server_key);
		_g_free0 (client_salt);
		_g_free0 (client_key);
		km = (g_free (km), NULL);
		_g_date_time_unref0 (maximum_time);
		_gnutls_deinit0 (session);
		_gnutls_certificate_free_credentials0 (cert_cred);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp56_ = client_key;
	if (_tmp56_ == NULL) {
		_tmp55_ = TRUE;
	} else {
		gnutls_datum_t* _tmp57_;
		_tmp57_ = client_salt;
		_tmp55_ = _tmp57_ == NULL;
	}
	if (_tmp55_) {
		_tmp54_ = TRUE;
	} else {
		gnutls_datum_t* _tmp58_;
		_tmp58_ = server_key;
		_tmp54_ = _tmp58_ == NULL;
	}
	if (_tmp54_) {
		_tmp53_ = TRUE;
	} else {
		gnutls_datum_t* _tmp59_;
		_tmp59_ = server_salt;
		_tmp53_ = _tmp59_ == NULL;
	}
	if (_tmp53_) {
		g_warning ("dtls_srtp.vala:208: SRTP client/server key/salt null");
	}
	_tmp60_ = self->priv->_mode;
	_tmp61_ = g_enum_get_value (g_type_class_ref (DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_MODE), _tmp60_);
	g_debug ("dtls_srtp.vala:211: Finished DTLS connection. We're %s", (_tmp61_ != NULL) ? _tmp61_->value_name : NULL);
	_tmp62_ = self->priv->_mode;
	if (_tmp62_ == DINO_PLUGINS_ICE_DTLS_SRTP_MODE_SERVER) {
		CryptoSrtpSession* _tmp63_;
		gnutls_datum_t* _tmp64_;
		gint _tmp65_ = 0;
		guint8* _tmp66_;
		guint8* _tmp67_;
		gint _tmp67__length1;
		gnutls_datum_t* _tmp68_;
		gint _tmp69_ = 0;
		guint8* _tmp70_;
		guint8* _tmp71_;
		gint _tmp71__length1;
		CryptoSrtpSession* _tmp72_;
		gnutls_datum_t* _tmp73_;
		gint _tmp74_ = 0;
		guint8* _tmp75_;
		guint8* _tmp76_;
		gint _tmp76__length1;
		gnutls_datum_t* _tmp77_;
		gint _tmp78_ = 0;
		guint8* _tmp79_;
		guint8* _tmp80_;
		gint _tmp80__length1;
		_tmp63_ = self->priv->srtp_session;
		_tmp64_ = server_key;
		_tmp66_ = gnutls_datum_extract (*_tmp64_, &_tmp65_);
		_tmp67_ = _tmp66_;
		_tmp67__length1 = _tmp65_;
		_tmp68_ = server_salt;
		_tmp70_ = gnutls_datum_extract (*_tmp68_, &_tmp69_);
		_tmp71_ = _tmp70_;
		_tmp71__length1 = _tmp69_;
		crypto_srtp_session_set_encryption_key (_tmp63_, CRYPTO_SRTP_AES_CM_128_HMAC_SHA1_80, _tmp67_, (gint) _tmp65_, _tmp71_, (gint) _tmp69_);
		_tmp71_ = (g_free (_tmp71_), NULL);
		_tmp67_ = (g_free (_tmp67_), NULL);
		_tmp72_ = self->priv->srtp_session;
		_tmp73_ = client_key;
		_tmp75_ = gnutls_datum_extract (*_tmp73_, &_tmp74_);
		_tmp76_ = _tmp75_;
		_tmp76__length1 = _tmp74_;
		_tmp77_ = client_salt;
		_tmp79_ = gnutls_datum_extract (*_tmp77_, &_tmp78_);
		_tmp80_ = _tmp79_;
		_tmp80__length1 = _tmp78_;
		crypto_srtp_session_set_decryption_key (_tmp72_, CRYPTO_SRTP_AES_CM_128_HMAC_SHA1_80, _tmp76_, (gint) _tmp74_, _tmp80_, (gint) _tmp78_);
		_tmp80_ = (g_free (_tmp80_), NULL);
		_tmp76_ = (g_free (_tmp76_), NULL);
	} else {
		CryptoSrtpSession* _tmp81_;
		gnutls_datum_t* _tmp82_;
		gint _tmp83_ = 0;
		guint8* _tmp84_;
		guint8* _tmp85_;
		gint _tmp85__length1;
		gnutls_datum_t* _tmp86_;
		gint _tmp87_ = 0;
		guint8* _tmp88_;
		guint8* _tmp89_;
		gint _tmp89__length1;
		CryptoSrtpSession* _tmp90_;
		gnutls_datum_t* _tmp91_;
		gint _tmp92_ = 0;
		guint8* _tmp93_;
		guint8* _tmp94_;
		gint _tmp94__length1;
		gnutls_datum_t* _tmp95_;
		gint _tmp96_ = 0;
		guint8* _tmp97_;
		guint8* _tmp98_;
		gint _tmp98__length1;
		_tmp81_ = self->priv->srtp_session;
		_tmp82_ = client_key;
		_tmp84_ = gnutls_datum_extract (*_tmp82_, &_tmp83_);
		_tmp85_ = _tmp84_;
		_tmp85__length1 = _tmp83_;
		_tmp86_ = client_salt;
		_tmp88_ = gnutls_datum_extract (*_tmp86_, &_tmp87_);
		_tmp89_ = _tmp88_;
		_tmp89__length1 = _tmp87_;
		crypto_srtp_session_set_encryption_key (_tmp81_, CRYPTO_SRTP_AES_CM_128_HMAC_SHA1_80, _tmp85_, (gint) _tmp83_, _tmp89_, (gint) _tmp87_);
		_tmp89_ = (g_free (_tmp89_), NULL);
		_tmp85_ = (g_free (_tmp85_), NULL);
		_tmp90_ = self->priv->srtp_session;
		_tmp91_ = server_key;
		_tmp93_ = gnutls_datum_extract (*_tmp91_, &_tmp92_);
		_tmp94_ = _tmp93_;
		_tmp94__length1 = _tmp92_;
		_tmp95_ = server_salt;
		_tmp97_ = gnutls_datum_extract (*_tmp95_, &_tmp96_);
		_tmp98_ = _tmp97_;
		_tmp98__length1 = _tmp96_;
		crypto_srtp_session_set_decryption_key (_tmp90_, CRYPTO_SRTP_AES_CM_128_HMAC_SHA1_80, _tmp94_, (gint) _tmp92_, _tmp98_, (gint) _tmp96_);
		_tmp98_ = (g_free (_tmp98_), NULL);
		_tmp94_ = (g_free (_tmp94_), NULL);
	}
	_tmp99_ = self->priv->credentials;
	_tmp100_ = _tmp99_->own_fingerprint;
	_tmp100__length1 = _tmp99_->own_fingerprint_length1;
	_tmp101_ = dino_plugins_ice_dtls_srtp_handler_get_peer_fingerprint (self, &_tmp102_);
	_tmp101__length1 = _tmp102_;
	_tmp103_ = _tmp101_;
	_tmp103__length1 = _tmp101__length1;
	_tmp104_ = xmpp_xep_jingle_content_encryption_new (XMPP_XEP_JINGLE_ICE_UDP_DTLS_NS_URI, "DTLS-SRTP", _tmp100_, _tmp100__length1, _tmp103_, _tmp103__length1);
	result = _tmp104_;
	_g_free0 (server_salt);
	_g_free0 (server_key);
	_g_free0 (client_salt);
	_g_free0 (client_key);
	km = (g_free (km), NULL);
	_g_date_time_unref0 (maximum_time);
	_gnutls_deinit0 (session);
	_gnutls_certificate_free_credentials0 (cert_cred);
	return result;
}

static gssize
dino_plugins_ice_dtls_srtp_handler_pull_function (void* transport_ptr,
                                                  guint8* buffer,
                                                  gint buffer_length1)
{
	DinoPluginsIceDtlsSrtpHandler* _self_ = NULL;
	DinoPluginsIceDtlsSrtpHandler* _tmp0_;
	DinoPluginsIceDtlsSrtpHandler* _tmp1_;
	GBytes* data = NULL;
	DinoPluginsIceDtlsSrtpHandler* _tmp10_;
	GeeLinkedList* _tmp11_;
	gpointer _tmp12_;
	DinoPluginsIceDtlsSrtpHandler* _tmp13_;
	guint8* data_uint8 = NULL;
	GBytes* _tmp14_;
	gsize _tmp15_ = 0;
	guint8* _tmp16_;
	gint data_uint8_length1;
	gint _data_uint8_size_;
	guint8* _tmp17_;
	gint _tmp17__length1;
	guint8* _tmp18_;
	gint _tmp18__length1;
	guint8* _tmp19_;
	gint _tmp19__length1;
	gssize result;
	_tmp0_ = _dino_plugins_ice_dtls_srtp_handler_ref0 (DINO_PLUGINS_ICE_DTLS_SRTP_IS_HANDLER (transport_ptr) ? ((DinoPluginsIceDtlsSrtpHandler*) transport_ptr) : NULL);
	_self_ = _tmp0_;
	_tmp1_ = _self_;
	g_mutex_lock (&_tmp1_->priv->buffer_mutex);
	while (TRUE) {
		DinoPluginsIceDtlsSrtpHandler* _tmp2_;
		GeeLinkedList* _tmp3_;
		gint _tmp4_;
		gint _tmp5_;
		DinoPluginsIceDtlsSrtpHandler* _tmp6_;
		DinoPluginsIceDtlsSrtpHandler* _tmp7_;
		DinoPluginsIceDtlsSrtpHandler* _tmp8_;
		_tmp2_ = _self_;
		_tmp3_ = _tmp2_->priv->buffer_queue;
		_tmp4_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp3_);
		_tmp5_ = _tmp4_;
		if (!(_tmp5_ == 0)) {
			break;
		}
		_tmp6_ = _self_;
		_tmp7_ = _self_;
		g_cond_wait (&_tmp6_->priv->buffer_cond, &_tmp7_->priv->buffer_mutex);
		_tmp8_ = _self_;
		if (_tmp8_->priv->stop) {
			DinoPluginsIceDtlsSrtpHandler* _tmp9_;
			_tmp9_ = _self_;
			g_mutex_unlock (&_tmp9_->priv->buffer_mutex);
			g_debug ("dtls_srtp.vala:230: DTLS handshake pull_function stopped");
			result = (gssize) -1;
			_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
			return result;
		}
	}
	_tmp10_ = _self_;
	_tmp11_ = _tmp10_->priv->buffer_queue;
	_tmp12_ = gee_abstract_list_remove_at ((GeeAbstractList*) _tmp11_, 0);
	data = (GBytes*) _tmp12_;
	_tmp13_ = _self_;
	g_mutex_unlock (&_tmp13_->priv->buffer_mutex);
	_tmp14_ = data;
	data = NULL;
	_tmp16_ = g_bytes_unref_to_data (_tmp14_, &_tmp15_);
	data_uint8 = _tmp16_;
	data_uint8_length1 = _tmp15_;
	_data_uint8_size_ = data_uint8_length1;
	_tmp17_ = data_uint8;
	_tmp17__length1 = data_uint8_length1;
	_tmp18_ = data_uint8;
	_tmp18__length1 = data_uint8_length1;
	memcpy (buffer, _tmp17_, (gsize) _tmp18__length1);
	_tmp19_ = data_uint8;
	_tmp19__length1 = data_uint8_length1;
	result = (gssize) _tmp19__length1;
	data_uint8 = (g_free (data_uint8), NULL);
	_g_bytes_unref0 (data);
	_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
	return result;
}

static gint
dino_plugins_ice_dtls_srtp_handler_pull_timeout_function (void* transport_ptr,
                                                          guint ms)
{
	DinoPluginsIceDtlsSrtpHandler* _self_ = NULL;
	DinoPluginsIceDtlsSrtpHandler* _tmp0_;
	gint64 end_time = 0LL;
	DinoPluginsIceDtlsSrtpHandler* _tmp1_;
	DinoPluginsIceDtlsSrtpHandler* _tmp11_;
	gint result;
	_tmp0_ = _dino_plugins_ice_dtls_srtp_handler_ref0 (DINO_PLUGINS_ICE_DTLS_SRTP_IS_HANDLER (transport_ptr) ? ((DinoPluginsIceDtlsSrtpHandler*) transport_ptr) : NULL);
	_self_ = _tmp0_;
	end_time = g_get_monotonic_time () + (ms * 1000);
	_tmp1_ = _self_;
	g_mutex_lock (&_tmp1_->priv->buffer_mutex);
	while (TRUE) {
		DinoPluginsIceDtlsSrtpHandler* _tmp2_;
		GeeLinkedList* _tmp3_;
		gint _tmp4_;
		gint _tmp5_;
		DinoPluginsIceDtlsSrtpHandler* _tmp6_;
		DinoPluginsIceDtlsSrtpHandler* _tmp7_;
		DinoPluginsIceDtlsSrtpHandler* _tmp8_;
		_tmp2_ = _self_;
		_tmp3_ = _tmp2_->priv->buffer_queue;
		_tmp4_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp3_);
		_tmp5_ = _tmp4_;
		if (!(_tmp5_ == 0)) {
			break;
		}
		_tmp6_ = _self_;
		_tmp7_ = _self_;
		g_cond_wait_until (&_tmp6_->priv->buffer_cond, &_tmp7_->priv->buffer_mutex, end_time);
		_tmp8_ = _self_;
		if (_tmp8_->priv->stop) {
			DinoPluginsIceDtlsSrtpHandler* _tmp9_;
			_tmp9_ = _self_;
			g_mutex_unlock (&_tmp9_->priv->buffer_mutex);
			g_debug ("dtls_srtp.vala:254: DTLS handshake pull_timeout_function stopped");
			result = -1;
			_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
			return result;
		}
		if (g_get_monotonic_time () > end_time) {
			DinoPluginsIceDtlsSrtpHandler* _tmp10_;
			_tmp10_ = _self_;
			g_mutex_unlock (&_tmp10_->priv->buffer_mutex);
			result = 0;
			_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
			return result;
		}
	}
	_tmp11_ = _self_;
	g_mutex_unlock (&_tmp11_->priv->buffer_mutex);
	result = 1;
	_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
	return result;
}

static gssize
dino_plugins_ice_dtls_srtp_handler_push_function (void* transport_ptr,
                                                  guint8* buffer,
                                                  gint buffer_length1)
{
	DinoPluginsIceDtlsSrtpHandler* _self_ = NULL;
	DinoPluginsIceDtlsSrtpHandler* _tmp0_;
	gssize result;
	_tmp0_ = _dino_plugins_ice_dtls_srtp_handler_ref0 (DINO_PLUGINS_ICE_DTLS_SRTP_IS_HANDLER (transport_ptr) ? ((DinoPluginsIceDtlsSrtpHandler*) transport_ptr) : NULL);
	_self_ = _tmp0_;
	g_signal_emit (_self_, dino_plugins_ice_dtls_srtp_handler_signals[DINO_PLUGINS_ICE_DTLS_SRTP_HANDLER_SEND_DATA_SIGNAL], 0, buffer, (gint) buffer_length1);
	result = (gssize) buffer_length1;
	_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
	return result;
}

static gint
dino_plugins_ice_dtls_srtp_handler_verify_function (struct gnutls_session_int* session)
{
	DinoPluginsIceDtlsSrtpHandler* _self_ = NULL;
	void* _tmp0_;
	DinoPluginsIceDtlsSrtpHandler* _tmp1_;
	GError* _inner_error0_ = NULL;
	gint result;
	g_return_val_if_fail (session != NULL, -1);
	_tmp0_ = gnutls_transport_get_ptr (session);
	_tmp1_ = _dino_plugins_ice_dtls_srtp_handler_ref0 (DINO_PLUGINS_ICE_DTLS_SRTP_IS_HANDLER (_tmp0_) ? ((DinoPluginsIceDtlsSrtpHandler*) _tmp0_) : NULL);
	_self_ = _tmp1_;
	{
		gboolean valid = FALSE;
		valid = dino_plugins_ice_dtls_srtp_handler_verify_peer_cert (_self_, session, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		if (!valid) {
			g_warning ("dtls_srtp.vala:282: DTLS certificate invalid. Aborting handshake.");
			result = 1;
			_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
			return result;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp2_;
		const gchar* _tmp3_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp2_ = e;
		_tmp3_ = _tmp2_->message;
		g_warning ("dtls_srtp.vala:286: Error during DTLS certificate validation: %s. Abor" \
"ting handshake.", _tmp3_);
		result = 1;
		_g_error_free0 (e);
		_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
		return result;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gint _tmp4_ = -1;
		_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return _tmp4_;
	}
	result = 0;
	_dino_plugins_ice_dtls_srtp_handler_unref0 (_self_);
	return result;
}

static void
gnutls_x509_crt_import_ (struct gnutls_x509_crt_int* self,
                         gnutls_datum_t* data,
                         gnutls_x509_crt_fmt_t format,
                         GError** error)
{
	gint err = 0;
	gint _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = gnutls_x509_crt_import (self, data, format);
	err = _tmp0_;
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static gboolean
dino_plugins_ice_dtls_srtp_handler_verify_peer_cert (DinoPluginsIceDtlsSrtpHandler* self,
                                                     struct gnutls_session_int* session,
                                                     GError** error)
{
	gnutls_datum_t* cert_datums = NULL;
	unsigned int _tmp0_ = 0;
	gnutls_datum_t* _tmp1_;
	gint cert_datums_length1;
	gint _cert_datums_size_;
	gnutls_datum_t* _tmp2_;
	gint _tmp2__length1;
	gnutls_datum_t* _tmp3_;
	gint _tmp3__length1;
	struct gnutls_x509_crt_int* peer_cert = NULL;
	struct gnutls_x509_crt_int* _tmp4_;
	struct gnutls_x509_crt_int* _tmp6_;
	gnutls_datum_t* _tmp7_;
	gint _tmp7__length1;
	gnutls_digest_algorithm_t algo = 0;
	const gchar* _tmp9_;
	const gchar* _tmp10_;
	GQuark _tmp12_ = 0U;
	static GQuark _tmp11_label0 = 0;
	guint8* real_peer_fp = NULL;
	struct gnutls_x509_crt_int* _tmp14_;
	gint _tmp15_ = 0;
	guint8* _tmp16_;
	gint real_peer_fp_length1;
	gint _real_peer_fp_size_;
	guint8* _tmp17_;
	gint _tmp17__length1;
	guint8* _tmp18_;
	gint _tmp18__length1;
	gint _tmp19_ = 0;
	guint8* _tmp20_;
	gint _tmp20__length1;
	GError* _inner_error0_ = NULL;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (session != NULL, FALSE);
	_tmp1_ = gnutls_certificate_get_peers (session, &_tmp0_);
	cert_datums = _tmp1_;
	cert_datums_length1 = _tmp0_;
	_cert_datums_size_ = cert_datums_length1;
	_tmp2_ = cert_datums;
	_tmp2__length1 = cert_datums_length1;
	if (_tmp2__length1 == 0) {
		g_warning ("dtls_srtp.vala:297: No peer certs");
		result = FALSE;
		return result;
	}
	_tmp3_ = cert_datums;
	_tmp3__length1 = cert_datums_length1;
	if (_tmp3__length1 > 1) {
		g_warning ("dtls_srtp.vala:300: More than one peer cert");
	}
	_tmp4_ = gnutls_x509_crt_create (&_inner_error0_);
	peer_cert = _tmp4_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gboolean _tmp5_ = FALSE;
		g_propagate_error (error, _inner_error0_);
		return _tmp5_;
	}
	_tmp6_ = peer_cert;
	_tmp7_ = cert_datums;
	_tmp7__length1 = cert_datums_length1;
	gnutls_x509_crt_import_ (_tmp6_, &_tmp7_[0], GNUTLS_X509_FMT_DER, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gboolean _tmp8_ = FALSE;
		g_propagate_error (error, _inner_error0_);
		_gnutls_x509_crt_deinit0 (peer_cert);
		return _tmp8_;
	}
	_tmp9_ = self->priv->_peer_fp_algo;
	_tmp10_ = _tmp9_;
	_tmp12_ = (NULL == _tmp10_) ? 0 : g_quark_from_string (_tmp10_);
	if (_tmp12_ == ((0 != _tmp11_label0) ? _tmp11_label0 : (_tmp11_label0 = g_quark_from_static_string ("sha-256")))) {
		switch (0) {
			default:
			{
				algo = GNUTLS_DIG_SHA256;
				break;
			}
		}
	} else {
		switch (0) {
			default:
			{
				const gchar* _tmp13_;
				_tmp13_ = self->priv->_peer_fp_algo;
				g_warning ("dtls_srtp.vala:311: Unkown peer fingerprint algorithm: %s", _tmp13_);
				result = FALSE;
				_gnutls_x509_crt_deinit0 (peer_cert);
				return result;
			}
		}
	}
	_tmp14_ = peer_cert;
	_tmp16_ = dino_plugins_ice_dtls_srtp_get_fingerprint (_tmp14_, algo, &_tmp15_);
	real_peer_fp = _tmp16_;
	real_peer_fp_length1 = _tmp15_;
	_real_peer_fp_size_ = real_peer_fp_length1;
	_tmp17_ = real_peer_fp;
	_tmp17__length1 = real_peer_fp_length1;
	_tmp18_ = dino_plugins_ice_dtls_srtp_handler_get_peer_fingerprint (self, &_tmp19_);
	_tmp18__length1 = _tmp19_;
	_tmp20_ = _tmp18_;
	_tmp20__length1 = _tmp18__length1;
	if (_tmp17__length1 != _tmp20__length1) {
		guint8* _tmp21_;
		gint _tmp21__length1;
		guint8* _tmp22_;
		gint _tmp22__length1;
		gint _tmp23_ = 0;
		guint8* _tmp24_;
		gint _tmp24__length1;
		_tmp21_ = real_peer_fp;
		_tmp21__length1 = real_peer_fp_length1;
		_tmp22_ = dino_plugins_ice_dtls_srtp_handler_get_peer_fingerprint (self, &_tmp23_);
		_tmp22__length1 = _tmp23_;
		_tmp24_ = _tmp22_;
		_tmp24__length1 = _tmp22__length1;
		g_warning ("dtls_srtp.vala:318: Fingerprint lengths not equal %i vs %i", _tmp21__length1, _tmp24__length1);
		result = FALSE;
		real_peer_fp = (g_free (real_peer_fp), NULL);
		_gnutls_x509_crt_deinit0 (peer_cert);
		return result;
	}
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp25_ = FALSE;
			_tmp25_ = TRUE;
			while (TRUE) {
				guint8* _tmp27_;
				gint _tmp27__length1;
				guint8* _tmp28_;
				gint _tmp28__length1;
				guint8 _tmp29_;
				guint8* _tmp30_;
				gint _tmp30__length1;
				gint _tmp31_ = 0;
				guint8* _tmp32_;
				gint _tmp32__length1;
				guint8 _tmp33_;
				if (!_tmp25_) {
					gint _tmp26_;
					_tmp26_ = i;
					i = _tmp26_ + 1;
				}
				_tmp25_ = FALSE;
				_tmp27_ = real_peer_fp;
				_tmp27__length1 = real_peer_fp_length1;
				if (!(i < _tmp27__length1)) {
					break;
				}
				_tmp28_ = real_peer_fp;
				_tmp28__length1 = real_peer_fp_length1;
				_tmp29_ = _tmp28_[i];
				_tmp30_ = dino_plugins_ice_dtls_srtp_handler_get_peer_fingerprint (self, &_tmp31_);
				_tmp30__length1 = _tmp31_;
				_tmp32_ = _tmp30_;
				_tmp32__length1 = _tmp30__length1;
				_tmp33_ = _tmp32_[i];
				if (_tmp29_ != _tmp33_) {
					guint8* _tmp34_;
					gint _tmp34__length1;
					gchar* _tmp35_;
					gchar* _tmp36_;
					guint8* _tmp37_;
					gint _tmp37__length1;
					gint _tmp38_ = 0;
					guint8* _tmp39_;
					gint _tmp39__length1;
					gchar* _tmp40_;
					gchar* _tmp41_;
					_tmp34_ = real_peer_fp;
					_tmp34__length1 = real_peer_fp_length1;
					_tmp35_ = dino_plugins_ice_dtls_srtp_format_fingerprint (_tmp34_, (gint) _tmp34__length1);
					_tmp36_ = _tmp35_;
					_tmp37_ = dino_plugins_ice_dtls_srtp_handler_get_peer_fingerprint (self, &_tmp38_);
					_tmp37__length1 = _tmp38_;
					_tmp39_ = _tmp37_;
					_tmp39__length1 = _tmp37__length1;
					_tmp40_ = dino_plugins_ice_dtls_srtp_format_fingerprint (_tmp39_, (gint) _tmp39__length1);
					_tmp41_ = _tmp40_;
					g_warning ("dtls_srtp.vala:324: First cert in peer cert list doesn't equal adverti" \
"sed one: %s vs %s", _tmp36_, _tmp41_);
					_g_free0 (_tmp41_);
					_g_free0 (_tmp36_);
					result = FALSE;
					real_peer_fp = (g_free (real_peer_fp), NULL);
					_gnutls_x509_crt_deinit0 (peer_cert);
					return result;
				}
			}
		}
	}
	result = TRUE;
	real_peer_fp = (g_free (real_peer_fp), NULL);
	_gnutls_x509_crt_deinit0 (peer_cert);
	return result;
}

DinoPluginsIceDtlsSrtpHandler*
dino_plugins_ice_dtls_srtp_handler_construct (GType object_type)
{
	DinoPluginsIceDtlsSrtpHandler* self = NULL;
	self = (DinoPluginsIceDtlsSrtpHandler*) g_type_create_instance (object_type);
	return self;
}

DinoPluginsIceDtlsSrtpHandler*
dino_plugins_ice_dtls_srtp_handler_new (void)
{
	return dino_plugins_ice_dtls_srtp_handler_construct (DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER);
}

gboolean
dino_plugins_ice_dtls_srtp_handler_get_ready (DinoPluginsIceDtlsSrtpHandler* self)
{
	gboolean result;
	gboolean _tmp0_ = FALSE;
	CryptoSrtpSession* _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp3_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = self->priv->srtp_session;
	_tmp2_ = crypto_srtp_session_get_has_encrypt (_tmp1_);
	_tmp3_ = _tmp2_;
	if (_tmp3_) {
		CryptoSrtpSession* _tmp4_;
		gboolean _tmp5_;
		gboolean _tmp6_;
		_tmp4_ = self->priv->srtp_session;
		_tmp5_ = crypto_srtp_session_get_has_decrypt (_tmp4_);
		_tmp6_ = _tmp5_;
		_tmp0_ = _tmp6_;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

DinoPluginsIceDtlsSrtpMode
dino_plugins_ice_dtls_srtp_handler_get_mode (DinoPluginsIceDtlsSrtpHandler* self)
{
	DinoPluginsIceDtlsSrtpMode result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_mode;
	return result;
}

void
dino_plugins_ice_dtls_srtp_handler_set_mode (DinoPluginsIceDtlsSrtpHandler* self,
                                             DinoPluginsIceDtlsSrtpMode value)
{
	g_return_if_fail (self != NULL);
	self->priv->_mode = value;
}

guint8*
dino_plugins_ice_dtls_srtp_handler_get_own_fingerprint (DinoPluginsIceDtlsSrtpHandler* self,
                                                        gint* result_length1)
{
	guint8* result;
	guint8* _tmp0_;
	gint _tmp0__length1;
	guint8* _tmp1_;
	gint _tmp1__length1;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_own_fingerprint;
	_tmp0__length1 = self->priv->_own_fingerprint_length1;
	_tmp1_ = _tmp0_;
	_tmp1__length1 = _tmp0__length1;
	if (result_length1) {
		*result_length1 = _tmp1__length1;
	}
	result = _tmp1_;
	return result;
}

static guint8*
_vala_array_dup4 (guint8* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (guint8));
	}
	return NULL;
}

static void
dino_plugins_ice_dtls_srtp_handler_set_own_fingerprint (DinoPluginsIceDtlsSrtpHandler* self,
                                                        guint8* value,
                                                        gint value_length1)
{
	guint8* _tmp0_;
	gint _tmp0__length1;
	g_return_if_fail (self != NULL);
	_tmp0_ = (value != NULL) ? _vala_array_dup4 (value, value_length1) : value;
	_tmp0__length1 = value_length1;
	self->priv->_own_fingerprint = (g_free (self->priv->_own_fingerprint), NULL);
	self->priv->_own_fingerprint = _tmp0_;
	self->priv->_own_fingerprint_length1 = _tmp0__length1;
	self->priv->__own_fingerprint_size_ = self->priv->_own_fingerprint_length1;
}

guint8*
dino_plugins_ice_dtls_srtp_handler_get_peer_fingerprint (DinoPluginsIceDtlsSrtpHandler* self,
                                                         gint* result_length1)
{
	guint8* result;
	guint8* _tmp0_;
	gint _tmp0__length1;
	guint8* _tmp1_;
	gint _tmp1__length1;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_peer_fingerprint;
	_tmp0__length1 = self->priv->_peer_fingerprint_length1;
	_tmp1_ = _tmp0_;
	_tmp1__length1 = _tmp0__length1;
	if (result_length1) {
		*result_length1 = _tmp1__length1;
	}
	result = _tmp1_;
	return result;
}

static guint8*
_vala_array_dup5 (guint8* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (guint8));
	}
	return NULL;
}

void
dino_plugins_ice_dtls_srtp_handler_set_peer_fingerprint (DinoPluginsIceDtlsSrtpHandler* self,
                                                         guint8* value,
                                                         gint value_length1)
{
	guint8* _tmp0_;
	gint _tmp0__length1;
	g_return_if_fail (self != NULL);
	_tmp0_ = (value != NULL) ? _vala_array_dup5 (value, value_length1) : value;
	_tmp0__length1 = value_length1;
	self->priv->_peer_fingerprint = (g_free (self->priv->_peer_fingerprint), NULL);
	self->priv->_peer_fingerprint = _tmp0_;
	self->priv->_peer_fingerprint_length1 = _tmp0__length1;
	self->priv->__peer_fingerprint_size_ = self->priv->_peer_fingerprint_length1;
}

const gchar*
dino_plugins_ice_dtls_srtp_handler_get_peer_fp_algo (DinoPluginsIceDtlsSrtpHandler* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_peer_fp_algo;
	result = _tmp0_;
	return result;
}

void
dino_plugins_ice_dtls_srtp_handler_set_peer_fp_algo (DinoPluginsIceDtlsSrtpHandler* self,
                                                     const gchar* value)
{
	gchar* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_strdup (value);
	_g_free0 (self->priv->_peer_fp_algo);
	self->priv->_peer_fp_algo = _tmp0_;
}

static void
g_cclosure_user_marshal_VOID__POINTER_INT (GClosure * closure,
                                           GValue * return_value,
                                           guint n_param_values,
                                           const GValue * param_values,
                                           gpointer invocation_hint,
                                           gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__POINTER_INT) (gpointer data1, gpointer arg_1, gint arg_2, gpointer data2);
	register GMarshalFunc_VOID__POINTER_INT callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__POINTER_INT) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_pointer (param_values + 1), g_value_get_int (param_values + 2), data2);
}

static void
dino_plugins_ice_dtls_srtp_value_handler_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
dino_plugins_ice_dtls_srtp_value_handler_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		dino_plugins_ice_dtls_srtp_handler_unref (value->data[0].v_pointer);
	}
}

static void
dino_plugins_ice_dtls_srtp_value_handler_copy_value (const GValue* src_value,
                                                     GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = dino_plugins_ice_dtls_srtp_handler_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
dino_plugins_ice_dtls_srtp_value_handler_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
dino_plugins_ice_dtls_srtp_value_handler_collect_value (GValue* value,
                                                        guint n_collect_values,
                                                        GTypeCValue* collect_values,
                                                        guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		DinoPluginsIceDtlsSrtpHandler * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = dino_plugins_ice_dtls_srtp_handler_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
dino_plugins_ice_dtls_srtp_value_handler_lcopy_value (const GValue* value,
                                                      guint n_collect_values,
                                                      GTypeCValue* collect_values,
                                                      guint collect_flags)
{
	DinoPluginsIceDtlsSrtpHandler ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = dino_plugins_ice_dtls_srtp_handler_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
dino_plugins_ice_dtls_srtp_param_spec_handler (const gchar* name,
                                               const gchar* nick,
                                               const gchar* blurb,
                                               GType object_type,
                                               GParamFlags flags)
{
	DinoPluginsIceDtlsSrtpParamSpecHandler* spec;
	g_return_val_if_fail (g_type_is_a (object_type, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

gpointer
dino_plugins_ice_dtls_srtp_value_get_handler (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER), NULL);
	return value->data[0].v_pointer;
}

void
dino_plugins_ice_dtls_srtp_value_set_handler (GValue* value,
                                              gpointer v_object)
{
	DinoPluginsIceDtlsSrtpHandler * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		dino_plugins_ice_dtls_srtp_handler_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dino_plugins_ice_dtls_srtp_handler_unref (old);
	}
}

void
dino_plugins_ice_dtls_srtp_value_take_handler (GValue* value,
                                               gpointer v_object)
{
	DinoPluginsIceDtlsSrtpHandler * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dino_plugins_ice_dtls_srtp_handler_unref (old);
	}
}

static void
dino_plugins_ice_dtls_srtp_handler_class_init (DinoPluginsIceDtlsSrtpHandlerClass * klass,
                                               gpointer klass_data)
{
	dino_plugins_ice_dtls_srtp_handler_parent_class = g_type_class_peek_parent (klass);
	((DinoPluginsIceDtlsSrtpHandlerClass *) klass)->finalize = dino_plugins_ice_dtls_srtp_handler_finalize;
	g_type_class_adjust_private_offset (klass, &DinoPluginsIceDtlsSrtpHandler_private_offset);
	dino_plugins_ice_dtls_srtp_handler_signals[DINO_PLUGINS_ICE_DTLS_SRTP_HANDLER_SEND_DATA_SIGNAL] = g_signal_new ("send-data", DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__POINTER_INT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_INT);
}

static void
dino_plugins_ice_dtls_srtp_handler_instance_init (DinoPluginsIceDtlsSrtpHandler * self,
                                                  gpointer klass)
{
	GeeLinkedList* _tmp0_;
	CryptoSrtpSession* _tmp1_;
	self->priv = dino_plugins_ice_dtls_srtp_handler_get_instance_private (self);
	self->priv->_mode = DINO_PLUGINS_ICE_DTLS_SRTP_MODE_CLIENT;
	g_cond_init (&self->priv->buffer_cond);
	g_mutex_init (&self->priv->buffer_mutex);
	_tmp0_ = gee_linked_list_new (G_TYPE_BYTES, (GBoxedCopyFunc) g_bytes_ref, (GDestroyNotify) g_bytes_unref, NULL, NULL, NULL);
	self->priv->buffer_queue = _tmp0_;
	self->priv->running = FALSE;
	self->priv->stop = FALSE;
	self->priv->restart = FALSE;
	_tmp1_ = crypto_srtp_session_new ();
	self->priv->srtp_session = _tmp1_;
	self->ref_count = 1;
}

static void
dino_plugins_ice_dtls_srtp_handler_finalize (DinoPluginsIceDtlsSrtpHandler * obj)
{
	DinoPluginsIceDtlsSrtpHandler * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DINO_PLUGINS_ICE_DTLS_SRTP_TYPE_HANDLER, DinoPluginsIceDtlsSrtpHandler);
	g_signal_handlers_destroy (self);
	self->priv->_own_fingerprint = (g_free (self->priv->_own_fingerprint), NULL);
	self->priv->_peer_fingerprint = (g_free (self->priv->_peer_fingerprint), NULL);
	_g_free0 (self->priv->_peer_fp_algo);
	_dino_plugins_ice_dtls_srtp_credentials_capsule_unref0 (self->priv->credentials);
	_vala_clear_GCond (&self->priv->buffer_cond);
	_vala_clear_GMutex (&self->priv->buffer_mutex);
	_g_object_unref0 (self->priv->buffer_queue);
	_crypto_srtp_session_unref0 (self->priv->srtp_session);
}

static GType
dino_plugins_ice_dtls_srtp_handler_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { dino_plugins_ice_dtls_srtp_value_handler_init, dino_plugins_ice_dtls_srtp_value_handler_free_value, dino_plugins_ice_dtls_srtp_value_handler_copy_value, dino_plugins_ice_dtls_srtp_value_handler_peek_pointer, "p", dino_plugins_ice_dtls_srtp_value_handler_collect_value, "p", dino_plugins_ice_dtls_srtp_value_handler_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (DinoPluginsIceDtlsSrtpHandlerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dino_plugins_ice_dtls_srtp_handler_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DinoPluginsIceDtlsSrtpHandler), 0, (GInstanceInitFunc) dino_plugins_ice_dtls_srtp_handler_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType dino_plugins_ice_dtls_srtp_handler_type_id;
	dino_plugins_ice_dtls_srtp_handler_type_id = g_type_register_fundamental (g_type_fundamental_next (), "DinoPluginsIceDtlsSrtpHandler", &g_define_type_info, &g_define_type_fundamental_info, 0);
	DinoPluginsIceDtlsSrtpHandler_private_offset = g_type_add_instance_private (dino_plugins_ice_dtls_srtp_handler_type_id, sizeof (DinoPluginsIceDtlsSrtpHandlerPrivate));
	return dino_plugins_ice_dtls_srtp_handler_type_id;
}

GType
dino_plugins_ice_dtls_srtp_handler_get_type (void)
{
	static volatile gsize dino_plugins_ice_dtls_srtp_handler_type_id__once = 0;
	if (g_once_init_enter (&dino_plugins_ice_dtls_srtp_handler_type_id__once)) {
		GType dino_plugins_ice_dtls_srtp_handler_type_id;
		dino_plugins_ice_dtls_srtp_handler_type_id = dino_plugins_ice_dtls_srtp_handler_get_type_once ();
		g_once_init_leave (&dino_plugins_ice_dtls_srtp_handler_type_id__once, dino_plugins_ice_dtls_srtp_handler_type_id);
	}
	return dino_plugins_ice_dtls_srtp_handler_type_id__once;
}

gpointer
dino_plugins_ice_dtls_srtp_handler_ref (gpointer instance)
{
	DinoPluginsIceDtlsSrtpHandler * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
dino_plugins_ice_dtls_srtp_handler_unref (gpointer instance)
{
	DinoPluginsIceDtlsSrtpHandler * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		DINO_PLUGINS_ICE_DTLS_SRTP_HANDLER_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static void
gnutls_x509_crt_get_fingerprint_ (struct gnutls_x509_crt_int* self,
                                  gnutls_digest_algorithm_t algo,
                                  void* buf,
                                  gsize* buf_size,
                                  GError** error)
{
	gint err = 0;
	gint _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = gnutls_x509_crt_get_fingerprint (self, algo, buf, buf_size);
	err = _tmp0_;
	gnutls_throw_if_error (err, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

guint8*
dino_plugins_ice_dtls_srtp_get_fingerprint (struct gnutls_x509_crt_int* certificate,
                                            gnutls_digest_algorithm_t digest_algo,
                                            gint* result_length1)
{
	guint8* buf = NULL;
	guint8* _tmp0_;
	gint buf_length1;
	gint _buf_size_;
	gsize buf_out_size = 0UL;
	guint8* ret = NULL;
	guint8* _tmp1_;
	gint ret_length1;
	gint _ret_size_;
	guint8* _tmp6_;
	gint _tmp6__length1;
	GError* _inner_error0_ = NULL;
	guint8* result;
	g_return_val_if_fail (certificate != NULL, NULL);
	_tmp0_ = g_new0 (guint8, 512);
	buf = _tmp0_;
	buf_length1 = 512;
	_buf_size_ = buf_length1;
	buf_out_size = (gsize) 512;
	gnutls_x509_crt_get_fingerprint_ (certificate, digest_algo, buf, &buf_out_size, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		buf = (g_free (buf), NULL);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp1_ = g_new0 (guint8, buf_out_size);
	ret = _tmp1_;
	ret_length1 = buf_out_size;
	_ret_size_ = ret_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				guint8* _tmp4_;
				gint _tmp4__length1;
				guint8 _tmp5_;
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = i;
					i = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				if (!(((gsize) i) < buf_out_size)) {
					break;
				}
				_tmp4_ = ret;
				_tmp4__length1 = ret_length1;
				_tmp5_ = buf[i];
				_tmp4_[i] = _tmp5_;
			}
		}
	}
	_tmp6_ = ret;
	_tmp6__length1 = ret_length1;
	if (result_length1) {
		*result_length1 = _tmp6__length1;
	}
	result = _tmp6_;
	buf = (g_free (buf), NULL);
	return result;
}

gchar*
dino_plugins_ice_dtls_srtp_format_fingerprint (guint8* fingerprint,
                                               gint fingerprint_length1)
{
	GString* sb = NULL;
	GString* _tmp0_;
	GString* _tmp8_;
	const gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* result;
	_tmp0_ = g_string_new ("");
	sb = _tmp0_;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				GString* _tmp3_;
				guint8 _tmp4_;
				gchar* _tmp5_;
				gchar* _tmp6_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = i;
					i = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(i < fingerprint_length1)) {
					break;
				}
				_tmp3_ = sb;
				_tmp4_ = fingerprint[i];
				_tmp5_ = g_strdup_printf ("%02X", (guint) _tmp4_);
				_tmp6_ = _tmp5_;
				g_string_append (_tmp3_, _tmp6_);
				_g_free0 (_tmp6_);
				if (i < (fingerprint_length1 - 1)) {
					GString* _tmp7_;
					_tmp7_ = sb;
					g_string_append (_tmp7_, ":");
				}
			}
		}
	}
	_tmp8_ = sb;
	_tmp9_ = _tmp8_->str;
	_tmp10_ = g_strdup (_tmp9_);
	result = _tmp10_;
	_g_string_free0 (sb);
	return result;
}

static GType
dino_plugins_ice_dtls_srtp_mode_get_type_once (void)
{
	static const GEnumValue values[] = {{DINO_PLUGINS_ICE_DTLS_SRTP_MODE_CLIENT, "DINO_PLUGINS_ICE_DTLS_SRTP_MODE_CLIENT", "client"}, {DINO_PLUGINS_ICE_DTLS_SRTP_MODE_SERVER, "DINO_PLUGINS_ICE_DTLS_SRTP_MODE_SERVER", "server"}, {0, NULL, NULL}};
	GType dino_plugins_ice_dtls_srtp_mode_type_id;
	dino_plugins_ice_dtls_srtp_mode_type_id = g_enum_register_static ("DinoPluginsIceDtlsSrtpMode", values);
	return dino_plugins_ice_dtls_srtp_mode_type_id;
}

GType
dino_plugins_ice_dtls_srtp_mode_get_type (void)
{
	static volatile gsize dino_plugins_ice_dtls_srtp_mode_type_id__once = 0;
	if (g_once_init_enter (&dino_plugins_ice_dtls_srtp_mode_type_id__once)) {
		GType dino_plugins_ice_dtls_srtp_mode_type_id;
		dino_plugins_ice_dtls_srtp_mode_type_id = dino_plugins_ice_dtls_srtp_mode_get_type_once ();
		g_once_init_leave (&dino_plugins_ice_dtls_srtp_mode_type_id__once, dino_plugins_ice_dtls_srtp_mode_type_id);
	}
	return dino_plugins_ice_dtls_srtp_mode_type_id__once;
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

static void
_vala_clear_GMutex (GMutex * mutex)
{
	GMutex zero_mutex = { 0 };
	if (memcmp (mutex, &zero_mutex, sizeof (GMutex))) {
		g_mutex_clear (mutex);
		memset (mutex, 0, sizeof (GMutex));
	}
}

static void
_vala_clear_GRecMutex (GRecMutex * mutex)
{
	GRecMutex zero_mutex = { 0 };
	if (memcmp (mutex, &zero_mutex, sizeof (GRecMutex))) {
		g_rec_mutex_clear (mutex);
		memset (mutex, 0, sizeof (GRecMutex));
	}
}

static void
_vala_clear_GRWLock (GRWLock * mutex)
{
	GRWLock zero_mutex = { 0 };
	if (memcmp (mutex, &zero_mutex, sizeof (GRWLock))) {
		g_rw_lock_clear (mutex);
		memset (mutex, 0, sizeof (GRWLock));
	}
}

static void
_vala_clear_GCond (GCond * mutex)
{
	GCond zero_mutex = { 0 };
	if (memcmp (mutex, &zero_mutex, sizeof (GCond))) {
		g_cond_clear (mutex);
		memset (mutex, 0, sizeof (GCond));
	}
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

