static void set_initial_codecs ( struct SimpleTestConference *from, struct SimpleTestStream *to) { GList *codecs = NULL; GList *filtered_codecs = NULL; GList *item = NULL; GList *rcodecs2 = NULL; GError *error = NULL; g_object_get (from->session, "codecs", &codecs, NULL); ts_fail_if (codecs == NULL, "Could not get the codecs"); for (item = g_list_first (codecs); item; item = g_list_next (item)) { FsCodec *codec = item->data; if (codec->id == 0 || codec->id == 8) filtered_codecs = g_list_append (filtered_codecs, codec); } ts_fail_if (filtered_codecs == NULL, "PCMA and PCMU are not in the codecs" " you must install gst-plugins-good"); g_debug ("Setting initial remote codecs on %d:%d from %d", to->dat->id, to->target->id, from->id); if (!fs_stream_set_remote_codecs (to->stream, filtered_codecs, &error)) { if (error) ts_fail ("Could not set the remote codecs on stream %d:%d (%d): %s", to->dat->id, to->target->id, error->code, error->message); else ts_fail ("Could not set the remote codecs on stream %d" " and we DID not get a GError!!", to->target->id); } g_object_get (to->stream, "remote-codecs", &rcodecs2, NULL); ts_fail_unless (_compare_codec_lists (rcodecs2, filtered_codecs), "Can not get remote codecs correctly"); fs_codec_list_destroy (rcodecs2); if (select_last_codec) ts_fail_unless ( fs_session_set_send_codec (to->dat->session, g_list_last (filtered_codecs)->data, &error), "Error setting the send codec to the last codec: %s", error ? error->message : "No GError"); g_clear_error (&error); g_list_free (filtered_codecs); fs_codec_list_destroy (codecs); }
static void _negotiated_codecs_notify (GObject *object, GParamSpec *paramspec, gpointer user_data) { struct SimpleTestConference *dat = user_data; FsSession *session = FS_SESSION (object); GList *codecs = NULL; GError *error = NULL; GList *item = NULL; g_debug ("%d: New negotiated codecs", dat->id); ts_fail_if (session != dat->session, "Got signal from the wrong object"); g_object_get (dat->session, "codecs", &codecs, NULL); ts_fail_if (codecs == NULL, "Could not get the negotiated codecs"); /* We have to find the stream from the target that points back to us */ for (item = g_list_first (dat->streams); item; item = g_list_next (item)) { struct SimpleTestStream *st = item->data; struct SimpleTestStream *st2 = find_pointback_stream (st->target, dat); GList *rcodecs2; g_debug ("Setting negotiated remote codecs on %d:%d from %d",st2->dat->id, st2->target->id, dat->id); if (!fs_stream_set_remote_codecs (st2->stream, codecs, &error)) { if (error) ts_fail ("Could not set the remote codecs on stream %d:%d (%d): %s", st2->dat->id, st2->target->id, error->code, error->message); else ts_fail ("Could not set the remote codecs on stream %d:%d" " and we DID not get a GError!!", st2->dat->id, st2->target->id); } g_object_get (st2->stream, "remote-codecs", &rcodecs2, NULL); ts_fail_unless (_compare_codec_lists (rcodecs2, codecs), "Can not get remote codecs correctly"); fs_codec_list_destroy (rcodecs2); if (select_last_codec) ts_fail_unless ( fs_session_set_send_codec (st2->dat->session, g_list_last (codecs)->data, &error), "Error setting the send codec to the last codec: %s", error ? error->message : "No GError"); g_clear_error (&error); break; } fs_codec_list_destroy (codecs); }
static void _double_codec_handoff_handler (GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer user_data) { static int buffer_count [2][2] = {{0,0},{0,0}}; static gpointer sts[2] = {NULL, NULL}; GstPad *peer = gst_pad_get_peer (pad); gchar *name; gint session, ssrc, pt; guint id = 0xFFFFFF; if (!(sts[0] == user_data || sts[1] == user_data)) { if (!sts[0]) sts[0] = user_data; else if (!sts[1]) sts[1] = user_data; else ts_fail ("Already have two streams"); } if (sts[0] == user_data) id = 0; else if (sts[1] == user_data) id = 1; else ts_fail ("Should not be here"); ts_fail_if (peer == NULL); name = gst_pad_get_name (peer); ts_fail_if (name == NULL); gst_object_unref (peer); ts_fail_unless (sscanf (name, "src_%d_%d_%d", &session, &ssrc, &pt) == 3); g_free (name); if (pt == 0) buffer_count[0][id]++; else if (pt == 8) buffer_count[1][id]++; else ts_fail ("Wrong PT: %d", pt); if (buffer_count[0][0] > 20 && buffer_count[0][1] > 20 && buffer_count[1][0] > 20 && buffer_count[1][1] > 20 ) { g_main_loop_quit (loop); } }
static void set_codecs (struct SimpleTestConference *dat, FsStream *stream) { GList *codecs = NULL; GList *filtered_codecs = NULL; GList *item = NULL; GError *error = NULL; FsCodec *dtmf_codec = NULL; g_object_get (dat->session, "codecs", &codecs, NULL); ts_fail_if (codecs == NULL, "Could not get the local codecs"); for (item = g_list_first (codecs); item; item = g_list_next (item)) { FsCodec *codec = item->data; if (codec->id == 0 || codec->id == 8) { filtered_codecs = g_list_append (filtered_codecs, codec); } else if (codec->clock_rate == 8000 && !g_ascii_strcasecmp (codec->encoding_name, "telephone-event")) { ts_fail_unless (dtmf_codec == NULL, "More than one copy of telephone-event"); dtmf_codec = codec; filtered_codecs = g_list_append (filtered_codecs, codec); } } ts_fail_if (filtered_codecs == NULL, "PCMA and PCMU are not in the codecs" " you must install gst-plugins-good"); ts_fail_unless (dtmf_codec != NULL); dtmf_codec->id = dtmf_id; if (!fs_stream_set_remote_codecs (stream, filtered_codecs, &error)) { if (error) ts_fail ("Could not set the remote codecs on stream (%d): %s", error->code, error->message); else ts_fail ("Could not set the remote codecs on stream" " and we did NOT get a GError!!"); } g_list_free (filtered_codecs); fs_codec_list_destroy (codecs); }
static void _new_local_candidate (FsStream *stream, FsCandidate *candidate) { struct SimpleTestStream *st = g_object_get_data (G_OBJECT (stream), "SimpleTestStream"); gboolean ret; GError *error = NULL; struct SimpleTestStream *other_st = find_pointback_stream (st->target, st->dat); GList *candidates = NULL; g_debug ("%d:%d: Setting remote candidate for component %d", other_st->dat->id, other_st->target->id, candidate->component_id); candidates = g_list_prepend (NULL, candidate); ret = fs_stream_set_remote_candidates (other_st->stream, candidates, &error); g_list_free (candidates); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); }
static gboolean _bus_stop_stream_cb (GstBus *bus, GstMessage *message, gpointer user_data) { FsStreamTransmitter *st = user_data; GstState oldstate, newstate, pending; if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_STATE_CHANGED || G_OBJECT_TYPE (GST_MESSAGE_SRC (message)) != GST_TYPE_PIPELINE) return bus_error_callback (bus, message, user_data); gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (newstate != GST_STATE_PLAYING) return TRUE; if (pending != GST_STATE_VOID_PENDING) ts_fail ("New state playing, but pending is %d", pending); GST_DEBUG ("Stopping stream transmitter"); fs_stream_transmitter_stop (st); g_object_unref (st); GST_DEBUG ("Stopped stream transmitter"); g_atomic_int_set(&running, FALSE); g_main_loop_quit (loop); return TRUE; }
static gboolean set_the_candidates (gpointer user_data) { FsStreamTransmitter *st = FS_STREAM_TRANSMITTER (user_data); GList *candidates = g_object_get_data (G_OBJECT (st), "candidates-set"); gboolean ret; GError *error = NULL; if (!candidates) { g_debug ("Skipping libnice check because it found NO local candidates"); g_atomic_int_set(&running, FALSE); g_main_loop_quit (loop); return FALSE; } if (force_candidates) { GList *item = NULL; GList *next = NULL; GList *new_list = NULL; for (item = candidates; item; item = next) { FsCandidate *cand = item->data; GList *item2 = NULL; next = g_list_next (item); for (item2 = new_list; item2; item2 = g_list_next (item2)) { FsCandidate *cand2 = item2->data; if (cand2->component_id == cand->component_id) break; } if (!item2) { candidates = g_list_remove (candidates, cand); new_list = g_list_append (new_list, cand); } } ret = fs_stream_transmitter_force_remote_candidates (st, new_list, &error); fs_candidate_list_destroy (new_list); } else { ret = fs_stream_transmitter_add_remote_candidates (st, candidates, &error); } if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error setting remote_candidate"); fs_candidate_list_destroy (candidates); return FALSE; }
static void _new_local_candidate (FsStream *stream, FsCandidate *candidate) { struct SimpleTestStream *st = g_object_get_data (G_OBJECT (stream), "SimpleTestStream"); gboolean ret; GError *error = NULL; struct SimpleTestStream *other_st; GList *candidates = NULL; TEST_LOCK (); if (st->target == NULL) { TEST_UNLOCK (); return; } other_st = find_pointback_stream (st->target, st->dat); if (other_st->stream == NULL || (candidate->component_id == FS_COMPONENT_RTCP && no_rtcp)) { TEST_UNLOCK (); return; } st->got_candidates = TRUE; GST_DEBUG ("%d:%d: Setting remote candidate for component %d", other_st->dat->id, other_st->target->id, candidate->component_id); if (other_st->stream == NULL) { TEST_UNLOCK (); return; } candidates = g_list_prepend (NULL, candidate); ret = fs_stream_add_remote_candidates (other_st->stream, candidates, &error); if (ret == FALSE && error && error->domain == FS_ERROR && error->code == FS_ERROR_NOT_IMPLEMENTED) { g_clear_error (&error); ret = fs_stream_force_remote_candidates (other_st->stream, candidates, &error); } g_list_free (candidates); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); TEST_UNLOCK (); }
static void _stream_state_changed (FsStreamTransmitter *st, guint component, FsStreamState state, gpointer user_data) { FsTransmitter *trans = FS_TRANSMITTER (user_data); GEnumClass *enumclass = NULL; GEnumValue *enumvalue = NULL; gchar *prop = NULL; FsStreamState oldstate = 0; enumclass = g_type_class_ref (FS_TYPE_STREAM_STATE); enumvalue = g_enum_get_value (enumclass, state); GST_DEBUG ("%p: Stream state for component %u is now %s (%u)", st, component, enumvalue->value_nick, state); ts_fail_if (state == FS_STREAM_STATE_FAILED, "Failed to establish a connection"); if (component == 1) prop = "last-state-1"; else if (component == 2) prop = "last-state-2"; else ts_fail ("Invalid component %u, component"); oldstate = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (st), prop)); ts_fail_if (state < FS_STREAM_STATE_CONNECTED && state < oldstate, "State went in wrong direction %d -> %d for component %u", oldstate, state, component); g_object_set_data (G_OBJECT (st), prop, GINT_TO_POINTER (state)); if (state < FS_STREAM_STATE_READY) return; if (component == 1) prop = "src_setup_1"; else if (component == 2) prop = "src_setup_2"; if (g_object_get_data (G_OBJECT (trans), prop) == NULL) { GstElement *pipeline = GST_ELEMENT ( g_object_get_data (G_OBJECT (trans), "pipeline")); GST_DEBUG ("%p: Setting up fakesrc for component %u", st, component); setup_fakesrc (trans, pipeline, component); g_object_set_data (G_OBJECT (trans), prop, ""); } else GST_DEBUG ("FAKESRC ALREADY SETUP for component %u", component); }
static void _switch_handoff_handler (GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer user_data) { struct SimpleTestStream *st = user_data; st->buffer_count++; if (st->buffer_count == 20) g_object_set (st->stream, "direction", FS_DIRECTION_SEND, NULL); if (st->buffer_count > 20) ts_fail ("Received a buffer on a stream that should have been sendonly"); }
static struct SimpleTestStream * find_pointback_stream ( struct SimpleTestConference *dat, struct SimpleTestConference *target) { GList *item = NULL; for (item = g_list_first (dat->streams); item; item = g_list_next (item)) { struct SimpleTestStream *st = item->data; if (st->target == target) return st; } ts_fail ("We did not find a return stream for %d in %d", target->id, dat->id); return NULL; }
static void _error_handoff_handler (GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer user_data) { ts_fail ("Received a buffer when we shouldn't have"); }
static void run_shm_transmitter_test (gint flags) { GError *error = NULL; FsTransmitter *trans; FsStreamTransmitter *st; GstBus *bus = NULL; GParameter params[1]; GList *local_cands = NULL; GstStateChangeReturn ret; FsCandidate *cand; GList *remote_cands = NULL; int param_count = 0; gint bus_source; done = FALSE; connected_count = 0; g_cond_init (&cond); g_mutex_init (&test_mutex); buffer_count[0] = 0; buffer_count[1] = 0; received_known[0] = 0; received_known[1] = 0; got_candidates[0] = FALSE; got_candidates[1] = FALSE; got_prepared[0] = FALSE; got_prepared[1] = FALSE; if (unlink ("/tmp/src1") < 0 && errno != ENOENT) fail ("Could not unlink /tmp/src1: %s", strerror (errno)); if (unlink ("/tmp/src2") < 0 && errno != ENOENT) fail ("Could not unlink /tmp/src2: %s", strerror (errno)); local_cands = g_list_append (local_cands, fs_candidate_new (NULL, 1, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "/tmp/src1", 0)); local_cands = g_list_append (local_cands, fs_candidate_new (NULL, 2, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "/tmp/src2", 0)); if (flags & FLAG_LOCAL_CANDIDATES) { memset (params, 0, sizeof (GParameter)); params[0].name = "preferred-local-candidates"; g_value_init (¶ms[0].value, FS_TYPE_CANDIDATE_LIST); g_value_take_boxed (¶ms[0].value, local_cands); param_count = 1; } associate_on_source = !(flags & FLAG_NO_SOURCE); if ((flags & FLAG_NOT_SENDING) && (flags & FLAG_RECVONLY_FILTER)) { buffer_count[0] = 20; received_known[0] = 20; } trans = fs_transmitter_new ("shm", 2, 0, &error); if (error) ts_fail ("Error creating transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL"); g_clear_error (&error); if (flags & FLAG_RECVONLY_FILTER) ts_fail_unless (g_signal_connect (trans, "get-recvonly-filter", G_CALLBACK (get_recvonly_filter), NULL)); pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler)); bus = gst_element_get_bus (pipeline); bus_source = gst_bus_add_watch (bus, bus_error_callback, NULL); gst_bus_enable_sync_message_emission (bus); g_signal_connect (bus, "sync-message::error", G_CALLBACK (sync_error_handler), NULL); gst_object_unref (bus); st = fs_transmitter_new_stream_transmitter (trans, NULL, param_count, params, &error); if (param_count) g_value_unset (¶ms[0].value); if (error) ts_fail ("Error creating stream transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL"); g_clear_error (&error); g_object_set (st, "sending", !(flags & FLAG_NOT_SENDING), NULL); ts_fail_unless (g_signal_connect (st, "new-local-candidate", G_CALLBACK (_new_local_candidate), trans), "Could not connect new-local-candidate signal"); ts_fail_unless (g_signal_connect (st, "local-candidates-prepared", G_CALLBACK (_candidate_prepared), NULL), "Could not connect local-candidates-prepared signal"); ts_fail_unless (g_signal_connect (st, "error", G_CALLBACK (stream_transmitter_error), NULL), "Could not connect error signal"); ts_fail_unless (g_signal_connect (st, "known-source-packet-received", G_CALLBACK (_known_source_packet_received), NULL), "Could not connect known-source-packet-received signal"); ts_fail_unless (g_signal_connect (st, "state-changed", G_CALLBACK (_state_changed), NULL), "Could not connect state-changed signal"); if (!fs_stream_transmitter_gather_local_candidates (st, &error)) { if (error) ts_fail ("Could not start gathering local candidates (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); else ts_fail ("Could not start gathering candidates" " (without a specified error)"); } else { ts_fail_unless (error == NULL); } g_clear_error (&error); ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); ts_fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not set the pipeline to playing"); if (!(flags & FLAG_LOCAL_CANDIDATES)) { ret = fs_stream_transmitter_force_remote_candidates (st, local_cands, &error); fs_candidate_list_destroy (local_cands); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); } else { ts_fail_unless (error == NULL); } g_clear_error (&error); cand = fs_candidate_new (NULL, 1, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, NULL, 0); cand->username = g_strdup ("/tmp/src1"); remote_cands = g_list_prepend (remote_cands, cand); cand = fs_candidate_new (NULL, 2, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, NULL, 0); cand->username = g_strdup ("/tmp/src2"); remote_cands = g_list_prepend (remote_cands, cand); ret = fs_stream_transmitter_force_remote_candidates (st, remote_cands, &error); fs_candidate_list_destroy (remote_cands); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); g_clear_error (&error); g_mutex_lock (&test_mutex); while (connected_count < 2) g_cond_wait (&cond, &test_mutex); g_mutex_unlock (&test_mutex); setup_fakesrc (trans, pipeline, 1); setup_fakesrc (trans, pipeline, 2); g_mutex_lock (&test_mutex); while (!done) g_cond_wait (&cond, &test_mutex); g_mutex_unlock (&test_mutex); fail_unless (got_prepared[0] == TRUE); fail_unless (got_prepared[1] == TRUE); fail_unless (got_candidates[0] == TRUE); fail_unless (got_candidates[1] == TRUE); gst_element_set_state (pipeline, GST_STATE_NULL); if (st) { fs_stream_transmitter_stop (st); g_object_unref (st); } g_object_unref (trans); g_source_remove (bus_source); gst_object_unref (pipeline); g_cond_clear (&cond); g_mutex_clear (&test_mutex); }
static void run_rawudp_transmitter_test (gint n_parameters, GParameter *params, gint flags) { GError *error = NULL; FsTransmitter *trans; FsStreamTransmitter *st; GstBus *bus = NULL; guint tos; buffer_count[0] = 0; buffer_count[1] = 0; received_known[0] = 0; received_known[1] = 0; pipeline_done = FALSE; has_stun = flags & FLAG_HAS_STUN; associate_on_source = !(flags & FLAG_NO_SOURCE); if ((flags & FLAG_NOT_SENDING) && (flags & FLAG_RECVONLY_FILTER)) { buffer_count[0] = 20; received_known[0] = 20; } loop = g_main_loop_new (NULL, FALSE); trans = fs_transmitter_new ("rawudp", 2, 0, &error); if (error) { ts_fail ("Error creating transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL"); g_object_set (trans, "tos", 2, NULL); g_object_get (trans, "tos", &tos, NULL); ts_fail_unless (tos == 2); if (flags & FLAG_RECVONLY_FILTER) ts_fail_unless (g_signal_connect (trans, "get-recvonly-filter", G_CALLBACK (get_recvonly_filter), NULL)); pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler)); bus = gst_element_get_bus (pipeline); gst_bus_add_watch (bus, bus_error_callback, NULL); gst_bus_enable_sync_message_emission (bus); g_signal_connect (bus, "sync-message::error", G_CALLBACK (sync_error_handler), NULL); gst_object_unref (bus); st = fs_transmitter_new_stream_transmitter (trans, NULL, n_parameters, params, &error); if (error) { if (has_stun && error->domain == FS_ERROR && error->code == FS_ERROR_NETWORK && error->message && strstr (error->message, "unreachable")) { GST_WARNING ("Skipping stunserver test, we have no network"); goto skip; } else ts_fail ("Error creating stream transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL"); g_object_set (st, "sending", !(flags & FLAG_NOT_SENDING), NULL); ts_fail_unless (g_signal_connect (st, "new-local-candidate", G_CALLBACK (_new_local_candidate), GINT_TO_POINTER (flags)), "Could not connect new-local-candidate signal"); ts_fail_unless (g_signal_connect (st, "local-candidates-prepared", G_CALLBACK (_local_candidates_prepared), GINT_TO_POINTER (flags)), "Could not connect local-candidates-prepared signal"); ts_fail_unless (g_signal_connect (st, "new-active-candidate-pair", G_CALLBACK (_new_active_candidate_pair), trans), "Could not connect new-active-candidate-pair signal"); ts_fail_unless (g_signal_connect (st, "error", G_CALLBACK (stream_transmitter_error), NULL), "Could not connect error signal"); ts_fail_unless (g_signal_connect (st, "known-source-packet-received", G_CALLBACK (_known_source_packet_received), NULL), "Could not connect known-source-packet-received signal"); ts_fail_if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE, "Could not set the pipeline to playing"); if (!fs_stream_transmitter_gather_local_candidates (st, &error)) { if (error) { ts_fail ("Could not start gathering local candidates (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } else ts_fail ("Could not start gathering candidates" " (without a specified error)"); } g_idle_add (check_running, NULL); g_main_loop_run (loop); skip: g_mutex_lock (&pipeline_mod_mutex); pipeline_done = TRUE; g_mutex_unlock (&pipeline_mod_mutex); gst_element_set_state (pipeline, GST_STATE_NULL); if (st) { fs_stream_transmitter_stop (st); g_object_unref (st); } g_object_unref (trans); gst_object_unref (pipeline); g_main_loop_unref (loop); }
static gboolean _bus_callback (GstBus *bus, GstMessage *message, gpointer user_data) { struct SimpleTestConference *dat = user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT: { const GstStructure *s = gst_message_get_structure (message); ts_fail_if (s==NULL, "NULL structure in element message"); if (gst_structure_has_name (s, "farsight-error")) { const GValue *value; FsError errorno; const gchar *error, *debug; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farsight-error from non-farsight element"); ts_fail_unless ( gst_structure_has_field_typed (s, "src-object", G_TYPE_OBJECT), "farsight-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-no", FS_TYPE_ERROR), "farsight-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-msg", G_TYPE_STRING), "farsight-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "debug-msg", G_TYPE_STRING), "farsight-error structure has no src-object field"); value = gst_structure_get_value (s, "error-no"); errorno = g_value_get_enum (value); error = gst_structure_get_string (s, "error-msg"); debug = gst_structure_get_string (s, "debug-msg"); ts_fail ("Error on BUS (%d) %s .. %s", errorno, error, debug); } else if (gst_structure_has_name (s, "farsight-new-local-candidate")) { FsStream *stream; FsCandidate *candidate; const GValue *value; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farsight-error from non-farsight element"); ts_fail_unless ( gst_structure_has_field_typed (s, "stream", FS_TYPE_STREAM), "farsight-new-local-candidate structure has no stream field"); ts_fail_unless ( gst_structure_has_field_typed (s, "candidate", FS_TYPE_CANDIDATE), "farsight-new-local-candidate structure has no candidate field"); value = gst_structure_get_value (s, "stream"); stream = g_value_get_object (value); value = gst_structure_get_value (s, "candidate"); candidate = g_value_get_boxed (value); ts_fail_unless (stream && candidate, "new-local-candidate with NULL" " stream(%p) or candidate(%p)", stream, candidate); _new_local_candidate (stream, candidate); } else if (gst_structure_has_name (s, "farsight-new-active-candidate-pair")) { FsStream *stream; FsCandidate *local_candidate, *remote_candidate; const GValue *value; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farsight-error from non-farsight element"); ts_fail_unless ( gst_structure_has_field_typed (s, "stream", FS_TYPE_STREAM), "farsight-new-active-candidate-pair structure" " has no stream field"); ts_fail_unless ( gst_structure_has_field_typed (s, "local-candidate", FS_TYPE_CANDIDATE), "farsight-new-active-candidate-pair structure" " has no local-candidate field"); ts_fail_unless ( gst_structure_has_field_typed (s, "remote-candidate", FS_TYPE_CANDIDATE), "farsight-new-active-candidate-pair structure" " has no remote-candidate field"); value = gst_structure_get_value (s, "stream"); stream = g_value_get_object (value); value = gst_structure_get_value (s, "local-candidate"); local_candidate = g_value_get_boxed (value); value = gst_structure_get_value (s, "remote-candidate"); remote_candidate = g_value_get_boxed (value); ts_fail_unless (stream && local_candidate && remote_candidate, "new-local-candidate with NULL stream(%p)" " or local_candidate(%p) or remote_candidate(%p)", stream, local_candidate, remote_candidate); } else if (gst_structure_has_name (s, "farsight-current-send-codec-changed")) { FsSession *session; FsCodec *codec; const GValue *value; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farsight-error from non-farsight element"); ts_fail_unless ( gst_structure_has_field_typed (s, "session", FS_TYPE_SESSION), "farsight-current-send-codec-changed structure" " has no session field"); ts_fail_unless ( gst_structure_has_field_typed (s, "codec", FS_TYPE_CODEC), ""); value = gst_structure_get_value (s, "session"); session = g_value_get_object (value); value = gst_structure_get_value (s, "codec"); codec = g_value_get_boxed (value); ts_fail_unless (session && codec, "current-send-codec-changed with NULL session(%p) or codec(%p)", session, codec); _current_send_codec_changed (session, codec); } } break; case GST_MESSAGE_ERROR: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_error (message, &error, &debug); ts_fail ("Got an error on the BUS (%d): %s (%s)", error->code, error->message, debug); g_error_free (error); g_free (debug); } break; case GST_MESSAGE_WARNING: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_warning (message, &error, &debug); g_debug ("%d: Got a warning on the BUS (%d): %s (%s)", dat->id, error->code, error->message, debug); g_error_free (error); g_free (debug); } break; default: break; } return TRUE; }
static void _new_local_candidate (FsStreamTransmitter *st, FsCandidate *candidate, gpointer user_data) { gboolean is_local = GPOINTER_TO_INT (user_data) & FLAG_IS_LOCAL; GError *error = NULL; GList *item = NULL; gboolean ret; GST_DEBUG ("Has local candidate %s:%u of type %d", candidate->ip, candidate->port, candidate->type); ts_fail_if (candidate == NULL, "Passed NULL candidate"); ts_fail_unless (candidate->ip != NULL, "Null IP in candidate"); ts_fail_if (candidate->port == 0, "Candidate has port 0"); ts_fail_unless (candidate->proto == FS_NETWORK_PROTOCOL_UDP, "Protocol is not UDP"); if (has_stun) ts_fail_unless (candidate->type == FS_CANDIDATE_TYPE_SRFLX, "Has stun, but candidate is not server reflexive," " it is: %s:%u of type %d on component %u", candidate->ip, candidate->port, candidate->type, candidate->component_id); else { ts_fail_unless (candidate->type == FS_CANDIDATE_TYPE_HOST, "Does not have stun, but candidate is not host"); if (candidate->component_id == FS_COMPONENT_RTP) { ts_fail_unless (candidate->port % 2 == 0, "RTP port should be odd"); } else if (candidate->component_id == FS_COMPONENT_RTCP) { ts_fail_unless (candidate->port % 2 == 1, "RTCP port should be event"); } } if (is_local) { ts_fail_unless (!strcmp (candidate->ip, "127.0.0.1"), "IP is wrong, it is %s but should be 127.0.0.1 when local candidate set", candidate->ip); if (candidate->component_id == FS_COMPONENT_RTP) { ts_fail_unless (candidate->port >= RTP_PORT , "RTP port invalid"); } else if (candidate->component_id == FS_COMPONENT_RTCP) { ts_fail_unless (candidate->port >= RTCP_PORT, "RTCP port invalid"); } } candidates[candidate->component_id-1] = 1; GST_DEBUG ("New local candidate %s:%d of type %d for component %d", candidate->ip, candidate->port, candidate->type, candidate->component_id); item = g_list_prepend (NULL, candidate); ret = fs_stream_transmitter_force_remote_candidates (st, item, &error); g_list_free (item); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); }
static void run_nice_transmitter_test (gint n_parameters, GParameter *params, gint flags) { GError *error = NULL; FsTransmitter *trans = NULL, *trans2 = NULL; FsStreamTransmitter *st = NULL, *st2 = NULL; GstBus *bus = NULL; GstElement *pipeline = NULL; GstElement *pipeline2 = NULL; FsNiceTestParticipant *p1 = NULL, *p2 = NULL; memset (buffer_count, 0, sizeof(gint)*4); memset (received_known, 0, sizeof(guint)*4); running = TRUE; associate_on_source = !(flags & FLAG_NO_SOURCE); is_address_local = (flags & FLAG_IS_LOCAL); force_candidates = (flags & FLAG_FORCE_CANDIDATES); if (flags & FLAG_RECVONLY_FILTER) ts_fail_unless (fs_fake_filter_register ()); if (flags & FLAG_NOT_SENDING) { buffer_count[0][0] = 20; received_known[0][0] = 20; buffer_count[1][0] = 20; received_known[1][0] = 20; } loop = g_main_loop_new (NULL, FALSE); trans = fs_transmitter_new ("nice", 2, 0, &error); if (error) { ts_fail ("Error creating transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL"); if (flags & FLAG_RECVONLY_FILTER) ts_fail_unless (g_signal_connect (trans, "get-recvonly-filter", G_CALLBACK (_get_recvonly_filter), NULL)); trans2 = fs_transmitter_new ("nice", 2, 0, &error); if (error) { ts_fail ("Error creating transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (trans2 == NULL, "No transmitter create, yet error is still NULL"); if (flags & FLAG_RECVONLY_FILTER) ts_fail_unless (g_signal_connect (trans2, "get-recvonly-filter", G_CALLBACK (_get_recvonly_filter), NULL)); pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler1)); pipeline2 = setup_pipeline (trans2, G_CALLBACK (_handoff_handler2)); g_object_set_data (G_OBJECT (trans), "pipeline", pipeline); g_object_set_data (G_OBJECT (trans2), "pipeline", pipeline2); bus = gst_element_get_bus (pipeline); gst_bus_add_watch (bus, bus_error_callback, NULL); gst_object_unref (bus); bus = gst_element_get_bus (pipeline2); gst_bus_add_watch (bus, bus_error_callback, NULL); gst_object_unref (bus); /* * I'm passing the participant because any gobject will work, * but it should be the participant */ p1 = g_object_new (fs_nice_test_participant_get_type (), NULL); p2 = g_object_new (fs_nice_test_participant_get_type (), NULL); st = fs_transmitter_new_stream_transmitter (trans, FS_PARTICIPANT (p1), n_parameters, params, &error); if (error) ts_fail ("Error creating stream transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL"); st2 = fs_transmitter_new_stream_transmitter (trans2, FS_PARTICIPANT (p2), n_parameters, params, &error); if (error) ts_fail ("Error creating stream transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_if (st2 == NULL, "No stream transmitter created, yet error is NULL"); g_object_set (st, "sending", !(flags & FLAG_NOT_SENDING), NULL); g_object_set (st2, "sending", !(flags & FLAG_NOT_SENDING), NULL); ts_fail_unless (g_signal_connect (st, "new-local-candidate", G_CALLBACK (_new_local_candidate), st2), "Could not connect new-local-candidate signal"); ts_fail_unless (g_signal_connect (st, "local-candidates-prepared", G_CALLBACK (_local_candidates_prepared), st2), "Could not connect local-candidates-prepared signal"); ts_fail_unless (g_signal_connect (st, "new-active-candidate-pair", G_CALLBACK (_new_active_candidate_pair), trans), "Could not connect new-active-candidate-pair signal"); ts_fail_unless (g_signal_connect (st, "error", G_CALLBACK (stream_transmitter_error), NULL), "Could not connect error signal"); ts_fail_unless (g_signal_connect (st, "state-changed", G_CALLBACK (_stream_state_changed), trans), "Could not connect to state-changed signal"); ts_fail_unless (g_signal_connect (st, "known-source-packet-received", G_CALLBACK (_known_source_packet_received), GUINT_TO_POINTER (1)), "Could not connect to known-source-packet-received signal"); ts_fail_unless (g_signal_connect (st2, "new-local-candidate", G_CALLBACK (_new_local_candidate), st), "Could not connect new-local-candidate signal"); ts_fail_unless (g_signal_connect (st2, "local-candidates-prepared", G_CALLBACK (_local_candidates_prepared), st), "Could not connect local-candidates-prepared signal"); ts_fail_unless (g_signal_connect (st2, "new-active-candidate-pair", G_CALLBACK (_new_active_candidate_pair), trans2), "Could not connect new-active-candidate-pair signal"); ts_fail_unless (g_signal_connect (st2, "error", G_CALLBACK (stream_transmitter_error), NULL), "Could not connect error signal"); ts_fail_unless (g_signal_connect (st2, "state-changed", G_CALLBACK (_stream_state_changed), trans2), "Could not connect to state-changed signal"); ts_fail_unless (g_signal_connect (st2, "known-source-packet-received", G_CALLBACK (_known_source_packet_received), GUINT_TO_POINTER (2)), "Could not connect to known-source-packet-received signal"); ts_fail_if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE, "Could not set the pipeline to playing"); ts_fail_if (gst_element_set_state (pipeline2, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE, "Could not set the pipeline to playing"); if (!fs_stream_transmitter_gather_local_candidates (st, &error)) { if (error) ts_fail ("Could not start gathering local candidates %s", error->message); else ts_fail ("Could not start gathering candidates" " (without a specified error)"); } if (!fs_stream_transmitter_gather_local_candidates (st2, &error)) { if (error) ts_fail ("Could not start gathering local candidates %s", error->message); else ts_fail ("Could not start gathering candidates" " (without a specified error)"); } g_idle_add (check_running, NULL); g_main_loop_run (loop); fs_stream_transmitter_stop (st); fs_stream_transmitter_stop (st2); gst_element_set_state (pipeline, GST_STATE_NULL); gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); gst_element_set_state (pipeline2, GST_STATE_NULL); gst_element_get_state (pipeline2, NULL, NULL, GST_CLOCK_TIME_NONE); if (st) g_object_unref (st); if (st2) g_object_unref (st2); g_object_unref (trans); g_object_unref (trans2); g_object_unref (p1); g_object_unref (p2); gst_object_unref (pipeline); g_main_loop_unref (loop); }
static void run_multicast_transmitter_test (gint n_parameters, GParameter *params) { GError *error = NULL; FsTransmitter *trans; FsStreamTransmitter *st; FsCandidate *tmpcand = NULL; GList *candidates = NULL; GstBus *bus = NULL; loop = g_main_loop_new (NULL, FALSE); trans = fs_transmitter_new ("multicast", 2, &error); if (error) { ts_fail ("Error creating transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL"); pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler)); st = fs_transmitter_new_stream_transmitter (trans, NULL, n_parameters, params, &error); if (error) { ts_fail ("Error creating stream transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL"); bus = gst_element_get_bus (pipeline); gst_bus_add_watch (bus, bus_error_callback, NULL); gst_object_unref (bus); ts_fail_unless (g_signal_connect (st, "new-active-candidate-pair", G_CALLBACK (_new_active_candidate_pair), trans), "Coult not connect new-active-candidate-pair signal"); ts_fail_unless (g_signal_connect (st, "error", G_CALLBACK (stream_transmitter_error), NULL), "Could not connect error signal"); g_idle_add (_start_pipeline, pipeline); tmpcand = fs_candidate_new ("L1", FS_COMPONENT_RTP, FS_CANDIDATE_TYPE_MULTICAST, FS_NETWORK_PROTOCOL_UDP, "224.0.0.110", 2322); tmpcand->ttl = 1; candidates = g_list_prepend (candidates, tmpcand); tmpcand = fs_candidate_new ("L2", FS_COMPONENT_RTCP, FS_CANDIDATE_TYPE_MULTICAST, FS_NETWORK_PROTOCOL_UDP, "224.0.0.110", 2323); tmpcand->ttl = 1; candidates = g_list_prepend (candidates, tmpcand); if (!fs_stream_transmitter_set_remote_candidates (st, candidates, &error)) ts_fail ("Error setting the remote candidates: %p %s", error, error ? error->message : "NO ERROR SET"); ts_fail_unless (error == NULL, "Error is not null after successful candidate" " addition"); fs_candidate_list_destroy (candidates); g_main_run (loop); g_object_unref (st); g_object_unref (trans); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); g_main_loop_unref (loop); }
static void one_way (GCallback havedata_handler, gpointer data) { FsParticipant *participant = NULL; GError *error = NULL; gint port = 0; GstElement *recv_pipeline; GList *candidates = NULL; GstBus *bus = NULL; dtmf_id = 105; digit = 0; sending = FALSE; received = FALSE; ready_to_send = FALSE; loop = g_main_loop_new (NULL, FALSE); dat = setup_simple_conference (1, "fsrtpconference", "tester@123445"); bus = gst_element_get_bus (dat->pipeline); gst_bus_add_watch (bus, _bus_callback, dat); gst_object_unref (bus); g_idle_add (_start_pipeline, dat); participant = fs_conference_new_participant ( FS_CONFERENCE (dat->conference), "*****@*****.**", &error); if (error) ts_fail ("Error while creating new participant (%d): %s", error->code, error->message); ts_fail_if (dat->session == NULL, "Could not make participant, but no GError!"); stream = fs_session_new_stream (dat->session, participant, FS_DIRECTION_SEND, "rawudp", 0, NULL, &error); if (error) ts_fail ("Error while creating new stream (%d): %s", error->code, error->message); ts_fail_if (stream == NULL, "Could not make stream, but no GError!"); recv_pipeline = build_recv_pipeline (havedata_handler, NULL, &port); GST_DEBUG ("port is %d", port); candidates = g_list_prepend (NULL, fs_candidate_new ("1", FS_COMPONENT_RTP, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "127.0.0.1", port)); ts_fail_unless (fs_stream_set_remote_candidates (stream, candidates, &error), "Could not set remote candidate"); fs_candidate_list_destroy (candidates); set_codecs (dat, stream); setup_fakesrc (dat); g_main_loop_run (loop); gst_element_set_state (dat->pipeline, GST_STATE_NULL); gst_element_set_state (recv_pipeline, GST_STATE_NULL); cleanup_simple_conference (dat); gst_object_unref (recv_pipeline); g_main_loop_unref (loop); }
static void _handoff_handler (GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer user_data) { struct SimpleTestStream *st = user_data; int i; gboolean stop = TRUE; GList *codecs = NULL; if (st->dat->session == NULL) return; g_object_get (st->dat->session, "codecs", &codecs, NULL); ts_fail_if (codecs == NULL, "Could not get codecs"); if (st->flags & WAITING_ON_LAST_CODEC) { if (fs_codec_are_equal ( g_list_last (codecs)->data, g_object_get_data (G_OBJECT (element), "codec"))) { st->flags &= ~WAITING_ON_LAST_CODEC; st->flags |= SHOULD_BE_LAST_CODEC; max_buffer_count += st->buffer_count; GST_DEBUG ("We HAVE last codec"); } else { #if 0 gchar *str = fs_codec_to_string ( g_object_get_data (G_OBJECT (element), "codec")); gchar *str2 = fs_codec_to_string (g_list_last (codecs)->data); GST_DEBUG ("not yet the last codec, skipping (we have %s, we want %s)", str, str2); g_free (str); g_free (str2); #endif fs_codec_list_destroy (codecs); return; } } if (select_last_codec || st->flags & SHOULD_BE_LAST_CODEC) { if (!fs_codec_are_equal ( g_list_last (codecs)->data, g_object_get_data (G_OBJECT (element), "codec"))) { if (!reset_to_last_codec) ts_fail ("The handoff handler got a buffer from the wrong codec" " (ie. not the last)"); fs_codec_list_destroy (codecs); return; } } else ts_fail_unless ( fs_codec_are_equal ( g_list_first (codecs)->data, g_object_get_data (G_OBJECT (element), "codec")), "The handoff handler got a buffer from the wrong codec"); fs_codec_list_destroy (codecs); st->buffer_count++; GST_LOG ("%d:%d: Buffer %d", st->dat->id, st->target->id, st->buffer_count); /* ts_fail_if (dat->buffer_count > max_buffer_count, "Too many buffers %d > max_buffer_count", dat->buffer_count); */ for (i = 0; i < count && !stop ; i++) { GList *item; for (item = g_list_first (dats[i]->streams); item; item = g_list_next (item)) { struct SimpleTestStream *st2 = item->data; if (st2->buffer_count < max_buffer_count) { stop = FALSE; break; } } } if (stop) { if (reset_to_last_codec && !(st->flags & HAS_BEEN_RESET)) { GError *error = NULL; GList *nego_codecs = NULL; gchar *str = NULL; g_object_get (st->target->session, "codecs", &nego_codecs, NULL); ts_fail_if (nego_codecs == NULL, "No codecs"); ts_fail_if (g_list_length (nego_codecs) < 2, "Only one negotiated codec"); str = fs_codec_to_string (g_list_last (nego_codecs)->data); GST_DEBUG ("Setting codec to: %s", str); g_free (str); ts_fail_unless (fs_session_set_send_codec (st->target->session, g_list_last (nego_codecs)->data, &error), "Could not set the send codec: %s", error ? error->message : "NO GError!!!"); g_clear_error (&error); fs_codec_list_destroy (nego_codecs); st->flags |= HAS_BEEN_RESET | WAITING_ON_LAST_CODEC; GST_DEBUG ("RESET TO LAST CODEC"); } else { g_main_loop_quit (loop); } } }
static gboolean set_the_candidates (gpointer user_data) { FsStreamTransmitter *st = FS_STREAM_TRANSMITTER (user_data); GList *candidates = g_object_get_data (G_OBJECT (st), "candidates-set"); gboolean ret; GError *error = NULL; if (!candidates) { g_debug ("Skipping libnice check because it found NO local candidates"); g_atomic_int_set(&running, FALSE); g_main_loop_quit (loop); return FALSE; } if (force_candidates) { GList *item = NULL; GList *next = NULL; GList *new_list = NULL; for (item = candidates; item; item = next) { FsCandidate *cand = item->data; GList *item2 = NULL; next = g_list_next (item); if (cand->type != FS_CANDIDATE_TYPE_HOST) continue; if (cand->component_id != 1) continue; for (item2 = candidates; item2; item2 = g_list_next (item2)) { FsCandidate *cand2 = item2->data; if (cand2->component_id == 2 && !strcmp (cand->foundation, cand2->foundation)) { new_list = g_list_append (new_list, cand); new_list = g_list_append (new_list, cand2); goto got_candidates; } } } ts_fail ("Could not find two matching host candidates???"); got_candidates: ts_fail_unless (g_list_length (new_list) == 2); ret = fs_stream_transmitter_force_remote_candidates (st, new_list, &error); } else { ret = fs_stream_transmitter_add_remote_candidates (st, candidates, &error); } if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error setting remote_candidate"); fs_candidate_list_destroy (candidates); return FALSE; }
static gboolean _bus_callback (GstBus *bus, GstMessage *message, gpointer user_data) { struct SimpleTestConference *dat = user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT: { const GstStructure *s = gst_message_get_structure (message); if (gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE) && gst_structure_has_name (s, "farsight-error")) { const GValue *value; FsError errorno; const gchar *error, *debug; GEnumClass *enumclass = NULL; GEnumValue *enumvalue = NULL; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farsight-error from non-farsight element"); ts_fail_unless ( gst_structure_has_field_typed (s, "src-object", G_TYPE_OBJECT), "farsight-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-no", FS_TYPE_ERROR), "farsight-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-msg", G_TYPE_STRING), "farsight-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "debug-msg", G_TYPE_STRING), "farsight-error structure has no src-object field"); value = gst_structure_get_value (s, "error-no"); errorno = g_value_get_enum (value); error = gst_structure_get_string (s, "error-msg"); debug = gst_structure_get_string (s, "debug-msg"); enumclass = g_type_class_ref (FS_TYPE_ERROR); enumvalue = g_enum_get_value (enumclass, errorno); ts_fail ("Error on BUS %s (%d, %s) %s .. %s", enumvalue->value_name, errorno, enumvalue->value_nick, error, debug); g_type_class_unref (enumclass); } else if (gst_structure_has_name (s, "farsight-send-codec-changed")) { ready_to_send = TRUE; } } break; case GST_MESSAGE_ERROR: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_error (message, &error, &debug); ts_fail ("Got an error on the BUS (%d): %s (%s)", error->code, error->message, debug); g_error_free (error); g_free (debug); } break; case GST_MESSAGE_WARNING: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_warning (message, &error, &debug); GST_WARNING ("%d: Got a warning on the BUS (%d): %s (%s)", dat->id, error->code, error->message, debug); g_error_free (error); g_free (debug); } break; default: break; } return TRUE; }
static gboolean bus_watch (GstBus *bus, GstMessage *message, gpointer user_data) { struct SimpleMsnConference *dat = user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT: { const GstStructure *s = gst_message_get_structure (message); ts_fail_if (s==NULL, "NULL structure in element message"); if (gst_structure_has_name (s, "farstream-error")) { const GValue *value; FsError errorno; const gchar *error; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farstream-error from non-farstream element"); ts_fail_unless ( gst_structure_has_field_typed (s, "src-object", G_TYPE_OBJECT), "farstream-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-no", FS_TYPE_ERROR), "farstream-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-msg", G_TYPE_STRING), "farstream-error structure has no src-object field"); value = gst_structure_get_value (s, "error-no"); errorno = g_value_get_enum (value); error = gst_structure_get_string (s, "error-msg"); ts_fail ("Error on BUS (%d) %s", errorno, error); } else if (gst_structure_has_name (s, "farstream-new-local-candidate")) { FsStream *stream; FsCandidate *candidate; const GValue *value; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farstream-error from non-farstream element"); ts_fail_unless ( gst_structure_has_field_typed (s, "stream", FS_TYPE_STREAM), "farstream-new-local-candidate structure has no stream field"); ts_fail_unless ( gst_structure_has_field_typed (s, "candidate", FS_TYPE_CANDIDATE), "farstream-new-local-candidate structure has no candidate field"); value = gst_structure_get_value (s, "stream"); stream = g_value_get_object (value); value = gst_structure_get_value (s, "candidate"); candidate = g_value_get_boxed (value); ts_fail_unless (stream && candidate, "new-local-candidate with NULL" " stream(%p) or candidate(%p)", stream, candidate); if (dat->target) { GError *error = NULL; GList *list = g_list_append (NULL, candidate); gboolean add_remote_candidates_res; GST_DEBUG ("Setting candidate: %s %d", candidate->ip, candidate->port); add_remote_candidates_res = fs_stream_add_remote_candidates ( dat->target->stream, list, &error); ts_fail_unless (add_remote_candidates_res, "Could not set remote candidate: %s", error ? error->message : "No GError"); ts_fail_unless (error == NULL); g_list_free (list); } } } break; case GST_MESSAGE_ERROR: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_error (message, &error, &debug); ts_fail ("Got an error on the BUS (%d): %s (%s)", error->code, error->message, debug); g_error_free (error); g_free (debug); } break; case GST_MESSAGE_WARNING: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_warning (message, &error, &debug); GST_DEBUG ("%d: Got a warning on the BUS: %s (%s)", error->code, error->message, debug); g_error_free (error); g_free (debug); } break; default: break; } return TRUE; }