diff options
author | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2008-10-16 14:54:51 +0300 |
---|---|---|
committer | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2008-10-16 14:54:51 +0300 |
commit | dd55960b6fd77aae66f8efc96a4d78b1ebb6b5b7 (patch) | |
tree | 7f989eb1cc02d862619a241b9a4af7f73b5e69d0 /src | |
parent | 2f1a2d12741b8ebcf92d2a3c80f6216c9006e30a (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.c | 228 |
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) { |