From db8a785798d97e2b0dcf6d78ed300f428e1786a5 Mon Sep 17 00:00:00 2001 From: Jakub Adam Date: Tue, 29 Mar 2011 21:56:28 +0200 Subject: [PATCH] conf: allow to join scheduled conference Users now can join scheduled conferences through an option in Pidgin's account menu. They need to provide meeting URI in format meet:sip:someone@company.com;gruu;opaque=app:conf:focus:id:abcdef1234?conf-key=1234 Link to the conference can be found in email invitations generated by Exchange when somebody schedules a live meeting. If Sipe is compiled without voice & video, user at least gets instant messaging session. --- src/api/sipe-core.h | 12 ++++++++++++ src/core/sipe-conf.c | 44 ++++++++++++++++++++++++++++++++++++++++++- src/purple/purple-plugin.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/api/sipe-core.h b/src/api/sipe-core.h index e71cc054..63769a5f 100644 --- a/src/api/sipe-core.h +++ b/src/api/sipe-core.h @@ -293,6 +293,18 @@ void sipe_core_chat_modify_lock(struct sipe_core_public *sipe_public, struct sipe_chat_session *chat_session, const gboolean locked); +/** + * Create new session with Focus URI + * + * @param sipe_public (in) SIPE core data. + * @param focus_uri (in) focus URI string + * + * @return new SIP session + */ +struct sip_session * +sipe_core_conf_create(struct sipe_core_public *sipe_public, + const gchar *focus_uri); + /* media */ void sipe_core_media_initiate_call(struct sipe_core_public *sipe_public, const char *participant, diff --git a/src/core/sipe-conf.c b/src/core/sipe-conf.c index 39d7f479..ae21e046 100644 --- a/src/core/sipe-conf.c +++ b/src/core/sipe-conf.c @@ -261,8 +261,13 @@ process_invite_conf_focus_response(struct sipe_core_private *sipe_private, } if (msg->response >= 400) { + gchar *reason = sipmsg_get_ms_diagnostics_reason(msg); + SIPE_DEBUG_INFO_NOFORMAT("process_invite_conf_focus_response: INVITE response is not 200. Failed to join focus."); - /* @TODO notify user of failure to join focus */ + sipe_backend_notify_error(_("Failed to join the conference"), + reason ? reason : _("no reason given")); + g_free(reason); + sipe_session_remove(sipe_private, session); g_free(focus_uri); return FALSE; @@ -285,6 +290,43 @@ process_invite_conf_focus_response(struct sipe_core_private *sipe_private, return TRUE; } +struct sip_session * +sipe_core_conf_create(struct sipe_core_public *sipe_public, + const gchar *focus_uri) +{ + gchar *buf; + const gchar *focus_uri_ue; + struct sip_session *session = NULL; + + focus_uri_ue = buf = sipe_utils_uri_unescape(focus_uri); + + // URI can have this prefix if it was typed in by the user + if (g_str_has_prefix(focus_uri_ue, "meet:")) + focus_uri_ue += 5; + + if (!focus_uri_ue || !g_str_has_prefix(focus_uri_ue, "sip:") || + strlen(focus_uri_ue) == 4 || g_strstr_len(focus_uri_ue, -1, "%")) { + gchar *error = g_strdup_printf(_("\"%s\" is not a valid focus URI"), + focus_uri ? focus_uri : ""); + sipe_backend_notify_error(_("Failed to join the conference"), + error); + g_free(error); + } else { + gchar *querystr = g_strstr_len(focus_uri_ue, -1, "?"); + if (querystr) { + /* TODO: Investigate how conf-key field should be used, + * ignoring for now */ + *querystr = '\0'; + } + + session = sipe_conf_create(SIPE_CORE_PRIVATE, NULL, focus_uri_ue); + } + + g_free(buf); + + return session; +} + /** Create new session with Focus URI */ struct sip_session * sipe_conf_create(struct sipe_core_private *sipe_private, diff --git a/src/purple/purple-plugin.c b/src/purple/purple-plugin.c index 7f136312..0c7df664 100644 --- a/src/purple/purple-plugin.c +++ b/src/purple/purple-plugin.c @@ -609,6 +609,50 @@ static void sipe_purple_show_find_contact(PurplePluginAction *action) purple_connection_get_account(gc), NULL, NULL, gc); } +static void sipe_purple_join_conference_cb(PurpleConnection *gc, + PurpleRequestFields *fields) +{ + GList *entries = purple_request_field_group_get_fields(purple_request_fields_get_groups(fields)->data); + + if (entries) { + PurpleRequestField *field = entries->data; + const char *id = purple_request_field_get_id(field); + const char *value = purple_request_field_string_get_value(field); + + if (!sipe_strequal(id, "meetingLocation")) + return; + + sipe_core_conf_create(PURPLE_GC_TO_SIPE_CORE_PUBLIC, value); + } +} + +static void sipe_purple_show_join_conference(PurplePluginAction *action) +{ + PurpleConnection *gc = (PurpleConnection *) action->context; + PurpleRequestFields *fields; + PurpleRequestFieldGroup *group; + PurpleRequestField *field; + + fields = purple_request_fields_new(); + group = purple_request_field_group_new(NULL); + purple_request_fields_add_group(fields, group); + + field = purple_request_field_string_new("meetingLocation", _("Meeting location"), NULL, FALSE); + purple_request_field_group_add_field(group, field); + + purple_request_fields(gc, + _("Join conference"), + _("Join scheduled conference"), + _("Enter meeting location string you received in the invitation.\n" + "\n" + "Valid location will be something like\n" + "meet:sip:someone@company.com;gruu;opaque=app:conf:focus:id:abcdef1234"), + fields, + _("_Join"), G_CALLBACK(sipe_purple_join_conference_cb), + _("_Cancel"), NULL, + purple_connection_get_account(gc), NULL, NULL, gc); +} + static void sipe_purple_republish_calendar(PurplePluginAction *action) { PurpleConnection *gc = (PurpleConnection *) action->context; @@ -633,6 +677,9 @@ static GList *sipe_purple_actions(SIPE_UNUSED_PARAMETER PurplePlugin *plugin, act = purple_plugin_action_new(_("Contact search..."), sipe_purple_show_find_contact); menu = g_list_prepend(menu, act); + act = purple_plugin_action_new(_("Join scheduled conference..."), sipe_purple_show_join_conference); + menu = g_list_prepend(menu, act); + act = purple_plugin_action_new(_("Republish Calendar"), sipe_purple_republish_calendar); menu = g_list_prepend(menu, act); -- 2.11.4.GIT