[Telepathy-commits] [telepathy-sofiasip/text-fixes] Tightened up the code for call channel group membership changes

Mikhail Zabaluev mikhail.zabaluev at nokia.com
Thu Oct 16 04:54:51 PDT 2008


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.
---
 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)
 {
-- 
1.5.6.5




More information about the Telepathy-commits mailing list