summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2012-02-29 15:36:44 -0500
committerOlivier CrĂȘte <olivier.crete@collabora.com>2012-02-29 15:36:44 -0500
commitd90b713b5198cb6e0bb3e4c79b99198dec122806 (patch)
treee4d332b3498cba9c22a0648f2a87dab69791c8f1
parent1d3e7ce04fa738443b382455625503d2d258ddfe (diff)
Remove old streamed media files
-rw-r--r--rakia/media-channel.c2032
-rw-r--r--rakia/media-channel.h94
-rw-r--r--rakia/media-session.c1249
-rw-r--r--rakia/media-session.h105
-rw-r--r--rakia/media-stream.c1532
-rw-r--r--rakia/media-stream.h93
6 files changed, 0 insertions, 5105 deletions
diff --git a/rakia/media-channel.c b/rakia/media-channel.c
deleted file mode 100644
index dc0c5b7..0000000
--- a/rakia/media-channel.c
+++ /dev/null
@@ -1,2032 +0,0 @@
-/*
- * sip-media-channel.c - Source for RakiaMediaChannel
- * Copyright (C) 2005-2008 Collabora Ltd.
- * Copyright (C) 2005-2010 Nokia Corporation
- * @author Kai Vehmanen <first.surname@nokia.com>
- * @author Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
- *
- * Based on telepathy-gabble implementation (gabble-media-channel).
- * @author Ole Andre Vadla Ravnaas <ole.andre.ravnaas@collabora.co.uk>
- *
- * This work is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This work is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this work; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include "rakia/media-channel.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <telepathy-glib/channel-iface.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/dtmf.h>
-#include <telepathy-glib/errors.h>
-#include <telepathy-glib/exportable-channel.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/svc-channel.h>
-
-#include <rakia/event-target.h>
-
-#define DEBUG_FLAG RAKIA_DEBUG_MEDIA
-#include "rakia/debug.h"
-
-#include <rakia/media-session.h>
-#include <rakia/base-connection.h>
-#include <rakia/sip-session.h>
-
-#define RAKIA_CHANNEL_CALL_STATE_PROCEEDING_MASK \
- (TP_CHANNEL_CALL_STATE_RINGING | \
- TP_CHANNEL_CALL_STATE_QUEUED | \
- TP_CHANNEL_CALL_STATE_IN_PROGRESS)
-
-/* DTMF dialstring playback durations in milliseconds */
-#define RAKIA_DTMF_TONE_DURATION 250
-#define RAKIA_DTMF_GAP_DURATION 100
-#define RAKIA_DTMF_PAUSE_DURATION 3000
-
-static void event_target_init (gpointer, gpointer);
-static void channel_iface_init (gpointer, gpointer);
-static void media_signalling_iface_init (gpointer, gpointer);
-static void streamed_media_iface_init (gpointer, gpointer);
-static void dtmf_iface_init (gpointer, gpointer);
-static void call_state_iface_init (gpointer, gpointer);
-static void hold_iface_init (gpointer, gpointer);
-
-static void priv_session_dtmf_ready_cb (RakiaMediaSession *session,
- RakiaMediaChannel *channel);
-
-G_DEFINE_TYPE_WITH_CODE (RakiaMediaChannel, rakia_media_channel,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (RAKIA_TYPE_EVENT_TARGET, event_target_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_PROPERTIES_INTERFACE,
- tp_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
- tp_group_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
- media_signalling_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DTMF,
- dtmf_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CALL_STATE,
- call_state_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_HOLD,
- hold_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAMED_MEDIA,
- streamed_media_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL);
- G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));
-
-static const gchar *rakia_media_channel_interfaces[] = {
- TP_IFACE_CHANNEL_INTERFACE_GROUP,
- TP_IFACE_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
- TP_IFACE_CHANNEL_INTERFACE_DTMF,
- TP_IFACE_CHANNEL_INTERFACE_CALL_STATE,
- TP_IFACE_CHANNEL_INTERFACE_HOLD,
- TP_IFACE_PROPERTIES_INTERFACE,
- NULL
-};
-
-/* properties */
-enum
-{
- PROP_CONNECTION = 1,
- PROP_OBJECT_PATH,
- PROP_CHANNEL_TYPE,
- PROP_HANDLE_TYPE,
- PROP_HANDLE,
- PROP_TARGET_ID,
- PROP_INITIATOR,
- PROP_INITIATOR_ID,
- PROP_REQUESTED,
- PROP_INTERFACES,
- PROP_CHANNEL_DESTROYED,
- PROP_CHANNEL_PROPERTIES,
- PROP_INITIAL_AUDIO,
- PROP_INITIAL_VIDEO,
- PROP_IMMUTABLE_STREAMS,
- PROP_CURRENTLY_SENDING_TONES,
- PROP_INITIAL_TONES,
- PROP_DEFERRED_TONES,
- PROP_SIP_SESSION,
- /* Telepathy properties (see below too) */
- PROP_NAT_TRAVERSAL,
- PROP_STUN_SERVER,
- PROP_STUN_PORT,
- LAST_PROPERTY
-};
-
-/* TP channel properties */
-enum
-{
- TP_PROP_NAT_TRAVERSAL = 0,
- TP_PROP_STUN_SERVER,
- TP_PROP_STUN_PORT,
- NUM_TP_PROPS
-};
-
-static const TpPropertySignature media_channel_property_signatures[NUM_TP_PROPS] =
-{
- { "nat-traversal", G_TYPE_STRING },
- { "stun-server", G_TYPE_STRING },
- { "stun-port", G_TYPE_UINT },
-};
-
-/* signals */
-enum
-{
- NUM_SIGNALS
-};
-
-//static guint signals[NUM_SIGNALS] = { 0 };
-
-
-/* private structure */
-struct _RakiaMediaChannelPrivate
-{
- RakiaBaseConnection *conn;
- RakiaMediaSession *session;
- RakiaSipSession *sipsession;
- gchar *object_path;
- TpHandle handle;
- TpHandle initiator;
- GHashTable *call_states;
- gchar *stun_server;
- guint stun_port;
- TpDTMFPlayer *dtmf_player;
- gchar *initial_tones;
- gchar *deferred_tones;
-
- gboolean initial_audio;
- gboolean initial_video;
- gboolean immutable_streams;
- gboolean closed;
- gboolean dispose_has_run;
-};
-
-
-
-static void rakia_media_channel_dispose (GObject *object);
-static void rakia_media_channel_finalize (GObject *object);
-static void rakia_media_channel_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-static void rakia_media_channel_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-
-static void priv_create_session (RakiaMediaChannel *channel,
- TpHandle peer);
-static void priv_destroy_session(RakiaMediaChannel *channel);
-
-static gboolean rakia_media_channel_remove_with_reason (
- GObject *iface,
- TpHandle handle,
- const gchar *message,
- guint reason,
- GError **error);
-static void priv_session_state_changed_cb (RakiaSipSession *session,
- guint old_state,
- guint state,
- RakiaMediaChannel *channel);
-
-
-#define RAKIA_MEDIA_CHANNEL_GET_PRIVATE(chan) ((chan)->priv)
-
-/***********************************************************************
- * Set: Gobject interface
- ***********************************************************************/
-
-static void
-rakia_media_channel_init (RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (self,
- RAKIA_TYPE_MEDIA_CHANNEL, RakiaMediaChannelPrivate);
-
- self->priv = priv;
-
- /* allocate any data required by the object here */
- priv->call_states = g_hash_table_new (NULL, NULL);
-
- /* initialise the properties mixin *before* GObject
- * sets the construct-time properties */
- tp_properties_mixin_init (G_OBJECT (self),
- G_STRUCT_OFFSET (RakiaMediaChannel, properties));
-}
-
-
-
-static void
-session_ringing_cb (RakiaSipSession *sipsession, RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- rakia_media_channel_change_call_state (self, priv->handle,
- TP_CHANNEL_CALL_STATE_RINGING, 0);
-}
-
-static void
-session_queued_cb (RakiaSipSession *sipsession, RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- rakia_media_channel_change_call_state (self, priv->handle,
- TP_CHANNEL_CALL_STATE_QUEUED, 0);
-}
-
-static void
-session_in_progress_cb (RakiaSipSession *sipsession, RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- rakia_media_channel_change_call_state (self, priv->handle,
- TP_CHANNEL_CALL_STATE_IN_PROGRESS, 0);
-}
-
-static void
-session_established_cb (RakiaSipSession *sipsession, RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
- TpIntSet *add = tp_intset_new_containing (priv->handle);
-
- tp_group_mixin_change_members ((GObject *) self,
- "",
- add, /* add */
- NULL, /* remove */
- NULL,
- NULL,
- priv->handle,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
- tp_intset_destroy (add);
-}
-
-static void
-session_ended_cb (RakiaSipSession *sipsession, gboolean self_actor,
- guint cause, gchar *message, RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
- TpGroupMixin *mixin = TP_GROUP_MIXIN (self);
- TpIntSet *remove;
- TpHandle actor;
- TpChannelGroupChangeReason reason;
-
- remove = tp_intset_new ();
- tp_intset_add (remove, priv->handle);
- tp_intset_add (remove, mixin->self_handle);
-
- if (self_actor)
- actor = mixin->self_handle;
- else
- actor = priv->handle;
-
- if (message == NULL)
- message = "";
-
- switch (cause)
- {
- case 410:
- case 604:
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_INVALID_CONTACT;
- break;
- case 486:
- case 600:
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_BUSY;
- break;
- case 408:
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER;
- break;
- case 404:
- case 480:
- if (rakia_sip_session_get_state (priv->sipsession) <=
- RAKIA_SIP_SESSION_STATE_INVITE_SENT)
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER;
- else
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_OFFLINE;
- break;
- case 603:
- /* No reason means roughly "rejected" */
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_NONE;
- break;
- case 403:
- case 401:
- case 407:
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED;
- break;
- default:
- if (cause < 300)
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_NONE;
- else
- reason = TP_CHANNEL_GROUP_CHANGE_REASON_ERROR;
- break;
- }
-
- tp_group_mixin_change_members ((GObject *) self, message,
- NULL, remove, NULL, NULL, actor, reason);
-
- tp_intset_destroy (remove);
-
-}
-
-
-static void
-rakia_media_channel_constructed (GObject *obj)
-{
- RakiaMediaChannel *chan = RAKIA_MEDIA_CHANNEL (obj);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (chan);
- TpBaseConnection *conn = (TpBaseConnection *)(priv->conn);
- GObjectClass *parent_object_class =
- G_OBJECT_CLASS (rakia_media_channel_parent_class);
- TpDBusDaemon *bus;
- TpHandleRepoIface *contact_repo;
- TpIntSet *add;
-
- if (parent_object_class->constructed != NULL)
- parent_object_class->constructed (obj);
-
- contact_repo = tp_base_connection_get_handles (conn,
- TP_HANDLE_TYPE_CONTACT);
-
- if (priv->handle != 0)
- tp_handle_ref (contact_repo, priv->handle);
-
- /* register object on the bus */
- bus = tp_base_connection_get_dbus_daemon (conn);
-
- DEBUG("registering object to dbus path=%s", priv->object_path);
- tp_dbus_daemon_register_object (bus, priv->object_path, obj);
-
- /* initialize group mixin */
- tp_group_mixin_init (obj,
- G_STRUCT_OFFSET (RakiaMediaChannel, group),
- contact_repo,
- conn->self_handle);
-
- /* automatically add initiator to channel, but also ref them again (because
- * priv->initiator is the InitiatorHandle) */
- g_assert (priv->initiator != 0);
- tp_handle_ref (contact_repo, priv->initiator);
-
- add = tp_intset_new_containing (priv->initiator);
- tp_group_mixin_change_members (obj, "", add, NULL, NULL, NULL, 0, 0);
- tp_intset_destroy (add);
-
- /* We start off with lots of flags, and then delete them as we work out what
- * kind of channel we are, rather than trying to track what we need to
- * add/remove over time. We should always have the right flags before we are
- * advertised on the bus. */
- tp_group_mixin_change_flags (obj,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD | TP_CHANNEL_GROUP_FLAG_CAN_REMOVE |
- TP_CHANNEL_GROUP_FLAG_CAN_RESCIND | TP_CHANNEL_GROUP_FLAG_PROPERTIES, 0);
-
- g_signal_connect_object (priv->sipsession, "ringing",
- G_CALLBACK (session_ringing_cb), chan, 0);
- g_signal_connect_object (priv->sipsession, "queued",
- G_CALLBACK (session_queued_cb), chan, 0);
- g_signal_connect_object (priv->sipsession, "in-progress",
- G_CALLBACK (session_in_progress_cb), chan, 0);
- g_signal_connect_object (priv->sipsession, "established",
- G_CALLBACK (session_established_cb), chan, 0);
- g_signal_connect_object (priv->sipsession, "ended",
- G_CALLBACK (session_ended_cb), chan, 0);
- g_signal_connect_object (priv->sipsession,
- "state-changed", G_CALLBACK(priv_session_state_changed_cb), chan, 0);
-
- if (priv->initiator != conn->self_handle)
- {
- /* Incoming */
- priv->initial_audio = rakia_sip_session_has_media (priv->sipsession,
- TP_MEDIA_STREAM_TYPE_AUDIO);
- priv->initial_video = rakia_sip_session_has_media (priv->sipsession,
- TP_MEDIA_STREAM_TYPE_VIDEO);
- priv_create_session (chan, priv->initiator);
-
- g_assert (priv->session != NULL);
- //rakia_sip_session_receive_invite (priv->sipsession);
- }
- else
- {
- priv_create_session (chan, priv->handle);
- }
-
-}
-static void
-rakia_media_channel_class_init (RakiaMediaChannelClass *klass)
-{
- static TpDBusPropertiesMixinPropImpl channel_props[] = {
- { "ChannelType", "channel-type", NULL },
- { "Interfaces", "interfaces", NULL },
- { "TargetHandleType", "handle-type", NULL },
- { "TargetHandle", "handle", NULL },
- { "TargetID", "target-id", NULL },
- { "InitiatorHandle", "initiator", NULL },
- { "InitiatorID", "initiator-id", NULL },
- { "Requested", "requested", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinPropImpl streamed_media_props[] = {
- { "InitialAudio", "initial-audio", NULL },
- { "InitialVideo", "initial-video", NULL },
- { "ImmutableStreams", "immutable-streams", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinPropImpl dtmf_props[] = {
- { "CurrentlySendingTones", "currently-sending-tones", NULL },
- { "InitialTones", "initial-tones", NULL },
- { "DeferredTones", "deferred-tones", 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,
- },
- { TP_IFACE_CHANNEL_INTERFACE_DTMF,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- dtmf_props,
- },
- { NULL }
- };
-
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- DEBUG("enter");
-
- g_type_class_add_private (klass, sizeof (RakiaMediaChannelPrivate));
-
- object_class->constructed = rakia_media_channel_constructed;
- object_class->dispose = rakia_media_channel_dispose;
- object_class->finalize = rakia_media_channel_finalize;
-
- object_class->get_property = rakia_media_channel_get_property;
- object_class->set_property = rakia_media_channel_set_property;
-
- g_object_class_override_property (object_class, PROP_HANDLE_TYPE,
- "handle-type");
- g_object_class_override_property (object_class, PROP_HANDLE, "handle");
- g_object_class_override_property (object_class, PROP_OBJECT_PATH,
- "object-path");
- g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
- "channel-type");
-
- g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED,
- "channel-destroyed");
- g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES,
- "channel-properties");
-
- param_spec = g_param_spec_object ("connection", "RakiaConnection object",
- "SIP connection object that owns this SIP media channel object.",
- RAKIA_TYPE_BASE_CONNECTION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
-
- param_spec = g_param_spec_string ("nat-traversal", "NAT traversal mechanism",
- "A string representing the type of NAT traversal that should be "
- "performed for streams on this channel.",
- "none",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_NAT_TRAVERSAL, param_spec);
-
- param_spec = g_param_spec_object ("sip-session", "RakiaSipSession object",
- "SIP session object that is used for this SIP media channel object.",
- RAKIA_TYPE_SIP_SESSION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_SIP_SESSION, param_spec);
-
- param_spec = g_param_spec_string ("stun-server", "STUN server",
- "IP or address of STUN server.", NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_SERVER, param_spec);
-
- param_spec = g_param_spec_uint ("stun-port", "STUN port",
- "UDP port of STUN server.", 0, G_MAXUINT16, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_PORT, param_spec);
-
- param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
- "Addition Channel.Interface.* interfaces", G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
-
- param_spec = g_param_spec_string ("target-id", "Target SIP URI",
- "Currently empty, because this channel always has handle 0.",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
-
- param_spec = g_param_spec_uint ("initiator", "Channel initiator",
- "The TpHandle representing the contact who created the channel.",
- 0, G_MAXUINT32, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIATOR, param_spec);
-
- param_spec = g_param_spec_string ("initiator-id", "Creator URI",
- "The URI obtained by inspecting the initiator handle.",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIATOR_ID, param_spec);
-
- param_spec = g_param_spec_boolean ("requested", "Requested?",
- "True if this channel was requested by the local user",
- FALSE,
- 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);
-
- param_spec = g_param_spec_boolean ("immutable-streams", "ImmutableStreams",
- "Whether the set of streams on this channel are fixed once requested",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_IMMUTABLE_STREAMS,
- param_spec);
-
- param_spec = g_param_spec_boolean ("currently-sending-tones",
- "Currently sending tones",
- "True if the channel is currently sending DTMF tones",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CURRENTLY_SENDING_TONES,
- param_spec);
-
- param_spec = g_param_spec_string ("initial-tones", "Initial tones",
- "The initial DTMF tones to send after audio stream(s) are established.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_TONES,
- param_spec);
-
- param_spec = g_param_spec_string ("deferred-tones", "Deferred tones",
- "The DTMF tones deferred waiting for user input.",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DEFERRED_TONES,
- param_spec);
-
-
- tp_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (RakiaMediaChannelClass, properties_class),
- media_channel_property_signatures, NUM_TP_PROPS, NULL);
-
- klass->dbus_props_class.interfaces =
- prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (RakiaMediaChannelClass, dbus_props_class));
-
- tp_group_mixin_class_init (object_class,
- G_STRUCT_OFFSET (RakiaMediaChannelClass, group_class),
- _rakia_media_channel_add_member,
- NULL);
- tp_group_mixin_class_allow_self_removal (object_class);
- tp_group_mixin_class_set_remove_with_reason_func(object_class,
- rakia_media_channel_remove_with_reason);
- tp_group_mixin_init_dbus_properties (object_class);
-
-}
-
-static void
-rakia_media_channel_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- RakiaMediaChannel *chan = RAKIA_MEDIA_CHANNEL (object);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (chan);
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
-
- switch (property_id) {
- case PROP_CONNECTION:
- g_value_set_object (value, priv->conn);
- break;
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_CHANNEL_TYPE:
- g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
- break;
- case PROP_HANDLE:
- g_value_set_uint (value, priv->handle);
- break;
- case PROP_HANDLE_TYPE:
- g_value_set_uint (value, priv->handle?
- TP_HANDLE_TYPE_CONTACT : TP_HANDLE_TYPE_NONE);
- break;
- case PROP_TARGET_ID:
- if (priv->handle != 0)
- {
- TpHandleRepoIface *repo = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
-
- g_value_set_string (value, tp_handle_inspect (repo, priv->handle));
- }
- else
- g_value_set_static_string (value, "");
- break;
- case PROP_INITIATOR:
- g_value_set_uint (value, priv->initiator);
- break;
- case PROP_INITIATOR_ID:
- {
- TpHandleRepoIface *repo = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
-
- g_value_set_string (value, tp_handle_inspect (repo, priv->initiator));
- }
- break;
- case PROP_REQUESTED:
- g_value_set_boolean (value, (priv->initiator == base_conn->self_handle));
- break;
- case PROP_INTERFACES:
- g_value_set_static_boxed (value, rakia_media_channel_interfaces);
- break;
- case PROP_CHANNEL_DESTROYED:
- g_value_set_boolean (value, priv->closed);
- break;
- case PROP_CHANNEL_PROPERTIES:
- g_value_take_boxed (value,
- tp_dbus_properties_mixin_make_properties_hash (object,
- TP_IFACE_CHANNEL, "ChannelType",
- TP_IFACE_CHANNEL, "TargetHandleType",
- TP_IFACE_CHANNEL, "TargetHandle",
- TP_IFACE_CHANNEL, "TargetID",
- TP_IFACE_CHANNEL, "InitiatorHandle",
- 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",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "ImmutableStreams",
- 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;
- case PROP_IMMUTABLE_STREAMS:
- g_value_set_boolean (value, priv->immutable_streams);
- break;
- case PROP_STUN_SERVER:
- g_value_set_string (value, priv->stun_server);
- break;
- case PROP_STUN_PORT:
- g_value_set_uint (value, priv->stun_port);
- break;
- case PROP_CURRENTLY_SENDING_TONES:
- g_value_set_boolean (value,
- priv->dtmf_player != NULL
- && tp_dtmf_player_is_active (priv->dtmf_player));
- break;
- case PROP_INITIAL_TONES:
- if (priv->initial_tones == NULL)
- g_value_set_static_string (value, "");
- else
- g_value_set_string (value, priv->initial_tones);
- break;
- case PROP_DEFERRED_TONES:
- if (priv->deferred_tones == NULL)
- g_value_set_static_string (value, "");
- else
- g_value_set_string (value, priv->deferred_tones);
- break;
- default:
- /* Some properties live in the mixin */
- {
- const gchar *param_name;
- guint tp_property_id;
- GValue *tp_property_value;
-
- param_name = g_param_spec_get_name (pspec);
- if (G_LIKELY (tp_properties_mixin_has_property (object, param_name,
- &tp_property_id)))
- {
- tp_property_value =
- chan->properties.properties[tp_property_id].value;
-
- if (G_LIKELY (tp_property_value != NULL))
- {
- g_value_copy (tp_property_value, value);
- return;
- }
- }
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static gboolean
-rakia_media_channel_set_tp_property (RakiaMediaChannel *chan,
- const GValue *value,
- GParamSpec *pspec)
-{
- GObject *obj = (GObject *) chan;
- const gchar *param_name = g_param_spec_get_name (pspec);
- guint tp_property_id;
-
- if (G_LIKELY (tp_properties_mixin_has_property (obj, param_name,
- &tp_property_id)))
- {
- tp_properties_mixin_change_value (obj, tp_property_id,
- value, NULL);
- tp_properties_mixin_change_flags (obj, tp_property_id,
- TP_PROPERTY_FLAG_READ, 0, NULL);
- return TRUE;
- }
- else
- {
- WARNING("Telepathy property '%s' is not defined for media channels",
- param_name);
- return FALSE;
- }
-}
-
-static void
-rakia_media_channel_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- RakiaMediaChannel *chan = RAKIA_MEDIA_CHANNEL (object);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (chan);
-
- switch (property_id) {
- case PROP_HANDLE_TYPE:
- case PROP_CHANNEL_TYPE:
- /* this property is writable in the interface, but not actually
- * meaningfully changable on this channel, so we do nothing */
- break;
- case PROP_CONNECTION:
- priv->conn = g_value_dup_object (value);
- break;
- case PROP_OBJECT_PATH:
- g_free (priv->object_path);
- priv->object_path = g_value_dup_string (value);
- break;
- case PROP_HANDLE:
- /* XXX: this property is defined as writable,
- * but don't set it after construction, mmkay? */
- /* we don't ref it here because we don't necessarily have access to the
- * contact repo yet - instead we ref it in constructed. */
- priv->handle = g_value_get_uint (value);
- break;
- case PROP_INITIATOR:
- /* 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;
- case PROP_IMMUTABLE_STREAMS:
- priv->immutable_streams = g_value_get_boolean (value);
- break;
- case PROP_STUN_SERVER:
- priv->stun_server = g_value_dup_string (value);
- /* Also expose as a legacy Telepathy property */
- rakia_media_channel_set_tp_property (chan, value, pspec);
- break;
- case PROP_STUN_PORT:
- priv->stun_port = g_value_get_uint (value);
- /* Also expose as a legacy Telepathy property */
- rakia_media_channel_set_tp_property (chan, value, pspec);
- break;
- case PROP_INITIAL_TONES:
- priv->initial_tones = g_value_dup_string (value);
- break;
- case PROP_SIP_SESSION:
- priv->sipsession = g_value_dup_object (value);
- break;
- default:
- /* some properties live in the mixin */
- if (rakia_media_channel_set_tp_property (chan, value, pspec))
- return;
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-rakia_media_channel_dispose (GObject *object)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (object);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
- TpHandleRepoIface *contact_handles;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG("enter");
-
- priv->dispose_has_run = TRUE;
-
- if (!priv->closed)
- rakia_media_channel_close (self);
-
- if (priv->sipsession)
- g_object_unref (priv->sipsession);
-
- if (priv->dtmf_player != NULL)
- g_object_unref (priv->dtmf_player);
-
- contact_handles = tp_base_connection_get_handles (
- TP_BASE_CONNECTION (priv->conn), TP_HANDLE_TYPE_CONTACT);
-
- tp_handle_unref (contact_handles, priv->initiator);
- priv->initiator = 0;
-
- g_object_unref (priv->conn);
-
- if (G_OBJECT_CLASS (rakia_media_channel_parent_class)->dispose)
- G_OBJECT_CLASS (rakia_media_channel_parent_class)->dispose (object);
-
- DEBUG("exit");
-}
-
-static void
-rakia_media_channel_finalize (GObject *object)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (object);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- g_hash_table_unref (priv->call_states);
-
- g_free (priv->initial_tones);
- g_free (priv->deferred_tones);
-
- g_free (priv->stun_server);
-
- g_free (priv->object_path);
-
- tp_group_mixin_finalize (object);
-
- tp_properties_mixin_finalize (object);
-
- G_OBJECT_CLASS (rakia_media_channel_parent_class)->finalize (object);
-
- DEBUG("exit");
-}
-
-/***********************************************************************
- * Set: Channel interface implementation (same for 0.12/0.13)
- ***********************************************************************/
-
-/**
- * rakia_media_channel_close_async
- *
- * Implements DBus method Close
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-rakia_media_channel_dbus_close (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
-
- rakia_media_channel_close (self);
- tp_svc_channel_return_from_close (context);
-}
-
-void
-rakia_media_channel_close (RakiaMediaChannel *obj)
-{
- RakiaMediaChannelPrivate *priv;
-
- DEBUG("enter");
-
- g_assert (RAKIA_IS_MEDIA_CHANNEL (obj));
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (obj);
-
- if (priv->closed)
- return;
-
- priv->closed = TRUE;
-
- if (priv->sipsession) {
- rakia_sip_session_terminate (priv->sipsession);
- }
-
- tp_svc_channel_emit_closed ((TpSvcChannel *)obj);
-
- return;
-}
-
-/**
- * rakia_media_channel_get_channel_type
- *
- * Implements DBus method GetChannelType
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-rakia_media_channel_get_channel_type (TpSvcChannel *obj,
- DBusGMethodInvocation *context)
-{
- tp_svc_channel_return_from_get_channel_type (context,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
-}
-
-
-/**
- * rakia_media_channel_get_handle
- *
- * Implements DBus method GetHandle
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-rakia_media_channel_get_handle (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- if (priv->handle != 0)
- tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_CONTACT,
- priv->handle);
- else
- tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_NONE, 0);
-}
-
-/**
- * rakia_media_channel_get_interfaces
- *
- * Implements DBus method GetInterfaces
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-rakia_media_channel_get_interfaces (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- tp_svc_channel_return_from_get_interfaces (context,
- rakia_media_channel_interfaces);
-}
-
-/***********************************************************************
- * Set: Channel.Interface.MediaSignalling Telepathy-0.13 interface
- ***********************************************************************/
-
-/**
- * rakia_media_channel_get_session_handlers
- *
- * Implements DBus method GetSessionHandlers
- * on interface org.freedesktop.Telepathy.Channel.Interface.MediaSignalling
- *
- * @error: Used to return a pointer to a GError detailing any error
- * that occured, DBus will throw the error only if this
- * function returns false.
- *
- * Returns: TRUE if successful, FALSE if an error was thrown.
- */
-static void
-rakia_media_channel_get_session_handlers (TpSvcChannelInterfaceMediaSignalling *iface,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv;
- GPtrArray *ret;
- GValue handler = { 0 };
-
- DEBUG("enter");
-
- g_assert (RAKIA_IS_MEDIA_CHANNEL (self));
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- ret = g_ptr_array_new ();
-
- if (priv->session)
- {
- GType handler_type;
- gchar *path;
-
- g_object_get (priv->session,
- "object-path", &path,
- NULL);
-
- handler_type = dbus_g_type_get_struct ("GValueArray",
- DBUS_TYPE_G_OBJECT_PATH,
- G_TYPE_STRING,
- G_TYPE_INVALID);
-
- g_value_init (&handler, handler_type);
- g_value_take_boxed (&handler,
- dbus_g_type_specialized_construct (handler_type));
-
- dbus_g_type_struct_set (&handler,
- 0, path,
- 1, "rtp",
- G_MAXUINT);
-
- g_free (path);
-
- g_ptr_array_add (ret, g_value_get_boxed (&handler));
- }
-
- tp_svc_channel_interface_media_signalling_return_from_get_session_handlers (
- context, ret);
-
- if (G_IS_VALUE(&handler))
- g_value_unset (&handler);
-
- g_ptr_array_unref (ret);
-}
-
-
-/***********************************************************************
- * Set: Channel.Type.StreamedMedia Telepathy-0.13 interface
- ***********************************************************************/
-
-/**
- * rakia_media_channel_list_streams
- *
- * Implements D-Bus method ListStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-rakia_media_channel_list_streams (TpSvcChannelTypeStreamedMedia *iface,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv;
- GPtrArray *ret = NULL;
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- ret = g_ptr_array_new ();
-
- if (priv->session != NULL)
- rakia_media_session_list_streams (priv->session, ret);
-
- tp_svc_channel_type_streamed_media_return_from_list_streams (context, ret);
-
- g_boxed_free (TP_ARRAY_TYPE_MEDIA_STREAM_INFO_LIST, ret);
-}
-
-/**
- * rakia_media_channel_remove_streams
- *
- * Implements D-Bus method RemoveStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-rakia_media_channel_remove_streams (TpSvcChannelTypeStreamedMedia *iface,
- const GArray *streams,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv;
- GError *error = NULL;
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- if (priv->immutable_streams)
- {
- error = g_error_new (TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
- "Cannot remove streams from the existing channel");
- }
- else if (priv->session != NULL)
- {
- rakia_media_session_remove_streams(priv->session,
- streams,
- &error);
- }
- else
- {
- error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "No session is available");
- }
-
- if (error != NULL)
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- tp_svc_channel_type_streamed_media_return_from_remove_streams (context);
-}
-
-/**
- * rakia_media_channel_request_stream_direction
- *
- * Implements D-Bus method RequestStreamDirection
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-rakia_media_channel_request_stream_direction (TpSvcChannelTypeStreamedMedia *iface,
- guint stream_id,
- guint stream_direction,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv;
- GError *error = NULL;
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- if (priv->immutable_streams)
- {
- GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "Cannot change directions on an immutable channel" };
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- if (priv->session != NULL)
- {
- rakia_media_session_request_stream_direction (priv->session,
- stream_id,
- stream_direction,
- &error);
- }
- else
- {
- error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "The media session is not available");
- }
-
- if (error == NULL)
- {
- tp_svc_channel_type_streamed_media_return_from_request_stream_direction (context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-
-/**
- * rakia_media_channel_request_streams
- *
- * Implements D-Bus method RequestStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-rakia_media_channel_request_streams (TpSvcChannelTypeStreamedMedia *iface,
- guint contact_handle,
- const GArray *types,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- GError *error = NULL;
- GPtrArray *ret = NULL;
- RakiaMediaChannelPrivate *priv;
- TpHandleRepoIface *contact_repo;
-
- DEBUG("enter");
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- if (priv->immutable_streams)
- {
- GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "Cannot add streams to the immutable channel" };
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- contact_repo = tp_base_connection_get_handles (
- (TpBaseConnection *)(priv->conn), TP_HANDLE_TYPE_CONTACT);
-
- if (!tp_handle_is_valid (contact_repo, contact_handle, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- ret = g_ptr_array_sized_new (types->len);
-
- if (rakia_media_session_request_streams (priv->session, types, ret, &error))
- {
- g_assert (types->len == ret->len);
- tp_svc_channel_type_streamed_media_return_from_request_streams (context,
- ret);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-
- g_boxed_free (TP_ARRAY_TYPE_MEDIA_STREAM_INFO_LIST, ret);
-
- DEBUG ("exit");
-}
-
-/***********************************************************************
- * Set: sip-media-channel API towards sip-connection
- ***********************************************************************/
-
-void
-rakia_media_channel_create_initial_streams (RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- g_assert (priv->initiator != priv->handle);
-
- /* RequestChannel(None, 0) => channel is anonymous:
- * caller uses RequestStreams to set the peer and start the call. */
- if (priv->handle == 0)
- return;
-
- g_assert (priv->session != NULL);
-
- if (priv->initial_audio)
- rakia_media_session_add_stream (priv->session,
- TP_MEDIA_STREAM_TYPE_AUDIO,
- TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- TRUE);
-
- if (priv->initial_video)
- rakia_media_session_add_stream (priv->session,
- TP_MEDIA_STREAM_TYPE_VIDEO,
- TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- TRUE);
-}
-
-
-
-guint
-rakia_media_channel_change_call_state (RakiaMediaChannel *self,
- TpHandle peer,
- guint flags_add,
- guint flags_remove)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
- gpointer key = GUINT_TO_POINTER (peer);
- guint old_state;
- guint new_state;
-
- /* XXX: check if the peer is a member? */
-
- old_state = GPOINTER_TO_UINT (g_hash_table_lookup (priv->call_states, key));
- new_state = (old_state | flags_add) & ~flags_remove;
-
- if (new_state != old_state)
- {
- DEBUG ("setting call state %u for peer %u", new_state, peer);
- if (new_state == 0)
- g_hash_table_remove (priv->call_states, key);
- else
- g_hash_table_replace (priv->call_states, key,
- GUINT_TO_POINTER (new_state));
-
- tp_svc_channel_interface_call_state_emit_call_state_changed (self,
- peer,
- new_state);
- }
-
- return new_state;
-}
-
-
-
-
-static void priv_session_state_changed_cb (RakiaSipSession *session,
- guint old_state,
- guint state,
- RakiaMediaChannel *channel)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (channel);
- TpGroupMixin *mixin = TP_GROUP_MIXIN (channel);
- TpHandle self_handle;
- TpHandle peer;
- TpIntSet *set = NULL;
-
- DEBUG("enter");
-
- self_handle = mixin->self_handle;
- peer = rakia_media_session_get_peer (priv->session);
-
- switch (state)
- {
- case RAKIA_SIP_SESSION_STATE_INVITE_SENT:
- g_assert (priv->initiator == self_handle);
-
- /* add the peer to remote pending */
- set = tp_intset_new_containing (peer);
- tp_group_mixin_change_members ((GObject *)channel,
- "",
- NULL, /* add */
- NULL, /* remove */
- NULL, /* local pending */
- set, /* remote pending */
- self_handle, /* actor */
- TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
-
- /* update flags: no more adding */
- tp_group_mixin_change_flags ((GObject *)channel, 0,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD);
-
- break;
-
- case RAKIA_SIP_SESSION_STATE_INVITE_RECEIVED:
- /* add ourself to local pending */
- set = tp_intset_new_containing (self_handle);
- tp_group_mixin_change_members ((GObject *) channel, "",
- NULL, /* add */
- NULL, /* remove */
- set, /* local pending */
- NULL, /* remote pending */
- priv->initiator, /* actor */
- TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
-
- /* No adding more members to the incoming call. Therefore also not
- * possible to add anyone to remote-pending, so rescinding would make
- * utterly no sense. We also disallow removing the remote peer if
- * we are not the initiator, so disallow that too.
- * Removing yourself to end the call is not represented by group flags.
- */
- tp_group_mixin_change_flags ((GObject *) channel, 0,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD | TP_CHANNEL_GROUP_FLAG_CAN_REMOVE |
- TP_CHANNEL_GROUP_FLAG_CAN_RESCIND);
-
- break;
-
- case RAKIA_SIP_SESSION_STATE_ACTIVE:
- if (priv->initiator == self_handle)
- {
- if (!tp_handle_set_is_member (mixin->remote_pending, peer))
- break; /* no-op */
-
- /* the peer has promoted itself to members */
- set = tp_intset_new_containing (peer);
- tp_group_mixin_change_members ((GObject *)channel, "",
- set, /* add */
- NULL, /* remove */
- NULL,
- NULL,
- peer, 0);
- }
- else
- {
- if (!tp_handle_set_is_member (mixin->local_pending, self_handle))
- break; /* no-op */
-
- /* promote ourselves to members */
- set = tp_intset_new_containing (self_handle);
- tp_group_mixin_change_members ((GObject *)channel, "",
- set, /* add */
- NULL, /* remove */
- NULL,
- NULL,
- self_handle, 0);
- }
-
- /* update flags: deny adding and rescinding. Removing the remote peer is
- * still allowed.
- * Removing yourself to end the call is not represented by group flags.
- */
- tp_group_mixin_change_flags ((GObject *)channel, 0,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD | TP_CHANNEL_GROUP_FLAG_CAN_RESCIND);
-
- break;
-
- case RAKIA_SIP_SESSION_STATE_ENDED:
- set = tp_intset_new ();
-
- /* remove us and the peer from the member list */
- tp_intset_add (set, self_handle);
- tp_intset_add (set, peer);
- tp_group_mixin_change_members ((GObject *)channel, "",
- NULL, /* add */
- set, /* remove */
- NULL,
- NULL,
- 0, 0);
-
- /* Close the channel; destroy the session first to avoid
- * the rakia_media_session_terminate() path in this case */
- priv_destroy_session (channel);
- rakia_media_channel_close (channel);
- break;
- }
-
- if (set != NULL)
- tp_intset_destroy (set);
-}
-
-/**
- * priv_create_session:
- *
- * Creates a RakiaMediaSession object for given peer.
- **/
-static void
-priv_create_session (RakiaMediaChannel *channel,
- TpHandle peer)
-{
- RakiaMediaChannelPrivate *priv;
- RakiaMediaSession *session;
- TpBaseConnection *conn;
- TpHandleRepoIface *contact_repo;
- gchar *object_path;
- gchar *local_ip_address = NULL;
-
- DEBUG("enter");
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (channel);
- conn = (TpBaseConnection *)(priv->conn);
- contact_repo = tp_base_connection_get_handles (conn,
- TP_HANDLE_TYPE_CONTACT);
-
- g_assert (priv->session == NULL);
-
- object_path = g_strdup_printf ("%s/MediaSession%u", priv->object_path, peer);
-
- DEBUG("allocating session, peer=%u", peer);
-
- /* The channel manages references to the peer handle for the session */
- tp_handle_ref (contact_repo, peer);
-
- g_object_get (priv->conn,
- "local-ip-address", &local_ip_address,
- NULL);
-
- session = g_object_new (RAKIA_TYPE_MEDIA_SESSION,
- "dbus-daemon",
- tp_base_connection_get_dbus_daemon (conn),
- "media-channel", channel,
- "object-path", object_path,
- "sip-session", priv->sipsession,
- "peer", peer,
- "local-ip-address", local_ip_address,
- NULL);
-
- g_free (local_ip_address);
-
- g_signal_connect_object (session,
- "dtmf-ready",
- G_CALLBACK (priv_session_dtmf_ready_cb),
- channel,
- 0);
-
- priv->session = session;
-
- tp_svc_channel_interface_media_signalling_emit_new_session_handler (
- (TpSvcChannelInterfaceMediaSignalling *)channel, object_path, "rtp");
-
- g_free (object_path);
-
- DEBUG ("exit");
-}
-
-static void
-priv_destroy_session(RakiaMediaChannel *channel)
-{
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (channel);
- RakiaMediaSession *session;
- TpBaseConnection *conn;
- TpHandleRepoIface *contact_repo;
-
- session = priv->session;
- if (session == NULL)
- return;
-
- DEBUG("enter");
-
- /* Release the peer handle */
- conn = (TpBaseConnection *)(priv->conn);
- contact_repo = tp_base_connection_get_handles (conn,
- TP_HANDLE_TYPE_CONTACT);
- tp_handle_unref (contact_repo, rakia_media_session_get_peer (session));
-
- priv->session = NULL;
- g_object_unref (session);
-
- DEBUG("exit");
-}
-
-gboolean
-_rakia_media_channel_add_member (GObject *iface,
- TpHandle handle,
- const gchar *message,
- GError **error)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
- TpGroupMixin *mixin = TP_GROUP_MIXIN (iface);
-
- DEBUG("mixin->self_handle=%d, handle=%d", mixin->self_handle, handle);
-
- if (priv->initiator == mixin->self_handle)
- {
- TpIntSet *remote_pending;
-
- /* Backwards compatible behavior:
- * add the peer to remote pending without waiting for the actual request
- * to be sent */
- remote_pending = tp_intset_new_containing (handle);
- tp_group_mixin_change_members (iface,
- "",
- NULL, /* add */
- NULL, /* remove */
- NULL, /* local pending */
- remote_pending, /* remote pending */
- mixin->self_handle, /* actor */
- TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
- tp_intset_destroy (remote_pending);
-
- /* update flags: no more adding.
- * Removal and rescinding are still allowed. */
- tp_group_mixin_change_flags (iface, 0,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD);
-
- return TRUE;
- }
-
- if (priv->session &&
- handle == mixin->self_handle &&
- tp_handle_set_is_member (mixin->local_pending, handle))
- {
- /* case b: an incoming invite */
- DEBUG("accepting an incoming invite");
- g_return_val_if_fail (priv->session != NULL, FALSE);
-
- rakia_media_session_accept (priv->session);
-
- return TRUE;
- }
-
- MESSAGE ("unsupported member change requested for a media channel");
-
- g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "handle %u cannot be added in the current state", handle);
- return FALSE;
-}
-
-static gint
-rakia_status_from_tp_reason (TpChannelGroupChangeReason reason)
-{
- switch (reason)
- {
- case TP_CHANNEL_GROUP_CHANGE_REASON_NONE:
- return 603; /* Decline */
- case TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER:
- case TP_CHANNEL_GROUP_CHANGE_REASON_OFFLINE:
- return 480; /* Temporarily Unavailable */
- case TP_CHANNEL_GROUP_CHANGE_REASON_BUSY:
- return 486; /* Busy Here */
- case TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED:
- case TP_CHANNEL_GROUP_CHANGE_REASON_BANNED:
- return 403; /* Forbidden */
- case TP_CHANNEL_GROUP_CHANGE_REASON_INVALID_CONTACT:
- return 404; /* Not Found */
- default:
- return 500; /* Server Internal Error */
- }
-}
-
-static gboolean
-rakia_media_channel_remove_with_reason (GObject *obj,
- TpHandle handle,
- const gchar *message,
- guint reason,
- GError **error)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (obj);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
- TpGroupMixin *mixin = TP_GROUP_MIXIN (obj);
- TpIntSet *set = NULL;
- TpHandle self_handle;
- gboolean rejected;
-
- self_handle = mixin->self_handle;
-
- if (priv->initiator != self_handle && handle != self_handle)
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
- "handle %u cannot be removed because you are not the initiator of the"
- " channel", handle);
-
- return FALSE;
- }
-
- if (priv->session == NULL)
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "handle %u cannot be removed in the current state", handle);
-
- return FALSE;
- }
-
- rejected = (handle == self_handle
- && tp_handle_set_is_member (mixin->local_pending, handle));
-
- /* We have excluded all the problem cases.
- * Now we always want to remove both members on behalf of the local user */
- set = tp_intset_new ();
- tp_intset_add (set, self_handle);
- tp_intset_add (set, rakia_media_session_get_peer (priv->session));
- tp_group_mixin_change_members (obj, "",
- NULL, /* add */
- set, /* remove */
- NULL,
- NULL,
- self_handle, 0);
- tp_intset_destroy (set);
-
- if (rejected)
- {
- /* The user has rejected the call */
-
- gint status;
-
- status = rakia_status_from_tp_reason (reason);
-
- /* XXX: raise NotAvailable if it's the wrong state? */
- rakia_sip_session_respond (priv->sipsession, status, message);
-
- /* This session is effectively ended, prevent the nua_i_state handler
- * from useless work */
- rakia_sip_session_change_state (priv->sipsession,
- RAKIA_SIP_SESSION_STATE_ENDED);
- }
- else
- {
- /* Want to terminate the call in whatever other situation;
- * rescinding is handled by sending CANCEL */
- rakia_sip_session_terminate (priv->sipsession);
- }
-
- return TRUE;
-}
-
-static void
-rakia_media_channel_get_call_states (TpSvcChannelInterfaceCallState *iface,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- tp_svc_channel_interface_call_state_return_from_get_call_states (
- context,
- priv->call_states);
-}
-
-static void
-rakia_media_channel_get_hold_state (TpSvcChannelInterfaceHold *iface,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
- TpLocalHoldState hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
- TpLocalHoldStateReason hold_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
-
- if (priv->session == NULL)
- {
- GError e = {TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "The media session is not available"};
- dbus_g_method_return_error (context, &e);
- }
-
- g_object_get (priv->session,
- "hold-state", &hold_state,
- "hold-state-reason", &hold_reason,
- NULL);
-
- tp_svc_channel_interface_hold_return_from_get_hold_state (context,
- hold_state,
- hold_reason);
-}
-
-static void
-rakia_media_channel_request_hold (TpSvcChannelInterfaceHold *iface,
- gboolean hold,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv;
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- if (priv->immutable_streams)
- {
- GError e = {TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "Session modification disabled"};
- dbus_g_method_return_error (context, &e);
- return;
- }
- else if (priv->session != NULL)
- {
- rakia_media_session_request_hold (priv->session, hold);
- }
- else
- {
- GError e = {TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "The media session is not available"};
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- tp_svc_channel_interface_hold_return_from_request_hold (context);
-}
-
-static void
-dtmf_player_started_tone_cb (TpDTMFPlayer *dtmf_player,
- guint event,
- gpointer user_data)
-{
- RakiaMediaChannel *self = user_data;
- RakiaMediaChannelPrivate *priv = self->priv;
-
- if (priv->session != NULL)
- rakia_media_session_start_telephony_event (priv->session, event);
-}
-
-static void
-dtmf_player_stopped_tone_cb (TpDTMFPlayer *dtmf_player,
- gpointer user_data)
-{
- RakiaMediaChannel *self = user_data;
- RakiaMediaChannelPrivate *priv = self->priv;
-
- if (priv->session != NULL)
- rakia_media_session_stop_telephony_event (priv->session);
-}
-
-static void
-dtmf_player_finished_cb (TpDTMFPlayer *dtmf_player,
- gboolean cancelled,
- gpointer user_data)
-{
- RakiaMediaChannel *self = user_data;
-
- tp_svc_channel_interface_dtmf_emit_stopped_tones (self, cancelled);
-}
-
-static void
-dtmf_player_tones_deferred_cb (TpDTMFPlayer *dtmf_player,
- gchar *tones,
- gpointer user_data)
-{
- RakiaMediaChannel *self = user_data;
- RakiaMediaChannelPrivate *priv = self->priv;
-
- g_free (priv->deferred_tones);
- priv->deferred_tones = g_strdup (tones);
-
- tp_svc_channel_interface_dtmf_emit_tones_deferred (self, tones);
-}
-
-static void
-priv_ensure_dtmf_player (RakiaMediaChannel *self)
-{
- RakiaMediaChannelPrivate *priv = self->priv;
- if (priv->dtmf_player != NULL)
- return;
-
- priv->dtmf_player = tp_dtmf_player_new ();
-
- g_signal_connect (priv->dtmf_player, "started-tone",
- G_CALLBACK (dtmf_player_started_tone_cb), self);
- g_signal_connect (priv->dtmf_player, "stopped-tone",
- G_CALLBACK (dtmf_player_stopped_tone_cb), self);
- g_signal_connect (priv->dtmf_player, "finished",
- G_CALLBACK (dtmf_player_finished_cb), self);
- g_signal_connect (priv->dtmf_player, "tones-deferred",
- G_CALLBACK (dtmf_player_tones_deferred_cb), self);
-}
-
-static gboolean
-rakia_media_channel_send_dtmf_tones (RakiaMediaChannel *self,
- const gchar *tones,
- guint tone_duration,
- GError **error)
-{
- RakiaMediaChannelPrivate *priv = self->priv;
-
- /* Perform sanity checks on the session */
- if (priv->session == NULL)
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "the media session is not available, has the channel been closed?");
- return FALSE;
- }
- if (!rakia_media_session_has_media (priv->session,
- TP_MEDIA_STREAM_TYPE_AUDIO))
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "no audio streams are available");
- return FALSE;
- }
-
- priv_ensure_dtmf_player (self);
-
- if (!tp_dtmf_player_play (priv->dtmf_player, tones, tone_duration,
- RAKIA_DTMF_GAP_DURATION, RAKIA_DTMF_PAUSE_DURATION, error))
- return FALSE;
-
- g_free (priv->deferred_tones);
- priv->deferred_tones = NULL;
-
- tp_svc_channel_interface_dtmf_emit_sending_tones (self, tones);
-
- return TRUE;
-}
-
-static void
-rakia_media_channel_start_tone (TpSvcChannelInterfaceDTMF *iface,
- guint stream_id,
- guchar event,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- GError *error = NULL;
- gchar tone[2];
-
- DEBUG("enter");
-
- if (event >= NUM_TP_DTMF_EVENTS)
- {
- g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "event %u is not a known DTMF event", event);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- tone[0] = tp_dtmf_event_to_char (event);
- tone[1] = '\0';
-
- if (!rakia_media_channel_send_dtmf_tones (self, tone, G_MAXUINT, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- tp_svc_channel_interface_dtmf_return_from_start_tone (context);
-}
-
-static void
-rakia_media_channel_stop_tone (TpSvcChannelInterfaceDTMF *iface,
- guint stream_id,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = RAKIA_MEDIA_CHANNEL (iface);
- RakiaMediaChannelPrivate *priv;
-
- DEBUG("enter");
-
- priv = RAKIA_MEDIA_CHANNEL_GET_PRIVATE (self);
-
- if (priv->dtmf_player != NULL)
- tp_dtmf_player_cancel (priv->dtmf_player);
-
- tp_svc_channel_interface_dtmf_return_from_stop_tone (context);
-}
-
-static void
-rakia_media_channel_multiple_tones (TpSvcChannelInterfaceDTMF *iface,
- const gchar *tones,
- DBusGMethodInvocation *context)
-{
- RakiaMediaChannel *self = (RakiaMediaChannel *) iface;
- GError *error = NULL;
-
- if (!rakia_media_channel_send_dtmf_tones (self, tones,
- RAKIA_DTMF_TONE_DURATION, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- tp_svc_channel_interface_dtmf_return_from_multiple_tones (context);
-}
-
-static void
-priv_session_dtmf_ready_cb (RakiaMediaSession *session,
- RakiaMediaChannel *channel)
-{
- RakiaMediaChannelPrivate *priv = channel->priv;
- if (!tp_str_empty (priv->initial_tones))
- rakia_media_channel_send_dtmf_tones (channel, priv->initial_tones,
- RAKIA_DTMF_TONE_DURATION, NULL);
-}
-
-static void
-event_target_init(gpointer g_iface, gpointer iface_data)
-{
-}
-
-static void
-channel_iface_init(gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelClass *klass = (TpSvcChannelClass *)g_iface;
-
- tp_svc_channel_implement_close (
- klass, rakia_media_channel_dbus_close);
-#define IMPLEMENT(x) tp_svc_channel_implement_##x (\
- klass, rakia_media_channel_##x)
- IMPLEMENT(get_channel_type);
- IMPLEMENT(get_handle);
- IMPLEMENT(get_interfaces);
-#undef IMPLEMENT
-}
-
-static void
-streamed_media_iface_init(gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelTypeStreamedMediaClass *klass = (TpSvcChannelTypeStreamedMediaClass *)g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_type_streamed_media_implement_##x (\
- klass, rakia_media_channel_##x)
- IMPLEMENT(list_streams);
- IMPLEMENT(remove_streams);
- IMPLEMENT(request_stream_direction);
- IMPLEMENT(request_streams);
-#undef IMPLEMENT
-}
-
-static void
-media_signalling_iface_init(gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelInterfaceMediaSignallingClass *klass = (TpSvcChannelInterfaceMediaSignallingClass *)g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_media_signalling_implement_##x (\
- klass, rakia_media_channel_##x)
- IMPLEMENT(get_session_handlers);
-#undef IMPLEMENT
-}
-
-static void
-dtmf_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelInterfaceDTMFClass *klass = (TpSvcChannelInterfaceDTMFClass *)g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_dtmf_implement_##x (\
- klass, rakia_media_channel_##x)
- IMPLEMENT(start_tone);
- IMPLEMENT(stop_tone);
- IMPLEMENT(multiple_tones);
-#undef IMPLEMENT
-}
-
-static void
-call_state_iface_init (gpointer g_iface,
- gpointer iface_data)
-{
- TpSvcChannelInterfaceCallStateClass *klass = g_iface;
-#define IMPLEMENT(x) tp_svc_channel_interface_call_state_implement_##x (\
- klass, rakia_media_channel_##x)
- IMPLEMENT (get_call_states);
-#undef IMPLEMENT
-}
-
-static void
-hold_iface_init (gpointer g_iface,
- gpointer iface_data)
-{
- TpSvcChannelInterfaceHoldClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_hold_implement_##x (\
- klass, rakia_media_channel_##x)
- IMPLEMENT (get_hold_state);
- IMPLEMENT (request_hold);
-#undef IMPLEMENT
-}
diff --git a/rakia/media-channel.h b/rakia/media-channel.h
deleted file mode 100644
index cbd42ec..0000000
--- a/rakia/media-channel.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * sip-media-channel.h - Header for RakiaMediaChannel
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005-2009 Nokia Corporation
- *
- * This work is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This work is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this work; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __RAKIA_MEDIA_CHANNEL_H__
-#define __RAKIA_MEDIA_CHANNEL_H__
-
-#include <glib-object.h>
-#include <sofia-sip/sdp.h>
-#include <telepathy-glib/dbus-properties-mixin.h>
-#include <telepathy-glib/group-mixin.h>
-#include <telepathy-glib/handle.h>
-#include <telepathy-glib/properties-mixin.h>
-
-#include <rakia/sofia-decls.h>
-
-
-G_BEGIN_DECLS
-
-typedef struct _RakiaMediaChannel RakiaMediaChannel;
-typedef struct _RakiaMediaChannelClass RakiaMediaChannelClass;
-typedef struct _RakiaMediaChannelPrivate RakiaMediaChannelPrivate;
-
-struct _RakiaMediaChannelClass {
- GObjectClass parent_class;
- TpGroupMixinClass group_class;
- TpPropertiesMixinClass properties_class;
- TpDBusPropertiesMixinClass dbus_props_class;
-};
-
-struct _RakiaMediaChannel {
- GObject parent;
- TpGroupMixin group;
- TpPropertiesMixin properties;
- RakiaMediaChannelPrivate *priv;
-};
-
-GType rakia_media_channel_get_type(void);
-
-/* TYPE MACROS */
-#define RAKIA_TYPE_MEDIA_CHANNEL \
- (rakia_media_channel_get_type())
-#define RAKIA_MEDIA_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), RAKIA_TYPE_MEDIA_CHANNEL, RakiaMediaChannel))
-#define RAKIA_MEDIA_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), RAKIA_TYPE_MEDIA_CHANNEL, RakiaMediaChannelClass))
-#define RAKIA_IS_MEDIA_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), RAKIA_TYPE_MEDIA_CHANNEL))
-#define RAKIA_IS_MEDIA_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), RAKIA_TYPE_MEDIA_CHANNEL))
-#define RAKIA_MEDIA_CHANNEL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), RAKIA_TYPE_MEDIA_CHANNEL, RakiaMediaChannelClass))
-
-/***********************************************************************
- * Additional declarations (not based on generated templates)
- ***********************************************************************/
-
-void rakia_media_channel_close (RakiaMediaChannel *self);
-
-gboolean _rakia_media_channel_add_member (GObject *iface,
- TpHandle handle,
- const gchar *message,
- GError **error);
-
-void rakia_media_channel_create_initial_streams (RakiaMediaChannel *self);
-
-void rakia_media_channel_attach_to_nua_handle (RakiaMediaChannel *self,
- nua_handle_t *nh);
-
-guint
-rakia_media_channel_change_call_state (RakiaMediaChannel *self,
- TpHandle peer,
- guint flags_add,
- guint flags_remove);
-
-G_END_DECLS
-
-#endif /* #ifndef __RAKIA_MEDIA_CHANNEL_H__*/
diff --git a/rakia/media-session.c b/rakia/media-session.c
deleted file mode 100644
index 445dd15..0000000
--- a/rakia/media-session.c
+++ /dev/null
@@ -1,1249 +0,0 @@
-/*
- * sip-media-session.c - Source for RakiaMediaSession
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005-2010 Nokia Corporation
- * @author Kai Vehmanen <first.surname@nokia.com>
- * @author Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
- *
- * Based on telepathy-gabble implementation (gabble-media-session).
- * @author Ole Andre Vadla Ravnaas <ole.andre.ravnaas@collabora.co.uk>
- *
- * This work is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This work is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this work; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include "rakia/media-session.h"
-
-#include <dbus/dbus-glib.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-
-#include <sofia-sip/sip_status.h>
-
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/errors.h>
-#include <telepathy-glib/gtypes.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/svc-media-interfaces.h>
-
-#include "config.h"
-
-#include <rakia/base-connection.h>
-
-#include "rakia/media-channel.h"
-#include "rakia/media-stream.h"
-#include "rakia/sip-session.h"
-
-#include "signals-marshal.h"
-
-#define DEBUG_FLAG RAKIA_DEBUG_MEDIA
-#include "rakia/debug.h"
-
-/* The timeout for outstanding re-INVITE transactions in seconds.
- * Chosen to match the allowed cancellation timeout for proxies
- * described in RFC 3261 Section 13.3.1.1 */
-#define RAKIA_REINVITE_TIMEOUT 180
-
-static void session_handler_iface_init (gpointer, gpointer);
-
-G_DEFINE_TYPE_WITH_CODE(RakiaMediaSession,
- rakia_media_session,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_MEDIA_SESSION_HANDLER,
- session_handler_iface_init)
- )
-
-/* signal enum */
-enum
-{
- SIG_DTMF_READY,
- SIG_LAST_SIGNAL
-};
-
-/* properties */
-enum
-{
- PROP_MEDIA_CHANNEL = 1,
- PROP_DBUS_DAEMON,
- PROP_OBJECT_PATH,
- PROP_SIP_SESSION,
- PROP_PEER,
- PROP_HOLD_STATE,
- PROP_HOLD_STATE_REASON,
- PROP_LOCAL_IP_ADDRESS,
- PROP_STUN_SERVERS,
- LAST_PROPERTY
-};
-
-static guint signals[SIG_LAST_SIGNAL] = {0};
-
-#ifdef ENABLE_DEBUG
-
-#define SESSION_DEBUG(session, format, ...) \
- rakia_log (DEBUG_FLAG, G_LOG_LEVEL_DEBUG, "session: " format, \
- ##__VA_ARGS__)
-
-#define SESSION_MESSAGE(session, format, ...) \
- rakia_log (DEBUG_FLAG, G_LOG_LEVEL_MESSAGE, "session: " format, \
- ##__VA_ARGS__)
-
-#else /* !ENABLE_DEBUG */
-
-#define SESSION_DEBUG(session, format, ...) G_STMT_START { } G_STMT_END
-#define SESSION_MESSAGE(session, format, ...) G_STMT_START { } G_STMT_END
-
-#endif /* ENABLE_DEBUG */
-
-/* private structure */
-struct _RakiaMediaSessionPrivate
-{
- TpDBusDaemon *dbus_daemon;
- RakiaMediaChannel *channel; /* see gobj. prop. 'media-channel' */
- gchar *object_path; /* see gobj. prop. 'object-path' */
- RakiaSipSession *sipsession;
- TpHandle peer; /* see gobj. prop. 'peer' */
- gchar *local_ip_address; /* see gobj. prop. 'local-ip-address' */
- TpLocalHoldState hold_state; /* local hold state aggregated from stream directions */
- TpLocalHoldStateReason hold_reason; /* last used hold state change reason */
-
- gint local_non_ready; /* number of streams with local information update pending */
- guint remote_stream_count; /* number of streams last seen in a remote offer */
- GPtrArray *streams;
- gboolean remote_initiated; /*< session is remotely intiated */
-
- gboolean se_ready; /*< connection established with stream-engine */
- gboolean audio_connected; /*< an audio stream has reached connected state */
- gboolean dispose_has_run;
-};
-
-#define RAKIA_MEDIA_SESSION_GET_PRIVATE(session) ((session)->priv)
-
-static void rakia_media_session_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-static void rakia_media_session_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-
-static RakiaMediaStream *
-rakia_media_session_get_stream (RakiaMediaSession *self,
- guint stream_id,
- GError **error);
-
-static void rakia_media_session_init (RakiaMediaSession *self)
-{
- RakiaMediaSessionPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- RAKIA_TYPE_MEDIA_SESSION, RakiaMediaSessionPrivate);
-
- self->priv = priv;
-
- priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
- priv->hold_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
-
- /* allocate any data required by the object here */
- priv->streams = g_ptr_array_new ();
-}
-
-static GObject *
-rakia_media_session_constructor (GType type, guint n_props,
- GObjectConstructParam *props)
-{
- GObject *obj;
- RakiaMediaSessionPrivate *priv;
-
- obj = G_OBJECT_CLASS (rakia_media_session_parent_class)->
- constructor (type, n_props, props);
- priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (RAKIA_MEDIA_SESSION (obj));
-
- g_assert (TP_IS_DBUS_DAEMON (priv->dbus_daemon));
- tp_dbus_daemon_register_object (priv->dbus_daemon, priv->object_path, obj);
-
- return obj;
-}
-
-static void rakia_media_session_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- RakiaMediaSession *session = RAKIA_MEDIA_SESSION (object);
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
-
- switch (property_id)
- {
- case PROP_DBUS_DAEMON:
- g_value_set_object (value, priv->dbus_daemon);
- break;
- case PROP_MEDIA_CHANNEL:
- g_value_set_object (value, priv->channel);
- break;
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_SIP_SESSION:
- g_value_set_object (value, priv->sipsession);
- break;
- case PROP_PEER:
- g_value_set_uint (value, priv->peer);
- break;
- case PROP_HOLD_STATE:
- g_value_set_uint (value, priv->hold_state);
- break;
- case PROP_HOLD_STATE_REASON:
- g_value_set_uint (value, priv->hold_reason);
- break;
- case PROP_LOCAL_IP_ADDRESS:
- g_value_set_string (value, priv->local_ip_address);
- break;
-
- case PROP_STUN_SERVERS:
- {
- /* TODO: should be able to get all entries from the DNS lookup(s).
- * At the moment, rawudp ignores all servers except the first one. */
- GPtrArray *servers;
- gchar *stun_server = NULL;
- guint stun_port = RAKIA_DEFAULT_STUN_PORT;
-
- g_return_if_fail (priv->channel != NULL);
-
- g_object_get (priv->channel,
- "stun-server", &stun_server,
- "stun-port", &stun_port,
- NULL);
-
- servers = g_ptr_array_new ();
-
- if (stun_server != NULL)
- {
- GValue addr = { 0 };
- const GType addr_type = TP_STRUCT_TYPE_SOCKET_ADDRESS_IP;
-
- g_value_init (&addr, addr_type);
- g_value_take_boxed (&addr,
- dbus_g_type_specialized_construct (addr_type));
-
- dbus_g_type_struct_set (&addr,
- 0, stun_server,
- 1, (guint16) stun_port,
- G_MAXUINT);
-
- g_ptr_array_add (servers, g_value_get_boxed (&addr));
-
- g_free (stun_server);
- }
-
- g_value_take_boxed (value, servers);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void rakia_media_session_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- RakiaMediaSession *session = RAKIA_MEDIA_SESSION (object);
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
-
- switch (property_id)
- {
- case PROP_DBUS_DAEMON:
- g_assert (priv->dbus_daemon == NULL); /* construct-only */
- priv->dbus_daemon = g_value_dup_object (value);
- break;
- case PROP_MEDIA_CHANNEL:
- priv->channel = RAKIA_MEDIA_CHANNEL (g_value_get_object (value));
- break;
- case PROP_OBJECT_PATH:
- g_assert (priv->object_path == NULL);
- priv->object_path = g_value_dup_string (value);
- break;
- case PROP_SIP_SESSION:
- priv->sipsession = g_value_dup_object (value);
- break;
- case PROP_PEER:
- priv->peer = g_value_get_uint (value);
- break;
- case PROP_LOCAL_IP_ADDRESS:
- g_assert (priv->local_ip_address == NULL);
- priv->local_ip_address = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void rakia_media_session_dispose (GObject *object);
-static void rakia_media_session_finalize (GObject *object);
-
-static void
-rakia_media_session_class_init (RakiaMediaSessionClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- g_type_class_add_private (klass, sizeof (RakiaMediaSessionPrivate));
-
- object_class->constructor = rakia_media_session_constructor;
-
- object_class->get_property = rakia_media_session_get_property;
- object_class->set_property = rakia_media_session_set_property;
-
- object_class->dispose = rakia_media_session_dispose;
- object_class->finalize = rakia_media_session_finalize;
-
- param_spec = g_param_spec_object ("dbus-daemon", "TpDBusDaemon",
- "Connection to D-Bus.", TP_TYPE_DBUS_DAEMON,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DBUS_DAEMON, param_spec);
-
- param_spec = g_param_spec_object ("media-channel", "RakiaMediaChannel object",
- "SIP media channel object that owns this media session object"
- " (not reference counted).",
- RAKIA_TYPE_MEDIA_CHANNEL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEDIA_CHANNEL, param_spec);
-
- param_spec = g_param_spec_string ("object-path", "D-Bus object path",
- "The D-Bus object path used for this object on the bus.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
-
- param_spec = g_param_spec_object ("sip-session", "RakiaSipSession object",
- "SIP session object that is used for this SIP media channel object.",
- RAKIA_TYPE_SIP_SESSION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_SIP_SESSION, param_spec);
-
- param_spec = g_param_spec_uint ("peer", "Session peer",
- "The TpHandle representing the contact with whom this session communicates.",
- 0, G_MAXUINT32,
- 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_PEER, param_spec);
-
- param_spec = g_param_spec_uint ("hold-state", "Local hold state",
- "The current Local_Hold_State value as reported by the Hold interface",
- TP_LOCAL_HOLD_STATE_UNHELD, TP_LOCAL_HOLD_STATE_PENDING_UNHOLD,
- TP_LOCAL_HOLD_STATE_UNHELD,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_HOLD_STATE, param_spec);
-
- param_spec = g_param_spec_uint ("hold-state-reason",
- "Local hold state change reason",
- "The last Local_Hold_State_Reason value as reported by the Hold interface",
- TP_LOCAL_HOLD_STATE_REASON_NONE,
- TP_LOCAL_HOLD_STATE_REASON_RESOURCE_NOT_AVAILABLE,
- TP_LOCAL_HOLD_STATE_REASON_NONE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_HOLD_STATE_REASON, param_spec);
-
- param_spec = g_param_spec_string ("local-ip-address", "Local IP address",
- "The local IP address preferred for media streams",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_LOCAL_IP_ADDRESS, param_spec);
-
- param_spec = g_param_spec_boxed ("stun-servers", "STUN servers",
- "Array of IP address-port pairs for available STUN servers",
- TP_ARRAY_TYPE_SOCKET_ADDRESS_IP_LIST,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_SERVERS, param_spec);
-
- signals[SIG_DTMF_READY] =
- g_signal_new ("dtmf-ready",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-static void
-rakia_media_session_dispose (GObject *object)
-{
- RakiaMediaSession *self = RAKIA_MEDIA_SESSION (object);
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG("enter");
-
- priv->dispose_has_run = TRUE;
-
- tp_clear_object (&priv->dbus_daemon);
-
- tp_clear_object (&priv->sipsession);
-
- if (G_OBJECT_CLASS (rakia_media_session_parent_class)->dispose)
- G_OBJECT_CLASS (rakia_media_session_parent_class)->dispose (object);
-
- DEBUG("exit");
-}
-
-static void
-rakia_media_session_finalize (GObject *object)
-{
- RakiaMediaSession *self = RAKIA_MEDIA_SESSION (object);
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- guint i;
-
- /* free any data held directly by the object here */
-
- for (i = 0; i < priv->streams->len; i++) {
- RakiaMediaStream *stream = g_ptr_array_index (priv->streams, i);
- if (stream != NULL)
- {
- WARNING ("stream %u (%p) left over, reaping", i, stream);
- g_object_unref (stream);
- }
- }
- g_ptr_array_free(priv->streams, TRUE);
-
- g_free (priv->local_ip_address);
- g_free (priv->object_path);
-
- G_OBJECT_CLASS (rakia_media_session_parent_class)->finalize (object);
-
- DEBUG("exit");
-}
-
-
-
-/**
- * rakia_media_session_error
- *
- * Implements DBus method Error
- * on interface org.freedesktop.Telepathy.Media.SessionHandler
- */
-static void
-rakia_media_session_error (TpSvcMediaSessionHandler *iface,
- guint errno,
- const gchar *message,
- DBusGMethodInvocation *context)
-{
- RakiaMediaSession *self = RAKIA_MEDIA_SESSION (iface);
- RakiaMediaSessionPrivate *priv = self->priv;
-
- SESSION_DEBUG (obj, "Media.SessionHandler::Error called (%s), terminating session", message);
-
- rakia_sip_session_terminate (priv->sipsession);
-
- tp_svc_media_session_handler_return_from_error (context);
-}
-
-static void priv_emit_new_stream (RakiaMediaSession *self,
- RakiaMediaStream *stream)
-{
- gchar *object_path;
- guint id;
- guint media_type;
- guint direction;
-
- g_object_get (stream,
- "object-path", &object_path,
- "id", &id,
- "media-type", &media_type,
- "direction", &direction,
- NULL);
-
- /* note: all of the streams are bidirectional from farsight's point of view, it's
- * just in the signalling they change */
-
- tp_svc_media_session_handler_emit_new_stream_handler (
- (TpSvcMediaSessionHandler *)self, object_path, id, media_type,
- direction);
-
- g_free (object_path);
-}
-
-
-/**
- * rakia_media_session_ready
- *
- * Implements DBus method Ready
- * on interface org.freedesktop.Telepathy.Media.SessionHandler
- */
-static void
-rakia_media_session_ready (TpSvcMediaSessionHandler *iface,
- DBusGMethodInvocation *context)
-{
- RakiaMediaSession *self = RAKIA_MEDIA_SESSION (iface);
- RakiaMediaSessionPrivate *priv = self->priv;
- guint i;
-
- SESSION_DEBUG (self, "Media.SessionHandler.Ready called");
-
- if (!priv->se_ready)
- {
- priv->se_ready = TRUE;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- RakiaMediaStream *stream = g_ptr_array_index (priv->streams, i);
- if (stream)
- priv_emit_new_stream (self, stream);
- }
- }
-
- tp_svc_media_session_handler_return_from_ready (context);
-}
-
-/***********************************************************************
- * Helper functions follow (not based on generated templates)
- ***********************************************************************/
-
-TpHandle
-rakia_media_session_get_peer (RakiaMediaSession *session)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
- return priv->peer;
-}
-
-static gboolean
-rakia_media_session_supports_media_type (guint media_type)
-{
- switch (media_type)
- {
- case TP_MEDIA_STREAM_TYPE_AUDIO:
- case TP_MEDIA_STREAM_TYPE_VIDEO:
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-priv_apply_streams_pending_direction (RakiaMediaSession *session,
- guint pending_send_mask)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
- RakiaMediaStream *stream;
- guint i;
-
- /* If there has been a local change pending a re-INVITE,
- * suspend remote approval until the next transaction */
- if (rakia_sip_session_pending_offer (priv->sipsession))
- pending_send_mask &= ~(guint)TP_MEDIA_STREAM_PENDING_REMOTE_SEND;
-
- /* Apply the pending direction changes */
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream != NULL)
- rakia_media_stream_apply_pending_direction (stream, pending_send_mask);
- }
-}
-
-
-void
-priv_add_stream_list_entry (GPtrArray *list,
- RakiaMediaStream *stream,
- RakiaMediaSession *session)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
- GValue entry = { 0 };
- GType stream_type;
- guint id;
- TpMediaStreamType type = TP_MEDIA_STREAM_TYPE_AUDIO;
- TpMediaStreamState connection_state = TP_MEDIA_STREAM_STATE_CONNECTED;
- TpMediaStreamDirection direction = TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL;
- guint pending_send_flags = 0;
-
- g_assert(stream != NULL);
-
- g_object_get (stream,
- "id", &id,
- "media-type", &type,
- "state", &connection_state,
- "direction", &direction,
- "pending-send-flags", &pending_send_flags,
- NULL);
-
- stream_type = TP_STRUCT_TYPE_MEDIA_STREAM_INFO;
-
- g_value_init (&entry, stream_type);
- g_value_take_boxed (&entry,
- dbus_g_type_specialized_construct (stream_type));
-
- dbus_g_type_struct_set (&entry,
- 0, id,
- 1, priv->peer,
- 2, type,
- 3, connection_state,
- 4, direction,
- 5, pending_send_flags,
- G_MAXUINT);
-
- g_ptr_array_add (list, g_value_get_boxed (&entry));
-}
-
-gboolean rakia_media_session_request_streams (RakiaMediaSession *session,
- const GArray *media_types,
- GPtrArray *ret,
- GError **error)
-{
- guint i;
-
- DEBUG ("enter");
-
- /* Validate the media types before creating any streams */
- for (i = 0; i < media_types->len; i++) {
- guint media_type = g_array_index (media_types, guint, i);
- if (!rakia_media_session_supports_media_type (media_type))
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "media type #%u is not supported", i);
- return FALSE;
- }
- }
-
- for (i = 0; i < media_types->len; i++) {
- guint media_type = g_array_index (media_types, guint, i);
- RakiaMediaStream *stream;
-
- stream = rakia_media_session_add_stream (session,
- media_type,
- TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- TRUE);
-
- if (stream == NULL)
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "creation of stream %u failed", i);
- /* XXX: should we close the streams already created as part of
- * this request, despite having emitted signals about them? */
- return FALSE;
- }
-
- priv_add_stream_list_entry (ret, stream, session);
- }
-
- return TRUE;
-}
-
-gboolean
-rakia_media_session_remove_streams (RakiaMediaSession *self,
- const GArray *stream_ids,
- GError **error)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream;
- RakiaSipMedia *media;
- guint stream_id;
- guint i;
-
- DEBUG ("enter");
-
- for (i = 0; i < stream_ids->len; i++)
- {
- stream_id = g_array_index (stream_ids, guint, i);
- stream = rakia_media_session_get_stream (self, stream_id, error);
- if (stream == NULL)
- return FALSE;
- media = rakia_media_stream_get_media (stream);
- rakia_media_stream_close (stream);
- rakia_sip_session_remove_media (priv->sipsession, media);
- }
-
- rakia_sip_session_media_changed (priv->sipsession);
-
- return TRUE;
-}
-
-void rakia_media_session_list_streams (RakiaMediaSession *session,
- GPtrArray *ret)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
- RakiaMediaStream *stream;
- guint i;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream)
- priv_add_stream_list_entry (ret, stream, session);
- }
-}
-
-
-static gboolean
-rakia_media_session_is_local_hold_ongoing (RakiaMediaSession *self)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- return (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD
- || priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD);
-}
-
-gboolean
-rakia_media_session_request_stream_direction (RakiaMediaSession *self,
- guint stream_id,
- guint direction,
- GError **error)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream;
- RakiaSipSessionState state;
-
- stream = rakia_media_session_get_stream (self, stream_id, error);
- if (stream == NULL)
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "stream %u does not exist", stream_id);
- return FALSE;
- }
-
- state = rakia_sip_session_get_state (priv->sipsession);
-
- SESSION_DEBUG (self, "direction %u requested for stream %u",
- direction, stream_id);
-
- if (state == RAKIA_SIP_SESSION_STATE_INVITE_RECEIVED
- || state == RAKIA_SIP_SESSION_STATE_REINVITE_RECEIVED)
- {
- /* While processing a session offer, we can only mask out direction
- * requested by the remote peer */
- direction &= rakia_sip_media_get_requested_direction (
- rakia_media_stream_get_media (stream));
- }
-
- if (rakia_media_session_is_local_hold_ongoing (self))
- direction = RAKIA_DIRECTION_NONE;
-
- rakia_sip_media_set_requested_direction (
- rakia_media_stream_get_media (stream), direction);
-
- return TRUE;
-}
-
-
-void
-rakia_media_session_accept (RakiaMediaSession *self)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
-
- if (rakia_sip_session_is_accepted (priv->sipsession))
- return;
-
- SESSION_DEBUG (self, "accepting the session");
-
- rakia_sip_session_accept (priv->sipsession);
-
- /* Apply the pending send flags */
- priv_apply_streams_pending_direction (self,
- TP_MEDIA_STREAM_PENDING_LOCAL_SEND |
- TP_MEDIA_STREAM_PENDING_REMOTE_SEND);
-
- /* Can play the DTMF dialstring if an audio stream is connected */
- if (priv->audio_connected)
- g_signal_emit (self, signals[SIG_DTMF_READY], 0);
-}
-
-
-static RakiaMediaStream *
-rakia_media_session_get_stream (RakiaMediaSession *self,
- guint stream_id,
- GError **error)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream;
-
- g_assert (priv->streams != NULL);
-
- if (stream_id >= priv->streams->len)
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "stream ID %u is invalid", stream_id);
- return NULL;
- }
-
- stream = g_ptr_array_index (priv->streams, stream_id);
-
- if (stream == NULL)
- {
- g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "stream %u does not exist", stream_id);
- return NULL;
- }
-
- return stream;
-}
-
-TpLocalHoldState
-rakia_media_session_get_hold_state (RakiaMediaSession *self)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- return priv->hold_state;
-}
-
-static void
-priv_initiate_hold (RakiaMediaSession *self,
- gboolean hold,
- TpLocalHoldStateReason reason)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- gboolean stream_hold_requested = FALSE;
- RakiaMediaStream *stream;
- guint i;
-
- DEBUG("enter");
-
- if (hold)
- {
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD
- || priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD)
- {
- MESSAGE ("redundant hold request");
- return;
- }
- }
- else
- {
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD
- || priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_UNHOLD)
- {
- MESSAGE ("redundant unhold request");
- return;
- }
- }
-
- /* Emit the hold notification for every stream that needs it */
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream != NULL
- && rakia_media_stream_request_hold_state (stream, hold))
- stream_hold_requested = TRUE;
- }
-
- if (stream_hold_requested)
- {
- priv->hold_state = hold? TP_LOCAL_HOLD_STATE_PENDING_HOLD
- : TP_LOCAL_HOLD_STATE_PENDING_UNHOLD;
- }
- else
- {
- /* There were no streams to flip, short cut to the final state */
- priv->hold_state = hold? TP_LOCAL_HOLD_STATE_HELD
- : TP_LOCAL_HOLD_STATE_UNHELD;
- }
- priv->hold_reason = reason;
-
- tp_svc_channel_interface_hold_emit_hold_state_changed (priv->channel,
- priv->hold_state, reason);
-}
-
-static void
-priv_finalize_hold (RakiaMediaSession *self)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream;
- TpLocalHoldState final_hold_state;
- guint i;
- gboolean held = FALSE;
- RakiaDirection dir;
-
- DEBUG("enter");
-
- switch (priv->hold_state)
- {
- case TP_LOCAL_HOLD_STATE_PENDING_HOLD:
- held = TRUE;
- break;
- case TP_LOCAL_HOLD_STATE_PENDING_UNHOLD:
- held = FALSE;
- break;
- default:
- /* Streams changed state without request, signal this to the client.
- * All streams should have the same hold state at this point,
- * so just query one of them for the current hold state */
- stream = NULL;
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream != NULL)
- break;
- }
- g_return_if_fail (stream != NULL);
-
- g_object_get (stream, "hold-state", &held, NULL);
- }
-
- if (held)
- {
- final_hold_state = TP_LOCAL_HOLD_STATE_HELD;
- dir = RAKIA_DIRECTION_NONE;
- }
- else
- {
- final_hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
- dir = RAKIA_DIRECTION_BIDIRECTIONAL;
- }
-
- priv->hold_state = final_hold_state;
- tp_svc_channel_interface_hold_emit_hold_state_changed (priv->channel,
- final_hold_state, priv->hold_reason);
-
- /* Set stream directions accordingly to the achieved hold state */
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream != NULL)
- {
- rakia_sip_media_set_requested_direction (
- rakia_media_stream_get_media (stream), dir);
- }
- }
-}
-
-void
-rakia_media_session_request_hold (RakiaMediaSession *self,
- gboolean hold)
-{
- priv_initiate_hold (self,
- hold,
- TP_LOCAL_HOLD_STATE_REASON_REQUESTED);
-}
-
-gboolean
-rakia_media_session_has_media (RakiaMediaSession *self,
- TpMediaStreamType type)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream;
- guint i;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream == NULL)
- continue;
- if (rakia_media_stream_get_media_type (stream) == type)
- return TRUE;
- }
-
- return FALSE;
-}
-
-void
-rakia_media_session_start_telephony_event (RakiaMediaSession *self,
- guchar event)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream;
- guint i;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream == NULL)
- continue;
- if (rakia_media_stream_get_media_type (stream)
- != TP_MEDIA_STREAM_TYPE_AUDIO)
- continue;
-
- SESSION_DEBUG (self, "starting telephony event %u on stream %u",
- (guint) event, i);
-
- rakia_media_stream_start_telephony_event (stream, event);
- }
-}
-
-void
-rakia_media_session_stop_telephony_event (RakiaMediaSession *self)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream;
- guint i;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index(priv->streams, i);
- if (stream == NULL)
- continue;
- if (rakia_media_stream_get_media_type (stream)
- != TP_MEDIA_STREAM_TYPE_AUDIO)
- continue;
-
- SESSION_DEBUG (self, "stopping the telephony event on stream %u", i);
-
- rakia_media_stream_stop_telephony_event (stream);
- }
-}
-
-gint
-rakia_media_session_rate_native_transport (RakiaMediaSession *session,
- const GValue *transport)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
- gint result = 0;
- gchar *address = NULL;
- guint proto = TP_MEDIA_STREAM_BASE_PROTO_UDP;
-
- dbus_g_type_struct_get (transport,
- 1, &address,
- 3, &proto,
- G_MAXUINT);
-
- g_assert (address != NULL);
-
- if (proto != TP_MEDIA_STREAM_BASE_PROTO_UDP)
- result = -1;
- /* XXX: this will not work properly when IPv6 support comes */
- else if (priv->local_ip_address != NULL
- && strcmp (address, priv->local_ip_address) == 0)
- result = 1;
-
- g_free (address);
-
- return result;
-}
-
-static void
-priv_stream_close_cb (RakiaMediaStream *stream,
- RakiaMediaSession *session)
-{
- RakiaMediaSessionPrivate *priv;
- RakiaSipMedia *media;
- guint id;
-
- DEBUG("enter");
-
- priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
-
- id = rakia_media_stream_get_id (stream);
- g_return_if_fail (g_ptr_array_index(priv->streams, id) == stream);
-
- media = rakia_media_stream_get_media (stream);
- rakia_sip_session_remove_media (priv->sipsession, media);
-
- g_object_unref (stream);
-
- g_ptr_array_index(priv->streams, id) = NULL;
-
- tp_svc_channel_type_streamed_media_emit_stream_removed (priv->channel, id);
-}
-
-static void
-priv_stream_state_changed_cb (RakiaMediaStream *stream,
- guint state,
- RakiaMediaSession *session)
-{
- RakiaMediaSessionPrivate *priv = session->priv;
-
- tp_svc_channel_type_streamed_media_emit_stream_state_changed(
- priv->channel,
- rakia_media_stream_get_id (stream), state);
-
- /* Check if DTMF can now be played */
- if (!priv->audio_connected
- && state == TP_MEDIA_STREAM_STATE_CONNECTED
- && rakia_media_stream_get_media_type (stream)
- == TP_MEDIA_STREAM_TYPE_AUDIO)
- {
- priv->audio_connected = TRUE;
-
- if (rakia_sip_session_is_accepted (priv->sipsession))
- g_signal_emit (session, signals[SIG_DTMF_READY], 0);
- }
-}
-
-static void
-priv_stream_direction_changed_cb (RakiaMediaStream *stream,
- guint direction,
- guint pending_send_flags,
- RakiaMediaChannel *channel)
-{
- g_assert (RAKIA_IS_MEDIA_CHANNEL (channel));
- tp_svc_channel_type_streamed_media_emit_stream_direction_changed (
- channel,
- rakia_media_stream_get_id (stream), direction, pending_send_flags);
-}
-
-static void
-priv_stream_hold_state_cb (RakiaMediaStream *stream,
- GParamSpec *pspec,
- RakiaMediaSession *session)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (session);
- gboolean hold;
- guint i;
-
- /* Determine the hold state all streams shall come to */
- switch (priv->hold_state)
- {
- case TP_LOCAL_HOLD_STATE_PENDING_HOLD:
- hold = TRUE;
- break;
- case TP_LOCAL_HOLD_STATE_PENDING_UNHOLD:
- hold = FALSE;
- break;
- default:
- SESSION_MESSAGE (session, "unexpected hold state change from a stream");
-
- /* Try to follow the changes and report the resulting hold state */
- g_object_get (stream, "hold-state", &hold, NULL);
- priv->hold_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- }
-
- /* Check if all streams have reached the desired hold state */
- for (i = 0; i < priv->streams->len; i++)
- {
- stream = g_ptr_array_index (priv->streams, i);
- if (stream != NULL)
- {
- gboolean stream_held = FALSE;
- g_object_get (stream, "hold-state", &stream_held, NULL);
- if ((!stream_held) != (!hold))
- {
- SESSION_DEBUG (session, "hold/unhold not complete yet");
- return;
- }
- }
- }
-
- priv_finalize_hold (session);
-}
-
-static void
-priv_stream_unhold_failure_cb (RakiaMediaStream *stream,
- RakiaMediaSession *session)
-{
- priv_initiate_hold (session,
- TRUE,
- TP_LOCAL_HOLD_STATE_REASON_RESOURCE_NOT_AVAILABLE);
-}
-
-RakiaMediaStream*
-rakia_media_session_add_stream (RakiaMediaSession *self,
- guint media_type,
- TpMediaStreamDirection direction,
- gboolean created_locally)
-{
- RakiaMediaSessionPrivate *priv = RAKIA_MEDIA_SESSION_GET_PRIVATE (self);
- RakiaMediaStream *stream = NULL;
-
- DEBUG ("enter");
-
- if (rakia_media_session_supports_media_type (media_type)) {
- guint stream_id;
- gchar *object_path;
- guint pending_send_flags;
- RakiaSipMedia *media;
-
- stream_id = priv->streams->len;
- object_path = g_strdup_printf ("%s/MediaStream%u",
- priv->object_path,
- stream_id);
- pending_send_flags = created_locally
- ? TP_MEDIA_STREAM_PENDING_REMOTE_SEND
- : TP_MEDIA_STREAM_PENDING_LOCAL_SEND;
-
- if (!created_locally)
- direction &= ~TP_MEDIA_STREAM_DIRECTION_SEND;
-
- if (rakia_media_session_is_local_hold_ongoing (self))
- direction &= ~TP_MEDIA_STREAM_DIRECTION_RECEIVE;
-
- media = rakia_sip_session_add_media (priv->sipsession,
- media_type, direction, created_locally);
-
- stream = g_object_new (RAKIA_TYPE_MEDIA_STREAM,
- "dbus-daemon", priv->dbus_daemon,
- "media-session", self,
- "sip-media", media,
- "media-type", media_type,
- "object-path", object_path,
- "id", stream_id,
- "direction", direction,
- "pending-send-flags", pending_send_flags,
- "created-locally", created_locally,
- NULL);
-
- g_free (object_path);
-
- g_signal_connect (stream, "close",
- G_CALLBACK (priv_stream_close_cb),
- self);
- g_signal_connect (stream, "state-changed",
- G_CALLBACK (priv_stream_state_changed_cb),
- self);
- g_signal_connect (stream, "direction-changed",
- G_CALLBACK (priv_stream_direction_changed_cb),
- priv->channel);
- g_signal_connect (stream, "notify::hold-state",
- G_CALLBACK (priv_stream_hold_state_cb),
- self);
- g_signal_connect (stream, "unhold-failure",
- G_CALLBACK (priv_stream_unhold_failure_cb),
- self);
-
- g_assert (priv->local_non_ready >= 0);
- ++priv->local_non_ready;
-
- if (priv->se_ready)
- priv_emit_new_stream (self, stream);
-
- tp_svc_channel_type_streamed_media_emit_stream_added (priv->channel,
- stream_id,
- priv->peer,
- media_type);
- if (direction != TP_MEDIA_STREAM_DIRECTION_RECEIVE
- || pending_send_flags != TP_MEDIA_STREAM_PENDING_LOCAL_SEND)
- {
- tp_svc_channel_type_streamed_media_emit_stream_direction_changed (
- priv->channel,
- stream_id,
- direction,
- pending_send_flags);
- }
- }
-
- /* note: we add an entry even for unsupported media types */
- g_ptr_array_add (priv->streams, stream);
-
- DEBUG ("exit");
-
- return stream;
-}
-
-static void
-session_handler_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcMediaSessionHandlerClass *klass = (TpSvcMediaSessionHandlerClass *)g_iface;
-
-#define IMPLEMENT(x) tp_svc_media_session_handler_implement_##x (\
- klass, (tp_svc_media_session_handler_##x##_impl) rakia_media_session_##x)
- IMPLEMENT(error);
- IMPLEMENT(ready);
-#undef IMPLEMENT
-}
-
-
-gboolean
-rakia_media_session_is_accepted (RakiaMediaSession *self)
-{
- return rakia_sip_session_is_accepted (self->priv->sipsession);
-}
diff --git a/rakia/media-session.h b/rakia/media-session.h
deleted file mode 100644
index 0a0c795..0000000
--- a/rakia/media-session.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * sip-media-session.h - Header for RakiaMediaSession
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005-2010 Nokia Corporation
- *
- * This work is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This work is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this work; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __RAKIA_MEDIA_SESSION_H__
-#define __RAKIA_MEDIA_SESSION_H__
-
-#include <rakia/media-stream.h>
-
-#include <glib-object.h>
-#include <telepathy-glib/handle.h>
-#include <sofia-sip/sdp.h>
-
-G_BEGIN_DECLS
-
-typedef struct _RakiaMediaSession RakiaMediaSession;
-typedef struct _RakiaMediaSessionClass RakiaMediaSessionClass;
-typedef struct _RakiaMediaSessionPrivate RakiaMediaSessionPrivate;
-
-struct _RakiaMediaSessionClass {
- GObjectClass parent_class;
-};
-
-struct _RakiaMediaSession {
- GObject parent;
- RakiaMediaSessionPrivate *priv;
-};
-
-GType rakia_media_session_get_type(void);
-
-/* TYPE MACROS */
-#define RAKIA_TYPE_MEDIA_SESSION \
- (rakia_media_session_get_type())
-#define RAKIA_MEDIA_SESSION(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), RAKIA_TYPE_MEDIA_SESSION, RakiaMediaSession))
-#define RAKIA_MEDIA_SESSION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), RAKIA_TYPE_MEDIA_SESSION, RakiaMediaSessionClass))
-#define RAKIA_IS_MEDIA_SESSION(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), RAKIA_TYPE_MEDIA_SESSION))
-#define RAKIA_IS_MEDIA_SESSION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), RAKIA_TYPE_MEDIA_SESSION))
-#define RAKIA_MEDIA_SESSION_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), RAKIA_TYPE_MEDIA_SESSION, RakiaMediaSessionClass))
-
-/***********************************************************************
- * Additional declarations (not based on generated templates)
- ***********************************************************************/
-
-TpHandle rakia_media_session_get_peer (RakiaMediaSession *session);
-RakiaMediaStream* rakia_media_session_add_stream (RakiaMediaSession *self,
- guint media_type,
- TpMediaStreamDirection direction,
- gboolean created_locally);
-gboolean rakia_media_session_request_streams (RakiaMediaSession *session,
- const GArray *media_types,
- GPtrArray *ret,
- GError **error);
-gboolean rakia_media_session_remove_streams (RakiaMediaSession *session,
- const GArray *stream_ids,
- GError **error);
-void rakia_media_session_list_streams (RakiaMediaSession *session,
- GPtrArray *ret);
-gboolean rakia_media_session_request_stream_direction (RakiaMediaSession *session,
- guint stream_id,
- guint direction,
- GError **error);
-void rakia_media_session_accept (RakiaMediaSession *self);
-gboolean rakia_media_session_is_accepted (RakiaMediaSession *self);
-
-TpLocalHoldState rakia_media_session_get_hold_state (RakiaMediaSession *session);
-void rakia_media_session_request_hold (RakiaMediaSession *session,
- gboolean hold);
-
-gboolean rakia_media_session_has_media (RakiaMediaSession *self,
- TpMediaStreamType type);
-
-void rakia_media_session_start_telephony_event (RakiaMediaSession *self,
- guchar event);
-void rakia_media_session_stop_telephony_event (RakiaMediaSession *self);
-
-gint rakia_media_session_rate_native_transport (RakiaMediaSession *session,
- const GValue *transport);
-
-gchar * rakia_sdp_get_string_attribute (const sdp_attribute_t *attrs,
- const char *name);
-
-G_END_DECLS
-
-#endif /* #ifndef __RAKIA_MEDIA_SESSION_H__*/
diff --git a/rakia/media-stream.c b/rakia/media-stream.c
deleted file mode 100644
index 3b62353..0000000
--- a/rakia/media-stream.c
+++ /dev/null
@@ -1,1532 +0,0 @@
-/*
- * sip-media-stream.c - Source for RakiaMediaStream
- * Copyright (C) 2006 Collabora Ltd.
- * Copyright (C) 2006-2010 Nokia Corporation
- * @author Kai Vehmanen <first.surname@nokia.com>
- * @author Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
- *
- * Based on telepathy-gabble implementation (gabble-media-stream).
- * @author Ole Andre Vadla Ravnaas <ole.andre.ravnaas@collabora.co.uk>
- *
- * This work is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This work is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this work; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "rakia/media-stream.h"
-
-#include <dbus/dbus-glib.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/enums.h>
-#include <telepathy-glib/errors.h>
-#include <telepathy-glib/gtypes.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/svc-generic.h>
-#include <telepathy-glib/svc-media-interfaces.h>
-#include <telepathy-glib/util.h>
-
-#include "config.h"
-
-#include <rakia/codec-param-formats.h>
-
-
-#include "rakia/media-session.h"
-#include "rakia/sip-session.h"
-
-#include <sofia-sip/msg_parser.h>
-
-#include "signals-marshal.h"
-
-#define DEBUG_FLAG RAKIA_DEBUG_MEDIA
-#include "rakia/debug.h"
-
-
-#define same_boolean(old, new) ((!(old)) == (!(new)))
-
-
-#ifdef ENABLE_DEBUG
-
-#define STREAM_DEBUG(stream, format, ...) \
- rakia_log (DEBUG_FLAG, G_LOG_LEVEL_DEBUG, "stream %u: " format, \
- (stream)->priv->id,##__VA_ARGS__)
-
-#define STREAM_MESSAGE(stream, format, ...) \
- rakia_log (DEBUG_FLAG, G_LOG_LEVEL_MESSAGE, "stream %u: " format, \
- (stream)->priv->id,##__VA_ARGS__)
-
-#else
-
-#define STREAM_DEBUG(stream, format, ...) G_STMT_START { } G_STMT_END
-#define STREAM_MESSAGE(stream, format, ...) G_STMT_START { } G_STMT_END
-
-#endif
-
-
-static void stream_handler_iface_init (gpointer, gpointer);
-
-G_DEFINE_TYPE_WITH_CODE(RakiaMediaStream,
- rakia_media_stream,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_MEDIA_STREAM_HANDLER,
- stream_handler_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- )
-
-/* signal enum */
-enum
-{
- SIG_READY,
- SIG_SUPPORTED_CODECS,
- SIG_STATE_CHANGED,
- SIG_DIRECTION_CHANGED,
- SIG_LOCAL_MEDIA_UPDATED,
- SIG_UNHOLD_FAILURE,
-
- SIG_LAST_SIGNAL
-};
-
-static guint signals[SIG_LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_MEDIA_SESSION = 1,
- PROP_DBUS_DAEMON,
- PROP_OBJECT_PATH,
- PROP_ID,
- PROP_MEDIA_TYPE,
- PROP_SIP_MEDIA,
- PROP_STATE,
- PROP_DIRECTION,
- PROP_PENDING_SEND_FLAGS,
- PROP_HOLD_STATE,
- PROP_CREATED_LOCALLY,
- PROP_NAT_TRAVERSAL,
- PROP_STUN_SERVERS,
- PROP_RELAY_INFO,
- LAST_PROPERTY
-};
-
-static GPtrArray *rakia_media_stream_relay_info_empty = NULL;
-
-/* private structure */
-struct _RakiaMediaStreamPrivate
-{
- TpDBusDaemon *dbus_daemon;
- RakiaMediaSession *session; /* see gobj. prop. 'media-session' */
- gchar *object_path; /* see gobj. prop. 'object-path' */
- RakiaSipMedia *media;
- guint id; /* see gobj. prop. 'id' */
- guint media_type; /* see gobj. prop. 'media-type' */
- guint state; /* see gobj. prop. 'state' */
- guint direction; /* see gobj. prop. 'direction' */
- guint pending_send_flags; /* see gobj. prop. 'pending-send-flags' */
- gboolean hold_state; /* see gobj. prop. 'hold-state' */
- gboolean created_locally; /* see gobj. prop. 'created-locally' */
-
- guint remote_candidate_counter;
- gchar *remote_candidate_id;
-
- gchar *native_candidate_id;
-
- gboolean ready_received; /* our ready method has been called */
- gboolean playing; /* stream set to playing */
- gboolean sending; /* stream set to sending */
- gboolean pending_remote_receive; /* TRUE if remote is to agree to receive media */
- gboolean native_cands_prepared; /* all candidates discovered */
- gboolean native_codecs_prepared; /* all codecs discovered */
- gboolean push_remote_cands_pending; /* SetRemoteCandidates emission is pending */
- gboolean push_remote_codecs_pending; /* SetRemoteCodecs emission is pending */
- gboolean codec_intersect_pending; /* codec intersection is pending */
- gboolean requested_hold_state; /* hold state last requested from the stream handler */
- gboolean dispose_has_run;
-};
-
-#define RAKIA_MEDIA_STREAM_GET_PRIVATE(stream) ((stream)->priv)
-
-static void push_remote_codecs (RakiaMediaStream *stream);
-static void push_remote_candidates (RakiaMediaStream *stream);
-static void priv_update_sending (RakiaMediaStream *stream,
- TpMediaStreamDirection direction);
-static void priv_emit_local_ready (RakiaMediaStream *stream);
-
-/***********************************************************************
- * Set: Gobject interface
- ***********************************************************************/
-
-static void
-rakia_media_stream_init (RakiaMediaStream *self)
-{
- RakiaMediaStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
- RAKIA_TYPE_MEDIA_STREAM, RakiaMediaStreamPrivate);
-
- self->priv = priv;
-}
-
-static void
-rakia_media_stream_constructed (GObject *obj)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (
- RAKIA_MEDIA_STREAM (obj));
- GObjectClass *parent_object_class =
- G_OBJECT_CLASS (rakia_media_stream_parent_class);
-
- /* call base class method */
- if (parent_object_class->constructed != NULL)
- parent_object_class->constructed (obj);
-
- /* XXX: overloading the remote pending send flag to check
- * if this is a locally offered stream. The code creating such streams
- * always sets the flag, because the remote end is supposed to decide
- * whether it wants to send.
- * This may look weird during a local hold. However, the pending flag
- * will be harmlessly cleared once the offer-answer is complete. */
- if ((priv->direction & TP_MEDIA_STREAM_DIRECTION_SEND) != 0
- && (priv->pending_send_flags & TP_MEDIA_STREAM_PENDING_REMOTE_SEND) != 0)
- {
- /* Block sending until the stream is remotely accepted */
- priv->pending_remote_receive = TRUE;
- }
-
- g_signal_connect_object (priv->media, "remote-candidates-updated",
- G_CALLBACK (push_remote_candidates), obj, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->media, "remote-codecs-updated",
- G_CALLBACK (push_remote_codecs), obj, G_CONNECT_SWAPPED);
-
- /* go for the bus */
- g_assert (TP_IS_DBUS_DAEMON (priv->dbus_daemon));
- tp_dbus_daemon_register_object (priv->dbus_daemon, priv->object_path, obj);
-}
-
-static void
-rakia_media_stream_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- RakiaMediaStream *stream = RAKIA_MEDIA_STREAM (object);
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
-
- switch (property_id)
- {
- case PROP_DBUS_DAEMON:
- g_value_set_object (value, priv->dbus_daemon);
- break;
- case PROP_MEDIA_SESSION:
- g_value_set_object (value, priv->session);
- break;
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_ID:
- g_value_set_uint (value, priv->id);
- break;
- case PROP_MEDIA_TYPE:
- g_value_set_uint (value, priv->media_type);
- break;
- case PROP_SIP_MEDIA:
- g_value_set_object (value, priv->media);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- case PROP_DIRECTION:
- g_value_set_uint (value, priv->direction);
- break;
- case PROP_PENDING_SEND_FLAGS:
- g_value_set_uint (value, priv->pending_send_flags);
- break;
- case PROP_HOLD_STATE:
- g_value_set_boolean (value, priv->hold_state);
- break;
- case PROP_CREATED_LOCALLY:
- g_value_set_boolean (value, priv->created_locally);
- break;
- case PROP_NAT_TRAVERSAL:
- g_value_set_static_string (value, "none");
- break;
- case PROP_STUN_SERVERS:
- g_return_if_fail (priv->session != NULL);
- g_object_get_property (G_OBJECT (priv->session), "stun-servers", value);
- break;
- case PROP_RELAY_INFO:
- g_value_set_static_boxed (value, rakia_media_stream_relay_info_empty);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-rakia_media_stream_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- RakiaMediaStream *stream = RAKIA_MEDIA_STREAM (object);
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
-
- switch (property_id)
- {
- case PROP_DBUS_DAEMON:
- g_assert (priv->dbus_daemon == NULL); /* construct-only */
- priv->dbus_daemon = g_value_dup_object (value);
- break;
- case PROP_MEDIA_SESSION:
- priv->session = g_value_get_object (value);
- break;
- case PROP_OBJECT_PATH:
- g_free (priv->object_path);
- priv->object_path = g_value_dup_string (value);
- break;
- case PROP_ID:
- priv->id = g_value_get_uint (value);
- break;
- case PROP_MEDIA_TYPE:
- priv->media_type = g_value_get_uint (value);
- break;
- case PROP_SIP_MEDIA:
- priv->media = g_value_dup_object (value);
- break;
- case PROP_STATE:
- priv->state = g_value_get_uint (value);
- break;
- case PROP_DIRECTION:
- priv->direction = g_value_get_uint (value);
- break;
- case PROP_PENDING_SEND_FLAGS:
- priv->pending_send_flags = g_value_get_uint (value);
- break;
- case PROP_HOLD_STATE:
- priv->hold_state = g_value_get_boolean (value);
- break;
- case PROP_CREATED_LOCALLY:
- priv->created_locally = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void rakia_media_stream_dispose (GObject *object);
-static void rakia_media_stream_finalize (GObject *object);
-
-static void
-rakia_media_stream_class_init (RakiaMediaStreamClass *klass)
-{
- static TpDBusPropertiesMixinPropImpl stream_handler_props[] = {
- { "CreatedLocally", "created-locally", NULL },
- { "NATTraversal", "nat-traversal", NULL },
- { "STUNServers", "stun-servers", NULL },
- { "RelayInfo", "relay-info", NULL },
- { NULL }
- };
-
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_MEDIA_STREAM_HANDLER,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- stream_handler_props,
- },
- { NULL }
- };
-
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GType stream_type = G_OBJECT_CLASS_TYPE (klass);
- GParamSpec *param_spec;
-
- g_type_class_add_private (klass, sizeof (RakiaMediaStreamPrivate));
-
- object_class->constructed = rakia_media_stream_constructed;
-
- object_class->get_property = rakia_media_stream_get_property;
- object_class->set_property = rakia_media_stream_set_property;
-
- object_class->dispose = rakia_media_stream_dispose;
- object_class->finalize = rakia_media_stream_finalize;
-
- param_spec = g_param_spec_object ("dbus-daemon", "TpDBusDaemon",
- "Connection to D-Bus.", TP_TYPE_DBUS_DAEMON,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DBUS_DAEMON, param_spec);
-
- param_spec = g_param_spec_object ("media-session", "RakiaMediaSession object",
- "SIP media session object that owns this media stream object.",
- RAKIA_TYPE_MEDIA_SESSION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEDIA_SESSION, param_spec);
-
- param_spec = g_param_spec_string ("object-path", "D-Bus object path",
- "The D-Bus object path used for this object on the bus.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
-
- param_spec = g_param_spec_uint ("id", "Stream ID",
- "A stream number for the stream used in the D-Bus API.",
- 0, G_MAXUINT,
- 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_ID, param_spec);
-
- param_spec = g_param_spec_uint ("media-type", "Stream media type",
- "A constant indicating which media type the stream carries.",
- TP_MEDIA_STREAM_TYPE_AUDIO, TP_MEDIA_STREAM_TYPE_VIDEO,
- TP_MEDIA_STREAM_TYPE_AUDIO,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEDIA_TYPE, param_spec);
-
-
- param_spec = g_param_spec_object ("sip-media", "RakiaSipMedia object",
- "SIP media session object that owns this media stream object.",
- RAKIA_TYPE_MEDIA_SESSION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEDIA_SESSION, param_spec);
-
-
- param_spec = g_param_spec_uint ("state", "Connection state",
- "Connection state of the media stream",
- TP_MEDIA_STREAM_STATE_DISCONNECTED, TP_MEDIA_STREAM_STATE_CONNECTED,
- TP_MEDIA_STREAM_STATE_DISCONNECTED,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STATE, param_spec);
-
- /* We don't change the following two as individual properties
- * after construction, use rakia_media_stream_set_direction() */
-
- param_spec = g_param_spec_uint ("direction", "Stream direction",
- "A value indicating the current direction of the stream",
- TP_MEDIA_STREAM_DIRECTION_NONE, TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DIRECTION, param_spec);
-
- param_spec = g_param_spec_uint ("pending-send-flags", "Pending send flags",
- "Flags indicating the current pending send state of the stream",
- 0,
- TP_MEDIA_STREAM_PENDING_LOCAL_SEND | TP_MEDIA_STREAM_PENDING_REMOTE_SEND,
- 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_PENDING_SEND_FLAGS,
- param_spec);
-
- param_spec = g_param_spec_boolean ("hold-state", "Hold state",
- "Hold state of the media stream as reported by the stream engine",
- FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_HOLD_STATE,
- param_spec);
-
- param_spec = g_param_spec_boolean ("created-locally", "Created locally?",
- "True if this stream was created by the local user", FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATED_LOCALLY,
- param_spec);
-
- param_spec = g_param_spec_string ("nat-traversal", "NAT traversal",
- "NAT traversal mechanism for this stream", NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_NAT_TRAVERSAL,
- param_spec);
-
- param_spec = g_param_spec_boxed ("stun-servers", "STUN servers",
- "Array of IP address-port pairs for available STUN servers",
- TP_ARRAY_TYPE_SOCKET_ADDRESS_IP_LIST,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_SERVERS, param_spec);
-
- param_spec = g_param_spec_boxed ("relay-info", "Relay info",
- "Array of mappings containing relay server information",
- TP_ARRAY_TYPE_STRING_VARIANT_MAP_LIST,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_RELAY_INFO, param_spec);
-
- rakia_media_stream_relay_info_empty = g_ptr_array_new ();
-
- /* signals not exported by DBus interface */
- signals[SIG_READY] =
- g_signal_new ("ready",
- stream_type,
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[SIG_SUPPORTED_CODECS] =
- g_signal_new ("supported-codecs",
- stream_type,
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
-
- signals[SIG_STATE_CHANGED] =
- g_signal_new ("state-changed",
- stream_type,
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
-
- signals[SIG_DIRECTION_CHANGED] =
- g_signal_new ("direction-changed",
- stream_type,
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- _rakia_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-
- signals[SIG_LOCAL_MEDIA_UPDATED] =
- g_signal_new ("local-media-updated",
- stream_type,
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[SIG_UNHOLD_FAILURE] =
- g_signal_new ("unhold-failure",
- stream_type,
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- klass->dbus_props_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (RakiaMediaStreamClass, dbus_props_class));
-}
-
-void
-rakia_media_stream_dispose (GObject *object)
-{
- RakiaMediaStream *self = RAKIA_MEDIA_STREAM (object);
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
-
- if (priv->dispose_has_run)
- return;
-
- priv->dispose_has_run = TRUE;
-
- tp_clear_object (&priv->media);
- tp_clear_object (&priv->dbus_daemon);
-
- if (G_OBJECT_CLASS (rakia_media_stream_parent_class)->dispose)
- G_OBJECT_CLASS (rakia_media_stream_parent_class)->dispose (object);
-
- DEBUG ("exit");
-}
-
-void
-rakia_media_stream_finalize (GObject *object)
-{
- RakiaMediaStream *self = RAKIA_MEDIA_STREAM (object);
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
-
- /* free any data held directly by the object here */
- g_free (priv->object_path);
-
-
- g_free (priv->native_candidate_id);
- g_free (priv->remote_candidate_id);
-
- G_OBJECT_CLASS (rakia_media_stream_parent_class)->finalize (object);
-
- DEBUG ("exit");
-}
-
-/***********************************************************************
- * Set: Media.StreamHandler interface implementation (same for 0.12/0.13???)
- ***********************************************************************/
-
-/**
- * rakia_media_stream_error
- *
- * Implements DBus method Error
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-rakia_media_stream_error (TpSvcMediaStreamHandler *iface,
- guint errno,
- const gchar *message,
- DBusGMethodInvocation *context)
-{
- RakiaMediaStream *self = RAKIA_MEDIA_STREAM (iface);
-
- STREAM_DEBUG (self, "StreamHandler.Error called: %u %s", errno, message);
-
- rakia_media_stream_close (self);
-
- tp_svc_media_stream_handler_return_from_error (context);
-}
-
-/**
- * rakia_media_stream_native_candidates_prepared
- *
- * Implements DBus method NativeCandidatesPrepared
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-rakia_media_stream_native_candidates_prepared (TpSvcMediaStreamHandler *iface,
- DBusGMethodInvocation *context)
-{
- /* purpose: "Informs the connection manager that all possible native candisates
- * have been discovered for the moment."
- */
-
- RakiaMediaStream *obj = RAKIA_MEDIA_STREAM (iface);
- RakiaMediaStreamPrivate *priv = obj->priv;
-
- STREAM_DEBUG(obj, "Media.StreamHandler.NativeCandidatesPrepared called");
-
- priv->native_cands_prepared = TRUE;
-
- rakia_sip_media_local_candidates_prepared (priv->media);
-
- if (priv->native_codecs_prepared)
- priv_emit_local_ready (obj);
-
- tp_svc_media_stream_handler_return_from_native_candidates_prepared (context);
-}
-
-
-/**
- * rakia_media_stream_new_active_candidate_pair
- *
- * Implements DBus method NewActiveCandidatePair
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-rakia_media_stream_new_active_candidate_pair (TpSvcMediaStreamHandler *iface,
- const gchar *native_candidate_id,
- const gchar *remote_candidate_id,
- DBusGMethodInvocation *context)
-{
- RakiaMediaStream *self = RAKIA_MEDIA_STREAM (iface);
- RakiaMediaStreamPrivate *priv = self->priv;
-
- STREAM_DEBUG (self, "stream engine reported new active candidate pair %s-%s",
- native_candidate_id, remote_candidate_id);
-
- if (priv->remote_candidate_id == NULL
- || strcmp (priv->remote_candidate_id, remote_candidate_id))
- {
- GError *err;
- err = g_error_new (TP_ERRORS,
- TP_ERROR_INVALID_ARGUMENT,
- "Remote candidate ID does not match the locally "
- "stored data");
- dbus_g_method_return_error (context, err);
- g_error_free (err);
- return;
- }
-
- tp_svc_media_stream_handler_return_from_new_active_candidate_pair (context);
-}
-
-
-/**
- * rakia_media_stream_new_native_candidate
- *
- * Implements DBus method NewNativeCandidate
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-rakia_media_stream_new_native_candidate (TpSvcMediaStreamHandler *iface,
- const gchar *candidate_id,
- const GPtrArray *transports,
- DBusGMethodInvocation *context)
-{
- RakiaMediaStream *obj = RAKIA_MEDIA_STREAM (iface);
- RakiaMediaStreamPrivate *priv;
- GValue transport = { 0, };
- guint i;
-
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (obj);
-
- g_return_if_fail (transports->len >= 1);
-
-
- /* Rate the preferability of the address */
- g_value_init (&transport, TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT);
-
- for (i = 0; i < transports->len; i++)
- {
- RakiaSipCandidate *sipcandidate;
- guint tr_component;
- guint tr_proto = G_MAXUINT;
- gchar *tr_ip;
- guint tr_port;
- gdouble tr_preference;
-
- g_value_set_static_boxed (&transport,
- g_ptr_array_index (transports, i));
-
- /* Find the RTP component */
- dbus_g_type_struct_get (&transport,
- 0, &tr_component,
- 1, &tr_ip,
- 2, &tr_port,
- 3, &tr_proto,
- 6, &tr_preference,
- G_MAXUINT);
-
- if (tr_proto != TP_MEDIA_STREAM_BASE_PROTO_UDP)
- continue;
-
- sipcandidate = rakia_sip_candidate_new (tr_component,
- tr_ip, tr_port, candidate_id, (guint) tr_preference * 65536);
-
- g_free (tr_ip);
-
- rakia_sip_media_take_local_candidate (priv->media, sipcandidate);
- }
-
-
- STREAM_DEBUG(obj, "put native candidate '%s' into cache", candidate_id);
-
- tp_svc_media_stream_handler_return_from_new_native_candidate (context);
-}
-
-static void
-priv_set_local_codecs (RakiaMediaStream *self,
- const GPtrArray *codecs)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
- GPtrArray *sipcodecs = g_ptr_array_new_with_free_func (
- (GDestroyNotify)rakia_sip_codec_free);
- GValue codec = { 0, };
- gchar *co_name = NULL;
- guint co_id;
- guint co_type;
- guint co_clockrate;
- guint co_channels;
- GHashTable *co_params = NULL;
- guint i;
- STREAM_DEBUG(self, "putting list of %d locally supported codecs into cache",
- codecs->len);
-
- g_value_init (&codec, TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC);
-
- for (i = 0; i < codecs->len; i++)
- {
- RakiaSipCodec *sipcodec;
- GHashTableIter iter;
- gpointer key, value;
-
- g_value_set_static_boxed (&codec, g_ptr_array_index (codecs, i));
-
- dbus_g_type_struct_get (&codec,
- 0, &co_id,
- 1, &co_name,
- 2, &co_type,
- 3, &co_clockrate,
- 4, &co_channels,
- 5, &co_params,
- G_MAXUINT);
-
- sipcodec = rakia_sip_codec_new (co_id, co_name, co_clockrate,
- co_channels);
-
- g_hash_table_iter_init (&iter, co_params);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- rakia_sip_codec_add_param (sipcodec, key, value);
- }
-
- g_ptr_array_add (sipcodecs, sipcodec);
-
- g_free (co_name);
- co_name = NULL;
- g_hash_table_unref (co_params);
- co_params = NULL;
- }
-
- rakia_sip_media_take_local_codecs (priv->media, sipcodecs);
-
- priv->native_codecs_prepared = TRUE;
- if (priv->native_cands_prepared)
- priv_emit_local_ready (self);
-}
-
-static void
-rakia_media_stream_codecs_updated (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- RakiaMediaStream *self = RAKIA_MEDIA_STREAM (iface);
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
-
- if (!priv->native_codecs_prepared)
- {
- GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "CodecsUpdated may not be called before codecs have been provided "
- "with SetLocalCodecs or Ready" };
-
- STREAM_DEBUG (self,
- "CodecsUpdated called before SetLocalCodecs or Ready");
-
- dbus_g_method_return_error (context, &e);
- }
- else
- {
- STREAM_DEBUG (self, "putting list of %d locally supported "
- "codecs from CodecsUpdated into cache", codecs->len);
- priv_set_local_codecs (self, codecs);
-
- if (priv->native_cands_prepared)
- g_signal_emit (self, signals[SIG_LOCAL_MEDIA_UPDATED], 0);
-
- tp_svc_media_stream_handler_return_from_codecs_updated (context);
- }
-}
-
-/**
- * rakia_media_stream_ready
- *
- * Implements DBus method Ready
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-rakia_media_stream_ready (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- /* purpose: "Inform the connection manager that a client is ready to handle
- * this StreamHandler. Also provide it with info about all supported
- * codecs."
- *
- * - note, with SIP we don't send the invite just yet (we need
- * candidates first
- */
-
- RakiaMediaStream *obj = RAKIA_MEDIA_STREAM (iface);
- RakiaMediaStreamPrivate *priv = obj->priv;
-
- STREAM_DEBUG (obj, "Media.StreamHandler.Ready called");
-
- if (priv->ready_received)
- {
- STREAM_MESSAGE (obj, "Ready called more than once");
- tp_svc_media_stream_handler_return_from_ready (context);
- return;
- }
-
- priv->ready_received = TRUE;
-
- if (codecs->len != 0)
- priv_set_local_codecs (obj, codecs);
-
- /* Push the initial sending/playing state */
- tp_svc_media_stream_handler_emit_set_stream_playing (
- iface, priv->playing);
- tp_svc_media_stream_handler_emit_set_stream_sending (
- iface, priv->sending);
-
- if (priv->push_remote_cands_pending)
- {
- priv->push_remote_cands_pending = FALSE;
- push_remote_candidates (obj);
- }
- if (priv->push_remote_codecs_pending)
- {
- priv->push_remote_codecs_pending = FALSE;
- push_remote_codecs (obj);
- }
-
-
- rakia_media_stream_set_playing (obj, TRUE);
-
- tp_svc_media_stream_handler_return_from_ready (context);
-}
-
-static void
-rakia_media_stream_set_local_codecs (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- priv_set_local_codecs (RAKIA_MEDIA_STREAM (iface), codecs);
- tp_svc_media_stream_handler_return_from_set_local_codecs (context);
-}
-
-/**
- * rakia_media_stream_stream_state
- *
- * Implements DBus method StreamState
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-rakia_media_stream_stream_state (TpSvcMediaStreamHandler *iface,
- guint state,
- DBusGMethodInvocation *context)
-{
- /* purpose: "Informs the connection manager of the stream's current state
- * State is as specified in *ChannelTypeStreamedMedia::GetStreams."
- *
- * - set the stream state for session
- */
-
- RakiaMediaStream *obj = RAKIA_MEDIA_STREAM (iface);
- RakiaMediaStreamPrivate *priv;
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (obj);
-
- if (priv->state != state)
- {
- STREAM_DEBUG (obj, "stream state change %u -> %u", priv->state, state);
- priv->state = state;
- g_signal_emit (obj, signals[SIG_STATE_CHANGED], 0, state);
- }
-
- tp_svc_media_stream_handler_return_from_stream_state (context);
-}
-
-/**
- * rakia_media_stream_supported_codecs
- *
- * Implements DBus method SupportedCodecs
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-rakia_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- /* purpose: "Inform the connection manager of the supported codecs for this session.
- * This is called after the connection manager has emitted SetRemoteCodecs
- * to notify what codecs are supported by the peer, and will thus be an
- * intersection of all locally supported codecs (passed to Ready)
- * and those supported by the peer."
- *
- * - emit SupportedCodecs
- */
-
- RakiaMediaStream *self = RAKIA_MEDIA_STREAM (iface);
- RakiaMediaStreamPrivate *priv;
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
-
- STREAM_DEBUG (self,
- "got codec intersection containing %u codecs from stream-engine",
- codecs->len);
-
- /* Save the local codecs, but avoid triggering a new
- * session update at this point. If the stream engine have changed any codec
- * parameters, it is supposed to follow up with CodecsUpdated. */
- priv_set_local_codecs (self, codecs);
-
- if (priv->codec_intersect_pending)
- {
- if (priv->push_remote_codecs_pending)
- {
- /* The remote codec list has been updated since the intersection
- * has started, plunge into a new intersection immediately */
- priv->push_remote_codecs_pending = FALSE;
- push_remote_codecs (self);
- }
- else
- {
- priv->codec_intersect_pending = FALSE;
- g_signal_emit (self, signals[SIG_SUPPORTED_CODECS], 0, codecs->len);
- }
- }
- else
- WARNING("SupportedCodecs called when no intersection is ongoing");
-
- tp_svc_media_stream_handler_return_from_supported_codecs (context);
-}
-
-static void
-rakia_media_stream_hold_state (TpSvcMediaStreamHandler *self,
- gboolean held,
- DBusGMethodInvocation *context)
-{
- g_object_set (self, "hold-state", held, NULL);
- tp_svc_media_stream_handler_return_from_hold_state (context);
-}
-
-static void
-rakia_media_stream_unhold_failure (TpSvcMediaStreamHandler *self,
- DBusGMethodInvocation *context)
-{
- /* Not doing anything to hold_state or requested_hold_state,
- * because the session is going to put all streams on hold after getting
- * the signal below */
-
- g_signal_emit (self, signals[SIG_UNHOLD_FAILURE], 0);
- tp_svc_media_stream_handler_return_from_unhold_failure (context);
-}
-
-/***********************************************************************
- * Helper functions follow (not based on generated templates)
- ***********************************************************************/
-
-guint
-rakia_media_stream_get_id (RakiaMediaStream *self)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
- return priv->id;
-}
-
-guint
-rakia_media_stream_get_media_type (RakiaMediaStream *self)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
- return priv->media_type;
-}
-
-void
-rakia_media_stream_close (RakiaMediaStream *self)
-{
- tp_svc_media_stream_handler_emit_close (self);
-}
-
-/*
- * Returns stream direction as requested by the latest local or remote
- * direction change.
- */
-static TpMediaStreamDirection
-priv_get_requested_direction (RakiaMediaStreamPrivate *priv)
-{
- TpMediaStreamDirection direction;
-
- direction = priv->direction;
- if ((priv->pending_send_flags & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) != 0)
- direction |= TP_MEDIA_STREAM_DIRECTION_SEND;
- return direction;
-}
-
-/**
- * Converts a sofia-sip media type enum to Telepathy media type.
- * See <sofia-sip/sdp.h> and <telepathy-constants.h>.
- *
- * @return G_MAXUINT if the media type cannot be mapped
- */
-guint
-rakia_tp_media_type (sdp_media_e sip_mtype)
-{
- switch (sip_mtype)
- {
- case sdp_media_audio: return TP_MEDIA_STREAM_TYPE_AUDIO;
- case sdp_media_video: return TP_MEDIA_STREAM_TYPE_VIDEO;
- default: return G_MAXUINT;
- }
-}
-
-
-/**
- * Sets the media state to playing or non-playing. When not playing,
- * received RTP packets may not be played locally.
- */
-void rakia_media_stream_set_playing (RakiaMediaStream *stream, gboolean playing)
-{
- RakiaMediaStreamPrivate *priv;
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
-
- if (same_boolean (priv->playing, playing))
- return;
-
- STREAM_DEBUG (stream, "set playing to %s", playing? "TRUE" : "FALSE");
-
- priv->playing = playing;
-
- if (priv->ready_received)
- tp_svc_media_stream_handler_emit_set_stream_playing (
- (TpSvcMediaStreamHandler *)stream, playing);
-}
-
-/**
- * Sets the media state to sending or non-sending. When not sending,
- * captured media are not sent over the network.
- */
-void
-rakia_media_stream_set_sending (RakiaMediaStream *stream, gboolean sending)
-{
- RakiaMediaStreamPrivate *priv;
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
-
- if (same_boolean(priv->sending, sending))
- return;
-
- STREAM_DEBUG (stream, "set sending to %s", sending? "TRUE" : "FALSE");
-
- priv->sending = sending;
-
- if (priv->ready_received)
- tp_svc_media_stream_handler_emit_set_stream_sending (
- (TpSvcMediaStreamHandler *)stream, sending);
-}
-
-static void
-priv_update_sending (RakiaMediaStream *stream,
- TpMediaStreamDirection direction)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
- gboolean sending = TRUE;
-
- /* XXX: the pending send flag check is probably an overkill
- * considering that effective sending direction and pending send should be
- * mutually exclusive */
- if ((direction & TP_MEDIA_STREAM_DIRECTION_SEND) == 0
- || priv->pending_remote_receive
- || (priv->pending_send_flags & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) != 0
- || !rakia_media_session_is_accepted (priv->session))
- {
- sending = FALSE;
- }
-
- rakia_media_stream_set_sending (stream, sending);
-}
-
-void
-rakia_media_stream_set_direction (RakiaMediaStream *stream,
- TpMediaStreamDirection direction,
- guint pending_send_mask)
-{
- RakiaMediaStreamPrivate *priv;
- guint pending_send_flags;
- TpMediaStreamDirection old_sdp_direction;
-
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
- pending_send_flags = priv->pending_send_flags & pending_send_mask;
-
- if ((direction & TP_MEDIA_STREAM_DIRECTION_SEND) == 0)
- {
- /* We won't be sending, clear the pending local send flag */
- pending_send_flags &= ~TP_MEDIA_STREAM_PENDING_LOCAL_SEND;
- }
- else if ((direction & TP_MEDIA_STREAM_DIRECTION_SEND & ~priv->direction) != 0)
- {
- /* We are requested to start sending, but... */
- if ((pending_send_mask
- & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) != 0)
- {
- /* ... but we need to confirm this with the client.
- * Clear the sending bit and set the pending send flag. */
- direction &= ~(guint)TP_MEDIA_STREAM_DIRECTION_SEND;
- pending_send_flags |= TP_MEDIA_STREAM_PENDING_LOCAL_SEND;
- }
- if ((pending_send_mask
- & TP_MEDIA_STREAM_PENDING_REMOTE_SEND) != 0
- && (priv->pending_send_flags
- & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) == 0)
- {
- g_assert ((priv_get_requested_direction (priv) & TP_MEDIA_STREAM_DIRECTION_SEND) == 0);
-
- /* ... but the caller wants to agree with the remote
- * end first. Block the stream handler from sending for now. */
- priv->pending_remote_receive = TRUE;
- }
- }
-
- if ((direction & TP_MEDIA_STREAM_DIRECTION_RECEIVE) == 0)
- {
- /* We are not going to receive, clear the pending remote send flag */
- pending_send_flags &= ~TP_MEDIA_STREAM_PENDING_REMOTE_SEND;
- }
- else if ((direction & TP_MEDIA_STREAM_DIRECTION_RECEIVE & ~priv->direction) != 0
- && (pending_send_mask
- & TP_MEDIA_STREAM_PENDING_REMOTE_SEND) != 0)
- {
- /* We're requested to start receiving, but the remote end did not
- * confirm if it will send. Set the pending send flag. */
- pending_send_flags |= TP_MEDIA_STREAM_PENDING_REMOTE_SEND;
- }
-
- if (priv->direction == direction
- && priv->pending_send_flags == pending_send_flags)
- return;
-
- old_sdp_direction = priv_get_requested_direction (priv);
-
- priv->direction = direction;
- priv->pending_send_flags = pending_send_flags;
-
- STREAM_DEBUG (stream, "set direction %u, pending send flags %u", priv->direction, priv->pending_send_flags);
-
- g_signal_emit (stream, signals[SIG_DIRECTION_CHANGED], 0,
- priv->direction, priv->pending_send_flags);
-
- priv_update_sending (stream, priv->direction);
-
- if (priv->native_cands_prepared
- && priv->native_codecs_prepared
- && priv_get_requested_direction (priv)
- != old_sdp_direction)
- g_signal_emit (stream, signals[SIG_LOCAL_MEDIA_UPDATED], 0);
-}
-
-/*
- * Clears the pending send flag(s) present in @pending_send_mask.
- * If #TP_MEDIA_STREAM_PENDING_LOCAL_SEND is thus cleared,
- * enable the sending bit in the stream direction.
- * If @pending_send_mask has #TP_MEDIA_STREAM_PENDING_REMOTE_SEND flag set,
- * also start sending if agreed by the stream direction.
- */
-void
-rakia_media_stream_apply_pending_direction (RakiaMediaStream *stream,
- guint pending_send_mask)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
- guint flags;
-
-
- /* Don't apply pending send for new streams that haven't been negotiated */
- //if (priv->remote_media == NULL)
- // return;
-
- /* Remember the flags that got changes and then clear the set */
- flags = (priv->pending_send_flags & pending_send_mask);
- priv->pending_send_flags &= ~pending_send_mask;
-
- if (flags != 0)
- {
- if ((flags & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) != 0)
- priv->direction |= TP_MEDIA_STREAM_DIRECTION_SEND;
-
- STREAM_DEBUG (stream, "set direction %u, pending send flags %u", priv->direction, priv->pending_send_flags);
-
- g_signal_emit (stream, signals[SIG_DIRECTION_CHANGED], 0,
- priv->direction, priv->pending_send_flags);
- }
-
- if ((pending_send_mask & TP_MEDIA_STREAM_PENDING_REMOTE_SEND) != 0)
- {
- priv->pending_remote_receive = FALSE;
- STREAM_DEBUG (stream, "remote end ready to receive");
- }
-
- /* Always check to enable sending because the session could become accepted */
- priv_update_sending (stream, priv->direction);
-}
-
-TpMediaStreamDirection
-rakia_media_stream_get_requested_direction (RakiaMediaStream *self)
-{
- return priv_get_requested_direction (RAKIA_MEDIA_STREAM_GET_PRIVATE (self));
-}
-
-/**
- * Returns true if the stream has a valid SDP description and
- * connection has been established with the stream engine.
- */
-gboolean rakia_media_stream_is_local_ready (RakiaMediaStream *self)
-{
- RakiaMediaStreamPrivate *priv = self->priv;
- return (priv->ready_received && priv->native_cands_prepared
- && priv->native_codecs_prepared);
-}
-
-gboolean
-rakia_media_stream_is_codec_intersect_pending (RakiaMediaStream *self)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
- return priv->codec_intersect_pending;
-}
-
-void
-rakia_media_stream_start_telephony_event (RakiaMediaStream *self, guchar event)
-{
- tp_svc_media_stream_handler_emit_start_telephony_event (
- (TpSvcMediaStreamHandler *)self, event);
-}
-
-void
-rakia_media_stream_stop_telephony_event (RakiaMediaStream *self)
-{
- tp_svc_media_stream_handler_emit_stop_telephony_event (
- (TpSvcMediaStreamHandler *)self);
-}
-
-gboolean
-rakia_media_stream_request_hold_state (RakiaMediaStream *self, gboolean hold)
-{
- RakiaMediaStreamPrivate *priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (self);
-
- if ((!priv->requested_hold_state) != (!hold))
- {
- priv->requested_hold_state = hold;
- tp_svc_media_stream_handler_emit_set_stream_held (self, hold);
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-priv_emit_local_ready (RakiaMediaStream *self)
-{
- /* Trigger any session updates that are due in the current session state */
- g_signal_emit (self, signals[SIG_LOCAL_MEDIA_UPDATED], 0);
- g_signal_emit (self, signals[SIG_READY], 0);
-}
-
-/**
- * Notify StreamEngine of remote codecs.
- *
- * @pre Ready signal must be receiveid (priv->ready_received)
- */
-static void push_remote_codecs (RakiaMediaStream *stream)
-{
- RakiaMediaStreamPrivate *priv;
- GPtrArray *codecs;
- GType codecs_type;
- GType codec_type;
- GPtrArray *sipcodecs;
- guint i, j;
-
- DEBUG ("enter");
-
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
-
- sipcodecs = rakia_sip_media_get_remote_codecs (priv->media);
- if (sipcodecs == NULL)
- {
- STREAM_DEBUG (stream, "remote media description is not received yet");
- return;
- }
-
- if (!priv->ready_received)
- {
- STREAM_DEBUG (stream, "the stream engine is not ready, SetRemoteCodecs is pending");
- priv->push_remote_codecs_pending = TRUE;
- return;
- }
-
- codec_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC;
- codecs_type = TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CODEC_LIST;
-
- codecs = dbus_g_type_specialized_construct (codecs_type);
-
- for (i = 0; i < sipcodecs->len; i++)
- {
- GValue codec = { 0, };
- GHashTable *opt_params;
- RakiaSipCodec *sipcodec = g_ptr_array_index (sipcodecs, i);
-
- g_value_init (&codec, codec_type);
- g_value_take_boxed (&codec,
- dbus_g_type_specialized_construct (codec_type));
-
- opt_params = g_hash_table_new (g_str_hash, g_str_equal);
- if (sipcodec->params)
- {
- for (j = 0; j < sipcodec->params->len; j++)
- {
- RakiaSipCodecParam *param =
- g_ptr_array_index (sipcodec->params, j);
-
- g_hash_table_insert (opt_params, param->name, param->value);
- }
- }
-
- dbus_g_type_struct_set (&codec,
- /* payload type: */
- 0, sipcodec->id,
- /* encoding name: */
- 1, sipcodec->encoding_name,
- /* media type */
- 2, (guint)priv->media_type,
- /* clock-rate */
- 3, sipcodec->clock_rate,
- /* number of supported channels: */
- 4, sipcodec->channels,
- /* optional params: */
- 5, opt_params,
- G_MAXUINT);
-
- g_hash_table_unref (opt_params);
-
- g_ptr_array_add (codecs, g_value_get_boxed (&codec));
- }
-
-
- STREAM_DEBUG(stream, "emitting %d remote codecs to the handler",
- codecs->len);
-
- tp_svc_media_stream_handler_emit_set_remote_codecs (
- (TpSvcMediaStreamHandler *)stream, codecs);
-
- g_boxed_free (codecs_type, codecs);
-}
-
-static void push_remote_candidates (RakiaMediaStream *stream)
-{
- RakiaMediaStreamPrivate *priv;
- GValue candidate = { 0 };
- GValue transport = { 0 };
- GValue transport_rtcp = { 0 };
- GPtrArray *candidates;
- GPtrArray *transports;
- GType candidate_type;
- GType candidates_type;
- GType transport_type;
- GType transports_type;
- gchar *candidate_id;
- GPtrArray *remote_candidates;
- RakiaSipCandidate *rtp_cand = NULL;
- RakiaSipCandidate *rtcp_cand = NULL;
- guint i;
-
- DEBUG("enter");
-
- priv = RAKIA_MEDIA_STREAM_GET_PRIVATE (stream);
-
- remote_candidates = rakia_sip_media_get_remote_candidates (priv->media);
-
- if (remote_candidates == NULL)
- {
- STREAM_DEBUG (stream, "remote media description is not received yet");
- return;
- }
-
- if (!priv->ready_received)
- {
- STREAM_DEBUG (stream, "the stream engine is not ready, SetRemoteCandidateList is pending");
- priv->push_remote_cands_pending = TRUE;
- return;
- }
-
- for (i = 0; i < remote_candidates->len; i++)
- {
- RakiaSipCandidate *tmpc = g_ptr_array_index (remote_candidates, i);
-
- if (tmpc->component == 1)
- {
- rtp_cand = tmpc;
- }
- else if (tmpc->component == 2)
- {
- rtcp_cand = tmpc;
- }
- }
-
- if (rtp_cand == NULL)
- {
- STREAM_DEBUG (stream, "no rtp candidate");
- priv->push_remote_cands_pending = TRUE;
- return;
- }
-
- transports_type = TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT_LIST;
- transports = dbus_g_type_specialized_construct (transports_type);
-
- transport_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT;
- g_value_init (&transport, transport_type);
- g_value_take_boxed (&transport,
- dbus_g_type_specialized_construct (transport_type));
- dbus_g_type_struct_set (&transport,
- 0, 1, /* component number */
- 1, rtp_cand->ip,
- 2, rtp_cand->port,
- 3, TP_MEDIA_STREAM_BASE_PROTO_UDP,
- 4, "RTP",
- 5, "AVP",
- /* 6, 0.0f, */
- 7, TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL,
- /* 8, "", */
- /* 9, "", */
- G_MAXUINT);
-
- STREAM_DEBUG (stream, "remote RTP address=<%s>, port=<%u>", rtp_cand->ip,
- rtp_cand->port);
- g_ptr_array_add (transports, g_value_get_boxed (&transport));
-
- if (rtcp_cand)
- {
- g_value_init (&transport_rtcp, transport_type);
- g_value_take_boxed (&transport_rtcp,
- dbus_g_type_specialized_construct (transport_type));
- dbus_g_type_struct_set (&transport_rtcp,
- 0, 2, /* component number */
- 1, rtcp_cand->ip,
- 2, rtcp_cand->port,
- 3, TP_MEDIA_STREAM_BASE_PROTO_UDP,
- 4, "RTP",
- 5, "AVP",
- /* 6, 0.0f, */
- 7, TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL,
- /* 8, "", */
- /* 9, "", */
- G_MAXUINT);
-
- STREAM_DEBUG (stream, "remote RTCP address=<%s>, port=<%u>",
- rtcp_cand->ip, rtcp_cand->port);
- g_ptr_array_add (transports, g_value_get_boxed (&transport_rtcp));
- }
-
- g_free (priv->remote_candidate_id);
- candidate_id = g_strdup_printf ("L%u", ++priv->remote_candidate_counter);
- priv->remote_candidate_id = candidate_id;
-
- candidate_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE;
- g_value_init (&candidate, candidate_type);
- g_value_take_boxed (&candidate,
- dbus_g_type_specialized_construct (candidate_type));
- dbus_g_type_struct_set (&candidate,
- 0, candidate_id,
- 1, transports,
- G_MAXUINT);
-
- candidates_type = TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE_LIST;
- candidates = dbus_g_type_specialized_construct (candidates_type);
- g_ptr_array_add (candidates, g_value_get_boxed (&candidate));
-
- STREAM_DEBUG (stream, "emitting SetRemoteCandidateList with %s", candidate_id);
-
- tp_svc_media_stream_handler_emit_set_remote_candidate_list (
- (TpSvcMediaStreamHandler *)stream, candidates);
-
- g_boxed_free (candidates_type, candidates);
- g_boxed_free (transports_type, transports);
-}
-
-
-static void
-stream_handler_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcMediaStreamHandlerClass *klass = (TpSvcMediaStreamHandlerClass *)g_iface;
-
-#define IMPLEMENT(x) tp_svc_media_stream_handler_implement_##x (\
- klass, (tp_svc_media_stream_handler_##x##_impl) rakia_media_stream_##x)
- IMPLEMENT(error);
- IMPLEMENT(native_candidates_prepared);
- IMPLEMENT(new_active_candidate_pair);
- IMPLEMENT(new_native_candidate);
- IMPLEMENT(ready);
- IMPLEMENT(set_local_codecs);
- IMPLEMENT(codecs_updated);
- IMPLEMENT(stream_state);
- IMPLEMENT(supported_codecs);
- IMPLEMENT(hold_state);
- IMPLEMENT(unhold_failure);
-#undef IMPLEMENT
-}
-
-RakiaSipMedia *
-rakia_media_stream_get_media (RakiaMediaStream *stream)
-{
- RakiaMediaStreamPrivate *priv = stream->priv;
-
- return priv->media;
-}
diff --git a/rakia/media-stream.h b/rakia/media-stream.h
deleted file mode 100644
index 1785d39..0000000
--- a/rakia/media-stream.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * sip-media-stream.h - Header for RakiaMediaStream
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005-2010 Nokia Corporation
- *
- * This work is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This work is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this work; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __RAKIA_MEDIA_STREAM_H__
-#define __RAKIA_MEDIA_STREAM_H__
-
-#include <glib-object.h>
-#include <telepathy-glib/dbus-properties-mixin.h>
-#include <telepathy-glib/enums.h>
-#include <sofia-sip/sdp.h>
-
-#include "rakia/sip-media.h"
-
-G_BEGIN_DECLS
-
-typedef struct _RakiaMediaStream RakiaMediaStream;
-typedef struct _RakiaMediaStreamClass RakiaMediaStreamClass;
-typedef struct _RakiaMediaStreamPrivate RakiaMediaStreamPrivate;
-
-struct _RakiaMediaStreamClass {
- GObjectClass parent_class;
- TpDBusPropertiesMixinClass dbus_props_class;
-};
-
-struct _RakiaMediaStream {
- GObject parent;
- RakiaMediaStreamPrivate *priv;
-};
-
-GType rakia_media_stream_get_type(void);
-
-/* TYPE MACROS */
-#define RAKIA_TYPE_MEDIA_STREAM \
- (rakia_media_stream_get_type())
-#define RAKIA_MEDIA_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), RAKIA_TYPE_MEDIA_STREAM, RakiaMediaStream))
-#define RAKIA_MEDIA_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), RAKIA_TYPE_MEDIA_STREAM, RakiaMediaStreamClass))
-#define RAKIA_IS_MEDIA_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), RAKIA_TYPE_MEDIA_STREAM))
-#define RAKIA_IS_MEDIA_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), RAKIA_TYPE_MEDIA_STREAM))
-#define RAKIA_MEDIA_STREAM_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), RAKIA_TYPE_MEDIA_STREAM, RakiaMediaStreamClass))
-
-/***********************************************************************
- * Additional declarations (not based on generated templates)
- ***********************************************************************/
-
-void rakia_media_stream_close (RakiaMediaStream *self);
-guint rakia_media_stream_get_id (RakiaMediaStream *self);
-guint rakia_media_stream_get_media_type (RakiaMediaStream *self);
-
-void rakia_media_stream_set_playing (RakiaMediaStream *self, gboolean playing);
-void rakia_media_stream_set_sending (RakiaMediaStream *self, gboolean sending);
-void rakia_media_stream_set_direction (RakiaMediaStream *stream,
- TpMediaStreamDirection direction,
- guint pending_send_mask);
-void rakia_media_stream_apply_pending_direction (RakiaMediaStream *stream,
- guint pending_send_mask);
-TpMediaStreamDirection rakia_media_stream_get_requested_direction (RakiaMediaStream *self);
-gboolean rakia_media_stream_is_local_ready (RakiaMediaStream *self);
-gboolean rakia_media_stream_is_codec_intersect_pending (RakiaMediaStream *self);
-void rakia_media_stream_start_telephony_event (RakiaMediaStream *self, guchar event);
-void rakia_media_stream_stop_telephony_event (RakiaMediaStream *self);
-gboolean rakia_media_stream_request_hold_state (RakiaMediaStream *self,
- gboolean hold);
-
-guint rakia_tp_media_type (sdp_media_e sip_mtype);
-
-
-RakiaSipMedia *rakia_media_stream_get_media (RakiaMediaStream *stream);
-
-G_END_DECLS
-
-#endif /* #ifndef __RAKIA_MEDIA_STREAM_H__*/