From 4d2d6969223b71f58e8968b089aae016fca2e609 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 23 May 2012 12:31:39 +0100 Subject: tube-dbus: explicitly set the requested property Signed-off-by: Jonny Lamb --- src/tube-dbus.c | 4 +++- src/tube-dbus.h | 3 ++- src/tubes-channel.c | 17 +++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/tube-dbus.c b/src/tube-dbus.c index cfa504bf..e92dde9b 100644 --- a/src/tube-dbus.c +++ b/src/tube-dbus.c @@ -1455,7 +1455,8 @@ salut_tube_dbus_new (SalutConnection *conn, TpHandle initiator, const gchar *service, GHashTable *parameters, - guint id) + guint id, + gboolean requested) { SalutTubeDBus *tube; gchar *object_path; @@ -1475,6 +1476,7 @@ salut_tube_dbus_new (SalutConnection *conn, "service", service, "parameters", parameters, "id", id, + "requested", requested, NULL); return tube; diff --git a/src/tube-dbus.h b/src/tube-dbus.h index e8a64eb1..b90285ac 100644 --- a/src/tube-dbus.h +++ b/src/tube-dbus.h @@ -69,7 +69,8 @@ SalutTubeDBus * salut_tube_dbus_new (SalutConnection *conn, SalutTubesChannel *tubes_channel, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, GibberMucConnection *muc_connection, TpHandle initiator, - const gchar *service, GHashTable *parameters, guint id); + const gchar *service, GHashTable *parameters, guint id, + gboolean requested); gboolean salut_tube_dbus_add_name (SalutTubeDBus *self, TpHandle handle, const gchar *name); diff --git a/src/tubes-channel.c b/src/tubes-channel.c index c847208a..834c6ad3 100644 --- a/src/tubes-channel.c +++ b/src/tubes-channel.c @@ -166,7 +166,7 @@ static gboolean extract_tube_information (SalutTubesChannel *self, static SalutTubeIface * create_new_tube (SalutTubesChannel *self, TpTubeType type, TpHandle initiator, gboolean offered, const gchar *service, GHashTable *parameters, guint tube_id, guint portnum, - WockyStanza *iq_req); + WockyStanza *iq_req, gboolean requested); static void salut_tubes_channel_init (SalutTubesChannel *self) @@ -698,7 +698,7 @@ salut_tubes_channel_muc_message_received (SalutTubesChannel *self, } tube = create_new_tube (self, type, initiator_handle, FALSE, - service, parameters, id, 0, NULL); + service, parameters, id, 0, NULL, FALSE); g_ptr_array_add (result, tube); /* the tube has reffed its initiator, no need to keep a ref */ @@ -794,7 +794,7 @@ salut_tubes_channel_message_received (SalutTubesChannel *self, if (tube == NULL) { tube = create_new_tube (self, tube_type, initiator_handle, FALSE, - service, parameters, tube_id, portnum, iq_req); + service, parameters, tube_id, portnum, iq_req, FALSE); return tube; } @@ -876,7 +876,7 @@ salut_tubes_channel_tube_request (SalutTubesChannel *self, (GDestroyNotify) tp_g_value_slice_free); tube = create_new_tube (self, type, priv->self_handle, FALSE, service, - parameters, tube_id, 0, NULL); + parameters, tube_id, 0, NULL, TRUE); g_hash_table_unref (parameters); return tube; @@ -1131,7 +1131,8 @@ create_new_tube (SalutTubesChannel *self, GHashTable *parameters, guint tube_id, guint portnum, - WockyStanza *iq_req) + WockyStanza *iq_req, + gboolean requested) { SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); SalutTubeIface *tube; @@ -1146,7 +1147,7 @@ create_new_tube (SalutTubesChannel *self, case TP_TUBE_TYPE_DBUS: tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, self, priv->handle, priv->handle_type, priv->self_handle, muc_connection, - initiator, service, parameters, tube_id)); + initiator, service, parameters, tube_id, requested)); break; case TP_TUBE_TYPE_STREAM: tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, self, @@ -1480,7 +1481,7 @@ salut_tubes_channel_offer_d_bus_tube (TpSvcChannelTypeTubes *iface, tube_id = generate_tube_id (); tube = create_new_tube (self, TP_TUBE_TYPE_DBUS, priv->self_handle, - TRUE, service, parameters, tube_id, 0, NULL); + TRUE, service, parameters, tube_id, 0, NULL, TRUE); if (!salut_tube_dbus_offer (SALUT_TUBE_DBUS (tube), &err)) { @@ -1970,7 +1971,7 @@ salut_tubes_channel_offer_stream_tube (TpSvcChannelTypeTubes *iface, tube_id = generate_tube_id (); tube = create_new_tube (self, TP_TUBE_TYPE_STREAM, priv->self_handle, - TRUE, service, parameters, tube_id, 0, NULL); + TRUE, service, parameters, tube_id, 0, NULL, TRUE); g_object_set (tube, "address-type", address_type, -- cgit v1.2.1 From 3360f5abbe98c28e6a2e6dfd5fe9553c80993e12 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 25 May 2012 11:15:30 +0100 Subject: tubes-channel: fix 'might be used unset' warning from gcc 4.7 Thanks for the heads up, GCC! Signed-off-by: Jonny Lamb --- src/tubes-channel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tubes-channel.c b/src/tubes-channel.c index 834c6ad3..1d7a1968 100644 --- a/src/tubes-channel.c +++ b/src/tubes-channel.c @@ -659,8 +659,10 @@ salut_tubes_channel_muc_message_received (SalutTubesChannel *self, stream_id = wocky_node_get_attribute (tube_node, "stream-id"); - extract_tube_information (self, tube_node, NULL, - NULL, NULL, NULL, &tube_id); + if (!extract_tube_information (self, tube_node, NULL, + NULL, NULL, NULL, &tube_id)) + continue; + tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); if (tube == NULL) -- cgit v1.2.1 From a64e1ec6fac7b9c01f9578ddbda49222b53d1784 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 25 May 2012 11:17:09 +0100 Subject: tube-dbus: subclass TpBaseChannel instead Signed-off-by: Jonny Lamb --- src/Makefile.am | 2 + src/muc-tube-dbus.c | 47 ++++++ src/muc-tube-dbus.h | 60 ++++++++ src/tube-dbus.c | 432 +++++++++++++--------------------------------------- src/tube-dbus.h | 5 +- src/tube-iface.c | 2 +- src/tubes-channel.c | 2 + 7 files changed, 223 insertions(+), 327 deletions(-) create mode 100644 src/muc-tube-dbus.c create mode 100644 src/muc-tube-dbus.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8a985abd..8be8d011 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,6 +45,8 @@ CORE_SOURCES = \ file-transfer-channel.c \ file-transfer-channel.h \ muc-channel.h \ + muc-tube-dbus.c \ + muc-tube-dbus.h \ presence-cache.c \ presence-cache.h \ tubes-manager.c \ diff --git a/src/muc-tube-dbus.c b/src/muc-tube-dbus.c new file mode 100644 index 00000000..0fedeaf4 --- /dev/null +++ b/src/muc-tube-dbus.c @@ -0,0 +1,47 @@ +/* + * muc-tube-dbus.c - Source for SalutMucTubeDBus + * Copyright (C) 2012 Collabora Ltd. + * + * 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. + * + * 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. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "muc-tube-dbus.h" + +G_DEFINE_TYPE (SalutMucTubeDBus, salut_muc_tube_dbus, + SALUT_TYPE_TUBE_DBUS) + +static const gchar *salut_muc_tube_dbus_interfaces[] = { + TP_IFACE_CHANNEL_INTERFACE_GROUP, + TP_IFACE_CHANNEL_INTERFACE_TUBE, + NULL +}; + +static void +salut_muc_tube_dbus_init (SalutMucTubeDBus *self) +{ +} + +static void +salut_muc_tube_dbus_class_init ( + SalutMucTubeDBusClass *salut_muc_tube_dbus_class) +{ + TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS ( + salut_muc_tube_dbus_class); + + base_class->interfaces = salut_muc_tube_dbus_interfaces; + base_class->target_handle_type = TP_HANDLE_TYPE_ROOM; +} diff --git a/src/muc-tube-dbus.h b/src/muc-tube-dbus.h new file mode 100644 index 00000000..cdaafab1 --- /dev/null +++ b/src/muc-tube-dbus.h @@ -0,0 +1,60 @@ +/* + * muc-tube-dbus.h - Header for SalutMucTubeDBus + * Copyright (C) 2012 Collabora Ltd. + * + * 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. + * + * 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. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SALUT_MUC_TUBE_DBUS_H__ +#define __SALUT_MUC_TUBE_DBUS_H__ + +#include + +#include "tube-dbus.h" + +G_BEGIN_DECLS + +typedef struct _SalutMucTubeDBus SalutMucTubeDBus; +typedef struct _SalutMucTubeDBusClass SalutMucTubeDBusClass; + +struct _SalutMucTubeDBusClass { + SalutTubeDBusClass parent_class; +}; + +struct _SalutMucTubeDBus { + SalutTubeDBus parent; +}; + +GType salut_muc_tube_dbus_get_type (void); + +/* TYPE MACROS */ +#define SALUT_TYPE_MUC_TUBE_DBUS \ + (salut_muc_tube_dbus_get_type ()) +#define SALUT_MUC_TUBE_DBUS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), SALUT_TYPE_MUC_TUBE_DBUS, SalutMucTubeDBus)) +#define SALUT_MUC_TUBE_DBUS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), SALUT_TYPE_MUC_TUBE_DBUS,\ + SalutMucTubeDBusClass)) +#define SALUT_IS_MUC_TUBE_DBUS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), SALUT_TYPE_MUC_TUBE_DBUS)) +#define SALUT_IS_MUC_TUBE_DBUS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), SALUT_TYPE_MUC_TUBE_DBUS)) +#define SALUT_MUC_TUBE_DBUS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), SALUT_TYPE_MUC_TUBE_DBUS,\ + SalutMucTubeDBusClass)) + +G_END_DECLS + +#endif /* #ifndef __SALUT_MUC_TUBE_DBUS_H__ */ diff --git a/src/tube-dbus.c b/src/tube-dbus.c index e92dde9b..aed98c33 100644 --- a/src/tube-dbus.c +++ b/src/tube-dbus.c @@ -44,6 +44,7 @@ #define DEBUG_FLAG DEBUG_TUBES #include "debug.h" #include "connection.h" +#include "muc-tube-dbus.h" #include "tube-iface.h" #include "sha1/sha1-util.h" @@ -56,27 +57,17 @@ * arbitrary limit on the queue size set to 4MB. */ #define MAX_QUEUE_SIZE (4096*1024) -static void channel_iface_init (gpointer, gpointer); static void tube_iface_init (gpointer g_iface, gpointer iface_data); static void dbustube_iface_init (gpointer g_iface, gpointer iface_data); -G_DEFINE_TYPE_WITH_CODE (SalutTubeDBus, salut_tube_dbus, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, - tp_dbus_properties_mixin_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init); +G_DEFINE_TYPE_WITH_CODE (SalutTubeDBus, salut_tube_dbus, TP_TYPE_BASE_CHANNEL, G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_DBUS_TUBE, dbustube_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE, - NULL); - G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL); - G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL)); + NULL)) static const gchar *salut_tube_dbus_interfaces[] = { - TP_IFACE_CHANNEL_INTERFACE_GROUP, - /* If more interfaces are added, either keep Group as the first, or change - * the implementations of salut_tube_dbus_get_interfaces () and - * salut_tube_dbus_get_property () too */ TP_IFACE_CHANNEL_INTERFACE_TUBE, NULL }; @@ -102,31 +93,19 @@ static guint signals[LAST_SIGNAL] = {0}; /* properties */ enum { - PROP_OBJECT_PATH = 1, - PROP_CHANNEL_TYPE, - PROP_CONNECTION, - PROP_INTERFACES, - PROP_TUBES_CHANNEL, - PROP_HANDLE, - PROP_HANDLE_TYPE, + PROP_TUBES_CHANNEL = 1, PROP_SELF_HANDLE, PROP_MUC_CONNECTION, PROP_ID, PROP_BYTESTREAM, PROP_STREAM_ID, PROP_TYPE, - PROP_INITIATOR_HANDLE, PROP_SERVICE, PROP_PARAMETERS, PROP_STATE, PROP_DBUS_ADDRESS, PROP_DBUS_NAME, PROP_DBUS_NAMES, - PROP_CHANNEL_DESTROYED, - PROP_CHANNEL_PROPERTIES, - PROP_REQUESTED, - PROP_TARGET_ID, - PROP_INITIATOR_ID, PROP_SUPPORTED_ACCESS_CONTROLS, LAST_PROPERTY }; @@ -134,11 +113,7 @@ enum typedef struct _SalutTubeDBusPrivate SalutTubeDBusPrivate; struct _SalutTubeDBusPrivate { - SalutConnection *conn; - gchar *object_path; SalutTubesChannel *tubes_channel; - TpHandle handle; - TpHandleType handle_type; TpHandle self_handle; GibberMucConnection *muc_connection; guint id; @@ -395,6 +370,7 @@ do_close (SalutTubeDBus *self) else { g_signal_emit (G_OBJECT (self), signals[CLOSED], 0); + tp_base_channel_destroyed (TP_BASE_CHANNEL (self)); } } @@ -546,6 +522,7 @@ bytestream_state_changed_cb (GibberBytestreamIface *bytestream, priv->closed = TRUE; g_signal_emit (G_OBJECT (self), signals[CLOSED], 0); + tp_base_channel_destroyed (TP_BASE_CHANNEL (self)); } else if (state == GIBBER_BYTESTREAM_STATE_OPEN) { @@ -635,7 +612,6 @@ salut_tube_dbus_finalize (GObject *object) SalutTubeDBus *self = SALUT_TUBE_DBUS (object); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); - g_free (priv->object_path); g_free (priv->stream_id); g_free (priv->service); g_hash_table_unref (priv->parameters); @@ -652,41 +628,12 @@ salut_tube_dbus_get_property (GObject *object, { SalutTubeDBus *self = SALUT_TUBE_DBUS (object); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); - TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn; switch (property_id) { - case PROP_OBJECT_PATH: - g_value_set_string (value, priv->object_path); - break; - case PROP_CHANNEL_TYPE: - g_value_set_static_string (value, - TP_IFACE_CHANNEL_TYPE_DBUS_TUBE); - break; - case PROP_CONNECTION: - g_value_set_object (value, priv->conn); - break; - case PROP_INTERFACES: - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - { - /* 1-1 tubes - omit the Group interface */ - g_value_set_boxed (value, salut_tube_dbus_interfaces + 1); - } - else - { - /* MUC tubes */ - g_value_set_boxed (value, salut_tube_dbus_interfaces); - } - break; case PROP_TUBES_CHANNEL: g_value_set_object (value, priv->tubes_channel); break; - case PROP_HANDLE: - g_value_set_uint (value, priv->handle); - break; - case PROP_HANDLE_TYPE: - g_value_set_uint (value, priv->handle_type); - break; case PROP_SELF_HANDLE: g_value_set_uint (value, priv->self_handle); break; @@ -705,9 +652,6 @@ salut_tube_dbus_get_property (GObject *object, case PROP_TYPE: g_value_set_uint (value, TP_TUBE_TYPE_DBUS); break; - case PROP_INITIATOR_HANDLE: - g_value_set_uint (value, priv->initiator); - break; case PROP_SERVICE: g_value_set_string (value, priv->service); break; @@ -726,72 +670,6 @@ salut_tube_dbus_get_property (GObject *object, case PROP_DBUS_NAMES: g_value_set_boxed (value, priv->dbus_names); break; - case PROP_CHANNEL_DESTROYED: - g_value_set_boolean (value, priv->closed); - break; - case PROP_CHANNEL_PROPERTIES: - { - GHashTable *properties; - - properties = tp_dbus_properties_mixin_make_properties_hash (object, - TP_IFACE_CHANNEL, "TargetHandle", - TP_IFACE_CHANNEL, "TargetHandleType", - TP_IFACE_CHANNEL, "ChannelType", - TP_IFACE_CHANNEL, "TargetID", - TP_IFACE_CHANNEL, "InitiatorHandle", - TP_IFACE_CHANNEL, "InitiatorID", - TP_IFACE_CHANNEL, "Requested", - TP_IFACE_CHANNEL, "Interfaces", - TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "ServiceName", - TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "SupportedAccessControls", - NULL); - - if (priv->initiator != priv->self_handle) - { - /* channel has not been requested so Parameters is immutable */ - GValue *prop_value = g_slice_new0 (GValue); - - /* FIXME: use tp_dbus_properties_mixin_add_properties once it's - * added in tp-glib */ - tp_dbus_properties_mixin_get (object, - TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters", - prop_value, NULL); - g_assert (G_IS_VALUE (prop_value)); - - g_hash_table_insert (properties, - g_strdup_printf ("%s.%s", TP_IFACE_CHANNEL_INTERFACE_TUBE, - "Parameters"), prop_value); - } - - g_value_take_boxed (value, properties); - } - break; - case PROP_REQUESTED: - g_value_set_boolean (value, - (priv->initiator == priv->self_handle)); - break; - case PROP_INITIATOR_ID: - { - TpHandleRepoIface *repo = tp_base_connection_get_handles ( - base_conn, TP_HANDLE_TYPE_CONTACT); - - /* some channel can have o.f.T.Channel.InitiatorHandle == 0 but - * tubes always have an initiator */ - g_assert (priv->initiator != 0); - - g_value_set_string (value, - tp_handle_inspect (repo, priv->initiator)); - } - break; - case PROP_TARGET_ID: - { - TpHandleRepoIface *repo = tp_base_connection_get_handles ( - base_conn, priv->handle_type); - - g_value_set_string (value, - tp_handle_inspect (repo, priv->handle)); - } - break; case PROP_SUPPORTED_ACCESS_CONTROLS: g_value_set_boxed (value, priv->supported_access_controls); break; @@ -812,26 +690,9 @@ salut_tube_dbus_set_property (GObject *object, switch (property_id) { - case PROP_OBJECT_PATH: - g_free (priv->object_path); - priv->object_path = g_value_dup_string (value); - break; - case PROP_CHANNEL_TYPE: - /* this property is writable in the interface, but not actually - * meaningfully changeable on this channel, so we do nothing */ - break; - case PROP_CONNECTION: - priv->conn = g_value_get_object (value); - break; case PROP_TUBES_CHANNEL: priv->tubes_channel = g_value_get_object (value); break; - case PROP_HANDLE: - priv->handle = g_value_get_uint (value); - break; - case PROP_HANDLE_TYPE: - priv->handle_type = g_value_get_uint (value); - break; case PROP_SELF_HANDLE: priv->self_handle = g_value_get_uint (value); break; @@ -860,9 +721,6 @@ salut_tube_dbus_set_property (GObject *object, G_CALLBACK (bytestream_state_changed_cb), self); } break; - case PROP_INITIATOR_HANDLE: - priv->initiator = g_value_get_uint (value); - break; case PROP_SERVICE: g_free (priv->service); priv->service = g_value_dup_string (value); @@ -886,7 +744,9 @@ salut_tube_dbus_constructor (GType type, GObject *obj; SalutTubeDBus *self; SalutTubeDBusPrivate *priv; - TpDBusDaemon *bus; + TpBaseChannel *base; + TpBaseChannelClass *cls; + SalutConnection *conn; TpBaseConnection *base_conn; TpHandleRepoIface *handles_repo; TpSocketAccessControl access_control; @@ -895,22 +755,18 @@ salut_tube_dbus_constructor (GType type, constructor (type, n_props, props); self = SALUT_TUBE_DBUS (obj); - priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); - - base_conn = TP_BASE_CONNECTION (priv->conn); - handles_repo = tp_base_connection_get_handles (base_conn, priv->handle_type); - - /* Ref the initiator handle */ - g_assert (priv->conn != NULL); - g_assert (priv->initiator != 0); + base = TP_BASE_CHANNEL (self); + cls = TP_BASE_CHANNEL_GET_CLASS (base); - bus = tp_base_connection_get_dbus_daemon (base_conn); - tp_dbus_daemon_register_object (bus, priv->object_path, obj); + priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); - DEBUG ("Registering at '%s'", priv->object_path); + conn = SALUT_CONNECTION (tp_base_channel_get_connection (base)); + base_conn = TP_BASE_CONNECTION (conn); + handles_repo = tp_base_connection_get_handles (base_conn, + cls->target_handle_type); g_assert (priv->self_handle != 0); - if (priv->handle_type == TP_HANDLE_TYPE_ROOM) + if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM) { /* * We have to create an MUC bytestream that will be @@ -927,15 +783,16 @@ salut_tube_dbus_constructor (GType type, priv->dbus_names = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); - priv->dbus_local_name = generate_dbus_unique_name (priv->conn->name); + priv->dbus_local_name = generate_dbus_unique_name (conn->name); DEBUG ("local name: %s", priv->dbus_local_name); - peer_id = tp_handle_inspect (handles_repo, priv->handle); + peer_id = tp_handle_inspect (handles_repo, + tp_base_channel_get_target_handle (base)); bytestream = g_object_new (GIBBER_TYPE_BYTESTREAM_MUC, "muc-connection", priv->muc_connection, "state", GIBBER_BYTESTREAM_STATE_LOCAL_PENDING, - "self-id", priv->conn->name, + "self-id", conn->name, "peer-id", peer_id, NULL); @@ -958,7 +815,13 @@ salut_tube_dbus_constructor (GType type, priv->reassembly_bytes_needed = 0; } - if (priv->initiator == priv->self_handle) + /* Tube needs to be offered if we initiated and requested it. Being + * the initiator is not enough as we could re-join a MUC containing + * an old tube we created when we were in this room some time + * ago. In that case, we have to accept it if we want to re-join the + * tube. */ + if (tp_base_channel_get_initiator (base) == priv->self_handle + && tp_base_channel_is_requested (base)) { priv->offered = FALSE; } @@ -983,20 +846,50 @@ salut_tube_dbus_constructor (GType type, return obj; } +static void +salut_tube_dbus_fill_immutable_properties (TpBaseChannel *chan, + GHashTable *properties) +{ + TpBaseChannelClass *cls = TP_BASE_CHANNEL_CLASS ( + salut_tube_dbus_parent_class); + + cls->fill_immutable_properties (chan, properties); + + tp_dbus_properties_mixin_fill_properties_hash ( + G_OBJECT (chan), properties, + TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "ServiceName", + TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "SupportedAccessControls", + NULL); + + if (!tp_base_channel_is_requested (chan)) + { + tp_dbus_properties_mixin_fill_properties_hash ( + G_OBJECT (chan), properties, + TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters", + NULL); + } +} + +static gchar * +salut_tube_dbus_get_object_path_suffix (TpBaseChannel *base) +{ + SalutTubeDBus *self = SALUT_TUBE_DBUS (base); + SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + + return g_strdup_printf ("DBusTubeChannel/%u/%u", + tp_base_channel_get_target_handle (base), + priv->id); +} + +static void +salut_tube_dbus_close_dbus (TpBaseChannel *base) +{ + do_close ((SalutTubeDBus *) base); +} + static void salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) { - static TpDBusPropertiesMixinPropImpl channel_props[] = { - { "TargetHandleType", "handle-type", NULL }, - { "TargetHandle", "handle", NULL }, - { "ChannelType", "channel-type", NULL }, - { "TargetID", "target-id", NULL }, - { "Interfaces", "interfaces", NULL }, - { "Requested", "requested", NULL }, - { "InitiatorHandle", "initiator-handle", NULL }, - { "InitiatorID", "initiator-id", NULL }, - { NULL } - }; static TpDBusPropertiesMixinPropImpl dbus_tube_props[] = { { "ServiceName", "service", NULL }, { "DBusNames", "dbus-names", NULL }, @@ -1009,11 +902,6 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) { NULL } }; static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { - { TP_IFACE_CHANNEL, - tp_dbus_properties_mixin_getter_gobject_properties, - NULL, - channel_props, - }, { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, tp_dbus_properties_mixin_getter_gobject_properties, NULL, @@ -1027,38 +915,36 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) { NULL } }; GObjectClass *object_class = G_OBJECT_CLASS (salut_tube_dbus_class); + TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (salut_tube_dbus_class); GParamSpec *param_spec; object_class->get_property = salut_tube_dbus_get_property; object_class->set_property = salut_tube_dbus_set_property; object_class->constructor = salut_tube_dbus_constructor; + base_class->channel_type = TP_IFACE_CHANNEL_TYPE_DBUS_TUBE; + base_class->interfaces = salut_tube_dbus_interfaces; + base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT; + base_class->close = salut_tube_dbus_close_dbus; + base_class->fill_immutable_properties = + salut_tube_dbus_fill_immutable_properties; + base_class->get_object_path_suffix = + salut_tube_dbus_get_object_path_suffix; + g_type_class_add_private (salut_tube_dbus_class, sizeof (SalutTubeDBusPrivate)); object_class->dispose = salut_tube_dbus_dispose; object_class->finalize = salut_tube_dbus_finalize; - g_object_class_override_property (object_class, PROP_OBJECT_PATH, - "object-path"); - g_object_class_override_property (object_class, PROP_CHANNEL_TYPE, - "channel-type"); - g_object_class_override_property (object_class, PROP_CONNECTION, - "connection"); g_object_class_override_property (object_class, PROP_TUBES_CHANNEL, "tubes-channel"); - g_object_class_override_property (object_class, PROP_HANDLE, - "handle"); - g_object_class_override_property (object_class, PROP_HANDLE_TYPE, - "handle-type"); g_object_class_override_property (object_class, PROP_SELF_HANDLE, "self-handle"); g_object_class_override_property (object_class, PROP_ID, "id"); g_object_class_override_property (object_class, PROP_TYPE, "type"); - g_object_class_override_property (object_class, PROP_INITIATOR_HANDLE, - "initiator-handle"); g_object_class_override_property (object_class, PROP_SERVICE, "service"); g_object_class_override_property (object_class, PROP_PARAMETERS, @@ -1066,11 +952,6 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) g_object_class_override_property (object_class, PROP_STATE, "state"); - g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED, - "channel-destroyed"); - g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES, - "channel-properties"); - param_spec = g_param_spec_object ( "muc-connection", "GibberMucConnection object", @@ -1123,31 +1004,6 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_DBUS_NAMES, param_spec); - param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces", - "Additional Channel.Interface.* interfaces", - G_TYPE_STRV, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INTERFACES, param_spec); - - param_spec = g_param_spec_string ("target-id", "Target JID", - "The string obtained by inspecting the target handle", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec); - - param_spec = g_param_spec_string ("initiator-id", "Initiator's bare JID", - "The string obtained by inspecting the initiator-handle", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INITIATOR_ID, - param_spec); - - param_spec = g_param_spec_boolean ("requested", "Requested?", - "True if this channel was requested by the local user", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_REQUESTED, param_spec); - param_spec = g_param_spec_boxed ( "supported-access-controls", "Supported access-controls", @@ -1194,6 +1050,8 @@ salut_tube_dbus_offer (SalutTubeDBus *self, GError **error) { SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); if (priv->offered) { @@ -1202,7 +1060,7 @@ salut_tube_dbus_offer (SalutTubeDBus *self, return FALSE; } - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { /* TODO: we don't implement 1-1 D-Bus tube atm */ ; @@ -1229,6 +1087,8 @@ message_received (SalutTubeDBus *tube, const char *data, size_t len) { + TpBaseChannel *base = TP_BASE_CHANNEL (tube); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (tube); DBusMessage *msg; DBusError error = {0,}; @@ -1245,7 +1105,7 @@ message_received (SalutTubeDBus *tube, return; } - if (priv->handle_type == TP_HANDLE_TYPE_ROOM) + if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM) { const gchar *destination; const gchar *sender_name; @@ -1331,8 +1191,11 @@ data_received_cb (GibberBytestreamIface *stream, { SalutTubeDBus *tube = SALUT_TUBE_DBUS (user_data); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (tube); + TpBaseChannel *base = TP_BASE_CHANNEL (tube); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); + tp_base_channel_get_connection (base), + TP_HANDLE_TYPE_CONTACT); TpHandle sender; sender = tp_handle_lookup (contact_repo, from, NULL, NULL); @@ -1342,7 +1205,7 @@ data_received_cb (GibberBytestreamIface *stream, return; } - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { GString *buf = priv->reassembly_buffer; @@ -1459,17 +1322,15 @@ salut_tube_dbus_new (SalutConnection *conn, gboolean requested) { SalutTubeDBus *tube; - gchar *object_path; + GType gtype = SALUT_TYPE_TUBE_DBUS; - object_path = g_strdup_printf ("%s/DBusTubeChannel_%u_%u", - conn->parent.object_path, handle, id); + if (handle_type == TP_HANDLE_TYPE_ROOM) + gtype = SALUT_TYPE_MUC_TUBE_DBUS; - tube = g_object_new (SALUT_TYPE_TUBE_DBUS, + tube = g_object_new (gtype, "connection", conn, - "object-path", object_path, "tubes-channel", tubes_channel, "handle", handle, - "handle-type", handle_type, "self-handle", self_handle, "muc-connection", muc_connection, "initiator-handle", initiator, @@ -1493,6 +1354,8 @@ salut_tube_dbus_accept (SalutTubeIface *tube, { SalutTubeDBus *self = SALUT_TUBE_DBUS (tube); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); GibberBytestreamState state; g_assert (priv->bytestream != NULL); @@ -1504,7 +1367,7 @@ salut_tube_dbus_accept (SalutTubeIface *tube, if (state != GIBBER_BYTESTREAM_STATE_LOCAL_PENDING) return TRUE; - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { /* TODO: SI reply */ } @@ -1553,12 +1416,15 @@ salut_tube_dbus_add_name (SalutTubeDBus *self, const gchar *name) { SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); + tp_base_channel_get_connection (base), + TP_HANDLE_TYPE_CONTACT); GHashTable *added; GArray *removed; - g_assert (priv->handle_type == TP_HANDLE_TYPE_ROOM); + g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM); if (g_hash_table_lookup (priv->dbus_names, GUINT_TO_POINTER (handle)) != NULL) @@ -1608,11 +1474,13 @@ salut_tube_dbus_remove_name (SalutTubeDBus *self, TpHandle handle) { SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); const gchar *name; GHashTable *added; GArray *removed; - g_assert (priv->handle_type == TP_HANDLE_TYPE_ROOM); + g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM); name = g_hash_table_lookup (priv->dbus_names, GUINT_TO_POINTER (handle)); if (name == NULL) @@ -1639,8 +1507,10 @@ salut_tube_dbus_handle_in_names (SalutTubeDBus *self, TpHandle handle) { SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); - g_assert (priv->handle_type == TP_HANDLE_TYPE_ROOM); + g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM); return (g_hash_table_lookup (priv->dbus_names, GUINT_TO_POINTER (handle)) != NULL); @@ -1652,77 +1522,6 @@ salut_tube_dbus_channel_get_allowed_properties (void) return salut_tube_dbus_channel_allowed_properties; } -/** - * salut_tube_dbus_close_async: - * - * Implements D-Bus method Close - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_dbus_close_async (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - salut_tube_dbus_close (SALUT_TUBE_IFACE (iface), FALSE); - tp_svc_channel_return_from_close (context); -} - -/** - * salut_tube_dbus_get_channel_type - * - * Implements D-Bus method GetChannelType - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_dbus_get_channel_type (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - tp_svc_channel_return_from_get_channel_type (context, - TP_IFACE_CHANNEL_TYPE_DBUS_TUBE); -} - -/** - * salut_tube_dbus_get_handle - * - * Implements D-Bus method GetHandle - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_dbus_get_handle (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - SalutTubeDBus *self = SALUT_TUBE_DBUS (iface); - SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); - - tp_svc_channel_return_from_get_handle (context, priv->handle_type, - priv->handle); -} - -/** - * salut_tube_dbus_get_interfaces - * - * Implements D-Bus method GetInterfaces - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_dbus_get_interfaces (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - SalutTubeDBus *self = SALUT_TUBE_DBUS (iface); - SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); - - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - { - /* omit the Group interface */ - tp_svc_channel_return_from_get_interfaces (context, - salut_tube_dbus_interfaces + 1); - } - else - { - tp_svc_channel_return_from_get_interfaces (context, - salut_tube_dbus_interfaces); - } -} - static gboolean salut_tube_dbus_check_access_control (SalutTubeDBus *self, guint access_control, @@ -1818,21 +1617,6 @@ salut_tube_dbus_accept_async (TpSvcChannelTypeDBusTube *self, } } -static void -channel_iface_init (gpointer g_iface, - gpointer iface_data) -{ - TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface; - -#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\ - klass, salut_tube_dbus_##x##suffix) - IMPLEMENT(close,_async); - IMPLEMENT(get_channel_type,); - IMPLEMENT(get_handle,); - IMPLEMENT(get_interfaces,); -#undef IMPLEMENT -} - static void tube_iface_init (gpointer g_iface, gpointer iface_data) diff --git a/src/tube-dbus.h b/src/tube-dbus.h index b90285ac..d3954ad4 100644 --- a/src/tube-dbus.h +++ b/src/tube-dbus.h @@ -22,6 +22,7 @@ #include +#include #include #include @@ -36,13 +37,13 @@ typedef struct _SalutTubeDBus SalutTubeDBus; typedef struct _SalutTubeDBusClass SalutTubeDBusClass; struct _SalutTubeDBusClass { - GObjectClass parent_class; + TpBaseChannelClass parent_class; TpDBusPropertiesMixinClass dbus_props_class; }; struct _SalutTubeDBus { - GObject parent; + TpBaseChannel parent; gpointer priv; }; diff --git a/src/tube-iface.c b/src/tube-iface.c index 18d39877..fa866442 100644 --- a/src/tube-iface.c +++ b/src/tube-iface.c @@ -96,7 +96,7 @@ salut_tube_iface_base_init (gpointer klass) "connection", "SalutConnection object", "Salut connection object that owns this D-Bus tube object.", - SALUT_TYPE_CONNECTION, + TP_TYPE_BASE_CONNECTION, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_interface_install_property (klass, param_spec); diff --git a/src/tubes-channel.c b/src/tubes-channel.c index 1d7a1968..77b5c7cd 100644 --- a/src/tubes-channel.c +++ b/src/tubes-channel.c @@ -1150,6 +1150,8 @@ create_new_tube (SalutTubesChannel *self, tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, self, priv->handle, priv->handle_type, priv->self_handle, muc_connection, initiator, service, parameters, tube_id, requested)); + + tp_base_channel_register ((TpBaseChannel *) tube); break; case TP_TUBE_TYPE_STREAM: tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, self, -- cgit v1.2.1 From 585826040b2b7dff021e742bc8421c23577dd0ba Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 25 May 2012 16:35:52 +0100 Subject: tube-stream: subclass TpBaseChannel Signed-off-by: Jonny Lamb --- src/Makefile.am | 4 +- src/muc-tube-stream.c | 47 +++++ src/muc-tube-stream.h | 60 ++++++ src/tube-stream.c | 518 +++++++++++++++----------------------------------- src/tube-stream.h | 7 +- src/tubes-channel.c | 6 +- 6 files changed, 269 insertions(+), 373 deletions(-) create mode 100644 src/muc-tube-stream.c create mode 100644 src/muc-tube-stream.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8be8d011..a8d1d534 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,7 +46,9 @@ CORE_SOURCES = \ file-transfer-channel.h \ muc-channel.h \ muc-tube-dbus.c \ - muc-tube-dbus.h \ + muc-tube-dbus.h \ + muc-tube-stream.c \ + muc-tube-stream.h \ presence-cache.c \ presence-cache.h \ tubes-manager.c \ diff --git a/src/muc-tube-stream.c b/src/muc-tube-stream.c new file mode 100644 index 00000000..0833d4df --- /dev/null +++ b/src/muc-tube-stream.c @@ -0,0 +1,47 @@ +/* + * muc-tube-stream.c - Source for SalutMucTubeStream + * Copyright (C) 2012 Collabora Ltd. + * + * 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. + * + * 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. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "muc-tube-stream.h" + +G_DEFINE_TYPE (SalutMucTubeStream, salut_muc_tube_stream, + SALUT_TYPE_TUBE_STREAM) + +static const gchar *salut_muc_tube_stream_interfaces[] = { + TP_IFACE_CHANNEL_INTERFACE_GROUP, + TP_IFACE_CHANNEL_INTERFACE_TUBE, + NULL +}; + +static void +salut_muc_tube_stream_init (SalutMucTubeStream *self) +{ +} + +static void +salut_muc_tube_stream_class_init ( + SalutMucTubeStreamClass *salut_muc_tube_stream_class) +{ + TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS ( + salut_muc_tube_stream_class); + + base_class->interfaces = salut_muc_tube_stream_interfaces; + base_class->target_handle_type = TP_HANDLE_TYPE_ROOM; +} diff --git a/src/muc-tube-stream.h b/src/muc-tube-stream.h new file mode 100644 index 00000000..d673a108 --- /dev/null +++ b/src/muc-tube-stream.h @@ -0,0 +1,60 @@ +/* + * muc-tube-stream.h - Header for SalutMucTubeStream + * Copyright (C) 2012 Collabora Ltd. + * + * 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. + * + * 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. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SALUT_MUC_TUBE_STREAM_H__ +#define __SALUT_MUC_TUBE_STREAM_H__ + +#include + +#include "tube-stream.h" + +G_BEGIN_DECLS + +typedef struct _SalutMucTubeStream SalutMucTubeStream; +typedef struct _SalutMucTubeStreamClass SalutMucTubeStreamClass; + +struct _SalutMucTubeStreamClass { + SalutTubeStreamClass parent_class; +}; + +struct _SalutMucTubeStream { + SalutTubeStream parent; +}; + +GType salut_muc_tube_stream_get_type (void); + +/* TYPE MACROS */ +#define SALUT_TYPE_MUC_TUBE_STREAM \ + (salut_muc_tube_stream_get_type ()) +#define SALUT_MUC_TUBE_STREAM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), SALUT_TYPE_MUC_TUBE_STREAM, SalutMucTubeStream)) +#define SALUT_MUC_TUBE_STREAM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), SALUT_TYPE_MUC_TUBE_STREAM,\ + SalutMucTubeStreamClass)) +#define SALUT_IS_MUC_TUBE_STREAM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), SALUT_TYPE_MUC_TUBE_STREAM)) +#define SALUT_IS_MUC_TUBE_STREAM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), SALUT_TYPE_MUC_TUBE_STREAM)) +#define SALUT_MUC_TUBE_STREAM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), SALUT_TYPE_MUC_TUBE_STREAM,\ + SalutMucTubeStreamClass)) + +G_END_DECLS + +#endif /* #ifndef __SALUT_MUC_TUBE_STREAM_H__ */ diff --git a/src/tube-stream.c b/src/tube-stream.c index acb3a8e9..b9782dda 100644 --- a/src/tube-stream.c +++ b/src/tube-stream.c @@ -67,32 +67,24 @@ #include "debug.h" #include "signals-marshal.h" #include "connection.h" +#include "muc-tube-stream.h" #include "tube-iface.h" #include "si-bytestream-manager.h" #include "contact-manager.h" #include "tubes-channel.h" static void tube_iface_init (gpointer g_iface, gpointer iface_data); -static void channel_iface_init (gpointer g_iface, gpointer iface_data); static void streamtube_iface_init (gpointer g_iface, gpointer iface_data); -G_DEFINE_TYPE_WITH_CODE (SalutTubeStream, salut_tube_stream, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, - tp_dbus_properties_mixin_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init); +G_DEFINE_TYPE_WITH_CODE (SalutTubeStream, salut_tube_stream, + TP_TYPE_BASE_CHANNEL, G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAM_TUBE, streamtube_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE, - NULL); - G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL); - G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL)); + NULL)); static const gchar *salut_tube_stream_interfaces[] = { - TP_IFACE_CHANNEL_INTERFACE_GROUP, - /* If more interfaces are added, either keep Tube as the first, or change - * the implementations of salut_tube_stream_get_interfaces () and - * salut_tube_stream_get_property () too */ TP_IFACE_CHANNEL_INTERFACE_TUBE, NULL }; @@ -131,15 +123,10 @@ static guint signals[LAST_SIGNAL] = {0}; /* properties */ enum { - PROP_CONNECTION = 1, - PROP_TUBES_CHANNEL, - PROP_INTERFACES, - PROP_HANDLE, - PROP_HANDLE_TYPE, + PROP_TUBES_CHANNEL = 1, PROP_SELF_HANDLE, PROP_ID, PROP_TYPE, - PROP_INITIATOR_HANDLE, PROP_SERVICE, PROP_PARAMETERS, PROP_STATE, @@ -150,13 +137,6 @@ enum PROP_ACCESS_CONTROL_PARAM, PROP_PORT, PROP_IQ_REQ, - PROP_CHANNEL_DESTROYED, - PROP_CHANNEL_PROPERTIES, - PROP_OBJECT_PATH, - PROP_CHANNEL_TYPE, - PROP_TARGET_ID, - PROP_REQUESTED, - PROP_INITIATOR_ID, PROP_SUPPORTED_SOCKET_TYPES, LAST_PROPERTY }; @@ -164,15 +144,11 @@ enum typedef struct _SalutTubeStreamPrivate SalutTubeStreamPrivate; struct _SalutTubeStreamPrivate { - SalutConnection *conn; SalutTubesChannel *tubes_channel; - TpHandle handle; - TpHandleType handle_type; TpHandle self_handle; guint id; guint port; WockyStanza *iq_req; - gchar *object_path; /* Bytestreams for MUC tubes (using stream initiation) or 1-1 tubes (using * direct TCP connections). One tube can have several bytestreams. The @@ -200,7 +176,6 @@ struct _SalutTubeStreamPrivate GHashTable *transport_to_id; guint last_connection_id; - TpHandle initiator; gchar *service; GHashTable *parameters; TpTubeChannelState state; @@ -219,8 +194,6 @@ struct _SalutTubeStreamPrivate /* listen for connections from the remote CM */ GibberListener *contact_listener; - gboolean closed; - gboolean offer_needed; gboolean dispose_has_run; @@ -499,10 +472,11 @@ extra_bytestream_negotiate_cb (GibberBytestreamIface *bytestream, static gchar * generate_stream_id (SalutTubeStream *self) { - SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); gchar *stream_id; - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { stream_id = g_strdup_printf ("%lu-%u", (unsigned long) time (NULL), g_random_int ()); @@ -522,10 +496,13 @@ start_stream_initiation (SalutTubeStream *self, GError **error) { SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); + TpHandle initiator = tp_base_channel_get_initiator (base); WockyNode *node, *si_node; WockyStanza *msg; WockyNode *msg_node; - TpHandleRepoIface *contact_repo; + TpHandleRepoIface *contact_repo, *room_repo; const gchar *jid; gchar *stream_id, *id_str; gboolean result; @@ -533,17 +510,19 @@ start_stream_initiation (SalutTubeStream *self, SalutContact *contact; SalutContactManager *contact_mgr; SalutSiBytestreamManager *si_bytestream_mgr; - TpHandleRepoIface *room_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_ROOM); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + SalutConnection *conn = SALUT_CONNECTION (base_conn); - contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); + contact_repo = tp_base_connection_get_handles (base_conn, + TP_HANDLE_TYPE_CONTACT); + room_repo = tp_base_connection_get_handles (base_conn, + TP_HANDLE_TYPE_ROOM); - jid = tp_handle_inspect (contact_repo, priv->initiator); + jid = tp_handle_inspect (contact_repo, initiator); stream_id = generate_stream_id (self); - msg = salut_si_bytestream_manager_make_stream_init_iq (priv->conn->name, jid, + msg = salut_si_bytestream_manager_make_stream_init_iq (conn->name, jid, stream_id, WOCKY_TELEPATHY_NS_TUBES); msg_node = wocky_stanza_get_top_node (msg); @@ -552,13 +531,13 @@ start_stream_initiation (SalutTubeStream *self, id_str = g_strdup_printf ("%u", priv->id); - g_assert (priv->handle_type == TP_HANDLE_TYPE_ROOM); + g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM); /* FIXME: this needs standardizing */ node = wocky_node_add_child_ns (si_node, "muc-stream", WOCKY_TELEPATHY_NS_TUBES); wocky_node_set_attribute (node, "muc", tp_handle_inspect ( - room_repo, priv->handle)); + room_repo, tp_base_channel_get_target_handle (base))); wocky_node_set_attribute (node, "tube", id_str); @@ -566,19 +545,19 @@ start_stream_initiation (SalutTubeStream *self, data->self = self; data->transport = g_object_ref (transport); - g_object_get (priv->conn, + g_object_get (conn, "si-bytestream-manager", &si_bytestream_mgr, "contact-manager", &contact_mgr, NULL); g_assert (si_bytestream_mgr != NULL); g_assert (contact_mgr != NULL); - contact = salut_contact_manager_get_contact (contact_mgr, priv->initiator); + contact = salut_contact_manager_get_contact (contact_mgr, initiator); if (contact == NULL) { result = FALSE; g_set_error (error, TP_ERROR, TP_ERROR_NETWORK_ERROR, - "can't find contact with handle %d", priv->initiator); + "can't find contact with handle %d", initiator); g_object_unref (transport); g_slice_free (struct _extra_bytestream_negotiate_cb_data, data); } @@ -623,22 +602,25 @@ start_stream_direct (SalutTubeStream *self, GError **error) { SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); + TpHandle initiator = tp_base_channel_get_initiator (base); SalutContact *contact; SalutContactManager *contact_mgr; GibberBytestreamIface *bytestream; - g_assert (priv->handle_type == TP_HANDLE_TYPE_CONTACT); + g_assert (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT); - g_object_get (priv->conn, + g_object_get (tp_base_channel_get_connection (base), "contact-manager", &contact_mgr, NULL); g_assert (contact_mgr != NULL); - contact = salut_contact_manager_get_contact (contact_mgr, priv->initiator); + contact = salut_contact_manager_get_contact (contact_mgr, initiator); if (contact == NULL) { g_set_error (error, TP_ERROR, TP_ERROR_NETWORK_ERROR, - "can't find contact with handle %d", priv->initiator); + "can't find contact with handle %d", initiator); g_object_unref (contact_mgr); @@ -713,7 +695,8 @@ local_new_connection_cb (GibberListener *listener, gpointer user_data) { SalutTubeStream *self = SALUT_TUBE_STREAM (user_data); - SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); /* Block the transport while there is no open bytestream to transfer * its data. */ @@ -725,7 +708,7 @@ local_new_connection_cb (GibberListener *listener, * Streams in P2P tubes are established directly with a TCP connection. We * use SalutDirectBytestreamManager. */ - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { if (!start_stream_direct (self, transport, NULL)) { @@ -774,9 +757,10 @@ new_connection_to_socket (SalutTubeStream *self, GibberBytestreamIface *bytestream) { SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); GibberTransport *transport; - g_assert (priv->initiator == priv->self_handle); + g_assert (tp_base_channel_is_requested (base)); #ifdef GIBBER_TYPE_UNIX_TRANSPORT if (priv->address_type == TP_SOCKET_ADDRESS_TYPE_UNIX) @@ -837,10 +821,11 @@ tube_stream_open (SalutTubeStream *self, GError **error) { SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); DEBUG ("called"); - if (priv->initiator == priv->self_handle) + if (tp_base_channel_is_requested (base)) /* Nothing to do if we are the initiator of this tube. * We'll connect to the socket each time request a new bytestream. */ return TRUE; @@ -970,7 +955,6 @@ salut_tube_stream_init (SalutTubeStream *self) priv->address = NULL; priv->access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST; priv->access_control_param = NULL; - priv->closed = FALSE; priv->offer_needed = FALSE; priv->dispose_has_run = FALSE; @@ -1010,13 +994,14 @@ salut_tube_stream_dispose (GObject *object) { SalutTubeStream *self = SALUT_TUBE_STREAM (object); SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); if (priv->dispose_has_run) return; salut_tube_iface_close (SALUT_TUBE_IFACE (self), FALSE); - if (priv->initiator != priv->self_handle && + if (tp_base_channel_is_requested (base) && priv->address_type == TP_SOCKET_ADDRESS_TYPE_UNIX && priv->address != NULL) { @@ -1077,7 +1062,6 @@ salut_tube_stream_finalize (GObject *object) SalutTubeStream *self = SALUT_TUBE_STREAM (object); SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); - g_free (priv->object_path); g_free (priv->service); if (priv->parameters != NULL) { @@ -1108,40 +1092,12 @@ salut_tube_stream_get_property (GObject *object, { SalutTubeStream *self = SALUT_TUBE_STREAM (object); SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); - TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn; switch (property_id) { case PROP_TUBES_CHANNEL: g_value_set_object (value, priv->tubes_channel); break; - case PROP_CONNECTION: - g_value_set_object (value, priv->conn); - break; - case PROP_OBJECT_PATH: - g_value_set_string (value, priv->object_path); - break; - case PROP_INTERFACES: - if (priv->handle_type == TP_HANDLE_TYPE_ROOM) - { - /* MUC tubes */ - g_value_set_boxed (value, salut_tube_stream_interfaces); - } - else - { - /* 1-1 tubes - omit the Group interface */ - g_value_set_boxed (value, salut_tube_stream_interfaces + 1); - } - break; - case PROP_CHANNEL_TYPE: - g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE); - break; - case PROP_HANDLE: - g_value_set_uint (value, priv->handle); - break; - case PROP_HANDLE_TYPE: - g_value_set_uint (value, priv->handle_type); - break; case PROP_SELF_HANDLE: g_value_set_uint (value, priv->self_handle); break; @@ -1151,9 +1107,6 @@ salut_tube_stream_get_property (GObject *object, case PROP_TYPE: g_value_set_uint (value, TP_TUBE_TYPE_STREAM); break; - case PROP_INITIATOR_HANDLE: - g_value_set_uint (value, priv->initiator); - break; case PROP_SERVICE: g_value_set_string (value, priv->service); break; @@ -1184,72 +1137,6 @@ salut_tube_stream_get_property (GObject *object, case PROP_IQ_REQ: g_value_set_pointer (value, priv->iq_req); break; - case PROP_CHANNEL_DESTROYED: - g_value_set_boolean (value, priv->closed); - break; - case PROP_CHANNEL_PROPERTIES: - { - GHashTable *properties; - - properties = tp_dbus_properties_mixin_make_properties_hash (object, - TP_IFACE_CHANNEL, "TargetHandle", - TP_IFACE_CHANNEL, "TargetHandleType", - TP_IFACE_CHANNEL, "ChannelType", - TP_IFACE_CHANNEL, "TargetID", - TP_IFACE_CHANNEL, "InitiatorHandle", - TP_IFACE_CHANNEL, "InitiatorID", - TP_IFACE_CHANNEL, "Requested", - TP_IFACE_CHANNEL, "Interfaces", - TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "Service", - TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "SupportedSocketTypes", - NULL); - - if (priv->initiator != priv->self_handle) - { - /* channel has not been requested so Parameters is immutable */ - GValue *prop_value = g_slice_new0 (GValue); - - /* FIXME: use tp_dbus_properties_mixin_add_properties once it's - * added in tp-glib */ - tp_dbus_properties_mixin_get (object, - TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters", - prop_value, NULL); - g_assert (G_IS_VALUE (prop_value)); - - g_hash_table_insert (properties, - g_strdup_printf ("%s.%s", TP_IFACE_CHANNEL_INTERFACE_TUBE, - "Parameters"), prop_value); - } - - g_value_take_boxed (value, properties); - } - break; - case PROP_REQUESTED: - g_value_set_boolean (value, - (priv->initiator == priv->self_handle)); - break; - case PROP_INITIATOR_ID: - { - TpHandleRepoIface *repo = tp_base_connection_get_handles ( - base_conn, TP_HANDLE_TYPE_CONTACT); - - /* some channel can have o.f.T.Channel.InitiatorHandle == 0 but - * tubes always have an initiator */ - g_assert (priv->initiator != 0); - - g_value_set_string (value, - tp_handle_inspect (repo, priv->initiator)); - } - break; - case PROP_TARGET_ID: - { - TpHandleRepoIface *repo = tp_base_connection_get_handles ( - base_conn, priv->handle_type); - - g_value_set_string (value, - tp_handle_inspect (repo, priv->handle)); - } - break; case PROP_SUPPORTED_SOCKET_TYPES: g_value_take_boxed (value, salut_tube_stream_get_supported_socket_types ()); @@ -1274,32 +1161,12 @@ salut_tube_stream_set_property (GObject *object, case PROP_TUBES_CHANNEL: priv->tubes_channel = g_value_get_object (value); break; - case PROP_CONNECTION: - priv->conn = g_value_get_object (value); - break; - case PROP_OBJECT_PATH: - g_free (priv->object_path); - priv->object_path = g_value_dup_string (value); - break; - case PROP_CHANNEL_TYPE: - /* this property is writable in the interface, but not actually - * meaningfully changeable on this channel, so we do nothing */ - break; - case PROP_HANDLE: - priv->handle = g_value_get_uint (value); - break; - case PROP_HANDLE_TYPE: - priv->handle_type = g_value_get_uint (value); - break; case PROP_SELF_HANDLE: priv->self_handle = g_value_get_uint (value); break; case PROP_ID: priv->id = g_value_get_uint (value); break; - case PROP_INITIATOR_HANDLE: - priv->initiator = g_value_get_uint (value); - break; case PROP_SERVICE: g_free (priv->service); priv->service = g_value_dup_string (value); @@ -1358,19 +1225,16 @@ salut_tube_stream_constructor (GType type, { GObject *obj; SalutTubeStreamPrivate *priv; - TpDBusDaemon *bus; - TpBaseConnection *base_conn; + TpBaseChannel *base; obj = G_OBJECT_CLASS (salut_tube_stream_parent_class)-> constructor (type, n_props, props); priv = SALUT_TUBE_STREAM_GET_PRIVATE (SALUT_TUBE_STREAM (obj)); - /* Ref the initiator handle */ - base_conn = TP_BASE_CONNECTION (priv->conn); - g_assert (priv->initiator != 0); + base = TP_BASE_CHANNEL (obj); - if (priv->initiator == priv->self_handle) + if (tp_base_channel_get_initiator (base) == priv->self_handle) { /* We initiated this tube */ priv->state = TP_TUBE_CHANNEL_STATE_NOT_OFFERED; @@ -1382,28 +1246,55 @@ salut_tube_stream_constructor (GType type, priv->state = TP_TUBE_CHANNEL_STATE_LOCAL_PENDING; } - bus = tp_base_connection_get_dbus_daemon (base_conn); - tp_dbus_daemon_register_object (bus, priv->object_path, obj); - - DEBUG ("Registering at '%s'", priv->object_path); + DEBUG ("Registering at '%s'", tp_base_channel_get_object_path (base)); return obj; } +static void +salut_tube_stream_fill_immutable_properties (TpBaseChannel *chan, + GHashTable *properties) +{ + TpBaseChannelClass *cls = TP_BASE_CHANNEL_CLASS ( + salut_tube_stream_parent_class); + + cls->fill_immutable_properties (chan, properties); + + tp_dbus_properties_mixin_fill_properties_hash ( + G_OBJECT (chan), properties, + TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "Service", + TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "SupportedSocketTypes", + NULL); + + if (!tp_base_channel_is_requested (chan)) + { + tp_dbus_properties_mixin_fill_properties_hash ( + G_OBJECT (chan), properties, + TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters", + NULL); + } +} + +static gchar * +salut_tube_stream_get_object_path_suffix (TpBaseChannel *base) +{ + SalutTubeStream *self = SALUT_TUBE_STREAM (base); + SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + + return g_strdup_printf ("StreamTubeChannel/%u/%u", + tp_base_channel_get_target_handle (base), + priv->id); +} + +static void +salut_tube_stream_close_dbus (TpBaseChannel *base) +{ + salut_tube_iface_close ((SalutTubeIface *) base, FALSE); +} + static void salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class) { - static TpDBusPropertiesMixinPropImpl channel_props[] = { - { "TargetHandleType", "handle-type", NULL }, - { "TargetHandle", "handle", NULL }, - { "ChannelType", "channel-type", NULL }, - { "TargetID", "target-id", NULL }, - { "Interfaces", "interfaces", NULL }, - { "Requested", "requested", NULL }, - { "InitiatorHandle", "initiator-handle", NULL }, - { "InitiatorID", "initiator-id", NULL }, - { NULL } - }; static TpDBusPropertiesMixinPropImpl stream_tube_props[] = { { "Service", "service", NULL }, { "SupportedSocketTypes", "supported-socket-types", NULL }, @@ -1415,11 +1306,6 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class) { NULL } }; static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { - { TP_IFACE_CHANNEL, - tp_dbus_properties_mixin_getter_gobject_properties, - NULL, - channel_props, - }, { TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, tp_dbus_properties_mixin_getter_gobject_properties, NULL, @@ -1434,34 +1320,36 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class) }; GObjectClass *object_class = G_OBJECT_CLASS (salut_tube_stream_class); + TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (salut_tube_stream_class); GParamSpec *param_spec; object_class->get_property = salut_tube_stream_get_property; object_class->set_property = salut_tube_stream_set_property; object_class->constructor = salut_tube_stream_constructor; + base_class->channel_type = TP_IFACE_CHANNEL_TYPE_STREAM_TUBE; + base_class->interfaces = salut_tube_stream_interfaces; + base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT; + base_class->close = salut_tube_stream_close_dbus; + base_class->fill_immutable_properties = + salut_tube_stream_fill_immutable_properties; + base_class->get_object_path_suffix = + salut_tube_stream_get_object_path_suffix; + g_type_class_add_private (salut_tube_stream_class, sizeof (SalutTubeStreamPrivate)); object_class->dispose = salut_tube_stream_dispose; object_class->finalize = salut_tube_stream_finalize; - g_object_class_override_property (object_class, PROP_CONNECTION, - "connection"); g_object_class_override_property (object_class, PROP_TUBES_CHANNEL, "tubes-channel"); - g_object_class_override_property (object_class, PROP_HANDLE, - "handle"); - g_object_class_override_property (object_class, PROP_HANDLE_TYPE, - "handle-type"); g_object_class_override_property (object_class, PROP_SELF_HANDLE, "self-handle"); g_object_class_override_property (object_class, PROP_ID, "id"); g_object_class_override_property (object_class, PROP_TYPE, "type"); - g_object_class_override_property (object_class, PROP_INITIATOR_HANDLE, - "initiator-handle"); g_object_class_override_property (object_class, PROP_SERVICE, "service"); g_object_class_override_property (object_class, PROP_PARAMETERS, @@ -1469,23 +1357,6 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class) g_object_class_override_property (object_class, PROP_STATE, "state"); - g_object_class_override_property (object_class, PROP_OBJECT_PATH, - "object-path"); - g_object_class_override_property (object_class, PROP_CHANNEL_TYPE, - "channel-type"); - - g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED, - "channel-destroyed"); - g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES, - "channel-properties"); - - param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces", - "Additional Channel.Interface.* interfaces", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME); - g_object_class_install_property (object_class, PROP_INTERFACES, param_spec); - param_spec = g_param_spec_uint ( "address-type", "address type", @@ -1525,13 +1396,6 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class) g_object_class_install_property (object_class, PROP_ACCESS_CONTROL_PARAM, param_spec); - param_spec = g_param_spec_string ("target-id", "Target JID", - "The string obtained by inspecting the target handle", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME); - g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec); - param_spec = g_param_spec_uint ( "port", "port on the initiator's CM", @@ -1565,19 +1429,6 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class) G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_OFFERED, param_spec); - param_spec = g_param_spec_string ("initiator-id", "Initiator's bare JID", - "The string obtained by inspecting the initiator-handle", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INITIATOR_ID, - param_spec); - - param_spec = g_param_spec_boolean ("requested", "Requested?", - "True if this channel was requested by the local user", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_REQUESTED, param_spec); - param_spec = g_param_spec_boxed ( "supported-socket-types", "Supported socket types", @@ -1681,20 +1532,19 @@ salut_tube_stream_new (SalutConnection *conn, GHashTable *parameters, guint id, guint portnum, - WockyStanza *iq_req) + WockyStanza *iq_req, + gboolean requested) { SalutTubeStream *obj; - char *object_path; + GType gtype = SALUT_TYPE_TUBE_STREAM; - object_path = g_strdup_printf ("%s/StreamTubeChannel_%u_%u", - conn->parent.object_path, handle, id); + if (handle_type == TP_HANDLE_TYPE_ROOM) + gtype = SALUT_TYPE_MUC_TUBE_STREAM; - obj = g_object_new (SALUT_TYPE_TUBE_STREAM, + obj = g_object_new (gtype, "connection", conn, "tubes-channel", tubes_channel, - "object-path", object_path, "handle", handle, - "handle-type", handle_type, "self-handle", self_handle, "initiator-handle", initiator, "offered", offered, @@ -1703,10 +1553,9 @@ salut_tube_stream_new (SalutConnection *conn, "id", id, "port", portnum, "iq-req", iq_req, + "requested", requested, NULL); - g_free (object_path); - return obj; } @@ -1721,6 +1570,10 @@ salut_tube_stream_accept (SalutTubeIface *tube, { SalutTubeStream *self = SALUT_TUBE_STREAM (tube); SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + SalutConnection *conn = SALUT_CONNECTION (base_conn); WockyStanza *reply; if (priv->state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING) @@ -1732,10 +1585,10 @@ salut_tube_stream_accept (SalutTubeIface *tube, return FALSE; } - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { reply = wocky_stanza_build_iq_result (priv->iq_req, NULL); - wocky_porter_send (priv->conn->porter, reply); + wocky_porter_send (conn->porter, reply); g_object_unref (priv->iq_req); priv->iq_req = NULL; @@ -1798,29 +1651,34 @@ contact_new_connection_cb (GibberListener *listener, gpointer user_data) { SalutTubeStream *self = SALUT_TUBE_STREAM (user_data); - SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + SalutConnection *conn = SALUT_CONNECTION (base_conn); GibberBytestreamIface *bytestream; SalutContactManager *contact_mgr; SalutContact *contact; - g_assert (priv->handle_type == TP_HANDLE_TYPE_CONTACT); + g_assert (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT); - g_object_get (priv->conn, + g_object_get (conn, "contact-manager", &contact_mgr, NULL); g_assert (contact_mgr != NULL); - contact = salut_contact_manager_get_contact (contact_mgr, priv->handle); + contact = salut_contact_manager_get_contact (contact_mgr, + tp_base_channel_get_target_handle (base)); if (contact == NULL) { - DEBUG ("can't find contact with handle %d", priv->handle); + DEBUG ("can't find contact with handle %d", + tp_base_channel_get_target_handle (base)); g_object_unref (contact_mgr); return; } bytestream = g_object_new (GIBBER_TYPE_BYTESTREAM_DIRECT, "state", GIBBER_BYTESTREAM_STATE_LOCAL_PENDING, - "self-id", priv->conn->name, + "self-id", conn->name, "peer-id", contact->name, NULL); @@ -1889,22 +1747,25 @@ salut_tube_stream_close (SalutTubeIface *tube, gboolean closed_remotely) { SalutTubeStream *self = SALUT_TUBE_STREAM (tube); SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + SalutConnection *conn = SALUT_CONNECTION (base_conn); - if (priv->closed) + if (tp_base_channel_is_destroyed (base)) return; - priv->closed = TRUE; g_hash_table_foreach_remove (priv->bytestream_to_transport, close_each_extra_bytestream, self); /* do not send the close stanza if the tube was closed due to the remote * contact */ - if (!closed_remotely && priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (!closed_remotely && cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { WockyStanza *stanza; const gchar *jid_from; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); + base_conn, TP_HANDLE_TYPE_CONTACT); gchar *tube_id_str; SalutContactManager *contact_mgr; SalutContact *contact; @@ -1912,11 +1773,11 @@ salut_tube_stream_close (SalutTubeIface *tube, gboolean closed_remotely) jid_from = tp_handle_inspect (contact_repo, priv->self_handle); tube_id_str = g_strdup_printf ("%u", priv->id); - g_object_get (priv->conn, "contact-manager", &contact_mgr, NULL); + g_object_get (conn, "contact-manager", &contact_mgr, NULL); g_assert (contact_mgr != NULL); contact = salut_contact_manager_get_contact (contact_mgr, - priv->handle); + tp_base_channel_get_target_handle (base)); stanza = wocky_stanza_build_to_contact (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, @@ -1926,7 +1787,7 @@ salut_tube_stream_close (SalutTubeIface *tube, gboolean closed_remotely) '@', "id", tube_id_str, ')', NULL); - wocky_porter_send_iq_async (priv->conn->porter, stanza, + wocky_porter_send_iq_async (conn->porter, stanza, NULL, iq_close_reply_cb, tube); g_free (tube_id_str); @@ -1936,19 +1797,26 @@ salut_tube_stream_close (SalutTubeIface *tube, gboolean closed_remotely) g_object_unref (contact_mgr); } - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { - if (priv->initiator == priv->self_handle) + if (priv->contact_listener != NULL) { - if (priv->contact_listener != NULL) - { - g_object_unref (priv->contact_listener); - priv->contact_listener = NULL; - } + g_object_unref (priv->contact_listener); + priv->contact_listener = NULL; } } + /* Take a ref to ourselves as when we emit tube-closed + * SalutTubesChannel will drop our last ref but we still need to + * declare ourselves as destroyed. this is rubbish, but will + * disappear when we finally remove the Tubes channel type. */ + g_object_ref (self); + g_signal_emit (G_OBJECT (self), signals[CLOSED], 0); + + tp_base_channel_destroyed (base); + + g_object_unref (self); } static void @@ -1969,9 +1837,11 @@ salut_tube_stream_add_bytestream (SalutTubeIface *tube, { SalutTubeStream *self = SALUT_TUBE_STREAM (tube); SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); GibberTransport *transport; - if (priv->initiator != priv->self_handle) + if (!tp_base_channel_is_requested (base)) { DEBUG ("I'm not the initiator of this tube, can't accept " "an extra bytestream"); @@ -1987,7 +1857,7 @@ salut_tube_stream_add_bytestream (SalutTubeIface *tube, TpHandle contact; gchar *peer_id; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); + base_conn, TP_HANDLE_TYPE_CONTACT); if (priv->state == TP_TUBE_CHANNEL_STATE_REMOTE_PENDING) { @@ -2314,7 +2184,7 @@ salut_tube_stream_accept_async (TpSvcChannelTypeStreamTube *iface, #if 0 /* TODO: add a property "muc" and set it at initialization */ - if (priv->handle_type == TP_HANDLE_TYPE_ROOM) + if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM) salut_muc_channel_send_presence (self->muc, NULL); #endif @@ -2322,77 +2192,6 @@ salut_tube_stream_accept_async (TpSvcChannelTypeStreamTube *iface, priv->address); } -/** - * salut_tube_stream_close_async: - * - * Implements D-Bus method Close - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_stream_close_async (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - salut_tube_stream_close (SALUT_TUBE_IFACE (iface), FALSE); - tp_svc_channel_return_from_close (context); -} - -/** - * salut_tube_stream_get_channel_type - * - * Implements D-Bus method GetChannelType - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_stream_get_channel_type (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - tp_svc_channel_return_from_get_channel_type (context, - TP_IFACE_CHANNEL_TYPE_STREAM_TUBE); -} - -/** - * salut_tube_stream_get_handle - * - * Implements D-Bus method GetHandle - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_stream_get_handle (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - SalutTubeStream *self = SALUT_TUBE_STREAM (iface); - SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); - - tp_svc_channel_return_from_get_handle (context, priv->handle_type, - priv->handle); -} - -/** - * salut_tube_stream_get_interfaces - * - * Implements D-Bus method GetInterfaces - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tube_stream_get_interfaces (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - SalutTubeStream *self = SALUT_TUBE_STREAM (iface); - SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); - - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - { - /* omit the Group interface */ - tp_svc_channel_return_from_get_interfaces (context, - salut_tube_stream_interfaces + 1); - } - else - { - tp_svc_channel_return_from_get_interfaces (context, - salut_tube_stream_interfaces); - } -} - static void destroy_socket_control_list (gpointer data) { @@ -2442,10 +2241,12 @@ salut_tube_stream_offer (SalutTubeStream *self, GError **error) { SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); g_assert (priv->state == TP_TUBE_CHANNEL_STATE_NOT_OFFERED); - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { priv->state = TP_TUBE_CHANNEL_STATE_REMOTE_PENDING; salut_tubes_channel_send_iq_offer (priv->tubes_channel); @@ -2499,18 +2300,3 @@ streamtube_iface_init (gpointer g_iface, IMPLEMENT(accept,_async); #undef IMPLEMENT } - -static void -channel_iface_init (gpointer g_iface, - gpointer iface_data) -{ - TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface; - -#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\ - klass, salut_tube_stream_##x##suffix) - IMPLEMENT(close,_async); - IMPLEMENT(get_channel_type,); - IMPLEMENT(get_handle,); - IMPLEMENT(get_interfaces,); -#undef IMPLEMENT -} diff --git a/src/tube-stream.h b/src/tube-stream.h index fb908590..f3d0fd0a 100644 --- a/src/tube-stream.h +++ b/src/tube-stream.h @@ -22,6 +22,7 @@ #include +#include #include #include @@ -35,13 +36,13 @@ typedef struct _SalutTubeStream SalutTubeStream; typedef struct _SalutTubeStreamClass SalutTubeStreamClass; struct _SalutTubeStreamClass { - GObjectClass parent_class; + TpBaseChannelClass parent_class; TpDBusPropertiesMixinClass dbus_props_class; }; struct _SalutTubeStream { - GObject parent; + TpBaseChannel parent; gpointer priv; }; @@ -70,7 +71,7 @@ SalutTubeStream *salut_tube_stream_new (SalutConnection *conn, TpHandleType handle_type, TpHandle self_handle, TpHandle initiator, gboolean offered, const gchar *service, GHashTable *parameters, guint id, guint portnum, - WockyStanza *iq_req); + WockyStanza *iq_req, gboolean requested); gboolean salut_tube_stream_check_params (TpSocketAddressType address_type, const GValue *address, TpSocketAccessControl access_control, diff --git a/src/tubes-channel.c b/src/tubes-channel.c index 77b5c7cd..be9d6186 100644 --- a/src/tubes-channel.c +++ b/src/tubes-channel.c @@ -1150,19 +1150,19 @@ create_new_tube (SalutTubesChannel *self, tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, self, priv->handle, priv->handle_type, priv->self_handle, muc_connection, initiator, service, parameters, tube_id, requested)); - - tp_base_channel_register ((TpBaseChannel *) tube); break; case TP_TUBE_TYPE_STREAM: tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, self, priv->handle, priv->handle_type, priv->self_handle, initiator, offered, service, parameters, - tube_id, portnum, iq_req)); + tube_id, portnum, iq_req, requested)); break; default: g_assert_not_reached (); } + tp_base_channel_register ((TpBaseChannel *) tube); + DEBUG ("create tube %u", tube_id); g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), tube); -- cgit v1.2.1 From 0b6256963b13dfdbc8618d77c9565d02016487ac Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 25 May 2012 17:24:54 +0100 Subject: tubes-manager: create only Tube channels for requests Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 274 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 184 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 3fc6bfc7..1b1b6e03 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -49,6 +49,7 @@ #include "self.h" #include "util.h" #include "tube-iface.h" +#include "tube-dbus.h" #include "tube-stream.h" @@ -91,6 +92,9 @@ struct _SalutTubesManagerPrivate GHashTable *tubes_channels; + /* guint tube ID => (owned) (SalutTubeIface *) */ + GHashTable *tubes; + gboolean dispose_has_run; }; @@ -108,6 +112,9 @@ salut_tubes_manager_init (SalutTubesManager *self) priv->tubes_channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_object_unref); + priv->conn = NULL; priv->dispose_has_run = FALSE; } @@ -408,14 +415,8 @@ salut_tubes_manager_close_all (SalutTubesManager *self) priv->status_changed_id = 0; } - if (priv->tubes_channels != NULL) - { - GHashTable *tmp; - - tmp = priv->tubes_channels; - priv->tubes_channels = NULL; - g_hash_table_unref (tmp); - } + tp_clear_pointer (&priv->tubes_channels, g_hash_table_unref); + tp_clear_pointer (&priv->tubes, g_hash_table_unref); } static void @@ -692,6 +693,12 @@ salut_tubes_manager_foreach_channel (TpChannelManager *manager, salut_tubes_channel_foreach (SALUT_TUBES_CHANNEL (chan), foreach, user_data); } + + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + foreach (TP_EXPORTABLE_CHANNEL (value), user_data); + } } static const gchar * const tubes_channel_fixed_properties[] = { @@ -730,24 +737,6 @@ salut_tubes_manager_type_foreach_channel_class (GType type, GHashTable *table; GValue *value; - /* 1-1 Channel.Type.Tubes */ - table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, - (GDestroyNotify) tp_g_value_slice_free); - - value = tp_g_value_slice_new (G_TYPE_STRING); - g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_TUBES); - g_hash_table_insert (table, TP_IFACE_CHANNEL ".ChannelType", - value); - - value = tp_g_value_slice_new (G_TYPE_UINT); - g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT); - g_hash_table_insert (table, TP_IFACE_CHANNEL ".TargetHandleType", - value); - - func (type, table, old_tubes_channel_allowed_properties, user_data); - - g_hash_table_unref (table); - /* 1-1 Channel.Type.StreamTube */ table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); @@ -789,6 +778,149 @@ salut_tubes_manager_type_foreach_channel_class (GType type, #endif } +static SalutTubeIface * +salut_tubes_manager_lookup (SalutTubesManager *self, + const gchar *type, + TpHandle handle, + const gchar *service) +{ + SalutTubesManagerPrivate *priv = + SALUT_TUBES_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + gpointer value; + + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + SalutTubeIface *tube = value; + gboolean match = FALSE; + + gchar *channel_type, *channel_service; + TpHandle channel_handle; + + g_object_get (tube, + "channel-type", &channel_type, + "handle", &channel_handle, + "service", &channel_service, + NULL); + + if (!tp_strdiff (type, channel_type) + && handle == channel_handle + && !tp_strdiff (service, channel_service)) + match = FALSE; + + g_free (channel_type); + g_free (channel_service); + + if (match) + return tube; + } + + return NULL; +} + +static void +channel_closed_cb (SalutTubeIface *tube, + SalutTubesManager *self) +{ + SalutTubesManagerPrivate *priv = + SALUT_TUBES_MANAGER_GET_PRIVATE (self); + guint id; + + g_object_get (tube, + "id", &id, + NULL); + + tp_channel_manager_emit_channel_closed_for_object (self, + TP_EXPORTABLE_CHANNEL (tube)); + + if (priv->tubes != NULL) + g_hash_table_remove (priv->tubes, GUINT_TO_POINTER (id)); +} + +static guint +generate_tube_id (SalutTubesManager *self) +{ + SalutTubesManagerPrivate *priv = + SALUT_TUBES_MANAGER_GET_PRIVATE (self); + guint out; + + /* probably totally overkill */ + do + { + out = g_random_int_range (0, G_MAXINT); + } + while (g_hash_table_lookup (priv->tubes, + GUINT_TO_POINTER (out)) != NULL); + + return out; +} + +static SalutTubeIface * +new_channel_from_request (SalutTubesManager *self, + GHashTable *request) +{ + SalutTubesManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + SALUT_TYPE_TUBES_MANAGER, SalutTubesManagerPrivate); + TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn); + SalutTubeIface *tube; + + const gchar *ctype, *service; + TpHandle handle; + TpHandleType handle_type; + guint tube_id; + GHashTable *parameters; + + ctype = tp_asv_get_string (request, TP_PROP_CHANNEL_CHANNEL_TYPE); + handle = tp_asv_get_uint32 (request, TP_PROP_CHANNEL_TARGET_HANDLE, NULL); + handle_type = tp_asv_get_uint32 (request, + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL); + + tube_id = generate_tube_id (self); + + /* requested tubes have an empty parameters dict */ + parameters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify) tp_g_value_slice_free); + + if (!tp_strdiff (ctype, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) + { + service = tp_asv_get_string (request, + TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE); + + tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, NULL, + handle, handle_type, + base_conn->self_handle, base_conn->self_handle, FALSE, service, + parameters, tube_id, 0, NULL, TRUE)); + + tube = SALUT_TUBE_IFACE (NULL); + } + else if (!tp_strdiff (ctype, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) + { + service = tp_asv_get_string (request, + TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME); + + tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, NULL, + handle, handle_type, base_conn->self_handle, NULL, + base_conn->self_handle, service, parameters, tube_id, TRUE)); + } + else + { + g_return_val_if_reached (NULL); + } + + tp_base_channel_register ((TpBaseChannel *) tube); + + g_signal_connect (tube, "closed", + G_CALLBACK (channel_closed_cb), self); + + g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), + tube); + + g_hash_table_unref (parameters); + + return tube; +} + static gboolean salut_tubes_manager_requestotron (SalutTubesManager *self, gpointer request_token, @@ -803,8 +935,10 @@ salut_tubes_manager_requestotron (SalutTubesManager *self, TpHandle handle; GError *error = NULL; const gchar *channel_type; - SalutTubesChannel *tubes_channel; const gchar *service = NULL; + SalutTubeIface *new_channel; + GSList *tokens = NULL; + GHashTable *channels; if (tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_CONTACT) @@ -813,21 +947,13 @@ salut_tubes_manager_requestotron (SalutTubesManager *self, channel_type = tp_asv_get_string (request_properties, TP_IFACE_CHANNEL ".ChannelType"); - if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES) && + if ( /* Temporarily disabled since the implementation is incomplete. */ /* tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE) && */ tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) return FALSE; - if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES)) - { - if (tp_channel_manager_asv_has_unknown_properties (request_properties, - tubes_channel_fixed_properties, - old_tubes_channel_allowed_properties, - &error)) - goto error; - } - else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) + if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) { if (tp_channel_manager_asv_has_unknown_properties (request_properties, tubes_channel_fixed_properties, @@ -894,74 +1020,42 @@ salut_tubes_manager_requestotron (SalutTubesManager *self, goto error; } - tubes_channel = g_hash_table_lookup (priv->tubes_channels, - GUINT_TO_POINTER (handle)); + new_channel = salut_tubes_manager_lookup (self, channel_type, + handle, service); - if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES)) + if (new_channel == NULL) { - if (tubes_channel == NULL) - { - GSList *tokens = NULL; - - tubes_channel = new_tubes_channel (self, handle, - base_conn->self_handle, request_token, TRUE, &error); - - if (tubes_channel == NULL) - goto error; + new_channel = new_channel_from_request (self, + request_properties); + g_assert (new_channel != NULL); - tokens = g_slist_prepend (tokens, request_token); + channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, NULL); - tp_channel_manager_emit_new_channel (self, - TP_EXPORTABLE_CHANNEL (tubes_channel), tokens); + if (request_token != NULL) + tokens = g_slist_prepend (NULL, request_token); - g_slist_free (tokens); - return TRUE; - } + g_hash_table_insert (channels, new_channel, tokens); + tp_channel_manager_emit_new_channels (self, channels); + g_hash_table_unref (channels); + g_slist_free (tokens); + } + else + { if (require_new) { g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "A tube channel with contact #%u already exists", handle); - DEBUG ("A tube channel with contact #%u already exists", handle); + "A channel to #%u (service: %s) is already open", + handle, service); goto error; } tp_channel_manager_emit_request_already_satisfied (self, - request_token, TP_EXPORTABLE_CHANNEL (tubes_channel)); - return TRUE; + request_token, TP_EXPORTABLE_CHANNEL (new_channel)); } - else - { - SalutTubeIface *new_channel; - GSList *tokens = NULL; - GHashTable *channels; - - if (tubes_channel == NULL) - { - tubes_channel = new_tubes_channel (self, handle, - base_conn->self_handle, NULL, FALSE, &error); - if (tubes_channel == NULL) - goto error; - } - new_channel = salut_tubes_channel_tube_request (tubes_channel, - request_token, request_properties, require_new); - g_assert (new_channel != NULL); - - if (request_token != NULL) - tokens = g_slist_prepend (NULL, request_token); - - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); - g_hash_table_insert (channels, tubes_channel, NULL); - g_hash_table_insert (channels, new_channel, tokens); - - tp_channel_manager_emit_new_channels (self, channels); - - g_hash_table_unref (channels); - g_slist_free (tokens); - return TRUE; - } + return TRUE; error: tp_channel_manager_emit_request_failed (self, request_token, -- cgit v1.2.1 From 05f0814132b5fcf2119017dfea72a2c40a3f79ec Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 25 May 2012 17:27:36 +0100 Subject: tubes-manager: stop adding caps for Tubes channels Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 1b1b6e03..7a5d02bc 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -1309,8 +1309,7 @@ gabble_private_tubes_factory_add_cap (GabbleCapsChannelManager *manager, TP_IFACE_CHANNEL ".ChannelType"); /* this channel is not for this factory */ - if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES) && - tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE) && + if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE) && tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) return; -- cgit v1.2.1 From b5ee1159b0a10ba187bb1ddb604febe6ebdf0e7e Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 25 May 2012 17:29:35 +0100 Subject: muc-manager: remove Tubes channel handling code Signed-off-by: Jonny Lamb --- src/muc-manager.c | 38 -------------------------------------- src/tubes-manager.c | 2 -- 2 files changed, 40 deletions(-) (limited to 'src') diff --git a/src/muc-manager.c b/src/muc-manager.c index 5f3f24d4..c502c92d 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -841,12 +841,10 @@ salut_muc_manager_request (SalutMucManager *self, gboolean require_new) { SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); - TpBaseConnection *base_conn = (TpBaseConnection *) priv->connection; GError *error = NULL; TpHandle handle; const gchar *channel_type; SalutMucChannel *text_chan; - SalutTubesChannel *tubes_chan; if (tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_ROOM) @@ -856,7 +854,6 @@ salut_muc_manager_request (SalutMucManager *self, TP_IFACE_CHANNEL ".ChannelType"); if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT) && - tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES) && tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE) && tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) return FALSE; @@ -896,41 +893,6 @@ salut_muc_manager_request (SalutMucManager *self, handle, request_token, TRUE, NULL); } - return TRUE; - } - else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES)) - { - if (tp_channel_manager_asv_has_unknown_properties (request_properties, - muc_tubes_channel_fixed_properties, - muc_tubes_channel_allowed_properties, - &error)) - goto error; - - tubes_chan = g_hash_table_lookup (priv->tubes_channels, - GUINT_TO_POINTER (handle)); - - if (tubes_chan != NULL) - { - if (require_new) - { - g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "That channel has already been created (or requested)"); - goto error; - } - else - { - tp_channel_manager_emit_request_already_satisfied (self, - request_token, TP_EXPORTABLE_CHANNEL (tubes_chan)); - } - } - else - { - tubes_chan = create_tubes_channel (self, handle, - base_conn->self_handle, request_token, TRUE, NULL, TRUE, &error); - if (tubes_chan == NULL) - goto error; - } - return TRUE; } else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 7a5d02bc..68ab4736 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -891,8 +891,6 @@ new_channel_from_request (SalutTubesManager *self, handle, handle_type, base_conn->self_handle, base_conn->self_handle, FALSE, service, parameters, tube_id, 0, NULL, TRUE)); - - tube = SALUT_TUBE_IFACE (NULL); } else if (!tp_strdiff (ctype, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) { -- cgit v1.2.1 From a54df636478156095a76548c1a2fc2130282b74b Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 25 May 2012 17:32:39 +0100 Subject: muc-manager: store Tube channels here Signed-off-by: Jonny Lamb --- src/muc-manager.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/muc-manager.c b/src/muc-manager.c index c502c92d..f160a994 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -87,6 +87,9 @@ struct _SalutMucManagerPrivate /* GUINT_TO_POINTER(room_handle) => (SalutTubesChannel *) */ GHashTable *tubes_channels; + /* tube ID => owned SalutTubeIface */ + GHashTable *tubes; + gboolean dispose_has_run; }; @@ -163,19 +166,8 @@ salut_muc_manager_close_all (SalutMucManager *self) priv->status_changed_id = 0; } - if (priv->text_channels) - { - GHashTable *tmp = priv->text_channels; - priv->text_channels = NULL; - g_hash_table_unref (tmp); - } - - if (priv->tubes_channels != NULL) - { - GHashTable *tmp = priv->tubes_channels; - priv->tubes_channels = NULL; - g_hash_table_unref (tmp); - } + tp_clear_pointer (&priv->text_channels, g_hash_table_unref); + tp_clear_pointer (&priv->tubes_channels, g_hash_table_unref); } static void -- cgit v1.2.1 From f60a51b46c64e5db8469cd9e89a7107de4454be3 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 29 May 2012 11:18:06 +0100 Subject: muc-channel: add way to request single Tube channels Signed-off-by: Jonny Lamb --- src/muc-channel.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/muc-channel.h | 4 ++ src/muc-manager.c | 21 ++++++++ 3 files changed, 177 insertions(+) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index 38bf002f..d403a851 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -53,6 +53,7 @@ #include "text-helper.h" #include "tube-stream.h" +#include "tube-dbus.h" G_DEFINE_TYPE_WITH_CODE(SalutMucChannel, salut_muc_channel, TP_TYPE_BASE_CHANNEL, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP, @@ -74,6 +75,7 @@ enum { READY, JOIN_ERROR, + NEW_TUBE, LAST_SIGNAL }; @@ -100,6 +102,8 @@ struct _SalutMucChannelPrivate /* (gchar *) -> (SalutContact *) */ GHashTable *senders; SalutMucManager *muc_manager; + + GHashTable *tubes; }; /* Callback functions */ @@ -306,6 +310,9 @@ salut_muc_channel_constructed (GObject *obj) TP_CHANNEL_GROUP_FLAG_CAN_ADD | TP_CHANNEL_GROUP_FLAG_MESSAGE_ADD, 0); + + priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_object_unref); } static void @@ -693,6 +700,17 @@ salut_muc_channel_class_init (SalutMucChannelClass *salut_muc_channel_class) g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[NEW_TUBE] = g_signal_new ( + "new-tube", + G_OBJECT_CLASS_TYPE (salut_muc_channel_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + /* this should be SALUT_TYPE_TUBE_IFACE but GObject + * wants a value type, not an interface. */ + G_TYPE_NONE, 1, TP_TYPE_BASE_CHANNEL); + tp_group_mixin_class_init (object_class, G_STRUCT_OFFSET(SalutMucChannelClass, group_class), salut_muc_channel_add_member, NULL); @@ -737,6 +755,8 @@ salut_muc_channel_dispose (GObject *object) priv->senders = NULL; } + tp_clear_pointer (&priv->tubes, g_hash_table_unref); + /* release any references held by the object here */ if (G_OBJECT_CLASS (salut_muc_channel_parent_class)->dispose) G_OBJECT_CLASS (salut_muc_channel_parent_class)->dispose (object); @@ -1146,3 +1166,135 @@ error: return; } +static void +tube_closed_cb (SalutTubeIface *tube, + SalutMucChannel *self) +{ + SalutMucChannelPrivate *priv = self->priv; + guint id; + + g_object_get (tube, + "id", &id, + NULL); + + if (priv->tubes != NULL) + g_hash_table_remove (priv->tubes, GUINT_TO_POINTER (id)); +} + +static guint +generate_tube_id (SalutMucChannel *self) +{ + SalutMucChannelPrivate *priv = self->priv; + guint out; + + /* probably totally overkill */ + do + { + out = g_random_int_range (0, G_MAXINT); + } + while (g_hash_table_lookup (priv->tubes, + GUINT_TO_POINTER (out)) != NULL); + + return out; +} + +static SalutTubeIface * +create_new_tube (SalutMucChannel *self, + TpTubeType type, + TpHandle initiator, + const gchar *service, + GHashTable *parameters, + guint tube_id, + guint portnum, + WockyStanza *iq_req, + gboolean requested) +{ + SalutMucChannelPrivate *priv = self->priv; + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + SalutConnection *conn = SALUT_CONNECTION (base_conn); + TpHandle self_handle = TP_GROUP_MIXIN (self)->self_handle; + TpHandle handle = tp_base_channel_get_target_handle (base); + SalutTubeIface *tube; + + switch (type) + { + case TP_TUBE_TYPE_DBUS: + tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (conn, NULL, + handle, TP_HANDLE_TYPE_ROOM, self_handle, priv->muc_connection, + initiator, service, parameters, tube_id, requested)); + break; + case TP_TUBE_TYPE_STREAM: + tube = SALUT_TUBE_IFACE (salut_tube_stream_new (conn, NULL, + handle, TP_HANDLE_TYPE_ROOM, + self_handle, initiator, FALSE, service, + parameters, tube_id, portnum, iq_req, requested)); + break; + default: + g_return_val_if_reached (NULL); + } + + tp_base_channel_register ((TpBaseChannel *) tube); + + DEBUG ("create tube %u", tube_id); + g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), tube); + + g_signal_connect (tube, "closed", G_CALLBACK (tube_closed_cb), self); + + return tube; +} + +SalutTubeIface * +salut_muc_channel_tube_request (SalutMucChannel *self, + GHashTable *request_properties) +{ + SalutTubeIface *tube; + const gchar *channel_type; + const gchar *service; + GHashTable *parameters = NULL; + guint tube_id; + TpTubeType type; + + tube_id = generate_tube_id (self); + + channel_type = tp_asv_get_string (request_properties, + TP_PROP_CHANNEL_CHANNEL_TYPE); + + if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) + { + type = TP_TUBE_TYPE_STREAM; + service = tp_asv_get_string (request_properties, + TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE); + + } + else if (! tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) + { + type = TP_TUBE_TYPE_DBUS; + service = tp_asv_get_string (request_properties, + TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME); + } + else + /* This assertion is safe: this function's caller only calls it in one of + * the above cases. + * FIXME: but it would be better to pass an enum member or something maybe. + */ + g_assert_not_reached (); + + /* requested tubes have an empty parameters dict */ + parameters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify) tp_g_value_slice_free); + + /* if the service property is missing, the requestotron rejects the request + */ + g_assert (service != NULL); + + DEBUG ("Request a tube channel with type='%s' and service='%s'", + channel_type, service); + + tube = create_new_tube (self, type, TP_GROUP_MIXIN (self)->self_handle, + service, parameters, tube_id, 0, NULL, TRUE); + g_hash_table_unref (parameters); + + return tube; +} + diff --git a/src/muc-channel.h b/src/muc-channel.h index 3bb01f04..79787af4 100644 --- a/src/muc-channel.h +++ b/src/muc-channel.h @@ -30,6 +30,7 @@ #include #include "connection.h" +#include "tube-iface.h" G_BEGIN_DECLS @@ -89,6 +90,9 @@ gboolean salut_muc_channel_publish_service (SalutMucChannel *self); gboolean salut_muc_channel_add_member (GObject *iface, TpHandle handle, const gchar *message, GError **error); +SalutTubeIface * salut_muc_channel_tube_request (SalutMucChannel *self, + GHashTable *request_properties); + G_END_DECLS #endif /* #ifndef __SALUT_MUC_CHANNEL_H__*/ diff --git a/src/muc-manager.c b/src/muc-manager.c index f160a994..6e0b4b43 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -444,6 +444,26 @@ tubes_channel_closed_cb (SalutTubesChannel *chan, } } +static void +muc_channel_tube_closed_cb (SalutTubeIface *tube, + SalutMucManager *mgr) +{ + tp_channel_manager_emit_channel_closed_for_object (mgr, + TP_EXPORTABLE_CHANNEL (tube)); +} + +static void +muc_channel_new_tube_cb (SalutMucChannel *channel, + SalutTubeIface *tube, + SalutMucManager *mgr) +{ + tp_channel_manager_emit_new_channel (mgr, + TP_EXPORTABLE_CHANNEL (tube), NULL); + + g_signal_connect (tube, "closed", + G_CALLBACK (muc_channel_tube_closed_cb), mgr); +} + static GibberMucConnection * _get_connection (SalutMucManager *mgr, const gchar *protocol, @@ -490,6 +510,7 @@ salut_muc_manager_new_muc_channel (SalutMucManager *mgr, tp_base_channel_register ((TpBaseChannel *) chan); g_signal_connect (chan, "closed", G_CALLBACK (muc_channel_closed_cb), mgr); + g_signal_connect (chan, "new-tube", G_CALLBACK (muc_channel_new_tube_cb), mgr); g_hash_table_insert (priv->text_channels, GUINT_TO_POINTER (handle), chan); -- cgit v1.2.1 From 4b1bccbb832805a55722f92d9cdb8ff3aa45d75d Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 29 May 2012 13:24:09 +0100 Subject: muc-channel: do foreach over muc channel tube channels again These have been stored in the Tubes channel before. No longer! Signed-off-by: Jonny Lamb --- src/muc-channel.c | 15 +++++++++++++++ src/muc-channel.h | 3 +++ src/muc-manager.c | 32 +++++++++++--------------------- 3 files changed, 29 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index d403a851..6af58488 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -1298,3 +1298,18 @@ salut_muc_channel_tube_request (SalutMucChannel *self, return tube; } +void +salut_muc_channel_foreach (SalutMucChannel *self, + TpExportableChannelFunc func, + gpointer user_data) +{ + SalutMucChannelPrivate *priv = self->priv; + GHashTableIter iter; + gpointer value; + + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + func (TP_EXPORTABLE_CHANNEL (value), user_data); + } +} diff --git a/src/muc-channel.h b/src/muc-channel.h index 79787af4..47abcb5f 100644 --- a/src/muc-channel.h +++ b/src/muc-channel.h @@ -93,6 +93,9 @@ gboolean salut_muc_channel_add_member (GObject *iface, TpHandle handle, SalutTubeIface * salut_muc_channel_tube_request (SalutMucChannel *self, GHashTable *request_properties); +void salut_muc_channel_foreach (SalutMucChannel *self, + TpExportableChannelFunc func, gpointer user_data); + G_END_DECLS #endif /* #ifndef __SALUT_MUC_CHANNEL_H__*/ diff --git a/src/muc-manager.c b/src/muc-manager.c index 6e0b4b43..c6be2140 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -271,23 +271,6 @@ salut_muc_manager_dispose (GObject *object) /* Channel Manager interface */ -struct _ForeachData -{ - TpExportableChannelFunc foreach; - gpointer user_data; -}; - -static void -_foreach_slave (gpointer key, - gpointer value, - gpointer user_data) -{ - struct _ForeachData *data = (struct _ForeachData *) user_data; - TpExportableChannel *channel = TP_EXPORTABLE_CHANNEL (value); - - data->foreach (channel, data->user_data); -} - static void salut_muc_manager_foreach_channel (TpChannelManager *iface, TpExportableChannelFunc foreach, @@ -295,14 +278,21 @@ salut_muc_manager_foreach_channel (TpChannelManager *iface, { SalutMucManager *fac = SALUT_MUC_MANAGER (iface); SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (fac); - struct _ForeachData data; GHashTableIter iter; gpointer value; - data.user_data = user_data; - data.foreach = foreach; + g_hash_table_iter_init (&iter, priv->text_channels); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + TpExportableChannel *chan = TP_EXPORTABLE_CHANNEL (value); - g_hash_table_foreach (priv->text_channels, _foreach_slave, &data); + /* do the text channel */ + foreach (chan, user_data); + + /* now its tube channels */ + salut_muc_channel_foreach (SALUT_MUC_CHANNEL (chan), + foreach, user_data); + } g_hash_table_iter_init (&iter, priv->tubes_channels); while (g_hash_table_iter_next (&iter, NULL, &value)) -- cgit v1.2.1 From 8bad2bff1b17deab8469df4e59c79383f1b49932 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 13:33:28 +0100 Subject: muc-manager: create only Tube channels for channel requests Signed-off-by: Jonny Lamb --- src/muc-manager.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/muc-manager.c b/src/muc-manager.c index c6be2140..3a84780b 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -724,47 +724,40 @@ handle_tube_channel_request (SalutMucManager *self, GError **error) { SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); - TpBaseConnection *base_conn = (TpBaseConnection *) priv->connection; SalutMucChannel *text_chan; - SalutTubesChannel *tubes_chan; SalutTubeIface *new_channel; GHashTable *channels; GSList *request_tokens; - gboolean announce_text = FALSE, announce_tubes = FALSE; + gboolean announce_text = FALSE; - tubes_chan = g_hash_table_lookup (priv->tubes_channels, + text_chan = g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (handle)); - if (tubes_chan == NULL) + + if (text_chan == NULL) { - tubes_chan = create_tubes_channel (self, handle, - base_conn->self_handle, NULL, FALSE, &announce_text, - FALSE, error); - if (tubes_chan == NULL) + DEBUG ("have to create the text channel before the tube one"); + text_chan = salut_muc_manager_request_new_muc_channel (self, + handle, NULL, FALSE, error); + + announce_text = TRUE; + + if (text_chan == NULL) return FALSE; - announce_tubes = TRUE; } - g_assert (tubes_chan != NULL); - new_channel = salut_tubes_channel_tube_request (tubes_chan, request_token, - request_properties, require_new); + new_channel = salut_muc_channel_tube_request (text_chan, + request_properties); g_assert (new_channel != NULL); + g_signal_connect (new_channel, "closed", + G_CALLBACK (muc_channel_tube_closed_cb), self); + /* announce channels */ channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); if (announce_text) - { - text_chan = g_hash_table_lookup (priv->text_channels, - GINT_TO_POINTER (handle)); - g_assert (text_chan != NULL); - g_hash_table_insert (channels, text_chan, NULL); - } - - if (announce_tubes) - { - g_hash_table_insert (channels, tubes_chan, NULL); - } + g_hash_table_insert (channels, text_chan, NULL); request_tokens = g_slist_prepend (NULL, request_token); g_hash_table_insert (channels, new_channel, request_tokens); -- cgit v1.2.1 From c23651bfdd6f3bca5891a272bb80e0b36e3d5057 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 13:28:33 +0100 Subject: muc-channel: send tube info messages to others in the MUC Signed-off-by: Jonny Lamb --- src/muc-channel.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index 6af58488..e316c795 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -126,6 +126,7 @@ static void salut_muc_channel_send (GObject *channel, TpMessageSendingFlags flags); static void salut_muc_channel_close (TpBaseChannel *base); +static void update_tube_info (SalutMucChannel *self); static void salut_muc_channel_get_property (GObject *object, @@ -1057,6 +1058,8 @@ salut_muc_channel_new_senders (GibberMucConnection *connection, DEBUG ("Got new senders. Adding myself as member"); salut_muc_channel_add_self_to_members (self); } + + update_tube_info (self); } static void @@ -1166,6 +1169,176 @@ error: return; } +static void +publish_tube_in_node (SalutMucChannel *self, + WockyNode *node, + SalutTubeIface *tube) +{ + TpBaseChannel *base = TP_BASE_CHANNEL (tube); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( + base_conn, TP_HANDLE_TYPE_CONTACT); + WockyNode *parameters_node; + GHashTable *parameters; + TpTubeType type; + gchar *service, *id_str; + guint tube_id; + TpHandle initiator_handle; + + g_object_get (tube, + "type", &type, + "initiator-handle", &initiator_handle, + "service", &service, + "parameters", ¶meters, + "id", &tube_id, + NULL); + + id_str = g_strdup_printf ("%u", tube_id); + + wocky_node_set_attribute (node, "service", service); + wocky_node_set_attribute (node, "id", id_str); + + g_free (id_str); + + switch (type) + { + case TP_TUBE_TYPE_DBUS: + { + gchar *name, *stream_id; + + g_object_get (G_OBJECT (tube), + "dbus-name", &name, + "stream-id", &stream_id, + NULL); + + wocky_node_set_attribute (node, "type", "dbus"); + wocky_node_set_attribute (node, "stream-id", stream_id); + wocky_node_set_attribute (node, "initiator", + tp_handle_inspect (contact_repo, initiator_handle)); + + if (name != NULL) + wocky_node_set_attribute (node, "dbus-name", name); + + g_free (name); + g_free (stream_id); + + } + break; + case TP_TUBE_TYPE_STREAM: + wocky_node_set_attribute (node, "type", "stream"); + break; + default: + g_assert_not_reached (); + } + + parameters_node = wocky_node_add_child (node, "parameters"); + salut_wocky_node_add_children_from_properties (parameters_node, + parameters, "parameter"); + + g_free (service); + g_hash_table_unref (parameters); +} + +static void +update_tube_info (SalutMucChannel *self) +{ + SalutMucChannelPrivate *priv = self->priv; + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + SalutConnection *conn = SALUT_CONNECTION (base_conn); + TpHandleRepoIface *room_repo = tp_base_connection_get_handles ( + base_conn, TP_HANDLE_TYPE_ROOM); + GHashTableIter iter; + gpointer value; + WockyStanza *msg; + WockyNode *msg_node; + WockyNode *node; + const gchar *jid; + GError *error = NULL; + + if (priv->tubes == NULL) + return; + + /* build the message */ + jid = tp_handle_inspect (room_repo, + tp_base_channel_get_target_handle (base)); + + msg = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, + WOCKY_STANZA_SUB_TYPE_GROUPCHAT, + conn->name, jid, + WOCKY_NODE_START, "tubes", + WOCKY_NODE_XMLNS, WOCKY_TELEPATHY_NS_TUBES, + WOCKY_NODE_END, NULL); + msg_node = wocky_stanza_get_top_node (msg); + + node = wocky_node_get_child_ns (msg_node, "tubes", + WOCKY_TELEPATHY_NS_TUBES); + + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + TpTubeChannelState state; + TpTubeType type; + TpHandle initiator; + WockyNode *tube_node; + + g_object_get (value, + "state", &state, + "type", &type, + "initiator-handle", &initiator, + NULL); + + if (state != TP_TUBE_CHANNEL_STATE_OPEN) + continue; + + if (type == TP_TUBE_TYPE_STREAM + && initiator != TP_GROUP_MIXIN (self)->self_handle) + /* We only announce stream tubes we initiated */ + return; + + tube_node = wocky_node_add_child (node, "tube"); + publish_tube_in_node (self, tube_node, value); + } + + /* Send it */ + if (!gibber_muc_connection_send (priv->muc_connection, msg, &error)) + { + g_warning ("%s: sending tubes info failed: %s", G_STRFUNC, + error->message); + g_error_free (error); + } + + g_object_unref (msg); +} + +static void +tube_opened_cb (SalutTubeIface *tube, + SalutMucChannel *self) +{ + if (SALUT_IS_TUBE_DBUS (tube)) + { + gchar *dbus_name; + + g_object_get (tube, + "dbus-name", &dbus_name, + NULL); + + salut_tube_dbus_add_name (SALUT_TUBE_DBUS (tube), + TP_GROUP_MIXIN (self)->self_handle, dbus_name); + + g_free (dbus_name); + } + + update_tube_info (self); +} + +static void +tube_offered_cb (SalutTubeIface *tube, + SalutMucChannel *self) +{ + update_tube_info (self); +} + static void tube_closed_cb (SalutTubeIface *tube, SalutMucChannel *self) @@ -1177,6 +1350,8 @@ tube_closed_cb (SalutTubeIface *tube, "id", &id, NULL); + update_tube_info (self); + if (priv->tubes != NULL) g_hash_table_remove (priv->tubes, GUINT_TO_POINTER (id)); } @@ -1239,6 +1414,8 @@ create_new_tube (SalutMucChannel *self, DEBUG ("create tube %u", tube_id); g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), tube); + g_signal_connect (tube, "tube-opened", G_CALLBACK (tube_opened_cb), self); + g_signal_connect (tube, "tube-offered", G_CALLBACK (tube_offered_cb), self); g_signal_connect (tube, "closed", G_CALLBACK (tube_closed_cb), self); return tube; -- cgit v1.2.1 From a17634a620622b765118e8eae39df6a5754d8f4d Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 13:23:44 +0100 Subject: muc-channel: add extract_tube_information This is copied from tubes-channel.c (soon to be removed). Signed-off-by: Jonny Lamb --- src/muc-channel.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index e316c795..b961e887 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -936,6 +936,105 @@ salut_muc_channel_remove_members (SalutMucChannel *self, tp_intset_destroy (empty); } +/* tube_node is a MUC */ +static gboolean +extract_tube_information (SalutMucChannel *self, + WockyNode *tube_node, + TpTubeType *type, + TpHandle *initiator_handle, + const gchar **service, + GHashTable **parameters, + guint *tube_id) +{ + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( + base_conn, TP_HANDLE_TYPE_CONTACT); + + if (type != NULL) + { + const gchar *_type; + + _type = wocky_node_get_attribute (tube_node, "type"); + + + if (!tp_strdiff (_type, "stream")) + { + *type = TP_TUBE_TYPE_STREAM; + } + else if (!tp_strdiff (_type, "dbus")) + { + *type = TP_TUBE_TYPE_DBUS; + } + else + { + DEBUG ("Unknown tube type: %s", _type); + return FALSE; + } + } + + if (initiator_handle != NULL) + { + const gchar *initiator; + + initiator = wocky_node_get_attribute (tube_node, "initiator"); + + if (initiator != NULL) + { + *initiator_handle = tp_handle_ensure (contact_repo, initiator, NULL, + NULL); + + if (*initiator_handle == 0) + { + DEBUG ("invalid initiator ID %s", initiator); + return FALSE; + } + } + else + { + *initiator_handle = 0; + } + } + + if (service != NULL) + { + *service = wocky_node_get_attribute (tube_node, "service"); + } + + if (parameters != NULL) + { + WockyNode *node; + + node = wocky_node_get_child (tube_node, "parameters"); + *parameters = salut_wocky_node_extract_properties (node, + "parameter"); + } + + if (tube_id != NULL) + { + const gchar *str; + gchar *endptr; + long int tmp; + + str = wocky_node_get_attribute (tube_node, "id"); + if (str == NULL) + { + DEBUG ("no tube id in SI request"); + return FALSE; + } + + tmp = strtol (str, &endptr, 10); + if (!endptr || *endptr) + { + DEBUG ("tube id is not numeric: %s", str); + return FALSE; + } + *tube_id = (int) tmp; + } + + return TRUE; +} + static void salut_muc_channel_received_stanza (GibberMucConnection *conn, const gchar *sender, -- cgit v1.2.1 From a980fd2ecee2548749ca71e85f8fac688b314f0f Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 13:29:28 +0100 Subject: muc-channel: handle tubes nodes in groupchat messages here This is basically code just copied from tubes-channel.c. Signed-off-by: Jonny Lamb --- src/muc-channel.c | 233 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 196 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index b961e887..626f4ac6 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -127,6 +128,15 @@ static void salut_muc_channel_send (GObject *channel, static void salut_muc_channel_close (TpBaseChannel *base); static void update_tube_info (SalutMucChannel *self); +static SalutTubeIface * create_new_tube (SalutMucChannel *self, + TpTubeType type, + TpHandle initiator, + const gchar *service, + GHashTable *parameters, + guint tube_id, + guint portnum, + WockyStanza *iq_req, + gboolean requested); static void salut_muc_channel_get_property (GObject *object, @@ -1035,6 +1045,191 @@ extract_tube_information (SalutMucChannel *self, return TRUE; } +static void +muc_channel_handle_tubes (SalutMucChannel *self, + TpHandle contact, + WockyStanza *stanza) +{ + SalutMucChannelPrivate *priv = self->priv; + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + TpHandleRepoIface *contact_repo = + tp_base_connection_get_handles (base_conn, + TP_HANDLE_TYPE_CONTACT); + const gchar *sender; + WockyStanzaType stanza_type; + WockyStanzaSubType sub_type; + GHashTable *old_dbus_tubes; + GHashTableIter iter; + gpointer key, value; + GSList *l; + WockyNode *tubes_node; + + if (contact == TP_GROUP_MIXIN (self)->self_handle) + /* we don't need to inspect our own tubes */ + return; + + sender = tp_handle_inspect (contact_repo, contact); + + wocky_stanza_get_type_info (stanza, &stanza_type, &sub_type); + if (stanza_type != WOCKY_STANZA_TYPE_MESSAGE + || sub_type != WOCKY_STANZA_SUB_TYPE_GROUPCHAT) + return; + + tubes_node = wocky_node_get_child_ns ( + wocky_stanza_get_top_node (stanza), "tubes", + WOCKY_TELEPATHY_NS_TUBES); + g_assert (tubes_node != NULL); + + /* fill old_dbus_tubes with D-Bus tubes previously announced by the + * contact */ + old_dbus_tubes = g_hash_table_new (NULL, NULL); + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + guint tube_id = GPOINTER_TO_UINT (key); + SalutTubeIface *tube = value; + TpTubeType type; + + g_object_get (tube, + "type", &type, + NULL); + + if (type != TP_TUBE_TYPE_DBUS) + return; + + if (salut_tube_dbus_handle_in_names (SALUT_TUBE_DBUS (tube), + contact)) + { + g_hash_table_insert (old_dbus_tubes, GUINT_TO_POINTER (tube_id), tube); + } + } + + for (l = tubes_node->children; l != NULL; l = l->next) + { + WockyNode *tube_node = (WockyNode *) l->data; + const gchar *stream_id; + SalutTubeIface *tube; + guint tube_id; + TpTubeType type; + GibberBytestreamIface *bytestream; + + stream_id = wocky_node_get_attribute (tube_node, "stream-id"); + + if (!extract_tube_information (self, tube_node, NULL, + NULL, NULL, NULL, &tube_id)) + continue; + + tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); + + if (tube == NULL) + { + /* a new tube */ + const gchar *service; + TpHandle initiator_handle; + GHashTable *parameters; + guint id; + + if (extract_tube_information (self, tube_node, &type, + &initiator_handle, &service, ¶meters, &id)) + { + switch (type) + { + case TP_TUBE_TYPE_DBUS: + { + if (initiator_handle == 0) + { + DEBUG ("D-Bus tube initiator missing"); + continue; + } + } + break; + case TP_TUBE_TYPE_STREAM: + initiator_handle = contact; + break; + default: + g_assert_not_reached (); + } + + tube = create_new_tube (self, type, initiator_handle, service, parameters, + id, 0, NULL, FALSE); + + g_signal_emit (self, signals[NEW_TUBE], 0, tube); + + g_hash_table_unref (parameters); + } + } + else + { + /* the contact is in the tube. + * remove it from old_dbus_tubes if needed. */ + g_hash_table_remove (old_dbus_tubes, GUINT_TO_POINTER (tube_id)); + } + + if (tube == NULL) + continue; + + g_object_get (tube, + "type", &type, + NULL); + + if (type == TP_TUBE_TYPE_DBUS + && !salut_tube_dbus_handle_in_names (SALUT_TUBE_DBUS (tube), + contact)) + { + /* contact just joined the tube */ + const gchar *new_name; + + new_name = wocky_node_get_attribute (tube_node, "dbus-name"); + + if (new_name == NULL) + { + DEBUG ("Contact %u isn't announcing his or her D-Bus name", contact); + continue; + } + + salut_tube_dbus_add_name (SALUT_TUBE_DBUS (tube), contact, new_name); + + g_object_get (tube, + "bytestream", &bytestream, + NULL); + g_assert (bytestream != NULL); + + if (GIBBER_IS_BYTESTREAM_MUC (bytestream)) + { + guint16 tmp = (guint16) atoi (stream_id); + + gibber_bytestream_muc_add_sender ( + GIBBER_BYTESTREAM_MUC (bytestream), sender, tmp); + } + + g_object_unref (bytestream); + } + } + + g_hash_table_iter_init (&iter, old_dbus_tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + SalutTubeDBus *tube = SALUT_TUBE_DBUS (value); + GibberBytestreamIface *bytestream; + + salut_tube_dbus_remove_name (tube, contact); + + g_object_get (tube, + "bytestream", &bytestream, + NULL); + g_assert (bytestream != NULL); + + if (GIBBER_IS_BYTESTREAM_MUC (bytestream) && sender != NULL) + { + gibber_bytestream_muc_remove_sender ( + GIBBER_BYTESTREAM_MUC (bytestream), sender); + } + + g_object_unref (bytestream); + } +} + static void salut_muc_channel_received_stanza (GibberMucConnection *conn, const gchar *sender, @@ -1083,43 +1278,7 @@ salut_muc_channel_received_stanza (GibberMucConnection *conn, WOCKY_TELEPATHY_NS_TUBES); if (tubes_node != NULL) { - SalutTubesChannel *tubes_chan; - GPtrArray *tubes; - guint i; - GHashTable *channels; - gboolean created; - - tubes_chan = salut_muc_manager_ensure_tubes_channel (priv->muc_manager, - tp_base_channel_get_target_handle (base_chan), from_handle, &created); - g_assert (tubes_chan != NULL); - - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); - - if (created) - { - g_hash_table_insert (channels, tubes_chan, NULL); - } - - tubes = salut_tubes_channel_muc_message_received (tubes_chan, sender, - stanza); - - for (i = 0; i < tubes->len; i++) - { - SalutTubeIface *tube; - - tube = g_ptr_array_index (tubes, i); - g_hash_table_insert (channels, tube, NULL); - } - - if (g_hash_table_size (channels) > 0) - { - tp_channel_manager_emit_new_channels (priv->muc_manager, channels); - } - - g_object_unref (tubes_chan); - g_ptr_array_unref (tubes); - g_hash_table_unref (channels); + muc_channel_handle_tubes (self, from_handle, stanza); } if (!text_helper_parse_incoming_message (stanza, &from, &msgtype, -- cgit v1.2.1 From c63a7e740c0d29b12e6688fde35f7030615745cd Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 13:31:54 +0100 Subject: muc-channel: add public function to deal with offered bytestreams Again, more code copied from tubes-channel.c. Signed-off-by: Jonny Lamb --- src/muc-channel.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/muc-channel.h | 4 +++ 2 files changed, 77 insertions(+) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index 626f4ac6..e54b6ad3 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -1748,3 +1748,76 @@ salut_muc_channel_foreach (SalutMucChannel *self, func (TP_EXPORTABLE_CHANNEL (value), user_data); } } + +void +salut_muc_channel_bytestream_offered (SalutMucChannel *self, + GibberBytestreamIface *bytestream, + WockyStanza *msg) +{ + SalutMucChannelPrivate *priv = self->priv; + WockyNode *node = wocky_stanza_get_top_node (msg); + const gchar *stream_id, *tmp; + gchar *endptr; + WockyNode *si_node, *stream_node; + guint tube_id; + unsigned long tube_id_tmp; + SalutTubeIface *tube; + WockyStanzaType type; + WockyStanzaSubType sub_type; + + /* Caller is expected to have checked that we have a stream or muc-stream + * node with a stream ID and the TUBES profile + */ + wocky_stanza_get_type_info (msg, &type, &sub_type); + g_return_if_fail (type == WOCKY_STANZA_TYPE_IQ); + g_return_if_fail (sub_type == WOCKY_STANZA_SUB_TYPE_SET); + + si_node = wocky_node_get_child_ns (node, "si", + WOCKY_XMPP_NS_SI); + g_return_if_fail (si_node != NULL); + + stream_node = wocky_node_get_child_ns (si_node, + "muc-stream", WOCKY_TELEPATHY_NS_TUBES); + g_return_if_fail (stream_node != NULL); + + stream_id = wocky_node_get_attribute (si_node, "id"); + g_return_if_fail (stream_id != NULL); + + tmp = wocky_node_get_attribute (stream_node, "tube"); + if (tmp == NULL) + { + GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, + " has no tube attribute" }; + + DEBUG ("%s", e.message); + gibber_bytestream_iface_close (bytestream, &e); + return; + } + tube_id_tmp = strtoul (tmp, &endptr, 10); + if (!endptr || *endptr || tube_id_tmp > G_MAXUINT32) + { + GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, + " tube attribute not numeric or > 2**32" }; + + DEBUG ("tube id is not numeric or > 2**32: %s", tmp); + gibber_bytestream_iface_close (bytestream, &e); + return; + } + tube_id = (guint) tube_id_tmp; + + tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); + if (tube == NULL) + { + GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, + " tube attribute points to a nonexistent " + "tube" }; + + DEBUG ("tube %u doesn't exist", tube_id); + gibber_bytestream_iface_close (bytestream, &e); + return; + } + + DEBUG ("received new bytestream request for existing tube: %u", tube_id); + + salut_tube_iface_add_bytestream (tube, bytestream); +} diff --git a/src/muc-channel.h b/src/muc-channel.h index 47abcb5f..8c888d18 100644 --- a/src/muc-channel.h +++ b/src/muc-channel.h @@ -96,6 +96,10 @@ SalutTubeIface * salut_muc_channel_tube_request (SalutMucChannel *self, void salut_muc_channel_foreach (SalutMucChannel *self, TpExportableChannelFunc func, gpointer user_data); +void salut_muc_channel_bytestream_offered (SalutMucChannel *self, + GibberBytestreamIface *bytestream, + WockyStanza *msg); + G_END_DECLS #endif /* #ifndef __SALUT_MUC_CHANNEL_H__*/ -- cgit v1.2.1 From 89c1cb976ac7ef8201391833d372bf4f4861fd7a Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 13:32:26 +0100 Subject: muc-manager: send SI stream requests to the MUC channel, not tubes channel Signed-off-by: Jonny Lamb --- src/muc-manager.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/muc-manager.c b/src/muc-manager.c index 3a84780b..7272faba 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -1116,23 +1116,23 @@ salut_muc_manager_handle_si_stream_request (SalutMucManager *self, SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); TpHandleRepoIface *room_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->connection, TP_HANDLE_TYPE_ROOM); - SalutTubesChannel *chan = NULL; + SalutMucChannel *chan = NULL; g_return_if_fail (tp_handle_is_valid (room_repo, room_handle, NULL)); - chan = g_hash_table_lookup (priv->tubes_channels, + chan = g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (room_handle)); if (chan == NULL) { GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - "No tubes channel available for this MUC" }; + "No channel available for this MUC" }; - DEBUG ("tubes channel doesn't exist for muc %d", room_handle); + DEBUG ("MUC channel doesn't exist for muc %d", room_handle); gibber_bytestream_iface_close (bytestream, &e); return; } - salut_tubes_channel_bytestream_offered (chan, bytestream, msg); + salut_muc_channel_bytestream_offered (chan, bytestream, msg); } /* Caller is reponsible of announcing the channel if created */ -- cgit v1.2.1 From ad31a233facbde4d692f69a5b667d904a350de66 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 15:57:04 +0100 Subject: tubes-manager: create only Tube channels for incoming invitations Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 140 ++++++++++++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 68ab4736..5da8524c 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -65,6 +65,15 @@ static void salut_tubes_manager_iface_init (gpointer g_iface, static void gabble_caps_channel_manager_iface_init ( GabbleCapsChannelManagerIface *); +static SalutTubeIface * create_new_tube (SalutTubesManager *self, + TpTubeType type, + TpHandle handle, + const gchar *service, + GHashTable *parameters, + guint tube_id, + guint portnum, + WockyStanza *iq_req); + G_DEFINE_TYPE_WITH_CODE (SalutTubesManager, salut_tubes_manager, G_TYPE_OBJECT, @@ -307,7 +316,7 @@ iq_tube_request_cb (WockyPorter *porter, gboolean close_; GError *error = NULL; - SalutTubesChannel *chan; + SalutTubeIface *chan; /* after this point, the message is for us, so in all cases we either handle * it or send an error reply */ @@ -332,70 +341,31 @@ iq_tube_request_cb (WockyPorter *porter, DEBUG ("received a tube request, tube id %d", tube_id); - chan = g_hash_table_lookup (priv->tubes_channels, - GUINT_TO_POINTER (initiator_handle)); + chan = g_hash_table_lookup (priv->tubes, + GUINT_TO_POINTER (tube_id)); + if (close_) { if (chan != NULL) { - salut_tubes_channel_message_close_received (chan, initiator_handle, - tube_id); + DEBUG ("received a tube close message"); + salut_tube_iface_close (chan, TRUE); } } else { - SalutTubeIface *tube; - GHashTable *channels; - gboolean tubes_channel_created = FALSE; - if (chan == NULL) { - GError *e = NULL; - - chan = new_tubes_channel (self, initiator_handle, initiator_handle, - NULL, FALSE, &e); - - if (chan == NULL) - { - DEBUG ("couldn't make new tubes channel: %s", e->message); - g_error_free (e); - g_hash_table_unref (parameters); - return TRUE; - } - - tubes_channel_created = TRUE; - } - - tube = salut_tubes_channel_message_received (chan, service, tube_type, - initiator_handle, parameters, tube_id, portnum, stanza); - - if (tube == NULL) - { - if (tubes_channel_created) - { - /* Destroy the tubes channel we just created as it's now - * useless */ - g_hash_table_remove (priv->tubes_channels, GUINT_TO_POINTER ( - initiator_handle)); - } - - g_hash_table_unref (parameters); - return TRUE; + /* create new tube here */ + chan = create_new_tube (self, tube_type, + initiator_handle, service, parameters, tube_id, portnum, stanza); } - /* announce tubes and tube channels */ - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); - - if (tubes_channel_created) - g_hash_table_insert (channels, chan, NULL); - - g_hash_table_insert (channels, tube, NULL); - - tp_channel_manager_emit_new_channels (self, channels); + /* announce tube channel */ + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (chan), NULL); g_hash_table_unref (parameters); - g_hash_table_unref (channels); } return TRUE; @@ -857,24 +827,63 @@ generate_tube_id (SalutTubesManager *self) } static SalutTubeIface * -new_channel_from_request (SalutTubesManager *self, - GHashTable *request) +create_new_tube (SalutTubesManager *self, + TpTubeType type, + TpHandle handle, + const gchar *service, + GHashTable *parameters, + guint tube_id, + guint portnum, + WockyStanza *iq_req) { SalutTubesManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SALUT_TYPE_TUBES_MANAGER, SalutTubesManagerPrivate); TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn); SalutTubeIface *tube; + if (type == TP_TUBE_TYPE_STREAM) + { + tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, NULL, + handle, TP_HANDLE_TYPE_CONTACT, + base_conn->self_handle, base_conn->self_handle, FALSE, service, + parameters, tube_id, portnum, iq_req, TRUE)); + } + else if (type == TP_TUBE_TYPE_DBUS) + { + tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, NULL, + handle, TP_HANDLE_TYPE_CONTACT, base_conn->self_handle, NULL, + base_conn->self_handle, service, parameters, tube_id, TRUE)); + } + else + { + g_return_val_if_reached (NULL); + } + + tp_base_channel_register ((TpBaseChannel *) tube); + + g_signal_connect (tube, "closed", + G_CALLBACK (channel_closed_cb), self); + + g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), + tube); + + return tube; +} + +static SalutTubeIface * +new_channel_from_request (SalutTubesManager *self, + GHashTable *request) +{ + SalutTubeIface *tube; + + TpTubeType type; const gchar *ctype, *service; TpHandle handle; - TpHandleType handle_type; guint tube_id; GHashTable *parameters; ctype = tp_asv_get_string (request, TP_PROP_CHANNEL_CHANNEL_TYPE); handle = tp_asv_get_uint32 (request, TP_PROP_CHANNEL_TARGET_HANDLE, NULL); - handle_type = tp_asv_get_uint32 (request, - TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL); tube_id = generate_tube_id (self); @@ -882,37 +891,28 @@ new_channel_from_request (SalutTubesManager *self, parameters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); + if (!tp_strdiff (ctype, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) { service = tp_asv_get_string (request, TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE); - tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, NULL, - handle, handle_type, - base_conn->self_handle, base_conn->self_handle, FALSE, service, - parameters, tube_id, 0, NULL, TRUE)); + type = TP_TUBE_TYPE_STREAM; } else if (!tp_strdiff (ctype, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) { service = tp_asv_get_string (request, TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME); - tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, NULL, - handle, handle_type, base_conn->self_handle, NULL, - base_conn->self_handle, service, parameters, tube_id, TRUE)); + type = TP_TUBE_TYPE_DBUS; } else { g_return_val_if_reached (NULL); } - tp_base_channel_register ((TpBaseChannel *) tube); - - g_signal_connect (tube, "closed", - G_CALLBACK (channel_closed_cb), self); - - g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), - tube); + tube = create_new_tube (self, type, handle, service, + parameters, tube_id, 0, NULL); g_hash_table_unref (parameters); -- cgit v1.2.1 From 52468dfb239962f924023c61eef66a3197586ac9 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 15:58:45 +0100 Subject: tubes-manager: remove all old TubesChannel references Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 120 ---------------------------------------------------- 1 file changed, 120 deletions(-) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 5da8524c..213a0cd0 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -43,7 +43,6 @@ #include "extensions/extensions.h" #include "connection.h" #include "capabilities.h" -#include "tubes-channel.h" #include "muc-manager.h" #include "muc-channel.h" #include "self.h" @@ -53,13 +52,6 @@ #include "tube-stream.h" -static SalutTubesChannel *new_tubes_channel (SalutTubesManager *fac, - TpHandle handle, TpHandle initiator, gpointer request_token, - gboolean requested, GError **error); - -static void tubes_channel_closed_cb (SalutTubesChannel *chan, - gpointer user_data); - static void salut_tubes_manager_iface_init (gpointer g_iface, gpointer iface_data); static void gabble_caps_channel_manager_iface_init ( @@ -99,8 +91,6 @@ struct _SalutTubesManagerPrivate guint iq_tube_handler_id; SalutContactManager *contact_manager; - GHashTable *tubes_channels; - /* guint tube ID => (owned) (SalutTubeIface *) */ GHashTable *tubes; @@ -118,9 +108,6 @@ salut_tubes_manager_init (SalutTubesManager *self) self->priv = priv; - priv->tubes_channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_object_unref); - priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_object_unref); @@ -385,7 +372,6 @@ salut_tubes_manager_close_all (SalutTubesManager *self) priv->status_changed_id = 0; } - tp_clear_pointer (&priv->tubes_channels, g_hash_table_unref); tp_clear_pointer (&priv->tubes, g_hash_table_unref); } @@ -552,93 +538,6 @@ salut_tubes_manager_class_init ( } -/** - * tubes_channel_closed_cb: - * - * Signal callback for when a Tubes channel is closed. Removes the references - * that TubesManager holds to them. - */ -static void -tubes_channel_closed_cb (SalutTubesChannel *chan, - gpointer user_data) -{ - SalutTubesManager *conn = SALUT_TUBES_MANAGER (user_data); - SalutTubesManagerPrivate *priv = - SALUT_TUBES_MANAGER_GET_PRIVATE (conn); - TpHandle contact_handle; - - if (priv->tubes_channels == NULL) - return; - - g_object_get (chan, "handle", &contact_handle, NULL); - - DEBUG ("removing tubes channel with handle %d", contact_handle); - - g_hash_table_remove (priv->tubes_channels, GUINT_TO_POINTER (contact_handle)); -} - -/** - * new_tubes_channel - * - * Creates the SalutTubes object associated with the given parameters - */ -static SalutTubesChannel * -new_tubes_channel (SalutTubesManager *fac, - TpHandle handle, - TpHandle initiator, - gpointer request_token, - gboolean requested, - GError **error) -{ - SalutTubesManagerPrivate *priv; - TpBaseConnection *conn; - SalutTubesChannel *chan; - char *object_path; - SalutContact *contact; - - g_assert (SALUT_IS_TUBES_MANAGER (fac)); - - priv = SALUT_TUBES_MANAGER_GET_PRIVATE (fac); - conn = (TpBaseConnection *) priv->conn; - - contact = salut_contact_manager_get_contact (priv->contact_manager, handle); - - if (contact == NULL) - { - TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - base_conn, TP_HANDLE_TYPE_CONTACT); - - g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "%s is not online", tp_handle_inspect (contact_repo, handle)); - return NULL; - } - - object_path = g_strdup_printf ("%s/TubesChannel%u", conn->object_path, - handle); - - chan = g_object_new (SALUT_TYPE_TUBES_CHANNEL, - "connection", priv->conn, - "object-path", object_path, - "handle", handle, - "handle-type", TP_HANDLE_TYPE_CONTACT, - "contact", contact, - "initiator-handle", initiator, - "requested", requested, - NULL); - - DEBUG ("object path %s", object_path); - - g_signal_connect (chan, "closed", G_CALLBACK (tubes_channel_closed_cb), fac); - - g_hash_table_insert (priv->tubes_channels, GUINT_TO_POINTER (handle), chan); - - g_object_unref (contact); - g_free (object_path); - - return chan; -} - static void salut_tubes_manager_foreach_channel (TpChannelManager *manager, TpExportableChannelFunc foreach, @@ -650,20 +549,6 @@ salut_tubes_manager_foreach_channel (TpChannelManager *manager, GHashTableIter iter; gpointer value; - g_hash_table_iter_init (&iter, priv->tubes_channels); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - TpExportableChannel *chan = TP_EXPORTABLE_CHANNEL (value); - - /* Add channels of type Channel.Type.Tubes */ - foreach (chan, user_data); - - /* Add channels of type Channel.Type.{Stream|DBus}Tube which live in the - * SalutTubesChannel object */ - salut_tubes_channel_foreach (SALUT_TUBES_CHANNEL (chan), foreach, - user_data); - } - g_hash_table_iter_init (&iter, priv->tubes); while (g_hash_table_iter_next (&iter, NULL, &value)) { @@ -677,11 +562,6 @@ static const gchar * const tubes_channel_fixed_properties[] = { NULL }; -static const gchar * const old_tubes_channel_allowed_properties[] = { - TP_IFACE_CHANNEL ".TargetHandle", - NULL -}; - static const gchar * const stream_tube_channel_allowed_properties[] = { TP_IFACE_CHANNEL ".TargetHandle", TP_IFACE_CHANNEL ".TargetID", -- cgit v1.2.1 From 9f16272288dcb115e94fdced6fed48b3c14a6150 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 16:01:27 +0100 Subject: muc-manager: remove all old TubesChannel references Signed-off-by: Jonny Lamb --- src/muc-manager.c | 208 ------------------------------------------------------ src/muc-manager.h | 5 -- 2 files changed, 213 deletions(-) (limited to 'src') diff --git a/src/muc-manager.c b/src/muc-manager.c index 7272faba..36d77ef0 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -36,7 +36,6 @@ #include "muc-channel.h" #include "contact-manager.h" -#include "tubes-channel.h" #include "roomlist-channel.h" #include "roomlist-manager.h" #include "discovery-client.h" @@ -84,8 +83,6 @@ struct _SalutMucManagerPrivate /* GUINT_TO_POINTER (room_handle) => (SalutMucChannel *) */ GHashTable *text_channels; - /* GUINT_TO_POINTER(room_handle) => (SalutTubesChannel *) */ - GHashTable *tubes_channels; /* tube ID => owned SalutTubeIface */ GHashTable *tubes; @@ -109,8 +106,6 @@ salut_muc_manager_init (SalutMucManager *obj) /* allocate any data required by the object here */ priv->text_channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); - priv->tubes_channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_object_unref); } static void @@ -167,7 +162,6 @@ salut_muc_manager_close_all (SalutMucManager *self) } tp_clear_pointer (&priv->text_channels, g_hash_table_unref); - tp_clear_pointer (&priv->tubes_channels, g_hash_table_unref); } static void @@ -261,7 +255,6 @@ salut_muc_manager_dispose (GObject *object) salut_muc_manager_close_all (self); g_assert (priv->text_channels == NULL); - g_assert (priv->tubes_channels == NULL); /* release any references held by the object here */ @@ -293,20 +286,6 @@ salut_muc_manager_foreach_channel (TpChannelManager *iface, salut_muc_channel_foreach (SALUT_MUC_CHANNEL (chan), foreach, user_data); } - - g_hash_table_iter_init (&iter, priv->tubes_channels); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - TpExportableChannel *chan = TP_EXPORTABLE_CHANNEL (value); - - /* Add channels of type Channel.Type.Tubes */ - foreach (chan, user_data); - - /* Add channels of type Channel.Type.{Stream|DBus}Tube which live in the - * SalutTubesChannel object */ - salut_tubes_channel_foreach (SALUT_TUBES_CHANNEL (chan), foreach, - user_data); - } } static const gchar * const muc_channel_fixed_properties[] = { @@ -324,10 +303,6 @@ static const gchar * const muc_channel_allowed_properties[] = { NULL }; -static const gchar * const * muc_tubes_channel_allowed_properties = - muc_channel_allowed_properties; - - static void salut_muc_manager_type_foreach_channel_class (GType type, TpChannelManagerTypeChannelClassFunc func, @@ -352,11 +327,6 @@ salut_muc_manager_type_foreach_channel_class (GType type, func (type, table, muc_channel_allowed_properties, user_data); - /* org.freedesktop.Telepathy.Channel.Type.Tubes */ - g_value_set_static_string (channel_type_value, TP_IFACE_CHANNEL_TYPE_TUBES); - func (type, table, muc_tubes_channel_allowed_properties, - user_data); - /* org.freedesktop.Telepathy.Channel.Type.StreamTube */ g_value_set_static_string (channel_type_value, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE); @@ -389,51 +359,10 @@ muc_channel_closed_cb (SalutMucChannel *chan, g_object_get (chan, "handle", &handle, NULL); DEBUG ("Removing channel with handle %u", handle); - if (priv->tubes_channels != NULL) - { - SalutTubesChannel *tubes; - - tubes = g_hash_table_lookup (priv->tubes_channels, - GUINT_TO_POINTER (handle)); - if (tubes != NULL) - salut_tubes_channel_close (tubes); - } - g_hash_table_remove (priv->text_channels, GUINT_TO_POINTER (handle)); } } -/** - * tubes_channel_closed_cb: - * - * Signal callback for when a tubes channel is closed. Removes the references - * that MucManager holds to them. - */ -static void -tubes_channel_closed_cb (SalutTubesChannel *chan, - gpointer user_data) -{ - SalutMucManager *fac = SALUT_MUC_MANAGER (user_data); - SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (fac); - TpHandle room_handle; - - tp_channel_manager_emit_channel_closed_for_object (fac, - TP_EXPORTABLE_CHANNEL (chan)); - - if (priv->tubes_channels != NULL) - { - g_object_get (chan, "handle", &room_handle, NULL); - - DEBUG ("removing MUC tubes channel with handle %u", room_handle); - - g_hash_table_remove (priv->tubes_channels, - GUINT_TO_POINTER (room_handle)); - - /* The channel will probably reopen soon due to an incoming tube message, - * but closing the corresponding text channel would be too astonishing */ - } -} - static void muc_channel_tube_closed_cb (SalutTubeIface *tube, SalutMucManager *mgr) @@ -507,50 +436,6 @@ salut_muc_manager_new_muc_channel (SalutMucManager *mgr, return chan; } -/** - * new_tubes_channel: - * - * Creates the SalutTubesChannel object with the given parameters. - */ -static SalutTubesChannel * -new_tubes_channel (SalutMucManager *self, - TpHandle room, - SalutMucChannel *muc, - TpHandle initiator, - gboolean requested) -{ - SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); - TpBaseConnection *conn = (TpBaseConnection *) priv->connection; - SalutTubesChannel *chan; - char *object_path; - - g_assert (g_hash_table_lookup (priv->tubes_channels, - GUINT_TO_POINTER (room)) == NULL); - - object_path = g_strdup_printf ("%s/MucTubesChannel%u", - conn->object_path, room); - - DEBUG ("creating new tubes chan, object path %s", object_path); - - chan = g_object_new (SALUT_TYPE_TUBES_CHANNEL, - "connection", priv->connection, - "object-path", object_path, - "handle", room, - "handle-type", TP_HANDLE_TYPE_ROOM, - "muc", muc, - "initiator-handle", initiator, - "requested", requested, - NULL); - - g_signal_connect (chan, "closed", (GCallback) tubes_channel_closed_cb, self); - - g_hash_table_insert (priv->tubes_channels, GUINT_TO_POINTER (room), chan); - - g_free (object_path); - - return chan; -} - static SalutMucChannel * salut_muc_manager_request_new_muc_channel (SalutMucManager *mgr, TpHandle handle, @@ -651,70 +536,6 @@ salut_muc_manager_request_new_muc_channel (SalutMucManager *mgr, return text_chan; } -static SalutTubesChannel * -create_tubes_channel (SalutMucManager *self, - TpHandle handle, - TpHandle initiator, - gpointer request_token, - gboolean announce, - gboolean *text_created_out, - gboolean requested, - GError **error) -{ - SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); - SalutMucChannel *text_chan; - SalutTubesChannel *tubes_chan; - gboolean text_created = FALSE; - - text_chan = g_hash_table_lookup (priv->text_channels, - GUINT_TO_POINTER (handle)); - - if (text_chan == NULL) - { - DEBUG ("have to create the text channel before the tubes one"); - text_chan = salut_muc_manager_request_new_muc_channel (self, - handle, NULL, FALSE, error); - - if (text_chan == NULL) - return NULL; - - text_created = TRUE; - } - - tubes_chan = new_tubes_channel (self, handle, text_chan, initiator, - requested); - g_assert (tubes_chan != NULL); - - if (announce) - { - GHashTable *channels; - GSList *tokens = NULL; - - if (request_token != NULL) - tokens = g_slist_prepend (tokens, request_token); - - /* announce channels */ - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); - - if (text_created) - { - g_hash_table_insert (channels, text_chan, NULL); - } - - g_hash_table_insert (channels, tubes_chan, tokens); - tp_channel_manager_emit_new_channels (self, channels); - - g_hash_table_unref (channels); - g_slist_free (tokens); - } - - if (text_created_out != NULL) - *text_created_out = text_created; - - return tubes_chan; -} - static gboolean handle_tube_channel_request (SalutMucManager *self, gpointer request_token, @@ -1134,32 +955,3 @@ salut_muc_manager_handle_si_stream_request (SalutMucManager *self, salut_muc_channel_bytestream_offered (chan, bytestream, msg); } - -/* Caller is reponsible of announcing the channel if created */ -SalutTubesChannel * -salut_muc_manager_ensure_tubes_channel (SalutMucManager *self, - TpHandle handle, - TpHandle actor, - gboolean *created) -{ - SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); - SalutTubesChannel *tubes_chan; - - tubes_chan = g_hash_table_lookup (priv->tubes_channels, - GUINT_TO_POINTER (handle)); - if (tubes_chan != NULL) - { - g_object_ref (tubes_chan); - *created = FALSE; - return tubes_chan; - } - - - tubes_chan = create_tubes_channel (self, handle, actor, NULL, FALSE, NULL, - FALSE, NULL); - g_assert (tubes_chan != NULL); - g_object_ref (tubes_chan); - - *created = TRUE; - return tubes_chan; -} diff --git a/src/muc-manager.h b/src/muc-manager.h index 2e761a8d..38ac0c8e 100644 --- a/src/muc-manager.h +++ b/src/muc-manager.h @@ -74,11 +74,6 @@ void salut_muc_manager_handle_si_stream_request (SalutMucManager *muc_manager, GibberBytestreamIface *bytestream, TpHandle room_handle, const gchar *stream_id, WockyStanza *msg); -SalutTubesChannel * salut_muc_manager_ensure_tubes_channel ( - SalutMucManager *muc_manager, TpHandle handle, TpHandle actor, - gboolean *created); - - G_END_DECLS #endif /* #ifndef __SALUT_MUC_MANAGER_H__*/ -- cgit v1.2.1 From 419b4203588ea16da23da025e5ef55d95db15202 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 16:08:16 +0100 Subject: tube-{iface,dbus,stream}: remove tubes-channel property Signed-off-by: Jonny Lamb --- src/muc-channel.c | 4 ++-- src/tube-dbus.c | 14 +------------- src/tube-dbus.h | 3 +-- src/tube-iface.c | 13 ------------- src/tube-stream.c | 16 +--------------- src/tube-stream.h | 2 -- src/tubes-manager.c | 4 ++-- 7 files changed, 7 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index e54b6ad3..782d9622 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -1653,12 +1653,12 @@ create_new_tube (SalutMucChannel *self, switch (type) { case TP_TUBE_TYPE_DBUS: - tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (conn, NULL, + tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (conn, handle, TP_HANDLE_TYPE_ROOM, self_handle, priv->muc_connection, initiator, service, parameters, tube_id, requested)); break; case TP_TUBE_TYPE_STREAM: - tube = SALUT_TUBE_IFACE (salut_tube_stream_new (conn, NULL, + tube = SALUT_TUBE_IFACE (salut_tube_stream_new (conn, handle, TP_HANDLE_TYPE_ROOM, self_handle, initiator, FALSE, service, parameters, tube_id, portnum, iq_req, requested)); diff --git a/src/tube-dbus.c b/src/tube-dbus.c index aed98c33..0d12086b 100644 --- a/src/tube-dbus.c +++ b/src/tube-dbus.c @@ -93,8 +93,7 @@ static guint signals[LAST_SIGNAL] = {0}; /* properties */ enum { - PROP_TUBES_CHANNEL = 1, - PROP_SELF_HANDLE, + PROP_SELF_HANDLE = 1, PROP_MUC_CONNECTION, PROP_ID, PROP_BYTESTREAM, @@ -113,7 +112,6 @@ enum typedef struct _SalutTubeDBusPrivate SalutTubeDBusPrivate; struct _SalutTubeDBusPrivate { - SalutTubesChannel *tubes_channel; TpHandle self_handle; GibberMucConnection *muc_connection; guint id; @@ -631,9 +629,6 @@ salut_tube_dbus_get_property (GObject *object, switch (property_id) { - case PROP_TUBES_CHANNEL: - g_value_set_object (value, priv->tubes_channel); - break; case PROP_SELF_HANDLE: g_value_set_uint (value, priv->self_handle); break; @@ -690,9 +685,6 @@ salut_tube_dbus_set_property (GObject *object, switch (property_id) { - case PROP_TUBES_CHANNEL: - priv->tubes_channel = g_value_get_object (value); - break; case PROP_SELF_HANDLE: priv->self_handle = g_value_get_uint (value); break; @@ -937,8 +929,6 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) object_class->dispose = salut_tube_dbus_dispose; object_class->finalize = salut_tube_dbus_finalize; - g_object_class_override_property (object_class, PROP_TUBES_CHANNEL, - "tubes-channel"); g_object_class_override_property (object_class, PROP_SELF_HANDLE, "self-handle"); g_object_class_override_property (object_class, PROP_ID, @@ -1310,7 +1300,6 @@ data_received_cb (GibberBytestreamIface *stream, SalutTubeDBus * salut_tube_dbus_new (SalutConnection *conn, - SalutTubesChannel *tubes_channel, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, @@ -1329,7 +1318,6 @@ salut_tube_dbus_new (SalutConnection *conn, tube = g_object_new (gtype, "connection", conn, - "tubes-channel", tubes_channel, "handle", handle, "self-handle", self_handle, "muc-connection", muc_connection, diff --git a/src/tube-dbus.h b/src/tube-dbus.h index d3954ad4..5e617cfc 100644 --- a/src/tube-dbus.h +++ b/src/tube-dbus.h @@ -27,7 +27,6 @@ #include #include "connection.h" -#include "tubes-channel.h" #include #include @@ -67,7 +66,7 @@ GType salut_tube_dbus_get_type (void); SalutTubeDBusClass)) SalutTubeDBus * -salut_tube_dbus_new (SalutConnection *conn, SalutTubesChannel *tubes_channel, +salut_tube_dbus_new (SalutConnection *conn, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, GibberMucConnection *muc_connection, TpHandle initiator, const gchar *service, GHashTable *parameters, guint id, diff --git a/src/tube-iface.c b/src/tube-iface.c index fa866442..6978b074 100644 --- a/src/tube-iface.c +++ b/src/tube-iface.c @@ -22,7 +22,6 @@ #include #include "connection.h" -#include "tubes-channel.h" #include @@ -101,18 +100,6 @@ salut_tube_iface_base_init (gpointer klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_interface_install_property (klass, param_spec); - param_spec = g_param_spec_object ( - "tubes-channel", - "SalutTubesChannel object", - "Salut tubes object that implements the old interface.", - SALUT_TYPE_TUBES_CHANNEL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB); - g_object_interface_install_property (klass, param_spec); - param_spec = g_param_spec_uint ( "handle", "Handle", diff --git a/src/tube-stream.c b/src/tube-stream.c index b9782dda..80fee7ea 100644 --- a/src/tube-stream.c +++ b/src/tube-stream.c @@ -71,7 +71,6 @@ #include "tube-iface.h" #include "si-bytestream-manager.h" #include "contact-manager.h" -#include "tubes-channel.h" static void tube_iface_init (gpointer g_iface, gpointer iface_data); static void streamtube_iface_init (gpointer g_iface, gpointer iface_data); @@ -123,8 +122,7 @@ static guint signals[LAST_SIGNAL] = {0}; /* properties */ enum { - PROP_TUBES_CHANNEL = 1, - PROP_SELF_HANDLE, + PROP_SELF_HANDLE = 1, PROP_ID, PROP_TYPE, PROP_SERVICE, @@ -144,7 +142,6 @@ enum typedef struct _SalutTubeStreamPrivate SalutTubeStreamPrivate; struct _SalutTubeStreamPrivate { - SalutTubesChannel *tubes_channel; TpHandle self_handle; guint id; guint port; @@ -1095,9 +1092,6 @@ salut_tube_stream_get_property (GObject *object, switch (property_id) { - case PROP_TUBES_CHANNEL: - g_value_set_object (value, priv->tubes_channel); - break; case PROP_SELF_HANDLE: g_value_set_uint (value, priv->self_handle); break; @@ -1158,9 +1152,6 @@ salut_tube_stream_set_property (GObject *object, switch (property_id) { - case PROP_TUBES_CHANNEL: - priv->tubes_channel = g_value_get_object (value); - break; case PROP_SELF_HANDLE: priv->self_handle = g_value_get_uint (value); break; @@ -1342,8 +1333,6 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class) object_class->dispose = salut_tube_stream_dispose; object_class->finalize = salut_tube_stream_finalize; - g_object_class_override_property (object_class, PROP_TUBES_CHANNEL, - "tubes-channel"); g_object_class_override_property (object_class, PROP_SELF_HANDLE, "self-handle"); g_object_class_override_property (object_class, PROP_ID, @@ -1522,7 +1511,6 @@ data_received_cb (GibberBytestreamIface *bytestream, SalutTubeStream * salut_tube_stream_new (SalutConnection *conn, - SalutTubesChannel *tubes_channel, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, @@ -1543,7 +1531,6 @@ salut_tube_stream_new (SalutConnection *conn, obj = g_object_new (gtype, "connection", conn, - "tubes-channel", tubes_channel, "handle", handle, "self-handle", self_handle, "initiator-handle", initiator, @@ -2249,7 +2236,6 @@ salut_tube_stream_offer (SalutTubeStream *self, if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { priv->state = TP_TUBE_CHANNEL_STATE_REMOTE_PENDING; - salut_tubes_channel_send_iq_offer (priv->tubes_channel); tp_svc_channel_interface_tube_emit_tube_channel_state_changed ( self, TP_TUBE_CHANNEL_STATE_REMOTE_PENDING); diff --git a/src/tube-stream.h b/src/tube-stream.h index f3d0fd0a..7c5f0f72 100644 --- a/src/tube-stream.h +++ b/src/tube-stream.h @@ -28,7 +28,6 @@ #include "extensions/extensions.h" #include "connection.h" -#include "tubes-channel.h" G_BEGIN_DECLS @@ -66,7 +65,6 @@ GType salut_tube_stream_get_type (void); SalutTubeStreamClass)) SalutTubeStream *salut_tube_stream_new (SalutConnection *conn, - SalutTubesChannel *tubes_channel, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, TpHandle initiator, gboolean offered, const gchar *service, diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 213a0cd0..b3a1136f 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -723,14 +723,14 @@ create_new_tube (SalutTubesManager *self, if (type == TP_TUBE_TYPE_STREAM) { - tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, NULL, + tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, handle, TP_HANDLE_TYPE_CONTACT, base_conn->self_handle, base_conn->self_handle, FALSE, service, parameters, tube_id, portnum, iq_req, TRUE)); } else if (type == TP_TUBE_TYPE_DBUS) { - tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, NULL, + tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, handle, TP_HANDLE_TYPE_CONTACT, base_conn->self_handle, NULL, base_conn->self_handle, service, parameters, tube_id, TRUE)); } -- cgit v1.2.1 From e9022193df8f12e72817bb3a8a07dbe3a75f4ab7 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 31 May 2012 16:02:11 +0100 Subject: tubes-channel: remove Hooray! Signed-off-by: Jonny Lamb --- src/Makefile.am | 2 - src/avahi-muc-manager.c | 1 - src/avahi-roomlist-manager.c | 1 - src/muc-manager.h | 1 - src/roomlist-manager.c | 1 - src/roomlist-manager.h | 1 - src/tubes-channel.c | 2598 ------------------------------------------ src/tubes-channel.h | 94 -- src/tubes-manager.h | 1 - 9 files changed, 2700 deletions(-) delete mode 100644 src/tubes-channel.c delete mode 100644 src/tubes-channel.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index a8d1d534..3fea9215 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,8 +76,6 @@ CORE_SOURCES = \ tube-iface.c \ tube-stream.h \ tube-stream.c \ - tubes-channel.h \ - tubes-channel.c \ util.h \ util.c \ protocol.c \ diff --git a/src/avahi-muc-manager.c b/src/avahi-muc-manager.c index 46fea622..7418ab63 100644 --- a/src/avahi-muc-manager.c +++ b/src/avahi-muc-manager.c @@ -34,7 +34,6 @@ #include "muc-channel.h" #include "contact-manager.h" -#include "tubes-channel.h" #include "roomlist-channel.h" #include "avahi-muc-channel.h" diff --git a/src/avahi-roomlist-manager.c b/src/avahi-roomlist-manager.c index 1ac27f78..625be31d 100644 --- a/src/avahi-roomlist-manager.c +++ b/src/avahi-roomlist-manager.c @@ -33,7 +33,6 @@ #include #include "contact-manager.h" -#include "tubes-channel.h" #include "roomlist-channel.h" #include diff --git a/src/muc-manager.h b/src/muc-manager.h index 38ac0c8e..a2cdd16f 100644 --- a/src/muc-manager.h +++ b/src/muc-manager.h @@ -26,7 +26,6 @@ #include #include "muc-channel.h" -#include "tubes-channel.h" #include "muc-channel.h" G_BEGIN_DECLS diff --git a/src/roomlist-manager.c b/src/roomlist-manager.c index b121917e..dbde4310 100644 --- a/src/roomlist-manager.c +++ b/src/roomlist-manager.c @@ -36,7 +36,6 @@ #include "roomlist-channel.h" #include "contact-manager.h" #include "muc-manager.h" -#include "tubes-channel.h" #include "roomlist-channel.h" #include "discovery-client.h" diff --git a/src/roomlist-manager.h b/src/roomlist-manager.h index eb087439..162b48a6 100644 --- a/src/roomlist-manager.h +++ b/src/roomlist-manager.h @@ -25,7 +25,6 @@ #include #include -#include "tubes-channel.h" #include "roomlist-channel.h" G_BEGIN_DECLS diff --git a/src/tubes-channel.c b/src/tubes-channel.c deleted file mode 100644 index be9d6186..00000000 --- a/src/tubes-channel.c +++ /dev/null @@ -1,2598 +0,0 @@ -/* - * tubes-channel.c - Source for SalutTubesChannel - * Copyright (C) 2007 Collabora Ltd. - * - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the tubesplied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "tubes-channel.h" - -#include -#include - -#include - -#ifdef G_OS_UNIX -#include -#include -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DEBUG_FLAG DEBUG_TUBES -#include "debug.h" -#include "extensions/extensions.h" -#include "util.h" -#include "connection.h" -#include "contact.h" -#include "muc-channel.h" -#include "muc-manager.h" -#include "tubes-manager.h" -#include "tube-iface.h" -#include "tube-dbus.h" -#include "tube-stream.h" - -#define SALUT_CHANNEL_TUBE_TYPE \ - (dbus_g_type_get_struct ("GValueArray", \ - G_TYPE_UINT, \ - G_TYPE_UINT, \ - G_TYPE_UINT, \ - G_TYPE_STRING, \ - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), \ - G_TYPE_UINT, \ - G_TYPE_INVALID)) - -#define DBUS_NAME_PAIR_TYPE \ - (dbus_g_type_get_struct ("GValueArray", \ - G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID)) - -static void channel_iface_init (gpointer g_iface, gpointer iface_data); -static void tubes_iface_init (gpointer g_iface, gpointer iface_data); - -G_DEFINE_TYPE_WITH_CODE (SalutTubesChannel, salut_tubes_channel, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, - tp_dbus_properties_mixin_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_TUBES, tubes_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP, - tp_external_group_mixin_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL); -); - -/* Channel state */ -typedef enum -{ - CHANNEL_NOT_CONNECTED = 0, - CHANNEL_CONNECTING, - CHANNEL_CONNECTED, - CHANNEL_CLOSING, -} ChannelState; - -/* properties */ -static const char *salut_tubes_channel_interfaces[] = { - TP_IFACE_CHANNEL_INTERFACE_GROUP, - /* If more interfaces are added, either keep Group as the first, or change - * the implementations of salut_tubes_channel_get_interfaces () and - * salut_tubes_channel_get_property () too */ - NULL -}; - -enum -{ - PROP_OBJECT_PATH = 1, - PROP_CHANNEL_TYPE, - PROP_HANDLE_TYPE, - PROP_HANDLE, - PROP_CONNECTION, - PROP_MUC, - PROP_INTERFACES, - PROP_TARGET_ID, - PROP_REQUESTED, - PROP_INITIATOR_ID, - PROP_INITIATOR_HANDLE, - PROP_CHANNEL_DESTROYED, - PROP_CHANNEL_PROPERTIES, - - /* only for 1-1 tubes */ - PROP_CONTACT, - - LAST_PROPERTY -}; - -/* private structure */ -typedef struct _SalutTubesChannelPrivate SalutTubesChannelPrivate; - -struct _SalutTubesChannelPrivate -{ - SalutConnection *conn; - gchar *object_path; - TpHandle handle; - TpHandleType handle_type; - TpHandle self_handle; - TpHandle initiator; - gboolean requested; - /* Used for MUC tubes channel only */ - GibberMucConnection *muc_connection; - - /* Used for 1-1 tubes channel */ - SalutContact *contact; - ChannelState state; - - /* guint tube_id -> SalutTubeDBus tube */ - GHashTable *tubes; - - gboolean closed; - gboolean dispose_has_run; -}; - -#define SALUT_TUBES_CHANNEL_GET_PRIVATE(obj) \ - ((SalutTubesChannelPrivate *) ((SalutTubesChannel *) obj)->priv) - -static gboolean update_tubes_info (SalutTubesChannel *self); -static void muc_connection_lost_senders_cb (GibberMucConnection *conn, - GArray *senders, gpointer user_data); -static void muc_connection_new_senders_cb (GibberMucConnection *conn, - GArray *senders, gpointer user_data); -static gboolean extract_tube_information (SalutTubesChannel *self, - WockyNode *tube_node, TpTubeType *type, TpHandle *initiator_handle, - const gchar **service, GHashTable **parameters, guint *tube_id); -static SalutTubeIface * create_new_tube (SalutTubesChannel *self, - TpTubeType type, TpHandle initiator, gboolean offered, - const gchar *service, GHashTable *parameters, guint tube_id, guint portnum, - WockyStanza *iq_req, gboolean requested); - -static void -salut_tubes_channel_init (SalutTubesChannel *self) -{ - SalutTubesChannelPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - SALUT_TYPE_TUBES_CHANNEL, SalutTubesChannelPrivate); - - self->priv = priv; - - priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) g_object_unref); - - priv->contact = NULL; - priv->state = CHANNEL_NOT_CONNECTED; - - priv->dispose_has_run = FALSE; - priv->closed = FALSE; -} - -static GObject * -salut_tubes_channel_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *obj; - SalutTubesChannel *self; - SalutTubesChannelPrivate *priv; - TpDBusDaemon *bus; - TpBaseConnection *base_conn; - - obj = G_OBJECT_CLASS (salut_tubes_channel_parent_class)-> - constructor (type, n_props, props); - - self = SALUT_TUBES_CHANNEL (obj); - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - base_conn = TP_BASE_CONNECTION (priv->conn); - - switch (priv->handle_type) - { - case TP_HANDLE_TYPE_CONTACT: - g_assert (self->muc == NULL); - priv->self_handle = ((TpBaseConnection *) - (priv->conn))->self_handle; - break; - - case TP_HANDLE_TYPE_ROOM: - g_assert (self->muc != NULL); - priv->self_handle = self->muc->group.self_handle; - tp_external_group_mixin_init (obj, (GObject *) self->muc); - g_object_get (self->muc, - "muc-connection", &(priv->muc_connection), - NULL); - g_assert (priv->muc_connection != NULL); - - g_signal_connect (priv->muc_connection, "new-senders", - G_CALLBACK (muc_connection_new_senders_cb), self); - g_signal_connect (priv->muc_connection, "lost-senders", - G_CALLBACK (muc_connection_lost_senders_cb), self); - - break; - default: - g_assert_not_reached (); - } - - /* Connect to the bus */ - bus = tp_base_connection_get_dbus_daemon (base_conn); - tp_dbus_daemon_register_object (bus, priv->object_path, obj); - - DEBUG ("Registering at '%s'", priv->object_path); - - return obj; -} - -static void -salut_tubes_channel_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - SalutTubesChannel *chan = SALUT_TUBES_CHANNEL (object); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (chan); - - switch (property_id) - { - case PROP_OBJECT_PATH: - g_value_set_string (value, priv->object_path); - break; - case PROP_CHANNEL_TYPE: - g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_TUBES); - break; - case PROP_HANDLE_TYPE: - g_value_set_uint (value, priv->handle_type); - break; - case PROP_HANDLE: - g_value_set_uint (value, priv->handle); - break; - case PROP_CONNECTION: - g_value_set_object (value, priv->conn); - break; - case PROP_MUC: - g_value_set_object (value, chan->muc); - break; - case PROP_CONTACT: - g_value_set_object (value, priv->contact); - break; - case PROP_INTERFACES: - if (chan->muc) - g_value_set_static_boxed (value, salut_tubes_channel_interfaces); - else - g_value_set_static_boxed (value, salut_tubes_channel_interfaces + 1); - break; - case PROP_TARGET_ID: - { - TpHandleRepoIface *repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, priv->handle_type); - - g_value_set_string (value, tp_handle_inspect (repo, priv->handle)); - } - break; - case PROP_INITIATOR_HANDLE: - g_assert (priv->initiator != 0); - g_value_set_uint (value, priv->initiator); - break; - case PROP_INITIATOR_ID: - { - TpHandleRepoIface *repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - - g_assert (priv->initiator != 0); - g_value_set_string (value, tp_handle_inspect (repo, priv->initiator)); - } - break; - case PROP_REQUESTED: - g_value_set_boolean (value, priv->requested); - break; - case PROP_CHANNEL_DESTROYED: - g_value_set_boolean (value, priv->closed); - break; - case PROP_CHANNEL_PROPERTIES: - g_value_take_boxed (value, - tp_dbus_properties_mixin_make_properties_hash (object, - TP_IFACE_CHANNEL, "TargetHandle", - TP_IFACE_CHANNEL, "TargetHandleType", - TP_IFACE_CHANNEL, "ChannelType", - TP_IFACE_CHANNEL, "TargetID", - TP_IFACE_CHANNEL, "InitiatorHandle", - TP_IFACE_CHANNEL, "InitiatorID", - TP_IFACE_CHANNEL, "Requested", - TP_IFACE_CHANNEL, "Interfaces", - NULL)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -salut_tubes_channel_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - SalutTubesChannel *chan = SALUT_TUBES_CHANNEL (object); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (chan); - const gchar *value_str; - - switch (property_id) - { - case PROP_OBJECT_PATH: - g_free (priv->object_path); - priv->object_path = g_value_dup_string (value); - break; - case PROP_CHANNEL_TYPE: - /* this property is writable in the interface (in - * telepathy-glib > 0.7.0), but not actually - * meaningfully changeable on this channel, so we do nothing */ - value_str = g_value_get_string (value); - g_assert (value_str == NULL || !tp_strdiff (value_str, - TP_IFACE_CHANNEL_TYPE_TUBES)); - break; - case PROP_HANDLE_TYPE: - priv->handle_type = g_value_get_uint (value); - break; - case PROP_HANDLE: - priv->handle = g_value_get_uint (value); - break; - case PROP_CONNECTION: - priv->conn = g_value_get_object (value); - break; - case PROP_MUC: - chan->muc = g_value_get_object (value); - break; - case PROP_CONTACT: - priv->contact = g_value_get_object (value); - /* contact is set only for 1-1 tubes */ - if (priv->contact != NULL) - g_object_ref (priv->contact); - break; - case PROP_INITIATOR_HANDLE: - priv->initiator = g_value_get_uint (value); - g_assert (priv->initiator != 0); - break; - case PROP_REQUESTED: - priv->requested = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -setup_connection (SalutTubesChannel *self) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - DEBUG ("setting up the tubes channel"); - - if (priv->state == CHANNEL_CONNECTING) - return; - - priv->state = CHANNEL_CONNECTED; - DEBUG ("priv->state = CHANNEL_CONNECTED"); - salut_tubes_channel_send_iq_offer (self); -} - -static void -d_bus_names_changed_added (SalutTubesChannel *self, - guint tube_id, - TpHandle contact, - const gchar *new_name) -{ - GPtrArray *added = g_ptr_array_sized_new (1); - GArray *removed = g_array_new (FALSE, FALSE, sizeof (guint)); - GValue tmp = {0,}; - guint i; - - g_value_init (&tmp, DBUS_NAME_PAIR_TYPE); - g_value_take_boxed (&tmp, - dbus_g_type_specialized_construct (DBUS_NAME_PAIR_TYPE)); - dbus_g_type_struct_set (&tmp, - 0, contact, - 1, new_name, - G_MAXUINT); - g_ptr_array_add (added, g_value_get_boxed (&tmp)); - - tp_svc_channel_type_tubes_emit_d_bus_names_changed (self, - tube_id, added, removed); - - for (i = 0; i < added->len; i++) - g_boxed_free (DBUS_NAME_PAIR_TYPE, added->pdata[i]); - g_ptr_array_unref (added); - g_array_unref (removed); -} - -static void -d_bus_names_changed_removed (SalutTubesChannel *self, - guint tube_id, - TpHandle contact) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - GPtrArray *added; - GArray *removed; - - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - return; - - added = g_ptr_array_new (); - removed = g_array_new (FALSE, FALSE, sizeof (guint)); - - g_array_append_val (removed, contact); - - tp_svc_channel_type_tubes_emit_d_bus_names_changed (self, - tube_id, added, removed); - - g_ptr_array_unref (added); - g_array_unref (removed); -} - -static void -add_name_in_dbus_names (SalutTubesChannel *self, - guint tube_id, - TpHandle handle, - const gchar *dbus_name) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - SalutTubeDBus *tube; - - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - return; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - if (tube == NULL) - return; - - if (salut_tube_dbus_add_name (tube, handle, dbus_name)) - { - /* Emit the DBusNamesChanged signal */ - d_bus_names_changed_added (self, tube_id, handle, dbus_name); - } -} - -static void -add_yourself_in_dbus_names (SalutTubesChannel *self, - guint tube_id) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - SalutTubeDBus *tube; - gchar *dbus_name; - - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - return; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - if (tube == NULL) - return; - - g_object_get (tube, - "dbus-name", &dbus_name, - NULL); - - add_name_in_dbus_names (self, tube_id, priv->self_handle, dbus_name); - - g_free (dbus_name); -} - -/** - * salut_tubes_channel_get_available_tube_types - * - * Implements D-Bus method GetAvailableTubeTypes - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_get_available_tube_types (TpSvcChannelTypeTubes *iface, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - GArray *ret; - TpTubeType type; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - ret = g_array_sized_new (FALSE, FALSE, sizeof (TpTubeType), 1); - type = TP_TUBE_TYPE_DBUS; - g_array_append_val (ret, type); - type = TP_TUBE_TYPE_STREAM; - g_array_append_val (ret, type); - - tp_svc_channel_type_tubes_return_from_get_available_tube_types (context, - ret); - - g_array_unref (ret); -} - -struct _add_in_old_dbus_tubes_data -{ - GHashTable *old_dbus_tubes; - TpHandle contact; -}; - -static void -add_in_old_dbus_tubes (gpointer key, - gpointer value, - gpointer user_data) -{ - guint tube_id = GPOINTER_TO_UINT (key); - SalutTubeIface *tube = SALUT_TUBE_IFACE (value); - struct _add_in_old_dbus_tubes_data *data = - (struct _add_in_old_dbus_tubes_data *) user_data; - TpTubeType type; - - g_object_get (tube, "type", &type, NULL); - - if (type != TP_TUBE_TYPE_DBUS) - return; - - if (salut_tube_dbus_handle_in_names (SALUT_TUBE_DBUS (tube), - data->contact)) - { - /* contact was in this tube */ - g_hash_table_insert (data->old_dbus_tubes, GUINT_TO_POINTER (tube_id), - tube); - } -} - -struct -emit_d_bus_names_changed_foreach_data -{ - SalutTubesChannel *self; - TpHandle contact; -}; - -static void -emit_d_bus_names_changed_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - guint tube_id = GPOINTER_TO_UINT (key); - SalutTubeDBus *tube = SALUT_TUBE_DBUS (value); - struct emit_d_bus_names_changed_foreach_data *data = - (struct emit_d_bus_names_changed_foreach_data *) user_data; - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE ( - data->self); - - if (salut_tube_dbus_remove_name (tube, data->contact)) - { - /* Emit the DBusNamesChanged signal */ - d_bus_names_changed_removed (data->self, tube_id, data->contact); - } - - /* Remove the contact as sender in the muc bytestream */ - if (priv->handle_type == TP_HANDLE_TYPE_ROOM) - { - GibberBytestreamIface *bytestream; - - g_object_get (tube, "bytestream", &bytestream, NULL); - g_assert (bytestream != NULL); - - if (GIBBER_IS_BYTESTREAM_MUC (bytestream)) - { - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - const gchar *sender; - - sender = tp_handle_inspect (contact_repo, data->contact); - if (sender != NULL) - gibber_bytestream_muc_remove_sender ( - GIBBER_BYTESTREAM_MUC (bytestream), sender); - } - - g_object_unref (bytestream); - } -} - -/* MUC message */ -/* Return an array containing all the SalutTubeIface * channels that have been - * created due to this message. These channels have not been announced yet - * so it's the responsability of the caller to announce them. */ -GPtrArray * -salut_tubes_channel_muc_message_received (SalutTubesChannel *self, - const gchar *sender, - WockyStanza *stanza) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - TpHandle contact; - WockyNode *top_node = wocky_stanza_get_top_node (stanza); - WockyNode *tubes_node; - GSList *l; - GHashTable *old_dbus_tubes; - struct _add_in_old_dbus_tubes_data add_data; - struct emit_d_bus_names_changed_foreach_data emit_data; - WockyStanzaType stanza_type; - WockyStanzaSubType sub_type; - GPtrArray *result = g_ptr_array_new (); - - contact = tp_handle_lookup (contact_repo, sender, NULL, NULL); - g_assert (contact != 0); - - if (contact == priv->self_handle) - /* We don't need to inspect our own tubes */ - return result; - - wocky_stanza_get_type_info (stanza, &stanza_type, &sub_type); - if (stanza_type != WOCKY_STANZA_TYPE_MESSAGE - || sub_type != WOCKY_STANZA_SUB_TYPE_GROUPCHAT) - return result; - - tubes_node = wocky_node_get_child_ns (top_node, "tubes", - WOCKY_TELEPATHY_NS_TUBES); - g_assert (tubes_node != NULL); - - /* Fill old_dbus_tubes with D-BUS tubes previoulsy announced by - * the contact */ - old_dbus_tubes = g_hash_table_new (g_direct_hash, g_direct_equal); - add_data.old_dbus_tubes = old_dbus_tubes; - add_data.contact = contact; - g_hash_table_foreach (priv->tubes, add_in_old_dbus_tubes, &add_data); - - for (l = tubes_node->children; l != NULL; l = l->next) - { - WockyNode *tube_node = (WockyNode *) l->data; - const gchar *stream_id; - SalutTubeIface *tube; - guint tube_id; - TpTubeType type; - - stream_id = wocky_node_get_attribute (tube_node, "stream-id"); - - if (!extract_tube_information (self, tube_node, NULL, - NULL, NULL, NULL, &tube_id)) - continue; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - - if (tube == NULL) - { - /* We don't know yet this tube */ - const gchar *service; - TpHandle initiator_handle; - GHashTable *parameters; - guint id; - - if (extract_tube_information (self, tube_node, &type, - &initiator_handle, &service, ¶meters, &id)) - { - switch (type) - { - case TP_TUBE_TYPE_DBUS: - { - if (initiator_handle == 0) - { - DEBUG ("D-Bus tube initiator missing"); - /* skip to the next child of */ - continue; - } - } - break; - case TP_TUBE_TYPE_STREAM: - { - initiator_handle = contact; - } - break; - default: - { - g_assert_not_reached (); - } - } - - tube = create_new_tube (self, type, initiator_handle, FALSE, - service, parameters, id, 0, NULL, FALSE); - g_ptr_array_add (result, tube); - - /* the tube has reffed its initiator, no need to keep a ref */ - g_hash_table_unref (parameters); - } - } - else - { - /* The contact is in the tube. - * Remove it from old_dbus_tubes if needed */ - g_hash_table_remove (old_dbus_tubes, GUINT_TO_POINTER (tube_id)); - } - - if (tube == NULL) - continue; - - g_object_get (tube, "type", &type, NULL); - - if (type == TP_TUBE_TYPE_DBUS) - { - /* Update mapping of handle -> D-Bus name. */ - if (!salut_tube_dbus_handle_in_names (SALUT_TUBE_DBUS (tube), - contact)) - { - /* Contact just joined the tube */ - const gchar *new_name; - - new_name = wocky_node_get_attribute (tube_node, - "dbus-name"); - - if (!new_name) - { - DEBUG ("Contact %u isn't announcing their D-Bus name", - contact); - continue; - } - - add_name_in_dbus_names (self, tube_id, contact, new_name); - - /* associate the contact with his stream id */ - if (priv->handle_type == TP_HANDLE_TYPE_ROOM) - { - GibberBytestreamIface *bytestream; - - g_object_get (tube, "bytestream", &bytestream, NULL); - g_assert (bytestream != NULL); - - if (GIBBER_IS_BYTESTREAM_MUC (bytestream)) - { - guint16 tmp = (guint16) atoi (stream_id); - - gibber_bytestream_muc_add_sender ( - GIBBER_BYTESTREAM_MUC (bytestream), sender, tmp); - } - - g_object_unref (bytestream); - } - } - } - } - - /* Tubes remaining in old_dbus_tubes was left by the contact */ - emit_data.contact = contact; - emit_data.self = self; - g_hash_table_foreach (old_dbus_tubes, emit_d_bus_names_changed_foreach, - &emit_data); - - g_hash_table_unref (old_dbus_tubes); - - return result; -} - -/* 1-1 message */ - -/* Return a newly created SalutTubeIface channel if it has been created - * due to this message. This channel has not been announced yet - * so it's the responsability of the caller to announce it. */ -SalutTubeIface * -salut_tubes_channel_message_received (SalutTubesChannel *self, - const gchar *service, - TpTubeType tube_type, - TpHandle initiator_handle, - GHashTable *parameters, - guint tube_id, - guint portnum, - WockyStanza *iq_req) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - SalutTubeIface *tube; - - /* do we already know this tube? */ - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - if (tube == NULL) - { - tube = create_new_tube (self, tube_type, initiator_handle, FALSE, - service, parameters, tube_id, portnum, iq_req, FALSE); - return tube; - } - - return NULL; -} - -void -salut_tubes_channel_message_close_received (SalutTubesChannel *self, - TpHandle initiator_handle, - guint tube_id) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - SalutTubeIface *tube; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - - if (tube) - { - DEBUG ("received a tube close message"); - salut_tube_iface_close (tube, TRUE); - } - else - { - DEBUG ("received a tube close message on a non existent tube"); - } -} - -static gint -generate_tube_id (void) -{ - return g_random_int_range (0, G_MAXINT); -} - -SalutTubeIface * -salut_tubes_channel_tube_request (SalutTubesChannel *self, - gpointer request_token, - GHashTable *request_properties, - gboolean require_new) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - SalutTubeIface *tube; - const gchar *channel_type; - const gchar *service; - guint tube_id; - TpTubeType type; - GHashTable *parameters; - - tube_id = generate_tube_id (); - - channel_type = tp_asv_get_string (request_properties, - TP_IFACE_CHANNEL ".ChannelType"); - - if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) - { - type = TP_TUBE_TYPE_STREAM; - service = tp_asv_get_string (request_properties, - TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service"); - - } - else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) - { - type = TP_TUBE_TYPE_DBUS; - service = tp_asv_get_string (request_properties, - TP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName"); - } - else - g_assert_not_reached (); - - /* if the service property is missing, the requestotron rejects the request - */ - g_assert (service != NULL); - - DEBUG ("Request a tube channel with type='%s' and service='%s'", - channel_type, service); - - /* requested tubes have an empty parameters dict */ - parameters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, - (GDestroyNotify) tp_g_value_slice_free); - - tube = create_new_tube (self, type, priv->self_handle, FALSE, service, - parameters, tube_id, 0, NULL, TRUE); - - g_hash_table_unref (parameters); - return tube; -} - -static void -muc_connection_new_senders_cb (GibberMucConnection *conn, - GArray *senders, - gpointer user_data) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data); - - update_tubes_info (self); -} - -static void -muc_connection_lost_senders_cb (GibberMucConnection *conn, - GArray *senders, - gpointer user_data) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - guint i; - - for (i = 0; i < senders->len; i++) - { - gchar *sender; - TpHandle contact; - GHashTable *old_dbus_tubes; - struct _add_in_old_dbus_tubes_data add_data; - struct emit_d_bus_names_changed_foreach_data emit_data; - - sender = g_array_index (senders, gchar *, i); - - contact = tp_handle_lookup (contact_repo, sender, NULL, NULL); - if (contact == 0) - { - DEBUG ("unknown sender: %s", sender); - return; - } - - old_dbus_tubes = g_hash_table_new (g_direct_hash, g_direct_equal); - add_data.old_dbus_tubes = old_dbus_tubes; - add_data.contact = contact; - g_hash_table_foreach (priv->tubes, add_in_old_dbus_tubes, &add_data); - - /* contact left the muc so he left all its tubes */ - emit_data.contact = contact; - emit_data.self = self; - g_hash_table_foreach (old_dbus_tubes, emit_d_bus_names_changed_foreach, - &emit_data); - - g_hash_table_unref (old_dbus_tubes); - } -} - -static void -copy_tube_in_ptr_array (gpointer key, - gpointer value, - gpointer user_data) -{ - SalutTubeIface *tube = (SalutTubeIface *) value; - guint tube_id = GPOINTER_TO_UINT(key); - TpHandle initiator; - gchar *service; - GHashTable *parameters; - TpTubeChannelState state; - TpTubeType type; - GPtrArray *array = (GPtrArray *) user_data; - GValue entry = {0,}; - - g_object_get (tube, - "type", &type, - "initiator-handle", &initiator, - "service", &service, - "parameters", ¶meters, - "state", &state, - NULL); - - g_value_init (&entry, SALUT_CHANNEL_TUBE_TYPE); - g_value_take_boxed (&entry, - dbus_g_type_specialized_construct (SALUT_CHANNEL_TUBE_TYPE)); - dbus_g_type_struct_set (&entry, - 0, tube_id, - 1, initiator, - 2, type, - 3, service, - 4, parameters, - 5, state, - G_MAXUINT); - - g_ptr_array_add (array, g_value_get_boxed (&entry)); - g_free (service); - g_hash_table_unref (parameters); -} - -static GPtrArray * -make_tubes_ptr_array (SalutTubesChannel *self, - GHashTable *tubes) -{ - GPtrArray *ret; - - ret = g_ptr_array_sized_new (g_hash_table_size (tubes)); - - g_hash_table_foreach (tubes, copy_tube_in_ptr_array, ret); - - return ret; -} - -/** - * salut_tubes_channel_list_tubes - * - * Implements D-Bus method ListTubes - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_list_tubes (TpSvcChannelTypeTubes *iface, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - GPtrArray *ret; - guint i; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - ret = make_tubes_ptr_array (self, priv->tubes); - tp_svc_channel_type_tubes_return_from_list_tubes (context, ret); - - for (i = 0; i < ret->len; i++) - g_boxed_free (SALUT_CHANNEL_TUBE_TYPE, ret->pdata[i]); - - g_ptr_array_unref (ret); -} - -static void -tube_closed_cb (SalutTubeIface *tube, - gpointer user_data) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - guint tube_id; - TpChannelManager *mgr; - - if (priv->closed) - return; - - g_object_get (tube, "id", &tube_id, NULL); - if (!g_hash_table_remove (priv->tubes, GUINT_TO_POINTER (tube_id))) - { - DEBUG ("Can't find tube having this id: %d", tube_id); - } - - DEBUG ("tube %d removed", tube_id); - - if (priv->handle_type == TP_HANDLE_TYPE_ROOM && SALUT_IS_TUBE_DBUS (tube)) - { - /* Emit the DBusNamesChanged signal */ - d_bus_names_changed_removed (self, tube_id, priv->self_handle); - } - - update_tubes_info (self); - - tp_svc_channel_type_tubes_emit_tube_closed (self, tube_id); - tp_svc_channel_emit_closed (tube); - - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - { - g_object_get (priv->conn, "tubes-manager", &mgr, NULL); - } - else - { - g_object_get (priv->conn, "muc-manager", &mgr, NULL); - } - - tp_channel_manager_emit_channel_closed_for_object (mgr, - TP_EXPORTABLE_CHANNEL (tube)); - - g_object_unref (mgr); -} - -static void -tube_opened_cb (SalutTubeIface *tube, - gpointer user_data) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data); - guint tube_id; - TpTubeType type; - - g_object_get (tube, - "id", &tube_id, - "type", &type, - NULL); - - if (type == TP_TUBE_TYPE_DBUS) - { - add_yourself_in_dbus_names (self, tube_id); - } - - update_tubes_info (self); - - tp_svc_channel_type_tubes_emit_tube_state_changed (self, tube_id, - TP_TUBE_STATE_OPEN); -} - -static void -tube_offered_cb (SalutTubeIface *tube, - gpointer user_data) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data); - guint tube_id; - TpHandle initiator; - TpTubeType type; - gchar *service; - GHashTable *parameters; - TpTubeState state; - - g_object_get (tube, - "id", &tube_id, - "initiator-handle", &initiator, - "type", &type, - "service", &service, - "parameters", ¶meters, - "state", &state, - NULL); - - /* tube has been offered and so can be announced using the old API */ - tp_svc_channel_type_tubes_emit_new_tube (self, - tube_id, - initiator, - type, - service, - parameters, - state); - - update_tubes_info (self); - - g_free (service); - g_hash_table_unref (parameters); -} - -static SalutTubeIface * -create_new_tube (SalutTubesChannel *self, - TpTubeType type, - TpHandle initiator, - gboolean offered, - const gchar *service, - GHashTable *parameters, - guint tube_id, - guint portnum, - WockyStanza *iq_req, - gboolean requested) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - SalutTubeIface *tube; - TpTubeChannelState state; - GibberMucConnection *muc_connection = NULL; - - if (self->muc != NULL) - g_object_get (self->muc, "muc-connection", &muc_connection, NULL); - - switch (type) - { - case TP_TUBE_TYPE_DBUS: - tube = SALUT_TUBE_IFACE (salut_tube_dbus_new (priv->conn, self, - priv->handle, priv->handle_type, priv->self_handle, muc_connection, - initiator, service, parameters, tube_id, requested)); - break; - case TP_TUBE_TYPE_STREAM: - tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, self, - priv->handle, priv->handle_type, - priv->self_handle, initiator, offered, service, parameters, - tube_id, portnum, iq_req, requested)); - break; - default: - g_assert_not_reached (); - } - - tp_base_channel_register ((TpBaseChannel *) tube); - - DEBUG ("create tube %u", tube_id); - g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), tube); - - g_object_get (tube, "state", &state, NULL); - - /* The old API doesn't know the "not offered" state, so we have to wait that - * the tube is offered before announcing it. */ - if (state != TP_TUBE_CHANNEL_STATE_NOT_OFFERED) - { - tp_svc_channel_type_tubes_emit_new_tube (self, - tube_id, - initiator, - type, - service, - parameters, - state); - } - - g_signal_connect (tube, "tube-opened", G_CALLBACK (tube_opened_cb), self); - g_signal_connect (tube, "tube-closed", G_CALLBACK (tube_closed_cb), self); - g_signal_connect (tube, "tube-offered", G_CALLBACK (tube_offered_cb), self); - - if (muc_connection != NULL) - g_object_unref (muc_connection); - - return tube; -} - -/* tube_node is a MUC */ -static gboolean -extract_tube_information (SalutTubesChannel *self, - WockyNode *tube_node, - TpTubeType *type, - TpHandle *initiator_handle, - const gchar **service, - GHashTable **parameters, - guint *tube_id) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - - if (type != NULL) - { - const gchar *_type; - - _type = wocky_node_get_attribute (tube_node, "type"); - - - if (!tp_strdiff (_type, "stream")) - { - *type = TP_TUBE_TYPE_STREAM; - } - else if (!tp_strdiff (_type, "dbus")) - { - *type = TP_TUBE_TYPE_DBUS; - } - else - { - DEBUG ("Unknown tube type: %s", _type); - return FALSE; - } - } - - if (initiator_handle != NULL) - { - const gchar *initiator; - - initiator = wocky_node_get_attribute (tube_node, "initiator"); - - if (initiator != NULL) - { - *initiator_handle = tp_handle_ensure (contact_repo, initiator, NULL, - NULL); - - if (*initiator_handle == 0) - { - DEBUG ("invalid initiator ID %s", initiator); - return FALSE; - } - } - else - { - *initiator_handle = 0; - } - } - - if (service != NULL) - { - *service = wocky_node_get_attribute (tube_node, "service"); - } - - if (parameters != NULL) - { - WockyNode *node; - - node = wocky_node_get_child (tube_node, "parameters"); - *parameters = salut_wocky_node_extract_properties (node, - "parameter"); - } - - if (tube_id != NULL) - { - const gchar *str; - gchar *endptr; - long int tmp; - - str = wocky_node_get_attribute (tube_node, "id"); - if (str == NULL) - { - DEBUG ("no tube id in SI request"); - return FALSE; - } - - tmp = strtol (str, &endptr, 10); - if (!endptr || *endptr) - { - DEBUG ("tube id is not numeric: %s", str); - return FALSE; - } - *tube_id = (int) tmp; - } - - return TRUE; -} - -static void -publish_tube_in_node (SalutTubesChannel *self, - WockyNode *node, - SalutTubeIface *tube) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - WockyNode *parameters_node; - GHashTable *parameters; - TpTubeType type; - gchar *service, *id_str; - guint tube_id; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - TpHandle initiator_handle; - - g_object_get (G_OBJECT (tube), - "type", &type, - "initiator-handle", &initiator_handle, - "service", &service, - "parameters", ¶meters, - "id", &tube_id, - NULL); - - id_str = g_strdup_printf ("%u", tube_id); - - wocky_node_set_attribute (node, "service", service); - wocky_node_set_attribute (node, "id", id_str); - - g_free (id_str); - - switch (type) - { - case TP_TUBE_TYPE_DBUS: - { - gchar *name, *stream_id; - - g_object_get (G_OBJECT (tube), - "dbus-name", &name, - "stream-id", &stream_id, - NULL); - - wocky_node_set_attribute (node, "type", "dbus"); - wocky_node_set_attribute (node, "stream-id", stream_id); - wocky_node_set_attribute (node, "initiator", - tp_handle_inspect (contact_repo, initiator_handle)); - - if (name != NULL) - wocky_node_set_attribute (node, "dbus-name", name); - - g_free (name); - g_free (stream_id); - - } - break; - case TP_TUBE_TYPE_STREAM: - wocky_node_set_attribute (node, "type", "stream"); - break; - default: - g_assert_not_reached (); - } - - parameters_node = wocky_node_add_child (node, "parameters"); - salut_wocky_node_add_children_from_properties (parameters_node, - parameters, "parameter"); - - g_free (service); - g_hash_table_unref (parameters); -} - -struct _i_hate_g_hash_table_foreach -{ - SalutTubesChannel *self; - WockyNode *tubes_node; -}; - -static void -publish_tubes_in_node (gpointer key, - gpointer value, - gpointer user_data) -{ - SalutTubeIface *tube = (SalutTubeIface *) value; - struct _i_hate_g_hash_table_foreach *data = - (struct _i_hate_g_hash_table_foreach *) user_data; - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE ( - data->self); - TpTubeChannelState state; - WockyNode *tube_node; - TpTubeType type; - TpHandle initiator; - - if (tube == NULL) - return; - - g_object_get (tube, - "state", &state, - "type", &type, - "initiator-handle", &initiator, - NULL); - - if (state != TP_TUBE_CHANNEL_STATE_OPEN) - return; - - if (type == TP_TUBE_TYPE_STREAM && initiator != priv->self_handle) - /* We only announce stream tubes we initiated */ - return; - - tube_node = wocky_node_add_child (data->tubes_node, "tube"); - publish_tube_in_node (data->self, tube_node, tube); -} - -static gboolean -update_tubes_info (SalutTubesChannel *self) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - TpBaseConnection *conn = (TpBaseConnection *) priv->conn; - TpHandleRepoIface *room_repo = tp_base_connection_get_handles ( - conn, TP_HANDLE_TYPE_ROOM); - WockyStanza *msg; - WockyNode *msg_node; - WockyNode *node; - const gchar *jid; - struct _i_hate_g_hash_table_foreach data; - GError *error = NULL; - - if (priv->handle_type != TP_HANDLE_TYPE_ROOM) - return FALSE; - - /* build the message */ - jid = tp_handle_inspect (room_repo, priv->handle); - - msg = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, - WOCKY_STANZA_SUB_TYPE_GROUPCHAT, - priv->conn->name, jid, - WOCKY_NODE_START, "tubes", - WOCKY_NODE_XMLNS, WOCKY_TELEPATHY_NS_TUBES, - WOCKY_NODE_END, NULL); - msg_node = wocky_stanza_get_top_node (msg); - - node = wocky_node_get_child_ns (msg_node, "tubes", - WOCKY_TELEPATHY_NS_TUBES); - - data.self = self; - data.tubes_node = node; - - g_hash_table_foreach (priv->tubes, publish_tubes_in_node, &data); - - /* Send it */ - if (!gibber_muc_connection_send (priv->muc_connection, msg, &error)) - { - g_warning ("%s: sending tubes info failed: %s", G_STRFUNC, - error->message); - g_error_free (error); - g_object_unref (msg); - return FALSE; - } - - g_object_unref (msg); - return TRUE; -} - -/** - * salut_tubes_channel_offer_d_bus_tube - * - * Implements D-Bus method OfferDBusTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_offer_d_bus_tube (TpSvcChannelTypeTubes *iface, - const gchar *service, - GHashTable *parameters, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - guint tube_id; - SalutTubeIface *tube; - GError *err = NULL; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - if (priv->handle_type == TP_HANDLE_TYPE_ROOM - && !tp_handle_set_is_member (TP_GROUP_MIXIN (self->muc)->members, - priv->self_handle)) - { - GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "Tube channel isn't connected" }; - - dbus_g_method_return_error (context, &error); - return; - } - - tube_id = generate_tube_id (); - - tube = create_new_tube (self, TP_TUBE_TYPE_DBUS, priv->self_handle, - TRUE, service, parameters, tube_id, 0, NULL, TRUE); - - if (!salut_tube_dbus_offer (SALUT_TUBE_DBUS (tube), &err)) - { - salut_tube_iface_close (tube, TRUE); - dbus_g_method_return_error (context, err); - - g_error_free (err); - return; - } - - tp_svc_channel_type_tubes_return_from_offer_d_bus_tube (context, tube_id); -} - -/** - * salut_tubes_channel_accept_d_bus_tube - * - * Implements D-Bus method AcceptDBusTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_accept_d_bus_tube (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - SalutTubeIface *tube; - TpTubeChannelState state; - TpTubeType type; - gchar *addr; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - if (tube == NULL) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &error); - - return; - } - - g_object_get (tube, - "type", &type, - "state", &state, - NULL); - - if (type != TP_TUBE_TYPE_DBUS) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a D-Bus tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - if (state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Tube is not in the local pending state" }; - - dbus_g_method_return_error (context, &error); - - return; - } - - salut_tube_iface_accept (tube, NULL); - - g_object_get (tube, - "dbus-address", &addr, - NULL); - - add_yourself_in_dbus_names (self, id); - - tp_svc_channel_type_tubes_return_from_accept_d_bus_tube (context, addr); - g_free (addr); -} - -/** - * salut_tubes_channel_close_tube - * - * Implements D-Bus method CloseTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_close_tube (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - SalutTubeIface *tube; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - if (tube == NULL) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - salut_tube_iface_close (tube, FALSE); - - tp_svc_channel_type_tubes_return_from_close_tube (context); -} - -/** - * salut_tubes_channel_get_d_bus_tube_address - * - * Implements D-Bus method GetDBusTubeAddress - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_get_d_bus_tube_address (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - SalutTubeIface *tube; - gchar *addr; - TpTubeType type; - TpTubeChannelState state; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - - if (tube == NULL) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - g_object_get (tube, - "type", &type, - "state", &state, - NULL); - - if (type != TP_TUBE_TYPE_DBUS) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a D-Bus tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - if (state != TP_TUBE_CHANNEL_STATE_OPEN) - { - GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "Tube is not open" }; - - dbus_g_method_return_error (context, &error); - return; - } - - g_object_get (tube, "dbus-address", &addr, NULL); - tp_svc_channel_type_tubes_return_from_get_d_bus_tube_address (context, - addr); - g_free (addr); -} - -static void -get_d_bus_names_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - GPtrArray *ret = user_data; - GValue tmp = {0,}; - - g_value_init (&tmp, DBUS_NAME_PAIR_TYPE); - g_value_take_boxed (&tmp, - dbus_g_type_specialized_construct (DBUS_NAME_PAIR_TYPE)); - dbus_g_type_struct_set (&tmp, - 0, key, - 1, value, - G_MAXUINT); - g_ptr_array_add (ret, g_value_get_boxed (&tmp)); -} - -/** - * salut_tubes_channel_get_d_bus_names - * - * Implements D-Bus method GetDBusNames - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_get_d_bus_names (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - SalutTubeIface *tube; - GHashTable *names; - GPtrArray *ret; - TpTubeType type; - TpTubeChannelState state; - guint i; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - - if (tube == NULL) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - g_object_get (tube, - "type", &type, - "state", &state, - NULL); - - if (type != TP_TUBE_TYPE_DBUS) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a D-Bus tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - if (state != TP_TUBE_CHANNEL_STATE_OPEN) - { - GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "Tube is not open" }; - - dbus_g_method_return_error (context, &error); - return; - } - - g_object_get (tube, "dbus-names", &names, NULL); - g_assert (names); - - ret = g_ptr_array_sized_new (g_hash_table_size (names)); - g_hash_table_foreach (names, get_d_bus_names_foreach, ret); - - tp_svc_channel_type_tubes_return_from_get_d_bus_names (context, ret); - - for (i = 0; i < ret->len; i++) - g_boxed_free (DBUS_NAME_PAIR_TYPE, ret->pdata[i]); - g_hash_table_unref (names); - g_ptr_array_unref (ret); -} - -static void -stream_tube_new_connection_cb (SalutTubeIface *tube, - guint contact, - gpointer user_data) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data); - guint tube_id; - TpTubeType type; - - g_object_get (tube, - "id", &tube_id, - "type", &type, - NULL); - - g_assert (type == TP_TUBE_TYPE_STREAM); - - tp_svc_channel_type_tubes_emit_stream_tube_new_connection (self, - tube_id, contact); -} - -static void -iq_reply_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - WockyPorter *porter = WOCKY_PORTER (source_object); - SalutTubeIface *tube = (SalutTubeIface *) user_data; - WockyStanzaSubType sub_type; - WockyStanza *reply_stanza; - GError *error = NULL; - - reply_stanza = wocky_porter_send_iq_finish (porter, result, &error); - - if (reply_stanza == NULL) - { - DEBUG ("Failed to send IQ: %s", error->message); - salut_tube_iface_close (tube, TRUE); - g_clear_error (&error); - return; - } - - wocky_stanza_get_type_info (reply_stanza, NULL, &sub_type); - if (sub_type != WOCKY_STANZA_SUB_TYPE_RESULT) - { - DEBUG ("The contact has declined our tube offer"); - salut_tube_iface_close (tube, TRUE); - return; - } - - salut_tube_iface_accepted (tube); - - DEBUG ("The contact has accepted our tube offer"); -} - -static void -send_channel_iq_tube (gpointer key, - gpointer value, - gpointer user_data) -{ - SalutTubesChannel *self = (SalutTubesChannel *) user_data; - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - SalutTubeIface *tube = (SalutTubeIface *) value; - guint tube_id = GPOINTER_TO_UINT (key); - TpHandle initiator; - gchar *service; - GHashTable *parameters; - TpTubeChannelState state; - TpTubeType type; - - g_object_get (tube, - "type", &type, - "initiator-handle", &initiator, - "service", &service, - "parameters", ¶meters, - "state", &state, - NULL); - - if (state != TP_TUBE_CHANNEL_STATE_NOT_OFFERED && - salut_tube_iface_offer_needed (tube)) - { - WockyNode *parameters_node; - const char *tube_type_str; - WockyStanza *stanza; - WockyNode *top_node; - const gchar *jid_from; - TpHandleRepoIface *contact_repo; - gchar *tube_id_str; - int port; - gchar *port_str; - - DEBUG ("Listening for connections from the remote contact " - "and sending the tube offer stanza"); - - /* listen for future connections from the remote CM before sending the - * iq */ - port = salut_tube_iface_listen (tube); - g_assert (port > 0); - - contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - - jid_from = tp_handle_inspect (contact_repo, priv->self_handle); - - switch (type) - { - case TP_TUBE_TYPE_DBUS: - tube_type_str = "dbus"; - break; - - case TP_TUBE_TYPE_STREAM: - tube_type_str = "stream"; - break; - default: - g_assert_not_reached (); - } - - port_str = g_strdup_printf ("%d", port); - tube_id_str = g_strdup_printf ("%d", tube_id); - - stanza = wocky_stanza_build_to_contact (WOCKY_STANZA_TYPE_IQ, - WOCKY_STANZA_SUB_TYPE_SET, - jid_from, WOCKY_CONTACT (priv->contact), - WOCKY_NODE_START, "tube", - WOCKY_NODE_XMLNS, WOCKY_TELEPATHY_NS_TUBES, - WOCKY_NODE_ATTRIBUTE, "type", tube_type_str, - WOCKY_NODE_ATTRIBUTE, "service", service, - WOCKY_NODE_ATTRIBUTE, "id", tube_id_str, - WOCKY_NODE_START, "transport", - WOCKY_NODE_ATTRIBUTE, "port", port_str, - WOCKY_NODE_END, - WOCKY_NODE_END, - NULL); - top_node = wocky_stanza_get_top_node (stanza); - - parameters_node = wocky_node_add_child ( - wocky_node_get_child (top_node, "tube"), "parameters"); - salut_wocky_node_add_children_from_properties (parameters_node, - parameters, "parameter"); - - wocky_porter_send_iq_async (priv->conn->porter, stanza, - NULL, iq_reply_cb, tube); - - g_object_unref (stanza); - g_free (tube_id_str); - g_free (port_str); - } - - g_free (service); - g_hash_table_unref (parameters); -} - -/** - * Send iq offer(s) for all tubes in this channel to the remote contact in iq - * stanza(s). If the XmppConnection is not established, try to establish it, - * and the offer will be sent later asynchronously. - * - * Iq stanzas are sent only when the tube has not been offered yet. It asks - * each tube whether it is really needed with salut_tube_iface_offer_needed() - * - * This is called when the client offer the tube, either via the old - * Channel.Type.Tubes interface, or the new Channel.Type.{Stream,DBus}Tube - * interface. This is also called when the XmppConnection is established in - * case a tube was offered while the XmppConnection was not established. - */ -void -salut_tubes_channel_send_iq_offer (SalutTubesChannel *self) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - if (priv->state != CHANNEL_CONNECTED) - { - /* TODO: do not connect if nothing to send... */ - setup_connection (self); - return; - } - - g_hash_table_foreach (priv->tubes, send_channel_iq_tube, self); -} - - -/** - * salut_tubes_channel_offer_stream_tube - * - * Implements D-Bus method OfferStreamTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_offer_stream_tube (TpSvcChannelTypeTubes *iface, - const gchar *service, - GHashTable *parameters, - guint address_type, - const GValue *address, - guint access_control, - const GValue *access_control_param, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - guint tube_id; - SalutTubeIface *tube; - GError *error = NULL; - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - if (priv->handle_type == TP_HANDLE_TYPE_ROOM - && !tp_handle_set_is_member (TP_GROUP_MIXIN (self->muc)->members, - priv->self_handle)) - { - GError err = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "Tube channel isn't connected" }; - - dbus_g_method_return_error (context, &err); - return; - } - - if (!salut_tube_stream_check_params (address_type, address, - access_control, access_control_param, &error)) - { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - tube_id = generate_tube_id (); - - tube = create_new_tube (self, TP_TUBE_TYPE_STREAM, priv->self_handle, - TRUE, service, parameters, tube_id, 0, NULL, TRUE); - - g_object_set (tube, - "address-type", address_type, - "address", address, - "access-control", access_control, - "access-control-param", access_control_param, - NULL); - - if (!salut_tube_stream_offer (SALUT_TUBE_STREAM (tube), &error)) - { - salut_tube_iface_close (tube, TRUE); - - dbus_g_method_return_error (context, error); - return; - } - - g_signal_connect (tube, "tube-new-connection", - G_CALLBACK (stream_tube_new_connection_cb), self); - - tp_svc_channel_type_tubes_return_from_offer_stream_tube (context, - tube_id); -} - -/** - * salut_tubes_channel_accept_stream_tube - * - * Implements D-Bus method AcceptStreamTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_accept_stream_tube (TpSvcChannelTypeTubes *iface, - guint id, - guint address_type, - guint access_control, - const GValue *access_control_param, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - SalutTubeIface *tube; - TpTubeChannelState state; - TpTubeType type; - GValue *address; - GError *error = NULL; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - if (tube == NULL) - { - GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &err); - return; - } - - if (address_type != TP_SOCKET_ADDRESS_TYPE_UNIX && - address_type != TP_SOCKET_ADDRESS_TYPE_IPV4 && - address_type != TP_SOCKET_ADDRESS_TYPE_IPV6) - { - GError *err = NULL; - - err = g_error_new (TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, - "Address type %d not implemented", address_type); - - dbus_g_method_return_error (context, err); - - g_error_free (err); - return; - } - - if (access_control != TP_SOCKET_ACCESS_CONTROL_LOCALHOST) - { - GError *err = NULL; - - err = g_error_new (TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Unix sockets only support localhost control access"); - - dbus_g_method_return_error (context, err); - - g_error_free (err); - return; - } - - g_object_get (tube, - "type", &type, - "state", &state, - NULL); - - if (type != TP_TUBE_TYPE_STREAM) - { - GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a stream tube" }; - - dbus_g_method_return_error (context, &err); - return; - } - - if (state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING) - { - GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Tube is not in the local pending state" }; - - dbus_g_method_return_error (context, &err); - return; - } - - g_object_set (tube, - "address-type", address_type, - "access-control", access_control, - "access-control-param", access_control_param, - NULL); - - if (!salut_tube_iface_accept (tube, &error)) - { - dbus_g_method_return_error (context, error); - return; - } - - g_object_get (tube, "address", &address, NULL); - - tp_svc_channel_type_tubes_return_from_accept_stream_tube (context, - address); -} - -/** - * salut_tubes_channel_get_stream_tube_socket_address - * - * Implements D-Bus method GetStreamTubeSocketAddress - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_get_stream_tube_socket_address (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - SalutTubeIface *tube; - TpTubeType type; - TpTubeChannelState state; - GValue *address; - TpSocketAddressType address_type; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - if (tube == NULL) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - g_object_get (tube, - "type", &type, - "state", &state, - NULL); - - if (type != TP_TUBE_TYPE_STREAM) - { - GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a Stream tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - if (state != TP_TUBE_CHANNEL_STATE_OPEN) - { - GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "Tube is not open" }; - - dbus_g_method_return_error (context, &error); - return; - } - - g_object_get (tube, - "address", &address, - "address-type", &address_type, - NULL); - - tp_svc_channel_type_tubes_return_from_get_stream_tube_socket_address ( - context, address_type, address); -} - -/** - * salut_tubes_channel_get_available_stream_tube_types - * - * Implements D-Bus method GetAvailableStreamTubeTypes - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -salut_tubes_channel_get_available_stream_tube_types ( - TpSvcChannelTypeTubes *iface, - DBusGMethodInvocation *context) -{ - GHashTable *ret; - - ret = salut_tube_stream_get_supported_socket_types (); - - tp_svc_channel_type_tubes_return_from_get_available_stream_tube_types ( - context, ret); - - g_hash_table_unref (ret); -} - -static void salut_tubes_channel_dispose (GObject *object); -static void salut_tubes_channel_finalize (GObject *object); - -static void -salut_tubes_channel_class_init ( - SalutTubesChannelClass *salut_tubes_channel_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (salut_tubes_channel_class); - GParamSpec *param_spec; - static TpDBusPropertiesMixinPropImpl channel_props[] = { - { "TargetHandleType", "handle-type", NULL }, - { "TargetHandle", "handle", NULL }, - { "TargetID", "target-id", NULL }, - { "ChannelType", "channel-type", NULL }, - { "Interfaces", "interfaces", NULL }, - { "Requested", "requested", NULL }, - { "InitiatorHandle", "initiator-handle", NULL }, - { "InitiatorID", "initiator-id", NULL }, - { NULL } - }; - static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { - { TP_IFACE_CHANNEL, - tp_dbus_properties_mixin_getter_gobject_properties, - NULL, - channel_props, - }, - { NULL } - }; - - g_type_class_add_private (salut_tubes_channel_class, - sizeof (SalutTubesChannelPrivate)); - - object_class->constructor = salut_tubes_channel_constructor; - - object_class->dispose = salut_tubes_channel_dispose; - object_class->finalize = salut_tubes_channel_finalize; - - object_class->get_property = salut_tubes_channel_get_property; - object_class->set_property = salut_tubes_channel_set_property; - - g_object_class_override_property (object_class, PROP_OBJECT_PATH, - "object-path"); - g_object_class_override_property (object_class, PROP_CHANNEL_TYPE, - "channel-type"); - g_object_class_override_property (object_class, PROP_HANDLE_TYPE, - "handle-type"); - g_object_class_override_property (object_class, PROP_HANDLE, "handle"); - - g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED, - "channel-destroyed"); - g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES, - "channel-properties"); - - param_spec = g_param_spec_string ("target-id", "Target JID", - "The string obtained by inspecting this channel's handle", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec); - - param_spec = g_param_spec_boolean ("requested", "Requested?", - "True if this channel was requested by the local user", - FALSE, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_REQUESTED, param_spec); - - param_spec = g_param_spec_uint ("initiator-handle", "Initiator's handle", - "The contact which caused the Tubes channel to appear", - 0, G_MAXUINT32, 0, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INITIATOR_HANDLE, - param_spec); - - param_spec = g_param_spec_string ("initiator-id", "Initiator JID", - "The string obtained by inspecting this channel's initiator-handle", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INITIATOR_ID, - param_spec); - - param_spec = g_param_spec_object ( - "connection", - "SalutConnection object", - "Salut Connection that owns the connection for this tubes channel", - SALUT_TYPE_CONNECTION, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_CONNECTION, param_spec); - - param_spec = g_param_spec_object ( - "muc", - "SalutMucChannel object", - "Salut text MUC channel corresponding to this Tubes channel object, " - "if the handle type is ROOM.", - SALUT_TYPE_MUC_CHANNEL, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_MUC, param_spec); - - param_spec = g_param_spec_object ( - "contact", - "SalutContact object", - "Salut Contact to which this channel is dedicated in case of 1-1 tube", - SALUT_TYPE_CONTACT, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB); - g_object_class_install_property (object_class, PROP_CONTACT, param_spec); - - param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces", - "Additional Channel.Interface.* interfaces", - G_TYPE_STRV, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INTERFACES, param_spec); - - salut_tubes_channel_class->dbus_props_class.interfaces = prop_interfaces; - tp_dbus_properties_mixin_class_init (object_class, - G_STRUCT_OFFSET (SalutTubesChannelClass, dbus_props_class)); - - tp_external_group_mixin_init_dbus_properties (object_class); -} - -void -salut_tubes_channel_dispose (GObject *object) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (object); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - if (priv->dispose_has_run) - return; - - if (priv->muc_connection != NULL) - { - g_signal_handlers_disconnect_matched (priv->muc_connection, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self); - - g_object_unref (priv->muc_connection); - priv->muc_connection = NULL; - } - - if (priv->contact != NULL) - { - g_object_unref (priv->contact); - priv->contact = NULL; - } - - priv->dispose_has_run = TRUE; - - if (self->muc != NULL) - tp_external_group_mixin_finalize (object); - - salut_tubes_channel_close (self); - - if (G_OBJECT_CLASS (salut_tubes_channel_parent_class)->dispose) - G_OBJECT_CLASS (salut_tubes_channel_parent_class)->dispose (object); -} - -static void -salut_tubes_channel_finalize (GObject *object) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (object); - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - g_free (priv->object_path); - - G_OBJECT_CLASS (salut_tubes_channel_parent_class)->finalize (object); -} - -static void -emit_tube_closed_signal (gpointer key, - gpointer value, - gpointer user_data) -{ - guint id = GPOINTER_TO_UINT (key); - SalutTubesChannel *self = (SalutTubesChannel *) user_data; - - tp_svc_channel_type_tubes_emit_tube_closed (self, id); -} - -void -salut_tubes_channel_foreach (SalutTubesChannel *self, - TpExportableChannelFunc foreach, - gpointer user_data) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - GHashTableIter iter; - gpointer value; - - g_hash_table_iter_init (&iter, priv->tubes); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - foreach (TP_EXPORTABLE_CHANNEL (value), user_data); - } -} - -void -salut_tubes_channel_close (SalutTubesChannel *self) -{ - SalutTubesChannelPrivate *priv; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - if (priv->closed) - { - return; - } - - priv->closed = TRUE; - - g_hash_table_foreach (priv->tubes, emit_tube_closed_signal, self); - g_hash_table_unref (priv->tubes); - - priv->tubes = NULL; - - tp_svc_channel_emit_closed (self); -} - -/** - * salut_tubes_channel_close_async: - * - * Implements D-Bus method Close - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tubes_channel_close_async (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - - salut_tubes_channel_close (self); - tp_svc_channel_return_from_close (context); -} - -/** - * salut_tubes_channel_get_channel_type - * - * Tubesplements DBus method GetChannelType - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tubes_channel_get_channel_type (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - tp_svc_channel_return_from_get_channel_type (context, - TP_IFACE_CHANNEL_TYPE_TUBES); -} - - -/** - * salut_tubes_channel_get_handle - * - * Tubesplements DBus method GetHandle - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tubes_channel_get_handle (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - SalutTubesChannelPrivate *priv; - - g_assert (SALUT_IS_TUBES_CHANNEL (self)); - priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - - tp_svc_channel_return_from_get_handle (context, priv->handle_type, - priv->handle); -} - - -/** - * salut_tubes_channel_get_interfaces - * - * Tubesplements DBus method GetInterfaces - * on interface org.freedesktop.Telepathy.Channel - */ -static void -salut_tubes_channel_get_interfaces (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface); - - if (self->muc) - { - tp_svc_channel_return_from_get_interfaces (context, - salut_tubes_channel_interfaces); - } - else - { - /* only show the NULL */ - tp_svc_channel_return_from_get_interfaces (context, - salut_tubes_channel_interfaces + 1); - } -} - -/* Called when we receive a SI request, - * via salut_muc_manager_handle_si_stream_request - */ -void -salut_tubes_channel_bytestream_offered (SalutTubesChannel *self, - GibberBytestreamIface *bytestream, - WockyStanza *msg) -{ - SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self); - WockyNode *node = wocky_stanza_get_top_node (msg); - const gchar *stream_id, *tmp; - gchar *endptr; - WockyNode *si_node, *stream_node; - guint tube_id; - unsigned long tube_id_tmp; - SalutTubeIface *tube; - WockyStanzaType type; - WockyStanzaSubType sub_type; - - /* Caller is expected to have checked that we have a stream or muc-stream - * node with a stream ID and the TUBES profile - */ - wocky_stanza_get_type_info (msg, &type, &sub_type); - g_return_if_fail (type == WOCKY_STANZA_TYPE_IQ); - g_return_if_fail (sub_type == WOCKY_STANZA_SUB_TYPE_SET); - - si_node = wocky_node_get_child_ns (node, "si", - WOCKY_XMPP_NS_SI); - g_return_if_fail (si_node != NULL); - - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - stream_node = wocky_node_get_child_ns (si_node, - "stream", WOCKY_TELEPATHY_NS_TUBES); - else - stream_node = wocky_node_get_child_ns (si_node, - "muc-stream", WOCKY_TELEPATHY_NS_TUBES); - g_return_if_fail (stream_node != NULL); - - stream_id = wocky_node_get_attribute (si_node, "id"); - g_return_if_fail (stream_id != NULL); - - tmp = wocky_node_get_attribute (stream_node, "tube"); - if (tmp == NULL) - { - GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - " or has no tube attribute" }; - - DEBUG ("%s", e.message); - gibber_bytestream_iface_close (bytestream, &e); - return; - } - tube_id_tmp = strtoul (tmp, &endptr, 10); - if (!endptr || *endptr || tube_id_tmp > G_MAXUINT32) - { - GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - " or tube attribute not numeric or > 2**32" }; - - DEBUG ("tube id is not numeric or > 2**32: %s", tmp); - gibber_bytestream_iface_close (bytestream, &e); - return; - } - tube_id = (guint) tube_id_tmp; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - if (tube == NULL) - { - GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - " or tube attribute points to a nonexistent " - "tube" }; - - DEBUG ("tube %u doesn't exist", tube_id); - gibber_bytestream_iface_close (bytestream, &e); - return; - } - - DEBUG ("received new bytestream request for existing tube: %u", tube_id); - - salut_tube_iface_add_bytestream (tube, bytestream); -} - -static void -tubes_iface_init (gpointer g_iface, - gpointer iface_data) -{ - TpSvcChannelTypeTubesClass *klass = (TpSvcChannelTypeTubesClass *) g_iface; - -#define IMPLEMENT(x) tp_svc_channel_type_tubes_implement_##x (\ - klass, salut_tubes_channel_##x) - IMPLEMENT(get_available_tube_types); - IMPLEMENT(list_tubes); - IMPLEMENT(close_tube); - IMPLEMENT(offer_d_bus_tube); - IMPLEMENT(accept_d_bus_tube); - IMPLEMENT(get_d_bus_tube_address); - IMPLEMENT(get_d_bus_names); - IMPLEMENT(offer_stream_tube); - IMPLEMENT(accept_stream_tube); - IMPLEMENT(get_stream_tube_socket_address); - IMPLEMENT(get_available_stream_tube_types); -#undef IMPLEMENT -} - -static void -channel_iface_init (gpointer g_iface, - gpointer iface_data) -{ - TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface; - -#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\ - klass, salut_tubes_channel_##x##suffix) - IMPLEMENT(close,_async); - IMPLEMENT(get_channel_type,); - IMPLEMENT(get_handle,); - IMPLEMENT(get_interfaces,); -#undef IMPLEMENT -} diff --git a/src/tubes-channel.h b/src/tubes-channel.h deleted file mode 100644 index c92fcb74..00000000 --- a/src/tubes-channel.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * tubes-channel.h - Header for SalutTubesChannel - * Copyright (C) 2007 Collabora Ltd. - * - * 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. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the tubesplied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __SALUT_TUBES_CHANNEL_H__ -#define __SALUT_TUBES_CHANNEL_H__ - -#include -#include -#include - -#include "muc-channel.h" -#include "tube-iface.h" - -G_BEGIN_DECLS - -typedef struct _SalutTubesChannel SalutTubesChannel; -typedef struct _SalutTubesChannelClass SalutTubesChannelClass; - -struct _SalutTubesChannelClass { - GObjectClass parent_class; - TpDBusPropertiesMixinClass dbus_props_class; -}; - -struct _SalutTubesChannel { - GObject parent; - - SalutMucChannel *muc; - - gpointer priv; -}; - -GType salut_tubes_channel_get_type (void); - -/* TYPE MACROS */ -#define SALUT_TYPE_TUBES_CHANNEL \ - (salut_tubes_channel_get_type ()) -#define SALUT_TUBES_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), SALUT_TYPE_TUBES_CHANNEL, \ - SalutTubesChannel)) -#define SALUT_TUBES_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), SALUT_TYPE_TUBES_CHANNEL, \ - SalutTubesChannelClass)) -#define SALUT_IS_TUBES_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), SALUT_TYPE_TUBES_CHANNEL)) -#define SALUT_IS_TUBES_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), SALUT_TYPE_TUBES_CHANNEL)) -#define SALUT_TUBES_CHANNEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), SALUT_TYPE_TUBES_CHANNEL, \ - SalutTubesChannelClass)) - -void salut_tubes_channel_foreach (SalutTubesChannel *self, - TpExportableChannelFunc foreach, gpointer user_data); - -void salut_tubes_channel_close (SalutTubesChannel *channel); - -void salut_tubes_channel_bytestream_offered (SalutTubesChannel *chanel, - GibberBytestreamIface *bytestream, WockyStanza *msg); - -GPtrArray * salut_tubes_channel_muc_message_received ( - SalutTubesChannel *channel, const gchar *sender, WockyStanza *stanza); - -SalutTubeIface * salut_tubes_channel_message_received (SalutTubesChannel *self, - const gchar *service, TpTubeType tube_type, TpHandle initiator_handle, - GHashTable *parameters, guint tube_id, guint portnum, - WockyStanza *iq_req); - -void salut_tubes_channel_message_close_received (SalutTubesChannel *self, - TpHandle initiator_handle, guint tube_id); - -SalutTubeIface *salut_tubes_channel_tube_request (SalutTubesChannel *self, - gpointer request_token, GHashTable *request_properties, - gboolean require_new); - -void salut_tubes_channel_send_iq_offer (SalutTubesChannel *self); - -G_END_DECLS - -#endif /* #ifndef __SALUT_TUBES_CHANNEL_H__*/ diff --git a/src/tubes-manager.h b/src/tubes-manager.h index 1697d9e0..449f6134 100644 --- a/src/tubes-manager.h +++ b/src/tubes-manager.h @@ -25,7 +25,6 @@ #include #include "connection.h" #include "contact-manager.h" -#include "tubes-channel.h" G_BEGIN_DECLS -- cgit v1.2.1 From 30478a5e6274ae8208a595b3e865eafb62a4dda3 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 5 Jun 2012 17:15:08 +0100 Subject: muc-channel: remove unused code to hold pointer to muc manager Signed-off-by: Jonny Lamb --- src/muc-channel.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index 782d9622..1b0c5886 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -102,7 +102,6 @@ struct _SalutMucChannelPrivate guint timeout; /* (gchar *) -> (SalutContact *) */ GHashTable *senders; - SalutMucManager *muc_manager; GHashTable *tubes; }; @@ -305,14 +304,6 @@ salut_muc_channel_constructed (GObject *obj) g_signal_connect (priv->muc_connection, "connected", G_CALLBACK (muc_connection_connected_cb), obj); - g_object_get (base_conn, - "muc-manager", &(priv->muc_manager), - NULL); - g_assert (priv->muc_manager != NULL); - - /* no need to keep a ref on the muc manager as it keeps a ref on us */ - g_object_unref (priv->muc_manager); - tp_group_mixin_init (obj, G_STRUCT_OFFSET(SalutMucChannel, group), contact_repo, base_conn->self_handle); -- cgit v1.2.1 From 7ab3404c9b3b3f154c94c92b366c2a005d78f250 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 6 Jun 2012 11:42:44 +0100 Subject: muc-manager: only signal channels when they're 'ready' It's nicer to only give the channel back when it's actually ready and joined instead of before hand. If it is returned too early gibber can be made to assert on its connection status. Gabble already does this. Signed-off-by: Jonny Lamb --- src/muc-channel.c | 6 ++ src/muc-channel.h | 2 + src/muc-manager.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 165 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index 1b0c5886..2abc5907 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -1812,3 +1812,9 @@ salut_muc_channel_bytestream_offered (SalutMucChannel *self, salut_tube_iface_add_bytestream (tube, bytestream); } + +gboolean +salut_muc_channel_is_ready (SalutMucChannel *self) +{ + return self->priv->connected; +} diff --git a/src/muc-channel.h b/src/muc-channel.h index 8c888d18..f5992768 100644 --- a/src/muc-channel.h +++ b/src/muc-channel.h @@ -100,6 +100,8 @@ void salut_muc_channel_bytestream_offered (SalutMucChannel *self, GibberBytestreamIface *bytestream, WockyStanza *msg); +gboolean salut_muc_channel_is_ready (SalutMucChannel *self); + G_END_DECLS #endif /* #ifndef __SALUT_MUC_CHANNEL_H__*/ diff --git a/src/muc-manager.c b/src/muc-manager.c index 36d77ef0..ca28004b 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -87,6 +87,12 @@ struct _SalutMucManagerPrivate /* tube ID => owned SalutTubeIface */ GHashTable *tubes; + /* borrowed TpExportableChannel => owned GSList of gpointer */ + GHashTable *queued_requests; + + /* borrowed SalutMucChannel => owned GSList of borrowed SalutTubeIface */ + GHashTable *text_needed_for_tube; + gboolean dispose_has_run; }; @@ -106,6 +112,11 @@ salut_muc_manager_init (SalutMucManager *obj) /* allocate any data required by the object here */ priv->text_channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + + priv->queued_requests = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_slist_free); + priv->text_needed_for_tube = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_slist_free); } static void @@ -148,6 +159,23 @@ salut_muc_manager_set_property (GObject *object, } } +static void +cancel_queued_requests (gpointer k, + gpointer v, + gpointer d) +{ + SalutMucManager *self = SALUT_MUC_MANAGER (d); + GSList *requests_satisfied = v; + GSList *iter; + + for (iter = requests_satisfied; iter != NULL; iter = iter->next) + { + tp_channel_manager_emit_request_failed (self, + iter->data, TP_ERROR, TP_ERROR_DISCONNECTED, + "Unable to complete this channel request, we're disconnecting!"); + } +} + static void salut_muc_manager_close_all (SalutMucManager *self) { @@ -161,6 +189,13 @@ salut_muc_manager_close_all (SalutMucManager *self) priv->status_changed_id = 0; } + if (priv->queued_requests != NULL) + g_hash_table_foreach (priv->queued_requests, + cancel_queued_requests, self); + + tp_clear_pointer (&priv->queued_requests, g_hash_table_unref); + tp_clear_pointer (&priv->text_needed_for_tube, g_hash_table_unref); + tp_clear_pointer (&priv->text_channels, g_hash_table_unref); } @@ -255,6 +290,8 @@ salut_muc_manager_dispose (GObject *object) salut_muc_manager_close_all (self); g_assert (priv->text_channels == NULL); + g_assert (priv->queued_requests == NULL); + g_assert (priv->text_needed_for_tube == NULL); /* release any references held by the object here */ @@ -342,6 +379,32 @@ salut_muc_manager_type_foreach_channel_class (GType type, g_hash_table_unref (table); } +static void +associate_channel_to_data (GHashTable *table, + gpointer channel, + gpointer data) +{ + GSList *list; + + if (data == NULL) + return; + + /* yes it might be more 'efficient' to use prepend, then reverse the + * list before use but that's just annoying. I doubt there'll ever + * be more than one item in the list anyway. */ + + /* get the old list */ + list = g_hash_table_lookup (table, channel); + + /* add the data to it */ + list = g_slist_append (list, data); + + /* steal it so it doesn't get freed */ + g_hash_table_steal (table, channel); + + /* throw it back in */ + g_hash_table_insert (table, channel, list); +} static void muc_channel_closed_cb (SalutMucChannel *chan, @@ -395,6 +458,80 @@ _get_connection (SalutMucManager *mgr, protocol, parameters, error); } +static void +muc_channel_ready_cb (SalutMucChannel *chan, + SalutMucManager *mgr) +{ + SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (mgr); + GSList *satisfied; + GSList *tube_channels; + GSList *l; + + /* announce the text channel finally */ + satisfied = g_hash_table_lookup (priv->queued_requests, chan); + tp_channel_manager_emit_new_channel (mgr, + TP_EXPORTABLE_CHANNEL (chan), satisfied); + g_hash_table_remove (priv->queued_requests, chan); + + /* announce tube channels now */ + tube_channels = g_hash_table_lookup (priv->text_needed_for_tube, chan); + + for (l = tube_channels; l != NULL; l = l->next) + { + SalutTubeIface *tube = SALUT_TUBE_IFACE (l->data); + GSList *requests_satisfied; + + requests_satisfied = g_hash_table_lookup (priv->queued_requests, tube); + + tp_channel_manager_emit_new_channel (mgr, + TP_EXPORTABLE_CHANNEL (tube), requests_satisfied); + + g_hash_table_remove (priv->queued_requests, tube); + } + + g_hash_table_remove (priv->text_needed_for_tube, chan); +} + +static void +muc_channel_join_error_cb (SalutMucChannel *chan, + GError *error, + SalutMucManager *mgr) +{ + SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (mgr); + GSList *requests_satisfied; + GSList *tube_channels; + GSList *l; + +#define FAIL_REQUESTS(requests) \ + { \ + GSList *_l; \ + for (_l = requests; _l != NULL; _l = _l->next) \ + { \ + tp_channel_manager_emit_request_failed (mgr, _l->data, \ + error->domain, error->code, error->message); \ + } \ + } + + /* first fail the text channel itself */ + requests_satisfied = g_hash_table_lookup (priv->queued_requests, chan); + FAIL_REQUESTS(requests_satisfied); + g_hash_table_remove (priv->queued_requests, chan); + + /* now fail all tube channel requests */ + tube_channels = g_hash_table_lookup (priv->text_needed_for_tube, chan); + + for (l = tube_channels; l != NULL; l = l->next) + { + TpExportableChannel *tube = TP_EXPORTABLE_CHANNEL (l->data); + + requests_satisfied = g_hash_table_lookup (priv->queued_requests, tube); + FAIL_REQUESTS (requests_satisfied); + g_hash_table_remove (priv->queued_requests, tube); + } + + g_hash_table_remove (priv->text_needed_for_tube, chan); +} + static SalutMucChannel * salut_muc_manager_new_muc_channel (SalutMucManager *mgr, TpHandle handle, @@ -433,6 +570,13 @@ salut_muc_manager_new_muc_channel (SalutMucManager *mgr, g_hash_table_insert (priv->text_channels, GUINT_TO_POINTER (handle), chan); + if (salut_muc_channel_is_ready (chan)) + muc_channel_ready_cb (chan, mgr); + else + g_signal_connect (chan, "ready", G_CALLBACK (muc_channel_ready_cb), mgr); + + g_signal_connect (chan, "join-error", G_CALLBACK (muc_channel_join_error_cb), mgr); + return chan; } @@ -522,13 +666,21 @@ salut_muc_manager_request_new_muc_channel (SalutMucManager *mgr, * succeed */ g_assert (r); - if (request_token != NULL) - tokens = g_slist_prepend (tokens, request_token); - if (announce) { - tp_channel_manager_emit_new_channel (mgr, - TP_EXPORTABLE_CHANNEL (text_chan), tokens); + if (salut_muc_channel_is_ready (text_chan)) + { + if (request_token != NULL) + tokens = g_slist_prepend (tokens, request_token); + + tp_channel_manager_emit_new_channel (mgr, + TP_EXPORTABLE_CHANNEL (text_chan), tokens); + } + else + { + associate_channel_to_data (priv->queued_requests, + text_chan, request_token); + } } g_slist_free (tokens); -- cgit v1.2.1 From a58250aa6e3686de8fdab854ca13bd7279435e61 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 6 Jun 2012 11:53:17 +0100 Subject: tubes-manager: replace emit_new_channels with singular version We're signalling the creation of only one channel anyway. Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index b3a1136f..07b2ca62 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -816,7 +816,6 @@ salut_tubes_manager_requestotron (SalutTubesManager *self, const gchar *service = NULL; SalutTubeIface *new_channel; GSList *tokens = NULL; - GHashTable *channels; if (tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_CONTACT) @@ -907,16 +906,12 @@ salut_tubes_manager_requestotron (SalutTubesManager *self, request_properties); g_assert (new_channel != NULL); - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); - if (request_token != NULL) tokens = g_slist_prepend (NULL, request_token); - g_hash_table_insert (channels, new_channel, tokens); - tp_channel_manager_emit_new_channels (self, channels); + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (new_channel), tokens); - g_hash_table_unref (channels); g_slist_free (tokens); } else -- cgit v1.2.1 From ef939874f0b344eec7b792b76b583066817b3ca8 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 6 Jun 2012 12:04:27 +0100 Subject: muc-manager: only expose the text MUC channel when necessary Signed-off-by: Jonny Lamb --- src/muc-channel.c | 55 ++++++++++++++++++++++++ src/muc-channel.h | 7 +++ src/muc-manager.c | 126 +++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 158 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index 2abc5907..eff9f72e 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -77,6 +77,7 @@ enum READY, JOIN_ERROR, NEW_TUBE, + APPEARED, LAST_SIGNAL }; @@ -103,6 +104,8 @@ struct _SalutMucChannelPrivate /* (gchar *) -> (SalutContact *) */ GHashTable *senders; + gboolean autoclose; + GHashTable *tubes; }; @@ -713,6 +716,15 @@ salut_muc_channel_class_init (SalutMucChannelClass *salut_muc_channel_class) * wants a value type, not an interface. */ G_TYPE_NONE, 1, TP_TYPE_BASE_CHANNEL); + signals[APPEARED] = g_signal_new ( + "appeared", + G_OBJECT_CLASS_TYPE (salut_muc_channel_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + tp_group_mixin_class_init (object_class, G_STRUCT_OFFSET(SalutMucChannelClass, group_class), salut_muc_channel_add_member, NULL); @@ -1257,6 +1269,17 @@ salut_muc_channel_received_stanza (GibberMucConnection *conn, return; } + /* are we actually hidden? */ + if (!tp_base_channel_is_registered (base_chan)) + { + DEBUG ("making MUC channel reappear!"); + tp_base_channel_reopened_with_requested (base_chan, FALSE, from_handle); + g_signal_emit (self, signals[APPEARED], 0); + } + + /* let's not autoclose now */ + priv->autoclose = FALSE; + #ifdef ENABLE_OLPC if (salut_connection_olpc_observe_muc_stanza ( SALUT_CONNECTION (base_connection), @@ -1364,11 +1387,43 @@ salut_muc_channel_disconnected (GibberTransport *transport, gpointer user_data) tp_base_channel_destroyed (TP_BASE_CHANNEL (self)); } +gboolean +salut_muc_channel_can_be_closed (SalutMucChannel *self) +{ + if (self->priv->tubes == NULL) + return TRUE; + + return (g_hash_table_size (self->priv->tubes) == 0); +} + +gboolean +salut_muc_channel_get_autoclose (SalutMucChannel *self) +{ + return self->priv->autoclose; +} + +void +salut_muc_channel_set_autoclose (SalutMucChannel *self, + gboolean autoclose) +{ + self->priv->autoclose = autoclose; +} + static void salut_muc_channel_close (TpBaseChannel *base) { SalutMucChannel *self = SALUT_MUC_CHANNEL (base); + /* if we have some tubes around then don't close yet and just + * disappear from the bus, faking having closed, otherwise + * cheerio! */ + if (!salut_muc_channel_can_be_closed (self)) + { + self->priv->autoclose = TRUE; + tp_base_channel_disappear (base); + return; + } + salut_muc_channel_leave (self, TP_CHANNEL_GROUP_CHANGE_REASON_NONE, ""); tp_base_channel_destroyed (base); diff --git a/src/muc-channel.h b/src/muc-channel.h index f5992768..868e7af4 100644 --- a/src/muc-channel.h +++ b/src/muc-channel.h @@ -100,6 +100,13 @@ void salut_muc_channel_bytestream_offered (SalutMucChannel *self, GibberBytestreamIface *bytestream, WockyStanza *msg); +void salut_muc_channel_set_autoclose (SalutMucChannel *chan, + gboolean autoclose); + +gboolean salut_muc_channel_get_autoclose (SalutMucChannel *chan); + +gboolean salut_muc_channel_can_be_closed (SalutMucChannel *chan); + gboolean salut_muc_channel_is_ready (SalutMucChannel *self); G_END_DECLS diff --git a/src/muc-manager.c b/src/muc-manager.c index ca28004b..cf9c94b7 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -99,6 +99,9 @@ struct _SalutMucManagerPrivate #define SALUT_MUC_MANAGER_GET_PRIVATE(obj) \ ((SalutMucManagerPrivate *) ((SalutMucManager *) obj)->priv) +#define TUBE_TEXT_QUARK (g_quark_from_static_string (\ + "salut-muc-manager-tube-text-channel")) + static void salut_muc_manager_init (SalutMucManager *obj) { @@ -412,12 +415,17 @@ muc_channel_closed_cb (SalutMucChannel *chan, { SalutMucManager *self = SALUT_MUC_MANAGER (user_data); SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (chan); TpHandle handle; - tp_channel_manager_emit_channel_closed_for_object (self, - TP_EXPORTABLE_CHANNEL (chan)); + if (tp_base_channel_is_registered (base)) + { + tp_channel_manager_emit_channel_closed_for_object (self, + TP_EXPORTABLE_CHANNEL (chan)); + } - if (priv->text_channels) + if (tp_base_channel_is_destroyed (base) + && priv->text_channels) { g_object_get (chan, "handle", &handle, NULL); DEBUG ("Removing channel with handle %u", handle); @@ -430,8 +438,27 @@ static void muc_channel_tube_closed_cb (SalutTubeIface *tube, SalutMucManager *mgr) { + SalutMucChannel *channel; + tp_channel_manager_emit_channel_closed_for_object (mgr, TP_EXPORTABLE_CHANNEL (tube)); + + channel = g_object_get_qdata (G_OBJECT (tube), TUBE_TEXT_QUARK); + g_assert (channel != NULL); + + if (salut_muc_channel_can_be_closed (channel) + && salut_muc_channel_get_autoclose (channel)) + { + tp_base_channel_close (TP_BASE_CHANNEL (channel)); + } +} + +static void +muc_channel_appeared_cb (SalutMucChannel *chan, + SalutMucManager *mgr) +{ + tp_channel_manager_emit_new_channel (mgr, + TP_EXPORTABLE_CHANNEL (chan), NULL); } static void @@ -444,6 +471,9 @@ muc_channel_new_tube_cb (SalutMucChannel *channel, g_signal_connect (tube, "closed", G_CALLBACK (muc_channel_tube_closed_cb), mgr); + + g_object_set_qdata (G_OBJECT (tube), TUBE_TEXT_QUARK, + channel); } static GibberMucConnection * @@ -463,14 +493,17 @@ muc_channel_ready_cb (SalutMucChannel *chan, SalutMucManager *mgr) { SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (mgr); - GSList *satisfied; GSList *tube_channels; GSList *l; - /* announce the text channel finally */ - satisfied = g_hash_table_lookup (priv->queued_requests, chan); - tp_channel_manager_emit_new_channel (mgr, - TP_EXPORTABLE_CHANNEL (chan), satisfied); + /* announce the text channel finally, but only if it is on the bus */ + if (tp_base_channel_is_registered (TP_BASE_CHANNEL (chan))) + { + GSList *satisfied = g_hash_table_lookup (priv->queued_requests, chan); + + tp_channel_manager_emit_new_channel (mgr, + TP_EXPORTABLE_CHANNEL (chan), satisfied); + } g_hash_table_remove (priv->queued_requests, chan); /* announce tube channels now */ @@ -538,7 +571,8 @@ salut_muc_manager_new_muc_channel (SalutMucManager *mgr, GibberMucConnection *connection, TpHandle initiator, gboolean new_connection, - gboolean requested) + gboolean requested, + gboolean initially_register) { SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE(mgr); TpBaseConnection *base_connection = TP_BASE_CONNECTION(priv->connection); @@ -563,10 +597,12 @@ salut_muc_manager_new_muc_channel (SalutMucManager *mgr, new_connection, requested); g_free (path); - tp_base_channel_register ((TpBaseChannel *) chan); + if (initially_register) + tp_base_channel_register ((TpBaseChannel *) chan); g_signal_connect (chan, "closed", G_CALLBACK (muc_channel_closed_cb), mgr); g_signal_connect (chan, "new-tube", G_CALLBACK (muc_channel_new_tube_cb), mgr); + g_signal_connect (chan, "appeared", G_CALLBACK (muc_channel_appeared_cb), mgr); g_hash_table_insert (priv->text_channels, GUINT_TO_POINTER (handle), chan); @@ -659,13 +695,17 @@ salut_muc_manager_request_new_muc_channel (SalutMucManager *mgr, text_chan = salut_muc_manager_new_muc_channel (mgr, handle, connection, base_connection->self_handle, params == NULL, - requested); + requested, announce); r = salut_muc_channel_invited (text_chan, base_connection->self_handle, NULL, NULL); /* Inviting ourselves to a connected channel should always * succeed */ g_assert (r); + /* only signal the creation of the text channel if we're asked for + * it to happen. note that in the case of announce=FALSE, + * muc_channel_ready_cb will still get fired, but because it isn't + * registered on the bus, it will not be signalled then either. */ if (announce) { if (salut_muc_channel_is_ready (text_chan)) @@ -699,9 +739,6 @@ handle_tube_channel_request (SalutMucManager *self, SalutMucManagerPrivate *priv = SALUT_MUC_MANAGER_GET_PRIVATE (self); SalutMucChannel *text_chan; SalutTubeIface *new_channel; - GHashTable *channels; - GSList *request_tokens; - gboolean announce_text = FALSE; text_chan = g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (handle)); @@ -712,8 +749,6 @@ handle_tube_channel_request (SalutMucManager *self, text_chan = salut_muc_manager_request_new_muc_channel (self, handle, NULL, FALSE, error); - announce_text = TRUE; - if (text_chan == NULL) return FALSE; } @@ -725,19 +760,29 @@ handle_tube_channel_request (SalutMucManager *self, g_signal_connect (new_channel, "closed", G_CALLBACK (muc_channel_tube_closed_cb), self); - /* announce channels */ - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); + g_object_set_qdata (G_OBJECT (new_channel), TUBE_TEXT_QUARK, + text_chan); - if (announce_text) - g_hash_table_insert (channels, text_chan, NULL); + if (salut_muc_channel_is_ready (text_chan)) + { + GSList *request_tokens = g_slist_append (NULL, request_token); + + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (new_channel), request_tokens); - request_tokens = g_slist_prepend (NULL, request_token); - g_hash_table_insert (channels, new_channel, request_tokens); - tp_channel_manager_emit_new_channels (self, channels); + g_slist_free (request_tokens); + } + else + { + associate_channel_to_data (priv->text_needed_for_tube, + text_chan, new_channel); + + /* we need to do this so when the muc channel is ready, the tube + * can be announced and satisfy this request */ + associate_channel_to_data (priv->queued_requests, + new_channel, request_token); + } - g_hash_table_unref (channels); - g_slist_free (request_tokens); return TRUE; } @@ -844,7 +889,8 @@ salut_muc_manager_request (SalutMucManager *self, if (text_chan != NULL) { - if (require_new) + if (require_new + && tp_base_channel_is_registered (TP_BASE_CHANNEL (text_chan))) { g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "That channel has already been created (or requested)"); @@ -852,8 +898,28 @@ salut_muc_manager_request (SalutMucManager *self, } else { - tp_channel_manager_emit_request_already_satisfied (self, - request_token, TP_EXPORTABLE_CHANNEL (text_chan)); + if (tp_base_channel_is_registered (TP_BASE_CHANNEL (text_chan))) + { + tp_channel_manager_emit_request_already_satisfied (self, + request_token, TP_EXPORTABLE_CHANNEL (text_chan)); + } + else + { + tp_base_channel_register (TP_BASE_CHANNEL (text_chan)); + + if (salut_muc_channel_is_ready (text_chan)) + { + GSList *tokens = g_slist_append (NULL, request_token); + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (text_chan), tokens); + g_slist_free (tokens); + } + else + { + associate_channel_to_data (priv->queued_requests, + text_chan, request_token); + } + } } } else @@ -1035,7 +1101,7 @@ invite_stanza_callback (WockyPorter *porter, } /* Need to create a new one */ chan = salut_muc_manager_new_muc_channel (self, room_handle, - connection, inviter_handle, FALSE, FALSE); + connection, inviter_handle, FALSE, FALSE, TRUE); tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (chan), NULL); -- cgit v1.2.1 From e95db12e8998d233810e78b544b44862f89478e3 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 6 Jun 2012 15:22:33 +0100 Subject: muc-channel: don't pretend to be connected after disposing Signed-off-by: Jonny Lamb --- src/muc-channel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index eff9f72e..270732d5 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -748,6 +748,8 @@ salut_muc_channel_dispose (GObject *object) priv->dispose_has_run = TRUE; + priv->connected = FALSE; + g_signal_handlers_disconnect_matched (priv->muc_connection, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self); -- cgit v1.2.1 From a088249c49902a76ac1abbb0f4dead484a3717d1 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 24 Jul 2012 17:16:22 +0100 Subject: tubes-manager: fix coding style Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 07b2ca62..b39dc759 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -551,9 +551,9 @@ salut_tubes_manager_foreach_channel (TpChannelManager *manager, g_hash_table_iter_init (&iter, priv->tubes); while (g_hash_table_iter_next (&iter, NULL, &value)) - { - foreach (TP_EXPORTABLE_CHANNEL (value), user_data); - } + { + foreach (TP_EXPORTABLE_CHANNEL (value), user_data); + } } static const gchar * const tubes_channel_fixed_properties[] = { -- cgit v1.2.1 From 952349de572a794428011753630c5827a2c454d1 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 24 Jul 2012 17:16:30 +0100 Subject: tubes-manager: correct logic in looking up existing tubes Good catch, Will! Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index b39dc759..778e11c5 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -657,7 +657,7 @@ salut_tubes_manager_lookup (SalutTubesManager *self, if (!tp_strdiff (type, channel_type) && handle == channel_handle && !tp_strdiff (service, channel_service)) - match = FALSE; + match = TRUE; g_free (channel_type); g_free (channel_service); -- cgit v1.2.1 From 83be5b433f7927f49e2d87d262ded4bbfdbb2e8f Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 2 Aug 2012 11:44:11 +0100 Subject: tubes: use guint64s for all tube IDs Signed-off-by: Jonny Lamb --- src/muc-channel.c | 34 ++++++++++++++++------------------ src/tube-dbus.c | 10 +++++----- src/tube-dbus.h | 2 +- src/tube-iface.c | 2 +- src/tube-stream.c | 14 +++++++------- src/tube-stream.h | 2 +- src/tubes-manager.c | 29 ++++++++++++++--------------- 7 files changed, 45 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index 270732d5..a408a056 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -135,7 +135,7 @@ static SalutTubeIface * create_new_tube (SalutMucChannel *self, TpHandle initiator, const gchar *service, GHashTable *parameters, - guint tube_id, + guint64 tube_id, guint portnum, WockyStanza *iq_req, gboolean requested); @@ -1488,7 +1488,7 @@ publish_tube_in_node (SalutMucChannel *self, GHashTable *parameters; TpTubeType type; gchar *service, *id_str; - guint tube_id; + guint64 tube_id; TpHandle initiator_handle; g_object_get (tube, @@ -1499,7 +1499,7 @@ publish_tube_in_node (SalutMucChannel *self, "id", &tube_id, NULL); - id_str = g_strdup_printf ("%u", tube_id); + id_str = g_strdup_printf ("%" G_GUINT64_FORMAT, tube_id); wocky_node_set_attribute (node, "service", service); wocky_node_set_attribute (node, "id", id_str); @@ -1650,7 +1650,7 @@ tube_closed_cb (SalutTubeIface *tube, SalutMucChannel *self) { SalutMucChannelPrivate *priv = self->priv; - guint id; + guint64 id; g_object_get (tube, "id", &id, @@ -1671,7 +1671,7 @@ generate_tube_id (SalutMucChannel *self) /* probably totally overkill */ do { - out = g_random_int_range (0, G_MAXINT); + out = g_random_int_range (1, G_MAXINT32); } while (g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (out)) != NULL); @@ -1685,7 +1685,7 @@ create_new_tube (SalutMucChannel *self, TpHandle initiator, const gchar *service, GHashTable *parameters, - guint tube_id, + guint64 tube_id, guint portnum, WockyStanza *iq_req, gboolean requested) @@ -1717,7 +1717,7 @@ create_new_tube (SalutMucChannel *self, tp_base_channel_register ((TpBaseChannel *) tube); - DEBUG ("create tube %u", tube_id); + DEBUG ("create tube %" G_GUINT64_FORMAT, tube_id); g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), tube); g_signal_connect (tube, "tube-opened", G_CALLBACK (tube_opened_cb), self); @@ -1735,7 +1735,7 @@ salut_muc_channel_tube_request (SalutMucChannel *self, const gchar *channel_type; const gchar *service; GHashTable *parameters = NULL; - guint tube_id; + guint64 tube_id; TpTubeType type; tube_id = generate_tube_id (self); @@ -1805,10 +1805,8 @@ salut_muc_channel_bytestream_offered (SalutMucChannel *self, SalutMucChannelPrivate *priv = self->priv; WockyNode *node = wocky_stanza_get_top_node (msg); const gchar *stream_id, *tmp; - gchar *endptr; WockyNode *si_node, *stream_node; - guint tube_id; - unsigned long tube_id_tmp; + guint64 tube_id; SalutTubeIface *tube; WockyStanzaType type; WockyStanzaSubType sub_type; @@ -1841,17 +1839,16 @@ salut_muc_channel_bytestream_offered (SalutMucChannel *self, gibber_bytestream_iface_close (bytestream, &e); return; } - tube_id_tmp = strtoul (tmp, &endptr, 10); - if (!endptr || *endptr || tube_id_tmp > G_MAXUINT32) + tube_id = g_ascii_strtoull (tmp, NULL, 10); + if (tube_id == 0 || tube_id > G_MAXUINT32) { GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - " tube attribute not numeric or > 2**32" }; + " tube attribute is non-numeric or out of range" }; - DEBUG ("tube id is not numeric or > 2**32: %s", tmp); + DEBUG ("tube id is non-numeric or out of range: %s", tmp); gibber_bytestream_iface_close (bytestream, &e); return; } - tube_id = (guint) tube_id_tmp; tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); if (tube == NULL) @@ -1860,12 +1857,13 @@ salut_muc_channel_bytestream_offered (SalutMucChannel *self, " tube attribute points to a nonexistent " "tube" }; - DEBUG ("tube %u doesn't exist", tube_id); + DEBUG ("tube %" G_GUINT64_FORMAT " doesn't exist", tube_id); gibber_bytestream_iface_close (bytestream, &e); return; } - DEBUG ("received new bytestream request for existing tube: %u", tube_id); + DEBUG ("received new bytestream request for existing tube: %" G_GUINT64_FORMAT, + tube_id); salut_tube_iface_add_bytestream (tube, bytestream); } diff --git a/src/tube-dbus.c b/src/tube-dbus.c index 0d12086b..39686d2f 100644 --- a/src/tube-dbus.c +++ b/src/tube-dbus.c @@ -114,7 +114,7 @@ struct _SalutTubeDBusPrivate { TpHandle self_handle; GibberMucConnection *muc_connection; - guint id; + guint64 id; GibberBytestreamIface *bytestream; gchar *stream_id; TpHandle initiator; @@ -636,7 +636,7 @@ salut_tube_dbus_get_property (GObject *object, g_value_set_object (value, priv->muc_connection); break; case PROP_ID: - g_value_set_uint (value, priv->id); + g_value_set_uint64 (value, priv->id); break; case PROP_BYTESTREAM: g_value_set_object (value, priv->bytestream); @@ -693,7 +693,7 @@ salut_tube_dbus_set_property (GObject *object, g_object_ref (priv->muc_connection); break; case PROP_ID: - priv->id = g_value_get_uint (value); + priv->id = g_value_get_uint64 (value); break; case PROP_BYTESTREAM: if (priv->bytestream == NULL) @@ -868,7 +868,7 @@ salut_tube_dbus_get_object_path_suffix (TpBaseChannel *base) SalutTubeDBus *self = SALUT_TUBE_DBUS (base); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); - return g_strdup_printf ("DBusTubeChannel/%u/%u", + return g_strdup_printf ("DBusTubeChannel/%u/%" G_GUINT64_FORMAT, tp_base_channel_get_target_handle (base), priv->id); } @@ -1307,7 +1307,7 @@ salut_tube_dbus_new (SalutConnection *conn, TpHandle initiator, const gchar *service, GHashTable *parameters, - guint id, + guint64 id, gboolean requested) { SalutTubeDBus *tube; diff --git a/src/tube-dbus.h b/src/tube-dbus.h index 5e617cfc..71b43bb6 100644 --- a/src/tube-dbus.h +++ b/src/tube-dbus.h @@ -69,7 +69,7 @@ SalutTubeDBus * salut_tube_dbus_new (SalutConnection *conn, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, GibberMucConnection *muc_connection, TpHandle initiator, - const gchar *service, GHashTable *parameters, guint id, + const gchar *service, GHashTable *parameters, guint64 id, gboolean requested); gboolean salut_tube_dbus_add_name (SalutTubeDBus *self, TpHandle handle, diff --git a/src/tube-iface.c b/src/tube-iface.c index 6978b074..56ad5e0c 100644 --- a/src/tube-iface.c +++ b/src/tube-iface.c @@ -130,7 +130,7 @@ salut_tube_iface_base_init (gpointer klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_interface_install_property (klass, param_spec); - param_spec = g_param_spec_uint ( + param_spec = g_param_spec_uint64 ( "id", "id", "The unique identifier of this tube", diff --git a/src/tube-stream.c b/src/tube-stream.c index 80fee7ea..ee501fe6 100644 --- a/src/tube-stream.c +++ b/src/tube-stream.c @@ -143,7 +143,7 @@ typedef struct _SalutTubeStreamPrivate SalutTubeStreamPrivate; struct _SalutTubeStreamPrivate { TpHandle self_handle; - guint id; + guint64 id; guint port; WockyStanza *iq_req; @@ -526,7 +526,7 @@ start_stream_initiation (SalutTubeStream *self, si_node = wocky_node_get_child_ns (msg_node, "si", WOCKY_XMPP_NS_SI); g_assert (si_node != NULL); - id_str = g_strdup_printf ("%u", priv->id); + id_str = g_strdup_printf ("%" G_GUINT64_FORMAT, priv->id); g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM); @@ -1096,7 +1096,7 @@ salut_tube_stream_get_property (GObject *object, g_value_set_uint (value, priv->self_handle); break; case PROP_ID: - g_value_set_uint (value, priv->id); + g_value_set_uint64 (value, priv->id); break; case PROP_TYPE: g_value_set_uint (value, TP_TUBE_TYPE_STREAM); @@ -1156,7 +1156,7 @@ salut_tube_stream_set_property (GObject *object, priv->self_handle = g_value_get_uint (value); break; case PROP_ID: - priv->id = g_value_get_uint (value); + priv->id = g_value_get_uint64 (value); break; case PROP_SERVICE: g_free (priv->service); @@ -1272,7 +1272,7 @@ salut_tube_stream_get_object_path_suffix (TpBaseChannel *base) SalutTubeStream *self = SALUT_TUBE_STREAM (base); SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self); - return g_strdup_printf ("StreamTubeChannel/%u/%u", + return g_strdup_printf ("StreamTubeChannel/%u/%" G_GUINT64_FORMAT, tp_base_channel_get_target_handle (base), priv->id); } @@ -1518,7 +1518,7 @@ salut_tube_stream_new (SalutConnection *conn, gboolean offered, const gchar *service, GHashTable *parameters, - guint id, + guint64 id, guint portnum, WockyStanza *iq_req, gboolean requested) @@ -1758,7 +1758,7 @@ salut_tube_stream_close (SalutTubeIface *tube, gboolean closed_remotely) SalutContact *contact; jid_from = tp_handle_inspect (contact_repo, priv->self_handle); - tube_id_str = g_strdup_printf ("%u", priv->id); + tube_id_str = g_strdup_printf ("%" G_GUINT64_FORMAT, priv->id); g_object_get (conn, "contact-manager", &contact_mgr, NULL); g_assert (contact_mgr != NULL); diff --git a/src/tube-stream.h b/src/tube-stream.h index 7c5f0f72..0594d20f 100644 --- a/src/tube-stream.h +++ b/src/tube-stream.h @@ -68,7 +68,7 @@ SalutTubeStream *salut_tube_stream_new (SalutConnection *conn, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, TpHandle initiator, gboolean offered, const gchar *service, - GHashTable *parameters, guint id, guint portnum, + GHashTable *parameters, guint64 id, guint portnum, WockyStanza *iq_req, gboolean requested); gboolean salut_tube_stream_check_params (TpSocketAddressType address_type, diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 778e11c5..597e12f4 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -62,7 +62,7 @@ static SalutTubeIface * create_new_tube (SalutTubesManager *self, TpHandle handle, const gchar *service, GHashTable *parameters, - guint tube_id, + guint64 tube_id, guint portnum, WockyStanza *iq_req); @@ -125,7 +125,7 @@ extract_tube_information (TpHandleRepoIface *contact_repo, TpHandle *initiator_handle, const gchar **service, GHashTable **parameters, - guint *tube_id, + guint64 *tube_id, guint *portnum, GError **error) { @@ -191,8 +191,7 @@ extract_tube_information (TpHandleRepoIface *contact_repo, if (tube_id != NULL) { const gchar *str; - gchar *endptr; - long int tmp; + guint64 tmp; str = wocky_node_get_attribute (node, "id"); if (str == NULL) @@ -202,14 +201,14 @@ extract_tube_information (TpHandleRepoIface *contact_repo, return FALSE; } - tmp = strtol (str, &endptr, 10); - if (!endptr || *endptr) + tmp = g_ascii_strtoull (str, NULL, 10); + if (tmp == 0 || tmp > G_MAXUINT32) { g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "tube id is not numeric: %s", str); + "tube id is non-numeric or out of range: %s", str); return FALSE; } - *tube_id = (int) tmp; + *tube_id = tmp; } /* next fields are not in the close stanza */ @@ -298,7 +297,7 @@ iq_tube_request_cb (WockyPorter *porter, TpTubeType tube_type; TpHandle initiator_handle; GHashTable *parameters; - guint tube_id; + guint64 tube_id; guint portnum = 0; gboolean close_; GError *error = NULL; @@ -326,7 +325,7 @@ iq_tube_request_cb (WockyPorter *porter, return TRUE; } - DEBUG ("received a tube request, tube id %d", tube_id); + DEBUG ("received a tube request, tube id %" G_GUINT64_FORMAT, tube_id); chan = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); @@ -688,17 +687,17 @@ channel_closed_cb (SalutTubeIface *tube, g_hash_table_remove (priv->tubes, GUINT_TO_POINTER (id)); } -static guint +static guint64 generate_tube_id (SalutTubesManager *self) { SalutTubesManagerPrivate *priv = SALUT_TUBES_MANAGER_GET_PRIVATE (self); - guint out; + guint64 out; /* probably totally overkill */ do { - out = g_random_int_range (0, G_MAXINT); + out = g_random_int_range (1, G_MAXINT32); } while (g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (out)) != NULL); @@ -712,7 +711,7 @@ create_new_tube (SalutTubesManager *self, TpHandle handle, const gchar *service, GHashTable *parameters, - guint tube_id, + guint64 tube_id, guint portnum, WockyStanza *iq_req) { @@ -759,7 +758,7 @@ new_channel_from_request (SalutTubesManager *self, TpTubeType type; const gchar *ctype, *service; TpHandle handle; - guint tube_id; + guint64 tube_id; GHashTable *parameters; ctype = tp_asv_get_string (request, TP_PROP_CHANNEL_CHANNEL_TYPE); -- cgit v1.2.1 From d884ea9c98163796436a3dbd4bbb5c19279b3b95 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 2 Aug 2012 11:47:57 +0100 Subject: tubes-manager: add a comment about who owns new channels Signed-off-by: Jonny Lamb --- src/tubes-manager.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/tubes-manager.c b/src/tubes-manager.c index 597e12f4..a94d1623 100644 --- a/src/tubes-manager.c +++ b/src/tubes-manager.c @@ -749,6 +749,8 @@ create_new_tube (SalutTubesManager *self, return tube; } +/* Returns: (transfer none): new tube channel. the channel manager + * holds the ref to this channel, so don't unref it! */ static SalutTubeIface * new_channel_from_request (SalutTubesManager *self, GHashTable *request) -- cgit v1.2.1 From f459366bff38f43d957d7f67b55aaef640f2e4b8 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Thu, 2 Aug 2012 16:07:48 +0100 Subject: muc-channel: remove ::appeared signal, replace with is_respawning check Signed-off-by: Jonny Lamb --- src/muc-channel.c | 11 ----------- src/muc-manager.c | 17 ++++++++--------- 2 files changed, 8 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/muc-channel.c b/src/muc-channel.c index a408a056..c83ca1de 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -77,7 +77,6 @@ enum READY, JOIN_ERROR, NEW_TUBE, - APPEARED, LAST_SIGNAL }; @@ -716,15 +715,6 @@ salut_muc_channel_class_init (SalutMucChannelClass *salut_muc_channel_class) * wants a value type, not an interface. */ G_TYPE_NONE, 1, TP_TYPE_BASE_CHANNEL); - signals[APPEARED] = g_signal_new ( - "appeared", - G_OBJECT_CLASS_TYPE (salut_muc_channel_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - tp_group_mixin_class_init (object_class, G_STRUCT_OFFSET(SalutMucChannelClass, group_class), salut_muc_channel_add_member, NULL); @@ -1276,7 +1266,6 @@ salut_muc_channel_received_stanza (GibberMucConnection *conn, { DEBUG ("making MUC channel reappear!"); tp_base_channel_reopened_with_requested (base_chan, FALSE, from_handle); - g_signal_emit (self, signals[APPEARED], 0); } /* let's not autoclose now */ diff --git a/src/muc-manager.c b/src/muc-manager.c index cf9c94b7..7dabb17a 100644 --- a/src/muc-manager.c +++ b/src/muc-manager.c @@ -418,6 +418,14 @@ muc_channel_closed_cb (SalutMucChannel *chan, TpBaseChannel *base = TP_BASE_CHANNEL (chan); TpHandle handle; + /* channel is actually reappearing, announce it */ + if (tp_base_channel_is_respawning (base)) + { + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (chan), NULL); + return; + } + if (tp_base_channel_is_registered (base)) { tp_channel_manager_emit_channel_closed_for_object (self, @@ -453,14 +461,6 @@ muc_channel_tube_closed_cb (SalutTubeIface *tube, } } -static void -muc_channel_appeared_cb (SalutMucChannel *chan, - SalutMucManager *mgr) -{ - tp_channel_manager_emit_new_channel (mgr, - TP_EXPORTABLE_CHANNEL (chan), NULL); -} - static void muc_channel_new_tube_cb (SalutMucChannel *channel, SalutTubeIface *tube, @@ -602,7 +602,6 @@ salut_muc_manager_new_muc_channel (SalutMucManager *mgr, g_signal_connect (chan, "closed", G_CALLBACK (muc_channel_closed_cb), mgr); g_signal_connect (chan, "new-tube", G_CALLBACK (muc_channel_new_tube_cb), mgr); - g_signal_connect (chan, "appeared", G_CALLBACK (muc_channel_appeared_cb), mgr); g_hash_table_insert (priv->text_channels, GUINT_TO_POINTER (handle), chan); -- cgit v1.2.1