summaryrefslogtreecommitdiff
path: root/src/conn-presence.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conn-presence.c')
-rw-r--r--src/conn-presence.c237
1 files changed, 108 insertions, 129 deletions
diff --git a/src/conn-presence.c b/src/conn-presence.c
index 55c75fe02..9dfd6b6b1 100644
--- a/src/conn-presence.c
+++ b/src/conn-presence.c
@@ -30,8 +30,7 @@
#include <telepathy-glib/util.h>
#include <telepathy-glib/interfaces.h>
-#include <wocky/wocky-c2s-porter.h>
-#include <wocky/wocky-utils.h>
+#include <wocky/wocky.h>
#define DEBUG_FLAG GABBLE_DEBUG_CONNECTION
@@ -58,7 +57,7 @@ typedef enum {
struct _GabbleConnectionPresencePrivate {
InvisibilityMethod invisibility_method;
- LmMessageHandler *iq_list_push_cb;
+ guint iq_list_push_id;
gchar *invisible_list_name;
/* Mapping between status "show" strings, and shared statuses */
@@ -123,22 +122,24 @@ static TpPresenceStatusSpec *gabble_statuses = NULL;
/* prototypes */
-static LmHandlerResult set_xep0186_invisible_cb (GabbleConnection *conn,
- LmMessage *sent_msg, LmMessage *reply_msg, GObject *obj,
+static void set_xep0186_invisible_cb (GabbleConnection *conn,
+ WockyStanza *sent_msg, WockyStanza *reply_msg, GObject *obj,
gpointer user_data);
-static LmHandlerResult activate_current_privacy_list_cb (
- GabbleConnection *conn, LmMessage *sent_msg, LmMessage *reply_msg,
+static void activate_current_privacy_list_cb (
+ GabbleConnection *conn, WockyStanza *sent_msg, WockyStanza *reply_msg,
GObject *obj, gpointer user_data);
static void setup_invisible_privacy_list_async (GabbleConnection *self,
GAsyncReadyCallback callback, gpointer user_data);
-static LmHandlerResult iq_privacy_list_push_cb (LmMessageHandler *handler,
- LmConnection *connection, LmMessage *message, gpointer user_data);
+static gboolean iq_privacy_list_push_cb (
+ WockyPorter *porter,
+ WockyStanza *message,
+ gpointer user_data);
-static LmHandlerResult verify_invisible_privacy_list_cb (
- GabbleConnection *conn, LmMessage *sent_msg, LmMessage *reply_msg,
+static void verify_invisible_privacy_list_cb (
+ GabbleConnection *conn, WockyStanza *sent_msg, WockyStanza *reply_msg,
GObject *obj, gpointer user_data);
static void toggle_presence_visibility_async (GabbleConnection *self,
@@ -512,7 +513,7 @@ set_xep0186_invisible (GabbleConnection *self,
g_object_unref (result);
}
}
- else if (!_gabble_connection_send_with_reply (self, (LmMessage *) iq,
+ else if (!_gabble_connection_send_with_reply (self, (WockyStanza *) iq,
set_xep0186_invisible_cb, NULL, result, &error))
{
g_simple_async_result_set_from_error (result, error);
@@ -525,21 +526,22 @@ set_xep0186_invisible (GabbleConnection *self,
g_object_unref (iq);
}
-static LmHandlerResult
+static void
set_xep0186_invisible_cb (GabbleConnection *conn,
- LmMessage *sent_msg,
- LmMessage *reply_msg,
+ WockyStanza *sent_msg,
+ WockyStanza *reply_msg,
GObject *obj,
gpointer user_data)
{
GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
GError *error = NULL;
- if (lm_message_get_sub_type (reply_msg) == LM_MESSAGE_SUB_TYPE_ERROR)
+ if (wocky_stanza_extract_errors (reply_msg, NULL, &error, NULL, NULL))
{
g_simple_async_result_set_error (result,
CONN_PRESENCE_ERROR, CONN_PRESENCE_ERROR_SET_INVISIBLE,
- "error setting XEP-0186 (in)visiblity");
+ "error setting XEP-0186 (in)visiblity: %s", error->message);
+ g_clear_error (&error);
}
else
{
@@ -561,8 +563,6 @@ set_xep0186_invisible_cb (GabbleConnection *conn,
g_simple_async_result_complete (result);
g_object_unref (result);
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
@@ -577,7 +577,7 @@ activate_current_privacy_list (GabbleConnection *self,
gboolean invisible;
GabblePresence *presence = self->self_presence;
GError *error = NULL;
- LmMessageNode *active_node;
+ WockyNode *active_node;
g_assert (priv->privacy_statuses != NULL);
@@ -607,7 +607,7 @@ activate_current_privacy_list (GabbleConnection *self,
if (base->status == TP_CONNECTION_STATUS_CONNECTED && invisible)
{
if (!gabble_connection_send_presence (self,
- LM_MESSAGE_SUB_TYPE_UNAVAILABLE, NULL, NULL, &error))
+ WOCKY_STANZA_SUB_TYPE_UNAVAILABLE, NULL, NULL, &error))
goto ERROR;
}
/* If we're still connecting and there's no list to be set, we don't
@@ -625,7 +625,7 @@ activate_current_privacy_list (GabbleConnection *self,
goto OUT;
}
- _gabble_connection_send_with_reply (self, (LmMessage *) iq,
+ _gabble_connection_send_with_reply (self, (WockyStanza *) iq,
activate_current_privacy_list_cb, NULL, result, &error);
ERROR:
@@ -641,21 +641,22 @@ activate_current_privacy_list (GabbleConnection *self,
g_object_unref (iq);
}
-static LmHandlerResult
+static void
activate_current_privacy_list_cb (GabbleConnection *conn,
- LmMessage *sent_msg,
- LmMessage *reply_msg,
+ WockyStanza *sent_msg,
+ WockyStanza *reply_msg,
GObject *obj,
gpointer user_data)
{
GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
GError *error = NULL;
- if (lm_message_get_sub_type (reply_msg) == LM_MESSAGE_SUB_TYPE_ERROR)
+ if (wocky_stanza_extract_errors (reply_msg, NULL, &error, NULL, NULL))
{
g_simple_async_result_set_error (result,
CONN_PRESENCE_ERROR, CONN_PRESENCE_ERROR_SET_PRIVACY_LIST,
- "error setting requested privacy list");
+ "error setting requested privacy list: %s", error->message);
+ g_clear_error (&error);
}
else
{
@@ -674,8 +675,6 @@ activate_current_privacy_list_cb (GabbleConnection *conn,
g_simple_async_result_complete (result);
g_object_unref (result);
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
static void
@@ -696,29 +695,25 @@ disable_invisible_privacy_list (GabbleConnection *self)
}
}
-static LmHandlerResult
+static void
create_invisible_privacy_list_reply_cb (GabbleConnection *conn,
- LmMessage *sent_msg,
- LmMessage *reply_msg,
+ WockyStanza *sent_msg,
+ WockyStanza *reply_msg,
GObject *obj,
gpointer user_data)
{
GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
+ GError *error = NULL;
- if (lm_message_get_sub_type (reply_msg) == LM_MESSAGE_SUB_TYPE_ERROR)
+ if (wocky_stanza_extract_errors (reply_msg, NULL, &error, NULL, NULL))
{
- GError *error = gabble_message_get_xmpp_error (reply_msg);
-
g_simple_async_result_set_from_error (result, error);
-
g_free (error);
}
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
static void
@@ -746,7 +741,7 @@ create_invisible_privacy_list_async (GabbleConnection *self,
DEBUG ("Creating '%s'", self->presence_priv->invisible_list_name);
- if (!_gabble_connection_send_with_reply (self, (LmMessage *) iq,
+ if (!_gabble_connection_send_with_reply (self, (WockyStanza *) iq,
create_invisible_privacy_list_reply_cb, NULL, result, &error))
{
g_simple_async_result_set_from_error (result, error);
@@ -925,53 +920,37 @@ iq_shared_status_changed_cb (WockyPorter *porter,
WockyNode *query_node = wocky_node_get_child_ns (
wocky_stanza_get_top_node (stanza), "query",
NS_GOOGLE_SHARED_STATUS);
- WockyStanza *result;
if (store_shared_statuses (self, query_node))
emit_presences_changed_for_self (self);
- result = wocky_stanza_build_iq_result (stanza, NULL);
-
- wocky_porter_send (porter, result);
-
- g_object_unref (result);
+ wocky_porter_acknowledge_iq (porter, stanza, NULL);
return TRUE;
}
-static LmHandlerResult
-iq_privacy_list_push_cb (LmMessageHandler *handler,
- LmConnection *connection,
- LmMessage *message,
+static gboolean
+iq_privacy_list_push_cb (
+ WockyPorter *porter,
+ WockyStanza *message,
gpointer user_data)
{
GabbleConnection *conn = GABBLE_CONNECTION (user_data);
- LmMessage *result;
- LmMessageNode *list_node, *iq;
+ WockyNode *list_node, *query_node, *iq;
const gchar *list_name;
- if (lm_message_get_sub_type (message) != LM_MESSAGE_SUB_TYPE_SET)
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
-
- iq = lm_message_get_node (message);
- list_node = lm_message_node_find_child (iq, "list");
-
- if (!lm_message_node_get_child_with_namespace (iq, "query", NS_PRIVACY) ||
- !list_node)
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ wocky_porter_acknowledge_iq (wocky_session_get_porter (conn->session),
+ message, NULL);
- result = lm_iq_message_make_result (message);
-
- wocky_porter_send (wocky_session_get_porter (conn->session), result);
-
- list_name = lm_message_node_get_attribute (list_node, "name");
+ iq = wocky_stanza_get_top_node (message);
+ query_node = wocky_node_get_first_child (iq);
+ list_node = wocky_node_get_child (query_node, "list");
+ list_name = wocky_node_get_attribute (list_node, "name");
if (g_strcmp0 (list_name, conn->presence_priv->invisible_list_name) == 0)
setup_invisible_privacy_list_async (conn, NULL, NULL);
- lm_message_unref (result);
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+ return TRUE;
}
/**********************************************************************
@@ -1099,19 +1078,19 @@ get_shared_status_finish (GabbleConnection *self,
wocky_implement_finish_void (self, get_shared_status_async);
}
-static LmHandlerResult
+static void
get_existing_privacy_lists_cb (GabbleConnection *conn,
- LmMessage *sent_msg,
- LmMessage *reply_msg,
+ WockyStanza *sent_msg,
+ WockyStanza *reply_msg,
GObject *obj,
gpointer user_data)
{
GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
WockyNode *query_node = wocky_node_get_child_ns (
wocky_stanza_get_top_node (reply_msg), "query", NS_PRIVACY);
- GError *error = gabble_message_get_xmpp_error (reply_msg);
+ GError *error = NULL;
- if (error != NULL)
+ if (wocky_stanza_extract_errors (reply_msg, NULL, &error, NULL, NULL))
{
DEBUG ("Error getting privacy lists: %s", error->message);
@@ -1127,7 +1106,7 @@ get_existing_privacy_lists_cb (GabbleConnection *conn,
else
{
GabbleConnectionPresencePrivate *priv = conn->presence_priv;
- LmMessageNode *list_node;
+ WockyNode *list_node;
WockyNodeIter iter;
GabblePluginLoader *loader = gabble_plugin_loader_dup ();
@@ -1141,7 +1120,7 @@ get_existing_privacy_lists_cb (GabbleConnection *conn,
wocky_node_iter_init (&iter, query_node, "list", NULL);
while (wocky_node_iter_next (&iter, &list_node))
{
- const gchar *list_name = lm_message_node_get_attribute (list_node,
+ const gchar *list_name = wocky_node_get_attribute (list_node,
"name");
const gchar *status_name;
@@ -1162,8 +1141,6 @@ get_existing_privacy_lists_cb (GabbleConnection *conn,
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
static void
@@ -1183,7 +1160,7 @@ get_existing_privacy_lists_async (GabbleConnection *self,
')',
NULL);
- if (!_gabble_connection_send_with_reply (self, (LmMessage *) iq,
+ if (!_gabble_connection_send_with_reply (self, (WockyStanza *) iq,
get_existing_privacy_lists_cb, NULL, result, &error))
{
g_simple_async_result_set_from_error (result, error);
@@ -1229,7 +1206,7 @@ setup_invisible_privacy_list_async (GabbleConnection *self,
')',
NULL);
- if (!_gabble_connection_send_with_reply (self, (LmMessage *) iq,
+ if (!_gabble_connection_send_with_reply (self, (WockyStanza *) iq,
verify_invisible_privacy_list_cb, NULL, result, &error))
{
g_simple_async_result_set_from_error (result, error);
@@ -1251,23 +1228,21 @@ setup_invisible_privacy_list_finish (GabbleConnection *self,
}
static gboolean
-is_valid_invisible_list (LmMessageNode *list_node)
+is_valid_invisible_list (WockyNode *list_node)
{
- LmMessageNode *top_node = NULL;
- NodeIter i;
+ WockyNode *top_node = NULL;
+ WockyNode *child;
+ WockyNodeIter i;
guint top_order = G_MAXUINT;
- for (i = node_iter (list_node); i; i = node_iter_next (i))
+ wocky_node_iter_init (&i, list_node, "item", NULL);
+ while (wocky_node_iter_next (&i, &child))
{
- LmMessageNode *child = node_iter_data (i);
const gchar *order_str;
guint order;
gchar *end;
- if (g_strcmp0 (lm_message_node_get_name (child), "item") != 0)
- continue;
-
- order_str = lm_message_node_get_attribute (child, "order");
+ order_str = wocky_node_get_attribute (child, "order");
if (order_str == NULL)
continue;
@@ -1286,9 +1261,9 @@ is_valid_invisible_list (LmMessageNode *list_node)
if (top_node != NULL)
{
- const gchar *value = lm_message_node_get_attribute (top_node, "value");
- const gchar *action = lm_message_node_get_attribute (top_node, "action");
- LmMessageNode *presence_out = lm_message_node_get_child (top_node,
+ const gchar *value = wocky_node_get_attribute (top_node, "value");
+ const gchar *action = wocky_node_get_attribute (top_node, "action");
+ WockyNode *presence_out = wocky_node_get_child (top_node,
"presence-out");
return (value == NULL && g_strcmp0 (action, "deny") == 0 &&
@@ -1298,22 +1273,27 @@ is_valid_invisible_list (LmMessageNode *list_node)
return FALSE;
}
-static LmHandlerResult
+static void
verify_invisible_privacy_list_cb (GabbleConnection *conn,
- LmMessage *sent_msg,
- LmMessage *reply_msg,
+ WockyStanza *sent_msg,
+ WockyStanza *reply_msg,
GObject *obj,
gpointer user_data)
{
GabbleConnectionPresencePrivate *priv = conn->presence_priv;
- LmMessageNode *node = lm_message_node_find_child
- (wocky_stanza_get_top_node (reply_msg), "list");
- GError *error = gabble_message_get_xmpp_error (reply_msg);
+ WockyNode *query_node, *list_node = NULL;
+ GError *error = NULL;
+
+ query_node = wocky_node_get_child_ns (wocky_stanza_get_top_node (reply_msg),
+ "query", NS_PRIVACY);
+
+ if (query_node != NULL)
+ list_node = wocky_node_get_child (query_node, "list");
- if (lm_message_get_sub_type (reply_msg) == LM_MESSAGE_SUB_TYPE_RESULT &&
- node != NULL)
+ if (!wocky_stanza_extract_errors (reply_msg, NULL, &error, NULL, NULL) &&
+ list_node != NULL)
{
- if (!is_valid_invisible_list (node))
+ if (!is_valid_invisible_list (list_node))
{
g_free (priv->invisible_list_name);
priv->invisible_list_name = g_strdup ("invisible-gabble");
@@ -1331,29 +1311,22 @@ verify_invisible_privacy_list_cb (GabbleConnection *conn,
toggle_presence_visibility_async (conn,
toggle_initial_presence_visibility_cb, user_data);
}
-
- goto OUT;
}
- else if (error != NULL)
+ else if (error->code == WOCKY_XMPP_ERROR_ITEM_NOT_FOUND)
{
- if (error->code == XMPP_ERROR_ITEM_NOT_FOUND)
- {
- create_invisible_privacy_list_async (conn,
- create_invisible_privacy_list_cb, user_data);
- goto OUT;
- }
+ create_invisible_privacy_list_async (conn,
+ create_invisible_privacy_list_cb, user_data);
}
+ else
+ {
+ disable_invisible_privacy_list (conn);
- disable_invisible_privacy_list (conn);
-
- toggle_presence_visibility_async (conn,
- toggle_initial_presence_visibility_cb, user_data);
+ toggle_presence_visibility_async (conn,
+ toggle_initial_presence_visibility_cb, user_data);
+ }
- OUT:
if (error != NULL)
g_error_free (error);
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
static void
@@ -1373,14 +1346,17 @@ initial_presence_setup_cb (GObject *source_object,
g_error_free (error);
}
- if (priv->invisibility_method == INVISIBILITY_METHOD_PRIVACY)
+ if (priv->invisibility_method == INVISIBILITY_METHOD_PRIVACY &&
+ self->session != NULL)
{
- priv->iq_list_push_cb = lm_message_handler_new (iq_privacy_list_push_cb,
- self, NULL);
-
- lm_connection_register_message_handler (self->lmconn,
- priv->iq_list_push_cb, LM_MESSAGE_TYPE_IQ,
- LM_HANDLER_PRIORITY_NORMAL);
+ priv->iq_list_push_id = wocky_c2s_porter_register_handler_from_server (
+ WOCKY_C2S_PORTER (wocky_session_get_porter (self->session)),
+ WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET,
+ WOCKY_PORTER_HANDLER_PRIORITY_NORMAL,
+ iq_privacy_list_push_cb, self,
+ '(', "query", ':', NS_PRIVACY,
+ '(', "list", ')',
+ ')', NULL);
}
g_simple_async_result_complete_in_idle (external_result);
@@ -1593,13 +1569,13 @@ conn_presence_signal_own_presence (GabbleConnection *self,
GabbleConnectionPresencePrivate *priv = self->presence_priv;
GabblePresence *presence = self->self_presence;
TpBaseConnection *base = (TpBaseConnection *) self;
- LmMessage *message = gabble_presence_as_message (presence, to);
+ WockyStanza *message = gabble_presence_as_message (presence, to);
gboolean ret;
if (presence->status == GABBLE_PRESENCE_HIDDEN && to == NULL)
{
if (priv->invisibility_method == INVISIBILITY_METHOD_PRESENCE_INVISIBLE)
- lm_message_node_set_attribute (lm_message_get_node (message),
+ wocky_node_set_attribute (wocky_stanza_get_top_node (message),
"type", "invisible");
/* FIXME: or if sending directed presence, should we add
* <show>away</show>? */
@@ -1609,7 +1585,7 @@ conn_presence_signal_own_presence (GabbleConnection *self,
ret = _gabble_connection_send (self, message, error);
- lm_message_unref (message);
+ g_object_unref (message);
/* FIXME: if sending broadcast presence, should we echo it to everyone we
* previously sent directed presence to? (Perhaps also GC them after a
@@ -2021,6 +1997,12 @@ conn_presence_dispose (GabbleConnection *self)
wocky_porter_unregister_handler (porter, priv->iq_shared_status_cb);
priv->iq_shared_status_cb = 0;
}
+
+ if (priv->iq_list_push_id != 0)
+ {
+ wocky_porter_unregister_handler (porter, priv->iq_list_push_id);
+ priv->iq_list_push_id = 0;
+ }
}
void
@@ -2036,9 +2018,6 @@ conn_presence_finalize (GabbleConnection *conn)
if (priv->shared_statuses != NULL)
g_hash_table_unref (priv->shared_statuses);
- if (priv->iq_list_push_cb != NULL)
- lm_message_handler_unref (priv->iq_list_push_cb);
-
g_slice_free (GabbleConnectionPresencePrivate, priv);
tp_presence_mixin_finalize ((GObject *) conn);