From ef4646d0f1521418342d2a92d42c88a9d687b429 Mon Sep 17 00:00:00 2001 From: Jakub Adam Date: Thu, 25 Nov 2010 00:03:27 +0100 Subject: [PATCH] conference: allow correct dominant speaker detection Canonical identifier in RTCP packets sent during media call should be set to Globally Routable UA URI (GRUU) of the Sipe instance. MSOC clients use this value to detect speaking persons in voice conference and in the list of participants display a different "talking telephone receiver" icon next to the one who is speaking right now. Libpurple patch is required to allow setting of SDES parameters of underlying Farsight conference, reported upstream as http://developer.pidgin.im/ticket/12981 --- contrib/media-patches/README.txt | 1 + contrib/media-patches/purple_SDES.patch | 170 ++++++++++++++++++++++++++++++++ src/api/sipe-backend.h | 2 + src/core/sipe-media.c | 30 ++++-- src/purple/purple-media.c | 20 ++++ 5 files changed, 214 insertions(+), 9 deletions(-) create mode 100644 contrib/media-patches/purple_SDES.patch diff --git a/contrib/media-patches/README.txt b/contrib/media-patches/README.txt index 87189e10..3e7c3357 100644 --- a/contrib/media-patches/README.txt +++ b/contrib/media-patches/README.txt @@ -6,6 +6,7 @@ supports voice & video): - purple_mime_document_parsen.patch - purple_media_get_active_candidates.patch - purple_media_fs2_dispose.patch + - purple_SDES.patch - pidgin_media_remove_request_timeout_cb_on_dispose.patch (optional) - libnice01-Compatibility-with-MSOC-2007-R2.patch - libnice02-Compatibility-with-MSOC-2007.patch diff --git a/contrib/media-patches/purple_SDES.patch b/contrib/media-patches/purple_SDES.patch new file mode 100644 index 00000000..373e973a --- /dev/null +++ b/contrib/media-patches/purple_SDES.patch @@ -0,0 +1,170 @@ +From ddbe866bd982832263ab010aa7392d2b2ef7f176 Mon Sep 17 00:00:00 2001 +From: Jakub Adam +Date: Wed, 24 Nov 2010 22:19:54 +0100 +Subject: [PATCH] Allow to set SDES properties of FsRtpConference + +--- + libpurple/media.c | 7 +++++++ + libpurple/media.h | 20 ++++++++++++++++++++ + libpurple/media/backend-fs2.c | 34 ++++++++++++++++++++++++++++++++++ + libpurple/media/backend-iface.c | 8 ++++++++ + libpurple/media/backend-iface.h | 12 ++++++++++++ + 5 files changed, 81 insertions(+), 0 deletions(-) + +diff --git a/libpurple/media.c b/libpurple/media.c +index ca79eed..854adb9 100644 +--- a/libpurple/media.c ++++ b/libpurple/media.c +@@ -916,6 +916,13 @@ purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type, + #endif + } + ++void purple_media_set_params(PurpleMedia *media, GParameter *params) ++{ ++#ifdef USE_VV ++ purple_media_backend_set_params(media->priv->backend, params); ++#endif ++} ++ + #ifdef USE_VV + static void + purple_media_new_local_candidate_cb(PurpleMediaBackend *backend, +diff --git a/libpurple/media.h b/libpurple/media.h +index dc84f2d..0017e46 100644 +--- a/libpurple/media.h ++++ b/libpurple/media.h +@@ -144,6 +144,26 @@ void purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type, + gboolean local); + + /** ++ * Sets various optional parameters of the media call. ++ * ++ * Currently supported are: ++ * - "sdes-cname" : The CNAME for the RTP sessions ++ * - "sdes-name" : Real name used to describe the source in SDES messages ++ * - "sdes-tool" : The TOOL to put in SDES messages ++ * - "sdes-email" : Email address to put in SDES messages ++ * - "sdes-location" : The LOCATION to put in SDES messages ++ * - "sdes-note" : The NOTE to put in SDES messages ++ * - "sdes-phone" : The PHONE to put in SDES messages ++ * ++ * @param media The media object to set the parameters on. ++ * @param params Array of @c GParameter to pass to Farsight, terminated with ++ * NULL-name parameter. ++ * ++ * @since 2.8.0 ++ */ ++void purple_media_set_params(PurpleMedia *media, GParameter *params); ++ ++/** + * Adds a stream to a session. + * + * It only adds a stream to one audio session or video session as +diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c +index fd9de82..530da67 100644 +--- a/libpurple/media/backend-fs2.c ++++ b/libpurple/media/backend-fs2.c +@@ -85,6 +85,8 @@ static gboolean purple_media_backend_fs2_set_remote_codecs( + static gboolean purple_media_backend_fs2_set_send_codec( + PurpleMediaBackend *self, const gchar *sess_id, + PurpleMediaCodec *codec); ++static void purple_media_backend_fs2_set_params(PurpleMediaBackend *self, ++ GParameter *params); + + struct _PurpleMediaBackendFs2Class + { +@@ -367,6 +369,7 @@ purple_media_backend_iface_init(PurpleMediaBackendIface *iface) + purple_media_backend_fs2_get_local_candidates; + iface->set_remote_codecs = purple_media_backend_fs2_set_remote_codecs; + iface->set_send_codec = purple_media_backend_fs2_set_send_codec; ++ iface->set_params = purple_media_backend_fs2_set_params; + } + + static FsMediaType +@@ -1958,6 +1961,37 @@ purple_media_backend_fs2_set_send_codec(PurpleMediaBackend *self, + + return TRUE; + } ++ ++static void purple_media_backend_fs2_set_params(PurpleMediaBackend *self, ++ GParameter *params) ++{ ++ PurpleMediaBackendFs2Private *priv; ++ ++ g_return_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self)); ++ ++ priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); ++ ++ if (priv->conference == NULL && ++ !init_conference(PURPLE_MEDIA_BACKEND_FS2(self))) { ++ purple_debug_error("backend-fs2", ++ "Error initializing the conference.\n"); ++ return; ++ } ++ ++ while (params->name != NULL) { ++ if (!strcmp(params->name, "sdes-cname") || ++ !strcmp(params->name, "sdes-name") || ++ !strcmp(params->name, "sdes-tool") || ++ !strcmp(params->name, "sdes-email") || ++ !strcmp(params->name, "sdes-location") || ++ !strcmp(params->name, "sdes-note") || ++ !strcmp(params->name, "sdes-phone")) ++ g_object_set(priv->conference, ++ params->name, g_value_get_string(¶ms->value), ++ NULL); ++ params += 1; ++ } ++} + #else + GType + purple_media_backend_fs2_get_type(void) +diff --git a/libpurple/media/backend-iface.c b/libpurple/media/backend-iface.c +index 9c06934..fef2f2f 100644 +--- a/libpurple/media/backend-iface.c ++++ b/libpurple/media/backend-iface.c +@@ -192,3 +192,11 @@ purple_media_backend_set_send_codec(PurpleMediaBackend *self, + return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_send_codec(self, + sess_id, codec); + } ++ ++void ++purple_media_backend_set_params(PurpleMediaBackend *self, ++ GParameter *params) ++{ ++ g_return_if_fail(PURPLE_IS_MEDIA_BACKEND(self)); ++ PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_params(self, params); ++} +diff --git a/libpurple/media/backend-iface.h b/libpurple/media/backend-iface.h +index 258db85..f1edfaf 100644 +--- a/libpurple/media/backend-iface.h ++++ b/libpurple/media/backend-iface.h +@@ -68,6 +68,7 @@ struct _PurpleMediaBackendIface + GList *codecs); + gboolean (*set_send_codec) (PurpleMediaBackend *self, + const gchar *sess_id, PurpleMediaCodec *codec); ++ void (*set_params) (PurpleMediaBackend *self, GParameter *params); + }; + + /** +@@ -191,6 +192,17 @@ gboolean purple_media_backend_set_remote_codecs(PurpleMediaBackend *self, + gboolean purple_media_backend_set_send_codec(PurpleMediaBackend *self, + const gchar *sess_id, PurpleMediaCodec *codec); + ++/** ++ * Sets various optional parameters of the media backend. ++ * ++ * @param self The media backend to set the parameters on. ++ * @param params Array of @c GParameter to pass to backend, terminated with ++ * NULL-name parameter. ++ * ++ * @since 2.8.0 ++ */ ++void purple_media_backend_set_params(PurpleMediaBackend *self, GParameter *params); ++ + G_END_DECLS + + #endif /* _MEDIA_BACKEND_IFACE_H_ */ +-- +1.7.2.3 + diff --git a/src/api/sipe-backend.h b/src/api/sipe-backend.h index c0d975f9..263953c6 100644 --- a/src/api/sipe-backend.h +++ b/src/api/sipe-backend.h @@ -351,6 +351,8 @@ struct sipe_backend_media *sipe_backend_media_new(struct sipe_core_public *sipe_ gboolean initiator); void sipe_backend_media_free(struct sipe_backend_media *media); +void sipe_backend_media_set_cname(struct sipe_backend_media *media, gchar *cname); + struct sipe_backend_media_relays * sipe_backend_media_relays_convert(GSList *media_relays, gchar *username, gchar *password); diff --git a/src/core/sipe-media.c b/src/core/sipe-media.c index cf1f8d08..0fcdba80 100644 --- a/src/core/sipe-media.c +++ b/src/core/sipe-media.c @@ -661,15 +661,29 @@ error_cb(struct sipe_media_call *call, struct sipe_backend_media *backend_media, static struct sipe_media_call_private * sipe_media_call_new(struct sipe_core_private *sipe_private, - const gchar* with, gboolean initiator) + const gchar* with, gboolean initiator, gboolean with_legacy) { struct sipe_media_call_private *call_private = g_new0(struct sipe_media_call_private, 1); + gchar *cname; call_private->sipe_private = sipe_private; + + cname = g_strdup(sipe_private->contact + 1); + cname[strlen(cname) - 1] = '\0'; + call_private->public.backend_private = sipe_backend_media_new(SIPE_CORE_PUBLIC, SIPE_MEDIA_CALL, with, initiator); + sipe_backend_media_set_cname(call_private->public.backend_private, cname); + + if (with_legacy) { + call_private->public.backend_private_legacy + = sipe_backend_media_new(SIPE_CORE_PUBLIC, SIPE_MEDIA_CALL, + with, initiator); + sipe_backend_media_set_cname(call_private->public.backend_private_legacy, cname); + } + call_private->ice_version = SIPE_ICE_RFC_5245; call_private->encryption_compatible = TRUE; @@ -681,6 +695,8 @@ sipe_media_call_new(struct sipe_core_private *sipe_private, call_private->public.call_hangup_cb = call_hangup_cb; call_private->public.error_cb = error_cb; + g_free(cname); + return call_private; } @@ -711,7 +727,7 @@ sipe_core_media_initiate_call(struct sipe_core_public *sipe_public, if (sipe_private->media_call) return; - call_private = sipe_media_call_new(sipe_private, with, TRUE); + call_private = sipe_media_call_new(sipe_private, with, TRUE, TRUE); session = sipe_session_add_call(sipe_private, with); dialog = sipe_dialog_add(session); @@ -751,11 +767,7 @@ sipe_core_media_initiate_call(struct sipe_core_public *sipe_public, return; } - backend_media_legacy = sipe_backend_media_new(SIPE_CORE_PUBLIC, - SIPE_MEDIA_CALL, - with, TRUE); - - call_private->public.backend_private_legacy = backend_media_legacy; + backend_media_legacy = call_private->public.backend_private_legacy; sipe_backend_media_add_stream(backend_media_legacy, "audio", with, SIPE_MEDIA_AUDIO, @@ -792,7 +804,7 @@ void sipe_core_media_connect_conference(struct sipe_core_public *sipe_public, av_uri = g_strjoinv("app:conf:audio-video:", parts); g_strfreev(parts); - sipe_private->media_call = sipe_media_call_new(sipe_private, av_uri, TRUE); + sipe_private->media_call = sipe_media_call_new(sipe_private, av_uri, TRUE, FALSE); session = sipe_session_add_call(sipe_private, av_uri); dialog = sipe_dialog_add(session); @@ -863,7 +875,7 @@ process_incoming_invite_call(struct sipe_core_private *sipe_private, struct sip_session *session; struct sip_dialog *dialog; - call_private = sipe_media_call_new(sipe_private, with, FALSE); + call_private = sipe_media_call_new(sipe_private, with, FALSE, FALSE); session = sipe_session_add_call(sipe_private, with); dialog = sipe_media_dialog_init(session, msg); diff --git a/src/purple/purple-media.c b/src/purple/purple-media.c index 23e79eec..a9577536 100644 --- a/src/purple/purple-media.c +++ b/src/purple/purple-media.c @@ -226,6 +226,26 @@ sipe_backend_media_free(struct sipe_backend_media *media) } } +void +sipe_backend_media_set_cname(struct sipe_backend_media *media, gchar *cname) +{ + if (media) { + GParameter *params = g_new0(GParameter, 4); + params[0].name = "sdes-cname"; + g_value_init(¶ms[0].value, G_TYPE_STRING); + g_value_set_string(¶ms[0].value, cname); + params[1].name = "sdes-name"; + g_value_init(¶ms[1].value, G_TYPE_STRING); + g_value_set_string(¶ms[1].value, NULL); + params[2].name = "sdes-tool"; + g_value_init(¶ms[2].value, G_TYPE_STRING); + params[3].name = NULL; + purple_media_set_params(media->m, params); + + g_free(params); + } +} + #define FS_CODECS_CONF \ "# Automatically created by SIPE plugin\n" \ "[video/H263]\n" \ -- 2.11.4.GIT