[Telepathy-commits] [telepathy-gabble/master] Raise an error if tpfs misuses CodecsUpdated
Will Thompson
will.thompson at collabora.co.uk
Fri Feb 27 10:06:57 PST 2009
(or, indeed, Ready, SetLocalCodecs, SupportedCodecs.)
---
src/jingle-media-rtp.c | 89 ++++++++++++++++++++++++++++++++++-------------
src/jingle-media-rtp.h | 4 +-
src/media-stream.c | 67 ++++++++++++++++++++++++++++-------
3 files changed, 119 insertions(+), 41 deletions(-)
diff --git a/src/jingle-media-rtp.c b/src/jingle-media-rtp.c
index cb89835..a8bb47e 100644
--- a/src/jingle-media-rtp.c
+++ b/src/jingle-media-rtp.c
@@ -614,13 +614,34 @@ codec_info_equal (const JingleCodec *c,
string_string_maps_equal (c->params, d->params));
}
-static GList *
-changed_codecs (GList *old,
- GList *new)
+/**
+ * compare_codecs:
+ * @old: previous local codecs
+ * @new: new local codecs supplied by streaming implementation
+ * @changed: location at which to store the changed codecs
+ * @error: location at which to store an error if the update was invalid
+ *
+ * Returns: %TRUE if the update made sense, %FALSE with @error set otherwise
+ */
+static gboolean
+compare_codecs (GList *old,
+ GList *new,
+ GList **changed,
+ GError **e)
{
- GList *changed = NULL;
GList *k, *l;
+ g_assert (changed != NULL && *changed == NULL);
+
+#define FAIL(msg, ...) \
+ G_STMT_START { \
+ g_set_error (e, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, msg, ##__VA_ARGS__); \
+ goto err; \
+ } G_STMT_END
+
+ if (g_list_length (new) != g_list_length (old))
+ FAIL ("tried to change the number of codecs!");
+
for (k = new; k != NULL; k = k->next)
{
JingleCodec *new_c = k->data;
@@ -633,36 +654,35 @@ changed_codecs (GList *old,
continue;
if (tp_strdiff (new_c->name, old_c->name))
- {
- DEBUG ("streaming implementation has changed codec %u's name "
- "from %s to %s!", new_c->id, old_c->name, new_c->name);
-
- /* FIXME: make CodecsUpdated fail. */
- }
+ FAIL ("tried to change codec %u's name from %s to %s",
+ new_c->id, old_c->name, new_c->name);
if (!codec_info_equal (old_c, new_c))
- {
- changed = g_list_prepend (changed, new_c);
- break;
- }
+ *changed = g_list_prepend (*changed, new_c);
+
+ break;
}
if (l == NULL)
- {
- DEBUG ("streaming implementation tried to update codec %u (%s) which "
- "wasn't there before", new_c->id, new_c->name);
- /* FIXME: make CodecsUpdated fail. */
- }
+ FAIL ("tried to update codec %u (%s) which wasn't there before",
+ new_c->id, new_c->name);
}
- /* FIXME: this doesn't detect the streaming implementation trying to remove codecs. */
+#undef FAIL
+
+ return TRUE;
- return changed;
+err:
+ g_list_free (*changed);
+ *changed = NULL;
+ return FALSE;
}
/* Takes in a list of slice-allocated JingleCodec structs */
-void
-jingle_media_rtp_set_local_codecs (GabbleJingleMediaRtp *self, GList *codecs)
+gboolean
+jingle_media_rtp_set_local_codecs (GabbleJingleMediaRtp *self,
+ GList *codecs,
+ GError **error)
{
GabbleJingleMediaRtpPrivate *priv = self->priv;
@@ -670,19 +690,38 @@ jingle_media_rtp_set_local_codecs (GabbleJingleMediaRtp *self, GList *codecs)
if (priv->local_codecs != NULL)
{
+ GList *changed = NULL;
+ GError *err = NULL;
+
/* Calling _gabble_jingle_content_set_media_ready () should use and unset
* these right after we set them.
*/
g_assert (priv->local_codec_updates == NULL);
- priv->local_codec_updates = changed_codecs (priv->local_codecs, codecs);
+
+ if (!compare_codecs (priv->local_codecs, codecs, &changed, &err))
+ {
+ DEBUG ("codec update was illegal: %s", err->message);
+ g_propagate_error (error, err);
+ return FALSE;
+ }
+
+ if (changed == NULL)
+ {
+ DEBUG ("codec update changed nothing!");
+ jingle_media_rtp_free_codecs (codecs);
+ return TRUE;
+ }
+
+ DEBUG ("%u codecs changed", g_list_length (changed));
+ priv->local_codec_updates = changed;
jingle_media_rtp_free_codecs (priv->local_codecs);
- priv->local_codecs = codecs;
}
priv->local_codecs = codecs;
_gabble_jingle_content_set_media_ready (GABBLE_JINGLE_CONTENT (self));
+ return TRUE;
}
void
diff --git a/src/jingle-media-rtp.h b/src/jingle-media-rtp.h
index 4bb3efa..3204596 100644
--- a/src/jingle-media-rtp.h
+++ b/src/jingle-media-rtp.h
@@ -71,8 +71,8 @@ typedef struct {
const gchar *gabble_jingle_media_rtp_parse (GabbleJingleMediaRtp *sess,
LmMessage *message, GError **error);
void jingle_media_rtp_register (GabbleJingleFactory *factory);
-void jingle_media_rtp_set_local_codecs (GabbleJingleMediaRtp *self,
- GList *codecs);
+gboolean jingle_media_rtp_set_local_codecs (GabbleJingleMediaRtp *self,
+ GList *codecs, GError **error);
GList *gabble_jingle_media_rtp_get_remote_codecs (GabbleJingleMediaRtp *self);
JingleCodec * jingle_media_rtp_codec_new (guint id, const gchar *name,
diff --git a/src/media-stream.c b/src/media-stream.c
index 117f0d0..ed788e2 100644
--- a/src/media-stream.c
+++ b/src/media-stream.c
@@ -1079,9 +1079,10 @@ gabble_media_stream_ready (TpSvcMediaStreamHandler *iface,
gabble_media_stream_set_local_codecs (iface, codecs, context);
}
-static void
+static gboolean
pass_local_codecs (GabbleMediaStream *stream,
- const GPtrArray *codecs)
+ const GPtrArray *codecs,
+ GError **error)
{
GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (stream);
GList *li = NULL;
@@ -1120,7 +1121,8 @@ pass_local_codecs (GabbleMediaStream *stream,
li = g_list_append (li, c);
}
- jingle_media_rtp_set_local_codecs (GABBLE_JINGLE_MEDIA_RTP (priv->content), li);
+ return jingle_media_rtp_set_local_codecs (
+ GABBLE_JINGLE_MEDIA_RTP (priv->content), li, error);
}
/**
@@ -1135,11 +1137,25 @@ gabble_media_stream_set_local_codecs (TpSvcMediaStreamHandler *iface,
DBusGMethodInvocation *context)
{
GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
+ GError *error = NULL;
+
+ DEBUG ("called");
if (gabble_jingle_content_is_created_by_us (self->priv->content))
- pass_local_codecs (self, codecs);
+ {
+ if (!pass_local_codecs (self, codecs, &error))
+ {
+ DEBUG ("failed: %s", error->message);
+
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+ }
else
- DEBUG ("ignoring local codecs, waiting for codec intersection");
+ {
+ DEBUG ("ignoring local codecs, waiting for codec intersection");
+ }
tp_svc_media_stream_handler_return_from_set_local_codecs (context);
}
@@ -1195,6 +1211,9 @@ gabble_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface,
{
GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
GabbleMediaStreamPrivate *priv = GABBLE_MEDIA_STREAM_GET_PRIVATE (self);
+ GError *error = NULL;
+
+ DEBUG ("called");
/* We don't need to do anything in response to the streaming implementation
* deciding it likes the new codec paramaters.
@@ -1202,11 +1221,22 @@ gabble_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface,
if (!priv->updating_remote_codecs)
{
if (gabble_jingle_content_is_created_by_us (self->priv->content))
- DEBUG ("we already sent our codecs, ignoring codec intersection");
+ {
+ DEBUG ("we already sent our codecs, ignoring codec intersection");
+ }
else
- pass_local_codecs (self, codecs);
+ {
+ if (!pass_local_codecs (self, codecs, &error))
+ {
+ DEBUG ("failed: %s", error->message);
- g_signal_emit (self, signals[SUPPORTED_CODECS], 0, codecs);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ g_signal_emit (self, signals[SUPPORTED_CODECS], 0, codecs);
+ }
}
tp_svc_media_stream_handler_return_from_supported_codecs (context);
@@ -1226,19 +1256,28 @@ gabble_media_stream_codecs_updated (TpSvcMediaStreamHandler *iface,
GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
gboolean codecs_set =
(g_value_get_boxed (&self->priv->native_codecs) != NULL);
+ GError *error = NULL;
- if (codecs_set)
- {
- pass_local_codecs (self, codecs);
- tp_svc_media_stream_handler_return_from_codecs_updated (context);
- }
- else
+ if (!codecs_set)
{
GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
"CodecsUpdated may only be called once an initial set of codecs "
"has been set" };
dbus_g_method_return_error (context, &e);
+ return;
+ }
+
+ if (pass_local_codecs (self, codecs, &error))
+ {
+ tp_svc_media_stream_handler_return_from_codecs_updated (context);
+ }
+ else
+ {
+ DEBUG ("failed: %s", error->message);
+
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
}
}
--
1.5.6.5
More information about the telepathy-commits
mailing list