From 7ba6310cf0981e44ff00bcc69156e18b046667ec Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Wed, 29 May 2013 22:44:56 +0300 Subject: [PATCH] Fix #193: Pidgin Status changes stop working (III) The previous commit only worked, because the SUBSCRIBE message was invalid in another way and generated an error message. It looked that it worked in testing, though... Add the missing "Supported: eventlist" header. But now we're back at square 1, because the server terminates our old subscription again. After studying [MS-PRES] and [MS-SIP] it seems that we should only send the SUBSCRIBE message to the added buddy URI for the case when the server tells us to re-subscribe. Sending the initial single SUBSCRIBE to self URI seems to fix the termination problem. --- src/core/sipe-buddy.c | 3 +-- src/core/sipe-notify.c | 5 +++-- src/core/sipe-subscriptions.c | 40 ++++++++++++++++++++++++++-------------- src/core/sipe-subscriptions.h | 5 ++++- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/core/sipe-buddy.c b/src/core/sipe-buddy.c index 7f130080..5753d9bd 100644 --- a/src/core/sipe-buddy.c +++ b/src/core/sipe-buddy.c @@ -232,8 +232,7 @@ void sipe_core_buddy_add(struct sipe_core_public *sipe_public, struct sipe_buddy *b = sipe_buddy_add(sipe_private, uri); b->just_added = TRUE; - /* @TODO should go to callback */ - sipe_subscribe_presence_single(sipe_private, b->name); + sipe_subscribe_presence_single_cb(sipe_private, b->name); } else { SIPE_DEBUG_INFO("sipe_core_buddy_add: buddy %s already in internal list", diff --git a/src/core/sipe-notify.c b/src/core/sipe-notify.c index 77f9f7ad..c5b06254 100644 --- a/src/core/sipe-notify.c +++ b/src/core/sipe-notify.c @@ -172,7 +172,8 @@ static void process_incoming_notify_rlmi_resub(struct sipe_core_private *sipe_pr g_hash_table_insert(servers, host, server); } else { sipe_subscribe_presence_single(sipe_private, - (void *) uri); + uri, + uri); } } } @@ -1101,7 +1102,7 @@ static void sipe_buddy_subscribe_cb(char *buddy_name, action_name, g_strdup(buddy_name), timeout, - sipe_subscribe_presence_single, + sipe_subscribe_presence_single_cb, g_free); g_free(action_name); } diff --git a/src/core/sipe-subscriptions.c b/src/core/sipe-subscriptions.c index 64313da7..19c2b884 100644 --- a/src/core/sipe-subscriptions.c +++ b/src/core/sipe-subscriptions.c @@ -446,7 +446,7 @@ static void sipe_process_presence_timeout(struct sipe_core_private *sipe_private action_name, g_strdup(who), timeout, - sipe_subscribe_presence_single, + sipe_subscribe_presence_single_cb, g_free); SIPE_DEBUG_INFO("Resubscription single contact with batched support(%s) in %d seconds", who, timeout); } @@ -490,27 +490,29 @@ static void sipe_subscribe_presence_buddy(struct sipe_core_private *sipe_private } /** + * if to == NULL: initial single subscription -> send to self URI + * + * if to != NULL: * Single Category SUBSCRIBE [MS-PRES] ; To send when the server returns a 200 OK message with state="resubscribe" in response. * The user sends a single SUBSCRIBE request to the subscribed contact. * The To-URI and the URI listed in the resource list MUST be the same for a single category SUBSCRIBE request. * */ void sipe_subscribe_presence_single(struct sipe_core_private *sipe_private, - gpointer buddy_name) + const gchar *uri, + const gchar *to) { - gchar *to = sip_uri((gchar *)buddy_name); + gchar *self = sip_uri_self(sipe_private); gchar *contact = get_contact(sipe_private); gchar *request; gchar *content = NULL; const gchar *additional; const gchar *content_type = ""; - struct sipe_buddy *sbuddy = g_hash_table_lookup(sipe_private->buddies, to); - const gchar *context = sbuddy && sbuddy->just_added ? ">" : "/>"; - - if (sbuddy) sbuddy->just_added = FALSE; + struct sipe_buddy *sbuddy = g_hash_table_lookup(sipe_private->buddies, uri); if (SIPE_CORE_PRIVATE_FLAG_IS(OCS2007)) { - additional = "Require: adhoclist, categoryList\r\n"; + additional = "Require: adhoclist, categoryList\r\n" \ + "Supported: eventlist\r\n"; content_type = "Content-Type: application/msrtc-adrl-categorylist+xml\r\n"; content = g_strdup_printf("\n" "\n" @@ -525,12 +527,15 @@ void sipe_subscribe_presence_single(struct sipe_core_private *sipe_private, "\n" "", sipe_private->username, - to, - context); + uri, + sbuddy && sbuddy->just_added ? ">" : "/>"); } else { additional = "Supported: com.microsoft.autoextend\r\n"; } + if (sbuddy) + sbuddy->just_added = FALSE; + request = g_strdup_printf("Accept: application/msrtc-event-categories+xml, text/xml+msrtc.pidf, application/xpidf+xml, application/pidf+xml, application/rlmi+xml, multipart/related\r\n" "Supported: ms-piggyback-first-notify\r\n" "%s%sSupported: ms-benotify\r\n" @@ -542,13 +547,20 @@ void sipe_subscribe_presence_single(struct sipe_core_private *sipe_private, contact); g_free(contact); - sipe_subscribe_presence_buddy(sipe_private, to, request, content); + sipe_subscribe_presence_buddy(sipe_private, to ? to : self, request, content); g_free(content); - g_free(to); + g_free(self); g_free(request); } +void sipe_subscribe_presence_single_cb(struct sipe_core_private *sipe_private, + gpointer uri) +{ + sipe_subscribe_presence_single(sipe_private, uri, NULL); +} + + /** * Support for Batch Category SUBSCRIBE [MS-PRES] - msrtc-event-categories+xml OCS 2007 * Support for Batch Category SUBSCRIBE [MS-SIP] - adrl+xml LCS 2005 @@ -566,7 +578,7 @@ static void sipe_subscribe_presence_batched_to(struct sipe_core_private *sipe_pr const gchar *require = ""; const gchar *accept = ""; const gchar *autoextend = ""; - gchar *content_type; + const gchar *content_type; if (SIPE_CORE_PRIVATE_FLAG_IS(OCS2007)) { require = ", categoryList"; @@ -811,7 +823,7 @@ static void sipe_subscription_expiration(struct sipe_core_private *sipe_private, action_name, g_strdup(who), timeout, - sipe_subscribe_presence_single, + sipe_subscribe_presence_single_cb, g_free); g_free(action_name); SIPE_DEBUG_INFO("Resubscription single contact '%s' in %d seconds", who, timeout); diff --git a/src/core/sipe-subscriptions.h b/src/core/sipe-subscriptions.h index f28ef333..ef39ed37 100644 --- a/src/core/sipe-subscriptions.h +++ b/src/core/sipe-subscriptions.h @@ -39,7 +39,10 @@ void sipe_subscribe_conference(struct sipe_core_private *sipe_private, gboolean expires); void sipe_subscribe_presence_single(struct sipe_core_private *sipe_private, - gpointer buddy_name); + const gchar *uri, + const gchar *to); +void sipe_subscribe_presence_single_cb(struct sipe_core_private *sipe_private, + gpointer uri); void sipe_subscribe_presence_batched(struct sipe_core_private *sipe_private); void sipe_subscribe_poolfqdn_resource_uri(const gchar *host, GSList *server, -- 2.11.4.GIT