static void call_content_setup_jingle (GabbleCallContent *self, GabbleCallMemberContent *mcontent) { TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self); GabbleJingleContent *jingle; GabbleCallStream *stream; gchar *path; JingleTransportType transport; JingleMediaDescription *md; GHashTable *tp_md; TpHandle contact; jingle = gabble_call_member_content_get_jingle_content (mcontent); if (jingle == NULL) return; transport = gabble_jingle_content_get_transport_type (jingle); path = g_strdup_printf ("%s/Stream%p", tp_base_call_content_get_object_path (base), jingle); stream = g_object_new (GABBLE_TYPE_CALL_STREAM, "object-path", path, "connection", tp_base_call_content_get_connection (base), "jingle-content", jingle, "transport", _jingle_to_tp_transport (transport), NULL); g_free (path); md = jingle_media_description_new (); /* FIXME: correct??? */ contact = gabble_call_member_get_handle ( gabble_call_member_content_get_member (mcontent)); tp_md = tp_base_media_call_content_get_local_media_description ( TP_BASE_MEDIA_CALL_CONTENT (self), contact); if (tp_md != NULL) { md->codecs = codec_array_to_list (tp_asv_get_boxed (tp_md, TP_PROP_CALL_CONTENT_MEDIA_DESCRIPTION_CODECS, TP_ARRAY_TYPE_CODEC_LIST)); } if (md->codecs != NULL) jingle_media_rtp_set_local_media_description ( GABBLE_JINGLE_MEDIA_RTP (jingle), md, TRUE, NULL); else jingle_media_description_free (md); tp_base_call_content_add_stream (base, TP_BASE_CALL_STREAM (stream)); gabble_call_stream_update_member_states (stream); g_object_unref (stream); }
static void media_remote_codecs_updated_cb (RakiaSipMedia *media, gboolean is_offer, RakiaCallContent *self) { TpBaseCallContent *bcc = TP_BASE_CALL_CONTENT (self); TpBaseMediaCallContent *bmcc = TP_BASE_MEDIA_CALL_CONTENT (self); RakiaCallContentPrivate *priv = self->priv; GPtrArray *remote_codecs = rakia_sip_media_get_remote_codec_offer (priv->media); TpCallContentMediaDescription *md; TpDBusDaemon *bus = tp_base_connection_get_dbus_daemon ( tp_base_call_content_get_connection (bcc)); gchar *object_path; guint i, j; if (remote_codecs == NULL) return; object_path = g_strdup_printf ("%s/Offer%u", tp_base_call_content_get_object_path (bcc), ++priv->codec_offer_id); md = tp_call_content_media_description_new (bus, object_path, tp_base_channel_get_target_handle (TP_BASE_CHANNEL (priv->channel)), TRUE, is_offer); g_free (object_path); for (i = 0; i < remote_codecs->len; i++) { RakiaSipCodec *codec = g_ptr_array_index (remote_codecs, i); GHashTable *parameters = g_hash_table_new (g_str_hash, g_str_equal); /* No need to copy the values as .._append_codec() will */ if (codec->params) for (j = 0; j < codec->params->len; j++) { RakiaSipCodecParam *param = g_ptr_array_index (codec->params, j); g_hash_table_insert (parameters, param->name, param->value); } tp_call_content_media_description_append_codec (md, codec->id, codec->encoding_name, codec->clock_rate, codec->channels, TRUE, parameters); g_hash_table_unref (parameters); } tp_base_media_call_content_offer_media_description_async (bmcc, md, md_offer_cb, GUINT_TO_POINTER (FALSE)); g_object_unref (md); }
void gabble_call_content_new_offer (GabbleCallContent *self, GabbleCallMemberContent *content) { GabbleCallContentPrivate *priv = self->priv; TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self); TpBaseConnection *conn = tp_base_call_content_get_connection (base); TpCallContentMediaDescription *md; gchar *path; TpHandle handle = 0; path = g_strdup_printf ("%s/Offer%d", tp_base_call_content_get_object_path (base), priv->offers++); if (content != NULL) { handle = gabble_call_member_get_handle ( gabble_call_member_content_get_member (content)); } /* FIXME: no idea... */ md = tp_call_content_media_description_new ( tp_base_connection_get_dbus_daemon (conn), path, handle, (content != NULL), (content == NULL)); if (content != NULL) { GList *codecs, *l; codecs = gabble_call_member_content_get_remote_codecs (content); for (l = codecs; l != NULL; l = g_list_next (l)) { JingleCodec *c = l->data; tp_call_content_media_description_append_codec (md, c->id, c->name, c->clockrate, c->channels, FALSE, /* FIXME: updated?? */ c->params); } } /* FIXME: We have to handle cases where the new codecs are rejected */ tp_base_media_call_content_offer_media_description_async ( TP_BASE_MEDIA_CALL_CONTENT (self), md, NULL, NULL); g_object_unref (md); g_free (path); }
static void rakia_call_content_constructed (GObject *object) { RakiaCallContent *self = RAKIA_CALL_CONTENT (object); RakiaCallContentPrivate *priv = self->priv; TpBaseChannel *bchan = TP_BASE_CHANNEL (priv->channel); TpBaseCallContent *bcc = TP_BASE_CALL_CONTENT (self); TpBaseMediaCallContent *bmcc = TP_BASE_MEDIA_CALL_CONTENT (self); TpHandle creator; gchar *object_path; g_signal_connect_object (priv->media, "remote-codec-offer-updated", G_CALLBACK (media_remote_codecs_updated_cb), self, 0); g_signal_connect (self, "local-media-description-updated", G_CALLBACK (local_media_description_updated), NULL); g_object_get (object, "creator", &creator, NULL); if (creator == tp_base_channel_get_self_handle (bchan)) { TpCallContentMediaDescription *md; TpDBusDaemon *bus = tp_base_connection_get_dbus_daemon ( tp_base_call_content_get_connection (bcc)); object_path = g_strdup_printf ("%s/InitialOffer", tp_base_call_content_get_object_path (bcc)); md = tp_call_content_media_description_new (bus, object_path, tp_base_channel_get_target_handle (bchan), FALSE, TRUE); g_free (object_path); tp_base_media_call_content_offer_media_description_async (bmcc, md, md_offer_cb, GUINT_TO_POINTER (TRUE)); } else { media_remote_codecs_updated_cb (priv->media, TRUE, self); } G_OBJECT_CLASS (rakia_call_content_parent_class)->constructed (object); }
static void md_offer_cb (GObject *obj, GAsyncResult *res, gpointer user_data) { RakiaCallContent *self = RAKIA_CALL_CONTENT (obj); RakiaCallContentPrivate *priv = self->priv; TpBaseMediaCallContent *bmcc = TP_BASE_MEDIA_CALL_CONTENT (self); GError *error = NULL; gboolean is_initial_offer = GPOINTER_TO_UINT (user_data); if (tp_base_media_call_content_offer_media_description_finish (bmcc, res, &error)) { GHashTable *local_md = tp_base_media_call_content_get_local_media_description (bmcc, tp_base_channel_get_target_handle (TP_BASE_CHANNEL (priv->channel))); set_telepathy_codecs (self, local_md); } else { /* Only reject if the codecs where rejected */ if (error->domain == TP_ERROR && error->code == TP_ERROR_MEDIA_CODECS_INCOMPATIBLE) { g_assert (!is_initial_offer); rakia_sip_media_codecs_rejected (priv->media); DEBUG ("Codecs rejected: %s", error->message); } /* FIXME: We need to allow for partial failures */ g_clear_error (&error); } }