[farsight2/master] a lot of stuff to move a bit forward in making fsmsnconference work...

Youness Alaoui youness.alaoui at collabora.co.uk
Tue Jul 14 09:50:45 PDT 2009


---
 gst/fsmsnconference/Makefile.am         |   24 ++++++-
 gst/fsmsnconference/fs-msn-conference.c |   83 +--------------------
 gst/fsmsnconference/fs-msn-connection.c |   98 +++++++++++++++++++++----
 gst/fsmsnconference/fs-msn-connection.h |    5 +-
 gst/fsmsnconference/fs-msn-session.c    |   49 ++++++++++++-
 gst/fsmsnconference/fs-msn-stream.c     |  121 ++++++++++++++++++++++---------
 gst/fsmsnconference/fs-msn-stream.h     |    2 +
 7 files changed, 243 insertions(+), 139 deletions(-)

diff --git a/gst/fsmsnconference/Makefile.am b/gst/fsmsnconference/Makefile.am
index 5aca5db..aadef38 100644
--- a/gst/fsmsnconference/Makefile.am
+++ b/gst/fsmsnconference/Makefile.am
@@ -24,11 +24,31 @@ libfsmsnconference_la_CFLAGS = \
 	$(FS2_INTERNAL_CFLAGS) \
 	$(FS2_CFLAGS) \
 	$(GST_PLUGINS_BASE_CFLAGS) \
-	$(GST_CFLAGS)
+	$(GST_CFLAGS) \
+	$(NICE_CFLAGS)
+
 libfsmsnconference_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libfsmsnconference_la_LIBADD = \
 	$(top_builddir)/gst-libs/gst/farsight/libgstfarsight-0.10.la \
 	$(FS2_LIBS) \
 	$(GST_BASE_LIBS) \
-	$(GST_LIBS)
+	$(GST_LIBS) \
+	$(NICE_LIBS)
+
+check_PROGRAMS = test-connection
+
+test_connection_SOURCES = test-connection.c fs-msn-connection.c
+test_connection_CFLAGS = \
+        $(FS2_INTERNAL_CFLAGS) \
+        $(FS2_CFLAGS) \
+        $(GST_PLUGINS_BASE_CFLAGS) \
+        $(GST_CFLAGS) \
+	$(NICE_CFLAGS)
+test_connection_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+test_connection_LDADD = \
+        $(top_builddir)/gst-libs/gst/farsight/libgstfarsight-0.10.la \
+        $(FS2_LIBS) \
+        $(GST_BASE_LIBS) \
+        $(GST_LIBS) \
+	$(NICE_LIBS)
 
diff --git a/gst/fsmsnconference/fs-msn-conference.c b/gst/fsmsnconference/fs-msn-conference.c
index d3a3c27..85bb196 100644
--- a/gst/fsmsnconference/fs-msn-conference.c
+++ b/gst/fsmsnconference/fs-msn-conference.c
@@ -52,8 +52,7 @@ enum
 /* Properties */
 enum
 {
-  PROP_0,
-  PROP_LOCAL_MSNADD,
+  PROP_0
 };
 
 
@@ -62,7 +61,8 @@ static GstElementDetails fs_msn_conference_details =
   "Farsight MSN Conference",
   "Generic/Bin/MSN",
   "A Farsight MSN Conference",
-  "Richard Spiers <richard.spiers at gmail.com>"
+  "Richard Spiers <richard.spiers at gmail.com>, "
+  "Youness Alaoui <youness.alaoui at collabora.co.uk"
 };
 
 
@@ -87,8 +87,6 @@ struct _FsMsnConferencePrivate
 {
   gboolean disposed;
   /* Protected by GST_OBJECT_LOCK */
-  gchar *local_address;
-
   FsMsnParticipant *participant;
   FsMsnSession *session;
 };
@@ -99,18 +97,6 @@ static void fs_msn_conference_do_init (GType type);
 GST_BOILERPLATE_FULL (FsMsnConference, fs_msn_conference, FsBaseConference,
     FS_TYPE_BASE_CONFERENCE, fs_msn_conference_do_init);
 
-static void fs_msn_conference_get_property (GObject *object,
-    guint prop_id,
-    GValue *value,
-    GParamSpec *pspec);
-
-static void fs_msn_conference_set_property (GObject *object,
-    guint prop_id,
-    const GValue *value,
-    GParamSpec *pspec);
-
-static void fs_msn_conference_finalize (GObject *object);
-
 static FsSession *fs_msn_conference_new_session (FsBaseConference *conf,
     FsMediaType media_type,
     GError **error);
@@ -155,18 +141,6 @@ fs_msn_conference_dispose (GObject * object)
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
-
-static void
-fs_msn_conference_finalize (GObject * object)
-{
-  FsMsnConference *self = FS_MSN_CONFERENCE (object);
-
-  g_free (self->priv->local_address);
-  self->priv->local_address = NULL;
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
 static void
 fs_msn_conference_class_init (FsMsnConferenceClass * klass)
 {
@@ -182,16 +156,7 @@ fs_msn_conference_class_init (FsMsnConferenceClass * klass)
   baseconf_class->new_participant =
     GST_DEBUG_FUNCPTR (fs_msn_conference_new_participant);
 
-  gobject_class->finalize = GST_DEBUG_FUNCPTR (fs_msn_conference_finalize);
   gobject_class->dispose = GST_DEBUG_FUNCPTR (fs_msn_conference_dispose);
-  gobject_class->set_property =
-    GST_DEBUG_FUNCPTR (fs_msn_conference_set_property);
-  gobject_class->get_property =
-    GST_DEBUG_FUNCPTR (fs_msn_conference_get_property);
-  g_object_class_install_property (gobject_class,PROP_LOCAL_MSNADD,
-      g_param_spec_string ("local_address", "Msn Address",
-          "The local contact address for the MSN sessions",
-          NULL, G_PARAM_READWRITE));
 }
 
 static void
@@ -217,48 +182,6 @@ fs_msn_conference_init (FsMsnConference *conf,
 }
 
 static void
-fs_msn_conference_get_property (GObject *object,
-                                guint prop_id,
-                                GValue *value,
-                                GParamSpec *pspec)
-{
-  FsMsnConference *self = FS_MSN_CONFERENCE (object);
-
-  switch (prop_id)
-  {
-    case PROP_LOCAL_MSNADD:
-      GST_OBJECT_LOCK (self);
-      g_value_set_string (value, self->priv->local_address);
-      GST_OBJECT_UNLOCK (self);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-static void
-fs_msn_conference_set_property (GObject *object,
-                                guint prop_id,
-                                const GValue *value,
-                                GParamSpec *pspec)
-{
-  FsMsnConference *self = FS_MSN_CONFERENCE (object);
-
-  switch (prop_id)
-  {
-    case PROP_LOCAL_MSNADD:
-      GST_OBJECT_LOCK (self);
-      g_free (self->priv->local_address);
-      self->priv->local_address = g_value_dup_string (value);
-      GST_OBJECT_UNLOCK (self);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
 _remove_session (gpointer user_data,
                  GObject *where_the_object_was)
 {
diff --git a/gst/fsmsnconference/fs-msn-connection.c b/gst/fsmsnconference/fs-msn-connection.c
index 553ac9a..8a05eec 100644
--- a/gst/fsmsnconference/fs-msn-connection.c
+++ b/gst/fsmsnconference/fs-msn-connection.c
@@ -40,13 +40,22 @@
 #include <unistd.h>
 #include <gst/gst.h>
 
+#include <nice/interfaces.h>
+
+
 /* Signals */
 enum
 {
-  LAST_SIGNAL
+  SIGNAL_NEW_LOCAL_CANDIDATE,
+  SIGNAL_LOCAL_CANDIDATES_PREPARED,
+  SIGNAL_CONNECTED,
+  SIGNAL_CONNECTION_FAILED,
+  N_SIGNALS
 };
 
 
+static guint signals[N_SIGNALS];
+
 /* props */
 enum
 {
@@ -86,7 +95,7 @@ static gboolean fs_msn_connection_attempt_connection (
     FsMsnConnection *connection,
     FsCandidate *candidate);
 static gboolean fs_msn_open_listening_port (FsMsnConnection *connection,
-    guint16 port, NewLocalCandidateCB cb, gpointer data);
+    guint16 port);
 
 static void successful_connection_cb (FsMsnConnection *self, FsMsnPollFD *fd);
 static void accept_connection_cb (FsMsnConnection *self, FsMsnPollFD *fd);
@@ -104,6 +113,49 @@ fs_msn_connection_class_init (FsMsnConnectionClass *klass)
 
   parent_class = g_type_class_peek_parent (klass);
 
+  signals[SIGNAL_NEW_LOCAL_CANDIDATE] = g_signal_new
+      ("new-local-candidate",
+          G_TYPE_FROM_CLASS (klass),
+          G_SIGNAL_RUN_LAST,
+          0,
+          NULL,
+          NULL,
+          g_cclosure_marshal_VOID__BOXED,
+          G_TYPE_NONE, 1, FS_TYPE_CANDIDATE);
+
+
+  signals[SIGNAL_LOCAL_CANDIDATES_PREPARED] = g_signal_new
+    ("local-candidates-prepared",
+      G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      0,
+      NULL,
+      NULL,
+      g_cclosure_marshal_VOID__VOID,
+      G_TYPE_NONE, 0);
+
+
+  signals[SIGNAL_CONNECTED] = g_signal_new
+    ("connected",
+      G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      0,
+      NULL,
+      NULL,
+      g_cclosure_marshal_VOID__UINT,
+        G_TYPE_NONE, 1, G_TYPE_UINT);
+
+
+  signals[SIGNAL_CONNECTION_FAILED] = g_signal_new
+    ("connection-failed",
+      G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      0,
+      NULL,
+      NULL,
+      g_cclosure_marshal_VOID__VOID,
+      G_TYPE_NONE, 0);
+
   gobject_class->dispose = fs_msn_connection_dispose;
 }
 
@@ -190,8 +242,7 @@ fs_msn_connection_new (guint session_id, guint initial_port)
 }
 
 gboolean
-fs_msn_connection_gather_local_candidates (FsMsnConnection *self,
-    NewLocalCandidateCB cb, gpointer data)
+fs_msn_connection_gather_local_candidates (FsMsnConnection *self)
 {
   gboolean ret = FALSE;
   g_static_rec_mutex_lock (&self->mutex);
@@ -200,7 +251,9 @@ fs_msn_connection_gather_local_candidates (FsMsnConnection *self,
       self, TRUE, NULL);
 
   if (self->polling_thread)
-    ret = fs_msn_open_listening_port (self, self->initial_port, cb, data);
+    ret = fs_msn_open_listening_port (self, self->initial_port);
+
+  g_signal_emit (self, signals[SIGNAL_LOCAL_CANDIDATES_PREPARED], 0);
 
   g_static_rec_mutex_unlock (&self->mutex);
   return ret;
@@ -222,6 +275,7 @@ fs_msn_connection_set_remote_candidates (FsMsnConnection *self,
 
   recipient_id = self->remote_recipient_id;
 
+
   for (item = candidates; item; item = g_list_next (item))
   {
     FsCandidate *candidate = item->data;
@@ -268,11 +322,14 @@ fs_msn_connection_set_remote_candidates (FsMsnConnection *self,
 
 
 static gboolean
-fs_msn_open_listening_port (FsMsnConnection *self,
-    guint16 port, NewLocalCandidateCB cb, gpointer data)
+fs_msn_open_listening_port (FsMsnConnection *self, guint16 port)
 {
   gint fd = -1;
   struct sockaddr_in myaddr;
+  FsCandidate * candidate = NULL;
+  GList *addresses = nice_interfaces_get_local_ips (FALSE);
+  GList *item = NULL;
+
   memset(&myaddr, 0, sizeof(myaddr));
 
   g_debug ("Attempting to listen on port %d.....",port);
@@ -326,14 +383,20 @@ fs_msn_open_listening_port (FsMsnConnection *self,
 
   g_debug ("Listening on port %d", port);
 
-  FsCandidate * cand = fs_candidate_new ("123", 1, FS_CANDIDATE_TYPE_HOST,
-      FS_NETWORK_PROTOCOL_TCP, "127.0.0.1", port);
-  g_static_rec_mutex_unlock (&self->mutex);
-  cb (cand, data);
-  g_static_rec_mutex_lock (&self->mutex);
-  fs_candidate_destroy (cand);
+  self->local_recipient_id = g_strdup_printf ("%d",
+      g_random_int_range (100, 199));
+
+  for (item = addresses;
+       item;
+       item = g_list_next (item))
+  {
+    candidate = fs_candidate_new (self->local_recipient_id, 1,
+        FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_TCP, item->data, port);
+
+    g_signal_emit (self, signals[SIGNAL_NEW_LOCAL_CANDIDATE], 0, candidate);
 
-  self->local_recipient_id = g_strdup ("123");
+    fs_candidate_destroy (candidate);
+  }
 
   return TRUE;
 }
@@ -699,7 +762,7 @@ connection_cb (FsMsnConnection *self, FsMsnPollFD *pollfd)
       }
     }
 
-    /* TODO : callback */
+    g_signal_emit (self, signals[SIGNAL_CONNECTED], 0, pollfd->pollfd.fd);
 
     pollfd->want_read = FALSE;
     pollfd->want_write = FALSE;
@@ -723,7 +786,10 @@ connection_cb (FsMsnConnection *self, FsMsnPollFD *pollfd)
       i--;
     }
   }
-
+  if (self->pollfds->len <= 1)
+  {
+    g_signal_emit (self, signals[SIGNAL_CONNECTION_FAILED], 0);
+  }
   return;
 }
 
diff --git a/gst/fsmsnconference/fs-msn-connection.h b/gst/fsmsnconference/fs-msn-connection.h
index a9cc39c..cf603eb 100644
--- a/gst/fsmsnconference/fs-msn-connection.h
+++ b/gst/fsmsnconference/fs-msn-connection.h
@@ -78,14 +78,11 @@ struct _FsMsnConnection
   GStaticRecMutex mutex;
 };
 
-typedef void (*NewLocalCandidateCB) (FsCandidate *candidate, gpointer data);
-
 GType fs_msn_connection_get_type (void);
 
 FsMsnConnection *fs_msn_connection_new (guint session_id, guint initial_port);
 
-gboolean fs_msn_connection_gather_local_candidates (FsMsnConnection *connection,
-    NewLocalCandidateCB cb, gpointer data);
+gboolean fs_msn_connection_gather_local_candidates (FsMsnConnection *connection);
 
 gboolean fs_msn_connection_set_remote_candidates (FsMsnConnection *connection,
     GList *candidates, GError **error);
diff --git a/gst/fsmsnconference/fs-msn-session.c b/gst/fsmsnconference/fs-msn-session.c
index e567c2e..a9eca83 100644
--- a/gst/fsmsnconference/fs-msn-session.c
+++ b/gst/fsmsnconference/fs-msn-session.c
@@ -62,7 +62,9 @@ enum
   PROP_CODECS_WITHOUT_CONFIG,
   PROP_CURRENT_SEND_CODEC,
   PROP_CODECS_READY,
-  PROP_CONFERENCE
+  PROP_CONFERENCE,
+  PROP_SESSION_ID,
+  PROP_INITIAL_PORT
 };
 
 
@@ -79,6 +81,9 @@ struct _FsMsnSessionPrivate
   GstPad *media_sink_pad;
   GstElement *valve;
 
+  guint session_id;
+  guint initial_port;
+
   gboolean disposed;
 };
 
@@ -156,6 +161,24 @@ fs_msn_session_class_init (FsMsnSessionClass *klass)
           FS_TYPE_MSN_CONFERENCE,
           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class,
+      PROP_SESSION_ID,
+      g_param_spec_uint ("session-id",
+          "The session-id of the session",
+          "This is the session-id of the MSN session",
+          9000, 9999, 9000,
+          G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+      PROP_SESSION_ID,
+      g_param_spec_uint ("initial-port",
+          "The initial port to listen on",
+          "The initial port to try to listen on for incoming connection."
+          " If already used, port+1 is tried until one succeeds",
+          0, 65535, 0,
+          G_PARAM_READWRITE));
+
+
   gobject_class->dispose = fs_msn_session_dispose;
   gobject_class->finalize = fs_msn_session_finalize;
 
@@ -169,6 +192,7 @@ fs_msn_session_init (FsMsnSession *self)
   self->priv = FS_MSN_SESSION_GET_PRIVATE (self);
   self->priv->disposed = FALSE;
   self->priv->construction_error = NULL;
+  self->priv->session_id = g_random_int_range (9000, 9999);
 
   g_static_rec_mutex_init (&self->mutex);
 
@@ -265,6 +289,12 @@ fs_msn_session_get_property (GObject *object,
         g_value_take_boxed (value, send_codec);
         break;
       }
+    case PROP_SESSION_ID:
+      g_value_set_uint (value, self->priv->session_id);
+      break;
+    case PROP_INITIAL_PORT:
+      g_value_set_uint (value, self->priv->initial_port);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -290,6 +320,18 @@ fs_msn_session_set_property (GObject *object,
     case PROP_CONFERENCE:
       self->priv->conference = FS_MSN_CONFERENCE (g_value_dup_object (value));
       break;
+    case PROP_SESSION_ID:
+      if (self->priv->stream)
+        GST_DEBUG ("Cannot change the session-id after a stream is created");
+      else
+        self->priv->session_id = g_value_get_uint (value);
+      break;
+    case PROP_INITIAL_PORT:
+      if (self->priv->stream)
+        GST_DEBUG ("Cannot change the initial-port after a stream is created");
+      else
+        self->priv->initial_port = g_value_get_uint (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -318,6 +360,8 @@ fs_msn_session_constructed (GObject *object)
     return;
   }
 
+  g_object_set (G_OBJECT (self->priv->valve), "drop", TRUE, NULL);
+
   pad = gst_element_get_static_pad (self->priv->valve, "sink");
   self->priv->media_sink_pad = gst_ghost_pad_new ("sink1", pad);
   gst_object_unref (pad);
@@ -406,7 +450,8 @@ fs_msn_session_new_stream (FsSession *session,
   msnparticipant = FS_MSN_PARTICIPANT (participant);
 
   new_stream = FS_STREAM_CAST (fs_msn_stream_new (self, msnparticipant,
-          direction,self->priv->conference,error));
+          direction, self->priv->conference,
+          self->priv->session_id, self->priv->initial_port, error));
 
   if (new_stream)
   {
diff --git a/gst/fsmsnconference/fs-msn-stream.c b/gst/fsmsnconference/fs-msn-stream.c
index a4ed6d0..0aaa460 100644
--- a/gst/fsmsnconference/fs-msn-stream.c
+++ b/gst/fsmsnconference/fs-msn-stream.c
@@ -34,6 +34,7 @@
 #endif
 
 #include "fs-msn-stream.h"
+#include "fs-msn-connection.h"
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <fcntl.h>
@@ -69,6 +70,7 @@ struct _FsMsnStreamPrivate
   FsMsnConference *conference;
   GstElement *media_fd_src,*media_fd_sink,*send_valve;
   GstPad *sink_pad,*src_pad;
+  FsMsnConnection *connection;
 
   GError *construction_error;
 
@@ -99,9 +101,16 @@ static gboolean fs_msn_stream_set_remote_candidates (FsStream *stream,
     GList *candidates,
     GError **error);
 
-static gboolean fs_msn_stream_set_remote_candidate  (FsMsnStream *stream,
+static void _local_candidates_prepared (FsMsnConnection *connection,
+    gpointer user_data);
+
+static void _new_local_candidate (
+    FsMsnConnection *connection,
     FsCandidate *candidate,
-    GError **error);
+    gpointer user_data);
+
+
+
 
 static GObjectClass *parent_class = NULL;
 
@@ -520,46 +529,63 @@ fs_msn_stream_constructed (GObject *object)
   GST_CALL_PARENT (G_OBJECT_CLASS, constructed, (object));
 }
 
-/**
- * fs_msn_stream_set_remote_candidate:
- */
-static gboolean
-fs_msn_stream_set_remote_candidates (FsStream *stream, GList *candidates,
-                                     GError **error)
+
+static void
+_local_candidates_prepared (FsMsnConnection *connection,
+    gpointer user_data)
 {
-  FsMsnStream *self = FS_MSN_STREAM (stream);
-  GList *item = NULL;
+  FsMsnStream *self = FS_MSN_STREAM (user_data);
 
-  for (item = candidates; item; item = g_list_next (item))
-  {
-    FsCandidate *candidate = item->data;
+  gst_element_post_message (GST_ELEMENT (self->priv->conference),
+      gst_message_new_element (GST_OBJECT (self->priv->conference),
+          gst_structure_new ("farsight-local-candidates-prepared",
+              "stream", FS_TYPE_STREAM, self,
+              NULL)));
 
-    if (!candidate->ip || !candidate->port)
-    {
-      g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS,
-          "The candidate passed does not contain a valid ip or port");
-      return FALSE;
-    }
-  }
+}
 
-  for (item = candidates; item; item = g_list_next (item))
-  {
-    FsCandidate *candidate = item->data;
-    if (!fs_msn_stream_set_remote_candidate (self,candidate,error))
-      return FALSE;
-  }
+static void
+_new_local_candidate (
+    FsMsnConnection *connection,
+    FsCandidate *candidate,
+    gpointer user_data)
+{
+  FsMsnStream *self = FS_MSN_STREAM (user_data);
+
+  gst_element_post_message (GST_ELEMENT (self->priv->conference),
+      gst_message_new_element (GST_OBJECT (self->priv->conference),
+          gst_structure_new ("farsight-new-local-candidate",
+              "stream", FS_TYPE_STREAM, self,
+              "candidate", FS_TYPE_CANDIDATE, candidate,
+              NULL)));
+}
 
-  return TRUE;
+
+static void
+_connected (
+    FsMsnConnection *connection,
+    guint *fd,
+    gpointer user_data)
+{
+  FsMsnStream *self = FS_MSN_STREAM (user_data);
+
+  (void)self;
 }
 
+/**
+ * fs_msn_stream_set_remote_candidate:
+ */
 static gboolean
-fs_msn_stream_set_remote_candidate  (FsMsnStream *stream,
-                                     FsCandidate *candidate,
+fs_msn_stream_set_remote_candidates (FsStream *stream, GList *candidates,
                                      GError **error)
 {
-  return FALSE;
+  FsMsnStream *self = FS_MSN_STREAM (stream);
+
+  return fs_msn_connection_set_remote_candidates (self->priv->connection,
+      candidates, error);
 }
 
+
 /**
  * fs_msn_stream_new:
  * @session: The #FsMsnSession this stream is a child of
@@ -574,10 +600,12 @@ fs_msn_stream_set_remote_candidate  (FsMsnStream *stream,
 
 FsMsnStream *
 fs_msn_stream_new (FsMsnSession *session,
-                   FsMsnParticipant *participant,
-                   FsStreamDirection direction,
-                   FsMsnConference *conference,
-                   GError **error)
+    FsMsnParticipant *participant,
+    FsStreamDirection direction,
+    FsMsnConference *conference,
+    guint session_id,
+    guint initial_port,
+    GError **error)
 {
   FsMsnStream *self = g_object_new (FS_TYPE_MSN_STREAM,
       "session", session,
@@ -586,13 +614,36 @@ fs_msn_stream_new (FsMsnSession *session,
       "conference",conference,
       NULL);
 
-  if (self->priv->construction_error)
+  if (!self)
+  {
+    *error = g_error_new (FS_ERROR, FS_ERROR_CONSTRUCTION,
+        "Could not create object");
+  }
+  else if (self->priv->construction_error)
   {
     g_propagate_error (error, self->priv->construction_error);
     g_object_unref (self);
     return NULL;
   }
 
+  if (self)
+  {
+    self->priv->connection = fs_msn_connection_new (session_id, initial_port);
+
+    g_signal_connect (self->priv->connection,
+        "new-local-candidate",
+        G_CALLBACK (_new_local_candidate), self);
+    g_signal_connect (self->priv->connection,
+        "local-candidates-prepared",
+        G_CALLBACK (_local_candidates_prepared), self);
+
+    g_signal_connect (self->priv->connection,
+        "connected",
+        G_CALLBACK (_connected), self);
+
+    fs_msn_connection_gather_local_candidates (self->priv->connection);
+  }
+
   return self;
 }
 
diff --git a/gst/fsmsnconference/fs-msn-stream.h b/gst/fsmsnconference/fs-msn-stream.h
index e78dc7a..5b7ca61 100644
--- a/gst/fsmsnconference/fs-msn-stream.h
+++ b/gst/fsmsnconference/fs-msn-stream.h
@@ -77,6 +77,8 @@ FsMsnStream *fs_msn_stream_new (FsMsnSession *session,
     FsMsnParticipant *participant,
     FsStreamDirection direction,
     FsMsnConference *conference,
+    guint session_id,
+    guint initial_port,
     GError **error);
 
 
-- 
1.5.6.5




More information about the farsight-commits mailing list