Пример #1
0
static void
member_content_removed_cb (GabbleCallMemberContent *mcontent,
    gpointer user_data)
{
  GabbleCallContent *self = GABBLE_CALL_CONTENT (user_data);
  GabbleCallContentPrivate *priv = self->priv;
  TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self);
  GabbleJingleContent *content;
  GList *l;

  priv->contents = g_list_remove (priv->contents, mcontent);

  content = gabble_call_member_content_get_jingle_content (mcontent);

  for (l = tp_base_call_content_get_streams (base);
       l != NULL;
       l = l->next)
    {
      GabbleCallStream *stream = GABBLE_CALL_STREAM (l->data);

      if (content == gabble_call_stream_get_jingle_content (stream))
        {
          tp_base_call_content_remove_stream (base, l->data,
              0, TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", "");
          break;
        }
    }
}
static void
new_content (RakiaCallChannel *self,
    const gchar *name,
    RakiaSipMedia *media,
    TpCallContentDisposition disposition)
{
  TpBaseChannel *bchan = TP_BASE_CHANNEL (self);
  RakiaCallContent *content;
  TpMediaStreamType media_type;
  TpHandle creator;
  gchar *object_path;
  gchar *free_name = NULL;
  const gchar *media_type_name;

  switch (rakia_sip_media_get_media_type (media))
    {
    case TP_MEDIA_STREAM_TYPE_AUDIO:
      media_type = TP_MEDIA_STREAM_TYPE_AUDIO;
      media_type_name = "Audio";
      break;
    case TP_MEDIA_STREAM_TYPE_VIDEO:
      media_type = TP_MEDIA_STREAM_TYPE_VIDEO;
      media_type_name = "Video";
      break;
    default:
      g_assert_not_reached ();
    }

  if (rakia_sip_media_is_created_locally (media))
    creator = tp_base_channel_get_self_handle (bchan);
  else
    creator = tp_base_channel_get_target_handle (bchan);

  object_path = g_strdup_printf ("%s/Content%u",
      tp_base_channel_get_object_path (bchan), ++self->priv->last_content_no);

  if (name == NULL)
    name = free_name = g_strdup_printf ("%s %u", media_type_name,
        self->priv->last_content_no);

  /* We already request bidi for initial media,
   * the client can change it before accepting.
   */
  if (disposition == TP_CALL_CONTENT_DISPOSITION_INITIAL)
    rakia_sip_media_set_requested_direction (media,
        TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL);


  content = rakia_call_content_new (self, media, object_path,
      tp_base_channel_get_connection (bchan), name,
      media_type, creator, disposition);

  g_free (free_name);
  g_free (object_path);

  tp_base_call_channel_add_content (TP_BASE_CALL_CHANNEL (self),
      TP_BASE_CALL_CONTENT (content));

  rakia_call_content_add_stream (content);
}
Пример #3
0
JingleMediaType
gabble_call_content_get_media_type (GabbleCallContent *self)
{
  TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self);

  return jingle_media_type_from_tp (
      tp_base_call_content_get_media_type (base));
}
Пример #4
0
static void
call_content_setup_jingle (GabbleCallContent *self,
    GabbleCallMemberContent *mcontent)
{
  TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self);
  GabbleJingleContent *jingle;
  GabbleCallStream *stream;
  gchar *path;
  JingleTransportType transport;
  JingleMediaDescription *md;
  GHashTable *tp_md;
  TpHandle contact;

  jingle = gabble_call_member_content_get_jingle_content (mcontent);

  if (jingle == NULL)
    return;

  transport = gabble_jingle_content_get_transport_type (jingle);
  path = g_strdup_printf ("%s/Stream%p",
      tp_base_call_content_get_object_path (base),
      jingle);
  stream = g_object_new (GABBLE_TYPE_CALL_STREAM,
      "object-path", path,
      "connection", tp_base_call_content_get_connection (base),
      "jingle-content", jingle,
      "transport", _jingle_to_tp_transport (transport),
      NULL);
  g_free (path);

  md = jingle_media_description_new ();

  /* FIXME: correct??? */
  contact = gabble_call_member_get_handle (
      gabble_call_member_content_get_member (mcontent));
  tp_md = tp_base_media_call_content_get_local_media_description (
      TP_BASE_MEDIA_CALL_CONTENT (self), contact);
  if (tp_md != NULL)
    {
      md->codecs = codec_array_to_list (tp_asv_get_boxed (tp_md,
          TP_PROP_CALL_CONTENT_MEDIA_DESCRIPTION_CODECS,
          TP_ARRAY_TYPE_CODEC_LIST));
    }

  if (md->codecs != NULL)
    jingle_media_rtp_set_local_media_description (
        GABBLE_JINGLE_MEDIA_RTP (jingle), md, TRUE, NULL);
  else
    jingle_media_description_free (md);

  tp_base_call_content_add_stream (base, TP_BASE_CALL_STREAM (stream));
  gabble_call_stream_update_member_states (stream);
  g_object_unref (stream);
}
static void
media_remote_codecs_updated_cb (RakiaSipMedia *media, gboolean is_offer,
    RakiaCallContent *self)
{
  TpBaseCallContent *bcc = TP_BASE_CALL_CONTENT (self);
  TpBaseMediaCallContent *bmcc = TP_BASE_MEDIA_CALL_CONTENT (self);
  RakiaCallContentPrivate *priv = self->priv;
  GPtrArray *remote_codecs =
      rakia_sip_media_get_remote_codec_offer (priv->media);
  TpCallContentMediaDescription *md;
  TpDBusDaemon *bus = tp_base_connection_get_dbus_daemon (
      tp_base_call_content_get_connection (bcc));
  gchar *object_path;
  guint i, j;

  if (remote_codecs == NULL)
    return;

  object_path = g_strdup_printf ("%s/Offer%u",
      tp_base_call_content_get_object_path (bcc), ++priv->codec_offer_id);

  md = tp_call_content_media_description_new (bus, object_path,
      tp_base_channel_get_target_handle (TP_BASE_CHANNEL (priv->channel)),
      TRUE, is_offer);

  g_free (object_path);

  for (i = 0; i < remote_codecs->len; i++)
    {
      RakiaSipCodec *codec = g_ptr_array_index (remote_codecs, i);
      GHashTable *parameters = g_hash_table_new (g_str_hash, g_str_equal);

      /* No need to copy the values as .._append_codec() will */
      if (codec->params)
        for (j = 0; j < codec->params->len; j++)
          {
            RakiaSipCodecParam *param = g_ptr_array_index (codec->params, j);

            g_hash_table_insert (parameters, param->name, param->value);
          }

      tp_call_content_media_description_append_codec (md, codec->id,
          codec->encoding_name, codec->clock_rate, codec->channels, TRUE,
          parameters);

      g_hash_table_unref (parameters);
    }

  tp_base_media_call_content_offer_media_description_async (bmcc,
      md, md_offer_cb, GUINT_TO_POINTER (FALSE));

  g_object_unref (md);
}
Пример #6
0
void
gabble_call_content_new_offer (GabbleCallContent *self,
  GabbleCallMemberContent *content)
{
  GabbleCallContentPrivate *priv = self->priv;
  TpBaseCallContent *base = TP_BASE_CALL_CONTENT (self);
  TpBaseConnection *conn = tp_base_call_content_get_connection (base);
  TpCallContentMediaDescription *md;
  gchar *path;
  TpHandle handle = 0;

  path = g_strdup_printf ("%s/Offer%d",
      tp_base_call_content_get_object_path (base),
      priv->offers++);

  if (content != NULL)
    {
      handle = gabble_call_member_get_handle (
        gabble_call_member_content_get_member (content));
    }

  /* FIXME: no idea... */
  md = tp_call_content_media_description_new (
      tp_base_connection_get_dbus_daemon (conn), path, handle,
      (content != NULL), (content == NULL));

  if (content != NULL)
    {
      GList *codecs, *l;

      codecs = gabble_call_member_content_get_remote_codecs (content);
      for (l = codecs; l != NULL; l = g_list_next (l))
        {
          JingleCodec *c = l->data;

          tp_call_content_media_description_append_codec (md,
              c->id, c->name, c->clockrate, c->channels,
              FALSE, /* FIXME: updated?? */
              c->params);
        }
    }

  /* FIXME: We have to handle cases where the new codecs are rejected */
  tp_base_media_call_content_offer_media_description_async (
      TP_BASE_MEDIA_CALL_CONTENT (self), md, NULL, NULL);

  g_object_unref (md);
  g_free (path);
}
static void
media_removed_cb (RakiaSipSession *session, RakiaSipMedia *media,
    RakiaCallChannel *self)
{
  RakiaCallContent *content;

  content = rakia_call_channel_get_content_by_media (self, media);
  if (content == NULL)
    return;

  tp_base_call_channel_remove_content (TP_BASE_CALL_CHANNEL (self),
      TP_BASE_CALL_CONTENT (content),
      tp_base_channel_get_target_handle (TP_BASE_CHANNEL (self)),
      TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", "Removed by remote side");
}
void
rakia_call_content_add_stream (RakiaCallContent *self)
{
  RakiaCallContentPrivate *priv = self->priv;
  TpBaseCallContent *bcc = TP_BASE_CALL_CONTENT (self);
  gchar *object_path;

  object_path = g_strdup_printf ("%s/Stream",
      tp_base_call_content_get_object_path (bcc));
  priv->stream = rakia_call_stream_new (self, priv->media,
      object_path, TP_STREAM_TRANSPORT_TYPE_RAW_UDP,
      tp_base_call_content_get_connection (bcc));
  g_free (object_path);

  tp_base_call_content_add_stream (bcc, TP_BASE_CALL_STREAM (priv->stream));
}
static void
rakia_call_content_constructed (GObject *object)
{
  RakiaCallContent *self = RAKIA_CALL_CONTENT (object);
  RakiaCallContentPrivate *priv = self->priv;
  TpBaseChannel *bchan = TP_BASE_CHANNEL (priv->channel);
  TpBaseCallContent *bcc = TP_BASE_CALL_CONTENT (self);
  TpBaseMediaCallContent *bmcc = TP_BASE_MEDIA_CALL_CONTENT (self);
  TpHandle creator;
  gchar *object_path;

  g_signal_connect_object (priv->media, "remote-codec-offer-updated",
      G_CALLBACK (media_remote_codecs_updated_cb), self, 0);

  g_signal_connect (self, "local-media-description-updated",
      G_CALLBACK (local_media_description_updated), NULL);

  g_object_get (object, "creator", &creator, NULL);

  if (creator == tp_base_channel_get_self_handle (bchan))
    {
      TpCallContentMediaDescription *md;
      TpDBusDaemon *bus = tp_base_connection_get_dbus_daemon (
          tp_base_call_content_get_connection (bcc));

      object_path = g_strdup_printf ("%s/InitialOffer",
          tp_base_call_content_get_object_path (bcc));

      md = tp_call_content_media_description_new (bus, object_path,
          tp_base_channel_get_target_handle (bchan), FALSE, TRUE);
      g_free (object_path);

      tp_base_media_call_content_offer_media_description_async (bmcc,
          md, md_offer_cb, GUINT_TO_POINTER (TRUE));
    }
  else
    {
      media_remote_codecs_updated_cb (priv->media, TRUE, self);
    }

  G_OBJECT_CLASS (rakia_call_content_parent_class)->constructed (object);
}
static TpBaseCallContent *
rakia_call_channel_add_content (
    TpBaseCallChannel *base,
    const gchar *name,
    TpMediaStreamType type,
    TpMediaStreamDirection initial_direction,
    GError **error)
{
  RakiaCallChannel *self = RAKIA_CALL_CHANNEL (base);
  RakiaCallChannelPrivate *priv = self->priv;
  RakiaCallContent *content;
  RakiaSipMedia *media;

  media = rakia_sip_session_add_media (priv->session,
      type, name, initial_direction);

  content = rakia_call_channel_get_content_by_media (self, media);

  return TP_BASE_CALL_CONTENT (content);

}