diff options
Diffstat (limited to 'src')
110 files changed, 2151 insertions, 4240 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index c0f831d46..158a0bcc0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -125,8 +125,6 @@ libgabble_convenience_la_SOURCES = \ tls-certificate.c \ tube-iface.h \ tube-iface.c \ - tubes-channel.h \ - tubes-channel.c \ tube-dbus.h \ tube-dbus.c \ tube-stream.h \ diff --git a/src/addressing-util.c b/src/addressing-util.c index 0f1b3ffcc..049c566c6 100644 --- a/src/addressing-util.c +++ b/src/addressing-util.c @@ -85,7 +85,7 @@ gabble_uri_to_jid (const gchar *uri, if (scheme == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid URI", uri); goto OUT; } @@ -106,7 +106,7 @@ gabble_uri_to_jid (const gchar *uri, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "'%s' URI scheme is not supported by this protocol", scheme); goto OUT; @@ -137,7 +137,7 @@ gabble_jid_to_uri (const gchar *scheme, if (!wocky_decode_jid (jid, &node, &domain, &resource)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid JID", jid); return NULL; } @@ -234,7 +234,7 @@ gabble_vcard_address_to_jid (const gchar *vcard_field, if (gabble_error != NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is an invalid address: %s", vcard_address, gabble_error->message); g_error_free (gabble_error); @@ -249,7 +249,7 @@ gabble_vcard_address_to_jid (const gchar *vcard_field, s++; if (G_UNLIKELY (*s != '\0')) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is an invalid facebook chat address", vcard_address); goto OUT; } @@ -258,7 +258,7 @@ gabble_vcard_address_to_jid (const gchar *vcard_field, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "'%s' vCard field is not supported by this protocol", vcard_field); } @@ -286,7 +286,7 @@ gabble_jid_to_vcard_address (const gchar *vcard_field, if (gabble_error != NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is an invalid address: %s", jid, gabble_error->message); g_error_free (gabble_error); @@ -312,13 +312,13 @@ gabble_jid_to_vcard_address (const gchar *vcard_field, s++; if (G_UNLIKELY (*s != '\0')) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is an invalid facebook chat address", jid); } } else { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is an invalid facebook chat address", jid); } @@ -326,7 +326,7 @@ gabble_jid_to_vcard_address (const gchar *vcard_field, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "'%s' vCard field is not supported by this protocol", vcard_field); } @@ -438,7 +438,7 @@ gabble_parse_xmpp_uri (const gchar *uri, if (scheme == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid URI", uri); goto OUT; } @@ -447,7 +447,7 @@ gabble_parse_xmpp_uri (const gchar *uri, if (!wocky_decode_jid (jid, &tmp_node, &tmp_domain, &tmp_resource)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid XMPP URI", uri); goto OUT; } @@ -458,7 +458,7 @@ gabble_parse_xmpp_uri (const gchar *uri, unescaped_node = g_uri_unescape_string (tmp_node, NULL); if (unescaped_node == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid XMPP URI", uri); goto OUT; } @@ -468,7 +468,7 @@ gabble_parse_xmpp_uri (const gchar *uri, unescaped_domain = g_uri_unescape_string (tmp_domain, NULL); if (unescaped_domain == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid XMPP URI", uri); goto OUT; } @@ -478,7 +478,7 @@ gabble_parse_xmpp_uri (const gchar *uri, unescaped_resource = g_uri_unescape_string (tmp_resource, NULL); if (unescaped_resource == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid XMPP URI", uri); goto OUT; } @@ -491,7 +491,7 @@ gabble_parse_xmpp_uri (const gchar *uri, if (gabble_error != NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid XMPP URI: %s", uri, gabble_error->message); g_error_free (gabble_error); @@ -500,7 +500,7 @@ gabble_parse_xmpp_uri (const gchar *uri, if (!wocky_decode_jid (normalized_jid, node, domain, resource)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is not a valid XMPP URI", uri); goto OUT; } diff --git a/src/addressing-util.h b/src/addressing-util.h index 9835e0d70..378d1fe78 100644 --- a/src/addressing-util.h +++ b/src/addressing-util.h @@ -20,7 +20,7 @@ #ifndef __GABBLE_UTIL_ADDRESSING_H__ #define __GABBLE_UTIL_ADDRESSING_H__ -#include <telepathy-glib/handle-repo-dynamic.h> +#include <telepathy-glib/telepathy-glib.h> const gchar * const * gabble_get_addressable_uri_schemes (void); diff --git a/src/auth-manager.c b/src/auth-manager.c index 57a8bbd62..fd90bf517 100644 --- a/src/auth-manager.c +++ b/src/auth-manager.c @@ -20,9 +20,8 @@ #include "config.h" #include "auth-manager.h" -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> diff --git a/src/auth-manager.h b/src/auth-manager.h index bdf7ebfe2..dad5115f9 100644 --- a/src/auth-manager.h +++ b/src/auth-manager.h @@ -22,7 +22,9 @@ #include <glib-object.h> #include <wocky/wocky.h> -#include <telepathy-glib/handle.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> G_BEGIN_DECLS diff --git a/src/base-call-channel.c b/src/base-call-channel.c index 5ea79b27b..3c682d2a4 100644 --- a/src/base-call-channel.c +++ b/src/base-call-channel.c @@ -25,16 +25,8 @@ #include <gio/gio.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/dtmf.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-iface.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-properties-interface.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "util.h" #include "call-content.h" diff --git a/src/base-call-channel.h b/src/base-call-channel.h index 068b2dada..04add06e8 100644 --- a/src/base-call-channel.h +++ b/src/base-call-channel.h @@ -23,9 +23,8 @@ #include <glib-object.h> -#include <telepathy-glib/base-channel.h> -#include <telepathy-glib/base-call-channel.h> -#include <telepathy-glib/base-media-call-channel.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "jingle-content.h" #include "call-member.h" diff --git a/src/bytestream-factory.c b/src/bytestream-factory.c index 725f06e9f..12dcb5207 100644 --- a/src/bytestream-factory.c +++ b/src/bytestream-factory.c @@ -26,7 +26,8 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> #include <wocky/wocky.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM @@ -1298,8 +1299,6 @@ out: g_slist_free (stream_methods); g_free (peer_resource); g_free (self_jid); - if (peer_handle != 0) - tp_handle_unref (contact_repo, peer_handle); return TRUE; } @@ -2146,9 +2145,6 @@ END: if (peer_resource != NULL) g_free (peer_resource); - if (peer_handle != 0) - tp_handle_unref (contact_repo, peer_handle); - g_free (self_jid); g_free (data->stream_id); g_slice_free (struct _streaminit_reply_cb_data, data); diff --git a/src/bytestream-factory.h b/src/bytestream-factory.h index 7a86cd4f8..733f1b886 100644 --- a/src/bytestream-factory.h +++ b/src/bytestream-factory.h @@ -21,7 +21,7 @@ #define __BYTESTREAM_FACTORY_H__ #include <glib-object.h> -#include <telepathy-glib/base-connection.h> +#include <telepathy-glib/telepathy-glib.h> #include "types.h" #include "bytestream-iface.h" #include "bytestream-ibb.h" diff --git a/src/bytestream-ibb.c b/src/bytestream-ibb.c index bfa1b5641..a479eb2fb 100644 --- a/src/bytestream-ibb.c +++ b/src/bytestream-ibb.c @@ -24,7 +24,8 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM @@ -124,16 +125,12 @@ gabble_bytestream_ibb_dispose (GObject *object) { GabbleBytestreamIBB *self = GABBLE_BYTESTREAM_IBB (object); GabbleBytestreamIBBPrivate *priv = GABBLE_BYTESTREAM_IBB_GET_PRIVATE (self); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); if (priv->dispose_has_run) return; priv->dispose_has_run = TRUE; - tp_handle_unref (contact_repo, priv->peer_handle); - if (priv->state != GABBLE_BYTESTREAM_STATE_CLOSED) { gabble_bytestream_iface_close (GABBLE_BYTESTREAM_IFACE (self), NULL); @@ -285,8 +282,6 @@ gabble_bytestream_ibb_constructor (GType type, contact_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - tp_handle_ref (contact_repo, priv->peer_handle); - jid = tp_handle_inspect (contact_repo, priv->peer_handle); if (priv->peer_resource != NULL) diff --git a/src/bytestream-ibb.h b/src/bytestream-ibb.h index fa1af3a2e..2d96baf12 100644 --- a/src/bytestream-ibb.h +++ b/src/bytestream-ibb.h @@ -22,7 +22,7 @@ #include <glib-object.h> #include <wocky/wocky.h> -#include <telepathy-glib/base-connection.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/bytestream-muc.c b/src/bytestream-muc.c index 4a803bc58..84ade6249 100644 --- a/src/bytestream-muc.c +++ b/src/bytestream-muc.c @@ -24,7 +24,8 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM @@ -100,16 +101,12 @@ gabble_bytestream_muc_dispose (GObject *object) { GabbleBytestreamMuc *self = GABBLE_BYTESTREAM_MUC (object); GabbleBytestreamMucPrivate *priv = GABBLE_BYTESTREAM_MUC_GET_PRIVATE (self); - TpHandleRepoIface *room_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_ROOM); if (priv->dispose_has_run) return; priv->dispose_has_run = TRUE; - tp_handle_unref (room_repo, priv->peer_handle); - if (priv->state != GABBLE_BYTESTREAM_STATE_CLOSED) { gabble_bytestream_iface_close (GABBLE_BYTESTREAM_IFACE (self), NULL); @@ -228,8 +225,6 @@ gabble_bytestream_muc_constructor (GType type, room_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_ROOM); - tp_handle_ref (room_repo, priv->peer_handle); - priv->peer_jid = tp_handle_inspect (room_repo, priv->peer_handle); diff --git a/src/bytestream-muc.h b/src/bytestream-muc.h index 06dcd2689..393410eec 100644 --- a/src/bytestream-muc.h +++ b/src/bytestream-muc.h @@ -22,7 +22,7 @@ #include <glib-object.h> #include <wocky/wocky.h> -#include <telepathy-glib/base-connection.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/bytestream-multiple.c b/src/bytestream-multiple.c index 07243e1f1..4fa1cb855 100644 --- a/src/bytestream-multiple.c +++ b/src/bytestream-multiple.c @@ -22,7 +22,9 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/interfaces.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM @@ -100,16 +102,12 @@ gabble_bytestream_multiple_dispose (GObject *object) GabbleBytestreamMultiple *self = GABBLE_BYTESTREAM_MULTIPLE (object); GabbleBytestreamMultiplePrivate *priv = GABBLE_BYTESTREAM_MULTIPLE_GET_PRIVATE (self); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); if (priv->dispose_has_run) return; priv->dispose_has_run = TRUE; - tp_handle_unref (contact_repo, priv->peer_handle); - if (priv->state != GABBLE_BYTESTREAM_STATE_CLOSED) { gabble_bytestream_iface_close (GABBLE_BYTESTREAM_IFACE (self), NULL); @@ -263,8 +261,6 @@ gabble_bytestream_multiple_constructor (GType type, contact_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - tp_handle_ref (contact_repo, priv->peer_handle); - jid = tp_handle_inspect (contact_repo, priv->peer_handle); if (priv->peer_resource != NULL) diff --git a/src/bytestream-socks5.c b/src/bytestream-socks5.c index 12bd7c509..dfebc2ac2 100644 --- a/src/bytestream-socks5.c +++ b/src/bytestream-socks5.c @@ -44,7 +44,9 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/interfaces.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <gibber/gibber-transport.h> #include <gibber/gibber-tcp-transport.h> @@ -232,8 +234,6 @@ gabble_bytestream_socks5_dispose (GObject *object) GabbleBytestreamSocks5 *self = GABBLE_BYTESTREAM_SOCKS5 (object); GabbleBytestreamSocks5Private *priv = GABBLE_BYTESTREAM_SOCKS5_GET_PRIVATE (self); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); if (priv->dispose_has_run) return; @@ -242,8 +242,6 @@ gabble_bytestream_socks5_dispose (GObject *object) stop_timer (self); - tp_handle_unref (contact_repo, priv->peer_handle); - if (priv->bytestream_state != GABBLE_BYTESTREAM_STATE_CLOSED) { gabble_bytestream_iface_close (GABBLE_BYTESTREAM_IFACE (self), NULL); @@ -398,8 +396,6 @@ gabble_bytestream_socks5_constructor (GType type, room_repo = tp_base_connection_get_handles (base_conn, TP_HANDLE_TYPE_ROOM); - tp_handle_ref (contact_repo, priv->peer_handle); - jid = tp_handle_inspect (contact_repo, priv->peer_handle); if (priv->peer_resource != NULL) diff --git a/src/bytestream-socks5.h b/src/bytestream-socks5.h index 524812f32..f3704e469 100644 --- a/src/bytestream-socks5.h +++ b/src/bytestream-socks5.h @@ -24,7 +24,7 @@ #include <glib-object.h> #include <wocky/wocky.h> -#include <telepathy-glib/base-connection.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/call-channel.c b/src/call-channel.c index 8e7b4bce2..223c22350 100644 --- a/src/call-channel.c +++ b/src/call-channel.c @@ -26,13 +26,8 @@ #include <gio/gio.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-iface.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "util.h" #include "call-channel.h" @@ -435,11 +430,11 @@ contact_is_media_capable (GabbleCallChannel *self, *wait_ret = wait; if (presence == NULL) - g_set_error (error, TP_ERRORS, TP_ERROR_OFFLINE, + g_set_error (error, TP_ERROR, TP_ERROR_OFFLINE, "contact %d (%s) has no presence available", handle, tp_handle_inspect (contact_handles, handle)); else - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_CAPABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE, "contact %d (%s) doesn't have sufficient media caps", handle, tp_handle_inspect (contact_handles, handle)); @@ -667,7 +662,7 @@ call_channel_add_content (TpBaseCallChannel *base, if (initial_direction == TP_MEDIA_STREAM_DIRECTION_NONE) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Jingle can not do contents with direction = NONE"); return NULL; } diff --git a/src/call-content.c b/src/call-content.c index 8550b82fc..46616e39f 100644 --- a/src/call-content.c +++ b/src/call-content.c @@ -23,12 +23,8 @@ #include <stdio.h> #include <stdlib.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/svc-properties-interface.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "call-member.h" #include "call-content.h" diff --git a/src/call-content.h b/src/call-content.h index ff3205f55..70df5405b 100644 --- a/src/call-content.h +++ b/src/call-content.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/base-media-call-content.h> +#include <telepathy-glib/telepathy-glib.h> #include "jingle-content.h" #include "call-member-content.h" diff --git a/src/call-member.c b/src/call-member.c index aba19013b..9c7b0d350 100644 --- a/src/call-member.c +++ b/src/call-member.c @@ -466,7 +466,7 @@ gabble_call_member_create_content (GabbleCallMember *self, if (content_ns == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Content type %d not available for this resource", mtype); return NULL; } @@ -550,7 +550,7 @@ gabble_call_member_start_session (GabbleCallMember *self, target, audio_name != NULL, video_name != NULL, &transport, &dialect, &resource)) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_CAPABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE, "member does not have the desired audio/video capabilities"); return FALSE; } diff --git a/src/call-member.h b/src/call-member.h index 5554a9ec0..4b052fa7e 100644 --- a/src/call-member.h +++ b/src/call-member.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/handle.h> +#include <telepathy-glib/telepathy-glib.h> #include "types.h" #include "jingle-session.h" diff --git a/src/call-muc-channel.c b/src/call-muc-channel.c index 62d40c695..3b4a063f1 100644 --- a/src/call-muc-channel.c +++ b/src/call-muc-channel.c @@ -23,9 +23,8 @@ #include <stdio.h> #include <stdlib.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> #include "call-content.h" @@ -1163,14 +1162,14 @@ call_muc_channel_add_content (TpBaseCallChannel *base, if (initial_direction == TP_MEDIA_STREAM_DIRECTION_NONE) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Jingle can not do contents with direction = NONE"); return NULL; } if (initial_direction != TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Adding un-directional contents is not supported" " in MUC channels"); return NULL; diff --git a/src/call-stream.c b/src/call-stream.c index a25365db9..ae9ac5e8f 100644 --- a/src/call-stream.c +++ b/src/call-stream.c @@ -23,11 +23,8 @@ #include <stdio.h> #include <stdlib.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/svc-properties-interface.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "call-stream.h" #include "connection.h" @@ -584,7 +581,7 @@ gabble_call_stream_add_candidates (TpBaseMediaCallStream *stream, if (accepted_candidates->len == 0 && candidates->len != 0) { - g_set_error_literal (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error_literal (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "All candidates had the wrong Type"); tp_clear_pointer (&accepted_candidates, g_ptr_array_unref); } diff --git a/src/call-stream.h b/src/call-stream.h index ed8bb767f..e30593e41 100644 --- a/src/call-stream.h +++ b/src/call-stream.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/base-media-call-stream.h> +#include <telepathy-glib/telepathy-glib.h> #include "jingle-types.h" diff --git a/src/capabilities.c b/src/capabilities.c index d2b25f57f..9d8a97f69 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -24,11 +24,8 @@ #include <stdlib.h> #include <string.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/handle-repo.h> -#include <telepathy-glib/handle-repo-dynamic.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE #include "debug.h" @@ -453,7 +450,7 @@ void gabble_capability_set_update (GabbleCapabilitySet *target, const GabbleCapabilitySet *source) { - TpIntSet *ret; + TpIntset *ret; g_return_if_fail (target != NULL); g_return_if_fail (source != NULL); @@ -539,9 +536,7 @@ gabble_capability_set_add (GabbleCapabilitySet *caps, g_return_if_fail (cap != NULL); handle = tp_handle_ensure (feature_handles, cap, NULL, NULL); - tp_handle_set_add (caps->handles, handle); - tp_handle_unref (feature_handles, handle); } gboolean @@ -613,16 +608,17 @@ gboolean gabble_capability_set_has_one (const GabbleCapabilitySet *caps, const GabbleCapabilitySet *alternatives) { - TpIntSetIter iter; + TpIntsetFastIter iter; + guint element; g_return_val_if_fail (caps != NULL, FALSE); g_return_val_if_fail (alternatives != NULL, FALSE); - tp_intset_iter_init (&iter, tp_handle_set_peek (alternatives->handles)); + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (alternatives->handles)); - while (tp_intset_iter_next (&iter)) + while (tp_intset_fast_iter_next (&iter, &element)) { - if (tp_handle_set_is_member (caps->handles, iter.element)) + if (tp_handle_set_is_member (caps->handles, element)) { return TRUE; } @@ -636,16 +632,17 @@ gboolean gabble_capability_set_at_least (const GabbleCapabilitySet *caps, const GabbleCapabilitySet *query) { - TpIntSetIter iter; + TpIntsetFastIter iter; + guint element; g_return_val_if_fail (caps != NULL, FALSE); g_return_val_if_fail (query != NULL, FALSE); - tp_intset_iter_init (&iter, tp_handle_set_peek (query->handles)); + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (query->handles)); - while (tp_intset_iter_next (&iter)) + while (tp_intset_fast_iter_next (&iter, &element)) { - if (!tp_handle_set_is_member (caps->handles, iter.element)) + if (!tp_handle_set_is_member (caps->handles, element)) { return FALSE; } @@ -670,16 +667,17 @@ void gabble_capability_set_foreach (const GabbleCapabilitySet *caps, GFunc func, gpointer user_data) { - TpIntSetIter iter; + TpIntsetFastIter iter; + guint element; g_return_if_fail (caps != NULL); g_return_if_fail (func != NULL); - tp_intset_iter_init (&iter, tp_handle_set_peek (caps->handles)); + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (caps->handles)); - while (tp_intset_iter_next (&iter)) + while (tp_intset_fast_iter_next (&iter, &element)) { - const gchar *var = tp_handle_inspect (feature_handles, iter.element); + const gchar *var = tp_handle_inspect (feature_handles, element); g_return_if_fail (var != NULL); @@ -690,10 +688,10 @@ gabble_capability_set_foreach (const GabbleCapabilitySet *caps, static void append_intset (GString *ret, - const TpIntSet *cap_ints, + const TpIntset *cap_ints, const gchar *indent) { - TpIntSetFastIter iter; + TpIntsetFastIter iter; guint element; tp_intset_fast_iter_init (&iter, cap_ints); @@ -739,7 +737,7 @@ gabble_capability_set_dump_diff (const GabbleCapabilitySet *old_caps, const GabbleCapabilitySet *new_caps, const gchar *indent) { - TpIntSet *old_ints, *new_ints, *rem, *add; + TpIntset *old_ints, *new_ints, *rem, *add; GString *ret; g_return_val_if_fail (old_caps != NULL, NULL); diff --git a/src/caps-channel-manager.c b/src/caps-channel-manager.c index dea13a652..c6b7e16b1 100644 --- a/src/caps-channel-manager.c +++ b/src/caps-channel-manager.c @@ -23,9 +23,7 @@ #include "config.h" #include "gabble/caps-channel-manager.h" -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/channel-manager.h> - +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE #include "debug.h" diff --git a/src/conn-addressing.c b/src/conn-addressing.c index c02910e10..7fff35455 100644 --- a/src/conn-addressing.c +++ b/src/conn-addressing.c @@ -23,8 +23,8 @@ #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "extensions/extensions.h" @@ -104,7 +104,6 @@ conn_addressing_get_contacts_by_uri (GabbleSvcConnectionInterfaceAddressing *ifa gabble_svc_connection_interface_addressing_return_from_get_contacts_by_uri ( context, requested, attributes); - tp_handles_unref (contact_repo, handles); g_array_unref (handles); g_hash_table_unref (requested); g_hash_table_unref (attributes); @@ -145,7 +144,6 @@ conn_addressing_get_contacts_by_vcard_field (GabbleSvcConnectionInterfaceAddress gabble_svc_connection_interface_addressing_return_from_get_contacts_by_vcard_field ( context, requested, attributes); - tp_handles_unref (contact_repo, handles); g_array_unref (handles); g_hash_table_unref (requested); g_hash_table_unref (attributes); diff --git a/src/conn-aliasing.c b/src/conn-aliasing.c index f48758eaf..ee5c886a6 100644 --- a/src/conn-aliasing.c +++ b/src/conn-aliasing.c @@ -22,10 +22,9 @@ #include "conn-aliasing.h" #include <wocky/wocky.h> -#include <telepathy-glib/contacts-mixin.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-connection.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_CONNECTION @@ -103,7 +102,6 @@ aliases_request_new (GabbleConnection *conn, const GArray *contacts) { AliasesRequest *request; - TpHandleRepoIface *contact_handles; request = g_slice_new0 (AliasesRequest); request->conn = conn; @@ -116,10 +114,6 @@ aliases_request_new (GabbleConnection *conn, g_new0 (GabbleRequestPipelineItem *, contacts->len); request->aliases = g_new0 (gchar *, contacts->len + 1); - contact_handles = tp_base_connection_get_handles ((TpBaseConnection *) conn, - TP_HANDLE_TYPE_CONTACT); - tp_handles_ref (contact_handles, contacts); - return request; } @@ -128,7 +122,6 @@ static void aliases_request_free (AliasesRequest *request) { guint i; - TpHandleRepoIface *contact_handles; for (i = 0; i < request->contacts->len; i++) { @@ -138,10 +131,6 @@ aliases_request_free (AliasesRequest *request) request->vcard_requests[i]); } - contact_handles = tp_base_connection_get_handles ( - (TpBaseConnection *) request->conn, TP_HANDLE_TYPE_CONTACT); - tp_handles_unref (contact_handles, request->contacts); - g_array_unref (request->contacts); g_free (request->vcard_requests); g_free (request->pep_requests); @@ -341,7 +330,6 @@ pep_request_cb ( pep_request_ctx *ctx = user_data; ctx->callback (conn, msg, ctx->user_data, error); - tp_handle_unref (ctx->contact_handles, ctx->handle); g_slice_free (pep_request_ctx, ctx); } @@ -372,7 +360,6 @@ gabble_do_pep_request (GabbleConnection *self, ctx->contact_handles = contact_handles; ctx->handle = handle; - tp_handle_ref (contact_handles, handle); to = tp_handle_inspect (contact_handles, handle); msg = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, to, diff --git a/src/conn-avatars.c b/src/conn-avatars.c index 3a12ce290..7504c6395 100644 --- a/src/conn-avatars.c +++ b/src/conn-avatars.c @@ -24,9 +24,8 @@ #include <string.h> -#include <telepathy-glib/svc-connection.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/contacts-mixin.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "base64.h" #include "presence.h" @@ -421,7 +420,7 @@ parse_avatar (WockyNode *vcard, if (NULL == photo_node) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "contact vCard has no photo"); return FALSE; } @@ -441,7 +440,7 @@ parse_avatar (WockyNode *vcard, if (NULL == binval_node) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "contact avatar is missing binval node"); return FALSE; } @@ -450,7 +449,7 @@ parse_avatar (WockyNode *vcard, if (NULL == binval_value) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "contact avatar is missing binval content"); return FALSE; } @@ -459,7 +458,7 @@ parse_avatar (WockyNode *vcard, if (NULL == *avatar) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "failed to decode avatar from base64"); return FALSE; } @@ -489,7 +488,7 @@ _request_avatar_cb (GabbleVCardManager *self, if (NULL == vcard) { - GError tp_error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError tp_error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, vcard_error->message }; if (vcard_error->domain == WOCKY_XMPP_ERROR) @@ -537,7 +536,7 @@ _request_avatar_cb (GabbleVCardManager *self, DEBUG ("treason uncloaked! avatar hash in presence does not match " "avatar in vCard for handle %u", handle); - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "avatar hash in presence does not match avatar in vCard"); dbus_g_method_return_error (context, error); g_error_free (error); @@ -755,7 +754,7 @@ _set_avatar_cb2 (GabbleVCardManager *manager, if (NULL == vcard) { - GError tp_error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError tp_error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, vcard_error->message }; /* Google Talk has been observed to return bad-request when the avatar is diff --git a/src/conn-client-types.c b/src/conn-client-types.c index 012749c19..1a5ff1e8f 100644 --- a/src/conn-client-types.c +++ b/src/conn-client-types.c @@ -22,7 +22,8 @@ #include <string.h> #include <stdlib.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <extensions/extensions.h> diff --git a/src/conn-contact-info.c b/src/conn-contact-info.c index a78f172e4..599197b9b 100644 --- a/src/conn-contact-info.c +++ b/src/conn-contact-info.c @@ -24,9 +24,8 @@ #include <string.h> -#include <telepathy-glib/svc-connection.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "vcard-manager.h" @@ -484,7 +483,7 @@ _return_from_request_contact_info (WockyNode *vcard_node, if (NULL == vcard_node) { - GError tp_error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError tp_error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, vcard_error->message }; if (vcard_error->domain == WOCKY_XMPP_ERROR) @@ -650,7 +649,7 @@ conn_contact_info_new_edit (const VCardField *field, if (field->types[0] == NULL && field_params[0] != NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s vCard field expects no type-parameters", field->xmpp_name); gabble_vcard_manager_edit_info_free (edit_info); return NULL; @@ -681,7 +680,7 @@ conn_contact_info_new_edit (const VCardField *field, if (!used) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s vCard field does not support type-parameter %s", field->xmpp_name, *p); gabble_vcard_manager_edit_info_free (edit_info); @@ -703,7 +702,7 @@ _set_contact_info_cb (GabbleVCardManager *vcard_manager, if (vcard_node == NULL) { - GError tp_error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError tp_error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, vcard_error->message }; if (vcard_error->domain == WOCKY_XMPP_ERROR) @@ -763,7 +762,7 @@ gabble_connection_set_contact_info (TpSvcConnectionInterfaceContactInfo *iface, if (field == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "unknown vCard field from D-Bus: %s", field_name); goto finally; } @@ -771,7 +770,7 @@ gabble_connection_set_contact_info (TpSvcConnectionInterfaceContactInfo *iface, if (!gabble_vcard_manager_can_use_vcard_field (self->vcard_manager, field->xmpp_name)) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s vCard field is not supported by this server", field->xmpp_name); goto finally; @@ -784,7 +783,7 @@ gabble_connection_set_contact_info (TpSvcConnectionInterfaceContactInfo *iface, { if (n_field_values != 1) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s vCard field expects one value but got %u", field->xmpp_name, n_field_values); goto finally; @@ -808,7 +807,7 @@ gabble_connection_set_contact_info (TpSvcConnectionInterfaceContactInfo *iface, if (n_field_values != n_elements) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s vCard field expects %u values but got %u", field->xmpp_name, n_elements, n_field_values); goto finally; @@ -834,7 +833,7 @@ gabble_connection_set_contact_info (TpSvcConnectionInterfaceContactInfo *iface, if (n_field_values == 0) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "ORG vCard field expects at least one value but got 0"); goto finally; } @@ -865,7 +864,7 @@ gabble_connection_set_contact_info (TpSvcConnectionInterfaceContactInfo *iface, if (n_field_values != 1) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s vCard field expects one value but got %u", field->xmpp_name, n_field_values); goto finally; diff --git a/src/conn-location.c b/src/conn-location.c index b9ac05474..f73907735 100644 --- a/src/conn-location.c +++ b/src/conn-location.c @@ -8,8 +8,8 @@ #define DEBUG_FLAG GABBLE_DEBUG_LOCATION -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> #include <gabble/gabble.h> @@ -263,7 +263,7 @@ add_to_geoloc_node (const gchar *tp_name, { if (G_VALUE_TYPE (value) != G_TYPE_STRING) { - g_set_error (err, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (err, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "expecting string for language value, but got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -286,7 +286,7 @@ add_to_geoloc_node (const gchar *tp_name, if (G_VALUE_TYPE (value) != mapping->type) { - g_set_error (err, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (err, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "'%s' is supposed to be of type %s but is %s", (const char *) tp_name, g_type_name (mapping->type), G_VALUE_TYPE_NAME (value)); @@ -364,7 +364,7 @@ location_set_location (TpSvcConnectionInterfaceLocation *iface, if (!(conn->features & GABBLE_CONNECTION_FEATURES_PEP)) { - GError error = { TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + GError error = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Server does not support PEP, cannot publish geolocation" }; dbus_g_method_return_error (context, &error); @@ -395,7 +395,7 @@ location_set_location (TpSvcConnectionInterfaceLocation *iface, if (!_gabble_connection_send_with_reply (conn, msg, set_location_sent_cb, G_OBJECT (conn), context, NULL)) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send msg" }; dbus_g_method_return_error (context, &error); @@ -511,7 +511,7 @@ conn_location_properties_setter (GObject *object, if (access_control_type != TP_RICH_PRESENCE_ACCESS_CONTROL_TYPE_PUBLISH_LIST) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Access control type not implemented"); return FALSE; } @@ -644,12 +644,9 @@ location_pep_node_changed (WockyPepService *pep, if (handle == base->self_handle) /* Ignore echoed pubsub notifications */ - goto out; + return; update_location_from_item (conn, handle, item_node); - -out: - tp_handle_unref (contact_repo, handle); } static void diff --git a/src/conn-mail-notif.c b/src/conn-mail-notif.c index 2fe12e41e..1735aa212 100644 --- a/src/conn-mail-notif.c +++ b/src/conn-mail-notif.c @@ -33,11 +33,9 @@ #include <string.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/svc-connection.h> -#include <telepathy-glib/util.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> @@ -90,12 +88,12 @@ return_from_request_inbox_url (GabbleConnection *conn) if (priv->inbox_url != NULL && priv->inbox_url[0] == '\0') { - error = g_error_new (TP_ERRORS, TP_ERROR_NETWORK_ERROR, + error = g_error_new (TP_ERROR, TP_ERROR_NETWORK_ERROR, "Server did not provide base URL."); } else if (priv->inbox_url == NULL) { - error = g_error_new (TP_ERRORS, TP_ERROR_DISCONNECTED, + error = g_error_new (TP_ERROR, TP_ERROR_DISCONNECTED, "Connection was disconnected during request."); } else @@ -143,7 +141,7 @@ check_supported_or_dbus_return (GabbleConnection *conn, { if (TP_BASE_CONNECTION (conn)->status != TP_CONNECTION_STATUS_CONNECTED) { - GError e = { TP_ERRORS, TP_ERROR_DISCONNECTED, "Not connected" }; + GError e = { TP_ERROR, TP_ERROR_DISCONNECTED, "Not connected" }; dbus_g_method_return_error (context, &e); return TRUE; } @@ -220,7 +218,7 @@ gabble_mail_notification_request_mail_url ( } else { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to retrieve URL from server."}; dbus_g_method_return_error (context, &error); } diff --git a/src/conn-olpc.c b/src/conn-olpc.c index 243d2dff0..167538ccd 100644 --- a/src/conn-olpc.c +++ b/src/conn-olpc.c @@ -23,8 +23,7 @@ #include <string.h> #include <stdlib.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_OLPC @@ -129,7 +128,7 @@ check_pep (GabbleConnection *conn, { if (!(conn->features & GABBLE_CONNECTION_FEATURES_PEP)) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Server does not support PEP" }; DEBUG ("%s", error.message); @@ -277,7 +276,7 @@ get_properties_reply_cb (GObject *source, NULL, &error); if (reply_msg == NULL) { - GError err = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError err = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property request to server" }; DEBUG ("Query failed: %s", error->message); @@ -379,7 +378,7 @@ transmit_properties (GabbleConnection *conn, if (!_gabble_connection_send_with_reply (conn, msg, set_properties_reply_cb, NULL, context, NULL)) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property change request to server" }; DEBUG ("%s", error.message); @@ -495,7 +494,7 @@ olpc_buddy_props_pep_node_changed (WockyPepService *pep, if (handle == base->self_handle) /* Ignore echoed pubsub notifications */ - goto out; + return; node = search_for_child ( wocky_stanza_get_top_node (stanza), "properties", NULL); @@ -503,8 +502,6 @@ olpc_buddy_props_pep_node_changed (WockyPepService *pep, gabble_svc_olpc_buddy_info_emit_properties_changed (conn, handle, properties); g_hash_table_unref (properties); -out: - tp_handle_unref (contact_repo, handle); } static void @@ -575,7 +572,7 @@ static GPtrArray * get_buddy_activities (GabbleConnection *conn, TpHandle buddy) { - TpIntSet *all; + TpIntset *all; gboolean free_all = FALSE; GPtrArray *activities = g_ptr_array_new (); TpHandleSet *invited_activities, *pep_activities; @@ -612,18 +609,21 @@ get_buddy_activities (GabbleConnection *conn, if (all != NULL) { - TpIntSetIter iter = TP_INTSET_ITER_INIT (all); + TpIntsetFastIter iter; + guint element; - while (tp_intset_iter_next (&iter)) + tp_intset_fast_iter_init (&iter, all); + + while (tp_intset_fast_iter_next (&iter, &element)) { GabbleOlpcActivity *activity = g_hash_table_lookup ( - conn->olpc_activities_info, GUINT_TO_POINTER (iter.element)); + conn->olpc_activities_info, GUINT_TO_POINTER (element)); GValue gvalue = { 0 }; g_assert (activity != NULL); if (activity->id == NULL) { - DEBUG ("... activity #%u has no ID, skipping", iter.element); + DEBUG ("... activity #%u has no ID, skipping", element); continue; } @@ -707,7 +707,6 @@ extract_activities (GabbleConnection *conn, if (tp_handle_set_is_member (activities_set, room_handle)) { NODE_DEBUG (node, "Room advertised twice, skipping"); - tp_handle_unref (room_repo, room_handle); continue; } @@ -719,7 +718,6 @@ extract_activities (GabbleConnection *conn, } /* pass ownership to the activities_set */ tp_handle_set_add (activities_set, room_handle); - tp_handle_unref (room_repo, room_handle); if (tp_strdiff (activity->id, act_id)) { @@ -824,7 +822,7 @@ get_activities_reply_cb (GObject *source, NULL, &err); if (reply_msg == NULL) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property request to server" }; DEBUG ("Query failed: %s", err->message); @@ -838,7 +836,7 @@ get_activities_reply_cb (GObject *source, wocky_stanza_get_top_node (reply_msg), "from"); if (from == NULL) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Error in pubsub reply: no sender" }; dbus_g_method_return_error (ctx->context, &error); @@ -848,7 +846,7 @@ get_activities_reply_cb (GObject *source, from_handle = tp_handle_lookup (contact_repo, from, NULL, NULL); if (from_handle == 0) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Error in pubsub reply: unknown sender" }; dbus_g_method_return_error (ctx->context, &error); @@ -938,13 +936,15 @@ upload_activities_pep (GabbleConnection *conn, if (my_activities != NULL) { - TpIntSetIter iter = TP_INTSET_ITER_INIT (tp_handle_set_peek - (my_activities)); + TpIntsetFastIter iter; + guint element; + + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (my_activities)); - while (tp_intset_iter_next (&iter)) + while (tp_intset_fast_iter_next (&iter, &element)) { GabbleOlpcActivity *activity = g_hash_table_lookup ( - conn->olpc_activities_info, GUINT_TO_POINTER (iter.element)); + conn->olpc_activities_info, GUINT_TO_POINTER (element)); WockyNode *activity_node; g_assert (activity != NULL); @@ -965,7 +965,7 @@ upload_activities_pep (GabbleConnection *conn, if (!ret) { - g_set_error (error, TP_ERRORS, TP_ERROR_NETWORK_ERROR, + g_set_error (error, TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property change request to server: %s", e->message); g_error_free (e); } @@ -1012,7 +1012,7 @@ add_activity (GabbleConnection *self, if (old_activities != NULL && tp_handle_set_is_member (old_activities, channel)) { - *error = g_error_new (TP_ERRORS, + *error = g_error_new (TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Can't set twice the same activity: %s", id); @@ -1109,7 +1109,7 @@ olpc_buddy_info_set_activities (GabbleSvcOLPCBuddyInfo *iface, { if (tp_handle_set_is_member (activities_set, channel)) { - error = g_error_new (TP_ERRORS, + error = g_error_new (TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Can't set twice the same activity: %s", room); @@ -1161,7 +1161,7 @@ olpc_buddy_info_set_activities (GabbleSvcOLPCBuddyInfo *iface, if (!upload_activities_pep (conn, set_activities_reply_cb, context, NULL)) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property request to server" }; dbus_g_method_return_error (context, &error); @@ -1302,8 +1302,6 @@ extract_current_activity (GabbleConnection *conn, conn->olpc_pep_activities); } - tp_handle_unref (room_repo, room_handle); - /* update current-activity cache */ if (activity != NULL) { @@ -1336,7 +1334,7 @@ get_current_activity_reply_cb (GObject *source, NULL, &error); if (reply_msg == NULL) { - GError err = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError err = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property request to server" }; DEBUG ("Query failed: %s", error->message); @@ -1501,7 +1499,7 @@ olpc_buddy_info_set_current_activity (GabbleSvcOLPCBuddyInfo *iface, if (!activity_in_own_set (conn, room)) { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Can't set an activity as current if you're not announcing it" }; dbus_g_method_return_error (context, &error); @@ -1522,7 +1520,7 @@ olpc_buddy_info_set_current_activity (GabbleSvcOLPCBuddyInfo *iface, if (!_gabble_connection_send_with_reply (conn, msg, set_current_activity_reply_cb, NULL, context, NULL)) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property change request to server" }; dbus_g_method_return_error (context, &error); @@ -1556,7 +1554,7 @@ olpc_current_act_pep_node_changed (WockyPepService *pep, if (handle == base->self_handle) /* Ignore echoed pubsub notifications */ - goto out; + return; node = search_for_child (wocky_stanza_get_top_node (stanza), "activity", NULL); @@ -1576,9 +1574,6 @@ olpc_current_act_pep_node_changed (WockyPepService *pep, gabble_svc_olpc_buddy_info_emit_current_activity_changed (conn, handle, "", 0); } - -out: - tp_handle_unref (contact_repo, handle); } static void @@ -1634,7 +1629,7 @@ olpc_buddy_info_add_activity (GabbleSvcOLPCBuddyInfo *iface, if (!upload_activities_pep (self, add_activity_reply_cb, context, NULL)) { - error = g_error_new (TP_ERRORS, TP_ERROR_NETWORK_ERROR, + error = g_error_new (TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property request to server"); dbus_g_method_return_error (context, error); @@ -1680,13 +1675,15 @@ upload_activity_properties_pep (GabbleConnection *conn, if (my_activities != NULL) { - TpIntSetIter iter = TP_INTSET_ITER_INIT (tp_handle_set_peek - (my_activities)); + TpIntsetFastIter iter; + guint element; - while (tp_intset_iter_next (&iter)) + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (my_activities)); + + while (tp_intset_fast_iter_next (&iter, &element)) { GabbleOlpcActivity *activity = g_hash_table_lookup ( - conn->olpc_activities_info, GUINT_TO_POINTER (iter.element)); + conn->olpc_activities_info, GUINT_TO_POINTER (element)); activity_info_contribute_properties (activity, publish, TRUE); } @@ -1697,7 +1694,7 @@ upload_activity_properties_pep (GabbleConnection *conn, if (!ret) { - g_set_error (error, TP_ERRORS, TP_ERROR_NETWORK_ERROR, + g_set_error (error, TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property change request to server: %s", e->message); g_error_free (e); } @@ -1793,12 +1790,14 @@ refresh_invitations (GabbleConnection *conn, if (invitees != NULL && tp_handle_set_size (invitees) > 0) { - TpIntSetIter iter = TP_INTSET_ITER_INIT (tp_handle_set_peek - (invitees)); + TpIntsetFastIter iter; + guint element; + + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (invitees)); - while (tp_intset_iter_next (&iter)) + while (tp_intset_fast_iter_next (&iter, &element)) { - const gchar *to = tp_handle_inspect (contact_repo, iter.element); + const gchar *to = tp_handle_inspect (contact_repo, element); WockyStanza *msg = wocky_stanza_build ( WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, NULL, to, NULL); @@ -1853,7 +1852,7 @@ olpc_activity_properties_set_properties (GabbleSvcOLPCActivityProperties *iface, if (!activity_in_own_set (conn, jid)) { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Can't set properties on an activity if you're not announcing it" }; dbus_g_method_return_error (context, &error); @@ -1870,7 +1869,7 @@ olpc_activity_properties_set_properties (GabbleSvcOLPCActivityProperties *iface, } if (muc_channel == NULL || state != MUC_STATE_JOINED) { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Can't set properties on an activity if you're not in it" }; dbus_g_method_return_error (context, &error); @@ -1898,7 +1897,7 @@ olpc_activity_properties_set_properties (GabbleSvcOLPCActivityProperties *iface, wocky_stanza_get_top_node (msg), FALSE); if (!_gabble_connection_send (conn, msg, NULL)) { - GError error = { TP_ERRORS, TP_ERROR_NETWORK_ERROR, + GError error = { TP_ERROR, TP_ERROR_NETWORK_ERROR, "Failed to send property change notification to chatroom" }; g_object_unref (msg); @@ -2093,8 +2092,6 @@ update_activity_properties (GabbleConnection *conn, } } - tp_handle_unref (room_repo, room_handle); - if (activity == NULL) return; @@ -2177,11 +2174,9 @@ olpc_act_props_pep_node_changed (WockyPepService *pep, if (handle == base->self_handle) /* Ignore echoed pubsub notifications */ - goto out; + return; update_activities_properties (conn, jid, stanza); -out: - tp_handle_unref (contact_repo, handle); } static void @@ -2364,7 +2359,6 @@ conn_olpc_process_activity_properties_message (GabbleConnection *conn, g_object_ref (activity); tp_handle_set_add (their_invites, room_handle); } - tp_handle_unref (room_repo, room_handle); } else { @@ -2496,13 +2490,15 @@ revoke_invitations (GabbleConnection *conn, if (invitees != NULL && tp_handle_set_size (invitees) > 0) { - TpIntSetIter iter = TP_INTSET_ITER_INIT (tp_handle_set_peek - (invitees)); + TpIntsetFastIter iter; + guint element; + + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (invitees)); DEBUG ("revoke invitations for activity %s", activity->id); - while (tp_intset_iter_next (&iter)) + while (tp_intset_fast_iter_next (&iter, &element)) { - const gchar *to = tp_handle_inspect (contact_repo, iter.element); + const gchar *to = tp_handle_inspect (contact_repo, element); WockyStanza *msg = wocky_stanza_build ( WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, NULL, to, @@ -2631,6 +2627,10 @@ muc_channel_closed_cb (GabbleMucChannel *chan, TpHandleSet *my_activities; gboolean was_in_our_pep = FALSE; + /* is the muc channel /actually/ disappearing */ + if (!tp_base_channel_is_destroyed (TP_BASE_CHANNEL (chan))) + return; + g_object_get (activity, "connection", &conn, NULL); /* Revoke invitations we sent for this activity */ @@ -2723,7 +2723,6 @@ muc_channel_pre_invite_cb (GabbleMucChannel *chan, } tp_handle_set_add (invitees, handle); - tp_handle_unref (contact_repo, handle); g_object_unref (conn); } @@ -3046,7 +3045,7 @@ olpc_activity_properties_get_activity (GabbleSvcOLPCActivityProperties *iface, activity = find_activity_by_id (self, activity_id); if (activity == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Activity unknown: %s", activity_id); goto error; } diff --git a/src/conn-presence.c b/src/conn-presence.c index 9dfd6b6b1..6599b92a6 100644 --- a/src/conn-presence.c +++ b/src/conn-presence.c @@ -24,11 +24,8 @@ #include <string.h> #include <stdlib.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/presence-mixin.h> -#include <telepathy-glib/svc-connection.h> -#include <telepathy-glib/util.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> @@ -1100,7 +1097,7 @@ get_existing_privacy_lists_cb (GabbleConnection *conn, else if (query_node == NULL) { g_simple_async_result_set_error (result, - TP_ERRORS, TP_ERROR_NETWORK_ERROR, + TP_ERROR, TP_ERROR_NETWORK_ERROR, "no <query/> node in 'list privacy lists' reply"); } else @@ -1764,7 +1761,7 @@ set_own_status_cb (GObject *obj, * with the check enabled). Assumes PresenceId value ordering. */ if (i < GABBLE_PRESENCE_HIDDEN) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Status '%s' can not be requested in this connection", gabble_statuses[i].name); retval = FALSE; @@ -1782,7 +1779,7 @@ set_own_status_cb (GObject *obj, if (!G_VALUE_HOLDS_STRING (message)) { DEBUG ("got a status message which was not a string"); - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Status argument 'message' requires a string"); retval = FALSE; goto OUT; @@ -1795,7 +1792,7 @@ set_own_status_cb (GObject *obj, if (!G_VALUE_HOLDS_INT (priority)) { DEBUG ("got a priority value which was not a signed integer"); - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Status argument 'priority' requires a signed integer"); retval = FALSE; goto OUT; diff --git a/src/conn-sidecars.c b/src/conn-sidecars.c index eb47bad0a..496a2dfa8 100644 --- a/src/conn-sidecars.c +++ b/src/conn-sidecars.c @@ -22,7 +22,7 @@ #include "conn-sidecars.h" -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> #include "extensions/extensions.h" @@ -157,7 +157,7 @@ create_sidecar_cb ( { /* TODO: maybe this lives in the loader? It knows what the plugin is * called. */ - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "A buggy plugin created a %s sidecar when asked to create %s", actual_iface, ctx->sidecar_iface); } @@ -210,7 +210,7 @@ gabble_connection_ensure_sidecar ( if (base_conn->status == TP_CONNECTION_STATUS_DISCONNECTED) { - GError e = { TP_ERRORS, TP_ERROR_DISCONNECTED, + GError e = { TP_ERROR, TP_ERROR_DISCONNECTED, "This connection has already disconnected" }; DEBUG ("already disconnected, declining request for %s", sidecar_iface); @@ -220,7 +220,7 @@ gabble_connection_ensure_sidecar ( if (!tp_dbus_check_valid_interface_name (sidecar_iface, &error)) { - error->domain = TP_ERRORS; + error->domain = TP_ERROR; error->code = TP_ERROR_INVALID_ARGUMENT; DEBUG ("%s is malformed: %s", sidecar_iface, error->message); dbus_g_method_return_error (context, error); @@ -305,7 +305,7 @@ sidecars_conn_status_changed_cb ( { const gchar *sidecar_iface = key; GList *contexts = value; - GError *error = g_error_new (TP_ERRORS, TP_ERROR_CANCELLED, + GError *error = g_error_new (TP_ERROR, TP_ERROR_CANCELLED, "Disconnected before %s could be created", sidecar_iface); DEBUG ("failing all %u requests for %s", g_list_length (contexts), diff --git a/src/connection-manager.c b/src/connection-manager.c index b2a0edb15..4031d49ae 100644 --- a/src/connection-manager.c +++ b/src/connection-manager.c @@ -25,8 +25,10 @@ #include <dbus/dbus-protocol.h> #include <dbus/dbus-glib.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/errors.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> + #include <wocky/wocky.h> #include "connection.h" diff --git a/src/connection-manager.h b/src/connection-manager.h index 775bba79b..fc269e8d8 100644 --- a/src/connection-manager.h +++ b/src/connection-manager.h @@ -22,7 +22,7 @@ #define __GABBLE_CONNECTION_MANAGER_H__ #include <glib-object.h> -#include <telepathy-glib/base-connection-manager.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/connection.c b/src/connection.c index 5ea0d1a67..e6c8a866b 100644 --- a/src/connection.c +++ b/src/connection.c @@ -30,14 +30,8 @@ #include <dbus/dbus-glib-lowlevel.h> #include <glib-object.h> #include <wocky/wocky.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/handle-repo-dynamic.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-generic.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "extensions/extensions.h" @@ -332,7 +326,7 @@ _gabble_connection_create_channel_managers (TpBaseConnection *conn) { GabbleConnection *self = GABBLE_CONNECTION (conn); GabblePluginConnection *plugin_connection = GABBLE_PLUGIN_CONNECTION (self); - GPtrArray *channel_managers = g_ptr_array_sized_new (5); + GPtrArray *channel_managers = g_ptr_array_sized_new (10); GabblePluginLoader *loader; GPtrArray *tmp; @@ -1398,7 +1392,7 @@ _gabble_connection_set_properties_from_account (GabbleConnection *conn, if (!wocky_decode_jid (account, &username, &server, &resource)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "unable to extract JID from account name"); result = FALSE; goto OUT; @@ -1484,7 +1478,7 @@ _gabble_connection_send (GabbleConnection *conn, WockyStanza *msg, GError **erro if (conn->priv->porter == NULL) { - g_set_error_literal (error, TP_ERRORS, TP_ERROR_NETWORK_ERROR, + g_set_error_literal (error, TP_ERROR, TP_ERROR_NETWORK_ERROR, "connection is disconnected"); return FALSE; } @@ -1600,7 +1594,7 @@ _gabble_connection_send_with_reply (GabbleConnection *conn, if (priv->porter == NULL) { - g_set_error_literal (error, TP_ERRORS, TP_ERROR_NETWORK_ERROR, + g_set_error_literal (error, TP_ERROR, TP_ERROR_NETWORK_ERROR, "connection is disconnected"); return FALSE; } @@ -1647,7 +1641,7 @@ gabble_connection_disconnect_with_tp_error (GabbleConnection *self, "debug-message", G_TYPE_STRING, tp_error->message, NULL); - g_assert (tp_error->domain == TP_ERRORS); + g_assert (tp_error->domain == TP_ERROR); tp_base_connection_disconnect_with_dbus_error (base, tp_error_get_dbus_name (tp_error->code), details, reason); g_hash_table_unref (details); @@ -1658,7 +1652,7 @@ remote_closed_cb (WockyPorter *porter, GabbleConnection *self) { TpBaseConnection *base = TP_BASE_CONNECTION (self); - GError e = { TP_ERRORS, TP_ERROR_CONNECTION_LOST, + GError e = { TP_ERROR, TP_ERROR_CONNECTION_LOST, "server closed its XMPP stream" }; if (base->status == TP_CONNECTION_STATUS_DISCONNECTED) @@ -1713,7 +1707,7 @@ remote_error_cb (WockyPorter *porter, return; gabble_set_tp_conn_error_from_wocky (&e, base->status, &reason, &error); - g_assert (error->domain == TP_ERRORS); + g_assert (error->domain == TP_ERROR); DEBUG ("Force closing of the connection %p", self); priv->closing = TRUE; @@ -1770,7 +1764,7 @@ connector_error_disconnect (GabbleConnection *self, gabble_set_tp_conn_error_from_wocky (error, base->status, &reason, &tp_error); DEBUG ("connection failed: %s", tp_error->message); - g_assert (tp_error->domain == TP_ERRORS); + g_assert (tp_error->domain == TP_ERROR); gabble_connection_disconnect_with_tp_error (self, tp_error, reason); g_error_free (tp_error); @@ -1962,9 +1956,9 @@ connector_connected (GabbleConnection *self, { DEBUG ("couldn't get our self handle: %s", error->message); - if (error->domain != TP_ERRORS) + if (error->domain != TP_ERROR) { - error->domain = TP_ERRORS; + error->domain = TP_ERROR; error->code = TP_ERROR_INVALID_HANDLE; } @@ -1980,9 +1974,9 @@ connector_connected (GabbleConnection *self, { DEBUG ("couldn't parse our own JID: %s", error->message); - if (error->domain != TP_ERRORS) + if (error->domain != TP_ERROR) { - error->domain = TP_ERRORS; + error->domain = TP_ERROR; error->code = TP_ERROR_INVALID_ARGUMENT; } @@ -2008,9 +2002,9 @@ connector_connected (GabbleConnection *self, DEBUG ("sending disco request failed: %s", error->message); - if (error->domain != TP_ERRORS) + if (error->domain != TP_ERROR) { - error->domain = TP_ERRORS; + error->domain = TP_ERROR; error->code = TP_ERROR_NETWORK_ERROR; } @@ -2027,9 +2021,9 @@ connector_connected (GabbleConnection *self, DEBUG ("Sending disco request to our own bare jid failed: %s", error->message); - if (error->domain != TP_ERRORS) + if (error->domain != TP_ERROR) { - error->domain = TP_ERRORS; + error->domain = TP_ERROR; error->code = TP_ERROR_NETWORK_ERROR; } @@ -2827,6 +2821,115 @@ decrement_waiting_connected (GabbleConnection *conn) } static void +conn_wlm_jid_lookup_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GabbleConnection *conn = (GabbleConnection *) source; + GSimpleAsyncResult *my_result = user_data; + WockyStanza *iq = NULL; + WockyNode *node; + const gchar *jid = NULL; + GError *error = NULL; + + if (!conn_util_send_iq_finish (conn, result, &iq, &error)) + { + g_simple_async_result_take_error (my_result, error); + goto out; + } + + node = wocky_node_get_child_ns (wocky_stanza_get_top_node (iq), + "getjid", NS_WLM_JID_LOOKUP); + + if (node != NULL) + { + jid = wocky_node_get_content_from_child (node, "jid"); + } + + if (!tp_str_empty (jid)) + { + g_simple_async_result_set_op_res_gpointer (my_result, + g_strdup (jid), g_free); + } + else + { + g_simple_async_result_set_error (my_result, + TP_ERROR, TP_ERROR_INVALID_HANDLE, + "jid not found in getjid reply"); + } + +out: + g_simple_async_result_complete (my_result); + g_object_unref (my_result); +} + +static void +conn_wlm_jid_lookup_async (TpHandleRepoIface *repo, + TpBaseConnection *base, + const gchar *id, + gpointer context, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GabbleConnection *self = GABBLE_CONNECTION (base); + WockyStanza *iq; + GSimpleAsyncResult *result; + gchar *normal_id; + GError *error = NULL; + + result = g_simple_async_result_new ((GObject *) repo, callback, user_data, + conn_wlm_jid_lookup_async); + + /* First, do local normalization */ + normal_id = gabble_normalize_contact (repo, id, context, &error); + if (normal_id == NULL) + { + g_simple_async_result_take_error (result, error); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); + return; + } + + /* If it is already a WLM jid, return it */ + if (g_str_has_suffix (normal_id, "@messenger.live.com")) + { + g_simple_async_result_set_op_res_gpointer (result, normal_id, g_free); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); + return; + } + + /* Ask the server to give a WLM jid */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + conn_util_get_bare_self_jid (self), normal_id, + '(', "getjid", + ':', NS_WLM_JID_LOOKUP, + ')', + NULL); + + conn_util_send_iq_async (self, iq, NULL, conn_wlm_jid_lookup_cb, result); + + g_object_unref (iq); + g_free (normal_id); +} + +static gchar * +conn_wlm_jid_lookup_finish (TpHandleRepoIface *repo, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple = (GSimpleAsyncResult *) result; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (repo), conn_wlm_jid_lookup_async), NULL); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + return g_strdup (g_simple_async_result_get_op_res_gpointer (simple)); +} + +static void connection_disco_cb (GabbleDisco *disco, GabbleDiscoRequest *request, const gchar *jid, @@ -2903,12 +3006,25 @@ connection_disco_cb (GabbleDisco *disco, conn->features |= GABBLE_CONNECTION_FEATURES_GOOGLE_QUEUE; else if (0 == strcmp (var, NS_GOOGLE_SETTING)) conn->features |= GABBLE_CONNECTION_FEATURES_GOOGLE_SETTING; + else if (0 == strcmp (var, NS_WLM_JID_LOOKUP)) + conn->features |= GABBLE_CONNECTION_FEATURES_WLM_JID_LOOKUP; } } DEBUG ("set features flags to %d", conn->features); } + if ((conn->features & GABBLE_CONNECTION_FEATURES_WLM_JID_LOOKUP) != 0) + { + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base, + TP_HANDLE_TYPE_CONTACT); + + tp_dynamic_handle_repo_set_normalize_async ( + (TpDynamicHandleRepo *) contact_repo, + conn_wlm_jid_lookup_async, + conn_wlm_jid_lookup_finish); + } + conn_presence_set_initial_presence_async (conn, connection_initial_presence_cb, NULL); diff --git a/src/connection.h b/src/connection.h index 50734b777..f648ef440 100644 --- a/src/connection.h +++ b/src/connection.h @@ -25,11 +25,7 @@ #include <dbus/dbus-glib.h> #include <glib-object.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/contacts-mixin.h> -#include <telepathy-glib/presence-mixin.h> -#include <telepathy-glib/dbus-properties-mixin.h> -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> #include <wocky/wocky.h> @@ -143,6 +139,7 @@ typedef enum GABBLE_CONNECTION_FEATURES_GOOGLE_SHARED_STATUS = 1 << 7, GABBLE_CONNECTION_FEATURES_GOOGLE_QUEUE = 1 << 8, GABBLE_CONNECTION_FEATURES_GOOGLE_SETTING = 1 << 9, + GABBLE_CONNECTION_FEATURES_WLM_JID_LOOKUP = 1 << 10, } GabbleConnectionFeatures; typedef struct _GabbleConnectionPrivate GabbleConnectionPrivate; diff --git a/src/debug.c b/src/debug.c index a7616f712..8e3dd0c50 100644 --- a/src/debug.c +++ b/src/debug.c @@ -16,8 +16,8 @@ #include <errno.h> #include <glib/gstdio.h> -#include <telepathy-glib/debug.h> -#include <telepathy-glib/debug-sender.h> + +#include <telepathy-glib/telepathy-glib.h> static GabbleDebugFlags flags = 0; diff --git a/src/disco.c b/src/disco.c index 6f142a4e1..20726dd31 100644 --- a/src/disco.c +++ b/src/disco.c @@ -28,7 +28,7 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_DISCO diff --git a/src/error.c b/src/error.c index e79ddef32..ad3bf7b14 100644 --- a/src/error.c +++ b/src/error.c @@ -344,7 +344,7 @@ gabble_set_tp_conn_error_from_wocky (const GError *wocky_error, klass = g_type_class_ref (WOCKY_TYPE_XMPP_ERROR); name = get_error_prefix (klass, wocky_error->code, "unknown WockyXmppError code"); - g_set_error (error, TP_ERRORS, + g_set_error (error, TP_ERROR, map_wocky_xmpp_error (wocky_error, conn_reason), "%s (#%d): %s", name, wocky_error->code, wocky_error->message); g_type_class_unref (klass); @@ -356,7 +356,7 @@ gabble_set_tp_conn_error_from_wocky (const GError *wocky_error, "unknown GIOError code"); /* FIXME: is it safe to assume that every GIOError we encounter from * Wocky is a NetworkError? */ - g_set_error (error, TP_ERRORS, TP_ERROR_NETWORK_ERROR, + g_set_error (error, TP_ERROR, TP_ERROR_NETWORK_ERROR, "%s (#%d): %s", name, wocky_error->code, wocky_error->message); g_type_class_unref (klass); @@ -368,7 +368,7 @@ gabble_set_tp_conn_error_from_wocky (const GError *wocky_error, klass = g_type_class_ref (WOCKY_TYPE_AUTH_ERROR); name = get_error_prefix (klass, wocky_error->code, "unknown WockyAuthError code"); - g_set_error (error, TP_ERRORS, + g_set_error (error, TP_ERROR, map_wocky_auth_error (wocky_error, conn_reason), "%s (#%d): %s", name, wocky_error->code, wocky_error->message); g_type_class_unref (klass); @@ -378,7 +378,7 @@ gabble_set_tp_conn_error_from_wocky (const GError *wocky_error, klass = g_type_class_ref (WOCKY_TYPE_CONNECTOR_ERROR); name = get_error_prefix (klass, wocky_error->code, "unknown WockyConnectorError code"); - g_set_error (error, TP_ERRORS, + g_set_error (error, TP_ERROR, map_wocky_connector_error (wocky_error, conn_reason), "%s (#%d): %s", name, wocky_error->code, wocky_error->message); g_type_class_unref (klass); @@ -388,7 +388,7 @@ gabble_set_tp_conn_error_from_wocky (const GError *wocky_error, klass = g_type_class_ref (WOCKY_TYPE_XMPP_STREAM_ERROR); name = get_error_prefix (klass, wocky_error->code, "unknown WockyXmppStreamError code"); - g_set_error (error, TP_ERRORS, + g_set_error (error, TP_ERROR, map_wocky_stream_error (wocky_error, previous_status, conn_reason), "%s (#%d): %s", name, wocky_error->code, wocky_error->message); g_type_class_unref (klass); @@ -398,7 +398,7 @@ gabble_set_tp_conn_error_from_wocky (const GError *wocky_error, klass = g_type_class_ref (WOCKY_TYPE_TLS_CERT_STATUS); name = get_error_prefix (klass, wocky_error->code, "unknown WockyTLSCertStatus code"); - g_set_error (error, TP_ERRORS, + g_set_error (error, TP_ERROR, map_wocky_tls_cert_error (wocky_error, conn_reason), "%s (#%d): %s", name, wocky_error->code, wocky_error->message); g_type_class_unref (klass); @@ -406,14 +406,14 @@ gabble_set_tp_conn_error_from_wocky (const GError *wocky_error, else if (wocky_error->domain == WOCKY_XMPP_CONNECTION_ERROR) { /* FIXME: there's no GEnum for WockyXmppConnectionError. */ - g_set_error_literal (error, TP_ERRORS, + g_set_error_literal (error, TP_ERROR, map_connection_error (wocky_error), wocky_error->message); } else { /* best we can do... */ - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "%s (#%d): %s", g_quark_to_string (wocky_error->domain), wocky_error->code, wocky_error->message); } diff --git a/src/ft-channel.c b/src/ft-channel.c index 57b891205..bfabae6d7 100644 --- a/src/ft-channel.c +++ b/src/ft-channel.c @@ -48,14 +48,8 @@ #include "presence-cache.h" #include "util.h" -#include <telepathy-glib/base-channel.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/svc-channel.h> - +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> static void file_transfer_iface_init (gpointer g_iface, gpointer iface_data); static void transferred_chunk (GabbleFileTransferChannel *self, guint64 count); @@ -481,21 +475,21 @@ file_transfer_channel_properties_setter (GObject *object, if (self->priv->uri != NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "URI has already be set"); return FALSE; } if (tp_base_channel_is_requested (base)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Channel is not an incoming transfer"); return FALSE; } if (self->priv->state != TP_FILE_TRANSFER_STATE_PENDING) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "State is not pending; cannot set URI"); return FALSE; } @@ -931,7 +925,7 @@ check_address_and_access_control (GabbleFileTransferChannel *self, GUINT_TO_POINTER (address_type)); if (access_arr == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "AddressType %u is not implemented", address_type); return FALSE; } @@ -946,7 +940,7 @@ check_address_and_access_control (GabbleFileTransferChannel *self, return TRUE; } - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "AccesControl %u is not implemented with AddressType %u", access_control, address_type); @@ -1410,7 +1404,7 @@ gabble_file_transfer_channel_offer_file (GabbleFileTransferChannel *self, if (presence == NULL) { DEBUG ("can't find contact's presence"); - g_set_error (error, TP_ERRORS, TP_ERROR_OFFLINE, + g_set_error (error, TP_ERROR, TP_ERROR_OFFLINE, "can't find contact's presence"); return FALSE; @@ -1422,7 +1416,7 @@ gabble_file_transfer_channel_offer_file (GabbleFileTransferChannel *self, { DEBUG ("trying to use Metadata properties on a contact " "who doesn't support it"); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_CAPABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE, "The specified contact does not support the " "Metadata extension; you should ensure both ServiceName and " "Metadata properties are not present in the channel " @@ -1490,7 +1484,7 @@ gabble_file_transfer_channel_offer_file (GabbleFileTransferChannel *self, else { DEBUG ("contact doesn't have file transfer capabilities"); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_CAPABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE, "contact doesn't have file transfer capabilities"); result = FALSE; } @@ -1698,7 +1692,7 @@ gabble_file_transfer_channel_accept_file (TpSvcChannelTypeFileTransfer *iface, if (tp_base_channel_is_requested (base)) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Channel is not an incoming transfer"); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1707,7 +1701,7 @@ gabble_file_transfer_channel_accept_file (TpSvcChannelTypeFileTransfer *iface, if (self->priv->state != TP_FILE_TRANSFER_STATE_PENDING) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "State is not pending; cannot accept file"); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1726,7 +1720,7 @@ gabble_file_transfer_channel_accept_file (TpSvcChannelTypeFileTransfer *iface, access_control_param)) { DEBUG ("Could not set up local socket"); - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Could not set up local socket"); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1798,7 +1792,7 @@ gabble_file_transfer_channel_provide_file ( if (!tp_base_channel_is_requested (TP_BASE_CHANNEL (self))) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Channel is not an outgoing transfer"); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1808,7 +1802,7 @@ gabble_file_transfer_channel_provide_file ( if (self->priv->state != TP_FILE_TRANSFER_STATE_PENDING && self->priv->state != TP_FILE_TRANSFER_STATE_ACCEPTED) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "State is not pending or accepted; cannot provide file"); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1817,7 +1811,7 @@ gabble_file_transfer_channel_provide_file ( if (self->priv->socket_address != NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "ProvideFile has already been called for this channel"); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1836,7 +1830,7 @@ gabble_file_transfer_channel_provide_file ( access_control_param)) { DEBUG ("Could not set up local socket"); - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Could not set up local socket"); dbus_g_method_return_error (context, error); g_error_free (error); diff --git a/src/ft-channel.h b/src/ft-channel.h index 323c1e651..87943646b 100644 --- a/src/ft-channel.h +++ b/src/ft-channel.h @@ -26,7 +26,7 @@ #include <glib-object.h> #include <extensions/extensions.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> typedef struct _GabbleFileTransferChannel GabbleFileTransferChannel; diff --git a/src/ft-manager.c b/src/ft-manager.c index a6bb13090..068e1cdb4 100644 --- a/src/ft-manager.c +++ b/src/ft-manager.c @@ -45,14 +45,8 @@ #include <wocky/wocky.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/base-channel.h> -#include <telepathy-glib/channel-factory-iface.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_FT #include "debug.h" @@ -493,7 +487,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager, /* Don't support opening a channel to our self handle */ if (handle == base_connection->self_handle) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Can't open a file transfer channel to yourself"); goto error; } @@ -502,7 +496,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".ContentType"); if (content_type == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "ContentType property is mandatory"); goto error; } @@ -511,7 +505,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".Filename"); if (filename == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Filename property is mandatory"); goto error; } @@ -520,7 +514,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".Size", NULL); if (size == 0) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Size property is mandatory"); goto error; } @@ -536,7 +530,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager, { if (content_hash_type >= NUM_TP_FILE_HASH_TYPES) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%u is not a valid ContentHashType", content_hash_type); goto error; } @@ -548,7 +542,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".ContentHash"); if (content_hash == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "ContentHash property is mandatory if ContentHashType is " "not None"); goto error; @@ -580,7 +574,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager, if (metadata != NULL && g_hash_table_lookup ((GHashTable *) metadata, "FORM_TYPE")) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Metadata cannot contain an item with key 'FORM_TYPE'"); goto error; } diff --git a/src/gabble.c b/src/gabble.c index 0d2fb6e29..f6bbf2c39 100644 --- a/src/gabble.c +++ b/src/gabble.c @@ -27,11 +27,8 @@ #include <glib/gstdio.h> -#include <telepathy-glib/debug.h> -#include <telepathy-glib/debug-sender.h> -#include <telepathy-glib/run.h> -#include <telepathy-glib/util.h> -#include <wocky/wocky.h> +#include <telepathy-glib/telepathy-glib.h> + #include <wocky/wocky.h> #include "debug.h" diff --git a/src/im-channel.c b/src/im-channel.c index d294c3a04..fd9f812c0 100644 --- a/src/im-channel.c +++ b/src/im-channel.c @@ -24,14 +24,9 @@ #include <string.h> #include <dbus/dbus-glib.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-iface.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-generic.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_IM #include "connection.h" @@ -44,7 +39,6 @@ #include "roster.h" #include "util.h" -static void chat_state_iface_init (gpointer, gpointer); static void destroyable_iface_init (gpointer, gpointer); G_DEFINE_TYPE_WITH_CODE (GabbleIMChannel, gabble_im_channel, @@ -54,13 +48,16 @@ G_DEFINE_TYPE_WITH_CODE (GabbleIMChannel, gabble_im_channel, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MESSAGES, tp_message_mixin_messages_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CHAT_STATE, - chat_state_iface_init); + tp_message_mixin_chat_state_iface_init) G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DESTROYABLE, destroyable_iface_init)); static void _gabble_im_channel_send_message (GObject *object, TpMessage *message, TpMessageSendingFlags flags); static void gabble_im_channel_close (TpBaseChannel *base_chan); +static gboolean _gabble_im_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error); static const gchar *gabble_im_channel_interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_CHAT_STATE, @@ -84,13 +81,6 @@ struct _GabbleIMChannelPrivate gboolean send_nick; ChatStateSupport chat_states_supported; - /* FALSE unless at least one chat state notification has been sent; <gone/> - * will only be sent when the channel closes if this is TRUE. This prevents - * opening a channel and closing it immediately sending a spurious <gone/> to - * the peer. - */ - gboolean send_gone; - gboolean dispose_has_run; }; @@ -143,8 +133,6 @@ gabble_im_channel_constructed (GObject *obj) else priv->send_nick = TRUE; - priv->chat_states_supported = CHAT_STATES_UNKNOWN; - tp_message_mixin_init (obj, G_STRUCT_OFFSET (GabbleIMChannel, message_mixin), base_conn); @@ -152,6 +140,10 @@ gabble_im_channel_constructed (GObject *obj) G_N_ELEMENTS (types), types, 0, TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_FAILURES, supported_content_types); + + priv->chat_states_supported = CHAT_STATES_UNKNOWN; + tp_message_mixin_implement_send_chat_state (obj, + _gabble_im_channel_send_chat_state); } static void gabble_im_channel_dispose (GObject *object); @@ -238,24 +230,6 @@ chat_states_supported (GabbleIMChannel *self, } static void -im_channel_send_gone (GabbleIMChannel *self) -{ - GabbleIMChannelPrivate *priv = self->priv; - TpBaseChannel *base = (TpBaseChannel *) self; - - if (priv->send_gone) - { - if (chat_states_supported (self, FALSE)) - gabble_message_util_send_chat_state (G_OBJECT (self), - GABBLE_CONNECTION (tp_base_channel_get_connection (base)), - WOCKY_STANZA_SUB_TYPE_CHAT, TP_CHANNEL_CHAT_STATE_GONE, - priv->peer_jid, NULL); - - priv->send_gone = FALSE; - } -} - -static void gabble_im_channel_dispose (GObject *object) { GabbleIMChannel *self = GABBLE_IM_CHANNEL (object); @@ -282,7 +256,7 @@ gabble_im_channel_dispose (GObject *object) } } - im_channel_send_gone (self); + tp_message_mixin_maybe_send_gone (object); if (G_OBJECT_CLASS (gabble_im_channel_parent_class)->dispose) G_OBJECT_CLASS (gabble_im_channel_parent_class)->dispose (object); @@ -340,9 +314,10 @@ _gabble_im_channel_send_message (GObject *object, { GabbleIMChannel *self = GABBLE_IM_CHANNEL (object); TpBaseChannel *base = (TpBaseChannel *) self; + TpBaseConnection *base_conn; GabbleConnection *gabble_conn; GabbleIMChannelPrivate *priv; - gint state = -1; + TpChannelChatState state = -1; WockyStanza *stanza = NULL; gchar *id = NULL; GError *error = NULL; @@ -352,16 +327,18 @@ _gabble_im_channel_send_message (GObject *object, g_assert (GABBLE_IS_IM_CHANNEL (self)); priv = self->priv; + base_conn = tp_base_channel_get_connection (base); + gabble_conn = GABBLE_CONNECTION (base_conn); + if (chat_states_supported (self, TRUE)) { state = TP_CHANNEL_CHAT_STATE_ACTIVE; - priv->send_gone = TRUE; + tp_message_mixin_change_chat_state (object, + base_conn->self_handle, state); } /* We don't support providing successful delivery reports. */ flags = 0; - gabble_conn = - GABBLE_CONNECTION (tp_base_channel_get_connection (base)); stanza = gabble_message_util_build_stanza (message, gabble_conn, 0, state, priv->peer_jid, @@ -555,15 +532,13 @@ _gabble_im_channel_state_receive (GabbleIMChannel *chan, GabbleIMChannelPrivate *priv; TpBaseChannel *base_chan; - g_assert (state < NUM_TP_CHANNEL_CHAT_STATES); g_assert (GABBLE_IS_IM_CHANNEL (chan)); base_chan = (TpBaseChannel *) chan; priv = chan->priv; priv->chat_states_supported = CHAT_STATES_SUPPORTED; - tp_svc_channel_interface_chat_state_emit_chat_state_changed ( - (TpSvcChannelInterfaceChatState *) chan, + tp_message_mixin_change_chat_state ((GObject *) chan, tp_base_channel_get_target_handle (base_chan), state); } @@ -572,7 +547,7 @@ gabble_im_channel_close (TpBaseChannel *base_chan) { GabbleIMChannel *self = GABBLE_IM_CHANNEL (base_chan); - im_channel_send_gone (self); + tp_message_mixin_maybe_send_gone ((GObject *) self); /* The IM factory will resurrect the channel if we have pending * messages. When we're resurrected, we want the initiator @@ -610,76 +585,24 @@ gabble_im_channel_destroy (TpSvcChannelInterfaceDestroyable *iface, tp_svc_channel_interface_destroyable_return_from_destroy (context); } - -/** - * gabble_im_channel_set_chat_state - * - * Implements D-Bus method SetChatState - * on interface org.freedesktop.Telepathy.Channel.Interface.ChatState - */ -static void -gabble_im_channel_set_chat_state (TpSvcChannelInterfaceChatState *iface, - guint state, - DBusGMethodInvocation *context) +static gboolean +_gabble_im_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error) { - GabbleIMChannel *self = GABBLE_IM_CHANNEL (iface); + GabbleIMChannel *self = GABBLE_IM_CHANNEL (object); + GabbleIMChannelPrivate *priv = self->priv; TpBaseChannel *base = (TpBaseChannel *) self; - GabbleIMChannelPrivate *priv; - GError *error = NULL; - - g_assert (GABBLE_IS_IM_CHANNEL (self)); - priv = self->priv; + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); - if (state >= NUM_TP_CHANNEL_CHAT_STATES) - { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "invalid state: %u", state); - } - else if (state == TP_CHANNEL_CHAT_STATE_GONE) - { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "you may not explicitly set the Gone state"); - } /* Only send anything to the peer if we actually know they support chat - * states. - */ - else if (chat_states_supported (self, FALSE)) - { - TpBaseConnection *base_conn = tp_base_channel_get_connection (base); - - if (gabble_message_util_send_chat_state (G_OBJECT (self), - GABBLE_CONNECTION (base_conn), - WOCKY_STANZA_SUB_TYPE_CHAT, state, priv->peer_jid, &error)) - { - priv->send_gone = TRUE; - - /* Send the ChatStateChanged signal for the local user */ - tp_svc_channel_interface_chat_state_emit_chat_state_changed (iface, - base_conn->self_handle, state); - } - } - - if (error != NULL) - { - DEBUG ("%s", error->message); - dbus_g_method_return_error (context, error); - g_error_free (error); - } - else - { - tp_svc_channel_interface_chat_state_return_from_set_chat_state (context); - } -} + * states. */ + if (!chat_states_supported (self, FALSE)) + return TRUE; -static void -chat_state_iface_init (gpointer g_iface, gpointer iface_data) -{ - TpSvcChannelInterfaceChatStateClass *klass = - (TpSvcChannelInterfaceChatStateClass *) g_iface; -#define IMPLEMENT(x) tp_svc_channel_interface_chat_state_implement_##x (\ - klass, gabble_im_channel_##x) - IMPLEMENT(set_chat_state); -#undef IMPLEMENT + return gabble_message_util_send_chat_state (G_OBJECT (self), + GABBLE_CONNECTION (base_conn), + WOCKY_STANZA_SUB_TYPE_CHAT, state, priv->peer_jid, error); } static void diff --git a/src/im-channel.h b/src/im-channel.h index fdbae19bf..076565ef5 100644 --- a/src/im-channel.h +++ b/src/im-channel.h @@ -24,9 +24,7 @@ #include <glib-object.h> #include <time.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/message-mixin.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/im-factory.c b/src/im-factory.c index 0459c2dc0..831e4aab2 100644 --- a/src/im-factory.c +++ b/src/im-factory.c @@ -24,10 +24,8 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> #define DEBUG_FLAG GABBLE_DEBUG_IM @@ -281,35 +279,39 @@ im_channel_closed_cb (GabbleIMChannel *chan, gpointer user_data) { GabbleImFactory *self = GABBLE_IM_FACTORY (user_data); GabbleImFactoryPrivate *priv = self->priv; - TpHandle contact_handle; - gboolean really_destroyed; + TpBaseChannel *base = TP_BASE_CHANNEL (chan); + TpHandle contact_handle = tp_base_channel_get_target_handle (base); DEBUG ("%p, channel %p", self, chan); - tp_channel_manager_emit_channel_closed_for_object (self, - (TpExportableChannel *) chan); + if (tp_base_channel_is_registered (base)) + { + tp_channel_manager_emit_channel_closed_for_object (self, + (TpExportableChannel *) chan); + } if (priv->channels != NULL) { - g_object_get (chan, - "handle", &contact_handle, - "channel-destroyed", &really_destroyed, - NULL); - - if (really_destroyed) + if (tp_base_channel_is_destroyed (base)) { DEBUG ("removing channel with handle %u", contact_handle); g_hash_table_remove (priv->channels, GUINT_TO_POINTER (contact_handle)); } - else + else if (tp_base_channel_is_respawning (base)) { - DEBUG ("reopening channel with handle %u due to pending messages", contact_handle); tp_channel_manager_emit_new_channel (self, (TpExportableChannel *) chan, NULL); } + else + { + /* this basically means tp_base_channel_disappear() must + * have been called; this doesn't have any meaning in this + * channel manager. */ + g_assert_not_reached (); + } } } @@ -704,7 +706,7 @@ gabble_im_factory_requestotron (GabbleImFactory *self, if (require_new) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Already chatting with contact #%u in another channel", handle); goto error; } diff --git a/src/jingle-info.c b/src/jingle-info.c index 4048fa3b3..bd1f6865d 100644 --- a/src/jingle-info.c +++ b/src/jingle-info.c @@ -18,10 +18,11 @@ */ #include "config.h" + #include "jingle-info.h" #include <stdlib.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_MEDIA #include "debug.h" diff --git a/src/legacy-caps.c b/src/legacy-caps.c index 3f4ebde5c..827fc15ea 100644 --- a/src/legacy-caps.c +++ b/src/legacy-caps.c @@ -21,7 +21,7 @@ #include "config.h" #include "legacy-caps.h" -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE #include "debug.h" diff --git a/src/media-channel-hold.c b/src/media-channel-hold.c index bb4cb576c..ca8241c34 100644 --- a/src/media-channel-hold.c +++ b/src/media-channel-hold.c @@ -19,10 +19,11 @@ */ #include "config.h" + #include "media-channel.h" #include "media-channel-internal.h" -#include <telepathy-glib/channel-iface.h> +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_MEDIA diff --git a/src/media-channel-internal.h b/src/media-channel-internal.h index 9264eac8b..ff931b567 100644 --- a/src/media-channel-internal.h +++ b/src/media-channel-internal.h @@ -26,7 +26,7 @@ #include <glib.h> -#include <telepathy-glib/dtmf.h> +#include <telepathy-glib/telepathy-glib.h> #include "media-stream.h" #include "jingle-session.h" diff --git a/src/media-channel.c b/src/media-channel.c index 0721b2908..f2b3e523a 100644 --- a/src/media-channel.c +++ b/src/media-channel.c @@ -26,14 +26,8 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-iface.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-properties-interface.h> -#include <telepathy-glib/svc-media-interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_MEDIA @@ -329,7 +323,7 @@ gabble_media_channel_constructor (GType type, guint n_props, GabbleMediaChannelPrivate *priv; TpBaseConnection *conn; TpDBusDaemon *bus; - TpIntSet *set; + TpIntset *set; TpHandleRepoIface *contact_handles; GabbleJingleInfo *ji; const gchar *relay_token; @@ -366,7 +360,6 @@ gabble_media_channel_constructor (GType type, guint n_props, /* automatically add creator to channel, but also ref them again (because * priv->creator is the InitiatorHandle) */ g_assert (priv->creator != 0); - tp_handle_ref (contact_handles, priv->creator); set = tp_intset_new_containing (priv->creator); tp_group_mixin_change_members (obj, "", set, NULL, NULL, NULL, 0, @@ -666,15 +659,6 @@ gabble_media_channel_set_property (GObject *object, break; case PROP_INITIAL_PEER: priv->initial_peer = g_value_get_uint (value); - - if (priv->initial_peer != 0) - { - TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn; - TpHandleRepoIface *repo = tp_base_connection_get_handles (base_conn, - TP_HANDLE_TYPE_CONTACT); - tp_handle_ref (repo, priv->initial_peer); - } - break; case PROP_PEER_IN_RP: priv->peer_in_rp = g_value_get_boolean (value); @@ -952,9 +936,6 @@ gabble_media_channel_dispose (GObject *object) { GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (object); GabbleMediaChannelPrivate *priv = self->priv; - TpBaseConnection *conn = (TpBaseConnection *) priv->conn; - TpHandleRepoIface *contact_handles = tp_base_connection_get_handles ( - conn, TP_HANDLE_TYPE_CONTACT); GList *l; if (priv->dispose_has_run) @@ -990,15 +971,6 @@ gabble_media_channel_dispose (GObject *object) priv->delayed_request_streams = NULL; } - tp_handle_unref (contact_handles, priv->creator); - priv->creator = 0; - - if (priv->initial_peer != 0) - { - tp_handle_unref (contact_handles, priv->initial_peer); - priv->initial_peer = 0; - } - /* All of the streams should have closed in response to the contents being * removed when the call ended. */ @@ -1279,7 +1251,7 @@ _find_stream_by_id (GabbleMediaChannel *chan, return stream; } - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "given stream id %u does not exist", stream_id); return NULL; } @@ -1331,7 +1303,7 @@ gabble_media_channel_remove_streams (TpSvcChannelTypeStreamedMedia *iface, if (!gabble_jingle_session_can_modify_contents (priv->session)) { - GError e = { TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + GError e = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Streams can't be removed from Google Talk calls" }; dbus_g_method_return_error (context, &e); return; @@ -1426,7 +1398,7 @@ gabble_media_channel_request_stream_direction (TpSvcChannelTypeStreamedMedia *if if (stream_direction > TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "given stream direction %u is not valid", stream_direction); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1464,7 +1436,7 @@ gabble_media_channel_request_stream_direction (TpSvcChannelTypeStreamedMedia *if } else { - GError e = { TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + GError e = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Stream direction can't be set to None in Google Talk calls" }; DEBUG ("%s", e.message); dbus_g_method_return_error (context, &e); @@ -1570,7 +1542,7 @@ pending_stream_request_maybe_fail (PendingStreamRequest *p, { if (content == p->contents[i]) { - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "A stream was removed before it could be fully set up" }; /* return early */ @@ -1590,7 +1562,7 @@ pending_stream_request_free (gpointer data) if (p->context != NULL) { - GError e = { TP_ERRORS, TP_ERROR_CANCELLED, + GError e = { TP_ERROR, TP_ERROR_CANCELLED, "The session terminated before the requested streams could be added" }; @@ -1635,7 +1607,7 @@ _gabble_media_channel_request_contents (GabbleMediaChannel *chan, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "given media type %u is invalid", media_type); return FALSE; } @@ -1654,7 +1626,7 @@ _gabble_media_channel_request_contents (GabbleMediaChannel *chan, /* is a google call... we have no other option */ if (!gabble_jingle_session_can_modify_contents (priv->session)) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Streams can't be added to ongoing Google Talk calls"); return FALSE; } @@ -1665,7 +1637,7 @@ _gabble_media_channel_request_contents (GabbleMediaChannel *chan, peer_resource, want_audio ? JINGLE_MEDIA_TYPE_AUDIO : JINGLE_MEDIA_TYPE_VIDEO)) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "member does not have the desired audio/video capabilities"); return FALSE; @@ -1699,7 +1671,7 @@ _gabble_media_channel_request_contents (GabbleMediaChannel *chan, if (!jingle_pick_best_resource (priv->conn, peer, want_audio, want_video, &transport_ns, &dialect, &peer_resource)) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_CAPABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE, "member does not have the desired audio/video capabilities"); return FALSE; } @@ -1729,7 +1701,7 @@ _gabble_media_channel_request_contents (GabbleMediaChannel *chan, /* check it's not a ridiculous number of streams */ if ((priv->streams->len + media_types->len) > MAX_STREAMS) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "I think that's quite enough streams already"); return FALSE; } @@ -1790,7 +1762,7 @@ destroy_request (struct _delayed_request_streams_ctx *ctx, if (ctx->context != NULL) { GError *error = NULL; - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "cannot add streams: peer has insufficient caps"); ctx->failed_cb (ctx->context, error); g_error_free (error); @@ -1917,7 +1889,7 @@ media_channel_request_streams (GabbleMediaChannel *self, if (priv->peer != 0 && priv->peer != contact_handle) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "cannot add streams for %u: this channel's peer is %u", contact_handle, priv->peer); goto error; @@ -2080,11 +2052,11 @@ contact_is_media_capable (GabbleMediaChannel *chan, *wait_ret = wait; if (presence == NULL) - g_set_error (error, TP_ERRORS, TP_ERROR_OFFLINE, + g_set_error (error, TP_ERROR, TP_ERROR_OFFLINE, "contact %d (%s) has no presence available", peer, tp_handle_inspect (contact_handles, peer)); else - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_CAPABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE, "contact %d (%s) doesn't have sufficient media caps", peer, tp_handle_inspect (contact_handles, peer)); @@ -2100,7 +2072,7 @@ gabble_media_channel_add_member (GObject *obj, GabbleMediaChannel *chan = GABBLE_MEDIA_CHANNEL (obj); GabbleMediaChannelPrivate *priv = chan->priv; TpGroupMixin *mixin = TP_GROUP_MIXIN (obj); - TpIntSet *set; + TpIntset *set; /* did we create this channel? */ if (priv->creator == mixin->self_handle) @@ -2113,7 +2085,7 @@ gabble_media_channel_add_member (GObject *obj, */ if (priv->peer != 0 && priv->peer != handle) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "handle %u cannot be added: this channel's peer is %u", handle, priv->peer); return FALSE; @@ -2160,7 +2132,7 @@ gabble_media_channel_add_member (GObject *obj, /* is the call on hold? */ if (priv->hold_state != TP_LOCAL_HOLD_STATE_UNHELD) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Can't answer a call while it's on hold"); return FALSE; } @@ -2182,7 +2154,7 @@ gabble_media_channel_add_member (GObject *obj, } } - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "handle %u cannot be added in the current state", handle); return FALSE; } @@ -2233,7 +2205,7 @@ gabble_media_channel_remove_member (GObject *obj, jingle_reason = JINGLE_REASON_TIMEOUT; break; default: - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%u doesn't make sense as a reason to end a call", reason); g_object_unref (chan); return FALSE; @@ -2358,7 +2330,7 @@ session_terminated_cb (GabbleJingleSession *session, TpGroupMixin *mixin = TP_GROUP_MIXIN (channel); guint terminator; JingleState state; - TpIntSet *set; + TpIntset *set; DEBUG ("called"); @@ -2445,7 +2417,7 @@ session_state_changed_cb (GabbleJingleSession *session, GabbleMediaChannelPrivate *priv = channel->priv; TpGroupMixin *mixin = TP_GROUP_MIXIN (channel); JingleState state; - TpIntSet *set; + TpIntset *set; DEBUG ("called"); @@ -2966,7 +2938,7 @@ gabble_media_channel_ready (TpSvcMediaSessionHandler *iface, * error message describes the only legitimate situation in which this * could arise. */ - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, "call has already ended" }; + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "call has already ended" }; DEBUG ("no session, returning an error."); dbus_g_method_return_error (context, &e); @@ -3013,7 +2985,7 @@ gabble_media_channel_error (TpSvcMediaSessionHandler *iface, * error message describes the only legitimate situation in which this * could arise. */ - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, "call has already ended" }; + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "call has already ended" }; DEBUG ("no session, returning an error."); dbus_g_method_return_error (context, &e); diff --git a/src/media-channel.h b/src/media-channel.h index b10886ca2..cbe488af2 100644 --- a/src/media-channel.h +++ b/src/media-channel.h @@ -23,8 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/dbus-properties-mixin.h> -#include <telepathy-glib/group-mixin.h> +#include <telepathy-glib/telepathy-glib.h> #include <telepathy-glib/properties-mixin.h> #include "presence.h" diff --git a/src/media-factory.c b/src/media-factory.c index 493a8173c..675505e80 100644 --- a/src/media-factory.c +++ b/src/media-factory.c @@ -25,9 +25,9 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_MEDIA @@ -776,7 +776,7 @@ gabble_media_factory_requestotron (TpChannelManager *manager, if (require_target_handle) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "A valid Contact handle must be provided when requesting a media " "channel"); goto error; @@ -918,7 +918,7 @@ gabble_media_factory_create_call (TpChannelManager *manager, if (!initial_audio && !initial_video) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Call channel must contain at least " "one of InitialAudio or InitialVideo"); goto error; diff --git a/src/media-stream.c b/src/media-stream.c index 75c9ea38f..300269214 100644 --- a/src/media-stream.c +++ b/src/media-stream.c @@ -27,14 +27,9 @@ #include <string.h> #include <dbus/dbus-glib.h> -#include <telepathy-glib/debug-ansi.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-media-interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_MEDIA @@ -1198,7 +1193,7 @@ pass_local_codecs (GabbleMediaStream *stream, GABBLE_JINGLE_MEDIA_RTP (priv->content), md, ready, &wocky_error)) return TRUE; - g_set_error_literal (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error_literal (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, wocky_error->message); g_clear_error (&wocky_error); return FALSE; @@ -1304,7 +1299,7 @@ gabble_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface, if (codecs->len == 0) { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + GError e = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "SupportedCodecs must have a non-empty list of codecs" }; dbus_g_method_return_error (context, &e); @@ -1357,7 +1352,7 @@ gabble_media_stream_codecs_updated (TpSvcMediaStreamHandler *iface, if (!self->priv->local_codecs_set) { - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "CodecsUpdated may only be called once an initial set of codecs " "has been set" }; @@ -1981,7 +1976,7 @@ gabble_media_stream_change_direction (GabbleMediaStream *stream, if (!gabble_jingle_content_change_direction (priv->content, senders)) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "stream direction invalid for the Jingle dialect in use"); return FALSE; } diff --git a/src/media-stream.h b/src/media-stream.h index c8c50929a..277399d07 100644 --- a/src/media-stream.h +++ b/src/media-stream.h @@ -22,12 +22,9 @@ #define __GABBLE_MEDIA_STREAM_H__ #include <glib-object.h> +#include <telepathy-glib/telepathy-glib.h> #include "jingle-types.h" -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/dtmf.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/dbus-properties-mixin.h> G_BEGIN_DECLS diff --git a/src/message-util.c b/src/message-util.c index 5001be307..2c284e37e 100644 --- a/src/message-util.c +++ b/src/message-util.c @@ -23,12 +23,13 @@ */ #include "config.h" + #include "message-util.h" #include <string.h> #include <time.h> -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> #include <wocky/wocky.h> #define DEBUG_FLAG GABBLE_DEBUG_IM @@ -103,7 +104,7 @@ gabble_message_util_build_stanza (TpMessage *message, #define RETURN_INVALID_ARGUMENT(msg, ...) \ G_STMT_START { \ DEBUG (msg , ## __VA_ARGS__); \ - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, \ + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, \ msg , ## __VA_ARGS__); \ return NULL; \ } G_STMT_END diff --git a/src/muc-channel.c b/src/muc-channel.c index 69fd30a6e..c56e4e431 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -28,13 +28,8 @@ #include <wocky/wocky.h> #include <dbus/dbus-glib.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/debug-ansi.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-iface.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_MUC #include "connection.h" @@ -51,6 +46,10 @@ #include "presence-cache.h" #include "gabble-signals-marshal.h" #include "gabble-enumtypes.h" +#include "tube-dbus.h" +#include "tube-stream.h" +#include "private-tubes-factory.h" +#include "bytestream-factory.h" #define DEFAULT_JOIN_TIMEOUT 180 #define DEFAULT_LEAVE_TIMEOUT 180 @@ -60,7 +59,6 @@ #define PROPS_POLL_INTERVAL_HIGH 60 static void password_iface_init (gpointer, gpointer); -static void chat_state_iface_init (gpointer, gpointer); static void subject_iface_init (gpointer, gpointer); #ifdef ENABLE_VOIP static void gabble_muc_channel_start_call_creation (GabbleMucChannel *gmuc, @@ -81,7 +79,7 @@ G_DEFINE_TYPE_WITH_CODE (GabbleMucChannel, gabble_muc_channel, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MESSAGES, tp_message_mixin_messages_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CHAT_STATE, - chat_state_iface_init); + tp_message_mixin_chat_state_iface_init) G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CONFERENCE, NULL); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_ROOM, NULL); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_ROOM_CONFIG, @@ -92,6 +90,9 @@ G_DEFINE_TYPE_WITH_CODE (GabbleMucChannel, gabble_muc_channel, static void gabble_muc_channel_send (GObject *obj, TpMessage *message, TpMessageSendingFlags flags); +static gboolean gabble_muc_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error); static void gabble_muc_channel_close (TpBaseChannel *base); static const gchar *gabble_muc_channel_interfaces[] = { @@ -129,11 +130,11 @@ static guint signals[LAST_SIGNAL] = {0}; enum { PROP_STATE = 1, + PROP_INITIALLY_REGISTER, PROP_INVITED, PROP_INVITATION_MESSAGE, PROP_SELF_JID, PROP_WOCKY_MUC, - PROP_TUBE, PROP_INITIAL_CHANNELS, PROP_INITIAL_INVITEE_HANDLES, PROP_INITIAL_INVITEE_IDS, @@ -163,6 +164,8 @@ struct _GabbleMucChannelPrivate { GabbleMucState state; gboolean closing; + gboolean autoclose; + gboolean initially_register; guint join_timer_id; guint poll_timer_id; @@ -203,7 +206,9 @@ struct _GabbleMucChannelPrivate gchar *invitation_message; WockyMuc *wmuc; - GabbleTubesChannel *tube; + + /* tube ID => owned GabbleTubeIface */ + GHashTable *tubes; #ifdef ENABLE_VOIP /* Current active call */ @@ -238,6 +243,9 @@ gabble_muc_channel_init (GabbleMucChannel *self) self->priv = priv; priv->requests_cancellable = g_cancellable_new (); + + priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_object_unref); } static TpHandle create_room_identity (GabbleMucChannel *) @@ -356,8 +364,6 @@ gabble_muc_channel_constructed (GObject *obj) if (chain_up != NULL) chain_up (obj); - priv->tube = NULL; - room_handles = tp_base_connection_get_handles (base_conn, TP_HANDLE_TYPE_ROOM); contact_handles = tp_base_connection_get_handles (base_conn, @@ -416,7 +422,8 @@ gabble_muc_channel_constructed (GObject *obj) } /* register object on the bus */ - tp_base_channel_register (base); + if (priv->initially_register) + tp_base_channel_register (base); /* initialize group mixin */ tp_group_mixin_init (obj, @@ -439,6 +446,8 @@ gabble_muc_channel_constructed (GObject *obj) TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_FAILURES | TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_SUCCESSES, supported_content_types); + tp_message_mixin_implement_send_chat_state (obj, + gabble_muc_channel_send_chat_state); tp_group_mixin_add_handle_owner (obj, self_handle, base_conn->self_handle); @@ -493,8 +502,8 @@ gabble_muc_channel_constructed (GObject *obj) if (priv->invited) { /* invited: add ourself to local pending and the inviter to members */ - TpIntSet *members = tp_intset_new_containing (initiator); - TpIntSet *pending = tp_intset_new_containing (self_handle); + TpIntset *members = tp_intset_new_containing (initiator); + TpIntset *pending = tp_intset_new_containing (self_handle); tp_group_mixin_change_members (obj, priv->invitation_message, members, NULL, pending, NULL, @@ -525,8 +534,6 @@ gabble_muc_channel_constructed (GObject *obj) g_assert (error == NULL); g_array_unref (members); } - - tp_handle_unref (contact_handles, self_handle); } typedef struct { @@ -776,6 +783,49 @@ send_join_request (GabbleMucChannel *gmuc) wocky_muc_join (priv->wmuc, NULL); } +static void +tube_pre_presence (GabbleMucChannel *gmuc, + WockyStanza *stanza) +{ + GabbleMucChannelPrivate *priv = gmuc->priv; + TpBaseConnection *conn = tp_base_channel_get_connection ( + TP_BASE_CHANNEL (gmuc)); + WockyNode *tubes_node; + GHashTableIter iter; + gpointer value; + + tubes_node = wocky_node_add_child_with_content_ns ( + wocky_stanza_get_top_node (stanza), "tubes", NULL, NS_TUBES); + + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + GabbleTubeIface *tube = value; + TpTubeChannelState state; + WockyNode *tube_node; + TpTubeType type; + TpHandle initiator; + + g_object_get (tube, + "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 (gmuc)->self_handle) + /* We only announce stream tubes we initiated */ + continue; + + tube_node = wocky_node_add_child_with_content (tubes_node, + "tube", NULL); + gabble_tube_iface_publish_in_node (tube, conn, tube_node); + } +} + static gboolean timeout_leave (gpointer data) { @@ -798,6 +848,8 @@ send_leave_message (GabbleMucChannel *gmuc, WockyStanza *stanza = wocky_muc_create_presence (priv->wmuc, WOCKY_STANZA_SUB_TYPE_UNAVAILABLE, reason); + tube_pre_presence (gmuc, stanza); + g_signal_emit (gmuc, signals[PRE_PRESENCE], 0, stanza); _gabble_connection_send ( GABBLE_CONNECTION (tp_base_channel_get_connection (base)), stanza, NULL); @@ -821,12 +873,12 @@ gabble_muc_channel_get_property (GObject *object, case PROP_STATE: g_value_set_uint (value, priv->state); break; + case PROP_INITIALLY_REGISTER: + g_value_set_boolean (value, priv->initially_register); + break; case PROP_SELF_JID: g_value_set_string (value, priv->self_jid->str); break; - case PROP_TUBE: - g_value_set_object (value, priv->tube); - break; case PROP_WOCKY_MUC: g_value_set_object (value, priv->wmuc); break; @@ -896,6 +948,9 @@ gabble_muc_channel_set_property (GObject *object, channel_state_changed (chan, prev_state, priv->state); break; + case PROP_INITIALLY_REGISTER: + priv->initially_register = g_value_get_boolean (value); + break; case PROP_INVITED: priv->invited = g_value_get_boolean (value); break; @@ -1022,6 +1077,12 @@ gabble_muc_channel_class_init (GabbleMucChannelClass *gabble_muc_channel_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_STATE, param_spec); + param_spec = g_param_spec_boolean ("initially-register", "Initially register", + "whether to register the channel on the bus on creation", + TRUE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INITIALLY_REGISTER, param_spec); + param_spec = g_param_spec_boolean ("invited", "Invited?", "Whether the user has been invited to the channel.", FALSE, G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); @@ -1043,11 +1104,6 @@ gabble_muc_channel_class_init (GabbleMucChannelClass *gabble_muc_channel_class) g_object_class_install_property (object_class, PROP_SELF_JID, param_spec); - param_spec = g_param_spec_object ("tube", "Tube Channel", - "The GabbleTubesChannel associated with this MUC (if any)", - GABBLE_TYPE_TUBES_CHANNEL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_TUBE, param_spec); - param_spec = g_param_spec_object ("wocky-muc", "Wocky MUC Object", "The backend (Wocky) MUC instance", WOCKY_TYPE_MUC, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); @@ -1178,7 +1234,9 @@ gabble_muc_channel_class_init (GabbleMucChannelClass *gabble_muc_channel_class) 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GABBLE_TYPE_TUBES_CHANNEL); + /* this should be GABBLE_TYPE_TUBE_IFACE but GObject + * wants a value type, not an interface. */ + G_TYPE_NONE, 1, TP_TYPE_BASE_CHANNEL); #ifdef ENABLE_VOIP signals[NEW_CALL] = g_signal_new ("new-call", @@ -1232,6 +1290,8 @@ gabble_muc_channel_dispose (GObject *object) tp_clear_object (&priv->requests_cancellable); tp_clear_object (&priv->room_config); + tp_clear_pointer (&priv->tubes, g_hash_table_unref); + if (G_OBJECT_CLASS (gabble_muc_channel_parent_class)->dispose) G_OBJECT_CLASS (gabble_muc_channel_parent_class)->dispose (object); } @@ -1472,19 +1532,42 @@ close_channel (GabbleMucChannel *chan, const gchar *reason, GabbleMucChannelPrivate *priv = chan->priv; GabbleConnection *conn = GABBLE_CONNECTION ( tp_base_channel_get_connection (base)); - TpIntSet *set; + TpIntset *set; GArray *handles; - GError error = { TP_ERRORS, TP_ERROR_CANCELLED, + GError error = { TP_ERROR, TP_ERROR_CANCELLED, "Muc channel closed below us" }; - if (tp_base_channel_is_destroyed (base) || priv->closing) + if (tp_base_channel_is_destroyed (base)) return; + /* if priv->closing is TRUE, we're waiting for the MUC to echo our + * presence. however, if we're being asked to close again, but this + * time without letting the muc know, let's actually close. if we + * don't then the channel won't disappear from the bus properly. */ + if (priv->closing && !inform_muc) + { + clear_leave_timer (chan); + tp_base_channel_destroyed (base); + return; + } + + /* If inform_muc is TRUE it means that we're closing the channel + * gracefully and we don't mind if the channel doesn't actually + * close behind the scenes if a tube/call is still open. Every call + * to this function has inform_muc=FALSE, except for Channel.Close() + * and RemoveMembers(self_handle) */ + if (inform_muc && !gabble_muc_channel_can_be_closed (chan)) + { + priv->autoclose = TRUE; + tp_base_channel_disappear (base); + return; + } + DEBUG ("Closing"); /* Ensure we stay alive even while telling everyone else to abandon us. */ g_object_ref (chan); - gabble_muc_channel_close_tube (chan); + g_hash_table_remove_all (priv->tubes); #ifdef ENABLE_VOIP muc_call_channel_finish_requests (chan, NULL, &error); @@ -1543,6 +1626,35 @@ _gabble_muc_channel_is_ready (GabbleMucChannel *chan) return priv->ready; } +/* returns TRUE if there are no tube or Call channels open in this MUC */ +gboolean +gabble_muc_channel_can_be_closed (GabbleMucChannel *chan) +{ + GabbleMucChannelPrivate *priv = chan->priv; + + if (g_hash_table_size (priv->tubes) > 0) + return FALSE; + + if (priv->calls != NULL || priv->call_requests != NULL + || priv->call_initiating) + return FALSE; + + return TRUE; +} + +gboolean +gabble_muc_channel_get_autoclose (GabbleMucChannel *chan) +{ + return chan->priv->autoclose; +} + +void +gabble_muc_channel_set_autoclose (GabbleMucChannel *chan, + gboolean autoclose) +{ + chan->priv->autoclose = autoclose; +} + static gboolean handle_nick_conflict (GabbleMucChannel *chan, WockyStanza *stanza, @@ -1554,7 +1666,7 @@ handle_nick_conflict (GabbleMucChannel *chan, TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( tp_base_channel_get_connection (base), TP_HANDLE_TYPE_CONTACT); TpHandle self_handle; - TpIntSet *add_rp, *remove_rp; + TpIntset *add_rp, *remove_rp; const gchar *from = wocky_stanza_get_from (stanza); /* If this is a nick conflict message with a resource in the JID, and the @@ -1578,7 +1690,7 @@ handle_nick_conflict (GabbleMucChannel *chan, if (priv->nick_retry_count >= MAX_NICK_RETRIES) { - g_set_error (tp_error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (tp_error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "nickname already in use and retry count exceeded"); return FALSE; } @@ -1602,7 +1714,6 @@ handle_nick_conflict (GabbleMucChannel *chan, tp_intset_destroy (add_rp); tp_intset_destroy (remove_rp); - tp_handle_unref (contact_repo, self_handle); priv->nick_retry_count++; send_join_request (chan); @@ -1801,18 +1912,18 @@ handle_error (GObject *source, switch (errnum) { case WOCKY_XMPP_ERROR_FORBIDDEN: - tp_error = g_error_new (TP_ERRORS, TP_ERROR_CHANNEL_BANNED, + tp_error = g_error_new (TP_ERROR, TP_ERROR_CHANNEL_BANNED, "banned from room"); reason = TP_CHANNEL_GROUP_CHANGE_REASON_BANNED; break; case WOCKY_XMPP_ERROR_SERVICE_UNAVAILABLE: - tp_error = g_error_new (TP_ERRORS, TP_ERROR_CHANNEL_FULL, + tp_error = g_error_new (TP_ERROR, TP_ERROR_CHANNEL_FULL, "room is full"); reason = TP_CHANNEL_GROUP_CHANGE_REASON_BUSY; break; case WOCKY_XMPP_ERROR_REGISTRATION_REQUIRED: - tp_error = g_error_new (TP_ERRORS, TP_ERROR_CHANNEL_INVITE_ONLY, + tp_error = g_error_new (TP_ERROR, TP_ERROR_CHANNEL_INVITE_ONLY, "room is invite only"); break; @@ -1822,7 +1933,7 @@ handle_error (GObject *source, break; default: - tp_error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + tp_error = g_error_new (TP_ERROR, TP_ERROR_NOT_AVAILABLE, "%s", wocky_xmpp_error_description (errnum)); break; } @@ -1835,90 +1946,388 @@ handle_error (GObject *source, } static void -tube_closed_cb (GabbleTubesChannel *chan, gpointer user_data) +tube_closed_cb (GabbleTubeIface *tube, + GabbleMucChannel *gmuc) { - GabbleMucChannel *gmuc = GABBLE_MUC_CHANNEL (user_data); GabbleMucChannelPrivate *priv = gmuc->priv; - TpHandle room; + guint64 tube_id; - if (priv->tube != NULL) - { - priv->tube = NULL; - g_object_get (chan, "handle", &room, NULL); - DEBUG ("removing MUC tubes channel with handle %d", room); - g_object_unref (chan); - } + g_object_get (tube, "id", &tube_id, NULL); + + g_hash_table_remove (priv->tubes, GUINT_TO_POINTER (tube_id)); } -static GabbleTubesChannel * -new_tube (GabbleMucChannel *gmuc, +static GabbleTubeIface * +create_new_tube (GabbleMucChannel *gmuc, + TpTubeType type, TpHandle initiator, + const gchar *service, + GHashTable *parameters, + const gchar *stream_id, + guint64 tube_id, + GabbleBytestreamIface *bytestream, gboolean requested) { GabbleMucChannelPrivate *priv = gmuc->priv; TpBaseChannel *base = TP_BASE_CHANNEL (gmuc); - TpBaseConnection *conn = tp_base_channel_get_connection (base); - char *object_path; + GabbleConnection *conn = GABBLE_CONNECTION ( + tp_base_channel_get_connection (base)); + TpHandle self_handle = TP_GROUP_MIXIN (gmuc)->self_handle; + TpHandle handle = tp_base_channel_get_target_handle (base); + GabbleTubeIface *tube; - g_assert (priv->tube == NULL); + switch (type) + { + case TP_TUBE_TYPE_DBUS: + tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (conn, + handle, TP_HANDLE_TYPE_ROOM, self_handle, initiator, + service, parameters, stream_id, tube_id, bytestream, gmuc, + requested)); + break; + case TP_TUBE_TYPE_STREAM: + tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (conn, + handle, TP_HANDLE_TYPE_ROOM, self_handle, initiator, + service, parameters, tube_id, gmuc, requested)); + break; + default: + g_return_val_if_reached (NULL); + } - object_path = g_strdup_printf ("%s/MucTubesChannel%u", - conn->object_path, tp_base_channel_get_target_handle (base)); + tp_base_channel_register ((TpBaseChannel *) tube); - DEBUG ("creating new tubes chan, object path %s", object_path); + DEBUG ("create tube %" G_GUINT64_FORMAT, tube_id); + g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id), tube); - priv->tube = g_object_new (GABBLE_TYPE_TUBES_CHANNEL, - "connection", tp_base_channel_get_connection (base), - "object-path", object_path, - "handle", tp_base_channel_get_target_handle (base), - "handle-type", TP_HANDLE_TYPE_ROOM, - "muc", gmuc, - "initiator-handle", initiator, - "requested", requested, - NULL); + g_signal_connect (tube, "closed", G_CALLBACK (tube_closed_cb), gmuc); + + return tube; +} + +static guint64 +generate_tube_id (GabbleMucChannel *self) +{ + GabbleMucChannelPrivate *priv = self->priv; + guint64 out; + + /* probably totally overkill */ + do + { + out = g_random_int_range (1, G_MAXINT32); + } + while (g_hash_table_lookup (priv->tubes, + GUINT_TO_POINTER (out)) != NULL); + + return out; +} + +GabbleTubeIface * +gabble_muc_channel_tube_request (GabbleMucChannel *self, + gpointer request_token, + GHashTable *request_properties, + gboolean require_new) +{ + GabbleTubeIface *tube; + const gchar *channel_type; + const gchar *service; + GHashTable *parameters = NULL; + guint64 tube_id; + gchar *stream_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); + + stream_id = gabble_bytestream_factory_generate_stream_id (); + tube = create_new_tube (self, type, TP_GROUP_MIXIN (self)->self_handle, + service, parameters, stream_id, tube_id, NULL, TRUE); + g_free (stream_id); + g_hash_table_unref (parameters); + + return tube; +} + +void +gabble_muc_channel_foreach_tubes (GabbleMucChannel *gmuc, + TpExportableChannelFunc foreach, + gpointer user_data) +{ + GabbleMucChannelPrivate *priv = gmuc->priv; + 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 +gabble_muc_channel_handle_si_stream_request (GabbleMucChannel *self, + GabbleBytestreamIface *bytestream, + const gchar *stream_id, + WockyStanza *msg) +{ + GabbleMucChannelPrivate *priv = self->priv; + WockyNode *si_node, *stream_node; + const gchar *tmp; + guint64 tube_id; + GabbleTubeIface *tube; + + si_node = wocky_node_get_child_ns ( + wocky_stanza_get_top_node (msg), "si", NS_SI); + g_return_if_fail (si_node != NULL); + + stream_node = wocky_node_get_child_ns (si_node, + "muc-stream", NS_TUBES); + g_return_if_fail (stream_node != NULL); + + tmp = wocky_node_get_attribute (stream_node, "tube"); + if (tmp == NULL) + { + GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, + "<muc-stream> has no tube attribute" }; + + NODE_DEBUG (stream_node, e.message); + gabble_bytestream_iface_close (bytestream, &e); + return; + } + 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, + "<muc-stream> tube ID attribute non-numeric or out of range" }; + + DEBUG ("tube id is non-numeric or out of range: %s", tmp); + gabble_bytestream_iface_close (bytestream, &e); + return; + } + + 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, + "<muc-stream> tube attribute points to a nonexistent " + "tube" }; + + DEBUG ("tube %" G_GUINT64_FORMAT " doesn't exist", tube_id); + gabble_bytestream_iface_close (bytestream, &e); + return; + } - g_signal_connect (priv->tube, "closed", (GCallback) tube_closed_cb, gmuc); + DEBUG ("received new bytestream request for existing tube: %" G_GUINT64_FORMAT, + tube_id); - g_signal_emit (gmuc, signals[NEW_TUBE], 0 , priv->tube); + gabble_tube_iface_add_bytestream (tube, bytestream); +} + +static void +tubes_presence_update (GabbleMucChannel *gmuc, + TpHandle contact, + WockyNode *pnode) +{ + GabbleMucChannelPrivate *priv = gmuc->priv; + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( + tp_base_channel_get_connection (TP_BASE_CHANNEL (gmuc)), + TP_HANDLE_TYPE_CONTACT); + const gchar *presence_type; + WockyNode *tubes_node; + GHashTable *old_dbus_tubes; + GHashTableIter iter; + gpointer key, value; + WockyNodeIter i; + WockyNode *tube_node; + + if (contact == TP_GROUP_MIXIN (gmuc)->self_handle) + /* We don't need to inspect our own presence */ + return; + + presence_type = wocky_node_get_attribute (pnode, "type"); + if (!tp_strdiff (presence_type, "unavailable")) + { + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + GabbleTubeDBus *tube = value; + + if (!GABBLE_IS_TUBE_DBUS (value)) + continue; + + gabble_tube_dbus_remove_name (tube, contact); + } + } + + tubes_node = wocky_node_get_child_ns (pnode, "tubes", NS_TUBES); + + if (tubes_node == NULL) + return; + + /* Fill old_dbus_tubes with D-BUS tubes previously announced by + * the contact */ + old_dbus_tubes = g_hash_table_new (g_direct_hash, g_direct_equal); + + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + if (!GABBLE_IS_TUBE_DBUS (value)) + continue; + + if (gabble_tube_dbus_handle_in_names (GABBLE_TUBE_DBUS (value), + contact)) + { + g_hash_table_insert (old_dbus_tubes, + key, value); + } + } + + wocky_node_iter_init (&i, tubes_node, NULL, NULL); + while (wocky_node_iter_next (&i, &tube_node)) + { + const gchar *stream_id; + GabbleTubeIface *tube; + guint64 tube_id; + TpTubeType type; + + stream_id = wocky_node_get_attribute (tube_node, "stream-id"); + + if (!gabble_private_tubes_factory_extract_tube_information ( + contact_repo, tube_node, NULL, NULL, NULL, NULL, &tube_id)) + { + DEBUG ("Bad tube ID, skipping to next child of <tubes>"); + continue; + } - g_free (object_path); + tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - return priv->tube; + if (tube == NULL) + { + /* We don't know yet this tube */ + const gchar *service; + TpHandle initiator_handle; + GHashTable *parameters; + + if (gabble_private_tubes_factory_extract_tube_information ( + contact_repo, tube_node, &type, &initiator_handle, + &service, ¶meters, NULL)) + { + if (type == TP_TUBE_TYPE_DBUS && initiator_handle == 0) + { + DEBUG ("D-Bus tube initiator missing"); + /* skip to the next child of <tubes> */ + continue; + } + else if (type == TP_TUBE_TYPE_STREAM) + { + initiator_handle = contact; + } + + tube = create_new_tube (gmuc, type, initiator_handle, + service, parameters, stream_id, tube_id, NULL, FALSE); + + g_signal_emit (gmuc, signals[NEW_TUBE], 0, tube); + + /* the tube has reffed its initiator, no need to keep a ref */ + tp_handle_unref (contact_repo, initiator_handle); + 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) + /* skip to the next child of <tubes> */ + continue; + + g_object_get (tube, "type", &type, NULL); + + if (type == TP_TUBE_TYPE_DBUS) + { + /* Update mapping of handle -> D-Bus name. */ + if (!gabble_tube_dbus_handle_in_names (GABBLE_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); + /* skip to the next child of <tubes> */ + continue; + } + + gabble_tube_dbus_add_name (GABBLE_TUBE_DBUS (tube), + contact, new_name); + } + } + } + + /* Tubes remaining in old_dbus_tubes was left by the contact */ + g_hash_table_iter_init (&iter, old_dbus_tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + gabble_tube_dbus_remove_name (GABBLE_TUBE_DBUS (value), contact); + } + + g_hash_table_unref (old_dbus_tubes); } /* ************************************************************************* */ /* presence related signal handlers */ -/* not actually a signal handler, but used by them: * - * creates a tube if none exists, and then prods the presence handler * - * in the gabble tubes implementation to do whatever else needs to be done */ +/* not actually a signal handler, but used by them. */ static void handle_tube_presence (GabbleMucChannel *gmuc, TpHandle from, WockyStanza *stanza) { - GabbleMucChannelPrivate *priv = gmuc->priv; WockyNode *node = wocky_stanza_get_top_node (stanza); if (from == 0) return; - if (priv->tube == NULL) - { - WockyNode *tubes; - tubes = wocky_node_get_child_ns (node, "tubes", NS_TUBES); - - /* presence doesn't contain tubes information, no need - * to create a tubes channel */ - if (tubes == NULL) - return; - - /* MUC Tubes channels (as opposed to the individual tubes) don't - * have a well-defined initiator (they're a consensus) so use 0 */ - priv->tube = new_tube (gmuc, 0, FALSE); - } - - gabble_tubes_channel_presence_updated (priv->tube, from, node); + tubes_presence_update (gmuc, from, node); } static TpChannelGroupChangeReason @@ -1955,7 +2364,7 @@ handle_parted (GObject *source, TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (tp_base_channel_get_connection (base), TP_HANDLE_TYPE_CONTACT); - TpIntSet *handles = NULL; + TpIntset *handles = NULL; TpHandle member = 0; TpHandle actor = 0; const char *jid = wocky_muc_jid (wmuc); @@ -1999,16 +2408,11 @@ handle_parted (GObject *source, reason = muc_status_codes_to_change_reason (codes); /* handle_tube_presence creates tubes if need be, so bypass it here: */ - if (priv->tube != NULL) - gabble_tubes_channel_presence_updated (priv->tube, member, - wocky_stanza_get_top_node (stanza)); + tubes_presence_update (gmuc, member, wocky_stanza_get_top_node (stanza)); close_channel (gmuc, why, FALSE, actor, reason); - if (actor != 0) - tp_handle_unref (contact_repo, actor); tp_intset_destroy (handles); - tp_handle_unref (contact_repo, member); } @@ -2026,12 +2430,11 @@ handle_left (GObject *source, { GabbleMucChannel *gmuc = GABBLE_MUC_CHANNEL (data); TpBaseChannel *base = TP_BASE_CHANNEL (gmuc); - GabbleMucChannelPrivate *priv = gmuc->priv; TpChannelGroupChangeReason reason = TP_CHANNEL_GROUP_CHANGE_REASON_NONE; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (tp_base_channel_get_connection (base), TP_HANDLE_TYPE_CONTACT); - TpIntSet *handles = NULL; + TpIntset *handles = NULL; TpHandle member = 0; TpHandle actor = 0; @@ -2056,17 +2459,14 @@ handle_left (GObject *source, reason = muc_status_codes_to_change_reason (codes); /* handle_tube_presence creates tubes if need be, so bypass it here: */ - if (priv->tube != NULL) - gabble_tubes_channel_presence_updated (priv->tube, member, - wocky_stanza_get_top_node (stanza)); + tubes_presence_update (gmuc, member, wocky_stanza_get_top_node (stanza)); tp_group_mixin_change_members (data, why, NULL, handles, NULL, NULL, actor, reason); + tp_message_mixin_change_chat_state (data, member, + TP_CHANNEL_CHAT_STATE_GONE); - if (actor != 0) - tp_handle_unref (contact_repo, actor); tp_intset_destroy (handles); - tp_handle_unref (contact_repo, member); } /* connect to wocky-muc:SIG_PERM_CHANGE, which we will receive when the * @@ -2124,6 +2524,8 @@ handle_fill_presence (WockyMuc *muc, conn->self_presence->status_message, 0); + tube_pre_presence (self, stanza); + g_signal_emit (self, signals[PRE_PRESENCE], 0, (WockyStanza *) stanza); } @@ -2141,7 +2543,7 @@ handle_renamed (GObject *source, TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (tp_base_channel_get_connection (base), TP_HANDLE_TYPE_CONTACT); - TpIntSet *old_self = tp_intset_new (); + TpIntset *old_self = tp_intset_new (); const gchar *me = wocky_muc_jid (wmuc); const gchar *me2 = wocky_muc_user (wmuc); TpHandle myself = tp_handle_ensure (contact_repo, me, @@ -2157,8 +2559,6 @@ handle_renamed (GObject *source, handle_tube_presence (gmuc, myself, stanza); tp_intset_destroy (old_self); - tp_handle_unref (contact_repo, userid); - tp_handle_unref (contact_repo, myself); } static void @@ -2194,7 +2594,6 @@ update_roster_presence (GabbleMucChannel *gmuc, GUINT_TO_POINTER (handle), GUINT_TO_POINTER (owner)); - tp_handle_unref (contact_repo, handle); /* make a note of the fact that owner JIDs are visible to us */ /* notify whomever that an identifiable contact joined the MUC */ if (owner != 0) @@ -2202,7 +2601,6 @@ update_roster_presence (GabbleMucChannel *gmuc, tp_group_mixin_change_flags (G_OBJECT (gmuc), 0, TP_CHANNEL_GROUP_FLAG_HANDLE_OWNERS_NOT_AVAILABLE); g_signal_emit (gmuc, signals[CONTACT_JOIN], 0, owner); - tp_handle_unref (contact_repo, owner); } handle_tube_presence (gmuc, handle, member->presence_stanza); @@ -2266,7 +2664,6 @@ handle_join (WockyMuc *muc, g_object_set (gmuc, "state", MUC_STATE_JOINED, NULL); - tp_handle_unref (contact_repo, myself); tp_handle_set_destroy (members); tp_handle_set_destroy (owners); g_hash_table_unref (omap); @@ -2341,10 +2738,6 @@ handle_presence (GObject *source, } #endif - /* zap the handle refs we created */ - tp_handle_unref (contact_repo, handle); - if (owner != 0) - tp_handle_unref (contact_repo, owner); tp_handle_set_destroy (handles); } @@ -2391,7 +2784,6 @@ handle_message (GObject *source, handle_type = TP_HANDLE_TYPE_ROOM; repo = tp_base_connection_get_handles (conn, handle_type); from = tp_base_channel_get_target_handle (base); - tp_handle_ref (repo, from); } switch (type) @@ -2413,7 +2805,7 @@ handle_message (GObject *source, if (from_member && state != WOCKY_MUC_MSG_STATE_NONE) { - gint tp_msg_state; + TpChannelChatState tp_msg_state; switch (state) { case WOCKY_MUC_MSG_STATE_ACTIVE: @@ -2432,15 +2824,12 @@ handle_message (GObject *source, tp_msg_state = TP_CHANNEL_CHAT_STATE_ACTIVE; } - tp_svc_channel_interface_chat_state_emit_chat_state_changed (gmuc, - from, tp_msg_state); + tp_message_mixin_change_chat_state ((GObject *) gmuc, from, tp_msg_state); } if (subject != NULL) _gabble_muc_channel_handle_subject (gmuc, handle_type, from, datetime, subject, stanza); - - tp_handle_unref (repo, from); } static void @@ -2485,7 +2874,6 @@ handle_errmsg (GObject *source, handle_type = TP_HANDLE_TYPE_ROOM; repo = tp_base_connection_get_handles (conn, handle_type); from = tp_base_channel_get_target_handle (base); - tp_handle_ref (repo, from); } tp_err = gabble_tp_send_error_from_wocky_xmpp_error (error); @@ -2514,8 +2902,6 @@ handle_errmsg (GObject *source, !tp_strdiff (xmpp_id, priv->set_subject_stanza_id))) _gabble_muc_channel_handle_subject (gmuc, handle_type, from, datetime, subject, stanza); - - tp_handle_unref (repo, from); } /* ************************************************************************* */ @@ -2655,6 +3041,16 @@ _gabble_muc_channel_receive (GabbleMucChannel *chan, return; } + /* are we actually hidden? */ + if (!tp_base_channel_is_registered (base)) + { + DEBUG ("making MUC channel reappear!"); + tp_base_channel_reopened_with_requested (base, FALSE, sender); + } + + /* let's not autoclose now */ + chan->priv->autoclose = FALSE; + message = tp_cm_message_new (base_conn, 2); /* Header common to normal message and delivery-echo */ @@ -2783,7 +3179,7 @@ gabble_muc_channel_provide_password (TpSvcChannelInterfacePassword *iface, if (!priv->must_provide_password || priv->password_ctx != NULL) { - GError error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "password cannot be provided in the current state" }; dbus_g_method_return_error (context, &error); } @@ -2839,14 +3235,21 @@ gabble_muc_channel_send (GObject *obj, GabbleMucChannel *self = GABBLE_MUC_CHANNEL (obj); TpBaseChannel *base = TP_BASE_CHANNEL (self); GabbleMucChannelPrivate *priv = self->priv; - GabbleConnection *gabble_conn = - GABBLE_CONNECTION (tp_base_channel_get_connection (base)); + TpBaseConnection *base_conn; + GabbleConnection *gabble_conn; _GabbleMUCSendMessageCtx *context = NULL; WockyStanza *stanza = NULL; WockyPorter *porter = NULL; GError *error = NULL; gchar *id = NULL; + base_conn = tp_base_channel_get_connection (base); + gabble_conn = GABBLE_CONNECTION (base_conn); + + tp_message_mixin_change_chat_state (obj, + tp_base_channel_get_self_handle (base), + TP_CHANNEL_CHAT_STATE_ACTIVE); + stanza = gabble_message_util_build_stanza (message, gabble_conn, WOCKY_STANZA_SUB_TYPE_GROUPCHAT, TP_CHANNEL_CHAT_STATE_ACTIVE, priv->jid, FALSE, &id, &error); @@ -2932,14 +3335,14 @@ gabble_muc_channel_add_member (GObject *obj, if (handle == mixin->self_handle) { TpBaseConnection *conn = tp_base_channel_get_connection (base); - TpIntSet *set_remove_members, *set_remote_pending; + TpIntset *set_remove_members, *set_remote_pending; GArray *arr_members; /* are we already a member or in remote pending? */ if (tp_handle_set_is_member (mixin->members, handle) || tp_handle_set_is_member (mixin->remote_pending, handle)) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "already a member or in remote pending"); return FALSE; @@ -2983,7 +3386,7 @@ gabble_muc_channel_add_member (GObject *obj, /* check that we're indeed a member when attempting to invite others */ if (priv->state < MUC_STATE_JOINED) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "channel membership is required for inviting others"); return FALSE; @@ -3250,7 +3653,7 @@ request_config_form_reply_cb ( * platforms, so fail at compile time if this is no longer the case */ #if TP_NUM_BASE_ROOM_CONFIG_PROPERTIES > 32 -#error GabbleMUCChannel request_config_form_reply_cb needs porting to TpIntSet +#error GabbleMUCChannel request_config_form_reply_cb needs porting to TpIntset #endif props_left = 0; @@ -3324,8 +3727,7 @@ request_config_form_reply_cb ( { GString *unsubstituted = g_string_new (""); - printf (TP_ANSI_BOLD_ON TP_ANSI_FG_WHITE TP_ANSI_BG_RED - "\n%s: the following properties were not substituted:\n", + printf ("\n%s: the following properties were not substituted:\n", G_STRFUNC); for (i = 0; i < TP_NUM_BASE_ROOM_CONFIG_PROPERTIES; i++) @@ -3345,10 +3747,10 @@ request_config_form_reply_cb ( printf ("\nthis is a MUC server compatibility bug in gabble, please " "report it with a full debug log attached (running gabble " - "with WOCKY_DEBUG=xmpp)" TP_ANSI_RESET "\n\n"); + "with WOCKY_DEBUG=xmpp)\n\n"); fflush (stdout); - error = g_error_new (TP_ERRORS, TP_ERROR_SERVICE_CONFUSED, + error = g_error_new (TP_ERROR, TP_ERROR_SERVICE_CONFUSED, "Couldn't find fields corresponding to %s in the muc#owner form. " "This is a MUC server compatibility bug in Gabble.", unsubstituted->str); @@ -3403,55 +3805,18 @@ request_config_form_submit_reply_cb ( g_object_unref (update_result); } -/** - * gabble_muc_channel_set_chat_state - * - * Implements D-Bus method SetChatState - * on interface org.freedesktop.Telepathy.Channel.Interface.ChatState - */ -static void -gabble_muc_channel_set_chat_state (TpSvcChannelInterfaceChatState *iface, - guint state, - DBusGMethodInvocation *context) +static gboolean +gabble_muc_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error) { - GabbleMucChannel *self = GABBLE_MUC_CHANNEL (iface); + GabbleMucChannel *self = GABBLE_MUC_CHANNEL (object); + GabbleMucChannelPrivate *priv = self->priv; TpBaseChannel *base = TP_BASE_CHANNEL (self); - GabbleMucChannelPrivate *priv; - GError *error = NULL; - - g_assert (GABBLE_IS_MUC_CHANNEL (self)); - - priv = self->priv; - - if (state >= NUM_TP_CHANNEL_CHAT_STATES) - { - DEBUG ("invalid state %u", state); - - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "invalid state: %u", state); - } - - if (state == TP_CHANNEL_CHAT_STATE_GONE) - { - /* We cannot explicitly set the Gone state */ - DEBUG ("you may not explicitly set the Gone state"); - - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "you may not explicitly set the Gone state"); - } - if (error != NULL || - !gabble_message_util_send_chat_state (G_OBJECT (self), - GABBLE_CONNECTION (tp_base_channel_get_connection (base)), - WOCKY_STANZA_SUB_TYPE_GROUPCHAT, state, priv->jid, &error)) - { - dbus_g_method_return_error (context, error); - g_error_free (error); - - return; - } - - tp_svc_channel_interface_chat_state_return_from_set_chat_state (context); + return gabble_message_util_send_chat_state (G_OBJECT (self), + GABBLE_CONNECTION (tp_base_channel_get_connection (base)), + WOCKY_STANZA_SUB_TYPE_GROUPCHAT, state, priv->jid, error); } void @@ -3473,40 +3838,6 @@ gabble_muc_channel_send_presence (GabbleMucChannel *self) g_object_unref (stanza); } -GabbleTubesChannel * -gabble_muc_channel_open_tube (GabbleMucChannel *gmuc, - TpHandle initiator, - gboolean requested) -{ - GabbleMucChannelPrivate *priv = gmuc->priv; - - if (priv->tube == NULL) - priv->tube = new_tube (gmuc, initiator, requested); - - if (priv->tube != NULL) - return g_object_ref (priv->tube); - - return NULL; -} - -void -gabble_muc_channel_close_tube (GabbleMucChannel *gmuc) -{ - GabbleMucChannelPrivate *priv = gmuc->priv; - - if (priv->tube != NULL) - { - TpHandle room; - GabbleTubesChannel *tube = priv->tube; - - priv->tube = NULL; - g_object_get (tube, "handle", &room, NULL); - DEBUG ("removing MUC tubes channel with handle %d", room); - gabble_tubes_channel_close (tube); - g_object_unref (tube); - } -} - #ifdef ENABLE_VOIP GabbleCallMucChannel * gabble_muc_channel_get_call (GabbleMucChannel *gmuc) @@ -3689,7 +4020,7 @@ gabble_muc_channel_request_call (GabbleMucChannel *gmuc, { g_simple_async_report_error_in_idle (G_OBJECT (gmuc), callback, user_data, - TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + TP_ERROR, TP_ERROR_NOT_AVAILABLE, "A request for a call is already in progress"); return; } @@ -3785,21 +4116,21 @@ gabble_muc_channel_set_subject (TpSvcChannelInterfaceSubject *iface, if (priv->state < MUC_STATE_JOINED) { - GError error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Steady on. You're not in the room yet" }; dbus_g_method_return_error (context, &error); } else if (priv->state > MUC_STATE_JOINED || priv->closing) { - GError error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Already left/leaving the room" }; dbus_g_method_return_error (context, &error); } else if (priv->set_subject_context != NULL) { - GError error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Hey! Stop changing the subject! (Your last request is still in " "flight.)" }; @@ -3845,18 +4176,6 @@ password_iface_init (gpointer g_iface, gpointer iface_data) } static void -chat_state_iface_init (gpointer g_iface, gpointer iface_data) -{ - TpSvcChannelInterfaceChatStateClass *klass = - (TpSvcChannelInterfaceChatStateClass *) g_iface; - -#define IMPLEMENT(x) tp_svc_channel_interface_chat_state_implement_##x (\ - klass, gabble_muc_channel_##x) - IMPLEMENT(set_chat_state); -#undef IMPLEMENT -} - -static void subject_iface_init (gpointer g_iface, gpointer iface_data) { TpSvcChannelInterfaceSubjectClass *klass = diff --git a/src/muc-channel.h b/src/muc-channel.h index f28b7a07e..21535ac23 100644 --- a/src/muc-channel.h +++ b/src/muc-channel.h @@ -27,16 +27,13 @@ #include <glib-object.h> #include <gio/gio.h> -#include <telepathy-glib/base-channel.h> -#include <telepathy-glib/dbus-properties-mixin.h> -#include <telepathy-glib/group-mixin.h> -#include <telepathy-glib/message-mixin.h> +#include <telepathy-glib/telepathy-glib.h> #include "types.h" -#include "tubes-channel.h" #ifdef ENABLE_VOIP #include "call-muc-channel.h" #endif +#include "tube-iface.h" G_BEGIN_DECLS @@ -88,15 +85,29 @@ GType gabble_muc_channel_get_type (void); gboolean _gabble_muc_channel_is_ready (GabbleMucChannel *chan); +void gabble_muc_channel_set_autoclose (GabbleMucChannel *chan, + gboolean autoclose); + +gboolean gabble_muc_channel_get_autoclose (GabbleMucChannel *chan); + +gboolean gabble_muc_channel_can_be_closed (GabbleMucChannel *chan); + void gabble_muc_channel_send_presence (GabbleMucChannel *chan); gboolean gabble_muc_channel_send_invite (GabbleMucChannel *self, const gchar *jid, const gchar *message, gboolean continue_, GError **error); -GabbleTubesChannel * -gabble_muc_channel_open_tube (GabbleMucChannel *gmuc, - TpHandle initiator, - gboolean requested); +GabbleTubeIface * gabble_muc_channel_tube_request (GabbleMucChannel *self, + gpointer request_token, + GHashTable *request_properties, + gboolean require_new); + +void gabble_muc_channel_foreach_tubes (GabbleMucChannel *gmuc, + TpExportableChannelFunc foreach, gpointer user_data); + +void gabble_muc_channel_handle_si_stream_request (GabbleMucChannel *self, + GabbleBytestreamIface *bytestream, const gchar *stream_id, + WockyStanza *msg); #ifdef ENABLE_VOIP GabbleCallMucChannel * gabble_muc_channel_get_call (GabbleMucChannel *gmuc); @@ -128,7 +139,6 @@ gboolean gabble_muc_channel_update_configuration_finish ( GError **error); void gabble_muc_channel_teardown (GabbleMucChannel *gmuc); -void gabble_muc_channel_close_tube (GabbleMucChannel *gmuc); G_END_DECLS diff --git a/src/muc-factory.c b/src/muc-factory.c index 4cc7e21b8..cf945f731 100644 --- a/src/muc-factory.c +++ b/src/muc-factory.c @@ -25,11 +25,9 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> #include <wocky/wocky.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_MUC @@ -46,7 +44,6 @@ #include "muc-channel.h" #include "namespaces.h" #include "presence-cache.h" -#include "tubes-channel.h" #include "tube-dbus.h" #include "tube-stream.h" #include "util.h" @@ -81,14 +78,10 @@ struct _GabbleMucFactoryPrivate guint message_cb_id; /* GUINT_TO_POINTER(room_handle) => (GabbleMucChannel *) */ GHashTable *text_channels; - /* Tubes channels which will be considered ready when the corresponding - * text channel is created. - * Borrowed GabbleMucChannel => borrowed GabbleTubesChannel */ - GHashTable *text_needed_for_tubes; /* Tube channels which will be considered ready when the corresponding - * tubes channel is created. - * Borrowed GabbleTubesChannel => GSlist of borrowed GabbleTubeIface */ - GHashTable *tubes_needed_for_tube; + * text channel is created. + * Borrowed GabbleMucChannel => owned GQueue of borrowed GabbleTubeIface */ + GHashTable *text_needed_for_tube; /* GabbleDiscoRequest * => NULL (used as a set) */ GHashTable *disco_requests; @@ -103,6 +96,9 @@ struct _GabbleMucFactoryPrivate static GObject *gabble_muc_factory_constructor (GType type, guint n_props, GObjectConstructParam *props); +static void gabble_muc_factory_associate_tube (GabbleMucFactory *self, + GabbleMucChannel *gmuc, GabbleTubeIface *tube); + static void gabble_muc_factory_init (GabbleMucFactory *fac) { @@ -113,13 +109,11 @@ gabble_muc_factory_init (GabbleMucFactory *fac) priv->text_channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); - priv->text_needed_for_tubes = g_hash_table_new_full (g_direct_hash, - g_direct_equal, NULL, NULL); - priv->tubes_needed_for_tube = 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_queue_free); priv->disco_requests = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); + NULL, NULL); priv->queued_requests = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); @@ -156,8 +150,7 @@ gabble_muc_factory_dispose (GObject *object) gabble_muc_factory_close_all (fac); g_assert (priv->text_channels == NULL); - g_assert (priv->text_needed_for_tubes == NULL); - g_assert (priv->tubes_needed_for_tube == NULL); + g_assert (priv->text_needed_for_tube == NULL); g_assert (priv->queued_requests == NULL); g_hash_table_foreach (priv->disco_requests, cancel_disco_request, @@ -239,19 +232,30 @@ muc_channel_closed_cb (GabbleMucChannel *chan, gpointer user_data) { GabbleMucFactory *fac = GABBLE_MUC_FACTORY (user_data); GabbleMucFactoryPrivate *priv = fac->priv; + TpBaseChannel *base = TP_BASE_CHANNEL (chan); TpHandle room_handle; - tp_channel_manager_emit_channel_closed_for_object (fac, - TP_EXPORTABLE_CHANNEL (chan)); + /* channel is actually reappearing, announce it */ + if (tp_base_channel_is_respawning (base)) + { + tp_channel_manager_emit_new_channel (fac, + TP_EXPORTABLE_CHANNEL (chan), NULL); + return; + } - if (priv->text_channels != NULL) + if (tp_base_channel_is_registered (base)) + { + tp_channel_manager_emit_channel_closed_for_object (fac, + TP_EXPORTABLE_CHANNEL (chan)); + } + + if (tp_base_channel_is_destroyed (base) + && priv->text_channels != NULL) { g_object_get (chan, "handle", &room_handle, NULL); DEBUG ("removing MUC channel with handle %d", room_handle); - gabble_muc_channel_close_tube (chan); - g_hash_table_remove (priv->text_channels, GUINT_TO_POINTER (room_handle)); } } @@ -262,86 +266,56 @@ muc_ready_cb (GabbleMucChannel *text_chan, { GabbleMucFactory *fac = GABBLE_MUC_FACTORY (data); GabbleMucFactoryPrivate *priv = fac->priv; - GabbleTubesChannel *tubes_chan; - GSList *requests_satisfied_text, *requests_satisfied_tubes = NULL; - gboolean text_requested; - GSList *tube_channels, *l; + GHashTable *channels; + TpBaseChannel *base = TP_BASE_CHANNEL (text_chan); + + GSList *requests_satisfied_text = NULL; + GQueue *tube_channels; DEBUG ("text chan=%p", text_chan); - g_object_get (text_chan, "requested", &text_requested, NULL); + channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_slist_free); requests_satisfied_text = g_hash_table_lookup ( priv->queued_requests, text_chan); g_hash_table_steal (priv->queued_requests, text_chan); requests_satisfied_text = g_slist_reverse (requests_satisfied_text); - tubes_chan = g_hash_table_lookup (priv->text_needed_for_tubes, text_chan); - g_hash_table_remove (priv->text_needed_for_tubes, text_chan); - - if (tubes_chan != NULL) - { - requests_satisfied_tubes = g_hash_table_lookup ( - priv->queued_requests, tubes_chan); - g_hash_table_steal (priv->queued_requests, tubes_chan); - } - /* Announce tube channels now */ - /* FIXME: we should probably aggregate tube announcement with tubes and text - * ones in some cases. */ - tube_channels = g_hash_table_lookup (priv->tubes_needed_for_tube, - tubes_chan); - - tube_channels = g_slist_reverse (tube_channels); - for (l = tube_channels; l != NULL; l = g_slist_next (l)) + tube_channels = g_hash_table_lookup (priv->text_needed_for_tube, text_chan); + if (tube_channels != NULL) { - GabbleTubeIface *tube_chan = GABBLE_TUBE_IFACE (l->data); - GSList *requests_satisfied_tube; + GList *l; - requests_satisfied_tube = g_hash_table_lookup (priv->queued_requests, - tube_chan); - g_hash_table_steal (priv->queued_requests, tube_chan); - requests_satisfied_tube = g_slist_reverse (requests_satisfied_tube); + for (l = tube_channels->head; l != NULL; l = l->next) + { + GabbleTubeIface *tube_chan = GABBLE_TUBE_IFACE (l->data); + GSList *requests_satisfied_tube; - tp_channel_manager_emit_new_channel (fac, - TP_EXPORTABLE_CHANNEL (tube_chan), requests_satisfied_tube); + requests_satisfied_tube = g_hash_table_lookup ( + priv->queued_requests, tube_chan); + g_hash_table_steal (priv->queued_requests, tube_chan); + requests_satisfied_tube = g_slist_reverse (requests_satisfied_tube); + + g_hash_table_insert (channels, tube_chan, requests_satisfied_tube); + } - g_slist_free (requests_satisfied_tube); + g_hash_table_remove (priv->text_needed_for_tube, text_chan); } - if (tubes_chan == NULL || text_requested) + /* only announce channels which are on the bus (requested or + * requested with an invite, not channels only around because they + * have to be) */ + if (tp_base_channel_is_registered (base)) { - /* There is no tubes channel or the text channel has been explicitely - * requested. In both cases, the text channel has to be announced - * separately. */ - - /* announce text channel */ tp_channel_manager_emit_new_channel (fac, TP_EXPORTABLE_CHANNEL (text_chan), requests_satisfied_text); - - if (tubes_chan != NULL) - { - tp_channel_manager_emit_new_channel (fac, - TP_EXPORTABLE_CHANNEL (tubes_chan), requests_satisfied_tubes); - } } - else - { - /* Announce text and tubes text_chan together */ - GHashTable *channels; - - channels = g_hash_table_new (g_direct_hash, g_direct_equal); - g_hash_table_insert (channels, text_chan, requests_satisfied_text); - g_hash_table_insert (channels, tubes_chan, requests_satisfied_tubes); - tp_channel_manager_emit_new_channels (fac, channels); - - g_hash_table_unref (channels); - } + tp_channel_manager_emit_new_channels (fac, channels); - g_hash_table_remove (priv->tubes_needed_for_tube, tubes_chan); - g_slist_free (requests_satisfied_text); - g_slist_free (requests_satisfied_tubes); + g_hash_table_unref (channels); } static void @@ -351,7 +325,7 @@ muc_join_error_cb (GabbleMucChannel *chan, { GabbleMucFactory *fac = GABBLE_MUC_FACTORY (data); GabbleMucFactoryPrivate *priv = fac->priv; - GabbleTubesChannel *tubes_chan; + GQueue *tube_channels; GSList *requests_satisfied; GSList *iter; @@ -369,23 +343,32 @@ muc_join_error_cb (GabbleMucChannel *chan, g_slist_free (requests_satisfied); - tubes_chan = g_hash_table_lookup (priv->text_needed_for_tubes, chan); + /* tube channels */ + tube_channels = g_hash_table_lookup (priv->text_needed_for_tube, chan); - if (tubes_chan != NULL) + if (tube_channels != NULL) { - g_hash_table_remove (priv->text_needed_for_tubes, chan); + GList *l; - requests_satisfied = g_slist_reverse (g_hash_table_lookup ( - priv->queued_requests, tubes_chan)); - g_hash_table_steal (priv->queued_requests, tubes_chan); - - for (iter = requests_satisfied; iter != NULL; iter = iter->next) + for (l = tube_channels->head; l != NULL; l = l->next) { - tp_channel_manager_emit_request_failed (fac, iter->data, - error->domain, error->code, error->message); + GabbleTubeIface *tube_chan = GABBLE_TUBE_IFACE (l->data); + + requests_satisfied = g_hash_table_lookup ( + priv->queued_requests, tube_chan); + g_hash_table_steal (priv->queued_requests, tube_chan); + requests_satisfied = g_slist_reverse (requests_satisfied); + + for (iter = requests_satisfied; iter != NULL; iter = iter->next) + { + tp_channel_manager_emit_request_failed (fac, iter->data, + error->domain, error->code, error->message); + } + + g_slist_free (requests_satisfied); } - g_slist_free (requests_satisfied); + g_hash_table_remove (priv->text_needed_for_tube, chan); } } @@ -394,9 +377,23 @@ muc_sub_channel_closed_cb (TpSvcChannel *chan, gpointer user_data) { GabbleMucFactory *fac = GABBLE_MUC_FACTORY (user_data); + GabbleMucChannel *muc; tp_channel_manager_emit_channel_closed_for_object (fac, TP_EXPORTABLE_CHANNEL (chan)); + + /* GabbleTubeDBus, GabbleTubeStream, and GabbleMucCallChannel all + * have "muc" properties. */ + g_object_get (chan, + "muc", &muc, + NULL); + + if (muc == NULL) + return; + + if (gabble_muc_channel_can_be_closed (muc) + && gabble_muc_channel_get_autoclose (muc)) + tp_base_channel_close (TP_BASE_CHANNEL (muc)); } #ifdef ENABLE_VOIP @@ -420,19 +417,18 @@ muc_channel_new_call (GabbleMucChannel *muc, static void muc_channel_new_tube (GabbleMucChannel *channel, - GabbleTubesChannel *tube, + GabbleTubeIface *tube, gpointer user_data) { GabbleMucFactory *fac = GABBLE_MUC_FACTORY (user_data); - GabbleMucFactoryPrivate *priv = fac->priv; - /* If the muc channel is ready announce the tubes channel right away + /* If the muc channel is ready announce the tube channel right away * otherwise wait for the text channel to be ready */ if (_gabble_muc_channel_is_ready (channel)) tp_channel_manager_emit_new_channel (fac, - TP_EXPORTABLE_CHANNEL (tube), NULL); + TP_EXPORTABLE_CHANNEL (tube), NULL); else - g_hash_table_insert (priv->text_needed_for_tubes, channel, tube); + gabble_muc_factory_associate_tube (fac, channel, tube); g_signal_connect (tube, "closed", G_CALLBACK (muc_sub_channel_closed_cb), fac); @@ -448,6 +444,7 @@ new_muc_channel (GabbleMucFactory *fac, TpHandle inviter, const gchar *message, gboolean requested, + gboolean initially_register, GHashTable *initial_channels, GArray *initial_handles, char **initial_ids, @@ -497,6 +494,7 @@ new_muc_channel (GabbleMucFactory *fac, "initial-invitee-handles", initial_handles, "initial-invitee-ids", initial_ids, "room-name", room_name, + "initially-register", initially_register, NULL); g_signal_connect (chan, "closed", (GCallback) muc_channel_closed_cb, fac); @@ -523,8 +521,6 @@ new_muc_channel (GabbleMucFactory *fac, return chan; } -// tubes_channel_closed_cb - static void do_invite (GabbleMucFactory *fac, const gchar *room, @@ -548,15 +544,13 @@ do_invite (GabbleMucFactory *fac, if (g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (room_handle)) == NULL) { - new_muc_channel (fac, room_handle, TRUE, inviter_handle, reason, FALSE, - NULL, NULL, NULL, NULL); + new_muc_channel (fac, room_handle, TRUE, inviter_handle, reason, + FALSE, TRUE, NULL, NULL, NULL, NULL); } else { DEBUG ("ignoring invite to room \"%s\"; we're already there", room); } - - tp_handle_unref (room_repo, room_handle); } struct DiscoInviteData { @@ -584,8 +578,6 @@ obsolete_invite_disco_cb (GabbleDisco *self, GabbleMucFactory *fac = GABBLE_MUC_FACTORY (data->factory); GabbleMucFactoryPrivate *priv = fac->priv; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); WockyNode *identity; const char *category = NULL, *type = NULL; @@ -617,7 +609,6 @@ obsolete_invite_disco_cb (GabbleDisco *self, do_invite (fac, jid, data->inviter, data->reason); out: - tp_handle_unref (contact_repo, data->inviter); g_free (data->reason); g_slice_free (struct DiscoInviteData, data); } @@ -690,8 +681,6 @@ process_muc_invite (GabbleMucFactory *fac, do_invite (fac, room, inviter_handle, reason); g_free (room); - tp_handle_unref (contact_repo, inviter_handle); - return TRUE; } @@ -769,7 +758,6 @@ process_obsolete_invite (GabbleMucFactory *fac, { DEBUG ("obsolete MUC invite disco failed, freeing info"); - tp_handle_unref (contact_repo, inviter_handle); g_free (disco_udata->reason); g_slice_free (struct DiscoInviteData, disco_udata); } @@ -840,6 +828,25 @@ gabble_muc_factory_broadcast_presence (GabbleMucFactory *self) } static void +gabble_muc_factory_associate_tube (GabbleMucFactory *self, + GabbleMucChannel *gmuc, + GabbleTubeIface *tube) +{ + GabbleMucFactoryPrivate *priv = self->priv; + GQueue *queue; + + queue = g_hash_table_lookup (priv->text_needed_for_tube, gmuc); + + if (queue == NULL) + { + queue = g_queue_new (); + g_hash_table_insert (priv->text_needed_for_tube, gmuc, queue); + } + + g_queue_push_tail (queue, tube); +} + +static void gabble_muc_factory_associate_request (GabbleMucFactory *self, gpointer channel, gpointer request) @@ -869,7 +876,7 @@ cancel_queued_requests (gpointer k, for (iter = requests_satisfied; iter != NULL; iter = iter->next) { tp_channel_manager_emit_request_failed (self, - iter->data, TP_ERRORS, TP_ERROR_DISCONNECTED, + iter->data, TP_ERROR, TP_ERROR_DISCONNECTED, "Unable to complete this channel request, we're disconnecting!"); } @@ -898,12 +905,11 @@ gabble_muc_factory_close_all (GabbleMucFactory *self) cancel_queued_requests, self); tp_clear_pointer (&priv->queued_requests, g_hash_table_unref); - tp_clear_pointer (&priv->text_needed_for_tubes, g_hash_table_unref); - tp_clear_pointer (&priv->tubes_needed_for_tube, g_hash_table_unref); + tp_clear_pointer (&priv->text_needed_for_tube, g_hash_table_unref); /* Use a temporary variable because we don't want - * muc_channel_closed_cb or tubes_channel_closed_cb to remove the channel - * from the hash table a second time */ + * muc_channel_closed_cb remove the channel from the hash table a + * second time */ if (priv->text_channels != NULL) { GHashTable *tmp = priv->text_channels; @@ -976,39 +982,6 @@ gabble_muc_factory_constructor (GType type, guint n_props, return obj; } - -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); - GabbleMucChannel *gmuc = GABBLE_MUC_CHANNEL (value); - GabbleTubesChannel *tube = NULL; - - data->foreach (channel, data->user_data); - - g_object_get (gmuc, "tube", &tube, NULL); - - if (tube != NULL) - { - channel = TP_EXPORTABLE_CHANNEL (tube); - data->foreach (channel, data->user_data); - gabble_tubes_channel_foreach (tube, data->foreach, data->user_data); - g_object_unref (tube); - } - -#ifdef ENABLE_VOIP - g_list_foreach (gabble_muc_channel_get_call_channels (gmuc), - (GFunc) data->foreach, data->user_data); -#endif -} - static void gabble_muc_factory_foreach_channel (TpChannelManager *manager, TpExportableChannelFunc foreach, @@ -1016,14 +989,24 @@ gabble_muc_factory_foreach_channel (TpChannelManager *manager, { GabbleMucFactory *fac = GABBLE_MUC_FACTORY (manager); GabbleMucFactoryPrivate *priv = fac->priv; - 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)) + { + GabbleMucChannel *gmuc = GABBLE_MUC_CHANNEL (value); - g_hash_table_foreach (priv->text_channels, _foreach_slave, &data); -} + foreach (TP_EXPORTABLE_CHANNEL (gmuc), user_data); + + gabble_muc_channel_foreach_tubes (gmuc, foreach, user_data); +#ifdef ENABLE_VOIP + g_list_foreach (gabble_muc_channel_get_call_channels (gmuc), + (GFunc) foreach, user_data); +#endif + } +} /** * ensure_muc_channel: @@ -1039,6 +1022,7 @@ ensure_muc_channel (GabbleMucFactory *fac, TpHandle handle, GabbleMucChannel **ret, gboolean requested, + gboolean export_text, GHashTable *initial_channels, GArray *initial_handles, char **initial_ids, @@ -1050,9 +1034,16 @@ ensure_muc_channel (GabbleMucFactory *fac, if (*ret == NULL) { - *ret = new_muc_channel (fac, handle, FALSE, base_conn->self_handle, NULL, - requested, initial_channels, initial_handles, initial_ids, room_name); - return FALSE; + *ret = new_muc_channel (fac, handle, FALSE, base_conn->self_handle, + NULL, requested, export_text, initial_channels, + initial_handles, initial_ids, room_name); + + gabble_muc_channel_set_autoclose (*ret, !export_text); + } + else + { + if (export_text) + gabble_muc_channel_set_autoclose (*ret, FALSE); } if (_gabble_muc_channel_is_ready (*ret)) @@ -1073,26 +1064,30 @@ gabble_muc_factory_handle_si_stream_request (GabbleMucFactory *self, TpHandleRepoIface *room_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_ROOM); GabbleMucChannel *gmuc = NULL; - GabbleTubesChannel *tube = NULL; + WockyStanzaType stanza_type; + WockyStanzaSubType sub_type; g_return_if_fail (tp_handle_is_valid (room_repo, room_handle, NULL)); + wocky_stanza_get_type_info (msg, &stanza_type, &sub_type); + g_return_if_fail (stanza_type == WOCKY_STANZA_TYPE_IQ); + g_return_if_fail (sub_type == WOCKY_STANZA_SUB_TYPE_SET); + gmuc = g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (room_handle)); - g_object_get (gmuc, "tube", &tube, NULL); - if (tube == NULL) + if (gmuc == NULL) { GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - "No tubes channel available for this MUC" }; + "No MUC channel available" }; - DEBUG ("tubes channel doesn't exist for muc %d", room_handle); + DEBUG ("MUC channel doesn't exist handle %d", room_handle); gabble_bytestream_iface_close (bytestream, &e); return; } - gabble_tubes_channel_bytestream_offered (tube, bytestream, msg); - g_object_unref (tube); + gabble_muc_channel_handle_si_stream_request ( + gmuc, bytestream, stream_id, msg); } GabbleMucChannel * @@ -1126,12 +1121,6 @@ static const gchar * const muc_channel_allowed_properties[] = { NULL }; -static const gchar * const muc_tubes_channel_allowed_properties[] = { - TP_PROP_CHANNEL_TARGET_HANDLE, - TP_PROP_CHANNEL_TARGET_ID, - NULL -}; - static void gabble_muc_factory_type_foreach_channel_class (GType type, TpChannelManagerTypeChannelClassFunc func, @@ -1156,11 +1145,6 @@ gabble_muc_factory_type_foreach_channel_class (GType type, func (type, table, muc_channel_allowed_properties, user_data); - /* 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); - /* Muc Channel.Type.StreamTube */ g_value_set_static_string (channel_type_value, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE); @@ -1185,31 +1169,6 @@ gabble_muc_factory_type_foreach_channel_class (GType type, g_hash_table_unref (table); } -/* return TRUE if the text_channel associated is ready */ -static gboolean -ensure_tubes_channel (GabbleMucFactory *self, - TpHandle handle, - GabbleTubesChannel **tubes_chan, - gboolean requested) -{ - GabbleMucFactoryPrivate *priv = self->priv; - TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn; - GabbleMucChannel *text_chan; - TpHandle initiator = base_conn->self_handle; - gboolean result; - - result = ensure_muc_channel (self, priv, handle, &text_chan, FALSE, - NULL, NULL, NULL, NULL); - - /* this refs the tube channel object */ - *tubes_chan = gabble_muc_channel_open_tube (text_chan, initiator, requested); - - if (!result) - g_hash_table_insert (priv->text_needed_for_tubes, text_chan, *tubes_chan); - - return result; -} - static gboolean handle_text_channel_request (GabbleMucFactory *self, gpointer request_token, @@ -1222,7 +1181,7 @@ handle_text_channel_request (GabbleMucFactory *self, TpBaseConnection *conn = TP_BASE_CONNECTION (priv->conn); GabbleMucChannel *text_chan; TpHandleSet *handles; - TpIntSet *continue_handles; + TpIntset *continue_handles; guint i; gboolean ret = TRUE; @@ -1276,7 +1235,7 @@ handle_text_channel_request (GabbleMucFactory *self, const char *object_path = g_ptr_array_index (initial_channels, i); GObject *object; TpHandle handle; - GabbleConnection *connection; + TpBaseConnection *connection; object = dbus_g_connection_lookup_g_object (bus, object_path); @@ -1287,19 +1246,19 @@ handle_text_channel_request (GabbleMucFactory *self, continue; } - g_object_get (object, - "connection", &connection, - "handle", &handle, - NULL); - g_object_unref (connection); /* drop the ref immediately */ + connection = tp_base_channel_get_connection ( + TP_BASE_CHANNEL (object)); - if (connection != priv->conn) + if ((GabbleConnection *) connection != priv->conn) { DEBUG ("Channel %s is from a different Connection, ignoring", object_path); continue; } + handle = tp_base_channel_get_target_handle ( + TP_BASE_CHANNEL (object)); + tp_handle_set_add (handles, handle); tp_intset_add (continue_handles, handle); g_hash_table_insert (final_channels, (char *) object_path, NULL); @@ -1340,7 +1299,6 @@ handle_text_channel_request (GabbleMucFactory *self, } tp_handle_set_add (handles, handle); - tp_handle_unref (contact_handles, handle); } } @@ -1415,11 +1373,6 @@ handle_text_channel_request (GabbleMucFactory *self, goto out; } } - else - { - /* ref room here so we can unref it again, below */ - tp_handle_ref (room_handles, room); - } /* Make sure TargetID and RoomName don't conflict. */ if (room_name != NULL && room_name[0] != '\0') @@ -1436,7 +1389,7 @@ handle_text_channel_request (GabbleMucFactory *self, if (!ok) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "TargetID's node part (%s) doesn't match RoomName (%s)", target_room, room_name); ret = FALSE; @@ -1466,7 +1419,7 @@ handle_text_channel_request (GabbleMucFactory *self, if (!ok) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "TargetID's domain part (%s) doesn't match Server (%s)", target_server, server_prop); ret = FALSE; @@ -1479,14 +1432,15 @@ handle_text_channel_request (GabbleMucFactory *self, } - if (ensure_muc_channel (self, priv, room, &text_chan, TRUE, + if (ensure_muc_channel (self, priv, room, &text_chan, TRUE, TRUE, final_channels, final_handles, final_ids, room_name)) { /* channel exists */ - if (require_new) + if (require_new + && tp_base_channel_is_registered (TP_BASE_CHANNEL (text_chan))) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "That channel has already been created (or requested)"); ret = FALSE; } @@ -1496,15 +1450,30 @@ handle_text_channel_request (GabbleMucFactory *self, initial_handles != NULL || initial_ids != NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Cannot set InitialChannels, InitialInviteeHandles or " "InitialInviteIDs for existing channel"); ret = FALSE; } 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 + { + GSList *tokens; + + tp_base_channel_register (TP_BASE_CHANNEL (text_chan)); + + tokens = g_slist_append (NULL, request_token); + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (text_chan), tokens); + g_slist_free (tokens); + } + ret = TRUE; } } @@ -1543,9 +1512,6 @@ handle_text_channel_request (GabbleMucFactory *self, } out: - if (room != 0) - tp_handle_unref (room_handles, room); - g_hash_table_unref (final_channels); g_array_unref (final_handles); g_free (final_ids); @@ -1557,62 +1523,6 @@ out: } static gboolean -handle_tubes_channel_request (GabbleMucFactory *self, - gpointer request_token, - GHashTable *request_properties, - gboolean require_new, - TpHandle handle, - GError **error) -{ - GabbleMucFactoryPrivate *priv = self->priv; - GabbleTubesChannel *tube = NULL; - GabbleMucChannel *gmuc = NULL; - - if (tp_channel_manager_asv_has_unknown_properties (request_properties, - muc_tubes_channel_fixed_properties, - muc_tubes_channel_allowed_properties, - error)) - return FALSE; - - gmuc = g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (handle)); - - if (gmuc != NULL) - g_object_get (gmuc, "tube", &tube, NULL); - - if (tube != NULL) - { - if (require_new) - { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, - "That channel has already been created (or requested)"); - return FALSE; - } - else - { - tp_channel_manager_emit_request_already_satisfied (self, - request_token, TP_EXPORTABLE_CHANNEL (tube)); - } - } - else if (ensure_tubes_channel (self, handle, &tube, TRUE)) - { - GSList *list = NULL; - - list = g_slist_prepend (list, request_token); - tp_channel_manager_emit_new_channel (self, - TP_EXPORTABLE_CHANNEL (tube), list); - g_slist_free (list); - } - else - { - gabble_muc_factory_associate_request (self, tube, request_token); - } - - g_object_unref (tube); - - return TRUE; -} - -static gboolean handle_tube_channel_request (GabbleMucFactory *self, gpointer request_token, GHashTable *request_properties, @@ -1622,63 +1532,38 @@ handle_tube_channel_request (GabbleMucFactory *self, { GabbleMucFactoryPrivate *priv = self->priv; - gboolean can_announce_now = TRUE; - gboolean tubes_channel_created = FALSE; - GabbleTubesChannel *tube = NULL; + gboolean can_announce_now; GabbleMucChannel * gmuc; GabbleTubeIface *new_channel; gmuc = g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (handle)); - if (gmuc != NULL) - g_object_get (gmuc, "tube", &tube, NULL); + if (gmuc == NULL) + ensure_muc_channel (self, priv, handle, &gmuc, FALSE, FALSE, + NULL, NULL, NULL, NULL); - if (tube == NULL) - { - /* Need to create a tubes channel */ - if (!ensure_tubes_channel (self, handle, &tube, FALSE)) - { - /* We have to wait the tubes channel before announcing */ - can_announce_now = FALSE; - } - - tubes_channel_created = TRUE; - } + can_announce_now = _gabble_muc_channel_is_ready (gmuc); - g_assert (tube != NULL); + new_channel = gabble_muc_channel_tube_request (gmuc, request_token, + request_properties, TRUE); - new_channel = gabble_tubes_channel_tube_request (tube, - request_token, request_properties, TRUE); - g_assert (new_channel != NULL); + g_signal_connect (new_channel, "closed", + G_CALLBACK (muc_sub_channel_closed_cb), self); if (can_announce_now) { - GHashTable *channels; GSList *request_tokens; - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); - - if (tubes_channel_created) - g_hash_table_insert (channels, tube, NULL); - 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); + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (new_channel), request_tokens); - g_hash_table_unref (channels); g_slist_free (request_tokens); } else { - GSList *l; - - l = g_hash_table_lookup (priv->tubes_needed_for_tube, tube); - g_hash_table_steal (priv->tubes_needed_for_tube, tube); - - l = g_slist_prepend (l, new_channel); - g_hash_table_insert (priv->tubes_needed_for_tube, tube, l); + gabble_muc_factory_associate_tube (self, gmuc, new_channel); /* And now finally associate the new stream or dbus tube channel with * the request token so that when the muc channel is ready, the request @@ -1686,8 +1571,6 @@ handle_tube_channel_request (GabbleMucFactory *self, gabble_muc_factory_associate_request (self, new_channel, request_token); } - g_object_unref (tube); - return TRUE; } @@ -1712,7 +1595,7 @@ handle_stream_tube_channel_request (GabbleMucFactory *self, TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE); if (service == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Request does not contain the mandatory property '%s'", TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE); return FALSE; @@ -1743,7 +1626,7 @@ handle_dbus_tube_channel_request (GabbleMucFactory *self, TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME); if (service == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Request does not contain the mandatory property '%s'", TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME); return FALSE; @@ -1807,12 +1690,12 @@ handle_call_channel_request (GabbleMucFactory *self, if (!initial_audio && !initial_video) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Request didn't set either InitialAudio or InitialVideo"); return FALSE; } - ensure_muc_channel (self, priv, handle, &muc, FALSE, NULL, NULL, NULL, NULL); + ensure_muc_channel (self, priv, handle, &muc, FALSE, FALSE, NULL, NULL, NULL, NULL); call = gabble_muc_channel_get_call (muc); @@ -1820,7 +1703,7 @@ handle_call_channel_request (GabbleMucFactory *self, { if (require_new) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "There is already a call in this muc"); goto error; } @@ -1867,7 +1750,6 @@ typedef struct { static ChannelTypeHandler channel_type_handlers[] = { { TP_IFACE_CHANNEL_TYPE_TEXT, handle_text_channel_request }, - { TP_IFACE_CHANNEL_TYPE_TUBES, handle_tubes_channel_request }, { TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, handle_stream_tube_channel_request }, { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, handle_dbus_tube_channel_request }, #ifdef ENABLE_VOIP diff --git a/src/muc-tube-dbus.c b/src/muc-tube-dbus.c index 2aa61fc82..7c37e9edb 100644 --- a/src/muc-tube-dbus.c +++ b/src/muc-tube-dbus.c @@ -18,6 +18,7 @@ */ #include "config.h" + #include "muc-tube-dbus.h" G_DEFINE_TYPE (GabbleMucTubeDBus, gabble_muc_tube_dbus, diff --git a/src/muc-tube-stream.c b/src/muc-tube-stream.c index 3700c46f6..a50a94a69 100644 --- a/src/muc-tube-stream.c +++ b/src/muc-tube-stream.c @@ -18,6 +18,7 @@ */ #include "config.h" + #include "muc-tube-stream.h" G_DEFINE_TYPE (GabbleMucTubeStream, gabble_muc_tube_stream, diff --git a/src/namespaces.h b/src/namespaces.h index 13ae5dbb6..0d06d7d54 100644 --- a/src/namespaces.h +++ b/src/namespaces.h @@ -135,4 +135,8 @@ #define NS_TP_FT_METADATA_SERVICE "http://telepathy.freedesktop.org/xmpp/file-transfer-service" #define NS_TP_FT_METADATA "http://telepathy.freedesktop.org/xmpp/file-transfer-metadata" +/* This is used by WLM to convert Windows Live ID to XMPP jid. + * See http://msdn.microsoft.com/en-us/library/live/hh550849.aspx */ +#define NS_WLM_JID_LOOKUP "http://messenger.live.com/xmpp/jidlookup" + #endif /* __GABBLE_NAMESPACES__H__ */ diff --git a/src/olpc-activity.c b/src/olpc-activity.c index 1c5f7d3af..a5f34a581 100644 --- a/src/olpc-activity.c +++ b/src/olpc-activity.c @@ -18,6 +18,7 @@ */ #include "config.h" + #include "olpc-activity.h" #include <stdlib.h> @@ -64,26 +65,6 @@ gabble_olpc_activity_init (GabbleOlpcActivity *self) } static void -gabble_olpc_activity_dispose (GObject *object) -{ - GabbleOlpcActivity *self = GABBLE_OLPC_ACTIVITY (object); - GabbleOlpcActivityPrivate *priv = self->priv; - TpHandleRepoIface *room_repo; - - if (priv->dispose_has_run) - return; - - room_repo = tp_base_connection_get_handles ((TpBaseConnection *) priv->conn, - TP_HANDLE_TYPE_ROOM); - tp_handle_unref (room_repo, self->room); - - priv->dispose_has_run = TRUE; - - if (G_OBJECT_CLASS (gabble_olpc_activity_parent_class)->dispose) - G_OBJECT_CLASS (gabble_olpc_activity_parent_class)->dispose (object); -} - -static void gabble_olpc_activity_finalize (GObject *object) { GabbleOlpcActivity *self = GABBLE_OLPC_ACTIVITY (object); @@ -172,23 +153,14 @@ gabble_olpc_activity_constructor (GType type, { GObject *obj; GabbleOlpcActivity *self; - GabbleOlpcActivityPrivate *priv; - TpHandleRepoIface *room_repo; obj = G_OBJECT_CLASS (gabble_olpc_activity_parent_class)-> constructor (type, n_props, props); self = GABBLE_OLPC_ACTIVITY (obj); - priv = self->priv; - - room_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, - TP_HANDLE_TYPE_ROOM); g_assert (self->room != 0); - tp_handle_ref (room_repo, self->room); - DEBUG ("new activity %s (%d)", gabble_olpc_activity_get_room (self), self->room); @@ -209,7 +181,6 @@ gabble_olpc_activity_class_init ( g_type_class_add_private (gabble_olpc_activity_class, sizeof (GabbleOlpcActivityPrivate)); - object_class->dispose = gabble_olpc_activity_dispose; object_class->finalize = gabble_olpc_activity_finalize; param_spec = g_param_spec_object ( diff --git a/src/olpc-activity.h b/src/olpc-activity.h index 47101bd66..4c08df6cf 100644 --- a/src/olpc-activity.h +++ b/src/olpc-activity.h @@ -22,8 +22,7 @@ #include <glib-object.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/handle-repo.h> +#include <telepathy-glib/telepathy-glib.h> #include "connection.h" diff --git a/src/plugin-connection.c b/src/plugin-connection.c index 0d0d95e9f..dcbb74bc6 100644 --- a/src/plugin-connection.c +++ b/src/plugin-connection.c @@ -23,7 +23,7 @@ #include <glib-object.h> #include <gabble/types.h> -#include <telepathy-glib/errors.h> +#include <telepathy-glib/telepathy-glib.h> #include <debug.h> diff --git a/src/plugin-loader.c b/src/plugin-loader.c index dedc724ad..d308437ee 100644 --- a/src/plugin-loader.c +++ b/src/plugin-loader.c @@ -28,8 +28,7 @@ # include <gmodule.h> #endif -#include <telepathy-glib/errors.h> -#include <telepathy-glib/presence-mixin.h> +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_PLUGINS #include "debug.h" @@ -301,7 +300,7 @@ gabble_plugin_loader_create_sidecar ( } g_simple_async_report_error_in_idle (G_OBJECT (self), callback, user_data, - TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, "No plugin implements sidecar '%s'", + TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "No plugin implements sidecar '%s'", sidecar_interface); } diff --git a/src/plugin-loader.h b/src/plugin-loader.h index 15bce505e..985cccbc5 100644 --- a/src/plugin-loader.h +++ b/src/plugin-loader.h @@ -23,8 +23,7 @@ #include <glib-object.h> #include <gio/gio.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/presence-mixin.h> +#include <telepathy-glib/telepathy-glib.h> #include <wocky/wocky.h> #include "gabble/sidecar.h" diff --git a/src/plugin.c b/src/plugin.c index 2003d3e87..2ddd23ea6 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -22,9 +22,7 @@ #include "gabble/plugin.h" -#include <telepathy-glib/errors.h> -#include <telepathy-glib/presence-mixin.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_PLUGINS #include "debug.h" @@ -110,17 +108,17 @@ gabble_plugin_create_sidecar_async ( if (!gabble_plugin_implements_sidecar (plugin, sidecar_interface)) g_simple_async_report_error_in_idle (G_OBJECT (plugin), callback, - user_data, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Gabble is buggy: '%s' doesn't implement sidecar %s", iface->name, sidecar_interface); else if (iface->create_sidecar_async == NULL) g_simple_async_report_error_in_idle (G_OBJECT (plugin), callback, - user_data, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "'%s' is buggy: it claims to implement %s, but does not implement " "create_sidecar_async", iface->name, sidecar_interface); else if (iface->create_sidecar_finish == NULL) g_simple_async_report_error_in_idle (G_OBJECT (plugin), callback, - user_data, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "'%s' is buggy: does not imlement create_sidecar_finish", iface->name); else diff --git a/src/presence-cache.c b/src/presence-cache.c index 72901a057..26118a48b 100644 --- a/src/presence-cache.c +++ b/src/presence-cache.c @@ -35,8 +35,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE #include <dbus/dbus-glib.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/intset.h> +#include <telepathy-glib/telepathy-glib.h> #include <wocky/wocky.h> #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE @@ -147,7 +146,6 @@ disco_waiter_new (TpHandleRepoIface *repo, DiscoWaiter *waiter; g_assert (repo); - tp_handle_ref (repo, handle); waiter = g_slice_new0 (DiscoWaiter); waiter->repo = repo; @@ -171,8 +169,6 @@ disco_waiter_free (DiscoWaiter *waiter) DEBUG ("freeing waiter %p for handle %u with serial %u", waiter, waiter->handle, waiter->serial); - tp_handle_unref (waiter->repo, waiter->handle); - g_free (waiter->resource); g_free (waiter->hash); g_free (waiter->ver); @@ -501,49 +497,9 @@ static void gabble_presence_cache_add_bundle_caps (GabblePresenceCache *cache, static void gabble_presence_cache_add_bundles (GabblePresenceCache *cache) { -#define GOOGLE_BUNDLE(cap, features) \ - gabble_presence_cache_add_bundle_caps (cache, \ - "http://www.google.com/xmpp/client/caps#" cap, features); \ - gabble_presence_cache_add_bundle_caps (cache, \ - "http://talk.google.com/xmpp/client/caps#" cap, features); \ - gabble_presence_cache_add_bundle_caps (cache, \ - "http://www.android.com/gtalk/client/caps#" cap, features); \ - gabble_presence_cache_add_bundle_caps (cache, \ - "http://www.android.com/gtalk/client/caps2#" cap, features); \ - gabble_presence_cache_add_bundle_caps (cache, \ - "http://talk.google.com/xmpp/bot/caps#" cap, features); - - /* Cache various bundle from the Google Talk clients as trusted. Some old - * versions of Google Talk do not reply correctly to discovery requests. - * Plus, we know what Google's bundles mean, so it's a waste of time to disco - * them, particularly the ones for features we don't support. The desktop - * client doesn't currently have all of these, but it doesn't hurt to cache - * them anyway. - */ - GOOGLE_BUNDLE ("voice-v1", NS_GOOGLE_FEAT_VOICE); - GOOGLE_BUNDLE ("video-v1", NS_GOOGLE_FEAT_VIDEO); - GOOGLE_BUNDLE ("camera-v1", NS_GOOGLE_FEAT_CAMERA); - - /* File transfer support */ - GOOGLE_BUNDLE ("share-v1", NS_GOOGLE_FEAT_SHARE); - - /* Not really sure what this ones is. */ - GOOGLE_BUNDLE ("sms-v1", NULL); - - /* TODO: remove this when we fix fd.o#22768. */ - GOOGLE_BUNDLE ("pmuc-v1", NULL); - - /* The camera-v1 bundle seems to mean "I have a camera plugged in". Not - * having it doesn't seem to affect anything, and we have no way of exposing - * that information anyway. - */ - GOOGLE_BUNDLE ("camera-v1", NULL); - -#undef GOOGLE_BUNDLE - - /* We should also cache the ext='' bundles Gabble advertises: older Gabbles - * advertise these and don't support hashed caps, and we shouldn't need to - * disco them. + /* We cache the ext='' bundles Gabble advertises: older Gabbles + * advertise these and don't support hashed caps, and we shouldn't + * need to disco them. */ gabble_presence_cache_add_bundle_caps (cache, NS_GABBLE_CAPS "#" BUNDLE_VOICE_V1, NS_GOOGLE_FEAT_VOICE); @@ -970,9 +926,10 @@ static GSList * _parse_cap_bundles ( WockyNode *lm_node, const gchar **hash, - const gchar **ver) + const gchar **ver, + const gchar **node) { - const gchar *node, *ext; + const gchar *ext; GSList *uris = NULL; WockyNode *cap_node; @@ -986,15 +943,15 @@ _parse_cap_bundles ( *hash = wocky_node_get_attribute (cap_node, "hash"); - node = wocky_node_get_attribute (cap_node, "node"); + *node = wocky_node_get_attribute (cap_node, "node"); - if (NULL == node) + if (NULL == *node) return NULL; *ver = wocky_node_get_attribute (cap_node, "ver"); if (NULL != *ver) - uris = g_slist_prepend (uris, g_strdup_printf ("%s#%s", node, *ver)); + uris = g_slist_prepend (uris, g_strdup (*ver)); /* If there is a hash, the remote contact uses XEP-0115 v1.5 and the 'ext' * attribute MUST be ignored. */ @@ -1010,7 +967,7 @@ _parse_cap_bundles ( exts = g_strsplit (ext, " ", 0); for (i = exts; NULL != *i; i++) - uris = g_slist_prepend (uris, g_strdup_printf ("%s#%s", node, *i)); + uris = g_slist_prepend (uris, g_strdup (*i)); g_strfreev (exts); } @@ -1365,7 +1322,7 @@ _caps_disco_cb (GabbleDisco *disco, if (NULL == waiter_self) { DEBUG ("Ignoring non requested disco reply from %s", jid); - goto OUT; + return; } /* Now onto caps */ @@ -1507,16 +1464,51 @@ _caps_disco_cb (GabbleDisco *disco, gabble_capability_set_free (cap_set); g_ptr_array_unref (data_forms); +} + +static gboolean +get_google_cap (const gchar *fragment, + const gchar **ns) +{ + if (!tp_strdiff (fragment, "voice-v1")) + { + *ns = NS_GOOGLE_FEAT_VOICE; + return TRUE; + } + else if (!tp_strdiff (fragment, "video-v1")) + { + *ns = NS_GOOGLE_FEAT_VIDEO; + return TRUE; + } + else if (!tp_strdiff (fragment, "share-v1")) + { + *ns = NS_GOOGLE_FEAT_SHARE; + return TRUE; + } + else if (!tp_strdiff (fragment, "sms-v1")) + { + *ns = NULL; + return TRUE; + } + else if (!tp_strdiff (fragment, "pmuc-v1")) + { + *ns = NULL; + return TRUE; + } + else if (!tp_strdiff (fragment, "camera-v1")) + { + *ns = NULL; + return TRUE; + } -OUT: - if (handle) - tp_handle_unref (contact_repo, handle); + return FALSE; } static void _process_caps_uri (GabblePresenceCache *cache, const gchar *from, - const gchar *uri, + const gchar *node, + const gchar *fragment, const gchar *hash, const gchar *ver, TpHandle handle, @@ -1529,6 +1521,8 @@ _process_caps_uri (GabblePresenceCache *cache, GabblePresenceCachePrivate *priv; TpHandleRepoIface *contact_repo; WockyCapsCache *caps_cache; + gchar *uri = g_strdup_printf ("%s#%s", node, fragment); + const gchar *ns = NULL; priv = cache->priv; contact_repo = tp_base_connection_get_handles ( @@ -1596,6 +1590,34 @@ _process_caps_uri (GabblePresenceCache *cache, if (cached_caps != NULL) gabble_capability_set_free (cached_caps); } + else if (hash == NULL && get_google_cap (fragment, &ns)) + { + /* if the hash is NULL then are looking at the ext='...' values, + * so this is starting to smell like Google */ + GabblePresence *presence = gabble_presence_cache_get (cache, handle); + + /* we already know about this fragment; apply the known value to + * the (handle, resource) */ + DEBUG ("we know about fragment %s, setting caps for %u (%s)", fragment, handle, + from); + + if (presence != NULL) + { + GabbleCapabilitySet *cap_set = gabble_capability_set_new (); + + if (ns != NULL) + gabble_capability_set_add (cap_set, ns); + + gabble_presence_set_capabilities ( + presence, resource, cap_set, NULL, serial); + + gabble_capability_set_free (cap_set); + } + else + { + DEBUG ("presence not found"); + } + } else { GSList *waiters; @@ -1661,6 +1683,8 @@ _process_caps_uri (GabblePresenceCache *cache, out: if (cached_query_reply != NULL) g_object_unref (cached_query_reply); + + g_free (uri); } static void @@ -1672,10 +1696,11 @@ _process_caps (GabblePresenceCache *cache, { const gchar *resource; GSList *uris, *i; + GabblePresenceCachePrivate *priv; GabbleCapabilitySet *old_cap_set = NULL; guint serial; - const gchar *hash, *ver; + const gchar *hash, *ver, *node; priv = cache->priv; serial = priv->caps_serial++; @@ -1684,7 +1709,7 @@ _process_caps (GabblePresenceCache *cache, if (resource != NULL) resource++; - uris = _parse_cap_bundles (lm_node, &hash, &ver); + uris = _parse_cap_bundles (lm_node, &hash, &ver, &node); if (presence) { @@ -1706,7 +1731,7 @@ _process_caps (GabblePresenceCache *cache, */ for (i = uris; NULL != i; i = i->next) { - _process_caps_uri (cache, from, (gchar *) i->data, hash, ver, handle, + _process_caps_uri (cache, from, node, (gchar *) i->data, hash, ver, handle, resource, serial); g_free (i->data); diff --git a/src/presence-cache.h b/src/presence-cache.h index 8c765517f..55023447f 100644 --- a/src/presence-cache.h +++ b/src/presence-cache.h @@ -68,7 +68,7 @@ struct _GabbleCapabilityInfo /* array of WockyDataForm or NULL */ GPtrArray *data_forms; - TpIntSet *guys; + TpIntset *guys; guint trust; /* bitfield of GabbleClientType flags */ diff --git a/src/presence.c b/src/presence.c index 704834ca2..db9830c6e 100644 --- a/src/presence.c +++ b/src/presence.c @@ -22,7 +22,7 @@ #include "presence.h" #include <string.h> -#include <telepathy-glib/channel-manager.h> +#include <telepathy-glib/telepathy-glib.h> #include <wocky/wocky.h> #include "gabble/capabilities.h" diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c index ea418f262..6929f11d5 100644 --- a/src/private-tubes-factory.c +++ b/src/private-tubes-factory.c @@ -25,17 +25,15 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/util.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "extensions/extensions.h" #define DEBUG_FLAG GABBLE_DEBUG_TUBES +#include "bytestream-factory.h" #include "gabble/caps-channel-manager.h" #include "connection.h" #include "debug.h" @@ -43,18 +41,18 @@ #include "muc-factory.h" #include "namespaces.h" #include "presence-cache.h" -#include "tubes-channel.h" #include "tube-dbus.h" #include "tube-stream.h" #include "util.h" -static GabbleTubesChannel *new_tubes_channel (GabblePrivateTubesFactory *fac, - TpHandle handle, TpHandle initiator, gpointer request_token, - gboolean send_new_channel_signal); +static GabbleTubeIface * new_channel_from_stanza (GabblePrivateTubesFactory *self, + WockyStanza *stanza, WockyNode *tube_node, guint64 tube_id, + GabbleBytestreamIface *bytestream); -static void tubes_channel_closed_cb (GabbleTubesChannel *chan, +static gboolean private_tubes_factory_tube_close_cb ( + WockyPorter *porter, + WockyStanza *msg, gpointer user_data); - static gboolean private_tubes_factory_msg_tube_cb ( WockyPorter *porter, WockyStanza *msg, @@ -85,7 +83,8 @@ struct _GabblePrivateTubesFactoryPrivate guint msg_tube_cb; guint msg_close_cb; - GHashTable *tubes_channels; + /* guint tube ID => (owned) (GabbleTubeIface *) */ + GHashTable *tubes; gboolean dispose_has_run; }; @@ -104,6 +103,97 @@ static const gchar * const old_tubes_channel_allowed_properties[] = { NULL }; +gboolean +gabble_private_tubes_factory_extract_tube_information ( + TpHandleRepoIface *contact_repo, + WockyNode *tube_node, + TpTubeType *type, + TpHandle *initiator_handle, + const gchar **service, + GHashTable **parameters, + guint64 *tube_id) +{ + 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, + GUINT_TO_POINTER (GABBLE_JID_ROOM_MEMBER), NULL); + + if (*initiator_handle == 0) + { + DEBUG ("invalid initiator JID %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 = lm_message_node_extract_properties (node, "parameter"); + } + + if (tube_id != NULL) + { + const gchar *str; + guint64 tmp; + + str = wocky_node_get_attribute (tube_node, "id"); + if (str == NULL) + { + DEBUG ("no tube id in SI request"); + return FALSE; + } + + tmp = g_ascii_strtoull (str, NULL, 10); + if (tmp == 0 || tmp > G_MAXUINT32) + { + DEBUG ("tube id is non-numeric or out of range: %s", str); + return FALSE; + } + *tube_id = tmp; + } + + return TRUE; +} + static void gabble_private_tubes_factory_init (GabblePrivateTubesFactory *self) { @@ -112,8 +202,8 @@ gabble_private_tubes_factory_init (GabblePrivateTubesFactory *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); priv->conn = NULL; priv->dispose_has_run = FALSE; @@ -141,7 +231,7 @@ porter_available_cb ( priv->msg_close_cb = wocky_porter_register_handler_from_anyone (porter, WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, WOCKY_PORTER_HANDLER_PRIORITY_MAX, - private_tubes_factory_msg_tube_cb, self, + private_tubes_factory_tube_close_cb, self, '(', "close", ':', NS_TUBES, ')', NULL); } @@ -199,7 +289,7 @@ gabble_private_tubes_factory_dispose (GObject *object) priv->dispose_has_run = TRUE; gabble_private_tubes_factory_close_all (fac); - g_assert (priv->tubes_channels == NULL); + g_assert (priv->tubes == NULL); if (G_OBJECT_CLASS (gabble_private_tubes_factory_parent_class)->dispose) G_OBJECT_CLASS (gabble_private_tubes_factory_parent_class)->dispose ( @@ -275,99 +365,6 @@ gabble_private_tubes_factory_class_init ( } - -/** - * tubes_channel_closed_cb: - * - * Signal callback for when an Tubes channel is closed. Removes the references - * that PrivateTubesFactory holds to them. - */ -static void -tubes_channel_closed_cb (GabbleTubesChannel *chan, - gpointer user_data) -{ - GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (user_data); - GabblePrivateTubesFactoryPrivate *priv = - GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); - TpHandle contact_handle; - - if (priv->tubes_channels == NULL) - return; - - g_object_get (chan, "handle", &contact_handle, NULL); - - tp_channel_manager_emit_channel_closed_for_object (self, - TP_EXPORTABLE_CHANNEL (chan)); - - 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 GabbleTubes object associated with the given parameters - */ -static GabbleTubesChannel * -new_tubes_channel (GabblePrivateTubesFactory *fac, - TpHandle handle, - TpHandle initiator, - gpointer request_token, - gboolean send_new_channel_signal) -{ - GabblePrivateTubesFactoryPrivate *priv; - TpBaseConnection *conn; - GabbleTubesChannel *chan; - char *object_path; - gboolean requested; - - g_assert (GABBLE_IS_PRIVATE_TUBES_FACTORY (fac)); - g_assert (handle != 0); - g_assert (initiator != 0); - - priv = GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (fac); - conn = (TpBaseConnection *) priv->conn; - - object_path = g_strdup_printf ("%s/SITubesChannel%u", conn->object_path, - handle); - - requested = (request_token != NULL); - - chan = g_object_new (GABBLE_TYPE_TUBES_CHANNEL, - "connection", priv->conn, - "object-path", object_path, - "handle", handle, - "handle-type", TP_HANDLE_TYPE_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_free (object_path); - - if (send_new_channel_signal) - { - GSList *request_tokens; - if (request_token != NULL) - request_tokens = g_slist_prepend (NULL, request_token); - else - request_tokens = NULL; - - tp_channel_manager_emit_new_channel (fac, - TP_EXPORTABLE_CHANNEL (chan), request_tokens); - - g_slist_free (request_tokens); - } - - return chan; -} - static void gabble_private_tubes_factory_close_all (GabblePrivateTubesFactory *fac) { @@ -393,10 +390,7 @@ gabble_private_tubes_factory_close_all (GabblePrivateTubesFactory *fac) priv->msg_close_cb = 0; } - /* Use a temporary variable (the macro does this) because we don't want - * tubes_channel_closed_cb to remove the channel from the hash table a - * second time */ - tp_clear_pointer (&priv->tubes_channels, g_hash_table_unref); + tp_clear_pointer (&priv->tubes, g_hash_table_unref); } static void @@ -658,16 +652,10 @@ _foreach_slave (gpointer key, gpointer value, gpointer user_data) { - struct _ForeachData *data = (struct _ForeachData *) user_data; + struct _ForeachData *data = user_data; TpExportableChannel *chan = TP_EXPORTABLE_CHANNEL (value); - /* Add channels of type Channel.Type.Tubes */ data->foreach (chan, data->user_data); - - /* Add channels of type Channel.Type.{Stream|DBus}Tube which live in the - * GabbleTubesChannel object */ - gabble_tubes_channel_foreach (GABBLE_TUBES_CHANNEL (chan), data->foreach, - data->user_data); } static void @@ -683,7 +671,7 @@ gabble_private_tubes_factory_foreach_channel (TpChannelManager *manager, data.user_data = user_data; data.foreach = foreach; - g_hash_table_foreach (priv->tubes_channels, _foreach_slave, &data); + g_hash_table_foreach (priv->tubes, _foreach_slave, &data); } void @@ -694,25 +682,54 @@ gabble_private_tubes_factory_handle_si_tube_request ( const gchar *stream_id, WockyStanza *msg) { - GabblePrivateTubesFactoryPrivate *priv = - GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + GabblePrivateTubesFactoryPrivate *priv = self->priv; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - GabbleTubesChannel *chan; + WockyNode *si_node, *tube_node; + WockyStanzaType stanza_type; + WockyStanzaSubType sub_type; + guint64 tube_id; + GabbleTubeIface *tube; DEBUG ("contact#%u stream %s", handle, stream_id); g_return_if_fail (tp_handle_is_valid (contact_repo, handle, NULL)); - chan = g_hash_table_lookup (priv->tubes_channels, GUINT_TO_POINTER (handle)); - if (chan == NULL) + wocky_stanza_get_type_info (msg, &stanza_type, &sub_type); + g_return_if_fail (stanza_type == WOCKY_STANZA_TYPE_IQ); + g_return_if_fail (sub_type == WOCKY_STANZA_SUB_TYPE_SET); + si_node = wocky_node_get_child_ns ( + wocky_stanza_get_top_node (msg), "si", NS_SI); + g_return_if_fail (si_node != NULL); + tube_node = wocky_node_get_child_ns (si_node, "tube", + NS_TUBES); + g_return_if_fail (tube_node != NULL); + + if (!gabble_private_tubes_factory_extract_tube_information ( + contact_repo, tube_node, NULL, NULL, + NULL, NULL, &tube_id)) { - chan = new_tubes_channel (self, handle, handle, NULL, TRUE); + GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, + "<tube> has no id attribute" }; - /* FIXME: Should we close the channel if the request is not properly - * handled by the newly created channel ? */ + NODE_DEBUG (tube_node, e.message); + gabble_bytestream_iface_close (bytestream, &e); + return; } - gabble_tubes_channel_tube_si_offered (chan, bytestream, msg); + 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 ID already in use" }; + + NODE_DEBUG (tube_node, e.message); + gabble_bytestream_iface_close (bytestream, &e); + return; + } + + /* New tube */ + tube = new_channel_from_stanza (self, msg, tube_node, + tube_id, bytestream); } void @@ -726,48 +743,82 @@ gabble_private_tubes_factory_handle_si_stream_request ( GabblePrivateTubesFactoryPrivate *priv = GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - GabbleTubesChannel *chan; + (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); + const gchar *tmp; + guint64 tube_id; + WockyNode *si_node, *stream_node; + GabbleTubeIface *tube; + WockyStanzaType stanza_type; + WockyStanzaSubType sub_type; DEBUG ("contact#%u stream %s", handle, stream_id); g_return_if_fail (tp_handle_is_valid (contact_repo, handle, NULL)); - chan = g_hash_table_lookup (priv->tubes_channels, GUINT_TO_POINTER (handle)); - if (chan == NULL) + wocky_stanza_get_type_info (msg, &stanza_type, &sub_type); + g_return_if_fail (stanza_type == WOCKY_STANZA_TYPE_IQ); + g_return_if_fail (sub_type == WOCKY_STANZA_SUB_TYPE_SET); + + si_node = wocky_node_get_child_ns ( + wocky_stanza_get_top_node (msg), "si", NS_SI); + g_return_if_fail (si_node != NULL); + + stream_node = wocky_node_get_child_ns (si_node, + "stream", NS_TUBES); + g_return_if_fail (stream_node != NULL); + + tmp = wocky_node_get_attribute (stream_node, "tube"); + if (tmp == NULL) { GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - "No tubes channel available for this contact" }; + "<stream> has no tube attribute" }; - DEBUG ("tubes channel with contact %d doesn't exist", handle); + NODE_DEBUG (stream_node, e.message); gabble_bytestream_iface_close (bytestream, &e); return; } + 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, + "<stream> tube ID attribute non-numeric or out of range" }; - gabble_tubes_channel_bytestream_offered (chan, bytestream, msg); + DEBUG ("tube id is non-numeric or out of range: %s", tmp); + gabble_bytestream_iface_close (bytestream, &e); + return; + } + + 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, + "<stream> tube attribute points to a nonexistent " + "tube" }; + + DEBUG ("tube %" G_GUINT64_FORMAT " doesn't exist", tube_id); + gabble_bytestream_iface_close (bytestream, &e); + return; + } + + DEBUG ("received new bytestream request for existing tube: %" G_GUINT64_FORMAT, + tube_id); + + gabble_tube_iface_add_bytestream (tube, bytestream); } static gboolean -private_tubes_factory_msg_tube_cb ( - WockyPorter *porter, +tube_msg_checks (GabblePrivateTubesFactory *self, WockyStanza *msg, - gpointer user_data) + WockyNode *node, + TpHandle *out_handle, + guint64 *out_tube_id) { - GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (user_data); GabblePrivateTubesFactoryPrivate *priv = GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - WockyNode *tube_node, *close_node; - GabbleTubesChannel *chan; - const gchar *from; + const gchar *from, *tmp; TpHandle handle; - - tube_node = wocky_node_get_child_ns ( - wocky_stanza_get_top_node (msg), "tube", NS_TUBES); - close_node = wocky_node_get_child_ns ( - wocky_stanza_get_top_node (msg), "close", NS_TUBES); - - g_return_val_if_fail (tube_node != NULL || close_node != NULL, FALSE); + guint64 tube_id; from = wocky_node_get_attribute ( wocky_stanza_get_top_node (msg), "from"); @@ -784,30 +835,392 @@ private_tubes_factory_msg_tube_cb ( return FALSE; } - /* Tube offer */ - chan = g_hash_table_lookup (priv->tubes_channels, GUINT_TO_POINTER (handle)); + tmp = wocky_node_get_attribute (node, "id"); + if (tmp == NULL) + { + DEBUG ("failed to get the tube ID"); + return FALSE; + } - if (chan == NULL) + tube_id = g_ascii_strtoull (tmp, NULL, 10); + if (tube_id == 0 || tube_id > G_MAXUINT32) { - if (tube_node != NULL) - { - /* We create the tubes channel only if the message is a new tube - * offer */ - chan = new_tubes_channel (self, handle, handle, NULL, TRUE); - } - else - { - DEBUG ("Ignore tube close message as there is no tubes channel" - " to handle it"); - return TRUE; - } + DEBUG ("tube ID is non-numeric or out of range: %s", tmp); + return FALSE; } - gabble_tubes_channel_tube_msg (chan, msg); + if (out_tube_id != NULL) + *out_tube_id = tube_id; + + if (out_handle != NULL) + *out_handle = handle; return TRUE; } +static gboolean +private_tubes_factory_msg_tube_cb ( + WockyPorter *porter, + WockyStanza *msg, + gpointer user_data) +{ + GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (user_data); + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + WockyNode *node; + guint64 tube_id; + GabbleTubeIface *channel; + TpHandle handle; + + node = wocky_node_get_child_ns ( + wocky_stanza_get_top_node (msg), "tube", NS_TUBES); + g_return_val_if_fail (node != NULL, FALSE); + + if (!tube_msg_checks (self, msg, node, &handle, &tube_id)) + return FALSE; + + channel = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); + + if (channel != NULL) + { + TpHandle tube_handle = 0; + + g_object_get (channel, + "handle", &tube_handle, + NULL); + + DEBUG ("tube ID already in use; do not open the offered tube and close " + "the existing tube if it's to the same contact"); + + /* only close the existing channel if it's the same contact + * otherwise contacts could force close unrelated tubes. */ + if (handle == tube_handle) + gabble_tube_iface_close (channel, FALSE); + + return TRUE; + } + + channel = new_channel_from_stanza (self, msg, node, tube_id, NULL); + + return TRUE; +} + +static gboolean +private_tubes_factory_tube_close_cb ( + WockyPorter *porter, + WockyStanza *msg, + gpointer user_data) +{ + GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (user_data); + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + WockyNode *node; + guint64 tube_id; + GabbleTubeIface *channel; + TpTubeType type; + + node = wocky_node_get_child_ns ( + wocky_stanza_get_top_node (msg), "close", NS_TUBES); + g_return_val_if_fail (node != NULL, FALSE); + + if (!tube_msg_checks (self, msg, node, NULL, &tube_id)) + return FALSE; + + channel = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); + + if (channel == NULL) + { + DEBUG ("<close> tube attribute points to a nonexistent tube"); + return TRUE; + } + + g_object_get (channel, "type", &type, NULL); + if (type != TP_TUBE_TYPE_STREAM) + { + DEBUG ("Only stream tubes can be closed using a close message"); + return TRUE; + } + + DEBUG ("tube %" G_GUINT64_FORMAT " was closed by remote peer", tube_id); + gabble_tube_iface_close (channel, TRUE); + + return TRUE; +} + +static GabbleTubeIface * +gabble_private_tubes_factory_lookup (GabblePrivateTubesFactory *self, + const gchar *type, + TpHandle handle, + const gchar *service) +{ + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + GHashTableIter iter; + gpointer value; + + g_hash_table_iter_init (&iter, priv->tubes); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + GabbleTubeIface *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 = TRUE; + + g_free (channel_type); + g_free (channel_service); + + if (match) + return tube; + } + + return NULL; +} + +static void +channel_closed_cb (GabbleTubeIface *tube, + GabblePrivateTubesFactory *self) +{ + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_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 guint64 +generate_tube_id (GabblePrivateTubesFactory *self) +{ + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + guint out; + + /* probably totally overkill */ + do + { + out = g_random_int_range (1, G_MAXINT32); + } + while (g_hash_table_lookup (priv->tubes, + GUINT_TO_POINTER (out)) != NULL); + + return out; +} + +/* Returns: (transfer none): new tube channel. the channel manager holds + * the ref to this channel, so don't unref it! */ +static GabbleTubeIface * +new_channel_from_request (GabblePrivateTubesFactory *self, + GHashTable *request) +{ + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + GabbleTubeIface *tube; + TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn); + + gchar *stream_id; + + TpHandle handle; + const gchar *ctype, *service; + TpHandleType handle_type; + GHashTable *parameters; + guint64 tube_id; + + 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 = GABBLE_TUBE_IFACE (gabble_tube_stream_new (priv->conn, + handle, handle_type, base_conn->self_handle, + base_conn->self_handle, service, parameters, + tube_id, NULL, TRUE)); + } + 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); + + stream_id = gabble_bytestream_factory_generate_stream_id (); + + tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (priv->conn, + handle, handle_type, base_conn->self_handle, + base_conn->self_handle, service, parameters, + stream_id, tube_id, NULL, NULL, TRUE)); + + g_free (stream_id); + } + 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 void +send_tube_close_msg (GabblePrivateTubesFactory *self, + const gchar *jid, + guint64 tube_id) +{ + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + WockyPorter *porter; + WockyStanza *msg; + gchar *id_str; + + id_str = g_strdup_printf ("%" G_GUINT64_FORMAT, tube_id); + + porter = gabble_connection_dup_porter (priv->conn); + + /* Send the close message */ + msg = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, + NULL, jid, + '(', "close", + ':', NS_TUBES, + '@', "tube", id_str, + ')', + GABBLE_AMP_DO_NOT_STORE_SPEC, + NULL); + g_free (id_str); + + wocky_porter_send (porter, msg); + + g_object_unref (porter); + g_object_unref (msg); +} + +/* Returns: (transfer none): new tube channel. the channel manager holds + * the ref to this channel, so don't unref it! */ +static GabbleTubeIface * +new_channel_from_stanza (GabblePrivateTubesFactory *self, + WockyStanza *stanza, + WockyNode *tube_node, + guint64 tube_id, + GabbleBytestreamIface *bytestream) +{ + GabblePrivateTubesFactoryPrivate *priv = + GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self); + GabbleTubeIface *tube; + TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn); + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( + (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); + + TpTubeType type; + TpHandle handle; + const gchar *service; + GHashTable *parameters; + + /* the validity of this has already been checked by wocky */ + handle = tp_handle_ensure (contact_repo, + wocky_stanza_get_from (stanza), NULL, NULL); + g_return_val_if_fail (handle != 0, NULL); + + if (!gabble_private_tubes_factory_extract_tube_information ( + contact_repo, tube_node, &type, NULL, + &service, ¶meters, NULL)) + { + DEBUG ("can't extract <tube> information from message"); + send_tube_close_msg (self, wocky_stanza_get_from (stanza), tube_id); + return NULL; + } + + if (bytestream == NULL && type != TP_TUBE_TYPE_STREAM) + { + DEBUG ("Only stream tubes are allowed to be created using messages"); + send_tube_close_msg (self, wocky_stanza_get_from (stanza), tube_id); + return NULL; + } + else if (bytestream != NULL && type != TP_TUBE_TYPE_DBUS) + { + GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_FORBIDDEN, + "Only D-Bus tubes are allowed to be created using SI" }; + + DEBUG ("%s", e.message); + gabble_bytestream_iface_close (bytestream, &e); + return NULL; + } + + if (type == TP_TUBE_TYPE_STREAM) + { + tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (priv->conn, + handle, TP_HANDLE_TYPE_CONTACT, base_conn->self_handle, + handle, service, parameters, tube_id, NULL, FALSE)); + } + else + { + WockyNode *si_node; + const gchar *stream_id; + + si_node = wocky_node_get_child_ns ( + wocky_stanza_get_top_node (stanza), "si", NS_SI); + g_return_val_if_fail (si_node != NULL, NULL); + + stream_id = wocky_node_get_attribute (si_node, "id"); + g_return_val_if_fail (stream_id != NULL, NULL); + + tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (priv->conn, + handle, TP_HANDLE_TYPE_CONTACT, base_conn->self_handle, + handle, service, parameters, + stream_id, tube_id, bytestream, NULL, FALSE)); + } + + 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); + + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (tube), NULL); + + return tube; +} + GabblePrivateTubesFactory * gabble_private_tubes_factory_new (GabbleConnection *conn) { @@ -827,24 +1240,6 @@ gabble_private_tubes_factory_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_PROP_CHANNEL_CHANNEL_TYPE, - 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_PROP_CHANNEL_TARGET_HANDLE_TYPE, - 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); @@ -895,7 +1290,8 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self, TpHandle handle; GError *error = NULL; const gchar *channel_type; - GabbleTubesChannel *channel; + GabbleTubeIface *channel; + const gchar *service = NULL; if (tp_asv_get_uint32 (request_properties, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) != TP_HANDLE_TYPE_CONTACT) @@ -904,25 +1300,14 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self, channel_type = tp_asv_get_string (request_properties, TP_PROP_CHANNEL_CHANNEL_TYPE); - 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 FALSE; - if (! tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES)) + 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, - old_tubes_channel_allowed_properties, - &error)) - goto error; - } - else if (! tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) - { - const gchar *service; - - if (tp_channel_manager_asv_has_unknown_properties (request_properties, - tubes_channel_fixed_properties, gabble_tube_stream_channel_get_allowed_properties (), &error)) goto error; @@ -932,7 +1317,7 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self, TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE); if (service == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Request does not contain the mandatory property '%s'", TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE); goto error; @@ -940,7 +1325,6 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self, } else if (! tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) { - const gchar *service; GError *err = NULL; if (tp_channel_manager_asv_has_unknown_properties (request_properties, @@ -954,7 +1338,7 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self, TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME); if (service == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Request does not contain the mandatory property '%s'", TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME); goto error; @@ -963,7 +1347,7 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self, if (!tp_dbus_check_valid_bus_name (service, TP_DBUS_NAME_TYPE_WELL_KNOWN, &err)) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Invalid ServiceName: %s", err->message); g_error_free (err); goto error; @@ -978,81 +1362,43 @@ gabble_private_tubes_factory_requestotron (GabblePrivateTubesFactory *self, /* Don't support opening a channel to our self handle */ if (handle == base_conn->self_handle) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Can't open a channel to your self handle"); goto error; } - channel = g_hash_table_lookup (self->priv->tubes_channels, - GUINT_TO_POINTER (handle)); + channel = gabble_private_tubes_factory_lookup (self, channel_type, + handle, service); - if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES)) + if (channel == NULL) { - if (channel == NULL) - { - new_tubes_channel (self, handle, base_conn->self_handle, - request_token, TRUE); - return TRUE; - } + GSList *request_tokens = NULL; + + channel = new_channel_from_request (self, request_properties); + if (request_token != NULL) + request_tokens = g_slist_prepend (NULL, request_token); + + tp_channel_manager_emit_new_channel (self, + TP_EXPORTABLE_CHANNEL (channel), request_tokens); + + g_slist_free (request_tokens); + } + else + { if (require_new) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, - "Tubes channel with contact #%u already exists", handle); - DEBUG ("Tubes channel with contact #%u already exists", - handle); + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, + "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 (channel)); - return TRUE; } - else - { - gboolean tubes_channel_already_existed = (channel != NULL); - GabbleTubeIface *new_channel; - - if (channel == NULL) - { - /* Don't give the request_token to new_tubes_channel() because we - * must emit NewChannels with 2 channels together */ - channel = new_tubes_channel (self, handle, base_conn->self_handle, - NULL, FALSE); - } - g_assert (channel != NULL); - - new_channel = gabble_tubes_channel_tube_request (channel, request_token, - request_properties, require_new); - if (new_channel != NULL) - { - GHashTable *channels; - GSList *request_tokens; - channels = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, NULL); - if (!tubes_channel_already_existed) - g_hash_table_insert (channels, channel, NULL); - - if (request_token != NULL) - request_tokens = g_slist_prepend (NULL, request_token); - else - request_tokens = NULL; - - g_hash_table_insert (channels, new_channel, request_tokens); - tp_channel_manager_emit_new_channels (self, channels); - - g_hash_table_unref (channels); - g_slist_free (request_tokens); - } - else - { - tp_channel_manager_emit_request_already_satisfied (self, - request_token, TP_EXPORTABLE_CHANNEL (channel)); - } - - return TRUE; - } + return TRUE; error: tp_channel_manager_emit_request_failed (self, request_token, diff --git a/src/private-tubes-factory.h b/src/private-tubes-factory.h index d9895199d..d9e01f17a 100644 --- a/src/private-tubes-factory.h +++ b/src/private-tubes-factory.h @@ -22,10 +22,10 @@ #include <glib-object.h> -#include <telepathy-glib/base-connection.h> +#include <telepathy-glib/telepathy-glib.h> + #include "connection.h" #include "bytestream-iface.h" -#include "tubes-channel.h" G_BEGIN_DECLS @@ -75,6 +75,12 @@ void gabble_private_tubes_factory_handle_si_stream_request ( GabblePrivateTubesFactory *fac, GabbleBytestreamIface *bytestream, TpHandle handle, const gchar *stream_id, WockyStanza *msg); +gboolean gabble_private_tubes_factory_extract_tube_information ( + TpHandleRepoIface *contact_repo, WockyNode *tube_node, + TpTubeType *type, TpHandle *initiator_handle, + const gchar **service, GHashTable **parameters, + guint64 *tube_id); + G_END_DECLS #endif /* #ifndef __PRIVATE_TUBES_FACTORY_H__ */ diff --git a/src/protocol.c b/src/protocol.c index a8bceb2ff..dda494fba 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -18,11 +18,13 @@ */ #include "config.h" + #include "protocol.h" #include <string.h> -#include <telepathy-glib/base-connection-manager.h> -#include <telepathy-glib/interfaces.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <dbus/dbus-protocol.h> #include <dbus/dbus-glib.h> diff --git a/src/protocol.h b/src/protocol.h index 30809df47..c013d9913 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -21,7 +21,7 @@ #define JABBER_PROTOCOL_H #include <glib-object.h> -#include <telepathy-glib/base-protocol.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/request-pipeline.c b/src/request-pipeline.c index 1bbfe4aa4..7b4eb5cc0 100644 --- a/src/request-pipeline.c +++ b/src/request-pipeline.c @@ -21,7 +21,7 @@ #include "config.h" #include "request-pipeline.h" -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> #define DEBUG_FLAG GABBLE_DEBUG_PIPELINE @@ -245,7 +245,7 @@ gabble_request_pipeline_flush (GabbleRequestPipeline *self, GSList **list) { GabbleRequestPipelineItem *item; - GError disconnected = { TP_ERRORS, TP_ERROR_DISCONNECTED, + GError disconnected = { TP_ERROR, TP_ERROR_DISCONNECTED, "Request failed because connection became disconnected" }; while (*list != NULL) diff --git a/src/room-config.c b/src/room-config.c index 47489058f..199545ad5 100644 --- a/src/room-config.c +++ b/src/room-config.c @@ -18,6 +18,7 @@ */ #include "config.h" + #include "room-config.h" #include "muc-channel.h" diff --git a/src/room-config.h b/src/room-config.h index a2981c186..ce5247201 100644 --- a/src/room-config.h +++ b/src/room-config.h @@ -21,7 +21,7 @@ #define GABBLE_ROOM_CONFIG_H #include <glib-object.h> -#include <telepathy-glib/base-room-config.h> +#include <telepathy-glib/telepathy-glib.h> typedef struct _GabbleRoomConfig GabbleRoomConfig; typedef struct _GabbleRoomConfigClass GabbleRoomConfigClass; diff --git a/src/roomlist-channel.c b/src/roomlist-channel.c index 642c983d1..d8e222e9a 100644 --- a/src/roomlist-channel.c +++ b/src/roomlist-channel.c @@ -24,14 +24,9 @@ #include <string.h> #include <dbus/dbus-glib.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-iface.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-generic.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_ROOMLIST @@ -415,7 +410,6 @@ room_info_cb (gpointer pipeline, GabbleDiscoItem *item, gpointer user_data) /* transfer the room handle ref to signalled_rooms */ tp_handle_set_add (priv->signalled_rooms, handle); - tp_handle_unref (room_handles, handle); g_value_init (&room, room_info_type); g_value_take_boxed (&room, diff --git a/src/roomlist-channel.h b/src/roomlist-channel.h index e86d6b028..5c74f3485 100644 --- a/src/roomlist-channel.h +++ b/src/roomlist-channel.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> #include "connection.h" diff --git a/src/roomlist-manager.c b/src/roomlist-manager.c index 6f8d499ea..ff2f37fef 100644 --- a/src/roomlist-manager.c +++ b/src/roomlist-manager.c @@ -25,10 +25,9 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_MUC @@ -329,7 +328,7 @@ gabble_roomlist_manager_handle_request (TpChannelManager *manager, if (tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandleType", NULL) != 0) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "RoomList channels can't have a target handle"); goto error; } @@ -349,7 +348,7 @@ gabble_roomlist_manager_handle_request (TpChannelManager *manager, if (server == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Unable to choose a default conference server"); goto error; } diff --git a/src/roster.c b/src/roster.c index 7bd6758f4..2ccab4d1b 100644 --- a/src/roster.c +++ b/src/roster.c @@ -25,9 +25,8 @@ #include <string.h> #include <dbus/dbus-glib.h> -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> #define DEBUG_FLAG GABBLE_DEBUG_ROSTER @@ -214,17 +213,6 @@ gabble_roster_dispose (GObject *object) } static void -item_handle_unref_foreach (gpointer key, gpointer data, gpointer user_data) -{ - TpHandle handle = GPOINTER_TO_UINT (key); - GabbleRosterPrivate *priv = (GabbleRosterPrivate *) user_data; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - - tp_handle_unref (contact_repo, handle); -} - -static void gabble_roster_finalize (GObject *object) { GabbleRoster *self = GABBLE_ROSTER (object); @@ -232,7 +220,6 @@ gabble_roster_finalize (GObject *object) DEBUG ("called with %p", object); - g_hash_table_foreach (priv->items, item_handle_unref_foreach, priv); g_hash_table_unref (priv->items); G_OBJECT_CLASS (gabble_roster_parent_class)->finalize (object); @@ -323,7 +310,6 @@ _parse_item_groups (WockyNode *item_node, TpBaseConnection *conn) if (!handle) continue; tp_handle_set_add (groups, handle); - tp_handle_unref (group_repo, handle); } return groups; @@ -459,7 +445,6 @@ _gabble_roster_item_ensure (GabbleRoster *roster, item->publish = TP_SUBSCRIPTION_STATE_NO; item->name = alias; item->groups = tp_handle_set_new (group_repo); - tp_handle_ref (contact_repo, handle); g_hash_table_insert (priv->items, GUINT_TO_POINTER (handle), item); } @@ -512,7 +497,6 @@ _gabble_roster_item_maybe_remove (GabbleRoster *roster, DEBUG ("removing contact#%u", handle); item = NULL; g_hash_table_remove (priv->items, GUINT_TO_POINTER (handle)); - tp_handle_unref (contact_repo, handle); return TRUE; } @@ -526,7 +510,7 @@ _gabble_roster_item_update (GabbleRoster *roster, GabbleRosterPrivate *priv = roster->priv; GabbleRosterItem *item; const gchar *ask, *name; - TpIntSet *new_groups, *added_to, *removed_from, *removed_from2; + TpIntset *new_groups, *added_to, *removed_from, *removed_from2; TpHandleSet *new_groups_handle_set, *old_groups; TpBaseContactList *base = (TpBaseContactList *) roster; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( @@ -588,7 +572,7 @@ _gabble_roster_item_update (GabbleRoster *roster, if (roster->priv->groups != NULL) { - TpIntSet *created_groups = tp_handle_set_update (roster->priv->groups, + TpIntset *created_groups = tp_handle_set_update (roster->priv->groups, new_groups); /* we don't need to do this work if TpBaseContactList will just be @@ -599,7 +583,7 @@ _gabble_roster_item_update (GabbleRoster *roster, { GPtrArray *strv = g_ptr_array_sized_new (tp_intset_size ( created_groups)); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle group; tp_intset_fast_iter_init (&iter, created_groups); @@ -636,7 +620,7 @@ _gabble_roster_item_update (GabbleRoster *roster, GPtrArray *removed_names = g_ptr_array_sized_new ( tp_intset_size (removed_from)); TpHandleSet *the_contact = tp_handle_set_new (contact_repo); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle group; tp_handle_set_add (the_contact, contact_handle); @@ -1113,7 +1097,6 @@ process_roster ( /* transfer ownership of the reference to referenced_handles */ tp_handle_set_add (referenced_handles, handle); - tp_handle_unref (contact_repo, handle); item = _gabble_roster_item_update (roster, handle, item_node, google_roster, &nickname_updated); @@ -1551,8 +1534,7 @@ gabble_roster_presence_cb (WockyPorter *porter, { NODE_DEBUG (pres_node, "ignoring presence from ourselves on another " "resource"); - ret = FALSE; - goto OUT; + return FALSE; } g_assert (handle != 0); @@ -1679,8 +1661,6 @@ gabble_roster_presence_cb (WockyPorter *porter, ret = FALSE; } -OUT: - tp_handle_unref (contact_repo, handle); return ret; } @@ -1880,7 +1860,6 @@ item_edit_new (TpHandleRepoIface *contact_repo, { GabbleRosterItemEdit *self = g_slice_new0 (GabbleRosterItemEdit); - tp_handle_ref (contact_repo, handle); self->contact_repo = g_object_ref (contact_repo); self->handle = handle; self->new_subscription = GABBLE_ROSTER_SUBSCRIPTION_INVALID; @@ -1906,7 +1885,6 @@ item_edit_free (GabbleRosterItemEdit *edits) g_slist_free (edits->results); - tp_handle_unref (edits->contact_repo, edits->handle); g_object_unref (edits->contact_repo); tp_clear_pointer (&edits->add_to_groups, tp_handle_set_destroy); tp_clear_pointer (&edits->remove_from_groups, tp_handle_set_destroy); @@ -1969,7 +1947,7 @@ roster_item_apply_edits (GabbleRoster *roster, { gboolean altered = FALSE; GabbleRosterItem edited_item; - TpIntSet *intset; + TpIntset *intset; GabbleRosterPrivate *priv = roster->priv; TpHandleRepoIface *group_repo = tp_base_connection_get_handles ( (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_GROUP); @@ -2658,7 +2636,7 @@ gabble_roster_request_subscription_added_cb (GObject *source, (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT); SubscribeContext *context = user_data; GError *error = NULL; - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; /* Now that we've added all the contacts, send off all the subscription @@ -2712,7 +2690,7 @@ gabble_roster_request_subscription_async (TpBaseContactList *base, GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self, gabble_roster_request_subscription_added_cb, context, gabble_roster_request_subscription_async, 1); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; /* Before subscribing, add items to the roster @@ -2740,7 +2718,7 @@ gabble_roster_authorize_publication_async (TpBaseContactList *base, gpointer user_data) { GabbleRoster *self = GABBLE_ROSTER (base); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; GError *error = NULL; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( @@ -2793,7 +2771,7 @@ gabble_roster_store_contacts_async (TpBaseContactList *base, gpointer user_data) { GabbleRoster *self = GABBLE_ROSTER (base); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self, callback, user_data, gabble_roster_store_contacts_async, 1); @@ -2814,7 +2792,7 @@ gabble_roster_remove_contacts_async (TpBaseContactList *base, gpointer user_data) { GabbleRoster *self = GABBLE_ROSTER (base); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self, callback, user_data, gabble_roster_request_subscription_async, 1); @@ -2839,7 +2817,7 @@ gabble_roster_unsubscribe_async (TpBaseContactList *base, (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT); TpHandleSet *changed = tp_handle_set_new (contact_repo); TpHandleSet *removed = tp_handle_set_new (contact_repo); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; GError *error = NULL; @@ -2900,7 +2878,7 @@ gabble_roster_unpublish_async (TpBaseContactList *base, (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT); TpHandleSet *changed = tp_handle_set_new (contact_repo); TpHandleSet *removed = tp_handle_set_new (contact_repo); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; GError *error = NULL; @@ -3041,7 +3019,7 @@ gabble_roster_block_contacts_async (TpBaseContactList *base, gpointer user_data) { GabbleRoster *self = GABBLE_ROSTER (base); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self, callback, user_data, gabble_roster_request_subscription_async, 1); @@ -3062,7 +3040,7 @@ gabble_roster_unblock_contacts_async (TpBaseContactList *base, gpointer user_data) { GabbleRoster *self = GABBLE_ROSTER (base); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self, callback, user_data, gabble_roster_request_subscription_async, 1); @@ -3086,7 +3064,7 @@ gabble_roster_dup_groups (TpBaseContactList *base) if (self->priv->groups != NULL) { - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle group; ret = g_ptr_array_sized_new ( @@ -3122,7 +3100,7 @@ gabble_roster_dup_contact_groups (TpBaseContactList *base, { TpHandleRepoIface *group_repo = tp_base_connection_get_handles ( (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle group; ret = g_ptr_array_sized_new (tp_handle_set_size (item->groups) + 1); @@ -3218,7 +3196,6 @@ gabble_roster_set_contact_groups_async (TpBaseContactList *base, g_ptr_array_add (groups_created, (gchar *) groups[i]); } - tp_handle_unref (group_repo, group_handle); } if (groups_created->len > 0) @@ -3273,7 +3250,7 @@ gabble_roster_set_group_members_async (TpBaseContactList *base, /* You can't add people to an invalid group. */ if (G_UNLIKELY (group_handle == 0)) { - g_simple_async_result_set_error (result, TP_ERRORS, + g_simple_async_result_set_error (result, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Invalid group name: %s", group); goto finally; } @@ -3300,8 +3277,6 @@ gabble_roster_set_group_members_async (TpBaseContactList *base, result); } - tp_handle_unref (group_repo, group_handle); - finally: gabble_simple_async_countdown_dec (result); g_object_unref (result); @@ -3315,7 +3290,7 @@ gabble_roster_add_to_group_async (TpBaseContactList *base, gpointer user_data) { GabbleRoster *self = GABBLE_ROSTER (base); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; TpHandleRepoIface *group_repo = tp_base_connection_get_handles ( (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP); @@ -3327,7 +3302,7 @@ gabble_roster_add_to_group_async (TpBaseContactList *base, /* You can't add people to an invalid group. */ if (G_UNLIKELY (group_handle == 0)) { - g_simple_async_result_set_error (result, TP_ERRORS, + g_simple_async_result_set_error (result, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Invalid group name: %s", group); goto finally; } @@ -3348,8 +3323,6 @@ gabble_roster_add_to_group_async (TpBaseContactList *base, gabble_roster_handle_add_to_group (self, contact, group_handle, result); } - tp_handle_unref (group_repo, group_handle); - finally: gabble_simple_async_countdown_dec (result); g_object_unref (result); @@ -3363,7 +3336,7 @@ gabble_roster_remove_from_group_async (TpBaseContactList *base, gpointer user_data) { GabbleRoster *self = GABBLE_ROSTER (base); - TpIntSetFastIter iter; + TpIntsetFastIter iter; TpHandle contact; TpHandleRepoIface *group_repo = tp_base_connection_get_handles ( (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP); @@ -3464,8 +3437,6 @@ gabble_roster_remove_group_removed_cb (GObject *source, DEBUG ("contact #%u is still a member of group '%s', not removing", remaining_member, group); } - - tp_handle_unref (group_repo, context->group_handle); } context->callback (source, result, context->user_data); @@ -3495,9 +3466,6 @@ gabble_roster_remove_group_async (TpBaseContactList *base, context->user_data = user_data; context->contacts = tp_handle_set_new (contact_repo); - if (context->group_handle != 0) - tp_handle_ref (group_repo, context->group_handle); - result = gabble_simple_async_countdown_new (self, gabble_roster_remove_group_removed_cb, context, gabble_roster_remove_group_async, 1); diff --git a/src/roster.h b/src/roster.h index 185dde514..4cc2b0dcf 100644 --- a/src/roster.h +++ b/src/roster.h @@ -24,7 +24,7 @@ #include <glib-object.h> -#include <telepathy-glib/base-contact-list.h> +#include <telepathy-glib/telepathy-glib.h> #include "types.h" diff --git a/src/search-channel.c b/src/search-channel.c index afbb098ee..cbebe1fbd 100644 --- a/src/search-channel.c +++ b/src/search-channel.c @@ -23,11 +23,8 @@ #include <string.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> @@ -234,7 +231,7 @@ parse_unextended_field_response ( } else { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "server is broken: %s is not a field defined in XEP 0055", field->name); g_ptr_array_unref (search_keys); @@ -272,7 +269,7 @@ parse_data_form ( if (tp_strdiff (wocky_node_get_attribute (x_node, "type"), "form")) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "server is broken: <x> not type='form'"); goto fail; } @@ -308,7 +305,7 @@ parse_data_form ( if (tp_strdiff (form_type, NS_SEARCH)) { DEBUG ("<x> form does not have FORM_TYPE %s", NS_SEARCH); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "server is broken: form lacking FORM_TYPE %s", NS_SEARCH); goto fail; } @@ -416,7 +413,7 @@ query_reply_cb (GabbleConnection *conn, } else if (NULL == query_node) { - err = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + err = g_error_new (TP_ERROR, TP_ERROR_NOT_AVAILABLE, "%s is broken: it replied to our <query> with an empty IQ", chan->priv->server); } @@ -461,7 +458,7 @@ request_search_fields (GabbleSearchChannel *chan) * change_search_state: * @chan: a search channel * @state: the new state for the channel - * @reason: an error in the TP_ERRORS domain if the search has failed; NULL + * @reason: an error in the TP_ERROR domain if the search has failed; NULL * otherwise. */ static void @@ -493,7 +490,7 @@ change_search_state (GabbleSearchChannel *chan, if (state == TP_CHANNEL_CONTACT_SEARCH_STATE_FAILED) { g_assert (reason != NULL); - g_assert (reason->domain == TP_ERRORS); + g_assert (reason->domain == TP_ERROR); error_name = tp_error_get_dbus_name (reason->code); g_value_init (&v, G_TYPE_STRING); @@ -737,7 +734,7 @@ parse_extended_search_results (GabbleSearchChannel *chan, x = wocky_node_get_child_ns (query_node, "x", NS_X_DATA); if (x == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "reply doens't contain a <x> node"); return FALSE; } @@ -802,7 +799,7 @@ search_reply_cb (GabbleConnection *conn, } else if (NULL == query_node) { - err = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + err = g_error_new (TP_ERROR, TP_ERROR_NOT_AVAILABLE, "%s is broken: its iq reply didn't contain a <query/>", chan->priv->server); } @@ -848,7 +845,7 @@ validate_terms (GabbleSearchChannel *chan, if (!tp_strv_contains (asks, field)) { DEBUG ("%s is not in AvailableSearchKeys", field); - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s is not in AvailableSearchKeys", field); return FALSE; } @@ -1204,7 +1201,7 @@ gabble_search_channel_class_init (GabbleSearchChannelClass *klass) * server gave us a set of search keys, and they were sane, all components * will be 0 or %NULL, indicating that this channel can be announced and * used; if the server doesn't actually speak XEP 0055 or is full of bees, - * they'll be an error in either the GABBLE_XMPP_ERROR or the TP_ERRORS + * they'll be an error in either the GABBLE_XMPP_ERROR or the TP_ERROR * domain. */ signals[READY_OR_NOT] = @@ -1235,7 +1232,7 @@ gabble_search_channel_search (TpSvcChannelTypeContactSearch *self, if (priv->state != TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED) { - error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + error = g_error_new (TP_ERROR, TP_ERROR_NOT_AVAILABLE, "SearchState is %s", states[priv->state]); goto err; } @@ -1262,7 +1259,7 @@ gabble_search_channel_stop (TpSvcChannelTypeContactSearch *self, { case TP_CHANNEL_CONTACT_SEARCH_STATE_IN_PROGRESS: { - GError e = { TP_ERRORS, TP_ERROR_CANCELLED, "Stop() called" }; + GError e = { TP_ERROR, TP_ERROR_CANCELLED, "Stop() called" }; change_search_state (chan, TP_CHANNEL_CONTACT_SEARCH_STATE_FAILED, &e); @@ -1274,7 +1271,7 @@ gabble_search_channel_stop (TpSvcChannelTypeContactSearch *self, break; case TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED: { - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Search() hasn't been called yet" }; dbus_g_method_return_error (context, &e); diff --git a/src/search-channel.h b/src/search-channel.h index 9b6c748ab..066fd8535 100644 --- a/src/search-channel.h +++ b/src/search-channel.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/search-manager.c b/src/search-manager.c index c78598fb1..d0d4beaaa 100644 --- a/src/search-manager.c +++ b/src/search-manager.c @@ -21,9 +21,8 @@ #include "config.h" #include "search-manager.h" -#include <telepathy-glib/channel-manager.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> @@ -149,7 +148,7 @@ disco_done_cb (GabbleDisco *disco, else { tp_channel_manager_emit_request_failed (self, request_token, - TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "No Server has been specified and no server has been " "discovered on the connection"); } @@ -408,7 +407,7 @@ search_channel_ready_or_not_cb (GabbleSearchChannel *chan, { if (domain == WOCKY_XMPP_ERROR) { - domain = TP_ERRORS; + domain = TP_ERROR; switch (code) { @@ -424,7 +423,7 @@ search_channel_ready_or_not_cb (GabbleSearchChannel *chan, } else { - g_assert (domain == TP_ERRORS); + g_assert (domain == TP_ERROR); } tp_channel_manager_emit_request_failed (ctx->self, @@ -490,7 +489,7 @@ gabble_search_manager_create_channel (TpChannelManager *manager, else if (!wocky_decode_jid (server, NULL, NULL, NULL)) { /* On the other hand, if the JID's invalid, blow up. */ - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Specified server '%s' is not a valid JID", server); goto error; } @@ -501,7 +500,7 @@ gabble_search_manager_create_channel (TpChannelManager *manager, { if (self->priv->disco_done) { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + error = g_error_new (TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "No Server has been specified and no server has been " "discovered on the connection"); goto error; diff --git a/src/server-sasl-channel.c b/src/server-sasl-channel.c index 961d6d491..7857dfa1d 100644 --- a/src/server-sasl-channel.c +++ b/src/server-sasl-channel.c @@ -36,15 +36,8 @@ #include <dbus/dbus-glib.h> #include <wocky/wocky.h> -#include <telepathy-glib/channel-iface.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-generic.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_AUTH @@ -470,7 +463,7 @@ gabble_server_sasl_channel_raise (DBusGMethodInvocation *context, GError *error = NULL; va_start (ap, message); - error = g_error_new_valist (TP_ERRORS, code, message, ap); + error = g_error_new_valist (TP_ERROR, code, message, ap); va_end (ap); dbus_g_method_return_error (context, error); @@ -924,7 +917,7 @@ gabble_server_sasl_channel_fail (GabbleServerSaslChannel *self, gabble_set_tp_conn_error_from_wocky (error, TP_CONNECTION_STATUS_CONNECTING, &conn_reason, &tp_error); - g_assert (tp_error->domain == TP_ERRORS); + g_assert (tp_error->domain == TP_ERROR); DEBUG ("auth failed: %s", tp_error->message); change_current_state (self, TP_SASL_STATUS_SERVER_FAILED, diff --git a/src/server-sasl-channel.h b/src/server-sasl-channel.h index 69b469974..32cae43ed 100644 --- a/src/server-sasl-channel.h +++ b/src/server-sasl-channel.h @@ -22,7 +22,7 @@ #include <glib-object.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> #include <wocky/wocky.h> #include "types.h" diff --git a/src/server-tls-channel.c b/src/server-tls-channel.c index a82842d77..1287b335e 100644 --- a/src/server-tls-channel.c +++ b/src/server-tls-channel.c @@ -22,10 +22,8 @@ #include "server-tls-channel.h" -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/channel-iface.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <wocky/wocky.h> diff --git a/src/server-tls-channel.h b/src/server-tls-channel.h index 45afbf2a3..a21f1e358 100644 --- a/src/server-tls-channel.h +++ b/src/server-tls-channel.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> #include <extensions/extensions.h> diff --git a/src/server-tls-manager.c b/src/server-tls-manager.c index c28d2d4d2..4e961cdde 100644 --- a/src/server-tls-manager.c +++ b/src/server-tls-manager.c @@ -21,7 +21,8 @@ #include "config.h" #include "server-tls-manager.h" -#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_TLS #include "debug.h" @@ -345,7 +346,7 @@ gabble_server_tls_manager_verify_async (WockyTLSHandler *handler, if (self->priv->connection == NULL) { DEBUG ("connection already went away; failing immediately"); - g_simple_async_result_set_error (result, TP_ERRORS, TP_ERROR_CANCELLED, + g_simple_async_result_set_error (result, TP_ERROR, TP_ERROR_CANCELLED, "The Telepathy connection has already been disconnected"); g_simple_async_result_complete_in_idle (result); g_object_unref (result); diff --git a/src/server-tls-manager.h b/src/server-tls-manager.h index e8f10af1b..816866b5e 100644 --- a/src/server-tls-manager.h +++ b/src/server-tls-manager.h @@ -23,8 +23,7 @@ #include <glib-object.h> #include <wocky/wocky.h> - -#include <telepathy-glib/enums.h> +#include <telepathy-glib/telepathy-glib.h> #include "extensions/extensions.h" diff --git a/src/tls-certificate.c b/src/tls-certificate.c index 6d5748568..303b70644 100644 --- a/src/tls-certificate.c +++ b/src/tls-certificate.c @@ -22,7 +22,7 @@ #include "tls-certificate.h" #include <telepathy-glib/telepathy-glib.h> -#include <telepathy-glib/svc-tls.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_TLS #include "debug.h" @@ -266,7 +266,7 @@ gabble_tls_certificate_accept (TpSvcAuthenticationTLSCertificate *cert, if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING) { GError error = - { TP_ERRORS, + { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Calling Accept() on a certificate with state != PENDING " "doesn't make sense." @@ -295,7 +295,7 @@ gabble_tls_certificate_reject (TpSvcAuthenticationTLSCertificate *cert, if (rejections->len < 1) { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Calling Reject() with a zero-length rejection list." }; dbus_g_method_return_error (context, &error); @@ -305,7 +305,7 @@ gabble_tls_certificate_reject (TpSvcAuthenticationTLSCertificate *cert, if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING) { GError error = - { TP_ERRORS, + { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Calling Reject() on a certificate with state != PENDING " "doesn't make sense." diff --git a/src/tls-certificate.h b/src/tls-certificate.h index e71245d1c..271ce09d7 100644 --- a/src/tls-certificate.h +++ b/src/tls-certificate.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include <telepathy-glib/dbus-properties-mixin.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/tube-dbus.c b/src/tube-dbus.c index 424bf3dc5..5223d4780 100644 --- a/src/tube-dbus.c +++ b/src/tube-dbus.c @@ -27,12 +27,8 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> #include <wocky/wocky.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/group-mixin.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-generic.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "extensions/extensions.h" @@ -120,7 +116,7 @@ enum struct _GabbleTubeDBusPrivate { TpHandle self_handle; - guint id; + guint64 id; GabbleBytestreamIface *bytestream; gchar *stream_id; gchar *service; @@ -394,7 +390,7 @@ create_dbus_server (GabbleTubeDBus *self, g_free (priv->socket_path); priv->socket_path = NULL; - g_set_error (err, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (err, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Can't create D-Bus server"); return FALSE; } @@ -411,6 +407,8 @@ static void tube_dbus_open (GabbleTubeDBus *self) { GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); g_signal_connect (priv->bytestream, "data-received", G_CALLBACK (data_received_cb), self); @@ -424,6 +422,15 @@ tube_dbus_open (GabbleTubeDBus *self) { dbus_server_setup_with_g_main (priv->dbus_srv, NULL); } + + if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM) + { + /* add yourself in dbus names */ + gabble_tube_dbus_add_name (self, priv->self_handle, + priv->dbus_local_name); + + gabble_muc_channel_send_presence (priv->muc); + } } static void @@ -435,17 +442,6 @@ gabble_tube_dbus_init (GabbleTubeDBus *self) self->priv = priv; } -static void -unref_handle_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - TpHandle handle = GPOINTER_TO_UINT (key); - TpHandleRepoIface *contact_repo = (TpHandleRepoIface *) user_data; - - tp_handle_unref (contact_repo, handle); -} - static TpTubeChannelState get_tube_state (GabbleTubeDBus *self) { @@ -485,11 +481,16 @@ bytestream_state_changed_cb (GabbleBytestreamIface *bytestream, { GabbleTubeDBus *self = GABBLE_TUBE_DBUS (user_data); GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base); if (state == GABBLE_BYTESTREAM_STATE_CLOSED) { tp_clear_object (&priv->bytestream); g_signal_emit (G_OBJECT (self), signals[CLOSED], 0); + + if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM) + gabble_muc_channel_send_presence (priv->muc); } else if (state == GABBLE_BYTESTREAM_STATE_OPEN) { @@ -507,10 +508,6 @@ gabble_tube_dbus_dispose (GObject *object) { GabbleTubeDBus *self = GABBLE_TUBE_DBUS (object); GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self); - TpBaseConnection *base_conn = tp_base_channel_get_connection ( - TP_BASE_CHANNEL (self)); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - base_conn, TP_HANDLE_TYPE_CONTACT); DEBUG ("called"); @@ -556,13 +553,6 @@ gabble_tube_dbus_dispose (GObject *object) tp_clear_pointer (&priv->dbus_srv_addr, g_free); tp_clear_pointer (&priv->socket_path, g_free); tp_clear_pointer (&priv->dbus_local_name, g_free); - - if (priv->dbus_names != NULL) - { - g_hash_table_foreach (priv->dbus_names, unref_handle_foreach, - contact_repo); - } - tp_clear_pointer (&priv->dbus_names, g_hash_table_unref); tp_clear_pointer (&priv->dbus_name_to_handle, g_hash_table_unref); @@ -605,7 +595,7 @@ gabble_tube_dbus_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_BYTESTREAM: g_value_set_object (value, priv->bytestream); @@ -661,7 +651,7 @@ gabble_tube_dbus_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_BYTESTREAM: if (priv->bytestream == NULL) @@ -839,7 +829,7 @@ gabble_tube_dbus_get_object_path_suffix (TpBaseChannel *base) { GabbleTubeDBus *self = GABBLE_TUBE_DBUS (base); - return g_strdup_printf ("DBusTubeChannel/%u/%u", + return g_strdup_printf ("DBusTubeChannel/%u/%" G_GUINT64_FORMAT, tp_base_channel_get_target_handle (base), self->priv->id); } @@ -1038,7 +1028,7 @@ gabble_tube_dbus_offer (GabbleTubeDBus *tube, if (priv->offered) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Tube has already been offered"); return FALSE; } @@ -1062,7 +1052,7 @@ gabble_tube_dbus_offer (GabbleTubeDBus *tube, if (presence == NULL) { DEBUG ("can't find contact %s's presence", jid); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "can't find contact %s's presence", jid); return FALSE; } @@ -1073,7 +1063,7 @@ gabble_tube_dbus_offer (GabbleTubeDBus *tube, if (resource == NULL) { DEBUG ("contact %s doesn't have tubes capabilities", jid); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "contact %s doesn't have tubes capabilities", jid); return FALSE; } @@ -1114,6 +1104,8 @@ gabble_tube_dbus_offer (GabbleTubeDBus *tube, g_object_set (priv->bytestream, "state", GABBLE_BYTESTREAM_STATE_OPEN, NULL); + + gabble_muc_channel_send_presence (priv->muc); } if (!create_dbus_server (tube, error)) @@ -1348,7 +1340,7 @@ gabble_tube_dbus_new (GabbleConnection *conn, const gchar *service, GHashTable *parameters, const gchar *stream_id, - guint id, + guint64 id, GabbleBytestreamIface *bytestream, GabbleMucChannel *muc, gboolean requested) @@ -1518,7 +1510,6 @@ gabble_tube_dbus_add_name (GabbleTubeDBus *self, name_copy = g_strdup (name); g_hash_table_insert (priv->dbus_names, GUINT_TO_POINTER (handle), name_copy); - tp_handle_ref (contact_repo, handle); g_hash_table_insert (priv->dbus_name_to_handle, name_copy, GUINT_TO_POINTER (handle)); @@ -1545,9 +1536,6 @@ gabble_tube_dbus_remove_name (GabbleTubeDBus *self, GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_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); - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - base_conn, TP_HANDLE_TYPE_CONTACT); const gchar *name; GHashTable *added; GArray *removed; @@ -1575,7 +1563,6 @@ gabble_tube_dbus_remove_name (GabbleTubeDBus *self, g_hash_table_unref (added); g_array_unref (removed); - tp_handle_unref (contact_repo, handle); return TRUE; } @@ -1661,7 +1648,7 @@ gabble_tube_dbus_check_access_control (GabbleTubeDBus *self, break; default: - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%u socket access control is not supported", access_control); return FALSE; } diff --git a/src/tube-dbus.h b/src/tube-dbus.h index 35073ce3f..b3020a9f4 100644 --- a/src/tube-dbus.h +++ b/src/tube-dbus.h @@ -22,10 +22,8 @@ #include <glib-object.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/group-mixin.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "connection.h" #include "bytestream-iface.h" @@ -73,7 +71,7 @@ GType gabble_tube_dbus_get_type (void); GabbleTubeDBus *gabble_tube_dbus_new (GabbleConnection *conn, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, TpHandle initiator, const gchar *service, GHashTable *parameters, const gchar *stream_id, - guint id, GabbleBytestreamIface *bytestream, GabbleMucChannel *muc, + guint64 id, GabbleBytestreamIface *bytestream, GabbleMucChannel *muc, gboolean requested); gboolean gabble_tube_dbus_add_name (GabbleTubeDBus *tube, TpHandle handle, diff --git a/src/tube-iface.c b/src/tube-iface.c index 62585eb33..7faf514ea 100644 --- a/src/tube-iface.c +++ b/src/tube-iface.c @@ -20,7 +20,8 @@ #include "config.h" #include "tube-iface.h" -#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "connection.h" #include "util.h" @@ -72,7 +73,7 @@ gabble_tube_iface_base_init (gpointer klass) G_PARAM_CONSTRUCT_ONLY | 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", @@ -151,7 +152,7 @@ gabble_tube_iface_publish_in_node (GabbleTubeIface *tube, GHashTable *parameters; TpTubeType type; gchar *service, *id_str; - guint tube_id; + guint64 tube_id; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( conn, TP_HANDLE_TYPE_CONTACT); TpHandle initiator_handle; @@ -164,7 +165,7 @@ gabble_tube_iface_publish_in_node (GabbleTubeIface *tube, "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_attributes (node, "service", service, diff --git a/src/tube-iface.h b/src/tube-iface.h index 311bf65bc..b727f391d 100644 --- a/src/tube-iface.h +++ b/src/tube-iface.h @@ -21,7 +21,7 @@ #define __GABBLE_TUBE_IFACE_H__ #include <glib-object.h> -#include <telepathy-glib/base-connection.h> +#include <telepathy-glib/telepathy-glib.h> #include "bytestream-iface.h" diff --git a/src/tube-stream.c b/src/tube-stream.c index a505ef1a1..69123b4f4 100644 --- a/src/tube-stream.c +++ b/src/tube-stream.c @@ -31,12 +31,8 @@ #endif #include <glib/gstdio.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/group-mixin.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-generic.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "extensions/extensions.h" @@ -136,7 +132,7 @@ enum struct _GabbleTubeStreamPrivate { TpHandle self_handle; - guint id; + guint64 id; /* Bytestreams for tubes. One tube can have several bytestreams. The * mapping between the tube bytestream and the transport to the local @@ -471,7 +467,7 @@ start_stream_initiation (GabbleTubeStream *self, if (presence == NULL) { DEBUG ("can't find initiator's presence"); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "can't find initiator's presence"); return FALSE; } @@ -481,7 +477,7 @@ start_stream_initiation (GabbleTubeStream *self, if (resource == NULL) { DEBUG ("initiator doesn't have tubes capabilities"); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "initiator doesn't have tubes capabilities"); return FALSE; } @@ -503,7 +499,7 @@ start_stream_initiation (GabbleTubeStream *self, wocky_stanza_get_top_node (msg), "si", 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); if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT) { @@ -1235,7 +1231,7 @@ gabble_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); @@ -1289,7 +1285,7 @@ gabble_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); @@ -1401,7 +1397,7 @@ gabble_tube_stream_get_object_path_suffix (TpBaseChannel *base) { GabbleTubeStream *self = GABBLE_TUBE_STREAM (base); - return g_strdup_printf ("StreamTubeChannel/%u/%u", + return g_strdup_printf ("StreamTubeChannel/%u/%" G_GUINT64_FORMAT, tp_base_channel_get_target_handle (base), self->priv->id); } @@ -1620,7 +1616,7 @@ gabble_tube_stream_new (GabbleConnection *conn, TpHandle initiator, const gchar *service, GHashTable *parameters, - guint id, + guint64 id, GabbleMucChannel *muc, gboolean requested) { @@ -1665,7 +1661,7 @@ gabble_tube_stream_accept (GabbleTubeIface *tube, if (priv->state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Tube is not in the local pending state"); goto fail; } @@ -1725,7 +1721,7 @@ gabble_tube_iface_stream_close (GabbleTubeIface *tube, jid = tp_handle_inspect (contact_repo, tp_base_channel_get_target_handle (base)); - id_str = g_strdup_printf ("%u", priv->id); + id_str = g_strdup_printf ("%" G_GUINT64_FORMAT, priv->id); /* Send the close message */ msg = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, @@ -1750,6 +1746,9 @@ gabble_tube_iface_stream_close (GabbleTubeIface *tube, * disappear when we finally remove the Tubes channel type.. */ g_object_ref (self); + if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM) + gabble_muc_channel_send_presence (priv->muc); + g_signal_emit (G_OBJECT (self), signals[CLOSED], 0); tp_base_channel_destroyed (base); @@ -1861,7 +1860,7 @@ check_unix_params (TpSocketAddressType address_type, { if (G_VALUE_TYPE (address) != DBUS_TYPE_G_UCHAR_ARRAY) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unix socket address is supposed to be ay"); return FALSE; } @@ -1870,7 +1869,7 @@ check_unix_params (TpSocketAddressType address_type, if (array->len > sizeof (dummy.sun_path) - 1) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unix socket path is too long (max length allowed: %" G_GSIZE_FORMAT ")", sizeof (dummy.sun_path) - 1); @@ -1881,7 +1880,7 @@ check_unix_params (TpSocketAddressType address_type, { if (g_array_index (array, gchar , i) == '\0') { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unix socket path can't contain zero bytes"); return FALSE; } @@ -1893,7 +1892,7 @@ check_unix_params (TpSocketAddressType address_type, { DEBUG ("Error calling stat on socket: %s", g_strerror (errno)); - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "%s: %s", + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s: %s", socket_address->str, g_strerror (errno)); g_string_free (socket_address, TRUE); return FALSE; @@ -1903,7 +1902,7 @@ check_unix_params (TpSocketAddressType address_type, { DEBUG ("%s is not a socket", socket_address->str); - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%s is not a socket", socket_address->str); g_string_free (socket_address, TRUE); return FALSE; @@ -1919,7 +1918,7 @@ check_unix_params (TpSocketAddressType address_type, return TRUE; } - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%u socket access control is not supported", access_control); return FALSE; } @@ -1944,7 +1943,7 @@ check_ip_params (TpSocketAddressType address_type, { if (G_VALUE_TYPE (address) != TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "IPv4 socket address is supposed to be sq"); return FALSE; } @@ -1953,7 +1952,7 @@ check_ip_params (TpSocketAddressType address_type, { if (G_VALUE_TYPE (address) != TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV6) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "IPv6 socket address is supposed to be sq"); return FALSE; } @@ -1981,7 +1980,7 @@ check_ip_params (TpSocketAddressType address_type, ret = getaddrinfo (ip, NULL, &req, &result); if (ret != 0) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Invalid address: %s", gai_strerror (ret)); g_free (ip); return FALSE; @@ -2002,7 +2001,7 @@ check_ip_params (TpSocketAddressType address_type, if (G_VALUE_TYPE (access_control_param) != TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Port access param is supposed to be sq"); return FALSE; } @@ -2010,7 +2009,7 @@ check_ip_params (TpSocketAddressType address_type, return TRUE; } - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "%u socket access control is not supported", access_control); return FALSE; } @@ -2040,7 +2039,7 @@ gabble_tube_stream_check_params (TpSocketAddressType address_type, access_control_param, error); default: - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Address type %d not implemented", address_type); return FALSE; } @@ -2077,7 +2076,7 @@ send_tube_offer (GabbleTubeStream *self, if (presence == NULL) { DEBUG ("can't find tube recipient's presence"); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "can't find tube recipient's presence"); return FALSE; } @@ -2087,7 +2086,7 @@ send_tube_offer (GabbleTubeStream *self, if (resource == NULL) { DEBUG ("tube recipient doesn't have tubes capabilities"); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "tube recipient doesn't have tubes capabilities"); return FALSE; } @@ -2141,6 +2140,8 @@ gabble_tube_stream_offer (GabbleTubeStream *self, /* muc tube is open as soon it's offered */ priv->state = TP_TUBE_CHANNEL_STATE_OPEN; g_signal_emit (G_OBJECT (self), signals[OPENED], 0); + + gabble_muc_channel_send_presence (priv->muc); } g_signal_emit (G_OBJECT (self), signals[OFFERED], 0); @@ -2239,7 +2240,7 @@ gabble_tube_stream_offer_async (TpSvcChannelTypeStreamTube *iface, if (priv->state != TP_TUBE_CHANNEL_STATE_NOT_OFFERED) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Tube is not in the not offered state"); dbus_g_method_return_error (context, error); g_error_free (error); diff --git a/src/tube-stream.h b/src/tube-stream.h index 991116238..5b26fcced 100644 --- a/src/tube-stream.h +++ b/src/tube-stream.h @@ -22,9 +22,8 @@ #include <glib-object.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/base-channel.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "connection.h" #include "extensions/extensions.h" @@ -69,7 +68,7 @@ GType gabble_tube_stream_get_type (void); GabbleTubeStream *gabble_tube_stream_new (GabbleConnection *conn, TpHandle handle, TpHandleType handle_type, TpHandle self_handle, TpHandle initiator, const gchar *service, GHashTable *parameters, - guint id, GabbleMucChannel *muc, gboolean requested); + guint64 id, GabbleMucChannel *muc, gboolean requested); gboolean gabble_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 deleted file mode 100644 index 7d7cab984..000000000 --- a/src/tubes-channel.c +++ /dev/null @@ -1,2398 +0,0 @@ -/* - * tubes-channel.c - Source for GabbleTubesChannel - * 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 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 "tubes-channel.h" - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> - -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif - -#include <glib/gstdio.h> -#include <dbus/dbus-glib.h> -#include <telepathy-glib/channel-iface.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/group-mixin.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel.h> -#include <telepathy-glib/svc-generic.h> - -#define DEBUG_FLAG GABBLE_DEBUG_TUBES - -#include "bytestream-factory.h" -#include "connection.h" -#include "debug.h" -#include "namespaces.h" -#include "presence-cache.h" -#include "presence.h" -#include "private-tubes-factory.h" -#include "tube-iface.h" -#include "tube-dbus.h" -#include "tube-stream.h" -#include "tube-dbus.h" -#include "util.h" - -static void channel_iface_init (gpointer, gpointer); -static void tubes_iface_init (gpointer, gpointer); - -G_DEFINE_TYPE_WITH_CODE (GabbleTubesChannel, gabble_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_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_EXPORTABLE_CHANNEL, NULL); - G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL)); - -static const gchar *gabble_tubes_channel_interfaces[] = { - TP_IFACE_CHANNEL_INTERFACE_GROUP, - /* If more interfaces are added, either keep Group as the first, or change - * the implementations of gabble_tubes_channel_get_interfaces () and - * gabble_tubes_channel_get_property () too */ - NULL -}; - - -enum -{ - PROP_OBJECT_PATH = 1, - PROP_CHANNEL_TYPE, - PROP_HANDLE_TYPE, - PROP_HANDLE, - PROP_TARGET_ID, - PROP_REQUESTED, - PROP_CONNECTION, - PROP_INTERFACES, - PROP_MUC, - PROP_INITIATOR_HANDLE, - PROP_INITIATOR_ID, - PROP_CHANNEL_DESTROYED, - PROP_CHANNEL_PROPERTIES, - LAST_PROPERTY, -}; - -/* private structure */ - -struct _GabbleTubesChannelPrivate -{ - GabbleConnection *conn; - char *object_path; - TpHandle handle; - TpHandleType handle_type; - TpHandle self_handle; - TpHandle initiator; - gboolean requested; - - GHashTable *tubes; - - gulong pre_presence_signal; - gboolean closed; - gboolean dispose_has_run; -}; - -static void update_tubes_presence (GabbleTubesChannel *self); - -static void pre_presence_cb (GabbleMucChannel *muc, WockyStanza *msg, - GabbleTubesChannel *self); - -static void -gabble_tubes_channel_init (GabbleTubesChannel *self) -{ - GabbleTubesChannelPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - GABBLE_TYPE_TUBES_CHANNEL, GabbleTubesChannelPrivate); - - self->priv = priv; - - priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) g_object_unref); -} - -static GObject * -gabble_tubes_channel_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *obj; - GabbleTubesChannel *self; - GabbleTubesChannelPrivate *priv; - TpDBusDaemon *bus; - TpHandleRepoIface *handle_repo, *contact_repo; - - DEBUG ("Called"); - - obj = G_OBJECT_CLASS (gabble_tubes_channel_parent_class)-> - constructor (type, n_props, props); - - self = GABBLE_TUBES_CHANNEL (obj); - priv = self->priv; - contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - handle_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, priv->handle_type); - - tp_handle_ref (handle_repo, priv->handle); - - if (priv->initiator != 0) - tp_handle_ref (contact_repo, priv->initiator); - - switch (priv->handle_type) - { - case TP_HANDLE_TYPE_CONTACT: - g_assert (self->muc == NULL); - g_assert (priv->initiator != 0); - priv->self_handle = ((TpBaseConnection *) (priv->conn))->self_handle; - break; - case TP_HANDLE_TYPE_ROOM: - g_assert (self->muc != NULL); - - priv->pre_presence_signal = g_signal_connect (self->muc, "pre-presence", - G_CALLBACK (pre_presence_cb), self); - - priv->self_handle = self->muc->group.self_handle; - tp_external_group_mixin_init (obj, (GObject *) self->muc); - break; - default: - g_return_val_if_reached (NULL); - } - - bus = tp_base_connection_get_dbus_daemon ((TpBaseConnection *) priv->conn); - tp_dbus_daemon_register_object (bus, priv->object_path, obj); - - DEBUG ("Registering at '%s'", priv->object_path); - - return obj; -} - -static void -gabble_tubes_channel_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GabbleTubesChannel *chan = GABBLE_TUBES_CHANNEL (object); - GabbleTubesChannelPrivate *priv = chan->priv; - 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_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_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_CONNECTION: - g_value_set_object (value, priv->conn); - break; - case PROP_INTERFACES: - if (chan->muc) - { - /* MUC tubes */ - g_value_set_boxed (value, gabble_tubes_channel_interfaces); - } - else - { - /* 1-1 tubes - omit the Group interface */ - g_value_set_boxed (value, gabble_tubes_channel_interfaces + 1); - } - break; - case PROP_MUC: - g_value_set_object (value, chan->muc); - break; - case PROP_INITIATOR_HANDLE: - g_value_set_uint (value, priv->initiator); - break; - case PROP_INITIATOR_ID: - if (priv->initiator == 0) - { - g_value_set_static_string (value, ""); - } - else - { - TpHandleRepoIface *repo = tp_base_connection_get_handles ( - base_conn, TP_HANDLE_TYPE_CONTACT); - - 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 -gabble_tubes_channel_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GabbleTubesChannel *chan = GABBLE_TUBES_CHANNEL (object); - GabbleTubesChannelPrivate *priv = chan->priv; - - switch (property_id) - { - case PROP_OBJECT_PATH: - g_free (priv->object_path); - priv->object_path = g_value_dup_string (value); - DEBUG ("Setting object_path: %s", priv->object_path); - 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_CONNECTION: - priv->conn = g_value_get_object (value); - break; - case PROP_MUC: - chan->muc = g_value_get_object (value); - break; - case PROP_INITIATOR_HANDLE: - priv->initiator = g_value_get_uint (value); - 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 -d_bus_names_changed_added (GabbleTubesChannel *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, TP_STRUCT_TYPE_DBUS_TUBE_MEMBER); - g_value_take_boxed (&tmp, - dbus_g_type_specialized_construct (TP_STRUCT_TYPE_DBUS_TUBE_MEMBER)); - 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 (TP_STRUCT_TYPE_DBUS_TUBE_MEMBER, added->pdata[i]); - g_ptr_array_unref (added); - g_array_unref (removed); -} - -static void -d_bus_names_changed_removed (GabbleTubesChannel *self, - guint tube_id, - TpHandle contact) -{ - GabbleTubesChannelPrivate *priv = self->priv; - 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 (GabbleTubesChannel *self, - guint tube_id, - TpHandle handle, - const gchar *dbus_name) -{ - GabbleTubesChannelPrivate *priv = self->priv; - GabbleTubeDBus *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 (gabble_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 (GabbleTubesChannel *self, - guint tube_id) -{ - GabbleTubesChannelPrivate *priv = self->priv; - GabbleTubeDBus *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); -} - -static void -tube_closed_cb (GabbleTubeIface *tube, - gpointer user_data) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (user_data); - GabbleTubesChannelPrivate *priv = self->priv; - guint tube_id; - - 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); - - /* Emit the DBusNamesChanged signal if muc tube */ - d_bus_names_changed_removed (self, tube_id, priv->self_handle); - - update_tubes_presence (self); - - tp_svc_channel_type_tubes_emit_tube_closed (self, tube_id); - - /* Ideally, this should be done in the factory directly but the private - * tubes factory and the muc factory are not aware of tube channels. - * This design is a legacy of the old tube API and we can't really change it - * without big refactoring. */ - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - { - tp_channel_manager_emit_channel_closed_for_object ( - priv->conn->private_tubes_factory, TP_EXPORTABLE_CHANNEL (tube)); - } - else - { - tp_channel_manager_emit_channel_closed_for_object ( - priv->conn->muc_factory, TP_EXPORTABLE_CHANNEL (tube)); - } - -} - -static void -tube_opened_cb (GabbleTubeIface *tube, - gpointer user_data) -{ - GabbleTubesChannel *self = GABBLE_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_presence (self); - - tp_svc_channel_type_tubes_emit_tube_state_changed (self, tube_id, - TP_TUBE_CHANNEL_STATE_OPEN); -} - -static void -tube_offered_cb (GabbleTubeIface *tube, - gpointer user_data) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (user_data); - guint tube_id; - TpHandle initiator; - TpTubeType type; - gchar *service; - GHashTable *parameters; - TpTubeChannelState 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; - * TpTubeState and TpTubeChannelState are numerically equal for - * values other than NOT_OFFERED */ - g_assert (state < NUM_TP_TUBE_STATES); - tp_svc_channel_type_tubes_emit_new_tube (self, - tube_id, - initiator, - type, - service, - parameters, - state); - - update_tubes_presence (self); - - g_free (service); - g_hash_table_unref (parameters); -} - -static GabbleTubeIface * -create_new_tube (GabbleTubesChannel *self, - TpTubeType type, - TpHandle initiator, - const gchar *service, - GHashTable *parameters, - const gchar *stream_id, - guint tube_id, - GabbleBytestreamIface *bytestream, - gboolean requested) -{ - GabbleTubesChannelPrivate *priv = self->priv; - GabbleTubeIface *tube; - TpTubeChannelState state; - - switch (type) - { - case TP_TUBE_TYPE_DBUS: - tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (priv->conn, - priv->handle, priv->handle_type, priv->self_handle, initiator, - service, parameters, stream_id, tube_id, bytestream, self->muc, - requested)); - break; - case TP_TUBE_TYPE_STREAM: - tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (priv->conn, - priv->handle, priv->handle_type, priv->self_handle, initiator, - service, parameters, tube_id, self->muc, 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_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. - * TpTubeState and TpTubeChannelState are numerically equal for - * values other than NOT_OFFERED */ - 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); - - return tube; -} - -static gboolean -extract_tube_information (GabbleTubesChannel *self, - WockyNode *tube_node, - TpTubeType *type, - TpHandle *initiator_handle, - const gchar **service, - GHashTable **parameters, - guint *tube_id) -{ - GabbleTubesChannelPrivate *priv = self->priv; - 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, - GUINT_TO_POINTER (GABBLE_JID_ROOM_MEMBER), NULL); - - if (*initiator_handle == 0) - { - DEBUG ("invalid initiator JID %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 = lm_message_node_extract_properties (node, "parameter"); - } - - if (tube_id != NULL) - { - const gchar *str; - gchar *endptr; - unsigned long tmp; - - str = wocky_node_get_attribute (tube_node, "id"); - if (str == NULL) - { - DEBUG ("no tube id in SI request"); - return FALSE; - } - - tmp = strtoul (str, &endptr, 10); - if (!endptr || *endptr || tmp > G_MAXUINT32) - { - DEBUG ("tube id is not numeric or > 2**32: %s", str); - return FALSE; - } - *tube_id = (guint) tmp; - } - - return TRUE; -} - -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); - GabbleTubeIface *tube = GABBLE_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 (gabble_tube_dbus_handle_in_names (GABBLE_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 -{ - GabbleTubesChannel *self; - TpHandle contact; -}; - -struct _ForeachData -{ - TpExportableChannelFunc foreach; - gpointer user_data; -}; - -static void -foreach_slave (gpointer key, - gpointer value, - gpointer user_data) -{ - GabbleTubeIface *tube = GABBLE_TUBE_IFACE (value); - struct _ForeachData *data = (struct _ForeachData *) user_data; - TpTubeType type; - - g_object_get (tube, "type", &type, NULL); - data->foreach (TP_EXPORTABLE_CHANNEL (tube), data->user_data); -} - -void gabble_tubes_channel_foreach (GabbleTubesChannel *self, - TpExportableChannelFunc foreach, gpointer user_data) -{ - struct _ForeachData data; - GabbleTubesChannelPrivate *priv = self->priv; - - data.user_data = user_data; - data.foreach = foreach; - - g_hash_table_foreach (priv->tubes, foreach_slave, &data); -} - -static void -emit_d_bus_names_changed_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - guint tube_id = GPOINTER_TO_UINT (key); - GabbleTubeDBus *tube = GABBLE_TUBE_DBUS (value); - struct _emit_d_bus_names_changed_foreach_data *data = - (struct _emit_d_bus_names_changed_foreach_data *) user_data; - - /* Remove from the D-Bus names mapping */ - if (gabble_tube_dbus_remove_name (tube, data->contact)) - { - /* Emit the DBusNamesChanged signal */ - d_bus_names_changed_removed (data->self, tube_id, data->contact); - } -} - -static void -contact_left_muc (GabbleTubesChannel *self, - TpHandle contact) -{ - GabbleTubesChannelPrivate *priv = self->priv; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - GHashTable *old_dbus_tubes; - struct _add_in_old_dbus_tubes_data add_data; - struct _emit_d_bus_names_changed_foreach_data emit_data; - - DEBUG ("%s left muc and so left all its tube", tp_handle_inspect ( - contact_repo, contact)); - - /* 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); - - /* 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); -} - -/* Called when we receive a presence from a contact who is - * in the muc associated with this tubes channel */ -void -gabble_tubes_channel_presence_updated (GabbleTubesChannel *self, - TpHandle contact, - WockyNode *pnode) -{ - GabbleTubesChannelPrivate *priv = self->priv; - WockyNode *tubes_node; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - WockyNodeIter i; - WockyNode *tube_node; - const gchar *presence_type; - GHashTable *old_dbus_tubes; - struct _add_in_old_dbus_tubes_data add_data; - struct _emit_d_bus_names_changed_foreach_data emit_data; - - if (contact == priv->self_handle) - /* We don't need to inspect our own presence */ - return; - - /* We are interested by this presence only if it contains tube information - * or indicates someone left the muc */ - presence_type = wocky_node_get_attribute (pnode, "type"); - if (!tp_strdiff (presence_type, "unavailable")) - { - contact_left_muc (self, contact); - return; - } - - tubes_node = wocky_node_get_child_ns (pnode, "tubes", NS_TUBES); - - if (tubes_node == NULL) - return; - - /* 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); - - wocky_node_iter_init (&i, tubes_node, NULL, NULL); - while (wocky_node_iter_next (&i, &tube_node)) - { - const gchar *stream_id; - GabbleTubeIface *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)) - { - DEBUG ("Bad tube ID, skipping to next child of <tubes>"); - 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; - - if (extract_tube_information (self, tube_node, &type, - &initiator_handle, &service, ¶meters, NULL)) - { - switch (type) - { - case TP_TUBE_TYPE_DBUS: - { - if (initiator_handle == 0) - { - DEBUG ("D-Bus tube initiator missing"); - /* skip to the next child of <tubes> */ - continue; - } - } - break; - case TP_TUBE_TYPE_STREAM: - { - if (initiator_handle != 0) - /* ignore it */ - tp_handle_unref (contact_repo, initiator_handle); - - initiator_handle = contact; - tp_handle_ref (contact_repo, initiator_handle); - } - break; - default: - { - g_return_if_reached (); - } - } - - tube = create_new_tube (self, type, initiator_handle, - service, parameters, stream_id, tube_id, NULL, FALSE); - - tp_channel_manager_emit_new_channel (priv->conn->muc_factory, - TP_EXPORTABLE_CHANNEL (tube), NULL); - - /* the tube has reffed its initiator, no need to keep a ref */ - tp_handle_unref (contact_repo, initiator_handle); - 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) - /* skip to the next child of <tubes> */ - continue; - - g_object_get (tube, "type", &type, NULL); - - if (type == TP_TUBE_TYPE_DBUS) - { - /* Update mapping of handle -> D-Bus name. */ - if (!gabble_tube_dbus_handle_in_names (GABBLE_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); - /* skip to the next child of <tubes> */ - continue; - } - - add_name_in_dbus_names (self, tube_id, contact, new_name); - } - } - } - - /* 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); -} - -static void -copy_tube_in_ptr_array (gpointer key, - gpointer value, - gpointer user_data) -{ - GabbleTubeIface *tube = (GabbleTubeIface *) 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, - "state", &state, - NULL); - - /* The old interface has no way to represent unoffered tubes, so they - * shouldn't appear in the result of ListTubes() - */ - if (state == TP_TUBE_CHANNEL_STATE_NOT_OFFERED) - return; - - g_object_get (tube, - "type", &type, - "initiator-handle", &initiator, - "service", &service, - "parameters", ¶meters, - NULL); - - g_value_init (&entry, TP_STRUCT_TYPE_TUBE_INFO); - g_value_take_boxed (&entry, - dbus_g_type_specialized_construct (TP_STRUCT_TYPE_TUBE_INFO)); - 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 (GabbleTubesChannel *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; -} - -/** - * gabble_tubes_channel_get_available_tube_types - * - * Implements D-Bus method GetAvailableTubeTypes - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_get_available_tube_types (TpSvcChannelTypeTubes *iface, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GArray *ret; - TpTubeType type; - - g_assert (GABBLE_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); -} - -/** - * gabble_tubes_channel_list_tubes - * - * Implements D-Bus method ListTubes - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_list_tubes (TpSvcChannelTypeTubes *iface, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - GPtrArray *ret; - guint i; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - priv = self->priv; - - 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 (TP_STRUCT_TYPE_TUBE_INFO, ret->pdata[i]); - - g_ptr_array_unref (ret); -} - -struct _i_hate_g_hash_table_foreach -{ - GabbleTubesChannel *self; - WockyNode *tubes_node; -}; - -static void -publish_tubes_in_node (gpointer key, - gpointer value, - gpointer user_data) -{ - GabbleTubeIface *tube = (GabbleTubeIface *) value; - struct _i_hate_g_hash_table_foreach *data = - (struct _i_hate_g_hash_table_foreach *) user_data; - GabbleTubesChannelPrivate *priv = data->self->priv; - 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_with_content (data->tubes_node, "tube", NULL); - gabble_tube_iface_publish_in_node (tube, (TpBaseConnection *) priv->conn, - tube_node); -} - -static void -pre_presence_cb (GabbleMucChannel *muc, - WockyStanza *msg, - GabbleTubesChannel *self) -{ - GabbleTubesChannelPrivate *priv = self->priv; - struct _i_hate_g_hash_table_foreach data; - WockyNode *node; - - /* Augment the muc presence with tubes information */ - node = wocky_node_add_child_with_content ( - wocky_stanza_get_top_node (msg), "tubes", NULL); - node->ns = g_quark_from_string (NS_TUBES); - data.self = self; - data.tubes_node = node; - - g_hash_table_foreach (priv->tubes, publish_tubes_in_node, &data); -} - -static void -update_tubes_presence (GabbleTubesChannel *self) -{ - GabbleTubesChannelPrivate *priv = self->priv; - - if (priv->handle_type != TP_HANDLE_TYPE_ROOM) - return; - - gabble_muc_channel_send_presence (self->muc); -} - -/* Called when we receive a SI request, - * via gabble_tubes_factory_handle_si_tube_request - */ -void -gabble_tubes_channel_tube_si_offered (GabbleTubesChannel *self, - GabbleBytestreamIface *bytestream, - WockyStanza *msg) -{ - GabbleTubesChannelPrivate *priv = self->priv; - const gchar *service, *stream_id; - GHashTable *parameters; - TpTubeType type; - WockyNode *si_node, *tube_node; - guint tube_id; - GabbleTubeIface *tube; - WockyStanzaType stanza_type; - WockyStanzaSubType sub_type; - - /* Caller is expected to have checked that we have a SI node with - * a stream ID, the TUBES profile and a <tube> element - */ - wocky_stanza_get_type_info (msg, &stanza_type, &sub_type); - g_return_if_fail (stanza_type == WOCKY_STANZA_TYPE_IQ); - g_return_if_fail (sub_type == WOCKY_STANZA_SUB_TYPE_SET); - si_node = wocky_node_get_child_ns ( - wocky_stanza_get_top_node (msg), "si", NS_SI); - g_return_if_fail (si_node != NULL); - stream_id = wocky_node_get_attribute (si_node, "id"); - g_return_if_fail (stream_id != NULL); - tube_node = wocky_node_get_child_ns (si_node, "tube", - NS_TUBES); - g_return_if_fail (tube_node != NULL); - - if (!extract_tube_information (self, tube_node, NULL, NULL, - NULL, NULL, &tube_id)) - { - GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - "<tube> has no id attribute" }; - - NODE_DEBUG (tube_node, e.message); - gabble_bytestream_iface_close (bytestream, &e); - return; - } - - 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 ID already in use" }; - - NODE_DEBUG (tube_node, e.message); - gabble_bytestream_iface_close (bytestream, &e); - return; - } - - /* New tube */ - if (!extract_tube_information (self, tube_node, &type, NULL, - &service, ¶meters, NULL)) - { - GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, - "can't extract <tube> information from SI request" }; - - NODE_DEBUG (tube_node, e.message); - gabble_bytestream_iface_close (bytestream, &e); - g_hash_table_unref (parameters); - return; - } - - if (type != TP_TUBE_TYPE_DBUS) - { - GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_FORBIDDEN, - "Only D-Bus tubes are allowed to be created using SI" }; - - DEBUG ("%s", e.message); - gabble_bytestream_iface_close (bytestream, &e); - return; - } - - tube = create_new_tube (self, type, priv->handle, service, - parameters, stream_id, tube_id, (GabbleBytestreamIface *) bytestream, - FALSE); - - tp_channel_manager_emit_new_channel (priv->conn->private_tubes_factory, - TP_EXPORTABLE_CHANNEL (tube), NULL); - - g_hash_table_unref (parameters); -} - -/* Called when we receive a SI request, - * via either gabble_muc_factory_handle_si_stream_request or - * gabble_tubes_factory_handle_si_stream_request - */ -void -gabble_tubes_channel_bytestream_offered (GabbleTubesChannel *self, - GabbleBytestreamIface *bytestream, - WockyStanza *msg) -{ - GabbleTubesChannelPrivate *priv = self->priv; - const gchar *stream_id, *tmp; - gchar *endptr; - WockyNode *si_node, *stream_node; - guint tube_id; - unsigned long tube_id_tmp; - GabbleTubeIface *tube; - WockyStanzaType stanza_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, &stanza_type, &sub_type); - g_return_if_fail (stanza_type == WOCKY_STANZA_TYPE_IQ); - g_return_if_fail (sub_type == WOCKY_STANZA_SUB_TYPE_SET); - - si_node = wocky_node_get_child_ns ( - wocky_stanza_get_top_node (msg), "si", 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", NS_TUBES); - else - stream_node = wocky_node_get_child_ns (si_node, - "muc-stream", 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, - "<stream> or <muc-stream> has no tube attribute" }; - - NODE_DEBUG (stream_node, e.message); - gabble_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, - "<stream> or <muc-stream> tube attribute not numeric or > 2**32" }; - - DEBUG ("tube id is not numeric or > 2**32: %s", tmp); - gabble_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, - "<stream> or <muc-stream> tube attribute points to a nonexistent " - "tube" }; - - DEBUG ("tube %u doesn't exist", tube_id); - gabble_bytestream_iface_close (bytestream, &e); - return; - } - - DEBUG ("received new bytestream request for existing tube: %u", tube_id); - - gabble_tube_iface_add_bytestream (tube, bytestream); -} - - -static void -send_tube_close_msg (GabbleTubesChannel *self, - guint tube_id) -{ - GabbleTubesChannelPrivate *priv = self->priv; - WockyStanza *msg; - const gchar *jid; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - gchar *id_str; - - jid = tp_handle_inspect (contact_repo, priv->handle); - id_str = g_strdup_printf ("%u", tube_id); - - /* Send the close message */ - msg = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, - NULL, jid, - '(', "close", - ':', NS_TUBES, - '@', "tube", id_str, - ')', - GABBLE_AMP_DO_NOT_STORE_SPEC, - NULL); - g_free (id_str); - - _gabble_connection_send (priv->conn, msg, NULL); - - g_object_unref (msg); -} - -static void -tube_msg_offered (GabbleTubesChannel *self, - WockyStanza *msg, - WockyNode *tube_node) -{ - GabbleTubesChannelPrivate *priv = self->priv; - const gchar *service; - GHashTable *parameters; - TpTubeType type; - guint tube_id; - GabbleTubeIface *tube; - WockyStanzaType stanza_type; - - wocky_stanza_get_type_info (msg, &stanza_type, NULL); - g_return_if_fail (stanza_type == WOCKY_STANZA_TYPE_MESSAGE); - - if (!extract_tube_information (self, tube_node, NULL, NULL, - NULL, NULL, &tube_id)) - { - DEBUG ("<tube> has no id attribute"); - /* We can't send a close message as reply so just ignore it */ - return; - } - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - if (tube != NULL) - { - DEBUG ("tube ID already in use. Do not open the offered tube and close " - "the existing tube id %u", tube_id); - gabble_tube_iface_close (tube, FALSE); - return; - } - - /* New tube */ - if (!extract_tube_information (self, tube_node, &type, NULL, - &service, ¶meters, NULL)) - { - DEBUG ("can't extract <tube> information from message"); - send_tube_close_msg (self, tube_id); - return; - } - - if (type != TP_TUBE_TYPE_STREAM) - { - DEBUG ("Only stream tubes are allowed to be created using messages"); - send_tube_close_msg (self, tube_id); - return; - } - - tube = create_new_tube (self, type, priv->handle, service, - parameters, NULL, tube_id, NULL, FALSE); - - tp_channel_manager_emit_new_channel (priv->conn->private_tubes_factory, - TP_EXPORTABLE_CHANNEL (tube), NULL); - - g_hash_table_unref (parameters); -} - -static void -tube_msg_close (GabbleTubesChannel *self, - WockyStanza *msg, - WockyNode *close_node) -{ - GabbleTubesChannelPrivate *priv = self->priv; - guint tube_id; - const gchar *tmp; - gchar *endptr; - GabbleTubeIface *tube; - TpTubeType type; - - tmp = wocky_node_get_attribute (close_node, "tube"); - if (tmp == NULL) - { - DEBUG ("no tube id in close message"); - return; - } - - tube_id = (guint) strtoul (tmp, &endptr, 10); - if (!endptr || *endptr || tube_id > G_MAXUINT32) - { - DEBUG ("tube id is not numeric or > 2**32: %s", tmp); - return; - } - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id)); - if (tube == NULL) - { - DEBUG ("<close> tube attribute points to a nonexistent tube"); - return; - } - - g_object_get (tube, "type", &type, NULL); - if (type != TP_TUBE_TYPE_STREAM) - { - DEBUG ("Only stream tubes can be closed using a close message"); - return; - } - - DEBUG ("tube %u was closed by remote peer", tube_id); - gabble_tube_iface_close (tube, TRUE); -} - -void -gabble_tubes_channel_tube_msg (GabbleTubesChannel *self, - WockyStanza *msg) -{ - WockyNode *node; - - node = wocky_node_get_child_ns ( - wocky_stanza_get_top_node (msg), "tube", NS_TUBES); - if (node != NULL) - { - tube_msg_offered (self, msg, node); - return; - } - - node = wocky_node_get_child_ns ( - wocky_stanza_get_top_node (msg), "close", NS_TUBES); - if (node != NULL) - { - tube_msg_close (self, msg, node); - return; - } -} - -static guint -generate_tube_id (void) -{ - /* We don't generate IDs in the top half of the range, to be nice to - * older Gabble versions. */ - return g_random_int_range (0, G_MAXINT); -} - -GabbleTubeIface *gabble_tubes_channel_tube_request (GabbleTubesChannel *self, - gpointer request_token, GHashTable *request_properties, - gboolean require_new) -{ - GabbleTubesChannelPrivate *priv = self->priv; - GabbleTubeIface *tube; - const gchar *channel_type; - const gchar *service; - GHashTable *parameters = NULL; - guint tube_id; - gchar *stream_id; - TpTubeType type; - - 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 - /* 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); - - stream_id = gabble_bytestream_factory_generate_stream_id (); - tube = create_new_tube (self, type, priv->self_handle, service, - parameters, stream_id, tube_id, NULL, TRUE); - g_free (stream_id); - g_hash_table_unref (parameters); - - return tube; -} - -/** - * gabble_tubes_channel_offer_d_bus_tube - * - * Implements D-Bus method OfferDBusTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_offer_d_bus_tube (TpSvcChannelTypeTubes *iface, - const gchar *service, - GHashTable *parameters, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - guint tube_id; - GabbleTubeIface *tube; - gchar *stream_id; - GError *error = NULL; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - priv = self->priv; - - stream_id = gabble_bytestream_factory_generate_stream_id (); - tube_id = generate_tube_id (); - - tube = create_new_tube (self, TP_TUBE_TYPE_DBUS, priv->self_handle, - service, parameters, (const gchar *) stream_id, tube_id, NULL, TRUE); - - if (!gabble_tube_dbus_offer (GABBLE_TUBE_DBUS (tube), &error)) - { - gabble_tube_iface_close (tube, TRUE); - dbus_g_method_return_error (context, error); - - g_error_free (error); - g_free (stream_id); - return; - } - - tp_svc_channel_type_tubes_return_from_offer_d_bus_tube (context, tube_id); - - g_free (stream_id); -} - -static void -stream_unix_tube_new_connection_cb (GabbleTubeIface *tube, - guint contact, - gpointer user_data) -{ - GabbleTubesChannel *self = GABBLE_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); -} - -/** - * gabble_tubes_channel_offer_stream_tube - * - * Implements D-Bus method OfferStreamTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_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) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - guint tube_id; - GabbleTubeIface *tube; - gchar *stream_id; - GError *error = NULL; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - priv = self->priv; - - if (!gabble_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; - } - - stream_id = gabble_bytestream_factory_generate_stream_id (); - tube_id = generate_tube_id (); - - tube = create_new_tube (self, TP_TUBE_TYPE_STREAM, priv->self_handle, - service, parameters, (const gchar *) stream_id, tube_id, NULL, TRUE); - - g_object_set (tube, - "address-type", address_type, - "address", address, - "access-control", access_control, - "access-control-param", access_control_param, - NULL); - - /* Tube was created using the old API so is already offered */ - if (!gabble_tube_stream_offer (GABBLE_TUBE_STREAM (tube), &error)) - { - gabble_tube_iface_close (tube, TRUE); - - dbus_g_method_return_error (context, error); - - g_error_free (error); - g_free (stream_id); - return; - } - - g_signal_connect (tube, "tube-new-connection", - G_CALLBACK (stream_unix_tube_new_connection_cb), self); - - /* announce the new tube channel we just created (new tube API) */ - if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) - { - tp_channel_manager_emit_new_channel (priv->conn->private_tubes_factory, - TP_EXPORTABLE_CHANNEL (tube), NULL); - } - else - { - tp_channel_manager_emit_new_channel (priv->conn->muc_factory, - TP_EXPORTABLE_CHANNEL (tube), NULL); - } - - tp_svc_channel_type_tubes_return_from_offer_stream_tube (context, - tube_id); - - g_free (stream_id); -} - -/** - * gabble_tubes_channel_accept_d_bus_tube - * - * Implements D-Bus method AcceptDBusTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_accept_d_bus_tube (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - GabbleTubeIface *tube; - TpTubeChannelState state; - TpTubeType type; - gchar *addr; - GError *error = NULL; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - priv = self->priv; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - if (tube == NULL) - { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &e); - return; - } - - g_object_get (tube, - "type", &type, - "state", &state, - NULL); - - if (type != TP_TUBE_TYPE_DBUS) - { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a D-Bus tube" }; - - dbus_g_method_return_error (context, &e); - return; - } - - if (state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING) - { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Tube is not in the local pending state" }; - - dbus_g_method_return_error (context, &e); - return; - } - - if (!gabble_tube_iface_accept (tube, &error)) - { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - g_object_get (tube, "dbus-address", &addr, NULL); - tp_svc_channel_type_tubes_return_from_accept_d_bus_tube (context, addr); - g_free (addr); -} - -/** - * gabble_tubes_channel_accept_stream_tube - * - * Implements D-Bus method AcceptStreamTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_accept_stream_tube (TpSvcChannelTypeTubes *iface, - guint id, - guint address_type, - guint access_control, - const GValue *access_control_param, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - GabbleTubeIface *tube; - TpTubeChannelState state; - TpTubeType type; - GValue *address; - GError *error = NULL; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - priv = self->priv; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - if (tube == NULL) - { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &e); - return; - } - - g_object_get (tube, - "type", &type, - "state", &state, - NULL); - - if (type != TP_TUBE_TYPE_STREAM) - { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a stream tube" }; - - dbus_g_method_return_error (context, &e); - return; - } - - /* most parameters sanity checks are done in gabble_tube_stream_accept, - * but at least check that they fit the properties requirements */ - if (address_type != TP_SOCKET_ADDRESS_TYPE_UNIX && - address_type != TP_SOCKET_ADDRESS_TYPE_IPV4 && - address_type != TP_SOCKET_ADDRESS_TYPE_IPV6) - { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Address type not implemented" }; - - dbus_g_method_return_error (context, &e); - return; - } - g_object_set (tube, - "address-type", address_type, - "access-control", access_control, - "access-control-param", access_control_param, - NULL); - - if (!gabble_tube_iface_accept (tube, &error)) - { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - update_tubes_presence (self); - - g_object_get (tube, "address", &address, NULL); - - tp_svc_channel_type_tubes_return_from_accept_stream_tube (context, - address); -} - -/** - * gabble_tubes_channel_close_tube - * - * Implements D-Bus method CloseTube - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_close_tube (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - GabbleTubeIface *tube; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - priv = self->priv; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - - if (tube == NULL) - { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "Unknown tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - gabble_tube_iface_close (tube, FALSE); - - tp_svc_channel_type_tubes_return_from_close_tube (context); -} - -/** - * gabble_tubes_channel_get_d_bus_tube_address - * - * Implements D-Bus method GetDBusTubeAddress - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_get_d_bus_tube_address (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - GabbleTubeIface *tube; - gchar *addr; - TpTubeType type; - TpTubeChannelState state; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - priv = self->priv; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - - if (tube == NULL) - { - GError error = { TP_ERRORS, 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_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a D-Bus tube" }; - - 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, TP_STRUCT_TYPE_DBUS_TUBE_MEMBER); - g_value_take_boxed (&tmp, - dbus_g_type_specialized_construct (TP_STRUCT_TYPE_DBUS_TUBE_MEMBER)); - dbus_g_type_struct_set (&tmp, - 0, key, - 1, value, - G_MAXUINT); - g_ptr_array_add (ret, g_value_get_boxed (&tmp)); -} - -/** - * gabble_tubes_channel_get_d_bus_names - * - * Implements D-Bus method GetDBusNames - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_get_d_bus_names (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv = self->priv; - GabbleTubeIface *tube; - GHashTable *names; - GPtrArray *ret; - TpTubeType type; - TpTubeChannelState state; - guint i; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - - if (tube == NULL) - { - GError error = { TP_ERRORS, 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 || - priv->handle_type != TP_HANDLE_TYPE_ROOM) - { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Tube is not a Muc D-Bus tube" }; - - dbus_g_method_return_error (context, &error); - return; - } - - if (state != TP_TUBE_CHANNEL_STATE_OPEN) - { - GError error = { TP_ERRORS, 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 (TP_STRUCT_TYPE_DBUS_TUBE_MEMBER, ret->pdata[i]); - g_hash_table_unref (names); - g_ptr_array_unref (ret); -} - -/** - * gabble_tubes_channel_get_stream_tube_socket_address - * - * Implements D-Bus method GetStreamTubeSocketAddress - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_get_stream_tube_socket_address (TpSvcChannelTypeTubes *iface, - guint id, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv = self->priv; - GabbleTubeIface *tube; - TpTubeType type; - TpTubeChannelState state; - TpSocketAddressType address_type; - GValue *address; - - tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (id)); - if (tube == NULL) - { - GError error = { TP_ERRORS, 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_ERRORS, 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_ERRORS, TP_ERROR_NOT_AVAILABLE, - "Tube is not open" }; - - dbus_g_method_return_error (context, &error); - return; - } - - g_object_get (tube, - "address-type", &address_type, - "address", &address, - NULL); - - tp_svc_channel_type_tubes_return_from_get_stream_tube_socket_address ( - context, address_type, address); -} - -/** - * gabble_tubes_channel_get_available_stream_tube_types - * - * Implements D-Bus method GetAvailableStreamTubeTypes - * on org.freedesktop.Telepathy.Channel.Type.Tubes - */ -static void -gabble_tubes_channel_get_available_stream_tube_types (TpSvcChannelTypeTubes *iface, - DBusGMethodInvocation *context) -{ - GHashTable *ret; - - ret = gabble_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 -emit_tube_closed_signal (gpointer key, - gpointer value, - gpointer user_data) -{ - guint id = GPOINTER_TO_UINT (key); - GabbleTubesChannel *self = (GabbleTubesChannel *) user_data; - - tp_svc_channel_type_tubes_emit_tube_closed (self, id); -} - -void -gabble_tubes_channel_close (GabbleTubesChannel *self) -{ - GabbleTubesChannelPrivate *priv; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - DEBUG ("called on %p", self); - - priv = self->priv; - - 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); -} - -/** - * gabble_tubes_channel_close_async: - * - * Implements D-Bus method Close - * on interface org.freedesktop.Telepathy.Channel - */ -static void -gabble_tubes_channel_close_async (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - - gabble_tubes_channel_close (self); - tp_svc_channel_return_from_close (context); -} - -/** - * gabble_tubes_channel_get_channel_type - * - * Implements D-Bus method GetChannelType - * on interface org.freedesktop.Telepathy.Channel - */ -static void -gabble_tubes_channel_get_channel_type (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - tp_svc_channel_return_from_get_channel_type (context, - TP_IFACE_CHANNEL_TYPE_TUBES); -} - -/** - * gabble_tubes_channel_get_handle - * - * Implements D-Bus method GetHandle - * on interface org.freedesktop.Telepathy.Channel - */ -static void -gabble_tubes_channel_get_handle (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - GabbleTubesChannelPrivate *priv; - - g_assert (GABBLE_IS_TUBES_CHANNEL (self)); - priv = self->priv; - - tp_svc_channel_return_from_get_handle (context, priv->handle_type, - priv->handle); -} - -/** - * gabble_tubes_channel_get_interfaces - * - * Implements D-Bus method GetInterfaces - * on interface org.freedesktop.Telepathy.Channel - */ -static void -gabble_tubes_channel_get_interfaces (TpSvcChannel *iface, - DBusGMethodInvocation *context) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (iface); - - if (self->muc) - { - tp_svc_channel_return_from_get_interfaces (context, - gabble_tubes_channel_interfaces); - } - else - { - /* omit the Group interface */ - tp_svc_channel_return_from_get_interfaces (context, - gabble_tubes_channel_interfaces + 1); - } -} - -static void gabble_tubes_channel_dispose (GObject *object); -static void gabble_tubes_channel_finalize (GObject *object); - -static void -gabble_tubes_channel_class_init ( - GabbleTubesChannelClass *gabble_tubes_channel_class) -{ - 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 } - }; - GObjectClass *object_class = G_OBJECT_CLASS (gabble_tubes_channel_class); - GParamSpec *param_spec; - - g_type_class_add_private (gabble_tubes_channel_class, - sizeof (GabbleTubesChannelPrivate)); - - object_class->constructor = gabble_tubes_channel_constructor; - - object_class->get_property = gabble_tubes_channel_get_property; - object_class->set_property = gabble_tubes_channel_set_property; - - object_class->dispose = gabble_tubes_channel_dispose; - object_class->finalize = gabble_tubes_channel_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_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_object ( - "connection", - "GabbleConnection object", - "Gabble connection object that owns this Tubes channel object.", - GABBLE_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_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_object ( - "muc", - "GabbleMucChannel object", - "Gabble text MUC channel corresponding to this Tubes channel object, " - "if the handle type is ROOM.", - GABBLE_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_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_uint ("initiator-handle", "Initiator's handle", - "The contact who initiated the channel", - 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'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_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_REQUESTED, param_spec); - - gabble_tubes_channel_class->dbus_props_class.interfaces = prop_interfaces; - tp_dbus_properties_mixin_class_init (object_class, - G_STRUCT_OFFSET (GabbleTubesChannelClass, dbus_props_class)); - - tp_external_group_mixin_init_dbus_properties (object_class); -} - -void -gabble_tubes_channel_dispose (GObject *object) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (object); - GabbleTubesChannelPrivate *priv = self->priv; - TpHandleRepoIface *handle_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, priv->handle_type); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - tp_handle_unref (handle_repo, priv->handle); - - if (self->muc != NULL) - { - g_signal_handler_disconnect (self->muc, priv->pre_presence_signal); - - tp_external_group_mixin_finalize (object); - } - gabble_tubes_channel_close (self); - - g_assert (priv->closed); - g_assert (priv->tubes == NULL); - - if (G_OBJECT_CLASS (gabble_tubes_channel_parent_class)->dispose) - G_OBJECT_CLASS (gabble_tubes_channel_parent_class)->dispose (object); -} - -void -gabble_tubes_channel_finalize (GObject *object) -{ - GabbleTubesChannel *self = GABBLE_TUBES_CHANNEL (object); - GabbleTubesChannelPrivate *priv = self->priv; - TpHandleRepoIface *contact_handles = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); - - g_free (priv->object_path); - - if (priv->initiator != 0) - tp_handle_unref (contact_handles, priv->initiator); - - G_OBJECT_CLASS (gabble_tubes_channel_parent_class)->finalize (object); -} - -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, gabble_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, gabble_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 dbf7d5fd4..000000000 --- a/src/tubes-channel.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * tubes-channel.h - Header for GabbleTubesChannel - * 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 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 __GABBLE_TUBES_CHANNEL_H__ -#define __GABBLE_TUBES_CHANNEL_H__ - -#include <glib-object.h> -#include <wocky/wocky.h> -#include <telepathy-glib/base-connection.h> -#include <telepathy-glib/exportable-channel.h> - -#include "bytestream-iface.h" -#include "muc-channel.h" -#include "tube-iface.h" -#include "types.h" - -G_BEGIN_DECLS - -typedef struct _GabbleTubesChannelPrivate GabbleTubesChannelPrivate; -typedef struct _GabbleTubesChannelClass GabbleTubesChannelClass; - -struct _GabbleTubesChannelClass { - GObjectClass parent_class; - - TpDBusPropertiesMixinClass dbus_props_class; -}; - -struct _GabbleTubesChannel { - GObject parent; - - GabbleMucChannel *muc; - - GabbleTubesChannelPrivate *priv; -}; - -GType gabble_tubes_channel_get_type (void); - -/* TYPE MACROS */ -#define GABBLE_TYPE_TUBES_CHANNEL \ - (gabble_tubes_channel_get_type ()) -#define GABBLE_TUBES_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GABBLE_TYPE_TUBES_CHANNEL,\ - GabbleTubesChannel)) -#define GABBLE_TUBES_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GABBLE_TYPE_TUBES_CHANNEL,\ - GabbleTubesChannelClass)) -#define GABBLE_IS_TUBES_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GABBLE_TYPE_TUBES_CHANNEL)) -#define GABBLE_IS_TUBES_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GABBLE_TYPE_TUBES_CHANNEL)) -#define GABBLE_TUBES_CHANNEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_TUBES_CHANNEL,\ - GabbleTubesChannelClass)) - -void gabble_tubes_channel_foreach (GabbleTubesChannel *self, - TpExportableChannelFunc foreach, gpointer user_data); - -GabbleTubeIface *gabble_tubes_channel_tube_request (GabbleTubesChannel *self, - gpointer request_token, GHashTable *request_properties, - gboolean require_new); - -void gabble_tubes_channel_presence_updated (GabbleTubesChannel *chan, - TpHandle contact, WockyNode *presence); - -void gabble_tubes_channel_tube_si_offered (GabbleTubesChannel *chan, - GabbleBytestreamIface *bytestream, WockyStanza *msg); - -void gabble_tubes_channel_bytestream_offered (GabbleTubesChannel *chan, - GabbleBytestreamIface *bytestream, WockyStanza *msg); - -void gabble_tubes_channel_tube_msg (GabbleTubesChannel *chan, WockyStanza *msg); - -void gabble_tubes_channel_close (GabbleTubesChannel *self); - -G_END_DECLS - -#endif /* #ifndef __GABBLE_TUBES_CHANNEL_H__*/ diff --git a/src/types.h b/src/types.h index 1c9de3f1a..977ff3fb7 100644 --- a/src/types.h +++ b/src/types.h @@ -24,7 +24,7 @@ #include "config.h" -#include <telepathy-glib/handle.h> +#include <telepathy-glib/telepathy-glib.h> #include "gabble/types.h" diff --git a/src/util.c b/src/util.c index 4102f2194..57b46605f 100644 --- a/src/util.c +++ b/src/util.c @@ -31,9 +31,8 @@ #include <gobject/gvaluecollector.h> #include <wocky/wocky.h> -#include <telepathy-glib/handle-repo-dynamic.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG_FLAG GABBLE_DEBUG_JID @@ -193,7 +192,7 @@ gabble_get_room_handle_from_jid (TpHandleRepoIface *room_repo, #define INVALID_HANDLE(e, f, ...) \ G_STMT_START { \ DEBUG (f, ##__VA_ARGS__); \ - g_set_error (e, TP_ERRORS, TP_ERROR_INVALID_HANDLE, f, ##__VA_ARGS__);\ + g_set_error (e, TP_ERROR, TP_ERROR_INVALID_HANDLE, f, ##__VA_ARGS__);\ } G_STMT_END gchar * diff --git a/src/util.h b/src/util.h index 10b2b6eec..cfea342d5 100644 --- a/src/util.h +++ b/src/util.h @@ -25,8 +25,7 @@ #include <config.h> #include <glib.h> -#include <telepathy-glib/handle-repo.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #include <wocky/wocky.h> #ifdef ENABLE_VOIP diff --git a/src/vcard-manager.c b/src/vcard-manager.c index 67466be01..b8777a4e2 100644 --- a/src/vcard-manager.c +++ b/src/vcard-manager.c @@ -24,8 +24,8 @@ #include <string.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/heap.h> +#include <telepathy-glib/telepathy-glib.h> + #include <wocky/wocky.h> #define DEBUG_FLAG GABBLE_DEBUG_VCARD @@ -403,9 +403,6 @@ static void cache_entry_free (gpointer data) { GabbleVCardCacheEntry *entry = data; - GabbleVCardManagerPrivate *priv = entry->manager->priv; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles - ((TpBaseConnection *) priv->connection, TP_HANDLE_TYPE_CONTACT); g_assert (entry != NULL); @@ -421,8 +418,6 @@ cache_entry_free (gpointer data) tp_clear_pointer (&entry->vcard_node, wocky_node_free); - tp_handle_unref (contact_repo, entry->handle); - g_slice_free (GabbleVCardCacheEntry, entry); } @@ -430,8 +425,6 @@ static GabbleVCardCacheEntry * cache_entry_get (GabbleVCardManager *manager, TpHandle handle) { GabbleVCardManagerPrivate *priv = manager->priv; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( - (TpBaseConnection *) priv->connection, TP_HANDLE_TYPE_CONTACT); GabbleVCardCacheEntry *entry; entry = g_hash_table_lookup (priv->cache, GUINT_TO_POINTER (handle)); @@ -442,7 +435,6 @@ cache_entry_get (GabbleVCardManager *manager, TpHandle handle) entry->manager = manager; entry->handle = handle; - tp_handle_ref (contact_repo, handle); g_hash_table_insert (priv->cache, GUINT_TO_POINTER (handle), entry); return entry; @@ -582,7 +574,7 @@ complete_one_request (GabbleVCardManagerRequest *request, static void disconnect_entry_foreach (gpointer handle, gpointer value, gpointer unused) { - GError err = { TP_ERRORS, TP_ERROR_DISCONNECTED, "Connection closed" }; + GError err = { TP_ERROR, TP_ERROR_DISCONNECTED, "Connection closed" }; GabbleVCardCacheEntry *entry = value; if (entry->suspended_timer_id) |