From 85948079432688deffb94086bef51479a03c6612 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Wed, 7 Dec 2011 23:28:16 +0200 Subject: [PATCH] core cleanup: the big status/activity revamp Core only has a mapping table activity -> translation. Backend only has a mapping table activity <-> token Replaced all SIPE_STATUS_ID_xxx with access to the backend mapping function. That freed up all the status functions in sipe.c and they could be moved out. @TODO: look into replacing all "const gchar *status_id" in the core & backend APIs with guint activity... There are only two status functions left in sipe.c that need to be split between core & backend. After that only the buddy menu functionality is left in sipe.c. --- po/POTFILES.in | 1 + src/api/sipe-backend.h | 4 + src/api/sipe-core.h | 58 ++++--- src/core/sipe-buddy.c | 8 +- src/core/sipe-core.c | 3 +- src/core/sipe-notify.c | 46 ++++- src/core/sipe-ocs2005.c | 195 ++++++++++++++++++++- src/core/sipe-ocs2005.h | 10 ++ src/core/sipe-ocs2007.c | 144 +++++++++++++-- src/core/sipe-ocs2007.h | 10 ++ src/core/sipe-status.c | 63 ++++++- src/core/sipe-status.h | 4 + src/core/sipe.c | 423 --------------------------------------------- src/core/sipe.h | 32 ---- src/purple/purple-plugin.c | 24 ++- 15 files changed, 510 insertions(+), 515 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 30e733a0..38f24489 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -19,6 +19,7 @@ src/core/sipe-incoming.c src/core/sipe-media.c src/core/sipe-notify.c src/core/sipe-ocs2007.c +src/core/sipe-status.c src/core/sipe-user.c src/purple/purple-buddy.c src/purple/purple-chat.c diff --git a/src/api/sipe-backend.h b/src/api/sipe-backend.h index 9657afcd..4b81f16f 100644 --- a/src/api/sipe-backend.h +++ b/src/api/sipe-backend.h @@ -559,6 +559,10 @@ const gchar *sipe_backend_setting(struct sipe_core_public *sipe_public, /** STATUS *******************************************************************/ +/* type == SIPE_ACTIVITY_xxx (see sipe-core.h) */ +const gchar *sipe_backend_activity_to_token(guint type); +guint sipe_backend_token_to_activity(const gchar *token); + gboolean sipe_backend_status_and_note(struct sipe_core_public *sipe_public, const gchar *status_id, const gchar *message); diff --git a/src/api/sipe-core.h b/src/api/sipe-core.h index 79f74ddc..2e3e2999 100644 --- a/src/api/sipe-core.h +++ b/src/api/sipe-core.h @@ -42,31 +42,6 @@ extern "C" { #endif /** - * Activity - * - core: maps this to OCS protocol values - * - backend: maps this to backend status values - */ -typedef enum -{ - SIPE_ACTIVITY_UNSET = 0, - SIPE_ACTIVITY_ONLINE, - SIPE_ACTIVITY_INACTIVE, - SIPE_ACTIVITY_BUSY, - SIPE_ACTIVITY_BUSYIDLE, - SIPE_ACTIVITY_DND, - SIPE_ACTIVITY_BRB, - SIPE_ACTIVITY_AWAY, - SIPE_ACTIVITY_LUNCH, - SIPE_ACTIVITY_OFFLINE, - SIPE_ACTIVITY_ON_PHONE, - SIPE_ACTIVITY_IN_CONF, - SIPE_ACTIVITY_IN_MEETING, - SIPE_ACTIVITY_OOF, - SIPE_ACTIVITY_URGENT_ONLY, - SIPE_ACTIVITY_NUM_TYPES -} sipe_activity; - -/** * Transport type */ #define SIPE_TRANSPORT_AUTO 0 @@ -190,6 +165,37 @@ void sipe_core_schedule_execute(gpointer data); void sipe_core_update_calendar(struct sipe_core_public *sipe_public); void sipe_core_reset_status(struct sipe_core_public *sipe_public); +/** + * Activity + * - core: maps this to OCS protocol values + * maps this to translated descriptions + * - backend: maps this to backend status values + * backend token string can be used as "ID" in protocol + * + * This is passed back-and-forth and therefore defined as list, not as enum. + * Can be used as array index + */ +#define SIPE_ACTIVITY_UNSET 0 +#define SIPE_ACTIVITY_AVAILABLE 1 +#define SIPE_ACTIVITY_ONLINE 2 +#define SIPE_ACTIVITY_INACTIVE 3 +#define SIPE_ACTIVITY_BUSY 4 +#define SIPE_ACTIVITY_BUSYIDLE 5 +#define SIPE_ACTIVITY_DND 6 +#define SIPE_ACTIVITY_BRB 7 +#define SIPE_ACTIVITY_AWAY 8 +#define SIPE_ACTIVITY_LUNCH 9 +#define SIPE_ACTIVITY_INVISIBLE 10 +#define SIPE_ACTIVITY_OFFLINE 11 +#define SIPE_ACTIVITY_ON_PHONE 12 +#define SIPE_ACTIVITY_IN_CONF 13 +#define SIPE_ACTIVITY_IN_MEETING 14 +#define SIPE_ACTIVITY_OOF 15 +#define SIPE_ACTIVITY_URGENT_ONLY 16 +#define SIPE_ACTIVITY_NUM_TYPES 17 /* use to define array size */ + +const gchar *sipe_core_activity_description(guint type); + /* buddy actions */ /** * Get status text for buddy. @@ -203,7 +209,7 @@ void sipe_core_reset_status(struct sipe_core_public *sipe_public); */ gchar *sipe_core_buddy_status(struct sipe_core_public *sipe_public, const gchar *uri, - const sipe_activity activity, + guint activity, const gchar *status_text); void sipe_core_buddy_got_status(struct sipe_core_public *sipe_public, diff --git a/src/core/sipe-buddy.c b/src/core/sipe-buddy.c index 82509ed3..9472f22a 100644 --- a/src/core/sipe-buddy.c +++ b/src/core/sipe-buddy.c @@ -42,12 +42,12 @@ #include "sipe-core-private.h" #include "sipe-group.h" #include "sipe-nls.h" +#include "sipe-ocs2005.h" #include "sipe-ocs2007.h" #include "sipe-schedule.h" #include "sipe-subscriptions.h" #include "sipe-utils.h" #include "sipe-xml.h" -#include "sipe.h" static void buddy_free(struct sipe_buddy *buddy) { @@ -102,7 +102,7 @@ void sipe_buddy_free_all(struct sipe_core_private *sipe_private) gchar *sipe_core_buddy_status(struct sipe_core_public *sipe_public, const gchar *uri, - const sipe_activity activity, + guint activity, const gchar *status_text) { struct sipe_buddy *sbuddy; @@ -267,7 +267,9 @@ void sipe_core_buddy_got_status(struct sipe_core_public *sipe_public, if (SIPE_CORE_PRIVATE_FLAG_IS(OCS2007)) { sipe_backend_buddy_set_status(sipe_public, uri, status_id); } else { - sipe_apply_calendar_status(sipe_private, sbuddy, status_id); + sipe_ocs2005_apply_calendar_status(sipe_private, + sbuddy, + status_id); } } diff --git a/src/core/sipe-core.c b/src/core/sipe-core.c index 27f62b81..f4784d71 100644 --- a/src/core/sipe-core.c +++ b/src/core/sipe-core.c @@ -51,6 +51,7 @@ #include "sipe-ocs2007.h" #include "sipe-schedule.h" #include "sipe-session.h" +#include "sipe-status.h" #include "sipe-subscriptions.h" #include "sipe-svc.h" #include "sipe-utils.h" @@ -279,7 +280,7 @@ struct sipe_core_public *sipe_core_allocate(const gchar *signin_name, sip->our_publications = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_destroy); sipe_subscriptions_init(sipe_private); - sipe_set_unknown_status(sipe_private); + sipe_status_set_activity(sipe_private, SIPE_ACTIVITY_UNSET); return((struct sipe_core_public *)sipe_private); } diff --git a/src/core/sipe-notify.c b/src/core/sipe-notify.c index 93b850d9..debb54eb 100644 --- a/src/core/sipe-notify.c +++ b/src/core/sipe-notify.c @@ -54,10 +54,10 @@ #include "sipe-ocs2005.h" #include "sipe-ocs2007.h" #include "sipe-schedule.h" +#include "sipe-status.h" #include "sipe-subscriptions.h" #include "sipe-utils.h" #include "sipe-xml.h" -#define _SIPE_NEED_ACTIVITIES #include "sipe.h" /* OCS2005 */ @@ -369,12 +369,12 @@ static void process_incoming_notify_msrtc(struct sipe_core_private *sipe_private const gchar *new_desc; res_avail = dev_avail; if (!is_empty(state)) { - if (sipe_strequal(state, sipe_activity_to_token(SIPE_ACTIVITY_ON_PHONE))) { + if (sipe_strequal(state, sipe_backend_activity_to_token(SIPE_ACTIVITY_ON_PHONE))) { g_free(activity); - activity = g_strdup(sipe_activity_description(SIPE_ACTIVITY_ON_PHONE)); + activity = g_strdup(sipe_core_activity_description(SIPE_ACTIVITY_ON_PHONE)); } else if (sipe_strequal(state, "presenting")) { g_free(activity); - activity = g_strdup(sipe_activity_description(SIPE_ACTIVITY_IN_CONF)); + activity = g_strdup(sipe_core_activity_description(SIPE_ACTIVITY_IN_CONF)); } else { activity = state; state = NULL; @@ -395,7 +395,7 @@ static void process_incoming_notify_msrtc(struct sipe_core_private *sipe_private /* oof */ if (xn_oof && res_avail >= 15000) { /* 12000 in 2007 */ g_free(activity); - activity = g_strdup(sipe_activity_description(SIPE_ACTIVITY_OOF)); + activity = g_strdup(sipe_core_activity_description(SIPE_ACTIVITY_OOF)); activity_since = 0; } @@ -450,8 +450,8 @@ static void process_incoming_notify_msrtc(struct sipe_core_private *sipe_private sip->note_since = time(NULL); } - sipe_set_status(sipe_private, - sbuddy->last_non_cal_status_id); + sipe_status_set_token(sipe_private, + sbuddy->last_non_cal_status_id); } } g_free(cal_free_busy_base64); @@ -671,13 +671,14 @@ static void process_incoming_notify_rlmi(struct sipe_core_private *sipe_private, /* from token */ if (!is_empty(token)) { - sbuddy->activity = g_strdup(sipe_activity_description_from_token(token)); + sbuddy->activity = g_strdup(sipe_core_activity_description(sipe_backend_token_to_activity(token))); } /* from custom element */ if (xn_custom) { char *custom = sipe_xml_data(xn_custom); if (!is_empty(custom)) { + g_free(sbuddy->activity); sbuddy->activity = custom; custom = NULL; } @@ -784,6 +785,35 @@ static void process_incoming_notify_rlmi(struct sipe_core_private *sipe_private, sipe_xml_free(xn_categories); } +static void sipe_buddy_status_from_activity(struct sipe_core_private *sipe_private, + const gchar *uri, + const gchar *activity, + gboolean is_online) +{ + if (is_online) { + const gchar *status_id = NULL; + if (activity) { + if (sipe_strequal(activity, + sipe_backend_activity_to_token(SIPE_ACTIVITY_BUSY))) { + status_id = sipe_backend_activity_to_token(SIPE_ACTIVITY_BUSY); + } else if (sipe_strequal(activity, + sipe_backend_activity_to_token(SIPE_ACTIVITY_AWAY))) { + status_id = sipe_backend_activity_to_token(SIPE_ACTIVITY_AWAY); + } + } + + if (!status_id) { + status_id = sipe_backend_activity_to_token(SIPE_ACTIVITY_AVAILABLE); + } + + SIPE_DEBUG_INFO("sipe_buddy_status_from_activity: status_id(%s)", status_id); + sipe_core_buddy_got_status(SIPE_CORE_PUBLIC, uri, status_id); + } else { + sipe_core_buddy_got_status(SIPE_CORE_PUBLIC, uri, + sipe_backend_activity_to_token(SIPE_ACTIVITY_OFFLINE)); + } +} + static void process_incoming_notify_pidf(struct sipe_core_private *sipe_private, const gchar *data, unsigned len) diff --git a/src/core/sipe-ocs2005.c b/src/core/sipe-ocs2005.c index f25a4b57..a436a9b8 100644 --- a/src/core/sipe-ocs2005.c +++ b/src/core/sipe-ocs2005.c @@ -33,17 +33,130 @@ #include "http-conn.h" /* sipe-cal.h requires this */ #include "sip-soap.h" #include "sipe-backend.h" +#include "sipe-buddy.h" #include "sipe-cal.h" #include "sipe-core.h" #include "sipe-core-private.h" #include "sipe-ews.h" #include "sipe-ocs2005.h" +#include "sipe-ocs2007.h" #include "sipe-schedule.h" #include "sipe-status.h" #include "sipe-utils.h" #include "sipe-xml.h" #include "sipe.h" +/** + * 2005-style Activity and Availability. + * + * [MS-SIP] 2.2.1 + * + * @param activity 2005 aggregated activity. Ex.: 600 + * @param availablity 2005 aggregated availablity. Ex.: 300 + * + * The values define the starting point of a range + */ +#define SIPE_OCS2005_ACTIVITY_UNKNOWN 0 +#define SIPE_OCS2005_ACTIVITY_AWAY 100 +#define SIPE_OCS2005_ACTIVITY_LUNCH 150 +#define SIPE_OCS2005_ACTIVITY_IDLE 200 +#define SIPE_OCS2005_ACTIVITY_BRB 300 +#define SIPE_OCS2005_ACTIVITY_AVAILABLE 400 /* user is active */ +#define SIPE_OCS2005_ACTIVITY_ON_PHONE 500 /* user is participating in a communcation session */ +#define SIPE_OCS2005_ACTIVITY_BUSY 600 +#define SIPE_OCS2005_ACTIVITY_AWAY2 700 +#define SIPE_OCS2005_ACTIVITY_AVAILABLE2 800 + +#define SIPE_OCS2005_AVAILABILITY_OFFLINE 0 +#define SIPE_OCS2005_AVAILABILITY_MAYBE 100 +#define SIPE_OCS2005_AVAILABILITY_ONLINE 300 +static guint sipe_ocs2005_activity_from_status(struct sipe_core_private *sipe_private) +{ + struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; + const gchar *status = sip->status; + + if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_AWAY))) { + return(SIPE_OCS2005_ACTIVITY_AWAY); + /*} else if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_LUNCH))) { + return(SIPE_OCS2005_ACTIVITY_LUNCH); */ + } else if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_BRB))) { + return(SIPE_OCS2005_ACTIVITY_BRB); + } else if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_AVAILABLE))) { + return(SIPE_OCS2005_ACTIVITY_AVAILABLE); + /*} else if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_ON_PHONE))) { + return(SIPE_OCS2005_ACTIVITY_ON_PHONE); */ + } else if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_BUSY)) || + sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_DND))) { + return(SIPE_OCS2005_ACTIVITY_BUSY); + } else if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_INVISIBLE)) || + sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_OFFLINE))) { + return(SIPE_OCS2005_ACTIVITY_AWAY); + } else { + return(SIPE_OCS2005_ACTIVITY_AVAILABLE); + } +} + +static guint sipe_ocs2005_availability_from_status(struct sipe_core_private *sipe_private) +{ + struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; + const gchar *status = sip->status; + + if (sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_INVISIBLE)) || + sipe_strequal(status, sipe_backend_activity_to_token(SIPE_ACTIVITY_OFFLINE))) + return(SIPE_OCS2005_AVAILABILITY_OFFLINE); + else + return(SIPE_OCS2005_AVAILABILITY_ONLINE); +} + +const gchar *sipe_ocs2005_status_from_activity_availability(guint activity, + guint availability) +{ + guint type; + + if (availability < SIPE_OCS2005_AVAILABILITY_MAYBE) { + type = SIPE_ACTIVITY_OFFLINE; + } else if (activity < SIPE_OCS2005_ACTIVITY_LUNCH) { + type = SIPE_ACTIVITY_AWAY; + } else if (activity < SIPE_OCS2005_ACTIVITY_IDLE) { + //type = SIPE_ACTIVITY_LUNCH; + type = SIPE_ACTIVITY_AWAY; + } else if (activity < SIPE_OCS2005_ACTIVITY_BRB) { + //type = SIPE_ACTIVITY_IDLE; + type = SIPE_ACTIVITY_AWAY; + } else if (activity < SIPE_OCS2005_ACTIVITY_AVAILABLE) { + type = SIPE_ACTIVITY_BRB; + } else if (activity < SIPE_OCS2005_ACTIVITY_ON_PHONE) { + type = SIPE_ACTIVITY_AVAILABLE; + } else if (activity < SIPE_OCS2005_ACTIVITY_BUSY) { + //type = SIPE_ACTIVITY_ON_PHONE; + type = SIPE_ACTIVITY_BUSY; + } else if (activity < SIPE_OCS2005_ACTIVITY_AWAY2) { + type = SIPE_ACTIVITY_BUSY; + } else if (activity < SIPE_OCS2005_ACTIVITY_AVAILABLE2) { + type = SIPE_ACTIVITY_AWAY; + } else { + type = SIPE_ACTIVITY_AVAILABLE; + } + + return(sipe_backend_activity_to_token(type)); +} + +const gchar *sipe_ocs2005_activity_description(guint activity) +{ + if ((activity >= SIPE_OCS2005_ACTIVITY_LUNCH) && + (activity < SIPE_OCS2005_ACTIVITY_IDLE)) { + return(sipe_core_activity_description(SIPE_ACTIVITY_LUNCH)); + } else if ((activity >= SIPE_OCS2005_ACTIVITY_IDLE) && + (activity < SIPE_OCS2005_ACTIVITY_BRB)) { + return(sipe_core_activity_description(SIPE_ACTIVITY_INACTIVE)); + } else if ((activity >= SIPE_OCS2005_ACTIVITY_ON_PHONE) && + (activity < SIPE_OCS2005_ACTIVITY_BUSY)) { + return(sipe_core_activity_description(SIPE_ACTIVITY_ON_PHONE)); + } else { + return(NULL); + } +} + void sipe_ocs2005_user_info_has_updated(struct sipe_core_private *sipe_private, const sipe_xml *xn_userinfo) { @@ -82,6 +195,14 @@ void sipe_ocs2005_user_info_has_updated(struct sipe_core_private *sipe_private, } } +static gboolean sipe_is_user_available(struct sipe_core_private *sipe_private) +{ + struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; + return(sipe_strequal(sip->status, + sipe_backend_activity_to_token(SIPE_ACTIVITY_AVAILABLE))); +} + + /** * OCS2005 presence XML messages * @@ -192,7 +313,7 @@ static void send_presence_soap(struct sipe_core_private *sipe_private, if (!sip->initial_state_published || do_reset_status) - sipe_set_initial_status(sipe_private); + sipe_status_set_activity(sipe_private, SIPE_ACTIVITY_AVAILABLE); /* Note */ if (pub_oof) { @@ -299,11 +420,81 @@ void sipe_ocs2005_reset_status(struct sipe_core_private *sipe_private) return send_presence_soap(sipe_private, FALSE, TRUE); } +void sipe_ocs2005_apply_calendar_status(struct sipe_core_private *sipe_private, + struct sipe_buddy *sbuddy, + const char *status_id) +{ + struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; + time_t cal_avail_since; + int cal_status = sipe_cal_get_status(sbuddy, time(NULL), &cal_avail_since); + int avail; + gchar *self_uri; + + if (!sbuddy) return; + + if (cal_status < SIPE_CAL_NO_DATA) { + SIPE_DEBUG_INFO("sipe_apply_calendar_status: cal_status : %d for %s", cal_status, sbuddy->name); + SIPE_DEBUG_INFO("sipe_apply_calendar_status: cal_avail_since : %s", asctime(localtime(&cal_avail_since))); + } + + /* scheduled Cal update call */ + if (!status_id) { + status_id = sbuddy->last_non_cal_status_id; + g_free(sbuddy->activity); + sbuddy->activity = g_strdup(sbuddy->last_non_cal_activity); + } + + if (!status_id) { + SIPE_DEBUG_INFO("sipe_apply_calendar_status: status_id is NULL for %s, exiting.", + sbuddy->name ? sbuddy->name : "" ); + return; + } + + /* adjust to calendar status */ + if (cal_status != SIPE_CAL_NO_DATA) { + SIPE_DEBUG_INFO("sipe_apply_calendar_status: user_avail_since: %s", asctime(localtime(&sbuddy->user_avail_since))); + + if ((cal_status == SIPE_CAL_BUSY) && + (cal_avail_since > sbuddy->user_avail_since) && + sipe_ocs2007_status_is_busy(status_id)) { + status_id = sipe_backend_activity_to_token(SIPE_ACTIVITY_BUSY); + g_free(sbuddy->activity); + sbuddy->activity = g_strdup(sipe_core_activity_description(SIPE_ACTIVITY_IN_MEETING)); + } + avail = sipe_ocs2007_availability_from_status(status_id, NULL); + + SIPE_DEBUG_INFO("sipe_apply_calendar_status: activity_since : %s", asctime(localtime(&sbuddy->activity_since))); + if (cal_avail_since > sbuddy->activity_since) { + if ((cal_status == SIPE_CAL_OOF) && + sipe_ocs2007_availability_is_away2(avail)) { + g_free(sbuddy->activity); + sbuddy->activity = g_strdup(sipe_core_activity_description(SIPE_ACTIVITY_OOF)); + } + } + } + + /* then set status_id actually */ + SIPE_DEBUG_INFO("sipe_apply_calendar_status: to %s for %s", status_id, sbuddy->name ? sbuddy->name : "" ); + sipe_backend_buddy_set_status(SIPE_CORE_PUBLIC, sbuddy->name, status_id); + + /* set our account state to the one in roaming (including calendar info) */ + self_uri = sip_uri_self(sipe_private); + if (sip->initial_state_published && sipe_strcase_equal(sbuddy->name, self_uri)) { + if (sipe_strequal(status_id, sipe_backend_activity_to_token(SIPE_ACTIVITY_OFFLINE))) { + /* do not let offline status switch us off */ + status_id = sipe_backend_activity_to_token(SIPE_ACTIVITY_INVISIBLE); + } + + sipe_status_and_note(sipe_private, status_id); + } + g_free(self_uri); +} + static void update_calendar_status_cb(SIPE_UNUSED_PARAMETER char *name, struct sipe_buddy *sbuddy, struct sipe_core_private *sipe_private) { - sipe_apply_calendar_status(sipe_private, sbuddy, NULL); + sipe_ocs2005_apply_calendar_status(sipe_private, sbuddy, NULL); } /** diff --git a/src/core/sipe-ocs2005.h b/src/core/sipe-ocs2005.h index 8f3d7f30..35274bd0 100644 --- a/src/core/sipe-ocs2005.h +++ b/src/core/sipe-ocs2005.h @@ -26,6 +26,13 @@ struct _sipe_xml; struct sipe_core_private; /** + * OCS2005 status ID, availability & activity + */ +const gchar *sipe_ocs2005_status_from_activity_availability(guint activity, + guint availablity); +const gchar *sipe_ocs2005_activity_description(guint activity); + +/** * Publish status (OCS2005) */ void sipe_ocs2005_presence_publish(struct sipe_core_private *sipe_private, @@ -33,6 +40,9 @@ void sipe_ocs2005_presence_publish(struct sipe_core_private *sipe_private, void sipe_ocs2005_reset_status(struct sipe_core_private *sipe_private); void sipe_ocs2005_user_info_has_updated(struct sipe_core_private *sipe_private, const struct _sipe_xml *xn_userinfo); +void sipe_ocs2005_apply_calendar_status(struct sipe_core_private *sipe_private, + struct sipe_buddy *sbuddy, + const char *status_id); void sipe_ocs2005_schedule_status_update(struct sipe_core_private *sipe_private, time_t calculate_from); diff --git a/src/core/sipe-ocs2007.c b/src/core/sipe-ocs2007.c index 962f7849..92bfab90 100644 --- a/src/core/sipe-ocs2007.c +++ b/src/core/sipe-ocs2007.c @@ -54,9 +54,128 @@ #include "sipe-utils.h" #include "sipe-xml.h" -#define _SIPE_NEED_ACTIVITIES /* ugly hack :-( */ #include "sipe.h" +/** + * 2007-style Activity and Availability. + * + * [MS-PRES] 3.7.5.5 + * + * Conversion of legacyInterop elements and attributes to MSRTC elements and attributes. + * + * The values define the starting point of a range + */ +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_ONLINE 3000 +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY 4500 +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_ON_PHONE 6000 +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_BUSY 7500 +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_DND 9000 /* do not disturb */ +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_BRB 12000 /* be right back */ +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY2 15000 +#define SIPE_OCS2007_LEGACY_AVAILIBILITY_OFFLINE 18000 +const gchar *sipe_ocs2007_status_from_legacy_availability(guint availability) +{ + guint type; + + if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_ONLINE) { + type = SIPE_ACTIVITY_OFFLINE; + } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY) { + type = SIPE_ACTIVITY_AVAILABLE; + } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_ON_PHONE) { + //type = SIPE_ACTIVITY_IDLE; + type = SIPE_ACTIVITY_AVAILABLE; + } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_BUSY) { + type = SIPE_ACTIVITY_BUSY; + } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_DND) { + //type = SIPE_ACTIVITY_BUSYIDLE; + type = SIPE_ACTIVITY_BUSY; + } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_BRB) { + type = SIPE_ACTIVITY_DND; + } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY2) { + type = SIPE_ACTIVITY_BRB; + } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_OFFLINE) { + type = SIPE_ACTIVITY_AWAY; + } else { + type = SIPE_ACTIVITY_OFFLINE; + } + + return(sipe_backend_activity_to_token(type)); +} + +const gchar *sipe_ocs2007_legacy_activity_description(guint availability) +{ + if ((availability >= SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY) && + (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_ON_PHONE)) { + return(sipe_core_activity_description(SIPE_ACTIVITY_INACTIVE)); + } else if ((availability >= SIPE_OCS2007_LEGACY_AVAILIBILITY_BUSY) && + (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_DND)) { + return(sipe_core_activity_description(SIPE_ACTIVITY_BUSYIDLE)); + } else { + return(NULL); + } +} + +/** + * @param sipe_status_id (in) + * @param activity_token (out) [only sipe-ocs2005.c/send_presence_soap() + * requests this token] + */ +#define SIPE_OCS2007_AVAILABILITY_UNKNOWN 0 +#define SIPE_OCS2007_AVAILABILITY_ONLINE 3500 +#define SIPE_OCS2007_AVAILABILITY_BUSY 6500 +#define SIPE_OCS2007_AVAILABILITY_DND 9500 /* do not disturb */ +#define SIPE_OCS2007_AVAILABILITY_BRB 12500 /* be right back */ +#define SIPE_OCS2007_AVAILABILITY_AWAY 15500 +#define SIPE_OCS2007_AVAILABILITY_OFFLINE 18500 +guint sipe_ocs2007_availability_from_status(const gchar *sipe_status_id, + const gchar **activity_token) +{ + guint availability; + guint activity; + + if (sipe_strequal(sipe_status_id, sipe_backend_activity_to_token(SIPE_ACTIVITY_AWAY))) { + availability = SIPE_OCS2007_AVAILABILITY_AWAY; + activity = SIPE_ACTIVITY_AWAY; + } else if (sipe_strequal(sipe_status_id, sipe_backend_activity_to_token(SIPE_ACTIVITY_BRB))) { + availability = SIPE_OCS2007_AVAILABILITY_BRB; + activity = SIPE_ACTIVITY_BRB; + } else if (sipe_strequal(sipe_status_id, sipe_backend_activity_to_token(SIPE_ACTIVITY_DND))) { + availability = SIPE_OCS2007_AVAILABILITY_DND; + activity = SIPE_ACTIVITY_DND; + } else if (sipe_strequal(sipe_status_id, sipe_backend_activity_to_token(SIPE_ACTIVITY_BUSY))) { + availability = SIPE_OCS2007_AVAILABILITY_BUSY; + activity = SIPE_ACTIVITY_BUSY; + } else if (sipe_strequal(sipe_status_id, sipe_backend_activity_to_token(SIPE_ACTIVITY_AVAILABLE))) { + availability = SIPE_OCS2007_AVAILABILITY_ONLINE; + activity = SIPE_ACTIVITY_ONLINE; + } else if (sipe_strequal(sipe_status_id, sipe_backend_activity_to_token(SIPE_ACTIVITY_UNSET))) { + availability = SIPE_OCS2007_AVAILABILITY_UNKNOWN; + activity = SIPE_ACTIVITY_UNSET; + } else { + /* Offline or invisible */ + availability = SIPE_OCS2007_AVAILABILITY_OFFLINE; + activity = SIPE_ACTIVITY_OFFLINE; + } + + if (activity_token) { + *activity_token = sipe_backend_activity_to_token(activity); + } + + return(availability); +} + +gboolean sipe_ocs2007_status_is_busy(const gchar *status_id) +{ + return(SIPE_OCS2007_AVAILABILITY_BUSY >= + sipe_ocs2007_availability_from_status(status_id, NULL)); + +} + +gboolean sipe_ocs2007_availability_is_away2(guint availability) +{ + return(availability >= SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY2); +} + static void send_presence_publish(struct sipe_core_private *sipe_private, const char *publications); @@ -747,17 +866,18 @@ static gchar *sipe_publish_get_category_state_calendar(struct sipe_core_private gchar *escaped_location = event->location ? g_markup_escape_text(event->location, -1) : NULL; if (event->cal_status == SIPE_CAL_BUSY) { - availability_xml_str = g_strdup_printf(SIPE_PUB_XML_STATE_CALENDAR_AVAIL, 6500); + availability_xml_str = g_strdup_printf(SIPE_PUB_XML_STATE_CALENDAR_AVAIL, + SIPE_OCS2007_AVAILABILITY_BUSY); } if (event->cal_status == SIPE_CAL_BUSY && event->is_meeting) { activity_xml_str = g_strdup_printf(SIPE_PUB_XML_STATE_CALENDAR_ACTIVITY, - sipe_activity_to_token(SIPE_ACTIVITY_IN_MEETING), + sipe_backend_activity_to_token(SIPE_ACTIVITY_IN_MEETING), "minAvailability=\"6500\"", "maxAvailability=\"8999\""); } else if (event->cal_status == SIPE_CAL_OOF) { activity_xml_str = g_strdup_printf(SIPE_PUB_XML_STATE_CALENDAR_ACTIVITY, - sipe_activity_to_token(SIPE_ACTIVITY_OOF), + sipe_backend_activity_to_token(SIPE_ACTIVITY_OOF), "minAvailability=\"12000\"", ""); } @@ -1362,7 +1482,7 @@ static void send_publish_category_initial(struct sipe_core_private *sipe_private gchar *pub_machine; gchar *publications; - sipe_set_initial_status(sipe_private); + sipe_status_set_activity(sipe_private, SIPE_ACTIVITY_AVAILABLE); pub_machine = sipe_publish_get_category_state_machine(sipe_private); publications = g_strdup_printf("%s%s", @@ -1965,7 +2085,7 @@ void sipe_ocs2007_process_roaming_self(struct sipe_core_private *sipe_private, event->start_time = sipe_utils_str_to_time(sipe_xml_attribute(xn_state, "startTime")); if (xn_activity) { if (sipe_strequal(sipe_xml_attribute(xn_activity, "token"), - sipe_activity_to_token(SIPE_ACTIVITY_IN_MEETING))) + sipe_backend_activity_to_token(SIPE_ACTIVITY_IN_MEETING))) { event->is_meeting = TRUE; } @@ -2207,11 +2327,15 @@ void sipe_ocs2007_process_roaming_self(struct sipe_core_private *sipe_private, do_update_status = FALSE; } else if (aggreg_avail) { - if (aggreg_avail && aggreg_avail < 18000) { /* not offline */ - sipe_set_status(sipe_private, - sipe_ocs2007_status_from_legacy_availability(aggreg_avail)); + if (aggreg_avail && + (aggreg_avail < SIPE_OCS2007_LEGACY_AVAILIBILITY_OFFLINE)) { + /* not offline */ + sipe_status_set_token(sipe_private, + sipe_ocs2007_status_from_legacy_availability(aggreg_avail)); } else { - sipe_set_invisible_status(sipe_private); /* not not let offline status switch us off */ + /* do not let offline status switch us off */ + sipe_status_set_activity(sipe_private, + SIPE_ACTIVITY_INVISIBLE); } } diff --git a/src/core/sipe-ocs2007.h b/src/core/sipe-ocs2007.h index 6b1d885d..85f90077 100644 --- a/src/core/sipe-ocs2007.h +++ b/src/core/sipe-ocs2007.h @@ -33,6 +33,16 @@ struct sipe_core_private; #define SIPE_OCS2007_INDENT_MARKED_FMT "* %s" /** + * OCS2007 status ID, availability & activity + */ +guint sipe_ocs2007_availability_from_status(const gchar *sipe_status_id, + const gchar **activity_token); +const gchar *sipe_ocs2007_status_from_legacy_availability(guint availability); +const gchar *sipe_ocs2007_legacy_activity_description(guint availability); +gboolean sipe_ocs2007_status_is_busy(const gchar *status_id); +gboolean sipe_ocs2007_availability_is_away2(guint availability); + +/** * Publish status (OCS2007+) */ void sipe_ocs2007_presence_publish(struct sipe_core_private *sipe_private, diff --git a/src/core/sipe-status.c b/src/core/sipe-status.c index 0fbd5c72..e86ccd46 100644 --- a/src/core/sipe-status.c +++ b/src/core/sipe-status.c @@ -21,25 +21,80 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include +#include "sipe-common.h" #include "http-conn.h" /* sipe-cal.h requires this */ #include "sipe-backend.h" #include "sipe-cal.h" #include "sipe-core.h" #include "sipe-core-private.h" +#include "sipe-nls.h" #include "sipe-ocs2005.h" #include "sipe-ocs2007.h" #include "sipe-schedule.h" #include "sipe-status.h" #include "sipe-utils.h" -#define _SIPE_NEED_ACTIVITIES #include "sipe.h" #define SIPE_IDLE_SET_DELAY 1 /* seconds */ +static struct +{ + guint type; + const gchar *desc; +} const sipe_activity_map[SIPE_ACTIVITY_NUM_TYPES] = { +/* + * This has nothing to do with Availability numbers, like 3500 (online). + * Just a mapping of Communicator Activities to translations + */ +/* @TODO: NULL means "default translation from Pidgin"? + * What about other backends? */ + { SIPE_ACTIVITY_UNSET, NULL }, + { SIPE_ACTIVITY_AVAILABLE, NULL }, + { SIPE_ACTIVITY_ONLINE, NULL }, + { SIPE_ACTIVITY_INACTIVE, N_("Inactive") }, + { SIPE_ACTIVITY_BUSY, N_("Busy") }, + { SIPE_ACTIVITY_BUSYIDLE, N_("Busy-Idle") }, + { SIPE_ACTIVITY_DND, NULL }, + { SIPE_ACTIVITY_BRB, N_("Be right back") }, + { SIPE_ACTIVITY_AWAY, NULL }, + { SIPE_ACTIVITY_LUNCH, N_("Out to lunch") }, + { SIPE_ACTIVITY_INVISIBLE, NULL }, + { SIPE_ACTIVITY_OFFLINE, NULL }, + { SIPE_ACTIVITY_ON_PHONE, N_("In a call") }, + { SIPE_ACTIVITY_IN_CONF, N_("In a conference") }, + { SIPE_ACTIVITY_IN_MEETING, N_("In a meeting") }, + { SIPE_ACTIVITY_OOF, N_("Out of office") }, + { SIPE_ACTIVITY_URGENT_ONLY, N_("Urgent interruptions only") } +}; + +const gchar *sipe_core_activity_description(guint type) +{ + return(gettext(sipe_activity_map[type].desc)); +} + +void sipe_status_set_token(struct sipe_core_private *sipe_private, + const gchar *status_id) +{ + struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; + g_free(sip->status); + sip->status = g_strdup(status_id); +} + +void sipe_status_set_activity(struct sipe_core_private *sipe_private, + guint activity) +{ + sipe_status_set_token(sipe_private, + sipe_backend_activity_to_token(activity)); +} + void sipe_core_reset_status(struct sipe_core_public *sipe_public) { struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE; @@ -63,7 +118,7 @@ void sipe_status_and_note(struct sipe_core_private *sipe_private, status_id, sip->note)) { /* status has changed */ - sipe_activity activity = sipe_activity_from_token(status_id); + guint activity = sipe_backend_token_to_activity(status_id); sip->do_not_publish[activity] = time(NULL); SIPE_DEBUG_INFO("sipe_status_and_note: do_not_publish[%s]=%d [now]", @@ -83,7 +138,7 @@ void sipe_core_status_set(struct sipe_core_public *sipe_public, gchar *action_name; gchar *tmp; time_t now = time(NULL); - sipe_activity activity = sipe_activity_from_token(status_id); + guint activity = sipe_backend_token_to_activity(status_id); gboolean do_not_publish = ((now - sip->do_not_publish[activity]) <= 2); /* when other point of presence clears note, but we are keeping @@ -106,7 +161,7 @@ void sipe_core_status_set(struct sipe_core_public *sipe_public, return; } - sipe_set_status(sipe_private, status_id); + sipe_status_set_token(sipe_private, status_id); /* hack to escape apostrof before comparison */ tmp = note ? sipe_utils_str_replace(note, "'", "'") : NULL; diff --git a/src/core/sipe-status.h b/src/core/sipe-status.h index 91b9309a..58c82939 100644 --- a/src/core/sipe-status.h +++ b/src/core/sipe-status.h @@ -24,6 +24,10 @@ /* Forward declarations */ struct sipe_core_private; +void sipe_status_set_token(struct sipe_core_private *sipe_private, + const gchar *status_id); +void sipe_status_set_activity(struct sipe_core_private *sipe_private, + guint activity); void sipe_status_and_note(struct sipe_core_private *sipe_private, const gchar *status_id); gboolean sipe_status_changed_by_user(struct sipe_core_private *sipe_private); diff --git a/src/core/sipe.c b/src/core/sipe.c index 7ed20831..43662a84 100644 --- a/src/core/sipe.c +++ b/src/core/sipe.c @@ -91,116 +91,8 @@ #include "sipe-status.h" #include "sipe-utils.h" -#define _SIPE_NEED_ACTIVITIES /* ugly hack :-( */ #include "sipe.h" -/* Status identifiers (see also: sipe_status_types()) */ -#define SIPE_STATUS_ID_UNKNOWN purple_primitive_get_id_from_type(PURPLE_STATUS_UNSET) /* Unset (primitive) */ -#define SIPE_STATUS_ID_OFFLINE purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE) /* Offline (primitive) */ -#define SIPE_STATUS_ID_AVAILABLE purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE) /* Online */ -/* PURPLE_STATUS_UNAVAILABLE: */ -#define SIPE_STATUS_ID_BUSY "busy" /* Busy */ -#define SIPE_STATUS_ID_BUSYIDLE "busyidle" /* BusyIdle */ -#define SIPE_STATUS_ID_DND "do-not-disturb" /* Do Not Disturb */ -#define SIPE_STATUS_ID_IN_MEETING "in-a-meeting" /* In a meeting */ -#define SIPE_STATUS_ID_IN_CONF "in-a-conference" /* In a conference */ -#define SIPE_STATUS_ID_ON_PHONE "on-the-phone" /* On the phone */ -#define SIPE_STATUS_ID_INVISIBLE purple_primitive_get_id_from_type(PURPLE_STATUS_INVISIBLE) /* Appear Offline */ -/* PURPLE_STATUS_AWAY: */ -#define SIPE_STATUS_ID_IDLE "idle" /* Idle/Inactive */ -#define SIPE_STATUS_ID_BRB "be-right-back" /* Be Right Back */ -#define SIPE_STATUS_ID_AWAY purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY) /* Away (primitive) */ -/** Reuters status (user settable) */ -#define SIPE_STATUS_ID_LUNCH "out-to-lunch" /* Out To Lunch */ -/* ??? PURPLE_STATUS_EXTENDED_AWAY */ -/* ??? PURPLE_STATUS_MOBILE */ -/* ??? PURPLE_STATUS_TUNE */ - -/* Status attributes (see also sipe_status_types() */ -#define SIPE_STATUS_ATTR_ID_MESSAGE "message" - -static struct sipe_activity_map_struct -{ - sipe_activity type; - const char *token; - const char *desc; -} const sipe_activity_map[] = -{ -/* This has nothing to do with Availability numbers, like 3500 (online). - * Just a mapping of Communicator Activities to Purple statuses to be able display them in Pidgin. - */ - { SIPE_ACTIVITY_UNSET, "unset", NULL }, - { SIPE_ACTIVITY_ONLINE, "online", NULL }, - { SIPE_ACTIVITY_INACTIVE, SIPE_STATUS_ID_IDLE, N_("Inactive") }, - { SIPE_ACTIVITY_BUSY, SIPE_STATUS_ID_BUSY, N_("Busy") }, - { SIPE_ACTIVITY_BUSYIDLE, SIPE_STATUS_ID_BUSYIDLE, N_("Busy-Idle") }, - { SIPE_ACTIVITY_DND, SIPE_STATUS_ID_DND, NULL }, - { SIPE_ACTIVITY_BRB, SIPE_STATUS_ID_BRB, N_("Be right back") }, - { SIPE_ACTIVITY_AWAY, "away", NULL }, - { SIPE_ACTIVITY_LUNCH, SIPE_STATUS_ID_LUNCH, N_("Out to lunch") }, - { SIPE_ACTIVITY_OFFLINE, "offline", NULL }, - { SIPE_ACTIVITY_ON_PHONE, SIPE_STATUS_ID_ON_PHONE, N_("In a call") }, - { SIPE_ACTIVITY_IN_CONF, SIPE_STATUS_ID_IN_CONF, N_("In a conference") }, - { SIPE_ACTIVITY_IN_MEETING, SIPE_STATUS_ID_IN_MEETING, N_("In a meeting") }, - { SIPE_ACTIVITY_OOF, "out-of-office", N_("Out of office") }, - { SIPE_ACTIVITY_URGENT_ONLY, "urgent-interruptions-only", N_("Urgent interruptions only") } -}; -/** @param x is sipe_activity */ -#define SIPE_ACTIVITY_I18N(x) gettext(sipe_activity_map[x].desc) - -const gchar *sipe_activity_to_token(sipe_activity type) -{ - return(sipe_activity_map[type].token); -} - -const gchar *sipe_activity_description(sipe_activity type) -{ - return(SIPE_ACTIVITY_I18N(type)); -} - -void sipe_set_status(struct sipe_core_private *sipe_private, - const gchar *status_id) -{ - struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; - g_free(sip->status); - sip->status = g_strdup(status_id); -} - -void sipe_set_unknown_status(struct sipe_core_private *sipe_private) -{ - sipe_set_status(sipe_private, SIPE_STATUS_ID_UNKNOWN); -} - -void sipe_set_initial_status(struct sipe_core_private *sipe_private) -{ - sipe_set_status(sipe_private, SIPE_STATUS_ID_AVAILABLE); -} - -void sipe_set_invisible_status(struct sipe_core_private *sipe_private) -{ - sipe_set_status(sipe_private, SIPE_STATUS_ID_INVISIBLE); -} - -sipe_activity sipe_activity_from_token(const gchar *token) -{ - int i; - - for (i = 0; i < SIPE_ACTIVITY_NUM_TYPES; i++) - { - if (sipe_strequal(token, sipe_activity_to_token(i))) - return sipe_activity_map[i].type; - } - - return sipe_activity_map[0].type; -} - -const gchar *sipe_activity_description_from_token(const gchar *token) -{ - if (!token) return NULL; - - return sipe_activity_description(sipe_activity_from_token(token)); -} - const gchar *sipe_get_buddy_status(struct sipe_core_private *sipe_private, const gchar *uri) { @@ -211,249 +103,6 @@ const gchar *sipe_get_buddy_status(struct sipe_core_private *sipe_private, return(purple_status_get_id(pstatus)); } -void sipe_buddy_status_from_activity(struct sipe_core_private *sipe_private, - const gchar *uri, - const gchar *activity, - gboolean is_online) -{ - if (is_online) { - const gchar *status_id = NULL; - if (activity) { - if (sipe_strequal(activity, sipe_activity_to_token(SIPE_ACTIVITY_BUSY))) { - status_id = SIPE_STATUS_ID_BUSY; - } else if (sipe_strequal(activity, sipe_activity_to_token(SIPE_ACTIVITY_AWAY))) { - status_id = SIPE_STATUS_ID_AWAY; - } - } - - if (!status_id) { - status_id = SIPE_STATUS_ID_AVAILABLE; - } - - SIPE_DEBUG_INFO("sipe_buddy_status_from_activity: status_id(%s)", status_id); - sipe_core_buddy_got_status(SIPE_CORE_PUBLIC, uri, status_id); - } else { - sipe_core_buddy_got_status(SIPE_CORE_PUBLIC, uri, SIPE_STATUS_ID_OFFLINE); - } -} - -/** - * 2005-style Activity and Availability. - * - * [MS-SIP] 2.2.1 - * - * @param activity 2005 aggregated activity. Ex.: 600 - * @param availablity 2005 aggregated availablity. Ex.: 300 - * - * The values define the starting point of a range - */ -#define SIPE_OCS2005_ACTIVITY_UNKNOWN 0 -#define SIPE_OCS2005_ACTIVITY_AWAY 100 -#define SIPE_OCS2005_ACTIVITY_LUNCH 150 -#define SIPE_OCS2005_ACTIVITY_IDLE 200 -#define SIPE_OCS2005_ACTIVITY_BRB 300 -#define SIPE_OCS2005_ACTIVITY_AVAILABLE 400 /* user is active */ -#define SIPE_OCS2005_ACTIVITY_ON_PHONE 500 /* user is participating in a communcation session */ -#define SIPE_OCS2005_ACTIVITY_BUSY 600 -#define SIPE_OCS2005_ACTIVITY_AWAY2 700 -#define SIPE_OCS2005_ACTIVITY_AVAILABLE2 800 - -#define SIPE_OCS2005_AVAILABILITY_OFFLINE 0 -#define SIPE_OCS2005_AVAILABILITY_MAYBE 100 -#define SIPE_OCS2005_AVAILABILITY_ONLINE 300 -guint sipe_ocs2005_activity_from_status(struct sipe_core_private *sipe_private) -{ - struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; - const gchar *status = sip->status; - - if (sipe_strequal(status, SIPE_STATUS_ID_AWAY)) { - return(SIPE_OCS2005_ACTIVITY_AWAY); - /*} else if (sipe_strequal(status, SIPE_STATUS_ID_LUNCH)) { - return(SIPE_OCS2005_ACTIVITY_LUNCH); */ - } else if (sipe_strequal(status, SIPE_STATUS_ID_BRB)) { - return(SIPE_OCS2005_ACTIVITY_BRB); - } else if (sipe_strequal(status, SIPE_STATUS_ID_AVAILABLE)) { - return(SIPE_OCS2005_ACTIVITY_AVAILABLE); - /*} else if (sipe_strequal(status, SIPE_STATUS_ID_ON_PHONE)) { - return(SIPE_OCS2005_ACTIVITY_ON_PHONE); */ - } else if (sipe_strequal(status, SIPE_STATUS_ID_BUSY) || - sipe_strequal(status, SIPE_STATUS_ID_DND)) { - return(SIPE_OCS2005_ACTIVITY_BUSY); - } else if (sipe_strequal(status, SIPE_STATUS_ID_INVISIBLE) || - sipe_strequal(status, SIPE_STATUS_ID_OFFLINE)) { - return(SIPE_OCS2005_ACTIVITY_AWAY); - } else { - return(SIPE_OCS2005_ACTIVITY_AVAILABLE); - } -} - -guint sipe_ocs2005_availability_from_status(struct sipe_core_private *sipe_private) -{ - struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; - const gchar *status = sip->status; - - if (sipe_strequal(status, SIPE_STATUS_ID_INVISIBLE) || - sipe_strequal(status, SIPE_STATUS_ID_OFFLINE)) - return(SIPE_OCS2005_AVAILABILITY_OFFLINE); - else - return(SIPE_OCS2005_AVAILABILITY_ONLINE); -} - -const gchar *sipe_ocs2005_status_from_activity_availability(guint activity, - guint availability) -{ - if (availability < SIPE_OCS2005_AVAILABILITY_MAYBE) { - return(SIPE_STATUS_ID_OFFLINE); - } else if (activity < SIPE_OCS2005_ACTIVITY_LUNCH) { - return(SIPE_STATUS_ID_AWAY); - } else if (activity < SIPE_OCS2005_ACTIVITY_IDLE) { - //return(SIPE_STATUS_ID_LUNCH); - return(SIPE_STATUS_ID_AWAY); - } else if (activity < SIPE_OCS2005_ACTIVITY_BRB) { - //return(SIPE_STATUS_ID_IDLE); - return(SIPE_STATUS_ID_AWAY); - } else if (activity < SIPE_OCS2005_ACTIVITY_AVAILABLE) { - return(SIPE_STATUS_ID_BRB); - } else if (activity < SIPE_OCS2005_ACTIVITY_ON_PHONE) { - return(SIPE_STATUS_ID_AVAILABLE); - } else if (activity < SIPE_OCS2005_ACTIVITY_BUSY) { - //return(SIPE_STATUS_ID_ON_PHONE); - return(SIPE_STATUS_ID_BUSY); - } else if (activity < SIPE_OCS2005_ACTIVITY_AWAY2) { - return(SIPE_STATUS_ID_BUSY); - } else if (activity < SIPE_OCS2005_ACTIVITY_AVAILABLE2) { - return(SIPE_STATUS_ID_AWAY); - } else { - return(SIPE_STATUS_ID_AVAILABLE); - } -} - -const gchar *sipe_ocs2005_activity_description(guint activity) -{ - if ((activity >= SIPE_OCS2005_ACTIVITY_LUNCH) && - (activity < SIPE_OCS2005_ACTIVITY_IDLE)) { - return(sipe_activity_description(SIPE_ACTIVITY_LUNCH)); - } else if ((activity >= SIPE_OCS2005_ACTIVITY_IDLE) && - (activity < SIPE_OCS2005_ACTIVITY_BRB)) { - return(sipe_activity_description(SIPE_ACTIVITY_INACTIVE)); - } else if ((activity >= SIPE_OCS2005_ACTIVITY_ON_PHONE) && - (activity < SIPE_OCS2005_ACTIVITY_BUSY)) { - return(sipe_activity_description(SIPE_ACTIVITY_ON_PHONE)); - } else { - return(NULL); - } -} - -/** - * 2007-style Activity and Availability. - * - * [MS-PRES] 3.7.5.5 - * - * Conversion of legacyInterop elements and attributes to MSRTC elements and attributes. - * - * The values define the starting point of a range - */ -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_ONLINE 3000 -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY 4500 -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_ON_PHONE 6000 -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_BUSY 7500 -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_DND 9000 /* do not disturb */ -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_BRB 12000 /* be right back */ -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY2 15000 -#define SIPE_OCS2007_LEGACY_AVAILIBILITY_OFFLINE 18000 -const gchar *sipe_ocs2007_status_from_legacy_availability(guint availability) -{ - if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_ONLINE) { - return(SIPE_STATUS_ID_OFFLINE); - } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY) { - return(SIPE_STATUS_ID_AVAILABLE); - } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_ON_PHONE) { - //return(SIPE_STATUS_ID_IDLE); - return(SIPE_STATUS_ID_AVAILABLE); - } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_BUSY) { - return(SIPE_STATUS_ID_BUSY); - } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_DND) { - //return(SIPE_STATUS_ID_BUSYIDLE); - return(SIPE_STATUS_ID_BUSY); - } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_BRB) { - return(SIPE_STATUS_ID_DND); - } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY2) { - return(SIPE_STATUS_ID_BRB); - } else if (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_OFFLINE) { - return(SIPE_STATUS_ID_AWAY); - } else { - return(SIPE_STATUS_ID_OFFLINE); - } -} - -const gchar *sipe_ocs2007_legacy_activity_description(guint availability) -{ - if ((availability >= SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY) && - (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_ON_PHONE)) { - return(sipe_activity_description(SIPE_ACTIVITY_INACTIVE)); - } else if ((availability >= SIPE_OCS2007_LEGACY_AVAILIBILITY_BUSY) && - (availability < SIPE_OCS2007_LEGACY_AVAILIBILITY_DND)) { - return(sipe_activity_description(SIPE_ACTIVITY_BUSYIDLE)); - } else { - return(NULL); - } -} - -/** - * @param sipe_status_id (in) - * @param activity_token (out) [only sipe-ocs2005.c/send_presence_soap() - * requests this token] - */ -#define SIPE_OCS2007_AVAILABILITY_UNKNOWN 0 -#define SIPE_OCS2007_AVAILABILITY_ONLINE 3500 -#define SIPE_OCS2007_AVAILABILITY_BUSY 6500 -#define SIPE_OCS2007_AVAILABILITY_DND 9500 /* do not disturb */ -#define SIPE_OCS2007_AVAILABILITY_BRB 12500 /* be right back */ -#define SIPE_OCS2007_AVAILABILITY_AWAY 15500 -#define SIPE_OCS2007_AVAILABILITY_OFFLINE 18500 -guint sipe_ocs2007_availability_from_status(const gchar *sipe_status_id, - const gchar **activity_token) -{ - guint availability; - sipe_activity activity; - - if (sipe_strequal(sipe_status_id, SIPE_STATUS_ID_AWAY)) { - availability = SIPE_OCS2007_AVAILABILITY_AWAY; - activity = SIPE_ACTIVITY_AWAY; - } else if (sipe_strequal(sipe_status_id, SIPE_STATUS_ID_BRB)) { - availability = SIPE_OCS2007_AVAILABILITY_BRB; - activity = SIPE_ACTIVITY_BRB; - } else if (sipe_strequal(sipe_status_id, SIPE_STATUS_ID_DND)) { - availability = SIPE_OCS2007_AVAILABILITY_DND; - activity = SIPE_ACTIVITY_DND; - } else if (sipe_strequal(sipe_status_id, SIPE_STATUS_ID_BUSY)) { - availability = SIPE_OCS2007_AVAILABILITY_BUSY; - activity = SIPE_ACTIVITY_BUSY; - } else if (sipe_strequal(sipe_status_id, SIPE_STATUS_ID_AVAILABLE)) { - availability = SIPE_OCS2007_AVAILABILITY_ONLINE; - activity = SIPE_ACTIVITY_ONLINE; - } else if (sipe_strequal(sipe_status_id, SIPE_STATUS_ID_UNKNOWN)) { - availability = SIPE_OCS2007_AVAILABILITY_UNKNOWN; - activity = SIPE_ACTIVITY_UNSET; - } else { - /* Offline or invisible */ - availability = SIPE_OCS2007_AVAILABILITY_OFFLINE; - activity = SIPE_ACTIVITY_OFFLINE; - } - - if (activity_token) { - *activity_token = sipe_activity_to_token(activity); - } - - return(availability); -} - -gboolean sipe_is_user_available(struct sipe_core_private *sipe_private) -{ - struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; - return(sipe_strequal(sip->status, SIPE_STATUS_ID_AVAILABLE)); -} - void send_presence_status(struct sipe_core_private *sipe_private, SIPE_UNUSED_PARAMETER gpointer unused) { @@ -469,78 +118,6 @@ void send_presence_status(struct sipe_core_private *sipe_private, sipe_cal_presence_publish(sipe_private, FALSE); } -void sipe_apply_calendar_status(struct sipe_core_private *sipe_private, - struct sipe_buddy *sbuddy, - const char *status_id) -{ - struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; - time_t cal_avail_since; - int cal_status = sipe_cal_get_status(sbuddy, time(NULL), &cal_avail_since); - int avail; - gchar *self_uri; - - if (!sbuddy) return; - - if (cal_status < SIPE_CAL_NO_DATA) { - SIPE_DEBUG_INFO("sipe_apply_calendar_status: cal_status : %d for %s", cal_status, sbuddy->name); - SIPE_DEBUG_INFO("sipe_apply_calendar_status: cal_avail_since : %s", asctime(localtime(&cal_avail_since))); - } - - /* scheduled Cal update call */ - if (!status_id) { - status_id = sbuddy->last_non_cal_status_id; - g_free(sbuddy->activity); - sbuddy->activity = g_strdup(sbuddy->last_non_cal_activity); - } - - if (!status_id) { - SIPE_DEBUG_INFO("sipe_apply_calendar_status: status_id is NULL for %s, exiting.", - sbuddy->name ? sbuddy->name : "" ); - return; - } - - /* adjust to calendar status */ - if (cal_status != SIPE_CAL_NO_DATA) { - SIPE_DEBUG_INFO("sipe_apply_calendar_status: user_avail_since: %s", asctime(localtime(&sbuddy->user_avail_since))); - - if (cal_status == SIPE_CAL_BUSY - && cal_avail_since > sbuddy->user_avail_since - && SIPE_OCS2007_AVAILABILITY_BUSY >= sipe_ocs2007_availability_from_status(status_id, NULL)) - { - status_id = SIPE_STATUS_ID_BUSY; - g_free(sbuddy->activity); - sbuddy->activity = g_strdup(sipe_activity_description(SIPE_ACTIVITY_IN_MEETING)); - } - avail = sipe_ocs2007_availability_from_status(status_id, NULL); - - SIPE_DEBUG_INFO("sipe_apply_calendar_status: activity_since : %s", asctime(localtime(&sbuddy->activity_since))); - if (cal_avail_since > sbuddy->activity_since) { - if (cal_status == SIPE_CAL_OOF - && avail >= SIPE_OCS2007_LEGACY_AVAILIBILITY_AWAY2) /* 12000 in 2007 */ - { - g_free(sbuddy->activity); - sbuddy->activity = g_strdup(sipe_activity_description(SIPE_ACTIVITY_OOF)); - } - } - } - - /* then set status_id actually */ - SIPE_DEBUG_INFO("sipe_apply_calendar_status: to %s for %s", status_id, sbuddy->name ? sbuddy->name : "" ); - sipe_backend_buddy_set_status(SIPE_CORE_PUBLIC, sbuddy->name, status_id); - - /* set our account state to the one in roaming (including calendar info) */ - self_uri = sip_uri_self(sipe_private); - if (sip->initial_state_published && sipe_strcase_equal(sbuddy->name, self_uri)) { - if (sipe_strequal(status_id, SIPE_STATUS_ID_OFFLINE)) { - /* do not let offline status switch us off */ - status_id = SIPE_STATUS_ID_INVISIBLE; - } - - sipe_status_and_note(sipe_private, status_id); - } - g_free(self_uri); -} - /* temporary function */ void sipe_purple_setup(struct sipe_core_public *sipe_public, PurpleConnection *gc) diff --git a/src/core/sipe.h b/src/core/sipe.h index 881bc366..3f2882fa 100644 --- a/src/core/sipe.h +++ b/src/core/sipe.h @@ -111,36 +111,8 @@ struct sipe_account_data { * - are needed by the already created new modules */ -#ifdef _SIPE_NEED_ACTIVITIES -/* need to improve or reduce visibility of this interface */ -const gchar *sipe_activity_to_token(sipe_activity); -const gchar *sipe_activity_description(sipe_activity); -sipe_activity sipe_activity_from_token(const gchar *token); -const gchar *sipe_activity_description_from_token(const gchar *token); -#endif -void sipe_set_status(struct sipe_core_private *sipe_private, - const gchar *status); -void sipe_set_unknown_status(struct sipe_core_private *sipe_private); -void sipe_set_initial_status(struct sipe_core_private *sipe_private); -void sipe_set_invisible_status(struct sipe_core_private *sipe_private); -/* OCS2007 status ID, availability & activity */ -guint sipe_ocs2007_availability_from_status(const gchar *sipe_status_id, - const gchar **activity_token); -const gchar *sipe_ocs2007_status_from_legacy_availability(guint availability); -const gchar *sipe_ocs2007_legacy_activity_description(guint availability); -/* OCS2005 status ID, availability & activity */ -guint sipe_ocs2005_activity_from_status(struct sipe_core_private *sipe_private); -guint sipe_ocs2005_availability_from_status(struct sipe_core_private *sipe_private); -const gchar *sipe_ocs2005_status_from_activity_availability(guint activity, - guint availablity); -const gchar *sipe_ocs2005_activity_description(guint activity); - void send_presence_status(struct sipe_core_private *sipe_private, gpointer unused); -gboolean sipe_is_user_available(struct sipe_core_private *sipe_private); -void sipe_apply_calendar_status(struct sipe_core_private *sipe_private, - struct sipe_buddy *sbuddy, - const char *status_id); /* libpurple memory leak workaround */ void sipe_blist_menu_free_containers(struct sipe_core_private *sipe_private); @@ -150,10 +122,6 @@ void sipe_blist_menu_free_containers(struct sipe_core_private *sipe_private); */ const gchar *sipe_get_buddy_status(struct sipe_core_private *sipe_private, const gchar *uri); -void sipe_buddy_status_from_activity(struct sipe_core_private *sipe_private, - const gchar *uri, - const gchar *activity, - gboolean is_online); /* referenced by sipe-notify.c - end */ diff --git a/src/purple/purple-plugin.c b/src/purple/purple-plugin.c index 0c0694a6..ae39f509 100644 --- a/src/purple/purple-plugin.c +++ b/src/purple/purple-plugin.c @@ -82,16 +82,18 @@ /* Sipe core activity <-> Purple status mapping */ static const gchar * const activity_to_purple[SIPE_ACTIVITY_NUM_TYPES] = { - /* SIPE_ACTIVITY_UNSET */ "unset", + /* SIPE_ACTIVITY_UNSET */ "unset", /* == purple_primitive_get_id_from_type(PURPLE_STATUS_UNSET) */ + /* SIPE_ACTIVITY_AVAILABLE */ "available", /* == purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE) */ /* SIPE_ACTIVITY_ONLINE */ "online", /* SIPE_ACTIVITY_INACTIVE */ "idle", /* SIPE_ACTIVITY_BUSY */ "busy", /* SIPE_ACTIVITY_BUSYIDLE */ "busyidle", /* SIPE_ACTIVITY_DND */ "do-not-disturb", /* SIPE_ACTIVITY_BRB */ "be-right-back", - /* SIPE_ACTIVITY_AWAY */ "away", + /* SIPE_ACTIVITY_AWAY */ "away", /* == purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY) */ /* SIPE_ACTIVITY_LUNCH */ "out-to-lunch", - /* SIPE_ACTIVITY_OFFLINE */ "offline", + /* SIPE_ACTIVITY_INVISIBLE */ "invisible", /* == purple_primitive_get_id_from_type(PURPLE_STATUS_INVISIBLE) */ + /* SIPE_ACTIVITY_OFFLINE */ "offline", /* == purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE) */ /* SIPE_ACTIVITY_ON_PHONE */ "on-the-phone", /* SIPE_ACTIVITY_IN_CONF */ "in-a-conference", /* SIPE_ACTIVITY_IN_MEETING */ "in-a-meeting", @@ -104,7 +106,7 @@ GHashTable *purple_to_activity = NULL; static void sipe_purple_activity_init(void) { - sipe_activity index = SIPE_ACTIVITY_UNSET; + guint index = SIPE_ACTIVITY_UNSET; purple_to_activity = g_hash_table_new(g_str_hash, g_str_equal); while (index < SIPE_ACTIVITY_NUM_TYPES) { g_hash_table_insert(purple_to_activity, @@ -114,6 +116,16 @@ static void sipe_purple_activity_init(void) } } +const gchar *sipe_backend_activity_to_token(guint type) +{ + return(activity_to_purple[type]); +} + +guint sipe_backend_token_to_activity(const gchar *token) +{ + return(PURPLE_STATUS_TO_ACTIVITY(token)); +} + gchar *sipe_backend_version(void) { return(g_strdup_printf("Purple/%s", purple_core_get_version())); @@ -176,7 +188,7 @@ static GList *sipe_purple_status_types(SIPE_UNUSED_PARAMETER PurpleAccount *acc) /* Busy */ SIPE_ADD_STATUS(PURPLE_STATUS_UNAVAILABLE, activity_to_purple[SIPE_ACTIVITY_BUSY], - _("Busy"), + sipe_core_activity_description(SIPE_ACTIVITY_BUSY), TRUE); /* Do Not Disturb */ @@ -198,7 +210,7 @@ static GList *sipe_purple_status_types(SIPE_UNUSED_PARAMETER PurpleAccount *acc) /* Be Right Back */ SIPE_ADD_STATUS(PURPLE_STATUS_AWAY, activity_to_purple[SIPE_ACTIVITY_BRB], - _("Be right back"), + sipe_core_activity_description(SIPE_ACTIVITY_BRB), TRUE); /* Appear Offline */ -- 2.11.4.GIT