static void
update_candidates (EmpathyCallHandler *self,
    FsCandidate *remote_candidate,
    FsCandidate *local_candidate,
    FsStream *stream)
{
  EmpathyCallHandlerPriv *priv = GET_PRIV (self);
  FsSession *session;
  FsMediaType type;

  if (stream == NULL)
    return;

  g_object_get (stream, "session", &session, NULL);
  if (session == NULL)
    return;

  g_object_get (session, "media-type", &type, NULL);

  if (type == FS_MEDIA_TYPE_AUDIO)
    {
      if (remote_candidate != NULL)
        {
          fs_candidate_destroy (priv->audio_remote_candidate);
          priv->audio_remote_candidate = fs_candidate_copy (remote_candidate);
          g_object_notify (G_OBJECT (self), "audio-remote-candidate");
        }

      if (local_candidate != NULL)
        {
          fs_candidate_destroy (priv->audio_local_candidate);
          priv->audio_local_candidate = fs_candidate_copy (local_candidate);
          g_object_notify (G_OBJECT (self), "audio-local-candidate");
        }

      g_signal_emit (G_OBJECT (self), signals[CANDIDATES_CHANGED], 0,
          FS_MEDIA_TYPE_AUDIO);
    }
  else if (type == FS_MEDIA_TYPE_VIDEO)
    {
      if (remote_candidate != NULL)
        {
          fs_candidate_destroy (priv->video_remote_candidate);
          priv->video_remote_candidate = fs_candidate_copy (remote_candidate);
          g_object_notify (G_OBJECT (self), "video-remote-candidate");
        }

      if (local_candidate != NULL)
        {
          fs_candidate_destroy (priv->video_local_candidate);
          priv->video_local_candidate = fs_candidate_copy (local_candidate);
          g_object_notify (G_OBJECT (self), "video-local-candidate");
        }

      g_signal_emit (G_OBJECT (self), signals[CANDIDATES_CHANGED], 0,
          FS_MEDIA_TYPE_VIDEO);
    }

  g_object_unref (session);
}
static void
empathy_call_handler_finalize (GObject *object)
{
  EmpathyCallHandlerPriv *priv = GET_PRIV (object);

  fs_codec_destroy (priv->send_audio_codec);
  fs_codec_destroy (priv->send_video_codec);
  fs_codec_list_destroy (priv->recv_audio_codecs);
  fs_codec_list_destroy (priv->recv_video_codecs);
  fs_candidate_destroy (priv->audio_remote_candidate);
  fs_candidate_destroy (priv->video_remote_candidate);
  fs_candidate_destroy (priv->audio_local_candidate);
  fs_candidate_destroy (priv->video_local_candidate);

  G_OBJECT_CLASS (empathy_call_handler_parent_class)->finalize (object);
}
Beispiel #3
0
/**
 * fs_candidate_list_destroy:
 * @candidate_list: A GList of #FsCandidate
 *
 * Deletes a GList of #FsCandidate and its contents
 */
void
fs_candidate_list_destroy (GList *candidate_list)
{
  GList *lp;
  FsCandidate *cand;

  for (lp = candidate_list; lp; lp = g_list_next (lp)) {
    cand = (FsCandidate *) lp->data;
    fs_candidate_destroy (cand);
    lp->data = NULL;
  }
  g_list_free (candidate_list);
}
static void
fs_rawudp_component_finalize (GObject *object)
{
  FsRawUdpComponent *self = FS_RAWUDP_COMPONENT (object);

  if (self->priv->remote_candidate)
    fs_candidate_destroy (self->priv->remote_candidate);
  if (self->priv->local_active_candidate)
    fs_candidate_destroy (self->priv->local_active_candidate);
  if (self->priv->local_forced_candidate)
    fs_candidate_destroy (self->priv->local_forced_candidate);
#ifdef HAVE_GUPNP
  if (self->priv->local_upnp_candidate)
    fs_candidate_destroy (self->priv->local_upnp_candidate);
#endif

  g_free (self->priv->ip);
  g_free (self->priv->stun_ip);

  g_mutex_clear (&self->priv->mutex);

  parent_class->finalize (object);
}
static gboolean
fs_msn_open_listening_port_unlock (FsMsnConnection *self, guint16 port,
    GError **error)
{
  gint fd = -1;
  struct sockaddr_in myaddr;
  guint myaddr_len = sizeof (struct sockaddr_in);
  FsCandidate * candidate = NULL;
  GList *addresses = nice_interfaces_get_local_ips (FALSE);
  GList *item = NULL;
  gchar *session_id;

  addresses = filter_ips_ipv4 (addresses);


  GST_DEBUG ("Attempting to listen on port %d.....",port);

  if ( (fd = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
  {
    gchar error_str[256];
    strerror_r (errno, error_str, 256);
    g_set_error (error, FS_ERROR, FS_ERROR_NETWORK,
        "Could not create socket: %s", error_str);
    goto error;
  }

  // set non-blocking mode
  fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
  for (;;) {
    GST_DEBUG ("Attempting to listen on port %d.....",port);
    memset(&myaddr, 0, sizeof(myaddr));
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons (port);
    // bind
    if (bind(fd, (struct sockaddr *) &myaddr, sizeof(myaddr)) != 0)
    {
      if (port != 0 && errno == EADDRINUSE)
      {
        port++;
      }
      else
      {
        gchar error_str[256];
        strerror_r (errno, error_str, 256);
        g_set_error (error, FS_ERROR, FS_ERROR_NETWORK,
            "Could not bind socket: %s", error_str);
        goto error;
      }
    } else {
      /* Listen */
      if (listen(fd, 3) != 0)
      {
        if (port != 0 && errno == EADDRINUSE)
        {
          port++;
        }
        else
        {
          gchar error_str[256];
          strerror_r (errno, error_str, 256);
          g_set_error (error, FS_ERROR, FS_ERROR_NETWORK,
              "Could not listen on socket: %s", error_str);
          goto error;
        }
      }
      else
      {
        goto done;
      }
    }
  }

 done:

  if (getsockname (fd, (struct sockaddr *) &myaddr, &myaddr_len) < 0) {
    gchar error_str[256];
    strerror_r (errno, error_str, 256);
    g_set_error (error, FS_ERROR, FS_ERROR_NETWORK,
        "Could not get the socket name: %s", error_str);
    goto error;
  }
  port = ntohs (myaddr.sin_port);
  add_pollfd_locked (self, fd, accept_connection_cb, TRUE, TRUE, FALSE);

  GST_DEBUG ("Listening on port %d", port);

  self->local_recipient_id = g_strdup_printf ("%d",
      g_random_int_range (100, 199));
  session_id = g_strdup_printf ("%u", self->session_id);

  FS_MSN_CONNECTION_UNLOCK (self);

  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);
    candidate->username = g_strdup (session_id);

    g_signal_emit (self, signals[SIGNAL_NEW_LOCAL_CANDIDATE], 0, candidate);

    fs_candidate_destroy (candidate);
  }

  g_free (session_id);

  g_list_foreach (addresses, (GFunc) g_free, NULL);
  g_list_free (addresses);

  return TRUE;

 error:
  if (fd >= 0)
    close (fd);
  g_list_foreach (addresses, (GFunc) g_free, NULL);
  g_list_free (addresses);
  FS_MSN_CONNECTION_UNLOCK (self);
  return FALSE;
}
gboolean
fs_rawudp_component_set_remote_candidate (FsRawUdpComponent *self,
    FsCandidate *candidate,
    GError **error)
{
  FsCandidate *old_candidate = NULL;
  gboolean sending;
  GInetAddress *addr;

  if (candidate->component_id != self->priv->component)
  {
    g_set_error (error, FS_ERROR, FS_ERROR_INTERNAL,
        "Remote candidate routed to wrong component (%d->%d)",
        candidate->component_id,
        self->priv->component);
    return FALSE;
  }

  addr = g_inet_address_new_from_string (candidate->ip);
  if (addr == NULL)
  {
    g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS,
        "Invalid address passed: %s", candidate->ip);
    return FALSE;
  }

  FS_RAWUDP_COMPONENT_LOCK (self);

  if (!self->priv->udpport)
  {
    g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS,
        "Can't call set_remote_candidate after the thread has been stopped");
    FS_RAWUDP_COMPONENT_UNLOCK (self);
    g_object_unref (addr);
    return FALSE;
  }

  if (self->priv->remote_candidate)
    fs_rawudp_transmitter_udpport_remove_known_address (self->priv->udpport,
        self->priv->remote_address, remote_is_unique_cb, self);

  old_candidate = self->priv->remote_candidate;
  self->priv->remote_candidate = fs_candidate_copy (candidate);
  sending = self->priv->sending;

  g_clear_object (&self->priv->remote_address);

  self->priv->remote_address = g_inet_socket_address_new (addr,
      candidate->port);
  g_object_unref (addr);

  self->priv->remote_is_unique =
    fs_rawudp_transmitter_udpport_add_known_address (self->priv->udpport,
        self->priv->remote_address, remote_is_unique_cb, self);

  FS_RAWUDP_COMPONENT_UNLOCK (self);

  if (sending)
    fs_rawudp_transmitter_udpport_add_dest (self->priv->udpport,
        candidate->ip, candidate->port);
  else
    fs_rawudp_transmitter_udpport_add_recvonly_dest (self->priv->udpport,
        candidate->ip, candidate->port);

  if (old_candidate)
  {
    if (sending)
      fs_rawudp_transmitter_udpport_remove_dest (self->priv->udpport,
          old_candidate->ip,
          old_candidate->port);
    else
      fs_rawudp_transmitter_udpport_remove_recvonly_dest (self->priv->udpport,
          candidate->ip,
          candidate->port);
    fs_candidate_destroy (old_candidate);
  }

  fs_rawudp_component_maybe_new_active_candidate_pair (self);

  return TRUE;
}
static void
fs_rawudp_component_set_property (GObject *object,
    guint prop_id,
    const GValue *value,
    GParamSpec *pspec)
{
  FsRawUdpComponent *self = FS_RAWUDP_COMPONENT (object);

  switch (prop_id)
  {
    case PROP_COMPONENT:
      self->priv->component = g_value_get_uint (value);
      break;
    case PROP_SENDING:
      {
        gboolean sending, old_sending;
        FsCandidate *candidate = NULL;

        g_return_if_fail (self->priv->udpport);


        FS_RAWUDP_COMPONENT_LOCK (self);
        old_sending = self->priv->sending;
        sending = self->priv->sending = g_value_get_boolean (value);
        if (self->priv->remote_candidate)
          candidate = fs_candidate_copy (self->priv->remote_candidate);
        FS_RAWUDP_COMPONENT_UNLOCK (self);

        if (sending != old_sending && candidate)
        {
          if (sending)
          {
            fs_rawudp_transmitter_udpport_remove_recvonly_dest (
                self->priv->udpport, candidate->ip, candidate->port);
            fs_rawudp_transmitter_udpport_add_dest (self->priv->udpport,
                candidate->ip, candidate->port);
          }
          else
          {
            fs_rawudp_transmitter_udpport_remove_dest (self->priv->udpport,
                candidate->ip, candidate->port);
            fs_rawudp_transmitter_udpport_add_recvonly_dest (
                self->priv->udpport, candidate->ip, candidate->port);
          }
        }
        if (candidate)
          fs_candidate_destroy (candidate);
      }
      break;
    case PROP_IP:
      g_free (self->priv->ip);
      self->priv->ip = g_value_dup_string (value);
      break;
    case PROP_PORT:
      self->priv->port = g_value_get_uint (value);
      break;
    case PROP_STUN_IP:
      g_free (self->priv->stun_ip);
      self->priv->stun_ip = g_value_dup_string (value);
      break;
    case PROP_STUN_PORT:
      self->priv->stun_port = g_value_get_uint (value);
      break;
    case PROP_STUN_TIMEOUT:
      self->priv->stun_timeout = g_value_get_uint (value);
      break;
    case PROP_TRANSMITTER:
      self->priv->transmitter = g_value_dup_object (value);
      break;
    case PROP_FORCED_CANDIDATE:
      FS_RAWUDP_COMPONENT_LOCK (self);
      if (self->priv->local_forced_candidate)
        GST_WARNING ("Tried to reset a forced candidate");
      else
        self->priv->local_forced_candidate = g_value_dup_boxed (value);
      FS_RAWUDP_COMPONENT_UNLOCK (self);
      break;
    case PROP_ASSOCIATE_ON_SOURCE:
      self->priv->associate_on_source = g_value_get_boolean (value);
      break;
#ifdef HAVE_GUPNP
    case PROP_UPNP_MAPPING:
      self->priv->upnp_mapping = g_value_get_boolean (value);
      break;
    case PROP_UPNP_DISCOVERY:
      self->priv->upnp_discovery = g_value_get_boolean (value);
      break;
    case PROP_UPNP_MAPPING_TIMEOUT:
      self->priv->upnp_mapping_timeout = g_value_get_uint (value);
      break;
    case PROP_UPNP_DISCOVERY_TIMEOUT:
      self->priv->upnp_discovery_timeout = g_value_get_uint (value);
      break;
    case PROP_UPNP_IGD:
      self->priv->upnp_igd = g_value_dup_object (value);
      break;
#endif
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}