[telepathy-sofiasip/master] Added properties InitialAudio and InitialVideo to media stream

Mikhail Zabaluev mikhail.zabaluev at nokia.com
Fri Jan 8 10:38:34 PST 2010


---
 src/media-factory.c     |   74 ++++++++++++++++++++++++++++++++++++++++++++--
 src/sip-media-channel.c |   43 +++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 4 deletions(-)

diff --git a/src/media-factory.c b/src/media-factory.c
index 7da29bf..59dab89 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -35,6 +35,11 @@
 #define DEBUG_FLAG TPSIP_DEBUG_CONNECTION
 #include "debug.h"
 
+typedef enum {
+  TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO = 1 << 0,
+  TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO = 1 << 1,
+} TpsipMediaChannelCreationFlags;
+
 static void channel_manager_iface_init (gpointer, gpointer);
 static void tpsip_media_factory_constructed (GObject *object);
 static void tpsip_media_factory_close_all (TpsipMediaFactory *fac);
@@ -255,13 +260,16 @@ media_channel_closed_cb (TpsipMediaChannel *chan, gpointer user_data)
 static TpsipMediaChannel *
 new_media_channel (TpsipMediaFactory *fac,
                    TpHandle initiator,
-                   TpHandle maybe_peer)
+                   TpHandle maybe_peer,
+                   TpsipMediaChannelCreationFlags flags)
 {
   TpsipMediaFactoryPrivate *priv;
   TpsipMediaChannel *chan = NULL;
   TpBaseConnection *conn;
   gchar *object_path;
   const gchar *nat_traversal = "none";
+  gboolean initial_audio;
+  gboolean initial_video;
 
   g_assert (initiator != 0);
 
@@ -273,6 +281,9 @@ new_media_channel (TpsipMediaFactory *fac,
 
   DEBUG("channel object path %s", object_path);
 
+  initial_audio = ((flags & TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO) != 0);
+  initial_video = ((flags & TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO) != 0);
+
   if (priv->stun_server != NULL)
     {
       nat_traversal = "stun";
@@ -283,6 +294,8 @@ new_media_channel (TpsipMediaFactory *fac,
                        "object-path", object_path,
                        "handle", maybe_peer,
                        "initiator", initiator,
+                       "initial-audio", initial_audio,
+                       "initial-video", initial_video,
                        "nat-traversal", nat_traversal,
                        NULL);
 
@@ -302,6 +315,33 @@ new_media_channel (TpsipMediaFactory *fac,
   return chan;
 }
 
+static guint
+initial_media_flags_from_sdp (const sdp_session_t *sdp)
+{
+  const sdp_media_t *media;
+  guint flags = 0;
+
+  for (media = sdp->sdp_media; media != NULL; media = media->m_next)
+    {
+      if (media->m_rejected || media->m_port == 0)
+        continue;
+
+      switch (media->m_type)
+        {
+        case sdp_media_audio:
+          flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO;
+          break;
+        case sdp_media_video:
+          flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO;
+          break;
+        default:
+          break;
+        }
+    }
+
+  return flags;
+}
+
 static gboolean
 tpsip_nua_i_invite_cb (TpBaseConnection    *conn,
                        const TpsipNuaEvent *ev,
@@ -311,6 +351,9 @@ tpsip_nua_i_invite_cb (TpBaseConnection    *conn,
   TpsipMediaChannel *channel;
   TpHandleRepoIface *contact_repo;
   TpHandle handle;
+  guint channel_flags = 0;
+  const sdp_session_t *sdp = NULL;
+  int offer_recv = 0;
 
   /* figure out a handle for the identity */
 
@@ -327,7 +370,15 @@ tpsip_nua_i_invite_cb (TpBaseConnection    *conn,
   DEBUG("Got incoming invite from <%s>",
         tp_handle_inspect (contact_repo, handle));
 
-  channel = new_media_channel (fac, handle, handle);
+  tl_gets(tags,
+          NUTAG_OFFER_RECV_REF(offer_recv),
+          SOATAG_REMOTE_SDP_REF(sdp),
+          TAG_END());
+
+  if (offer_recv && sdp != NULL)
+    channel_flags = initial_media_flags_from_sdp (sdp);
+
+  channel = new_media_channel (fac, handle, handle, channel_flags);
 
   tpsip_media_channel_receive_invite (channel, ev->nua_handle);
 
@@ -414,12 +465,16 @@ static const gchar * const media_channel_fixed_properties[] = {
 static const gchar * const named_channel_allowed_properties[] = {
     TP_IFACE_CHANNEL ".TargetHandle",
     TP_IFACE_CHANNEL ".TargetID",
+    TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio",
+    TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo",
     NULL
 };
 
 /* not advertised in foreach_channel_class - can only be requested with
  * RequestChannel, not with CreateChannel/EnsureChannel */
 static const gchar * const anon_channel_allowed_properties[] = {
+    TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio",
+    TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo",
     NULL
 };
 
@@ -468,6 +523,7 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
   TpsipMediaChannel *channel = NULL;
   GError *error = NULL;
   GSList *request_tokens;
+  guint chan_flags = 0;
   gboolean require_target_handle;
   gboolean add_peer_to_remote_pending;
 
@@ -514,6 +570,14 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
   handle = tp_asv_get_uint32 (request_properties,
       TP_IFACE_CHANNEL ".TargetHandle", NULL);
 
+  if (tp_asv_get_boolean (request_properties,
+        TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio", NULL))
+    chan_flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO;
+
+  if (tp_asv_get_boolean (request_properties,
+        TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo", NULL))
+    chan_flags |= TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO;
+
   switch (handle_type)
     {
     case TP_HANDLE_TYPE_NONE:
@@ -532,7 +596,7 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
               &error))
         goto error;
 
-      channel = new_media_channel (self, conn->self_handle, 0);
+      channel = new_media_channel (self, conn->self_handle, 0, chan_flags);
       break;
 
     case TP_HANDLE_TYPE_CONTACT:
@@ -562,13 +626,15 @@ tpsip_media_factory_requestotron (TpChannelManager *manager,
             }
         }
 
-      channel = new_media_channel (self, conn->self_handle, handle);
+      channel = new_media_channel (self, conn->self_handle, handle, chan_flags);
 
       if (add_peer_to_remote_pending)
         {
           if (!_tpsip_media_channel_add_member ((GObject *) channel, handle,
                 "", &error))
             {
+              /* FIXME: do we really want to emit Closed in this case?
+               * There wasn't a NewChannel/NewChannels emission */
               tpsip_media_channel_close (channel);
               goto error;
             }
diff --git a/src/sip-media-channel.c b/src/sip-media-channel.c
index 0f97556..cedc518 100644
--- a/src/sip-media-channel.c
+++ b/src/sip-media-channel.c
@@ -104,6 +104,8 @@ enum
   PROP_INTERFACES,
   PROP_CHANNEL_DESTROYED,
   PROP_CHANNEL_PROPERTIES,
+  PROP_INITIAL_AUDIO,
+  PROP_INITIAL_VIDEO,
   /* Telepathy properties (see below too) */
   PROP_NAT_TRAVERSAL,
   PROP_STUN_SERVER,
@@ -139,6 +141,8 @@ struct _TpsipMediaChannelPrivate
   TpHandle initiator;
   GHashTable *call_states;
 
+  gboolean initial_audio;
+  gboolean initial_video;
   gboolean closed;
   gboolean dispose_has_run;
 };
@@ -253,12 +257,23 @@ tpsip_media_channel_class_init (TpsipMediaChannelClass *klass)
       { "Requested", "requested", NULL },
       { NULL }
   };
+  static TpDBusPropertiesMixinPropImpl streamed_media_props[] = {
+      { "InitialAudio", "initial-audio", NULL },
+      { "InitialVideo", "initial-video", NULL },
+      { NULL }
+  };
+
   static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
       { TP_IFACE_CHANNEL,
         tp_dbus_properties_mixin_getter_gobject_properties,
         NULL,
         channel_props,
       },
+      { TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
+        tp_dbus_properties_mixin_getter_gobject_properties,
+        NULL,
+        streamed_media_props,
+      },
       { NULL }
   };
 
@@ -341,6 +356,20 @@ tpsip_media_channel_class_init (TpsipMediaChannelClass *klass)
       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
 
+  param_spec = g_param_spec_boolean ("initial-audio", "InitialAudio",
+      "Whether the channel initially contained an audio stream",
+      FALSE,
+      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_INITIAL_AUDIO,
+      param_spec);
+
+  param_spec = g_param_spec_boolean ("initial-video", "InitialVideo",
+      "Whether the channel initially contained a video stream",
+      FALSE,
+      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
+      param_spec);
+
   tp_properties_mixin_class_init (object_class,
       G_STRUCT_OFFSET (TpsipMediaChannelClass, properties_class),
       media_channel_property_signatures, NUM_TP_PROPS, NULL);
@@ -430,8 +459,16 @@ tpsip_media_channel_get_property (GObject    *object,
               TP_IFACE_CHANNEL, "InitiatorID",
               TP_IFACE_CHANNEL, "Requested",
               TP_IFACE_CHANNEL, "Interfaces",
+              TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialAudio",
+              TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialVideo",
               NULL));
       break;
+    case PROP_INITIAL_AUDIO:
+      g_value_set_boolean (value, priv->initial_audio);
+      break;
+    case PROP_INITIAL_VIDEO:
+      g_value_set_boolean (value, priv->initial_video);
+      break;
     default:
       /* Some properties live in the mixin */
       {
@@ -492,6 +529,12 @@ tpsip_media_channel_set_property (GObject     *object,
       /* similarly we can't ref this yet */
       priv->initiator = g_value_get_uint (value);
       break;
+    case PROP_INITIAL_AUDIO:
+      priv->initial_audio = g_value_get_boolean (value);
+      break;
+    case PROP_INITIAL_VIDEO:
+      priv->initial_video = g_value_get_boolean (value);
+      break;
     default:
       /* some properties live in the mixin */
       {
-- 
1.5.6.5




More information about the telepathy-commits mailing list