diff options
Diffstat (limited to 'src/conn-presence.c')
-rw-r--r-- | src/conn-presence.c | 237 |
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); |