[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