diff options
author | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2008-02-26 16:37:57 +0000 |
---|---|---|
committer | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2008-02-26 16:37:57 +0000 |
commit | 468756fed5bc4cba93bb86ab862546c0337199aa (patch) | |
tree | c4401f576b9b2152e9a5ec92be1c5f53e9fb952e | |
parent | aeef618369660dadc6d21e581325566944171693 (diff) |
SIPMediaChannel: implement the new behavior of RequestStreams and MembersChanged, as per Telepathy spec 0.17.1.1
-rw-r--r-- | src/sip-media-channel.c | 170 |
1 files changed, 88 insertions, 82 deletions
diff --git a/src/sip-media-channel.c b/src/sip-media-channel.c index 2becd1c..7404ca3 100644 --- a/src/sip-media-channel.c +++ b/src/sip-media-channel.c @@ -191,6 +191,10 @@ static void priv_create_session (SIPMediaChannel *channel, nua_handle_t *nh, TpHandle peer); static void priv_destroy_session(SIPMediaChannel *channel); + +static void priv_outbound_call (SIPMediaChannel *channel, + TpHandle peer); + static gboolean sip_media_channel_add_member (GObject *iface, TpHandle handle, const gchar *message, @@ -762,18 +766,7 @@ sip_media_channel_request_streams (TpSvcChannelTypeStreamedMedia *iface, return; } - if (!tp_handle_set_is_member (self->group.members, contact_handle) && - !tp_handle_set_is_member (self->group.remote_pending, contact_handle)) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "given handle " - "%u is not a member of the channel", contact_handle); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - /* if the person is a channel member, we should have a session */ - g_assert (priv->session != NULL); + priv_outbound_call (self, contact_handle); ret = g_ptr_array_sized_new (types->len); @@ -1055,46 +1048,82 @@ static void priv_session_state_changed_cb (SIPMediaSession *session, { TpGroupMixin *mixin = TP_GROUP_MIXIN (channel); TpHandle peer; - TpIntSet *set; + TpIntSet *set = NULL; + TpIntSet *rset; DEBUG("enter"); peer = sip_media_session_get_peer (session); - if (state == SIP_MEDIA_SESSION_STATE_ACTIVE) { - - /* add the peer to the member list */ - set = tp_intset_new (); - tp_intset_add (set, peer); - tp_group_mixin_change_members ((GObject *)channel, - "Call active", - set, /* add */ - NULL, /* remove */ - NULL, /* local pending */ - NULL, /* remote pending */ - 0, 0); - tp_intset_destroy (set); + switch (state) + { + case SIP_MEDIA_SESSION_STATE_INVITE_SENT: + set = tp_intset_new (); + rset = tp_intset_new (); - /* update flags accordingly -- 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); - } - if (state == SIP_MEDIA_SESSION_STATE_ENDED) { - set = tp_intset_new (); + /* add the peer to remote pending, make sure the self handle is + * in the member list */ + tp_intset_add (set, mixin->self_handle); + tp_intset_add (rset, peer); + tp_group_mixin_change_members ((GObject *)channel, + "INVITE sent", + set, /* add */ + NULL, /* remove */ + NULL, /* local pending */ + rset, /* remote pending */ + 0, 0); + tp_intset_destroy (rset); - /* remove us and the peer from the member list */ - tp_intset_add (set, mixin->self_handle); - tp_intset_add (set, peer); - tp_group_mixin_change_members ((GObject *)channel, - "Call ended", NULL, set, NULL, NULL, 0, 0); + /* update flags: allow adding, removal and rescinding */ + 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_intset_destroy (set); + break; + case SIP_MEDIA_SESSION_STATE_ACTIVE: + set = tp_intset_new (); - priv_destroy_session (channel); - sip_media_channel_close (channel); - } + /* add the peer to the member list */ + tp_intset_add (set, peer); + tp_group_mixin_change_members ((GObject *)channel, + "Call active", + set, /* add */ + NULL, /* remove */ + NULL, + NULL, + 0, 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 SIP_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, peer); + tp_group_mixin_change_members ((GObject *)channel, + "Call ended", + NULL, /* add */ + set, /* remove */ + NULL, + NULL, + 0, 0); + + /* Close the channel; destroy the session first to avoid + * the sip_media_session_terminate() path in this case */ + priv_destroy_session (channel); + sip_media_channel_close (channel); + break; + } + + if (set != NULL) + tp_intset_destroy (set); } /** @@ -1185,47 +1214,29 @@ priv_destroy_session(SIPMediaChannel *channel) DEBUG("exit"); } -#if 0 -/* Check that self_handle is not already in the members. If it is, - * we're trying to call ourselves. */ +/* + * Creates an outbound call session if a session does not exist + */ static void -priv_add_members (TpSvcChannelInterfaceGroup *obj, - const GArray *contacts, - const gchar *message, - DBusGMethodInvocation *context) +priv_outbound_call (SIPMediaChannel *channel, + TpHandle peer) { - TpGroupMixin *mixin = TP_GROUP_MIXIN (obj); - guint i; - TpHandle handle; - GError *error = NULL; + SIPMediaChannelPrivate *priv = SIP_MEDIA_CHANNEL_GET_PRIVATE (channel); + nua_handle_t *nh; - for (i = 0; i < contacts->len; i++) + if (priv->session == NULL) { - handle = g_array_index (contacts, TpHandle, i); - - if (handle == mixin->self_handle && - tp_handle_set_is_member (mixin->members, handle)) - { - DEBUG ("attempted to add self_handle into the mixin again"); - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_HANDLE, - "you cannot call yourself"); - } - } - - if (error == NULL) - tp_group_mixin_add_members ((GObject *) obj, contacts, message, &error); + DEBUG("making outbound call - setting peer handle to %u", peer); - if (error == NULL) - { - tp_svc_channel_interface_group_return_from_add_members (context); + nh = sip_conn_create_request_handle (priv->conn, peer); + priv_create_session (channel, nh, peer); + nua_handle_unref (nh); } else - { - dbus_g_method_return_error (context, error); - g_error_free (error); - } + DEBUG("session already exists"); + + g_assert (priv->session != NULL); } -#endif static gboolean sip_media_channel_add_member (GObject *iface, @@ -1243,13 +1254,8 @@ sip_media_channel_add_member (GObject *iface, if (mixin->self_handle != handle) { TpIntSet *lset, *rset; - nua_handle_t *nh; - DEBUG("making outbound call - setting peer handle to %u", handle); - - nh = sip_conn_create_request_handle (priv->conn, handle); - priv_create_session (self, nh, handle); - nua_handle_unref (nh); + priv_outbound_call (self, handle); /* make remote pending */ rset = tp_intset_new (); |