From e18495d5605c232baa061fc4e1bf116c202fe4c9 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Mon, 28 May 2012 10:30:55 +0200 Subject: [PATCH] WIP: Implement WLM jidlookup See description: http://msdn.microsoft.com/en-us/library/live/hh550849.aspx https://bugs.freedesktop.org/show_bug.cgi?id=50341 --- src/connection.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/connection.h | 1 + src/namespaces.h | 4 ++ 3 files changed, 130 insertions(+) diff --git a/src/connection.c b/src/connection.c index ac46929..35e7e7f 100644 --- a/src/connection.c +++ b/src/connection.c @@ -2823,6 +2823,120 @@ decrement_waiting_connected (GabbleConnection *conn) } static void +conn_wlm_jid_lookup_result_ensure_handle (GSimpleAsyncResult *result, + TpHandleRepoIface *contact_repo, + const gchar *jid, + gpointer context) +{ + TpHandle handle; + GError *error = NULL; + + handle = tp_handle_ensure (contact_repo, jid, context, &error); + if (handle == 0) + { + g_simple_async_result_take_error (result, error); + } + else + { + g_simple_async_result_set_op_res_gpointer (result, + GUINT_TO_POINTER (handle), NULL); + } +} + +typedef struct +{ + GSimpleAsyncResult *result; + TpHandleRepoIface *repo; + gpointer context; +} WLMJidLookupData; + +static void +conn_wlm_jid_lookup_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GabbleConnection *conn = (GabbleConnection *) source; + WLMJidLookupData *data = 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 (data->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)) + { + conn_wlm_jid_lookup_result_ensure_handle (data->result, data->repo, jid, + data->context); + } + else + { + g_simple_async_result_set_error (data->result, + TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "jid not found in getjid reply"); + } + +out: + g_simple_async_result_complete (data->result); + g_object_unref (data->result); + g_slice_free (WLMJidLookupData, data); +} + +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; + WLMJidLookupData *data; + GSimpleAsyncResult *result; + + result = g_simple_async_result_new ((GObject *) repo, callback, user_data, + conn_wlm_jid_lookup_async); + + if (g_str_has_suffix (id, "@messenger.live.com")) + { + /* This is already a jid */ + conn_wlm_jid_lookup_result_ensure_handle (result, repo, id, context); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); + return; + } + + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + conn_util_get_bare_self_jid (self), id, + '(', "getjid", + ':', NS_WLM_JID_LOOKUP, + ')', + NULL); + + data = g_slice_new0 (WLMJidLookupData); + data->result = result; + data->repo = repo; + data->context = context; + + conn_util_send_iq_async (self, iq, NULL, conn_wlm_jid_lookup_cb, data); + + g_object_unref (iq); +} + +static void connection_disco_cb (GabbleDisco *disco, GabbleDiscoRequest *request, const gchar *jid, @@ -2899,12 +3013,23 @@ 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_handle_repo_iface_implement_ensure_handle_async (contact_repo, + conn_wlm_jid_lookup_async, NULL); + } + conn_presence_set_initial_presence_async (conn, connection_initial_presence_cb, NULL); diff --git a/src/connection.h b/src/connection.h index 50734b7..500af0d 100644 --- a/src/connection.h +++ b/src/connection.h @@ -143,6 +143,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/namespaces.h b/src/namespaces.h index 4f8415c..0103aa4 100644 --- a/src/namespaces.h +++ b/src/namespaces.h @@ -134,4 +134,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__ */ -- 1.7.9.5