summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSenko Rasic <senko.rasic@collabora.co.uk>2006-10-03 20:39:39 +0000
committerSenko Rasic <senko.rasic@collabora.co.uk>2006-10-03 20:39:39 +0000
commit0c46dac7cf6cf034cfd5b4342dcd239074951d75 (patch)
tree60052521c25638a3643e08beb0bce69682fc79b0
parentcc5a1f0d23eb2e3a77c5050c014f5a6ee8540e13 (diff)
backport from head: support presence from JIDs with no resource [dafydd.harries@collabora.co.uk]
-rw-r--r--src/gabble-presence-cache.c6
-rw-r--r--src/gabble-presence.c29
-rw-r--r--tests/test-gabble-presence.c12
3 files changed, 37 insertions, 10 deletions
diff --git a/src/gabble-presence-cache.c b/src/gabble-presence-cache.c
index c724f055e..5bb0e361c 100644
--- a/src/gabble-presence-cache.c
+++ b/src/gabble-presence-cache.c
@@ -420,12 +420,6 @@ _parse_presence_message (GabblePresenceCache *cache,
gabble_handle_decode_jid (from, NULL, NULL, &resource);
- if (resource == NULL)
- {
- HANDLER_DEBUG (presence_node, "ignoring presence with no resource");
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
- }
-
presence = gabble_presence_cache_get (cache, handle);
if (NULL != presence)
diff --git a/src/gabble-presence.c b/src/gabble-presence.c
index 6d70badc9..7bdb2f61e 100644
--- a/src/gabble-presence.c
+++ b/src/gabble-presence.c
@@ -42,6 +42,7 @@ struct _Resource {
typedef struct _GabblePresencePrivate GabblePresencePrivate;
struct _GabblePresencePrivate {
+ gchar *no_resource_status_message;
GSList *resources;
};
@@ -76,6 +77,7 @@ gabble_presence_finalize (GObject *object)
g_slist_free (priv->resources);
g_free (presence->nickname);
+ g_free (priv->no_resource_status_message);
}
static void
@@ -172,14 +174,33 @@ gabble_presence_update (GabblePresence *presence, const gchar *resource, GabbleP
guint8 prio;
gboolean ret = FALSE;
- g_assert (NULL != resource);
-
- res = _find_resource (presence, resource);
-
/* save our current state */
old_status = presence->status;
old_status_message = g_strdup (presence->status_message);
+ if (NULL == resource)
+ {
+ /* presence from a JID with no resource: free all resources and set
+ * presence directly */
+
+ for (i = priv->resources; i; i = i->next)
+ _resource_free (i->data);
+
+ g_slist_free (priv->resources);
+ priv->resources = NULL;
+
+ if (g_strdiff (priv->no_resource_status_message, status_message))
+ {
+ g_free (priv->no_resource_status_message);
+ priv->no_resource_status_message = g_strdup (status_message);
+ }
+
+ presence->status = status;
+ presence->status_message = priv->no_resource_status_message;
+ }
+
+ res = _find_resource (presence, resource);
+
/* remove, create or update a Resource as appropriate */
if (GABBLE_PRESENCE_OFFLINE == status &&
NULL == status_message)
diff --git a/tests/test-gabble-presence.c b/tests/test-gabble-presence.c
index a1b1fbac4..f975f02b0 100644
--- a/tests/test-gabble-presence.c
+++ b/tests/test-gabble-presence.c
@@ -70,6 +70,18 @@ int main(int argc, char **argv)
PRESENCE_CAP_GOOGLE_VOICE);
g_assert (0 == strcmp ("foo", resource));
+ /* presence turns up from null resource; it trumps other presence regardless
+ * of whether status is more present or not */
+ g_assert (TRUE == gabble_presence_update (presence, NULL,
+ GABBLE_PRESENCE_OFFLINE, "gone", 0));
+ g_assert (GABBLE_PRESENCE_OFFLINE == presence->status);
+ g_assert (0 == strcmp("gone", presence->status_message));
+
+ /* caps are gone too */
+ resource = gabble_presence_pick_resource_by_caps (presence,
+ PRESENCE_CAP_GOOGLE_VOICE);
+ g_assert (NULL == resource);
+
return 0;
}