static void member_content_removed_cb (GabbleCallMemberContent *mcontent, gpointer user_data) { GabbleCallContent *self = GABBLE_CALL_CONTENT (user_data); GabbleCallContentPrivate *priv = self->priv; TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self); GabbleJingleContent *content; GList *l; priv->contents = g_list_remove (priv->contents, mcontent); content = gabble_call_member_content_get_jingle_content (mcontent); for (l = tp_base_call_content_get_streams (base); l != NULL; l = l->next) { GabbleCallStream *stream = GABBLE_CALL_STREAM (l->data); if (content == gabble_call_stream_get_jingle_content (stream)) { tp_base_call_content_remove_stream (base, l->data, 0, TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", ""); break; } } }
static void new_content (RakiaCallChannel *self, const gchar *name, RakiaSipMedia *media, TpCallContentDisposition disposition) { TpBaseChannel *bchan = TP_BASE_CHANNEL (self); RakiaCallContent *content; TpMediaStreamType media_type; TpHandle creator; gchar *object_path; gchar *free_name = NULL; const gchar *media_type_name; switch (rakia_sip_media_get_media_type (media)) { case TP_MEDIA_STREAM_TYPE_AUDIO: media_type = TP_MEDIA_STREAM_TYPE_AUDIO; media_type_name = "Audio"; break; case TP_MEDIA_STREAM_TYPE_VIDEO: media_type = TP_MEDIA_STREAM_TYPE_VIDEO; media_type_name = "Video"; break; default: g_assert_not_reached (); } if (rakia_sip_media_is_created_locally (media)) creator = tp_base_channel_get_self_handle (bchan); else creator = tp_base_channel_get_target_handle (bchan); object_path = g_strdup_printf ("%s/Content%u", tp_base_channel_get_object_path (bchan), ++self->priv->last_content_no); if (name == NULL) name = free_name = g_strdup_printf ("%s %u", media_type_name, self->priv->last_content_no); /* We already request bidi for initial media, * the client can change it before accepting. */ if (disposition == TP_CALL_CONTENT_DISPOSITION_INITIAL) rakia_sip_media_set_requested_direction (media, TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL); content = rakia_call_content_new (self, media, object_path, tp_base_channel_get_connection (bchan), name, media_type, creator, disposition); g_free (free_name); g_free (object_path); tp_base_call_channel_add_content (TP_BASE_CALL_CHANNEL (self), TP_BASE_CALL_CONTENT (content)); rakia_call_content_add_stream (content); }
JingleMediaType gabble_call_content_get_media_type (GabbleCallContent *self) { TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self); return jingle_media_type_from_tp ( tp_base_call_content_get_media_type (base)); }
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 media_removed_cb (RakiaSipSession *session, RakiaSipMedia *media, RakiaCallChannel *self) { RakiaCallContent *content; content = rakia_call_channel_get_content_by_media (self, media); if (content == NULL) return; tp_base_call_channel_remove_content (TP_BASE_CALL_CHANNEL (self), TP_BASE_CALL_CONTENT (content), tp_base_channel_get_target_handle (TP_BASE_CHANNEL (self)), TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", "Removed by remote side"); }
void rakia_call_content_add_stream (RakiaCallContent *self) { RakiaCallContentPrivate *priv = self->priv; TpBaseCallContent *bcc = TP_BASE_CALL_CONTENT (self); gchar *object_path; object_path = g_strdup_printf ("%s/Stream", tp_base_call_content_get_object_path (bcc)); priv->stream = rakia_call_stream_new (self, priv->media, object_path, TP_STREAM_TRANSPORT_TYPE_RAW_UDP, tp_base_call_content_get_connection (bcc)); g_free (object_path); tp_base_call_content_add_stream (bcc, TP_BASE_CALL_STREAM (priv->stream)); }
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 TpBaseCallContent * rakia_call_channel_add_content ( TpBaseCallChannel *base, const gchar *name, TpMediaStreamType type, TpMediaStreamDirection initial_direction, GError **error) { RakiaCallChannel *self = RAKIA_CALL_CHANNEL (base); RakiaCallChannelPrivate *priv = self->priv; RakiaCallContent *content; RakiaSipMedia *media; media = rakia_sip_session_add_media (priv->session, type, name, initial_direction); content = rakia_call_channel_get_content_by_media (self, media); return TP_BASE_CALL_CONTENT (content); }