[farsight2/master] Implement setting the remote candidates

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:26:14 PST 2008


---
 transmitters/nice/fs-nice-stream-transmitter.c |  158 ++++++++++++++++++++++++
 1 files changed, 158 insertions(+), 0 deletions(-)

diff --git a/transmitters/nice/fs-nice-stream-transmitter.c b/transmitters/nice/fs-nice-stream-transmitter.c
index 326ba15..54faa4b 100644
--- a/transmitters/nice/fs-nice-stream-transmitter.c
+++ b/transmitters/nice/fs-nice-stream-transmitter.c
@@ -91,6 +91,10 @@ struct _FsNiceStreamTransmitterPrivate
   /* Everything below is protected by the mutex */
 
   gboolean gathered;
+
+  gboolean candidates_added;
+
+  GList *candidates_to_set;
 };
 
 #define FS_NICE_STREAM_TRANSMITTER_GET_PRIVATE(o)  \
@@ -377,6 +381,72 @@ fs_nice_stream_transmitter_set_property (GObject *object,
   }
 }
 
+
+static NiceCandidateType
+fs_candidate_type_to_nice_candidate_type (FsCandidateType type)
+{
+  switch (type)
+  {
+    case FS_CANDIDATE_TYPE_HOST:
+      return NICE_CANDIDATE_TYPE_HOST;
+    case FS_CANDIDATE_TYPE_SRFLX:
+      return NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE;
+    case FS_CANDIDATE_TYPE_PRFLX:
+      return NICE_CANDIDATE_TYPE_PEER_REFLEXIVE;
+    case FS_CANDIDATE_TYPE_RELAY:
+      return NICE_CANDIDATE_TYPE_RELAYED;
+    default:
+      GST_WARNING ("Invalid candidate type %d, defaulting to type host", type);
+      return NICE_CANDIDATE_TYPE_HOST;
+  }
+}
+
+static NiceCandidateTransport
+fs_network_protocol_to_nice_candidate_protocol (FsNetworkProtocol proto)
+{
+  switch (proto)
+  {
+    case FS_NETWORK_PROTOCOL_UDP:
+      return NICE_CANDIDATE_TRANSPORT_UDP;
+    default:
+      GST_WARNING ("Invalid Fs network protocol type %u", proto);
+      return NICE_CANDIDATE_TRANSPORT_UDP;
+  }
+}
+
+static NiceCandidate *
+fs_candidate_to_nice_candidate (FsNiceStreamTransmitter *self,
+    FsCandidate *candidate)
+{
+  NiceCandidate *nc = g_new0 (NiceCandidate, 1);
+
+  nc->type = fs_candidate_type_to_nice_candidate_type (candidate->type);
+  nc->transport =
+    fs_network_protocol_to_nice_candidate_protocol (candidate->proto);
+  nc->priority = candidate->priority;
+  nc->stream_id = self->priv->stream_id;
+  nc->component_id = candidate->component_id;
+  strncpy (nc->foundation, candidate->foundation,
+      NICE_CANDIDATE_MAX_FOUNDATION);
+  nc->username = (gchar*) candidate->username;
+  nc->password = (gchar*) candidate->username;
+
+  if (candidate->ip)
+    if (!nice_address_set_from_string (&nc->addr, candidate->ip))
+      goto error;
+  nice_address_set_port (&nc->addr, candidate->port);
+  if (candidate->base_ip)
+    if (!nice_address_set_from_string (&nc->base_addr, candidate->base_ip))
+      goto error;
+  nice_address_set_port (&nc->base_addr, candidate->base_port);
+
+  return nc;
+
+ error:
+  g_free (nc);
+  return NULL;
+}
+
 /**
  * fs_nice_stream_transmitter_add_remote_candidate
  * @streamtransmitter: a #FsStreamTransmitter
@@ -394,6 +464,45 @@ fs_nice_stream_transmitter_add_remote_candidate (
     FsStreamTransmitter *streamtransmitter, FsCandidate *candidate,
     GError **error)
 {
+  FsNiceStreamTransmitter *self =
+    FS_NICE_STREAM_TRANSMITTER (streamtransmitter);
+  GSList *list = NULL;
+  NiceCandidate *cand = NULL;
+
+  FS_NICE_STREAM_TRANSMITTER_LOCK (self);
+  if (!self->priv->candidates_added)
+  {
+    self->priv->candidates_to_set = g_list_append (
+        self->priv->candidates_to_set,
+        candidate);
+    FS_NICE_STREAM_TRANSMITTER_UNLOCK (self);
+    return TRUE;
+  }
+  FS_NICE_STREAM_TRANSMITTER_UNLOCK (self);
+
+  cand = fs_candidate_to_nice_candidate (self, candidate);
+
+  if (!cand)
+  {
+    g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS,
+        "Invalid candidate added");
+    goto error;
+  }
+
+  list = g_slist_prepend (NULL, cand);
+
+  nice_agent_set_remote_candidates (self->priv->transmitter->agent,
+      self->priv->stream_id, candidate->component_id, list);
+
+  g_slist_free (list);
+  g_free (cand);
+
+
+  return TRUE;
+
+ error:
+
+  FS_NICE_STREAM_TRANSMITTER_UNLOCK (self);
   return FALSE;
 }
 
@@ -402,6 +511,55 @@ static void
 fs_nice_stream_transmitter_remote_candidates_added (
     FsStreamTransmitter *streamtransmitter)
 {
+  FsNiceStreamTransmitter *self =
+    FS_NICE_STREAM_TRANSMITTER (streamtransmitter);
+  GList *candidates = NULL, *item;
+  GSList *nice_candidates = NULL;
+  gint c;
+
+  FS_NICE_STREAM_TRANSMITTER_LOCK (self);
+  self->priv->candidates_added = TRUE;
+  candidates = self->priv->candidates_to_set;
+  self->priv->candidates_to_set = NULL;
+  FS_NICE_STREAM_TRANSMITTER_UNLOCK (self);
+
+
+  if (candidates)
+  {
+    FsCandidate *cand= candidates->data;
+    nice_agent_set_remote_credentials (self->priv->transmitter->agent,
+        self->priv->stream_id, cand->username, cand->password);
+  }
+
+  for (c = 1; c < self->priv->transmitter->components; c++)
+  {
+    for (item = candidates;
+         item;
+         item = g_list_next (item))
+    {
+      FsCandidate *candidate = item->data;
+      NiceCandidate *nc = fs_candidate_to_nice_candidate (self, candidate);
+
+      if (!nc)
+        goto error;
+
+      nice_candidates = g_slist_append (nice_candidates, nc);
+    }
+
+    nice_agent_set_remote_candidates (self->priv->transmitter->agent,
+        self->priv->stream_id, c, nice_candidates);
+
+    g_slist_foreach (nice_candidates, (GFunc) g_free, NULL);
+    g_slist_free (nice_candidates);
+  }
+  return;
+ error:
+  fs_stream_transmitter_emit_error (FS_STREAM_TRANSMITTER (self),
+      FS_ERROR_INVALID_ARGUMENTS,
+      "Invalid remote candidate passed",
+      "Remote candidate passed in previous add_remote_candidate() call invalid");
+  g_slist_foreach (nice_candidates, (GFunc) g_free, NULL);
+  g_slist_free (nice_candidates);
 }
 
 static gboolean
-- 
1.5.6.5




More information about the farsight-commits mailing list