[Telepathy-commits] [telepathy-gabble/master] MediaStream code cleanup, support for stream directions
Senko Rasic
senko at phyrexia.lan
Tue Dec 2 04:33:58 PST 2008
---
src/media-stream.c | 753 ++++++++--------------------------------------------
src/media-stream.h | 2 +
2 files changed, 111 insertions(+), 644 deletions(-)
diff --git a/src/media-stream.c b/src/media-stream.c
index 4afb65c..93c7d9e 100644
--- a/src/media-stream.c
+++ b/src/media-stream.c
@@ -149,6 +149,10 @@ static void new_remote_candidates_cb (GabbleJingleContent *content,
GList *clist, GabbleMediaStream *stream);
static void new_remote_codecs_cb (GabbleJingleContent *content,
GList *clist, GabbleMediaStream *stream);
+static void content_state_changed_cb (GabbleJingleContent *c,
+ GParamSpec *pspec, GabbleMediaStream *stream);
+static void content_senders_changed_cb (GabbleJingleContent *c,
+ GParamSpec *pspec, GabbleMediaStream *stream);
static void
gabble_media_stream_init (GabbleMediaStream *self)
@@ -347,10 +351,21 @@ gabble_media_stream_set_property (GObject *object,
g_signal_connect (priv->content, "remote-codecs",
(GCallback) new_remote_codecs_cb, stream);
+ g_signal_connect (priv->content, "notify::state",
+ (GCallback) content_state_changed_cb, stream);
+
+ g_signal_connect (priv->content, "notify::senders",
+ (GCallback) content_senders_changed_cb, stream);
+
/* we can immediately get the codecs if we're responder */
new_remote_codecs_cb (priv->content,
gabble_jingle_media_rtp_get_remote_codecs (GABBLE_JINGLE_MEDIA_RTP (priv->content)),
stream);
+
+ /* if any candidates arrived before idle loop had the chance to excute
+ * us, we don't wan to miss them */
+ new_remote_candidates_cb (priv->content,
+ gabble_jingle_content_get_remote_candidates (priv->content), stream);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -1087,223 +1102,6 @@ gabble_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface,
tp_svc_media_stream_handler_return_from_supported_codecs (context);
}
-#if 0
-static LmHandlerResult
-candidates_msg_reply_cb (GabbleConnection *conn,
- LmMessage *sent_msg,
- LmMessage *reply_msg,
- GObject *object,
- gpointer user_data)
-{
- GabbleMediaStream *stream = GABBLE_MEDIA_STREAM (object);
- GabbleMediaStreamPrivate *priv;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
-
- /* FIXME
- MSG_REPLY_CB_END_SESSION_IF_NOT_SUCCESSFUL (priv->session,
- "candidates failed"); */
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
-}
-#endif
-
-#if 0
-static void
-_add_rtp_candidate_node (GabbleMediaSession *session, LmMessageNode *parent,
- GValueArray *candidate)
-{
- gchar *addr;
- gchar *user;
- gchar *pass;
- gchar *port_str;
- gchar *pref_str;
- gchar *xml;
- const gchar *type_str, *proto_str, *candidate_id;
- guint port;
- gdouble pref;
- TpMediaStreamBaseProto proto;
- TpMediaStreamTransportType type;
- const GPtrArray *transports;
- GValue transport = { 0, };
- LmMessageNode *cand_node;
-
- candidate_id = g_value_get_string (g_value_array_get_nth (candidate, 0));
- transports = g_value_get_boxed (g_value_array_get_nth (candidate, 1));
-
- /* jingle audio only supports the concept of one transport per candidate */
- g_assert (transports->len == 1);
-
- g_value_init (&transport, TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT);
- g_value_set_static_boxed (&transport, g_ptr_array_index (transports, 0));
-
- dbus_g_type_struct_get (&transport,
- 1, &addr,
- 2, &port,
- 3, &proto,
- 6, &pref,
- 7, &type,
- 8, &user,
- 9, &pass,
- G_MAXUINT);
-
- port_str = g_strdup_printf ("%d", port);
- pref_str = g_strdup_printf ("%f", pref);
-
- switch (type) {
- case TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL:
- type_str = "local";
- break;
- case TP_MEDIA_STREAM_TRANSPORT_TYPE_DERIVED:
- type_str = "stun";
- break;
- case TP_MEDIA_STREAM_TRANSPORT_TYPE_RELAY:
- type_str = "relay";
- break;
- default:
- g_warning ("%s: TpMediaStreamTransportType has an invalid value, "
- "ignoring candidate", G_STRFUNC);
- goto out;
- }
-
- switch (proto)
- {
- case TP_MEDIA_STREAM_BASE_PROTO_UDP:
- proto_str = "udp";
- break;
- case TP_MEDIA_STREAM_BASE_PROTO_TCP:
- if (port == 443 && type == TP_MEDIA_STREAM_TRANSPORT_TYPE_RELAY)
- proto_str = "ssltcp";
- else
- proto_str = "tcp";
- break;
- default:
- g_warning ("%s: TpMediaStreamBaseProto has an invalid value, ignoring "
- "candidate", G_STRFUNC);
- goto out;
- }
-
- cand_node = lm_message_node_add_child (parent, "candidate", NULL);
- lm_message_node_set_attributes (cand_node,
- "name", "rtp",
- "address", addr,
- "port", port_str,
- "username", user,
- "password", pass,
- "preference", pref_str,
- "protocol", proto_str,
- "type", type_str,
- "network", "0",
- "generation", "0",
- NULL);
-
- xml = lm_message_node_to_string (cand_node);
- GMS_DEBUG_DUMP (session,
- " from Telepathy D-Bus struct: [%s\"%s\", %s[%s1, \"%s\", %d, %s, "
- "\"%s\", \"%s\", %f, %s, \"%s\", \"%s\"%s]]",
- TP_ANSI_BOLD_OFF, candidate_id, TP_ANSI_BOLD_ON, TP_ANSI_BOLD_OFF,
- addr, port, tp_protocols[proto], "RTP", "AVP", pref, tp_transports[type],
- user, pass, TP_ANSI_BOLD_ON);
- GMS_DEBUG_DUMP (session,
- " to Jingle XML: [%s%s%s]", TP_ANSI_BOLD_OFF, xml, TP_ANSI_BOLD_ON);
- g_free (xml);
-
-out:
- g_free (addr);
- g_free (user);
- g_free (pass);
- g_free (port_str);
- g_free (pref_str);
-}
-#endif
-
-#if 0
-static LmMessage *
-_gabble_media_stream_message_new (GabbleMediaStream *stream,
- const gchar *action,
- LmMessageNode **content_node)
-{
- GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
- LmMessage *msg;
- LmMessageNode *session_node = NULL;
-
- /* construct a session message */
- msg = _gabble_media_session_message_new (priv->session, action,
- &session_node);
-
- /* add our content node to it if necessary */
- *content_node = _gabble_media_stream_add_content_node (stream, session_node);
-
- return msg;
-}
-#endif
-
-#if 0
-static void
-push_candidate (GabbleMediaStream *stream, GValueArray *candidate)
-{
- GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
- LmMessage *msg;
- LmMessageNode *content_node, *transport_node;
- const gchar *action;
-
- if (priv->mode == MODE_GOOGLE)
- action = "candidates";
- else
- action = "transport-info";
-
- /* construct a base message */
- msg = _gabble_media_stream_message_new (stream, action, &content_node);
-
- /* for jingle, add a transport */
- transport_node = _gabble_media_stream_content_node_add_transport (stream,
- content_node);
-
- /* add transport info to it */
- _add_rtp_candidate_node (priv->session, transport_node, candidate);
-
- GMS_DEBUG_INFO (priv->session, "sending jingle session action \"%s\" to "
- "peer", action);
-
- /* send it */
- _gabble_connection_send_with_reply (priv->conn, msg, candidates_msg_reply_cb,
- G_OBJECT (stream), NULL, NULL);
-
- /* clean up */
- lm_message_unref (msg);
-}
-#endif
-
-#if 0
-static void
-push_native_candidates (GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv;
- GPtrArray *candidates;
- guint i;
- GType candidate_list_type =
- TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE_LIST;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
-
- if (stream->signalling_state == STREAM_SIG_STATE_NEW ||
- stream->signalling_state == STREAM_SIG_STATE_REMOVING)
- return;
-
- candidates = g_value_get_boxed (&priv->native_candidates);
-
- for (i = 0; i < candidates->len; i++)
- push_candidate (stream, g_ptr_array_index (candidates, i));
-
- g_value_take_boxed (&priv->native_candidates,
- dbus_g_type_specialized_construct (candidate_list_type));
-}
-#endif
-
void
_gabble_media_stream_close (GabbleMediaStream *stream)
{
@@ -1320,114 +1118,6 @@ _gabble_media_stream_close (GabbleMediaStream *stream)
}
}
-#if 0
-gboolean
-_gabble_media_stream_post_remote_codecs (GabbleMediaStream *stream,
- LmMessage *message,
- LmMessageNode *desc_node,
- GError **error)
-{
- GabbleMediaStreamPrivate *priv;
- LmMessageNode *node;
- GPtrArray *codecs;
- GType codec_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
-
- codecs = g_value_get_boxed (&priv->remote_codecs);
-
- g_assert (codecs->len == 0);
-
- for (node = desc_node->children; node; node = node->next)
- {
- guchar id;
- const gchar *name, *str;
- guint clockrate, channels;
- GHashTable *params;
- GValue codec = { 0, };
-
- if (tp_strdiff (node->name, "payload-type"))
- continue;
-
- /* id of codec */
- str = lm_message_node_get_attribute (node, "id");
- if (str == NULL)
- {
- g_set_error (error, GABBLE_XMPP_ERROR, XMPP_ERROR_BAD_REQUEST,
- "description has no ID");
- return FALSE;
- }
-
- id = atoi (str);
-
- /* codec name */
- name = lm_message_node_get_attribute (node, "name");
- if (name == NULL)
- {
- name = "";
- }
-
- /* clock rate: jingle and newer GTalk */
- str = lm_message_node_get_attribute (node, "clockrate"); /* google */
- if (str == NULL)
- str = lm_message_node_get_attribute (node, "rate"); /* jingle */
-
- if (str != NULL)
- {
- clockrate = atoi (str);
- }
- else
- {
- clockrate = 0;
- }
-
- /* number of channels: jingle only */
- str = lm_message_node_get_attribute (node, "channels");
- if (str != NULL)
- {
- channels = atoi (str);
- }
- else
- {
- channels = 1;
- }
-
- params = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
-
- /* bitrate: newer GTalk only */
- str = lm_message_node_get_attribute (node, "bitrate");
- if (str != NULL)
- {
- g_hash_table_insert (params, "bitrate", g_strdup (str));
- }
-
- g_value_init (&codec, codec_struct_type);
- g_value_take_boxed (&codec,
- dbus_g_type_specialized_construct (codec_struct_type));
-
- dbus_g_type_struct_set (&codec,
- 0, id,
- 1, name,
- 2, priv->media_type,
- 3, clockrate,
- 4, channels,
- 5, params,
- G_MAXUINT);
-
- g_ptr_array_add (codecs, g_value_get_boxed (&codec));
- }
-
- GMS_DEBUG_INFO (priv->session, "put %d remote codecs from peer into cache",
- codecs->len);
-
- push_remote_codecs (stream);
-
- return TRUE;
-}
-#endif
-
static void
new_remote_codecs_cb (GabbleJingleContent *content,
GList *clist, GabbleMediaStream *stream)
@@ -1465,6 +1155,8 @@ new_remote_codecs_cb (GabbleJingleContent *content,
2, priv->media_type,
3, c->clockrate,
4, c->channels,
+ /* FIXME: valgrind shows leak in g_hash_table_new_full - doesn't
+ * dbus-glib free that? */
5, g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free),
G_MAXUINT);
@@ -1571,218 +1263,28 @@ new_remote_candidates_cb (GabbleJingleContent *content,
}
}
-#if 0
-gboolean
-_gabble_media_stream_post_remote_candidates (GabbleMediaStream *stream,
- LmMessage *message,
- LmMessageNode *transport_node,
- GError **error)
+static void
+content_state_changed_cb (GabbleJingleContent *c,
+ GParamSpec *pspec,
+ GabbleMediaStream *stream)
{
- GabbleMediaStreamPrivate *priv;
- LmMessageNode *node;
- const gchar *str;
- GPtrArray *candidates;
- GType transport_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT;
- GType candidate_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
+ GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
+ JingleContentState state;
- priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
+ g_object_get (c, "state", &state, NULL);
- candidates = g_value_get_boxed (&priv->remote_candidates);
+ DEBUG ("called");
- for (node = transport_node->children; node; node = node->next)
+ if (state == JINGLE_CONTENT_STATE_ACKNOWLEDGED)
{
- gchar *candidate_id;
- const gchar *name, *addr;
- guint16 port;
- TpMediaStreamBaseProto proto;
- gdouble pref;
- TpMediaStreamTransportType type;
- const gchar *user, *pass;
- guchar net, gen;
- GValue candidate = { 0, };
- GPtrArray *transports;
- GValue transport = { 0, };
- gchar *xml;
-
- if (tp_strdiff (node->name, "candidate"))
- continue;
-
- /*
- * Candidate
- */
-
- /* stream name */
- name = lm_message_node_get_attribute (node, "name");
- if (name == NULL || strcmp (name, "rtp") != 0)
- goto FAILURE;
-
-
- /*
- * Transport
- */
-
- /* ip address */
- addr = lm_message_node_get_attribute (node, "address");
- if (addr == NULL)
- goto FAILURE;
-
- /* port */
- str = lm_message_node_get_attribute (node, "port");
- if (str == NULL)
- goto FAILURE;
- port = atoi (str);
-
- /* protocol */
- str = lm_message_node_get_attribute (node, "protocol");
- if (str == NULL)
- goto FAILURE;
-
- if (strcmp (str, "udp") == 0)
- {
- proto = TP_MEDIA_STREAM_BASE_PROTO_UDP;
- }
- else if (strcmp (str, "tcp") == 0)
- {
- if (port == 443)
- {
- GMS_DEBUG_WARNING (priv->session, "%s: tcp candidates on port "
- "443 must be ssltcp, ignoring candidate", G_STRFUNC);
- continue;
- }
-
- proto = TP_MEDIA_STREAM_BASE_PROTO_TCP;
- }
- else if (strcmp (str, "ssltcp") == 0)
- {
- if (port != 443)
- {
- GMS_DEBUG_WARNING (priv->session, "%s: ssltcp candidates must "
- "be on port 443, ignoring candidate", G_STRFUNC);
- continue;
- }
-
- proto = TP_MEDIA_STREAM_BASE_PROTO_TCP;
- }
- else
- goto FAILURE;
-
- /* protocol profile: hardcoded to "AVP" for now */
-
- /* preference */
- str = lm_message_node_get_attribute (node, "preference");
- if (str == NULL)
- goto FAILURE;
- pref = g_ascii_strtod (str, NULL);
-
- /* type */
- str = lm_message_node_get_attribute (node, "type");
- if (str == NULL)
- goto FAILURE;
-
- if (strcmp (str, "local") == 0)
- {
- type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL;
- }
- else if (strcmp (str, "stun") == 0)
- {
- type = TP_MEDIA_STREAM_TRANSPORT_TYPE_DERIVED;
- }
- else if (strcmp (str, "relay") == 0)
- {
- type = TP_MEDIA_STREAM_TRANSPORT_TYPE_RELAY;
- }
- else
- goto FAILURE;
-
- /* username */
- user = lm_message_node_get_attribute (node, "username");
- if (user == NULL)
- goto FAILURE;
-
- /* password */
- pass = lm_message_node_get_attribute (node, "password");
- if (pass == NULL)
- goto FAILURE;
-
- /* unknown */
- str = lm_message_node_get_attribute (node, "network");
- if (str == NULL)
- goto FAILURE;
- net = atoi (str);
-
- /* unknown */
- str = lm_message_node_get_attribute (node, "generation");
- if (str == NULL)
- goto FAILURE;
- gen = atoi (str);
-
-
- g_value_init (&transport, transport_struct_type);
- g_value_take_boxed (&transport,
- dbus_g_type_specialized_construct (transport_struct_type));
-
- dbus_g_type_struct_set (&transport,
- 0, 1, /* component number */
- 1, addr,
- 2, port,
- 3, proto,
- 4, "RTP",
- 5, "AVP",
- 6, pref,
- 7, type,
- 8, user,
- 9, pass,
- G_MAXUINT);
-
- transports = g_ptr_array_sized_new (1);
- g_ptr_array_add (transports, g_value_get_boxed (&transport));
-
-
- g_value_init (&candidate, candidate_struct_type);
- g_value_take_boxed (&candidate,
- dbus_g_type_specialized_construct (candidate_struct_type));
-
- /* FIXME: is this naming scheme sensible? */
- candidate_id = g_strdup_printf ("R%d", ++priv->remote_candidate_count);
-
- dbus_g_type_struct_set (&candidate,
- 0, candidate_id,
- 1, transports,
- G_MAXUINT);
-
- g_ptr_array_add (candidates, g_value_get_boxed (&candidate));
+ /* FIXME: check direction for these */
+ stream->playing = TRUE;
+ priv->sending = TRUE;
- xml = lm_message_node_to_string (node);
- GMS_DEBUG_INFO (priv->session,
- "put 1 remote candidate from peer into cache");
- GMS_DEBUG_DUMP (priv->session, " from Jingle XML: [%s%s%s]",
- TP_ANSI_BOLD_OFF, xml, TP_ANSI_BOLD_ON);
- GMS_DEBUG_DUMP (priv->session,
- " to Telepathy D-Bus struct: [%s\"%s\", %s[%s1, \"%s\", %d, %s, "
- "\"%s\", \"%s\", %f, %s, \"%s\", \"%s\"%s]]",
- TP_ANSI_BOLD_OFF, candidate_id, TP_ANSI_BOLD_ON,
- TP_ANSI_BOLD_OFF, addr, port, tp_protocols[proto],
- "RTP", "AVP", pref, tp_transports[type],
- user, pass, TP_ANSI_BOLD_ON);
- g_free (xml);
-
- g_free (candidate_id);
+ push_playing (stream);
+ push_sending (stream);
}
-
-/*SUCCESS:*/
- push_remote_candidates (stream);
-
- return TRUE;
-
-FAILURE:
- g_set_error (error, GABBLE_XMPP_ERROR, XMPP_ERROR_BAD_REQUEST,
- "unable to parse candidate");
-
- return FALSE;
}
-#endif
static void
push_remote_candidates (GabbleMediaStream *stream)
@@ -1927,139 +1429,102 @@ codec_params_from_tp_foreach (gpointer key, gpointer value, gpointer user_data)
}
#endif
-#if 0
-LmMessageNode *
-_gabble_media_stream_add_content_node (GabbleMediaStream *stream,
- LmMessageNode *session_node)
+static void
+content_senders_changed_cb (GabbleJingleContent *c,
+ GParamSpec *pspec,
+ GabbleMediaStream *stream)
{
- GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
- LmMessageNode *node = session_node;
+ // GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
+ JingleContentSenders senders;
- /* add our content node to it if in jingle mode */
- if (priv->mode == MODE_JINGLE)
- {
- node = lm_message_node_add_child (session_node, "content", NULL);
- lm_message_node_set_attribute (node, "name", stream->name);
-
- if (priv->session->initiator == stream->initiator)
- lm_message_node_set_attribute (node, "creator", "initiator");
- else
- lm_message_node_set_attribute (node, "creator", "responder");
- }
-
- return node;
+ g_object_get (c, "senders", &senders, NULL);
}
-void
-_gabble_media_stream_content_node_add_description (GabbleMediaStream *stream,
- LmMessageNode *content_node)
+gboolean
+gabble_media_stream_change_direction (GabbleMediaStream *stream,
+ guint requested_dir, GError **error)
{
- GabbleMediaStreamPrivate *priv;
- const GPtrArray *codecs;
- LmMessageNode *desc_node;
- guint i;
- const gchar *xmlns;
- GType codec_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
-
- codecs = g_value_get_boxed (&priv->native_codecs);
-
- desc_node = lm_message_node_add_child (content_node, "description", NULL);
-
- if (priv->mode == MODE_GOOGLE)
- xmlns = NS_GOOGLE_SESSION_PHONE;
- else if (priv->media_type == TP_MEDIA_STREAM_TYPE_VIDEO)
- xmlns = NS_JINGLE_DESCRIPTION_VIDEO;
- else
- xmlns = NS_JINGLE_DESCRIPTION_AUDIO;
-
- lm_message_node_set_attribute (desc_node, "xmlns", xmlns);
-
- for (i = 0; i < codecs->len; i++)
+ GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
+ CombinedStreamDirection new_combined_dir;
+ TpMediaStreamDirection current_dir;
+ TpMediaStreamPendingSend pending_send;
+ JingleContentSenders senders;
+ gboolean local_initiator;
+
+ current_dir = COMBINED_DIRECTION_GET_DIRECTION (stream->combined_direction);
+ pending_send = COMBINED_DIRECTION_GET_PENDING_SEND
+ (stream->combined_direction);
+
+ /* if we're awaiting a local decision on sending... */
+ if ((pending_send & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) != 0)
{
- GValue codec = { 0, };
- guint id, clock_rate, channels;
- gchar *name, buf[16];
- GHashTable *params;
- LmMessageNode *pt_node;
- CodecParamsFromTpContext ctx;
-
- g_value_init (&codec, codec_struct_type);
- g_value_set_static_boxed (&codec, g_ptr_array_index (codecs, i));
+ /* clear the flag */
+ pending_send &= ~TP_MEDIA_STREAM_PENDING_LOCAL_SEND;
- dbus_g_type_struct_get (&codec,
- 0, &id,
- 1, &name,
- 3, &clock_rate,
- 4, &channels,
- 5, ¶ms,
- G_MAXUINT);
-
- /* create a sub-node called "payload-type" and fill it */
- pt_node = lm_message_node_add_child (desc_node, "payload-type", NULL);
-
- /* id: required */
- sprintf (buf, "%u", id);
- lm_message_node_set_attribute (pt_node, "id", buf);
-
- /* name: optional */
- if (*name != '\0')
- {
- lm_message_node_set_attribute (pt_node, "name", name);
- }
-
- /* clock rate: optional */
- if (clock_rate != 0)
- {
- sprintf (buf, "%u", clock_rate);
- lm_message_node_set_attribute (pt_node,
- (priv->mode == MODE_GOOGLE) ? "clockrate" : "rate", buf);
- }
-
- /* number of channels: optional, jingle only */
- /* FIXME: is it? */
- if (channels != 0 && priv->mode == MODE_JINGLE)
- {
- sprintf (buf, "%u", channels);
- lm_message_node_set_attribute (pt_node, "channels", buf);
- }
+ /* make our current_dir match what other end thinks (he thinks we're
+ * bidirectional) so that we send the correct transitions */
+ current_dir ^= TP_MEDIA_STREAM_DIRECTION_SEND;
+ }
- /* parse the optional params */
- ctx.priv = priv;
- ctx.pt_node = pt_node;
- g_hash_table_foreach (params, codec_params_from_tp_foreach, &ctx);
+#if 0
+ /* if we're asking the remote end to start sending, set the pending flag and
+ * don't change our directionality just yet */
+ new_dir = requested_dir;
+ if (((current_dir & TP_MEDIA_STREAM_DIRECTION_RECEIVE) == 0) &&
+ ((new_dir & TP_MEDIA_STREAM_DIRECTION_RECEIVE) != 0))
+ {
+ pending_send ^= TP_MEDIA_STREAM_PENDING_REMOTE_SEND;
+ new_dir &= ~TP_MEDIA_STREAM_DIRECTION_RECEIVE;
+ }
+#endif
- /* clean up */
- g_free (name);
- g_hash_table_destroy (params);
+ /* make any necessary changes */
+ new_combined_dir = MAKE_COMBINED_DIRECTION (requested_dir, pending_send);
+ if (new_combined_dir != stream->combined_direction)
+ {
+ g_object_set (stream, "combined-direction", new_combined_dir, NULL);
+ _gabble_media_stream_update_sending (stream, FALSE);
}
-}
-LmMessageNode *
-_gabble_media_stream_content_node_add_transport (GabbleMediaStream *stream,
- LmMessageNode *content_node)
-{
- GabbleMediaStreamPrivate *priv;
- LmMessageNode *node;
+ /* short-circuit sending a request if we're not asking for anything new */
+ if (current_dir == requested_dir)
+ return TRUE;
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
+ g_object_get (priv->content->session, "local-initiator", &local_initiator, NULL);
- priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
+ switch (requested_dir)
+ {
+ case TP_MEDIA_STREAM_DIRECTION_SEND:
+ senders = local_initiator ?
+ JINGLE_CONTENT_SENDERS_INITIATOR : JINGLE_CONTENT_SENDERS_RESPONDER;
+ break;
+
+ case TP_MEDIA_STREAM_DIRECTION_RECEIVE:
+ senders = local_initiator ?
+ JINGLE_CONTENT_SENDERS_RESPONDER : JINGLE_CONTENT_SENDERS_INITIATOR;
+ break;
+
+ case TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL:
+ senders = JINGLE_CONTENT_SENDERS_BOTH;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
- if (priv->mode != MODE_JINGLE)
- return content_node;
+ if (!gabble_jingle_content_change_direction (priv->content, senders))
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
+ "stream direction invalid for the Jingle dialect in use");
+ return FALSE;
+ }
- node = lm_message_node_add_child (content_node, "transport", NULL);
+ return TRUE;
+}
- lm_message_node_set_attribute (node, "xmlns", NS_GOOGLE_TRANSPORT_P2P);
- return node;
-}
-#endif
+/* FIXME: this doesn't work yet */
void
_gabble_media_stream_update_sending (GabbleMediaStream *stream,
gboolean start_sending)
diff --git a/src/media-stream.h b/src/media-stream.h
index c378d90..1369fc7 100644
--- a/src/media-stream.h
+++ b/src/media-stream.h
@@ -107,6 +107,8 @@ void _gabble_media_stream_close (GabbleMediaStream *close);
void _gabble_media_stream_update_sending (GabbleMediaStream *stream,
gboolean start_sending);
void gabble_media_stream_hold (GabbleMediaStream *stream, gboolean hold);
+gboolean gabble_media_stream_change_direction (GabbleMediaStream *stream,
+ guint requested_dir, GError **error);
G_END_DECLS
--
1.5.6.5
More information about the Telepathy-commits
mailing list