summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMikhail Zabaluev <mikhail.zabaluev@nokia.com>2008-10-16 14:54:51 +0300
committerMikhail Zabaluev <mikhail.zabaluev@nokia.com>2008-10-16 14:54:51 +0300
commitdd55960b6fd77aae66f8efc96a4d78b1ebb6b5b7 (patch)
tree7f989eb1cc02d862619a241b9a4af7f73b5e69d0 /src
parent2f1a2d12741b8ebcf92d2a3c80f6216c9006e30a (diff)
Tightened up the code for call channel group membership changes
The actual changes and emissions are now concentrated in the callback for protocol session state changes, plus the cases when a call termination reason and text is obtained from the protocol messages.
Diffstat (limited to 'src')
-rw-r--r--src/sip-media-channel.c228
1 files changed, 92 insertions, 136 deletions
diff --git a/src/sip-media-channel.c b/src/sip-media-channel.c
index f80b8e1..6ab861d 100644
--- a/src/sip-media-channel.c
+++ b/src/sip-media-channel.c
@@ -49,7 +49,6 @@ 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 priv_group_mixin_iface_init (gpointer, gpointer);
static void call_state_iface_init (gpointer, gpointer);
static void hold_iface_init (gpointer, gpointer);
@@ -62,7 +61,7 @@ G_DEFINE_TYPE_WITH_CODE (TpsipMediaChannel, tpsip_media_channel,
tp_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
- priv_group_mixin_iface_init);
+ 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,
@@ -858,44 +857,16 @@ tpsip_media_channel_receive_invite (TpsipMediaChannel *self,
{
TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self);
TpBaseConnection *conn = TP_BASE_CONNECTION (priv->conn);
- TpHandleRepoIface *contact_repo;
- TpIntSet *pending_set;
g_assert (priv->creator != conn->self_handle);
+ g_assert (priv->session == NULL);
- contact_repo = tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT);
-
- if (priv->session == NULL)
- {
- /* note: start the local stream-engine; once the local
- * media are ready, reply with nua_respond() */
- priv_create_session (self, nh, priv->creator);
- g_assert (priv->session != NULL);
- tpsip_media_session_receive_invite (priv->session);
- }
- else
- /* FIXME: This shall really be an assertion */
- g_warning ("session already exists");
-
- /* add self_handle to local pending */
-
- pending_set = tp_intset_new ();
- tp_intset_add (pending_set, conn->self_handle);
-
- tp_group_mixin_change_members ((GObject *) self, "INVITE received",
- NULL, /* add */
- NULL, /* remove */
- pending_set, /* local pending */
- NULL, /* remote pending */
- priv->creator, /* actor */
- TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
-
- tp_intset_destroy (pending_set);
+ /* Start the local stream-engine; once the local
+ * media are ready, reply with nua_respond() */
+ priv_create_session (self, nh, priv->creator);
- /* No adding more members to the incoming call, removing is OK */
- tp_group_mixin_change_flags ((GObject *) self,
- TP_CHANNEL_GROUP_FLAG_CAN_REMOVE,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD);
+ g_assert (priv->session != NULL);
+ tpsip_media_session_receive_invite (priv->session);
}
static gboolean
@@ -921,6 +892,7 @@ tpsip_media_channel_peer_error (TpsipMediaChannel *self,
guint status,
const char* message)
{
+ TpGroupMixin *mixin = TP_GROUP_MIXIN (self);
TpIntSet *set;
guint reason = TP_CHANNEL_GROUP_CHANGE_REASON_ERROR;
@@ -957,6 +929,7 @@ tpsip_media_channel_peer_error (TpsipMediaChannel *self,
set = tp_intset_new ();
tp_intset_add (set, peer);
+ tp_intset_add (set, mixin->self_handle);
tp_group_mixin_change_members ((GObject *)self, message,
NULL, set, NULL, NULL, peer, reason);
tp_intset_destroy (set);
@@ -1042,7 +1015,7 @@ priv_nua_i_cancel_cb (TpsipMediaChannel *self,
}
if (message == NULL || !g_utf8_validate (message, -1, NULL))
- message = "Cancelled";
+ message = "";
set = tp_intset_new ();
tp_intset_add (set, peer);
@@ -1157,11 +1130,13 @@ static void priv_session_state_changed_cb (TpsipMediaSession *session,
{
TpsipMediaChannelPrivate *priv = TPSIP_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 = tpsip_media_session_get_peer (session);
switch (state)
@@ -1169,57 +1144,95 @@ static void priv_session_state_changed_cb (TpsipMediaSession *session,
case TPSIP_MEDIA_SESSION_STATE_INVITE_SENT:
set = tp_intset_new ();
- g_assert (priv->creator == mixin->self_handle);
+ g_assert (priv->creator == self_handle);
/* add the peer to remote pending */
tp_intset_add (set, peer);
tp_group_mixin_change_members ((GObject *)channel,
- "INVITE sent",
+ "",
NULL, /* add */
NULL, /* remove */
NULL, /* local pending */
set, /* remote pending */
- mixin->self_handle, /* actor */
+ self_handle, /* actor */
TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
- /* update flags: allow adding, removal and rescinding */
+ /* update flags: allow removal and rescinding, no more adding */
tp_group_mixin_change_flags ((GObject *)channel,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD
- | TP_CHANNEL_GROUP_FLAG_CAN_REMOVE
- | TP_CHANNEL_GROUP_FLAG_CAN_RESCIND,
- 0);
+ TP_CHANNEL_GROUP_FLAG_CAN_REMOVE | TP_CHANNEL_GROUP_FLAG_CAN_RESCIND,
+ TP_CHANNEL_GROUP_FLAG_CAN_ADD);
+
+ break;
+
+ case TPSIP_MEDIA_SESSION_STATE_INVITE_RECEIVED:
+ set = tp_intset_new ();
+
+ /* add ourself to local pending */
+ tp_intset_add (set, self_handle);
+ tp_group_mixin_change_members ((GObject *) channel, "",
+ NULL, /* add */
+ NULL, /* remove */
+ set, /* local pending */
+ NULL, /* remote pending */
+ priv->creator, /* actor */
+ TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
+
+ /* No adding more members to the incoming call, removing is OK */
+ tp_group_mixin_change_flags ((GObject *) channel,
+ TP_CHANNEL_GROUP_FLAG_CAN_REMOVE,
+ TP_CHANNEL_GROUP_FLAG_CAN_ADD);
break;
+
case TPSIP_MEDIA_SESSION_STATE_ACTIVE:
- if (priv->creator == mixin->self_handle)
+ if (priv->creator == self_handle)
{
- /* add the peer to the member list */
+ if (!tp_handle_set_is_member (mixin->remote_pending, peer))
+ break; /* no-op */
+
set = tp_intset_new ();
+ /* the peer has promoted itself to members */
tp_intset_add (set, peer);
- tp_group_mixin_change_members ((GObject *)channel,
- "Call active",
+ tp_group_mixin_change_members ((GObject *)channel, "",
set, /* add */
NULL, /* remove */
NULL,
NULL,
- 0, 0);
+ peer, 0);
+ }
+ else
+ {
+ if (!tp_handle_set_is_member (mixin->local_pending, self_handle))
+ break; /* no-op */
- /* update flags: allow removal, deny adding and rescinding */
- tp_group_mixin_change_flags ((GObject *)channel,
- TP_CHANNEL_GROUP_FLAG_CAN_REMOVE,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD
- | TP_CHANNEL_GROUP_FLAG_CAN_RESCIND);
+ set = tp_intset_new ();
+
+ /* promote ourselves to members */
+ tp_intset_add (set, self_handle);
+ tp_group_mixin_change_members ((GObject *)channel, "",
+ set, /* add */
+ NULL, /* remove */
+ NULL,
+ NULL,
+ self_handle, 0);
}
+
+ /* update flags: allow removal, deny adding and rescinding */
+ tp_group_mixin_change_flags ((GObject *)channel,
+ TP_CHANNEL_GROUP_FLAG_CAN_REMOVE,
+ TP_CHANNEL_GROUP_FLAG_CAN_ADD
+ | TP_CHANNEL_GROUP_FLAG_CAN_RESCIND);
+
break;
+
case TPSIP_MEDIA_SESSION_STATE_ENDED:
set = tp_intset_new ();
/* remove us and the peer from the member list */
- tp_intset_add (set, mixin->self_handle);
+ tp_intset_add (set, self_handle);
tp_intset_add (set, peer);
- tp_group_mixin_change_members ((GObject *)channel,
- "Call ended",
+ tp_group_mixin_change_members ((GObject *)channel, "",
NULL, /* add */
set, /* remove */
NULL,
@@ -1394,26 +1407,11 @@ tpsip_media_channel_add_member (GObject *iface,
if (priv->creator == mixin->self_handle)
{
/* case a: outgoing call (we are the initiator, a new handle added) */
- TpIntSet *set;
-
priv_outbound_call (self, handle);
- /* make remote pending */
- set = tp_intset_new ();
- tp_intset_add (set, handle);
- tp_group_mixin_change_members (iface, "Sending INVITE",
- NULL, /* add */
- NULL, /* remove */
- NULL, /* local pending */
- set, /* remote pending */
- mixin->self_handle, 0);
- tp_intset_destroy (set);
-
- /* and update flags accordingly */
- tp_group_mixin_change_flags (iface,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD | TP_CHANNEL_GROUP_FLAG_CAN_REMOVE |
- TP_CHANNEL_GROUP_FLAG_CAN_RESCIND,
- 0);
+ /* disallow addition of any new members */
+ tp_group_mixin_change_flags ((GObject *) self,
+ 0, TP_CHANNEL_GROUP_FLAG_CAN_ADD);
return TRUE;
}
@@ -1422,22 +1420,9 @@ tpsip_media_channel_add_member (GObject *iface,
tp_handle_set_is_member (mixin->local_pending, handle))
{
/* case b: an incoming invite */
- TpIntSet *set;
-
DEBUG("accepting an incoming invite");
-
g_return_val_if_fail (priv->session != NULL, FALSE);
- set = tp_intset_new ();
- tp_intset_add (set, handle);
- tp_group_mixin_change_members (iface, "Incoming call accepted",
- set, /* add */
- NULL, /* remove */
- NULL, /* local pending */
- NULL, /* remote pending */
- 0, 0);
- tp_intset_destroy (set);
-
tpsip_media_session_accept (priv->session);
return TRUE;
@@ -1493,46 +1478,33 @@ tpsip_media_channel_remove_with_reason (GObject *obj,
return FALSE;
}
- /* We handle only one case: removal of the self handle from local pending
- * due to the user rejecting the call */
- /* FIXME: handle also rescinding and removal of self from members */
- if (priv->session &&
- handle == mixin->self_handle &&
- tp_handle_set_is_member (mixin->local_pending, handle))
+ if (priv->session == NULL)
{
- TpIntSet *set;
+ g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
+ "handle %u cannot be removed in the current state", handle);
+
+ return FALSE;
+ }
+
+ if (handle == mixin->self_handle
+ && tp_handle_set_is_member (mixin->local_pending, handle))
+ {
+ /* The user has rejected the call */
gint status;
status = tpsip_status_from_tp_reason (reason);
/* XXX: raise NotAvailable if it's the wrong state? */
tpsip_media_session_respond (priv->session, status, message);
-
- set = tp_intset_new ();
- tp_intset_add (set, handle);
- tp_group_mixin_change_members (obj,
- message,
- NULL, /* add */
- set, /* remove */
- NULL, /* add local pending */
- NULL, /* add remote pending */
- 0, /* actor */
- reason);
- tp_intset_destroy (set);
-
- /* no more adding to this channel */
- tp_group_mixin_change_flags (obj,
- 0,
- TP_CHANNEL_GROUP_FLAG_CAN_ADD);
-
- return TRUE;
+ }
+ else
+ {
+ /* Want to terminate the call in whatever other situation;
+ * rescinding is handled by sending CANCEL */
+ tpsip_media_session_terminate (priv->session);
}
- g_assert_not_reached();
-
- g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
- "Can't map this member change to protocol behavior");
- return FALSE;
+ return TRUE;
}
static void
@@ -1719,22 +1691,6 @@ dtmf_iface_init (gpointer g_iface, gpointer iface_data)
}
static void
-priv_group_mixin_iface_init (gpointer g_iface, gpointer iface_data)
-{
-#if 0
- TpSvcChannelInterfaceGroupClass *klass =
- (TpSvcChannelInterfaceGroupClass *)g_iface;
-#endif
-
- tp_group_mixin_iface_init (g_iface, iface_data);
-
-#if 0
- tp_svc_channel_interface_group_implement_add_members (klass,
- priv_add_members);
-#endif
-}
-
-static void
call_state_iface_init (gpointer g_iface,
gpointer iface_data)
{