summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Zabaluev <mikhail.zabaluev@nokia.com>2008-04-04 15:20:21 +0000
committerMikhail Zabaluev <mikhail.zabaluev@nokia.com>2008-04-04 15:20:21 +0000
commitb10fe314452cb3cb6e076fef269e77f6ddeea730 (patch)
tree77e8924be48830d1b86e882b84f55845308dab1d
parent8949826f048c6e75427940e2fbe4353613de5dd2 (diff)
Updated the media channel implementation to the reworked Hold and CallState APIs as of 0.17.3.1.
The CallState interface helpers are provided by telepathy-glib as of 0.7.6. This patch does not implement the specified behavior for local hold. 20080404152021-5b6ca-666f266095e8b6765e1f8917b26a8cf42292aa3c.gz
-rw-r--r--configure.ac2
-rw-r--r--src/sip-media-channel.c82
-rw-r--r--src/sip-media-channel.h6
-rw-r--r--src/sip-media-session.c61
-rw-r--r--src/sip-media-session.h4
-rw-r--r--tpsip-extensions/Channel_Interface_Call_State.xml99
-rw-r--r--tpsip-extensions/Makefile.am1
-rw-r--r--tpsip-extensions/channel.xml1
8 files changed, 90 insertions, 166 deletions
diff --git a/configure.ac b/configure.ac
index dd7a5a1..39e19a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,7 +97,7 @@ AC_SUBST(SOFIA_SIP_UA_CFLAGS)
AC_SUBST(SOFIA_SIP_UA_VERSION)
dnl Check for telepathy-glib
-PKG_CHECK_MODULES(TELEPATHY_GLIB, [telepathy-glib >= 0.7.3])
+PKG_CHECK_MODULES(TELEPATHY_GLIB, [telepathy-glib >= 0.7.6])
AC_SUBST(TELEPATHY_GLIB_CFLAGS)
AC_SUBST(TELEPATHY_GLIB_LIBS)
diff --git a/src/sip-media-channel.c b/src/sip-media-channel.c
index 05b11ff..03030b3 100644
--- a/src/sip-media-channel.c
+++ b/src/sip-media-channel.c
@@ -36,7 +36,7 @@
#include <tpsip/event-target.h>
-/* Hold and CallState interfaces */
+/* Hold interface */
#include <tpsip-extensions/extensions.h>
#include "sip-media-channel.h"
@@ -68,7 +68,7 @@ G_DEFINE_TYPE_WITH_CODE (TpsipMediaChannel, tpsip_media_channel,
media_signalling_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DTMF,
dtmf_iface_init);
- G_IMPLEMENT_INTERFACE (TPSIP_TYPE_SVC_CHANNEL_INTERFACE_CALL_STATE,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CALL_STATE,
call_state_iface_init);
G_IMPLEMENT_INTERFACE (TPSIP_TYPE_SVC_CHANNEL_INTERFACE_HOLD,
hold_iface_init);
@@ -535,7 +535,7 @@ tpsip_media_channel_get_interfaces (TpSvcChannel *iface,
TP_IFACE_CHANNEL_INTERFACE_GROUP,
TP_IFACE_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
TP_IFACE_CHANNEL_INTERFACE_DTMF,
- TPSIP_IFACE_CHANNEL_INTERFACE_CALL_STATE,
+ TP_IFACE_CHANNEL_INTERFACE_CALL_STATE,
TPSIP_IFACE_CHANNEL_INTERFACE_HOLD,
TP_IFACE_PROPERTIES_INTERFACE,
NULL
@@ -908,34 +908,37 @@ tpsip_media_channel_peer_error (TpsipMediaChannel *self,
tp_intset_destroy (set);
}
-static void
-priv_set_call_state (TpsipMediaChannel *self,
- TpHandle peer,
- guint flags)
+guint
+tpsip_media_channel_change_call_state (TpsipMediaChannel *self,
+ TpHandle peer,
+ guint flags_add,
+ guint flags_remove)
{
TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self);
+ gpointer key = GUINT_TO_POINTER (peer);
+ guint old_state;
+ guint new_state;
- DEBUG ("setting call state %u for peer %u", flags, peer);
- g_hash_table_replace (priv->call_states,
- GUINT_TO_POINTER (peer),
- GUINT_TO_POINTER (flags));
- tpsip_svc_channel_interface_call_state_emit_call_state_changed (self,
- peer,
- flags);
-}
+ /* XXX: check if the peer is a member? */
-static void
-priv_clear_call_state (TpsipMediaChannel *self,
- TpHandle peer)
-{
- TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self);
+ old_state = GPOINTER_TO_UINT (g_hash_table_lookup (priv->call_states, key));
+ new_state = (old_state | flags_add) & ~flags_remove;
- DEBUG ("clearing call state for peer %u", peer);
- if (g_hash_table_remove (priv->call_states,
- GUINT_TO_POINTER (peer)))
- tpsip_svc_channel_interface_call_state_emit_call_state_changed (self,
- peer,
- 0);
+ 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 gboolean
@@ -962,19 +965,23 @@ priv_nua_r_invite_cb (TpsipMediaChannel *self,
if (status >= 200)
{
- /* The final response, clear the Ringing call state flag if set */
- priv_clear_call_state (self, peer);
+ /* The final response, clear the Ringing and Queued call state flags */
+ tpsip_media_channel_change_call_state (self, peer, 0,
+ TP_CHANNEL_CALL_STATE_RINGING |
+ TP_CHANNEL_CALL_STATE_QUEUED);
if (status >= 300)
tpsip_media_channel_peer_error (self, peer, status, message);
}
else if (status == 180)
{
- priv_set_call_state (self, peer, TPSIP_CHANNEL_CALL_STATE_RINGING);
+ tpsip_media_channel_change_call_state (self, peer,
+ TP_CHANNEL_CALL_STATE_RINGING, 0);
}
else if (status == 182)
{
- priv_set_call_state (self, peer, TPSIP_CHANNEL_CALL_STATE_QUEUED);
+ tpsip_media_channel_change_call_state (self, peer,
+ TP_CHANNEL_CALL_STATE_QUEUED, 0);
}
return TRUE;
@@ -1502,20 +1509,20 @@ tpsip_media_channel_remove_with_reason (GObject *obj,
}
static void
-tpsip_media_channel_get_call_states (TpsipSvcChannelInterfaceCallState *iface,
- DBusGMethodInvocation *context)
+tpsip_media_channel_get_call_states (TpSvcChannelInterfaceCallState *iface,
+ DBusGMethodInvocation *context)
{
TpsipMediaChannel *self = TPSIP_MEDIA_CHANNEL (iface);
TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self);
- tpsip_svc_channel_interface_call_state_return_from_get_call_states (
+ tp_svc_channel_interface_call_state_return_from_get_call_states (
context,
priv->call_states);
}
static void
tpsip_media_channel_get_hold_state (TpsipSvcChannelInterfaceHold *iface,
- DBusGMethodInvocation *context)
+ DBusGMethodInvocation *context)
{
TpsipMediaChannel *self = TPSIP_MEDIA_CHANNEL (iface);
TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self);
@@ -1523,7 +1530,8 @@ tpsip_media_channel_get_hold_state (TpsipSvcChannelInterfaceHold *iface,
tpsip_svc_channel_interface_hold_return_from_get_hold_state (context,
(priv->session != NULL)
? tpsip_media_session_get_hold_state (priv->session)
- : TPSIP_CHANNEL_HOLD_STATE_NONE);
+ : TPSIP_LOCAL_HOLD_STATE_UNHELD,
+ TPSIP_LOCAL_HOLD_STATE_REASON_NONE);
}
static void
@@ -1692,8 +1700,8 @@ static void
call_state_iface_init (gpointer g_iface,
gpointer iface_data)
{
- TpsipSvcChannelInterfaceCallStateClass *klass = g_iface;
-#define IMPLEMENT(x) tpsip_svc_channel_interface_call_state_implement_##x (\
+ TpSvcChannelInterfaceCallStateClass *klass = g_iface;
+#define IMPLEMENT(x) tp_svc_channel_interface_call_state_implement_##x (\
klass, tpsip_media_channel_##x)
IMPLEMENT (get_call_states);
#undef IMPLEMENT
diff --git a/src/sip-media-channel.h b/src/sip-media-channel.h
index 8aae83a..42fba02 100644
--- a/src/sip-media-channel.h
+++ b/src/sip-media-channel.h
@@ -75,6 +75,12 @@ void tpsip_media_channel_receive_invite (TpsipMediaChannel *self,
nua_handle_t *nh,
TpHandle handle);
+guint
+tpsip_media_channel_change_call_state (TpsipMediaChannel *self,
+ TpHandle peer,
+ guint flags_add,
+ guint flags_remove);
+
G_END_DECLS
#endif /* #ifndef __TPSIP_MEDIA_CHANNEL_H__*/
diff --git a/src/sip-media-session.c b/src/sip-media-session.c
index 1a2d8b9..285c2ca 100644
--- a/src/sip-media-session.c
+++ b/src/sip-media-session.c
@@ -117,8 +117,8 @@ struct _TpsipMediaSessionPrivate
nua_handle_t *nua_op; /** see gobj. prop. 'nua-handle' */
TpHandle peer; /** see gobj. prop. 'peer' */
gchar *local_ip_address; /** see gobj. prop. 'local-ip-address' */
- TpsipMediaSessionState state; /** session state */
- TpsipChannelHoldState hold_state; /** hold state aggregated from stream directions */
+ TpsipMediaSessionState state; /** session state */
+ TpsipLocalHoldState hold_state; /** local hold state aggregated from stream directions */
nua_saved_event_t saved_event[1]; /** Saved incoming request event */
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 */
@@ -170,7 +170,7 @@ static void tpsip_media_session_init (TpsipMediaSession *obj)
priv->state = TPSIP_MEDIA_SESSION_STATE_CREATED;
- priv->hold_state = TPSIP_CHANNEL_HOLD_STATE_NONE;
+ priv->hold_state = TPSIP_LOCAL_HOLD_STATE_UNHELD;
/* allocate any data required by the object here */
priv->streams = g_ptr_array_new ();
@@ -1104,13 +1104,21 @@ tpsip_media_session_get_stream (TpsipMediaSession *self,
return stream;
}
-TpsipChannelHoldState
+TpsipLocalHoldState
tpsip_media_session_get_hold_state (TpsipMediaSession *self)
{
TpsipMediaSessionPrivate *priv = TPSIP_MEDIA_SESSION_GET_PRIVATE (self);
return priv->hold_state;
}
+static gboolean
+tpsip_media_session_is_local_hold_ongoing (TpsipMediaSession *self)
+{
+ TpsipMediaSessionPrivate *priv = TPSIP_MEDIA_SESSION_GET_PRIVATE (self);
+ return (priv->hold_state == TPSIP_LOCAL_HOLD_STATE_HELD
+ || priv->hold_state == TPSIP_LOCAL_HOLD_STATE_PENDING_HOLD);
+}
+
void
tpsip_media_session_request_hold (TpsipMediaSession *self,
gboolean hold)
@@ -1278,16 +1286,15 @@ priv_local_media_changed (TpsipMediaSession *session)
}
static void
-priv_update_hold_state (TpsipMediaSession *session)
+priv_update_remote_hold (TpsipMediaSession *session)
{
TpsipMediaSessionPrivate *priv = TPSIP_MEDIA_SESSION_GET_PRIVATE (session);
TpsipMediaStream *stream;
gboolean has_streams = FALSE;
- guint hold_state = TPSIP_CHANNEL_HOLD_STATE_BOTH;
+ gboolean remote_held = TRUE;
guint i;
- /* Starting with bidirectional hold, bid down accordingly to availability
- * of streams unheld localy or remotely */
+ /* The call is remotely unheld if there's at least one sending stream */
for (i = 0; i < priv->streams->len; i++)
{
stream = g_ptr_array_index(priv->streams, i);
@@ -1299,21 +1306,25 @@ priv_update_hold_state (TpsipMediaSession *session)
NULL);
if ((direction & TP_MEDIA_STREAM_DIRECTION_SEND) != 0)
- hold_state &= ~TPSIP_CHANNEL_HOLD_STATE_REMOTE;
- if ((direction & TP_MEDIA_STREAM_DIRECTION_RECEIVE) != 0)
- hold_state &= ~TPSIP_CHANNEL_HOLD_STATE_LOCAL;
+ remote_held = FALSE;
has_streams = TRUE;
}
}
- if (has_streams && priv->hold_state != hold_state)
- {
- DEBUG("changing hold state to %u", hold_state);
- priv->hold_state = hold_state;
- tpsip_svc_channel_interface_hold_emit_hold_state_changed (priv->channel,
- priv->hold_state);
- }
+ if (!has_streams)
+ return;
+
+ if (remote_held)
+ tpsip_media_channel_change_call_state (priv->channel,
+ priv->peer,
+ TP_CHANNEL_CALL_STATE_HELD,
+ 0);
+ else
+ tpsip_media_channel_change_call_state (priv->channel,
+ priv->peer,
+ 0,
+ TP_CHANNEL_CALL_STATE_HELD);
}
static gboolean
@@ -1334,9 +1345,9 @@ priv_update_remote_media (TpsipMediaSession *session, gboolean authoritative)
*/
if (authoritative)
direction_up_mask
- = ((priv->hold_state & TPSIP_CHANNEL_HOLD_STATE_LOCAL) == 0)
- ? TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL
- : TP_MEDIA_STREAM_DIRECTION_SEND;
+ = tpsip_media_session_is_local_hold_ongoing (session)
+ ? TP_MEDIA_STREAM_DIRECTION_SEND
+ : TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL;
else
direction_up_mask = 0;
@@ -1422,7 +1433,7 @@ priv_update_remote_media (TpsipMediaSession *session, gboolean authoritative)
}
if (has_supported_media)
- priv_update_hold_state (session);
+ priv_update_remote_hold (session);
DEBUG("exit");
@@ -1793,9 +1804,9 @@ priv_create_media_stream (TpsipMediaSession *self,
priv->object_path,
stream_id);
- direction = ((priv->hold_state & TPSIP_CHANNEL_HOLD_STATE_LOCAL) == 0)
- ? TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL
- : TP_MEDIA_STREAM_DIRECTION_SEND;
+ direction = tpsip_media_session_is_local_hold_ongoing (self)
+ ? TP_MEDIA_STREAM_DIRECTION_SEND
+ : TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL;
stream = g_object_new (TPSIP_TYPE_MEDIA_STREAM,
"media-session", self,
diff --git a/src/sip-media-session.h b/src/sip-media-session.h
index 082a594..c8fe31e 100644
--- a/src/sip-media-session.h
+++ b/src/sip-media-session.h
@@ -99,9 +99,9 @@ void tpsip_media_session_reject (TpsipMediaSession *self,
gint status,
const char *message);
-TpsipChannelHoldState tpsip_media_session_get_hold_state (TpsipMediaSession *session);
+TpsipLocalHoldState tpsip_media_session_get_hold_state (TpsipMediaSession *session);
void tpsip_media_session_request_hold (TpsipMediaSession *session,
- gboolean hold);
+ gboolean hold);
gboolean tpsip_media_session_start_telephony_event (TpsipMediaSession *self,
guint stream_id,
diff --git a/tpsip-extensions/Channel_Interface_Call_State.xml b/tpsip-extensions/Channel_Interface_Call_State.xml
deleted file mode 100644
index b0faa42..0000000
--- a/tpsip-extensions/Channel_Interface_Call_State.xml
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0" ?>
-<node name="/Channel_Interface_Call_State" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
- <tp:copyright> Copyright (C) 2008 Collabora Limited </tp:copyright>
- <tp:copyright> Copyright (C) 2008 Nokia Corporation </tp:copyright>
- <tp:license xmlns="http://www.w3.org/1999/xhtml">
- <p>This library 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.</p>
-
-<p>This library 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.</p>
-
-<p>You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
- </tp:license>
- <interface name="org.freedesktop.Telepathy.Channel.Interface.CallState">
- <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.StreamedMedia"/>
-
- <tp:docstring>
- An interface for streamed media channels that can indicate call
- progress or call states. The presence of this interface is no guarantee
- that call states will actually be signalled (for instance, SIP
- implementations are not guaranteed to generate status 180 Ringing,
- so a call can be accepted without the Ringing flag ever having been set).
- </tp:docstring>
-
- <method name="GetCallStates">
- <tp:docstring>
- Get the current call states for all contacts involved in this call.
- </tp:docstring>
-
- <arg tp:type="Channel_Call_State_Map" name="States" direction="out"
- type="a{uu}">
- <tp:docstring>
- The current call states. Participants where the call state flags
- would be 0 (all unset) may be omitted from this mapping.
- </tp:docstring>
- </arg>
- </method>
-
- <signal name="CallStateChanged">
- <tp:docstring>
- Emitted when the state of a member of the channel has changed.
- </tp:docstring>
-
- <arg name="contact" type="u" tp:type="Contact_Handle">
- <tp:docstring>
- An integer handle for the contact.
- </tp:docstring>
- </arg>
-
- <arg name="state" type="u" tp:type="Channel_Call_State_Flags">
- <tp:docstring>
- The new state for this contact.
- </tp:docstring>
- </arg>
- </signal>
-
- <tp:mapping name="Channel_Call_State_Map">
- <tp:docstring>
- A map from contacts to call states.
- </tp:docstring>
-
- <tp:member name="Contact" type="u" tp:type="Contact_Handle">
- <tp:docstring>A contact involved in this call.</tp:docstring>
- </tp:member>
-
- <tp:member name="State" type="u" tp:type="Channel_Call_State_Flags">
- <tp:docstring>State flags for the given contact.</tp:docstring>
- </tp:member>
- </tp:mapping>
-
- <tp:flags name="Channel_Call_State_Flags" value-prefix="Channel_Call_State" type="u">
- <tp:docstring>
- A set of flags representing call states.
- </tp:docstring>
-
- <tp:flag suffix="Ringing" value="1">
- <tp:docstring>
- The contact has been alerted about the call but has not responded
- (e.g. 180 Ringing in SIP).
- </tp:docstring>
- </tp:flag>
-
- <tp:flag suffix="Queued" value="2">
- <tp:docstring>
- The contact is temporarily unavailable, and the call has been placed
- in a queue (e.g. 182 Queued in SIP, or call-waiting in telephony).
- </tp:docstring>
- </tp:flag>
- </tp:flags>
-
- </interface>
-</node>
-<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/tpsip-extensions/Makefile.am b/tpsip-extensions/Makefile.am
index 0e8190d..356f381 100644
--- a/tpsip-extensions/Makefile.am
+++ b/tpsip-extensions/Makefile.am
@@ -9,7 +9,6 @@ AM_CFLAGS = \
EXTRA_DIST = \
all.xml \
channel.xml \
- Channel_Interface_Call_State.xml \
Channel_Interface_Hold.xml
noinst_LTLIBRARIES = libtpsip-extensions.la
diff --git a/tpsip-extensions/channel.xml b/tpsip-extensions/channel.xml
index 84abb22..d8ecf19 100644
--- a/tpsip-extensions/channel.xml
+++ b/tpsip-extensions/channel.xml
@@ -4,7 +4,6 @@
<tp:title>Channel extensions for telepathy-sofiasip</tp:title>
-<xi:include href="Channel_Interface_Call_State.xml"/>
<xi:include href="Channel_Interface_Hold.xml"/>
</tp:spec>