summaryrefslogtreecommitdiff
path: root/src/muc-factory.c
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2012-01-26 13:09:47 +0000
committerWill Thompson <will.thompson@collabora.co.uk>2012-01-26 13:09:47 +0000
commite142bebe3e112d715af2b4784b24730eb9c310a0 (patch)
tree594393ed618bf82b4600f61c624de58ad3340ca1 /src/muc-factory.c
parenta2a603bdfb12bc9aa80726bf1f822cc22c76917e (diff)
parent035a6b0a6e8ce1787abf2583bb918436282026fe (diff)
downloadtelepathy-gabble-e142bebe3e112d715af2b4784b24730eb9c310a0.tar.gz
Merge branch 'master' into BYE-BYE-LOUDMOUTH
Conflicts: src/connection.c src/connection.h src/ft-manager.c src/jingle-content.c src/jingle-factory.c src/jingle-session.c src/message-util.c src/muc-channel.c src/muc-channel.h
Diffstat (limited to 'src/muc-factory.c')
-rw-r--r--src/muc-factory.c338
1 files changed, 209 insertions, 129 deletions
diff --git a/src/muc-factory.c b/src/muc-factory.c
index b6bb486d5..f5c324968 100644
--- a/src/muc-factory.c
+++ b/src/muc-factory.c
@@ -20,13 +20,12 @@
#include "config.h"
#include "muc-factory.h"
-#define DBUS_API_SUBJECT_TO_CHANGE
-
#include <string.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <loudmouth/loudmouth.h>
+#include <wocky/wocky-utils.h>
#include <telepathy-glib/channel-manager.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/interfaces.h>
@@ -36,7 +35,7 @@
#define DEBUG_FLAG GABBLE_DEBUG_MUC
-#include "caps-channel-manager.h"
+#include "gabble/caps-channel-manager.h"
#include "connection.h"
#include "conn-olpc.h"
#include "debug.h"
@@ -99,17 +98,14 @@ struct _GabbleMucFactoryPrivate
gboolean dispose_has_run;
};
-#define GABBLE_MUC_FACTORY_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), GABBLE_TYPE_MUC_FACTORY, \
- GabbleMucFactoryPrivate))
-
static GObject *gabble_muc_factory_constructor (GType type, guint n_props,
GObjectConstructParam *props);
static void
gabble_muc_factory_init (GabbleMucFactory *fac)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (fac,
+ GABBLE_TYPE_MUC_FACTORY, GabbleMucFactoryPrivate);
fac->priv = priv;
@@ -150,7 +146,7 @@ static void
gabble_muc_factory_dispose (GObject *object)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (object);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
if (priv->dispose_has_run)
return;
@@ -166,7 +162,7 @@ gabble_muc_factory_dispose (GObject *object)
g_hash_table_foreach (priv->disco_requests, cancel_disco_request,
priv->conn->disco);
- g_hash_table_destroy (priv->disco_requests);
+ g_hash_table_unref (priv->disco_requests);
if (G_OBJECT_CLASS (gabble_muc_factory_parent_class)->dispose)
G_OBJECT_CLASS (gabble_muc_factory_parent_class)->dispose (object);
@@ -179,7 +175,7 @@ gabble_muc_factory_get_property (GObject *object,
GParamSpec *pspec)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (object);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
switch (property_id) {
case PROP_CONNECTION:
@@ -198,7 +194,7 @@ gabble_muc_factory_set_property (GObject *object,
GParamSpec *pspec)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (object);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
switch (property_id) {
case PROP_CONNECTION:
@@ -242,7 +238,7 @@ static void
muc_channel_closed_cb (GabbleMucChannel *chan, gpointer user_data)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (user_data);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
TpHandle room_handle;
tp_channel_manager_emit_channel_closed_for_object (fac,
@@ -265,7 +261,7 @@ muc_ready_cb (GabbleMucChannel *text_chan,
gpointer data)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (data);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
GabbleTubesChannel *tubes_chan;
GSList *requests_satisfied_text, *requests_satisfied_tubes = NULL;
gboolean text_requested;
@@ -340,7 +336,7 @@ muc_ready_cb (GabbleMucChannel *text_chan,
tp_channel_manager_emit_new_channels (fac, channels);
- g_hash_table_destroy (channels);
+ g_hash_table_unref (channels);
}
g_hash_table_remove (priv->tubes_needed_for_tube, tubes_chan);
@@ -354,7 +350,7 @@ muc_join_error_cb (GabbleMucChannel *chan,
gpointer data)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (data);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
GabbleTubesChannel *tubes_chan;
GSList *requests_satisfied;
GSList *iter;
@@ -452,9 +448,10 @@ new_muc_channel (GabbleMucFactory *fac,
gboolean requested,
GHashTable *initial_channels,
GArray *initial_handles,
- char **initial_ids)
+ char **initial_ids,
+ const char *room_name)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
TpBaseConnection *conn = (TpBaseConnection *) priv->conn;
GabbleMucChannel *chan;
char *object_path;
@@ -497,6 +494,7 @@ new_muc_channel (GabbleMucFactory *fac,
"initial-channels", initial_channels_array,
"initial-invitee-handles", initial_handles,
"initial-invitee-ids", initial_ids,
+ "room-name", room_name,
NULL);
g_signal_connect (chan, "closed", (GCallback) muc_channel_closed_cb, fac);
@@ -507,7 +505,7 @@ new_muc_channel (GabbleMucFactory *fac,
g_hash_table_insert (priv->text_channels, GUINT_TO_POINTER (handle), chan);
g_free (object_path);
- g_ptr_array_free (initial_channels_array, TRUE);
+ g_ptr_array_unref (initial_channels_array);
g_array_unref (initial_handles);
if (_gabble_muc_channel_is_ready (chan))
@@ -529,7 +527,7 @@ do_invite (GabbleMucFactory *fac,
TpHandle inviter_handle,
const gchar *reason)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
TpHandleRepoIface *room_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_ROOM);
TpHandle room_handle;
@@ -547,7 +545,7 @@ do_invite (GabbleMucFactory *fac,
GUINT_TO_POINTER (room_handle)) == NULL)
{
new_muc_channel (fac, room_handle, TRUE, inviter_handle, reason, FALSE,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
}
else
{
@@ -581,7 +579,7 @@ obsolete_invite_disco_cb (GabbleDisco *self,
struct DiscoInviteData *data = (struct DiscoInviteData *) user_data;
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (data->factory);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
WockyNode *identity;
@@ -626,7 +624,7 @@ process_muc_invite (GabbleMucFactory *fac,
const gchar *from,
TpChannelTextSendError send_error)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
TpBaseConnection *conn = (TpBaseConnection *) priv->conn;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
TP_HANDLE_TYPE_CONTACT);
@@ -700,7 +698,7 @@ process_obsolete_invite (GabbleMucFactory *fac,
const gchar *body,
TpChannelTextSendError send_error)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
TpBaseConnection *conn = (TpBaseConnection *) priv->conn;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
TP_HANDLE_TYPE_CONTACT);
@@ -788,7 +786,7 @@ muc_factory_message_cb (LmMessageHandler *handler,
gpointer user_data)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (user_data);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
const gchar *from, *body, *id;
time_t stamp;
@@ -824,7 +822,7 @@ muc_factory_message_cb (LmMessageHandler *handler,
void
gabble_muc_factory_broadcast_presence (GabbleMucFactory *self)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
GHashTableIter iter;
gpointer channel = NULL;
@@ -842,7 +840,7 @@ gabble_muc_factory_associate_request (GabbleMucFactory *self,
gpointer channel,
gpointer request)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
GSList *list = g_hash_table_lookup (priv->queued_requests, channel);
g_assert (TP_IS_EXPORTABLE_CHANNEL (channel));
@@ -880,7 +878,7 @@ cancel_queued_requests (gpointer k,
static void
gabble_muc_factory_close_all (GabbleMucFactory *self)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
DEBUG ("closing channels");
@@ -895,9 +893,9 @@ gabble_muc_factory_close_all (GabbleMucFactory *self)
g_hash_table_foreach_steal (priv->queued_requests,
cancel_queued_requests, self);
- tp_clear_pointer (&priv->queued_requests, g_hash_table_destroy);
- tp_clear_pointer (&priv->text_needed_for_tubes, g_hash_table_destroy);
- tp_clear_pointer (&priv->tubes_needed_for_tube, g_hash_table_destroy);
+ 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);
/* Use a temporary variable because we don't want
* muc_channel_closed_cb or tubes_channel_closed_cb to remove the channel
@@ -914,7 +912,7 @@ gabble_muc_factory_close_all (GabbleMucFactory *self)
while (g_hash_table_iter_next (&iter, NULL, &chan))
gabble_muc_channel_teardown (GABBLE_MUC_CHANNEL (chan));
- g_hash_table_destroy (tmp);
+ g_hash_table_unref (tmp);
}
if (priv->message_cb != NULL)
@@ -935,7 +933,7 @@ connection_status_changed_cb (GabbleConnection *conn,
guint reason,
GabbleMucFactory *self)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
switch (status)
{
@@ -964,7 +962,7 @@ gabble_muc_factory_constructor (GType type, guint n_props,
GObject *obj = G_OBJECT_CLASS (gabble_muc_factory_parent_class)->
constructor (type, n_props, props);
GabbleMucFactory *self = GABBLE_MUC_FACTORY (obj);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
priv->status_changed_id = g_signal_connect (priv->conn,
"status-changed", (GCallback) connection_status_changed_cb, obj);
@@ -1009,7 +1007,7 @@ gabble_muc_factory_foreach_channel (TpChannelManager *manager,
gpointer user_data)
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (manager);
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (fac);
+ GabbleMucFactoryPrivate *priv = fac->priv;
struct _ForeachData data;
data.user_data = user_data;
@@ -1035,7 +1033,8 @@ ensure_muc_channel (GabbleMucFactory *fac,
gboolean requested,
GHashTable *initial_channels,
GArray *initial_handles,
- char **initial_ids)
+ char **initial_ids,
+ const char *room_name)
{
TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn;
@@ -1044,7 +1043,7 @@ 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);
+ requested, initial_channels, initial_handles, initial_ids, room_name);
return FALSE;
}
@@ -1062,7 +1061,7 @@ gabble_muc_factory_handle_si_stream_request (GabbleMucFactory *self,
const gchar *stream_id,
LmMessage *msg)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
TpHandleRepoIface *room_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_ROOM);
GabbleMucChannel *gmuc = NULL;
@@ -1092,15 +1091,15 @@ GabbleMucChannel *
gabble_muc_factory_find_text_channel (GabbleMucFactory *self,
TpHandle handle)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
return g_hash_table_lookup (priv->text_channels, GUINT_TO_POINTER (handle));
}
static const gchar * const muc_channel_fixed_properties[] = {
- TP_IFACE_CHANNEL ".ChannelType",
- TP_IFACE_CHANNEL ".TargetHandleType",
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
NULL
};
@@ -1108,18 +1107,20 @@ static const gchar * const * muc_tubes_channel_fixed_properties =
muc_channel_fixed_properties;
static const gchar * const muc_channel_allowed_properties[] = {
- TP_IFACE_CHANNEL ".TargetHandle",
- TP_IFACE_CHANNEL ".TargetID",
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels",
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeHandles",
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeIDs",
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InvitationMessage",
+ TP_PROP_CHANNEL_TARGET_HANDLE,
+ TP_PROP_CHANNEL_TARGET_ID,
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_CHANNELS,
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_HANDLES,
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS,
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INVITATION_MESSAGE,
+ TP_PROP_CHANNEL_INTERFACE_ROOM_ROOM_NAME,
+ TP_PROP_CHANNEL_INTERFACE_ROOM_SERVER,
NULL
};
static const gchar * const muc_tubes_channel_allowed_properties[] = {
- TP_IFACE_CHANNEL ".TargetHandle",
- TP_IFACE_CHANNEL ".TargetID",
+ TP_PROP_CHANNEL_TARGET_HANDLE,
+ TP_PROP_CHANNEL_TARGET_ID,
NULL
};
@@ -1134,12 +1135,12 @@ gabble_muc_factory_type_foreach_channel_class (GType type,
channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
/* no string value yet - we'll change it for each channel class */
- g_hash_table_insert (table, TP_IFACE_CHANNEL ".ChannelType",
+ g_hash_table_insert (table, TP_PROP_CHANNEL_CHANNEL_TYPE,
channel_type_value);
handle_type_value = tp_g_value_slice_new (G_TYPE_UINT);
g_value_set_uint (handle_type_value, TP_HANDLE_TYPE_ROOM);
- g_hash_table_insert (table, TP_IFACE_CHANNEL ".TargetHandleType",
+ g_hash_table_insert (table, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
handle_type_value);
/* Channel.Type.Text */
@@ -1171,7 +1172,7 @@ gabble_muc_factory_type_foreach_channel_class (GType type,
gabble_media_factory_call_channel_allowed_properties (),
user_data);
- g_hash_table_destroy (table);
+ g_hash_table_unref (table);
}
/* return TRUE if the text_channel associated is ready */
@@ -1181,14 +1182,14 @@ ensure_tubes_channel (GabbleMucFactory *self,
GabbleTubesChannel **tubes_chan,
gboolean requested)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ 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, NULL, NULL, NULL);
/* this refs the tube channel object */
*tubes_chan = gabble_muc_channel_open_tube (text_chan, initiator, requested);
@@ -1207,7 +1208,7 @@ handle_text_channel_request (GabbleMucFactory *self,
TpHandle room,
GError **error)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
TpBaseConnection *conn = TP_BASE_CONNECTION (priv->conn);
GabbleMucChannel *text_chan;
TpHandleSet *handles;
@@ -1226,22 +1227,29 @@ handle_text_channel_request (GabbleMucFactory *self,
char **initial_ids, **final_ids;
const char *invite_msg;
+ const gchar *room_name, *server_prop;
+
if (tp_channel_manager_asv_has_unknown_properties (request_properties,
muc_channel_fixed_properties, muc_channel_allowed_properties,
error))
return FALSE;
initial_channels = tp_asv_get_boxed (request_properties,
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels",
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_CHANNELS,
TP_ARRAY_TYPE_OBJECT_PATH_LIST);
initial_handles = tp_asv_get_boxed (request_properties,
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeHandles",
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_HANDLES,
DBUS_TYPE_G_UINT_ARRAY);
initial_ids = tp_asv_get_boxed (request_properties,
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeIDs",
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS,
G_TYPE_STRV);
invite_msg = tp_asv_get_string (request_properties,
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InvitationMessage");
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INVITATION_MESSAGE);
+
+ room_name = tp_asv_get_string (request_properties,
+ TP_PROP_CHANNEL_INTERFACE_ROOM_ROOM_NAME);
+ server_prop = tp_asv_get_string (request_properties,
+ TP_PROP_CHANNEL_INTERFACE_ROOM_SERVER);
handles = tp_handle_set_new (contact_handles);
continue_handles = tp_intset_new ();
@@ -1339,9 +1347,11 @@ handle_text_channel_request (GabbleMucFactory *self,
final_ids[i] = (char *) id;
}
+ /* TargetHandleType=None and TargetHandle=0 */
if (room == 0)
{
char *uuid, *id, *server = "";
+ gchar *tmp = NULL;
/* There's no super obvious way to tell.. you can't invite GMail users to
* a non-Google MUC (it just doesn't work), and if your own account is on
@@ -1365,15 +1375,29 @@ handle_text_channel_request (GabbleMucFactory *self,
}
}
- uuid = gabble_generate_id ();
- id = g_strdup_printf ("private-chat-%s%s", uuid, server);
+ if (server_prop != NULL)
+ {
+ tmp = g_strdup_printf ("@%s", server_prop);
+ server = tmp;
+ }
- DEBUG ("Creating PMUC '%s'", id);
+ if (room_name != NULL && room_name[0] != '\0')
+ {
+ id = g_strdup_printf ("%s%s", room_name, server);
+ }
+ else
+ {
+ uuid = gabble_generate_id ();
+ id = g_strdup_printf ("private-chat-%s%s", uuid, server);
+ g_free (uuid);
+
+ DEBUG ("Creating PMUC '%s'", id);
+ }
room = tp_handle_ensure (room_handles, id, NULL, error);
- g_free (uuid);
g_free (id);
+ g_free (tmp);
if (room == 0)
{
@@ -1387,8 +1411,66 @@ handle_text_channel_request (GabbleMucFactory *self,
tp_handle_ref (room_handles, room);
}
+ /* Make sure TargetID and RoomName don't conflict. */
+ if (room_name != NULL && room_name[0] != '\0')
+ {
+ const gchar *target_id = tp_handle_inspect (room_handles, room);
+ gchar *target_room = NULL;
+ gboolean ok;
+
+ /* JIDs that are handles must already be valid. */
+ ok = wocky_decode_jid (target_id, &target_room, NULL, NULL);
+ g_assert (ok);
+
+ ok = !tp_strdiff (target_room, room_name);
+
+ if (!ok)
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "TargetID's node part (%s) doesn't match RoomName (%s)",
+ target_room, room_name);
+ ret = FALSE;
+ }
+
+ g_free (target_room);
+
+ if (!ok)
+ goto out;
+ }
+
+ /* Make sure TargetID and Server don't conflict. */
+ if (server_prop != NULL)
+ {
+ const gchar *target_id = tp_handle_inspect (room_handles, room);
+ gchar *target_server = NULL;
+ gboolean ok = TRUE;
+
+ /* JIDs that are handles must already be valid. */
+ ok = wocky_decode_jid (target_id, NULL, &target_server, NULL);
+ g_assert (ok);
+
+ if (target_server != NULL)
+ ok = !tp_strdiff (target_server, server_prop);
+ else
+ ok = TRUE;
+
+ if (!ok)
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "TargetID's domain part (%s) doesn't match Server (%s)",
+ target_server, server_prop);
+ ret = FALSE;
+ }
+
+ g_free (target_server);
+
+ if (!ok)
+ goto out;
+
+ }
+
if (ensure_muc_channel (self, priv, room, &text_chan, TRUE,
- final_channels, final_handles, final_ids))
+ final_channels, final_handles, final_ids, room_name))
{
/* channel exists */
@@ -1454,8 +1536,8 @@ out:
if (room != 0)
tp_handle_unref (room_handles, room);
- g_hash_table_destroy (final_channels);
- g_array_free (final_handles, TRUE);
+ g_hash_table_unref (final_channels);
+ g_array_unref (final_handles);
g_free (final_ids);
tp_handle_set_destroy (handles);
@@ -1472,7 +1554,7 @@ handle_tubes_channel_request (GabbleMucFactory *self,
TpHandle handle,
GError **error)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
GabbleTubesChannel *tube = NULL;
GabbleMucChannel *gmuc = NULL;
@@ -1529,7 +1611,7 @@ handle_tube_channel_request (GabbleMucFactory *self,
GError **error)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
gboolean can_announce_now = TRUE;
gboolean tubes_channel_created = FALSE;
GabbleTubesChannel *tube = NULL;
@@ -1575,7 +1657,7 @@ handle_tube_channel_request (GabbleMucFactory *self,
g_hash_table_insert (channels, new_channel, request_tokens);
tp_channel_manager_emit_new_channels (self, channels);
- g_hash_table_destroy (channels);
+ g_hash_table_unref (channels);
g_slist_free (request_tokens);
}
else
@@ -1617,12 +1699,12 @@ handle_stream_tube_channel_request (GabbleMucFactory *self,
/* "Service" is a mandatory, not-fixed property */
service = tp_asv_get_string (request_properties,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
+ TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE);
if (service == NULL)
{
g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
"Request does not contain the mandatory property '%s'",
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
+ TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE);
return FALSE;
}
@@ -1648,12 +1730,12 @@ handle_dbus_tube_channel_request (GabbleMucFactory *self,
/* "ServiceName" is a mandatory, not-fixed property */
service = tp_asv_get_string (request_properties,
- TP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName");
+ TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME);
if (service == NULL)
{
g_set_error (error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
"Request does not contain the mandatory property '%s'",
- TP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName");
+ TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME);
return FALSE;
}
@@ -1695,7 +1777,7 @@ handle_call_channel_request (GabbleMucFactory *self,
TpHandle handle,
GError **error)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
gboolean initial_audio, initial_video;
GabbleMucChannel *muc;
GabbleCallMucChannel *call;
@@ -1719,7 +1801,7 @@ handle_call_channel_request (GabbleMucFactory *self,
return FALSE;
}
- ensure_muc_channel (self, priv, handle, &muc, FALSE, NULL, NULL, NULL);
+ ensure_muc_channel (self, priv, handle, &muc, FALSE, NULL, NULL, NULL, NULL);
call = gabble_muc_channel_get_call (muc);
@@ -1758,6 +1840,27 @@ error:
return FALSE;
}
+typedef gboolean (*ChannelTypeHandlerFunc) (
+ GabbleMucFactory *self,
+ gpointer request_token,
+ GHashTable *request_properties,
+ gboolean require_new,
+ TpHandle room,
+ GError **error);
+
+typedef struct {
+ const gchar *channel_type;
+ ChannelTypeHandlerFunc f;
+} ChannelTypeHandler;
+
+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 },
+ { TPY_IFACE_CHANNEL_TYPE_CALL, handle_call_channel_request },
+ { NULL }
+};
static gboolean
gabble_muc_factory_request (GabbleMucFactory *self,
@@ -1768,80 +1871,57 @@ gabble_muc_factory_request (GabbleMucFactory *self,
GError *error = NULL;
TpHandleType handle_type;
TpHandle handle;
- gboolean conference;
+ gboolean conference, room;
const gchar *channel_type;
+ ChannelTypeHandler *h;
handle_type = tp_asv_get_uint32 (request_properties,
- TP_IFACE_CHANNEL ".TargetHandleType", NULL);
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL);
channel_type = tp_asv_get_string (request_properties,
- TP_IFACE_CHANNEL ".ChannelType");
+ TP_PROP_CHANNEL_CHANNEL_TYPE);
/* Conference channels can be anonymous (HandleTypeNone) */
conference = (handle_type == TP_HANDLE_TYPE_NONE &&
!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT) &&
(g_hash_table_lookup (request_properties,
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels") ||
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_CHANNELS) ||
g_hash_table_lookup (request_properties,
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeHandles") ||
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_HANDLES) ||
g_hash_table_lookup (request_properties,
- TP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeIDs")));
+ TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS)));
- /* the channel must either be a room, or a new conference */
- if (handle_type != TP_HANDLE_TYPE_ROOM && !conference)
- return FALSE;
+ room = (handle_type == TP_HANDLE_TYPE_NONE
+ && !tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT)
+ && g_hash_table_lookup (request_properties,
+ TP_PROP_CHANNEL_INTERFACE_ROOM_ROOM_NAME));
- if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT) &&
- tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES) &&
- tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE) &&
- tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE) &&
- tp_strdiff (channel_type, TPY_IFACE_CHANNEL_TYPE_CALL))
+ /* the channel must either be a room, or a new conference */
+ if (handle_type != TP_HANDLE_TYPE_ROOM && !conference && !room)
return FALSE;
/* validity already checked by TpBaseConnection */
handle = tp_asv_get_uint32 (request_properties,
- TP_IFACE_CHANNEL ".TargetHandle", NULL);
- g_assert (conference || handle != 0);
+ TP_PROP_CHANNEL_TARGET_HANDLE, NULL);
+ g_assert (conference || room || handle != 0);
- if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT))
+ for (h = channel_type_handlers; h->channel_type != NULL; h++)
{
- if (handle_text_channel_request (self, request_token,
- request_properties, require_new, handle, &error))
- return TRUE;
- }
- else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES))
- {
- if (handle_tubes_channel_request (self, request_token,
- request_properties, require_new, handle, &error))
- return TRUE;
- }
- else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE))
- {
- if (handle_stream_tube_channel_request (self, request_token,
- request_properties, require_new, handle, &error))
- return TRUE;
- }
- else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
- {
- if (handle_dbus_tube_channel_request (self, request_token,
- request_properties, require_new, handle, &error))
- return TRUE;
- }
- else if (!tp_strdiff (channel_type, TPY_IFACE_CHANNEL_TYPE_CALL))
- {
- if (handle_call_channel_request (self, request_token,
- request_properties, require_new, handle, &error))
- return TRUE;
- }
- else
- {
- g_assert_not_reached ();
+ if (tp_strdiff (channel_type, h->channel_type))
+ continue;
+
+ if (!h->f (self, request_token, request_properties, require_new,
+ handle, &error))
+ {
+ tp_channel_manager_emit_request_failed (self, request_token,
+ error->domain, error->code, error->message);
+ g_error_free (error);
+ }
+
+ /* We've handled the request one way or another. */
+ return TRUE;
}
- /* Something failed */
- tp_channel_manager_emit_request_failed (self, request_token,
- error->domain, error->code, error->message);
- g_error_free (error);
- return TRUE;
+ return FALSE;
}
@@ -1884,7 +1964,7 @@ gboolean
gabble_muc_factory_handle_jingle_session (GabbleMucFactory *self,
GabbleJingleSession *session)
{
- GabbleMucFactoryPrivate *priv = GABBLE_MUC_FACTORY_GET_PRIVATE (self);
+ GabbleMucFactoryPrivate *priv = self->priv;
TpHandleRepoIface *room_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_ROOM);
TpHandle room;