Mercurial > pidgin
changeset 23759:315151da0dc6
Basic Google Talk voice call support. No UI; receiving a call auto-accepts it.
line wrap: on
line diff
--- a/finch/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -59,6 +59,7 @@ $(INTLLIBS) \ $(GLIB_LIBS) \ $(LIBXML_LIBS) \ + $(FARSIGHT_LIBS) \ $(GNT_LIBS) \ $(GSTREAMER_LIBS) \ ./libgnt/libgnt.la \ @@ -78,5 +79,6 @@ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ $(LIBXML_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GSTREAMER_CFLAGS) \ $(GNT_CFLAGS)
--- a/finch/gntaccount.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntaccount.c Wed Sep 05 00:47:58 2007 +0000 @@ -22,6 +22,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <account.h> +#include <accountopt.h> +#include <connection.h> +#include <notify.h> +#include <plugin.h> +#include <request.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -36,13 +43,6 @@ #include "finch.h" -#include <account.h> -#include <accountopt.h> -#include <connection.h> -#include <notify.h> -#include <plugin.h> -#include <request.h> - #include "gntaccount.h" #include "gntblist.h"
--- a/finch/gntdebug.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntdebug.c Wed Sep 05 00:47:58 2007 +0000 @@ -22,6 +22,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "util.h" + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -33,7 +35,6 @@ #include "gntdebug.h" #include "finch.h" -#include "util.h" #include <stdio.h> #include <string.h>
--- a/finch/gntft.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntft.c Wed Sep 05 00:47:58 2007 +0000 @@ -22,19 +22,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "internal.h" +#include "debug.h" +#include "notify.h" +#include "ft.h" +#include "prpl.h" +#include "util.h" + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> #include <gntcheckbox.h> #include <gntlabel.h> #include <gnttree.h> -#include "internal.h" - -#include "debug.h" -#include "notify.h" -#include "ft.h" -#include "prpl.h" -#include "util.h" #include "gntft.h" #include "prefs.h"
--- a/finch/gntnotify.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntnotify.c Wed Sep 05 00:47:58 2007 +0000 @@ -22,6 +22,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <util.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -31,7 +33,6 @@ #include "finch.h" -#include <util.h> #include "gntnotify.h"
--- a/finch/gntplugin.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntplugin.c Wed Sep 05 00:47:58 2007 +0000 @@ -22,6 +22,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "notify.h" +#include "request.h" + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -31,8 +34,6 @@ #include "finch.h" -#include "notify.h" -#include "request.h" #include "gntplugin.h" #include "gntrequest.h"
--- a/finch/gntpounce.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntpounce.c Wed Sep 05 00:47:58 2007 +0000 @@ -23,6 +23,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ +#include "internal.h" +#include "account.h" +#include "conversation.h" +#include "debug.h" +#include "notify.h" +#include "prpl.h" +#include "request.h" +#include "server.h" +#include "util.h" + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -34,18 +44,8 @@ #include <gnttree.h> #include <gntutils.h> -#include "internal.h" #include "finch.h" -#include "account.h" -#include "conversation.h" -#include "debug.h" -#include "notify.h" -#include "prpl.h" -#include "request.h" -#include "server.h" -#include "util.h" - #include "gntpounce.h"
--- a/finch/gntrequest.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntrequest.c Wed Sep 05 00:47:58 2007 +0000 @@ -22,6 +22,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "util.h" + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -35,7 +38,6 @@ #include "finch.h" #include "gntrequest.h" -#include "util.h" typedef struct {
--- a/finch/gntstatus.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntstatus.c Wed Sep 05 00:47:58 2007 +0000 @@ -22,6 +22,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <notify.h> +#include <request.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -34,9 +38,6 @@ #include "finch.h" -#include <notify.h> -#include <request.h> - #include "gntstatus.h" static struct
--- a/finch/gntui.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/gntui.c Wed Sep 05 00:47:58 2007 +0000 @@ -19,9 +19,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <prefs.h> #include "internal.h" -#include "gntui.h" #include "gntaccount.h" #include "gntblist.h" @@ -37,7 +37,7 @@ #include "gntstatus.h" #include "gntsound.h" -#include <prefs.h> +#include "gntui.h" void gnt_ui_init() {
--- a/finch/libgnt/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/libgnt/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -88,6 +88,7 @@ AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GNT_CFLAGS) \ $(DEBUG_CFLAGS) \ $(LIBXML_CFLAGS)
--- a/finch/libgnt/wms/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/libgnt/wms/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -34,5 +34,6 @@ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(GNT_CFLAGS) \ - $(PLUGIN_CFLAGS) + $(PLUGIN_CFLAGS) \ + $(FARSIGHT_CFLAGS)
--- a/finch/libgnt/wms/s.c Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/libgnt/wms/s.c Wed Sep 05 00:47:58 2007 +0000 @@ -2,6 +2,7 @@ #include <sys/types.h> #include "internal.h" +#include "blist.h" #include "gnt.h" #include "gntbox.h" @@ -11,7 +12,6 @@ #include "gntwindow.h" #include "gntlabel.h" -#include "blist.h" #define TYPE_S (s_get_gtype())
--- a/finch/plugins/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/finch/plugins/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -37,7 +37,8 @@ -I$(top_srcdir) \ -I$(top_srcdir)/finch \ -I$(top_srcdir)/finch/libgnt \ - $(DEBUG_CFLAGS) \ + $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GLIB_CFLAGS) \ $(GNT_CFLAGS) \ $(PLUGIN_CFLAGS)
--- a/libpurple/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -49,6 +49,8 @@ idle.c \ imgstore.c \ log.c \ + media.c \ + mediamanager.c \ mime.c \ nat-pmp.c \ network.c \ @@ -100,6 +102,8 @@ idle.h \ imgstore.h \ log.h \ + media.h \ + mediamanager.h \ mime.h \ nat-pmp.h \ network.h \ @@ -231,6 +235,7 @@ $(LIBXML_LIBS) \ $(LIBNM_LIBS) \ $(INTLLIBS) \ + $(FARSIGHT_LIBS) \ -lm AM_CPPFLAGS = \ @@ -243,4 +248,5 @@ $(DEBUG_CFLAGS) \ $(DBUS_CFLAGS) \ $(LIBXML_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(LIBNM_CFLAGS)
--- a/libpurple/example/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/example/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -7,7 +7,8 @@ $(DBUS_LIBS) \ $(INTLLIBS) \ $(GLIB_LIBS) \ - $(LIBXML_LIBS) \ + $(LIBXML_LIBS) \ + $(FARSIGHT_LIBS) \ $(top_builddir)/libpurple/libpurple.la AM_CPPFLAGS = \ @@ -22,4 +23,5 @@ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(LIBXML_CFLAGS)
--- a/libpurple/plugins/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/plugins/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -130,6 +130,7 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GLIB_CFLAGS) \ $(PLUGIN_CFLAGS) \ $(DBUS_CFLAGS)
--- a/libpurple/plugins/perl/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/plugins/perl/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -5,7 +5,7 @@ plugin_LTLIBRARIES = perl.la perl_la_LDFLAGS = -module -avoid-version -perl_la_LIBADD = $(GLIB_LIBS) $(PERL_LIBS) +perl_la_LIBADD = $(GLIB_LIBS) $(PERL_LIBS) $(FARSIGHT_LIBS) perl_la_SOURCES = \ perl.c \ perl-common.c \ @@ -159,4 +159,5 @@ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(PLUGIN_CFLAGS) \ - $(PERL_CFLAGS) + $(PERL_CFLAGS) \ + $(FARSIGHT_CFLAGS)
--- a/libpurple/plugins/ssl/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/plugins/ssl/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -31,6 +31,7 @@ -I$(top_builddir)/libpurple \ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(PLUGIN_CFLAGS) ssl_gnutls_la_CFLAGS = $(AM_CPPFLAGS) $(GNUTLS_CFLAGS)
--- a/libpurple/plugins/tcl/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/plugins/tcl/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -7,7 +7,7 @@ tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_purple.h \ tcl_ref.c tcl_cmd.c -tcl_la_LIBADD = $(GLIB_LIBS) $(TCL_LIBS) $(TK_LIBS) +tcl_la_LIBADD = $(GLIB_LIBS) $(TCL_LIBS) $(TK_LIBS) $(FARSIGHT_LIBS) EXTRA_DIST = signal-test.tcl Makefile.mingw @@ -18,5 +18,6 @@ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(PLUGIN_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(TK_CFLAGS) \ $(TCL_CFLAGS)
--- a/libpurple/protocols/bonjour/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/bonjour/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -69,8 +69,8 @@ -I$(top_builddir)/libpurple \ $(GLIB_CFLAGS) \ $(DEBUG_CFLAGS) \ - $(LIBXML_CFLAGS) - + $(LIBXML_CFLAGS) \ + $(FARSIGHT_CFLAGS) if MDNS_AVAHI AM_CPPFLAGS += $(AVAHI_CFLAGS) else
--- a/libpurple/protocols/bonjour/bonjour.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Wed Sep 05 00:47:58 2007 +0000 @@ -439,7 +439,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static PurplePluginInfo info =
--- a/libpurple/protocols/gg/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/gg/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -75,5 +75,6 @@ -I$(top_builddir)/libpurple \ $(INTGG_CFLAGS) \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS)
--- a/libpurple/protocols/gg/gg.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/gg/gg.c Wed Sep 05 00:47:58 2007 +0000 @@ -2126,7 +2126,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; /* }}} */
--- a/libpurple/protocols/irc/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/irc/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -32,4 +32,5 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS)
--- a/libpurple/protocols/irc/irc.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/irc/irc.c Wed Sep 05 00:47:58 2007 +0000 @@ -931,7 +931,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static void _init_plugin(PurplePlugin *plugin)
--- a/libpurple/protocols/jabber/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -68,4 +68,5 @@ -I$(top_builddir)/libpurple \ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(LIBXML_CFLAGS)
--- a/libpurple/protocols/jabber/disco.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/disco.c Wed Sep 05 00:47:58 2007 +0000 @@ -98,6 +98,15 @@ SUPPORT_FEATURE("http://jabber.org/protocol/si/profile/file-transfer") SUPPORT_FEATURE("http://jabber.org/protocol/xhtml-im") SUPPORT_FEATURE("urn:xmpp:ping") + } else if (node && !strcmp(node, CAPS0115_NODE "#voice-v1")) { + SUPPORT_FEATURE("http://www.google.com/session"); + SUPPORT_FEATURE("http://www.google.com/transport/p2p"); + SUPPORT_FEATURE("http://www.google.com/transport/raw-udp"); + SUPPORT_FEATURE("http://www.google.com/session/phone"); + SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0166.html"); + SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0180.html"); + SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0167.html"); + SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0177.html"); } else { xmlnode *error, *inf;
--- a/libpurple/protocols/jabber/google.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/google.c Wed Sep 05 00:47:58 2007 +0000 @@ -18,8 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <farsight/farsight-transport.h> + #include "internal.h" #include "debug.h" +#include "mediamanager.h" #include "util.h" #include "privacy.h" @@ -29,6 +32,299 @@ #include "presence.h" #include "iq.h" +typedef struct { + char *id; + char *initiator; +} GoogleSessionId; + +typedef enum { + UNINIT, + SENT_INITIATE, + RECEIVED_INITIATE, + IN_PRORESS, + TERMINATED +} GoogleSessionState; + +typedef struct { + GoogleSessionId id; + GoogleSessionState state; + PurpleMedia *media; + FarsightStream *stream; + JabberStream *js; + char *remote_jid; +} GoogleSession; + + +static guint +google_session_id_hash(gconstpointer key) +{ + GoogleSessionId *id = (GoogleSessionId*)key; + + guint id_hash = g_str_hash(id->id); + guint init_hash = g_str_hash(id->initiator); + + return 23 * id_hash + init_hash; +} + +static gboolean +google_session_id_equal(gconstpointer a, gconstpointer b) +{ + GoogleSessionId *c = (GoogleSessionId*)a; + GoogleSessionId *d = (GoogleSessionId*)b; + + return !strcmp(c->id, d->id) && !strcmp(c->initiator, d->initiator); +} + +GHashTable *sessions = NULL; + +static xmlnode * +google_session_create_xmlnode(GoogleSession *session, const char *type) +{ + xmlnode *node = xmlnode_new("session"); + xmlnode_set_namespace(node, "http://www.google.com/session"); + xmlnode_set_attrib(node, "id", session->id.id); + xmlnode_set_attrib(node, "initiator", session->id.initiator); + xmlnode_set_attrib(node, "type", type); + return node; +} + +static void +google_session_send_accept(GoogleSession *session) +{ + xmlnode *sess, *desc, *payload; + GList *codecs = farsight_stream_get_codec_intersection(session->stream); + JabberIq *iq = jabber_iq_new(session->js, JABBER_IQ_SET); + + xmlnode_set_attrib(iq->node, "to", session->remote_jid); + sess = google_session_create_xmlnode(session, "accept"); + xmlnode_insert_child(iq->node, sess); + desc = xmlnode_new_child(sess, "description"); + xmlnode_set_namespace(desc, "http://www.google.com/session/phone"); + + for (;codecs; codecs = codecs->next) { + FarsightCodec *codec = (FarsightCodec*)codecs->data; + char id[8], clockrate[10]; + payload = xmlnode_new_child(desc, "payload-type"); + g_snprintf(id, sizeof(id), "%d", codec->id); + g_snprintf(clockrate, sizeof(clockrate), "%d", codec->clock_rate); + xmlnode_set_attrib(payload, "name", codec->encoding_name); + xmlnode_set_attrib(payload, "id", id); + xmlnode_set_attrib(payload, "clockrate", clockrate); + } + + jabber_iq_send(iq); + farsight_stream_start(session->stream); +} + +static void +google_session_candidates_prepared (FarsightStream *stream, gchar *candidate_id, GoogleSession *session) +{ + JabberIq *iq = jabber_iq_new(session->js, JABBER_IQ_SET); + GList *candidates = farsight_stream_get_native_candidate_list(stream); + FarsightTransportInfo *transport; + xmlnode *sess; + xmlnode *candidate; + sess = google_session_create_xmlnode(session, "candidates"); + xmlnode_insert_child(iq->node, sess); + xmlnode_set_attrib(iq->node, "to", session->remote_jid); + + for (;candidates;candidates = candidates->next) { + transport = (FarsightTransportInfo*)(candidates->data); + char port[8]; + char pref[8]; + + if (!strcmp(transport->ip, "127.0.0.1")) + continue; + + candidate = xmlnode_new("candidate"); + + g_snprintf(port, sizeof(port), "%d", transport->port); + g_snprintf(pref, sizeof(pref), "%f", transport->preference); + + xmlnode_set_attrib(candidate, "address", transport->ip); + xmlnode_set_attrib(candidate, "port", port); + xmlnode_set_attrib(candidate, "name", "rtp"); + xmlnode_set_attrib(candidate, "username", transport->username); + xmlnode_set_attrib(candidate, "password", transport->password); + xmlnode_set_attrib(candidate, "preference", pref); + xmlnode_set_attrib(candidate, "protocol", transport->proto == FARSIGHT_NETWORK_PROTOCOL_UDP ? "udp" : "tcp"); + xmlnode_set_attrib(candidate, "type", transport->type == FARSIGHT_CANDIDATE_TYPE_LOCAL ? "local" : + transport->type == FARSIGHT_CANDIDATE_TYPE_DERIVED ? "stun" : + transport->type == FARSIGHT_CANDIDATE_TYPE_RELAY ? "relay" : NULL); + xmlnode_set_attrib(candidate, "generation", "0"); + xmlnode_set_attrib(candidate, "network", "0"); + xmlnode_insert_child(sess, candidate); + + } + jabber_iq_send(iq); +} + +static gboolean +google_session_handle_initiate(JabberStream *js, GoogleSession *session, xmlnode *packet) +{ + PurpleMedia *media; + FarsightSession *fs; + GList *codecs = NULL; + xmlnode *desc_element, *codec_element; + FarsightCodec *codec; + const char *id, *encoding_name, *clock_rate; + int res; + + + if (session->state != UNINIT) { + purple_debug_error("jabber", "Received initiate for active session.\n"); + return FALSE; + } + + fs = farsight_session_factory_make("rtp"); + if (!fs) { + purple_debug_error("jabber", "Farsight's rtp plugin not installed"); + return FALSE; + } + session->stream = farsight_session_create_stream(fs, FARSIGHT_MEDIA_TYPE_AUDIO, FARSIGHT_STREAM_DIRECTION_BOTH); + + g_object_set(G_OBJECT(session->stream), "transmitter", "libjingle", NULL); + + desc_element = xmlnode_get_child(packet, "description"); + + for (codec_element = xmlnode_get_child(desc_element, "payload-type"); + codec_element; + codec_element = xmlnode_get_next_twin(codec_element)) { + encoding_name = xmlnode_get_attrib(codec_element, "name"); + id = xmlnode_get_attrib(codec_element, "id"); + clock_rate = xmlnode_get_attrib(codec_element, "clockrate"); + + codec = g_new0(FarsightCodec, 1); + farsight_codec_init(codec, atoi(id), encoding_name, FARSIGHT_MEDIA_TYPE_AUDIO, clock_rate ? atoi(clock_rate) : 0); + codecs = g_list_append(codecs, codec); + } + GstElement *e = gst_element_factory_make("alsasrc", "source"); + farsight_stream_set_source(session->stream, e); + farsight_stream_set_source_filter(session->stream, gst_caps_new_simple("audio/x-raw-int", "rate",G_TYPE_INT,8000, NULL)); + gst_object_unref(e); + + e = gst_element_factory_make("alsasink", "fakes"); + g_object_set(e, "sync", FALSE, NULL); + farsight_stream_set_sink(session->stream, e); + gst_object_unref(e); + + farsight_stream_prepare_transports(session->stream); + res = farsight_stream_set_remote_codecs(session->stream, codecs); + + + farsight_codec_list_destroy(codecs); + g_signal_connect(G_OBJECT(session->stream), "new-native-candidate", G_CALLBACK(google_session_candidates_prepared), session); +google_session_send_accept(session); + media = purple_media_manager_create_media(purple_media_manager_get(), js->gc, session->remote_jid); + return res; +} + +static gboolean +google_session_handle_candidates(JabberStream *js, GoogleSession *session, xmlnode *sess) +{ + GList *list = NULL; + xmlnode *cand; + static int name = 0; + char n[4]; + + for (cand = xmlnode_get_child(sess, "candidate"); cand; cand = xmlnode_get_next_twin(cand)) { + FarsightTransportInfo *info = g_new0(FarsightTransportInfo, 1); + g_snprintf(n, sizeof(n), "S%d", name++); + info->ip = xmlnode_get_attrib(cand, "address"); + info->port = atoi(xmlnode_get_attrib(cand, "port")); + info->proto = !strcmp(xmlnode_get_attrib(cand, "protocol"),"udp") ? FARSIGHT_NETWORK_PROTOCOL_UDP : FARSIGHT_NETWORK_PROTOCOL_TCP; + info->preference = atof(xmlnode_get_attrib(cand, "preference")); + info->type = !strcmp(xmlnode_get_attrib(cand, "type"), "local") ? FARSIGHT_CANDIDATE_TYPE_LOCAL : + !strcmp(xmlnode_get_attrib(cand, "type"), "stun") ? FARSIGHT_CANDIDATE_TYPE_DERIVED : + !strcmp(xmlnode_get_attrib(cand, "type"), "relay") ? FARSIGHT_CANDIDATE_TYPE_RELAY : FARSIGHT_CANDIDATE_TYPE_LOCAL; + info->candidate_id = n; + info->username = xmlnode_get_attrib(cand, "username"); + info->password = xmlnode_get_attrib(cand, "password"); + list = g_list_append(list, info); + } + + farsight_stream_add_remote_candidate(session->stream, list); + g_list_foreach(list, g_free, NULL); + g_list_free(list); + return TRUE; +} + +static void +google_session_parse_iq(JabberStream *js, GoogleSession *session, xmlnode *packet) +{ + JabberIq *result; + gboolean valid = TRUE; + xmlnode *sess = xmlnode_get_child(packet, "session"); + const char *type = xmlnode_get_attrib(sess, "type"); + + if (!strcmp(type, "initiate")) { + valid = google_session_handle_initiate(js, session, sess); + } else if (!strcmp(type, "accept")) { + } else if (!strcmp(type, "reject")) { + } else if (!strcmp(type, "terminate")) { + } else if (!strcmp(type, "candidates")) { + valid = google_session_handle_candidates(js, session, sess); + } + + if (valid) { + result = jabber_iq_new(js, JABBER_IQ_RESULT); + jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id")); + xmlnode_set_attrib(result->node, "to", session->remote_jid); + jabber_iq_send(result); + } +} + +void +jabber_google_session_parse(JabberStream *js, xmlnode *packet) +{ + GoogleSession *session; + GoogleSessionId id; + JabberIq *result; + + xmlnode *session_node; + xmlnode *desc_node; + + if (strcmp(xmlnode_get_attrib(packet, "type"), "set")) + return; + + session_node = xmlnode_get_child(packet, "session"); + if (!session_node) + return; + + id.id = xmlnode_get_attrib(session_node, "id"); + if (!id.id) + return; + + id.initiator = xmlnode_get_attrib(session_node, "initiator"); + if (!id.initiator) + return; + + if (sessions == NULL) + sessions = g_hash_table_new(google_session_id_hash, google_session_id_equal); + session = (GoogleSession*)g_hash_table_lookup(sessions, &id); + + if (session) { + google_session_parse_iq(js, session, packet); + return; + } + + /* If the session doesn't exist, this has to be an initiate message */ + if (strcmp(xmlnode_get_attrib(session_node, "type"), "initiate")) + return; + desc_node = xmlnode_get_child(session_node, "description"); + if (!desc_node) + return; + session = g_new0(GoogleSession, 1); + session->id.id = g_strdup(id.id); + session->id.initiator = g_strdup(id.initiator); + session->state = UNINIT; + session->js = js; + session->remote_jid = g_strdup(session->id.initiator); + g_hash_table_insert(sessions, &(session->id), session); + + google_session_parse_iq(js, session, packet); +} + static void jabber_gmail_parse(JabberStream *js, xmlnode *packet, gpointer nul) {
--- a/libpurple/protocols/jabber/google.h Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/google.h Wed Sep 05 00:47:58 2007 +0000 @@ -41,6 +41,7 @@ char *jabber_google_format_to_html(const char *text); +void jabber_google_session_parse(JabberStream *js, xmlnode *node); #endif /* _PURPLE_GOOGLE_H_ */
--- a/libpurple/protocols/jabber/iq.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/iq.c Wed Sep 05 00:47:58 2007 +0000 @@ -333,6 +333,11 @@ return; } } + + if (xmlnode_get_child_with_namespace(packet, "session", "http://www.google.com/session")) { + jabber_google_session_parse(js, packet); + return; + } if(xmlnode_get_child_with_namespace(packet, "si", "http://jabber.org/protocol/si")) { jabber_si_parse(js, packet);
--- a/libpurple/protocols/jabber/jabber.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/jabber.c Wed Sep 05 00:47:58 2007 +0000 @@ -1814,6 +1814,11 @@ return TRUE; } +PurpleMedia *jabber_media_initiate(PurpleConnection *gc, const char *who, PurpleMediaStreamType type) +{ + return NULL; +} + void jabber_register_commands(void) { purple_cmd_register("config", "", PURPLE_CMD_P_PRPL,
--- a/libpurple/protocols/jabber/jabber.h Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/jabber.h Wed Sep 05 00:47:58 2007 +0000 @@ -187,5 +187,5 @@ GList *jabber_actions(PurplePlugin *plugin, gpointer context); void jabber_register_commands(void); void jabber_init_plugin(PurplePlugin *plugin); - +PurpleMedia *jabber_media_initiate(PurpleConnection *gc, const char *who, PurpleMediaStreamType type); #endif /* _PURPLE_JABBER_H_ */
--- a/libpurple/protocols/jabber/libxmpp.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Wed Sep 05 00:47:58 2007 +0000 @@ -112,11 +112,10 @@ jabber_prpl_send_raw, /* send_raw */ jabber_roomlist_room_serialize, /* roomlist_room_serialize */ - /* padding */ NULL, NULL, - NULL, - NULL + jabber_media_initiate, /* initiate_media */ + sizeof(PurplePluginProtocolInfo) }; static gboolean load_plugin(PurplePlugin *plugin)
--- a/libpurple/protocols/jabber/presence.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/jabber/presence.c Wed Sep 05 00:47:58 2007 +0000 @@ -183,6 +183,10 @@ xmlnode_set_namespace(c, "http://jabber.org/protocol/caps"); xmlnode_set_attrib(c, "node", CAPS0115_NODE); xmlnode_set_attrib(c, "ver", VERSION); +#ifdef USE_FARSIGHT + /* Make sure this is 'voice-v1', or you won't be able to talk to Google Talk */ + xmlnode_set_attrib(c, "ext", "voice-v1"); +#endif return presence; }
--- a/libpurple/protocols/msn/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/msn/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -87,4 +87,5 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ $(GLIB_CFLAGS) \ - $(DEBUG_CFLAGS) + $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS)
--- a/libpurple/protocols/msn/msn.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/msn/msn.c Wed Sep 05 00:47:58 2007 +0000 @@ -2148,7 +2148,7 @@ NULL, #endif NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static PurplePluginInfo info =
--- a/libpurple/protocols/myspace/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/myspace/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -38,4 +38,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/libpurple \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS)
--- a/libpurple/protocols/myspace/myspace.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.c Wed Sep 05 00:47:58 2007 +0000 @@ -2813,7 +2813,7 @@ NULL, /* _purple_reserved2 */ #endif NULL, /* _purple_reserved3 */ - NULL /* _purple_reserved4 */ + sizeof(PurplePluginProtocolInfo) };
--- a/libpurple/protocols/novell/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/novell/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -54,4 +54,5 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GLIB_CFLAGS)
--- a/libpurple/protocols/novell/novell.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/novell/novell.c Wed Sep 05 00:47:58 2007 +0000 @@ -3499,7 +3499,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static PurplePluginInfo info = {
--- a/libpurple/protocols/null/nullprpl.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/null/nullprpl.c Wed Sep 05 00:47:58 2007 +0000 @@ -1125,7 +1125,7 @@ NULL, /* padding... */ NULL, NULL, - NULL, + sizeof(PurpleProtocolPluginInfo) }; static void nullprpl_init(PurplePlugin *plugin)
--- a/libpurple/protocols/oscar/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/oscar/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -76,4 +76,5 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS)
--- a/libpurple/protocols/oscar/libaim.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/oscar/libaim.c Wed Sep 05 00:47:58 2007 +0000 @@ -97,7 +97,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static PurplePluginInfo info =
--- a/libpurple/protocols/oscar/libicq.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/oscar/libicq.c Wed Sep 05 00:47:58 2007 +0000 @@ -97,7 +97,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static PurplePluginInfo info =
--- a/libpurple/protocols/qq/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/qq/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -94,4 +94,5 @@ -I$(top_builddir)/libpurple \ -DQQ_BUDDY_ICON_DIR=\"$(datadir)/pixmaps/purple/buddy_icons/qq\" \ $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GLIB_CFLAGS)
--- a/libpurple/protocols/qq/qq.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/qq/qq.c Wed Sep 05 00:47:58 2007 +0000 @@ -741,7 +741,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) };
--- a/libpurple/protocols/sametime/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/sametime/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -32,7 +32,7 @@ AM_CFLAGS = \ - $(GLIB_CFLAGS) $(MEANWHILE_CFLAGS) \ + $(GLIB_CFLAGS) $(MEANWHILE_CFLAGS) $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS) \ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple
--- a/libpurple/protocols/sametime/sametime.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/sametime/sametime.c Wed Sep 05 00:47:58 2007 +0000 @@ -5132,7 +5132,8 @@ .new_xfer = mw_prpl_new_xfer, .offline_message = NULL, .whiteboard_prpl_ops = NULL, - .send_raw = NULL + .send_raw = NULL, + .struct_size = sizeof(PurplePluginProtocolInfo) };
--- a/libpurple/protocols/silc/silc.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/silc/silc.c Wed Sep 05 00:47:58 2007 +0000 @@ -1892,7 +1892,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurpleProtocolPluginInfo) }; static void
--- a/libpurple/protocols/silc10/silc.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/silc10/silc.c Wed Sep 05 00:47:58 2007 +0000 @@ -1835,7 +1835,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurpleProtocolPluginInfo) }; static void
--- a/libpurple/protocols/simple/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/simple/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -33,4 +33,5 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS)
--- a/libpurple/protocols/simple/simple.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/simple/simple.c Wed Sep 05 00:47:58 2007 +0000 @@ -1808,7 +1808,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) };
--- a/libpurple/protocols/yahoo/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/yahoo/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -53,4 +53,5 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS)
--- a/libpurple/protocols/yahoo/yahoo.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Wed Sep 05 00:47:58 2007 +0000 @@ -4339,7 +4339,7 @@ /* padding */ NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static PurplePluginInfo info =
--- a/libpurple/protocols/zephyr/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/zephyr/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -106,5 +106,6 @@ -I$(top_srcdir)/libpurple/protocols \ -DCONFDIR=\"$(confdir)\" \ $(GLIB_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(KRB4_CFLAGS) \ $(DEBUG_CFLAGS)
--- a/libpurple/protocols/zephyr/zephyr.c Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/protocols/zephyr/zephyr.c Wed Sep 05 00:47:58 2007 +0000 @@ -2926,7 +2926,7 @@ NULL, NULL, NULL, - NULL + sizeof(PurplePluginProtocolInfo) }; static PurplePluginInfo info = {
--- a/libpurple/prpl.h Tue Aug 28 01:02:01 2007 +0000 +++ b/libpurple/prpl.h Wed Sep 05 00:47:58 2007 +0000 @@ -63,6 +63,7 @@ #include "conversation.h" #include "ft.h" #include "imgstore.h" +#include "media.h" #include "notify.h" #include "proxy.h" #include "plugin.h" @@ -350,10 +351,18 @@ /* Attention API for sending & receiving zaps/nudges/buzzes etc. */ gboolean (*send_attention)(PurpleConnection *gc, const char *username, guint type); GList *(*attention_types)(PurpleAccount *acct); +#ifdef USE_FARSIGHT + PurpleMedia *(*initiate_media)(PurpleConnection *conn, const char *who, PurpleMediaStreamType type); +#else + void (*initiate_media)(void) +#endif + /* Make sure you do not try to dereference anything past struct_size! */ + int struct_size; +}; - void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); -}; +#define PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, member) \ + ((G_STRUCT_OFFSET(PurpleProtocolPluginInfo, member) < prpl->struct_size) && \ + prpl->member != NULL) #define PURPLE_IS_PROTOCOL_PLUGIN(plugin) \ ((plugin)->info->type == PURPLE_PLUGIN_PROTOCOL)
--- a/pidgin/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/pidgin/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -186,6 +186,7 @@ $(STARTUP_NOTIFICATION_LIBS) \ $(LIBXML_LIBS) \ $(GTK_LIBS) \ + $(FARSIGHT_LIBS) \ $(top_builddir)/libpurple/libpurple.la if USE_INTERNAL_LIBGADU @@ -208,5 +209,6 @@ $(GTKSPELL_CFLAGS) \ $(STARTUP_NOTIFICATION_CFLAGS) \ $(LIBXML_CFLAGS) \ - $(INTGG_CFLAGS) + $(INTGG_CFLAGS) \ + $(FARSIGHT_CFLAGS) endif # ENABLE_GTK
--- a/pidgin/plugins/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/pidgin/plugins/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -119,6 +119,7 @@ -I$(top_srcdir)/libpurple \ -I$(top_srcdir)/pidgin \ $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GTK_CFLAGS) \ $(PLUGIN_CFLAGS)
--- a/pidgin/plugins/gestures/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/pidgin/plugins/gestures/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -23,4 +23,5 @@ -I$(top_builddir)/libpurple \ -I$(top_srcdir)/pidgin \ $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GTK_CFLAGS)
--- a/pidgin/plugins/gevolution/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/pidgin/plugins/gevolution/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -24,6 +24,7 @@ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ -I$(top_srcdir)/pidgin \ - $(EVOLUTION_ADDRESSBOOK_CFLAGS) \ + $(EVOLUTION_ADDRESSBOOK_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(DEBUG_CFLAGS) \ $(GTK_CFLAGS)
--- a/pidgin/plugins/musicmessaging/Makefile.am Tue Aug 28 01:02:01 2007 +0000 +++ b/pidgin/plugins/musicmessaging/Makefile.am Wed Sep 05 00:47:58 2007 +0000 @@ -39,6 +39,7 @@ -I$(top_builddir)/libpurple \ -I$(top_srcdir)/libpurple \ -I$(top_srcdir)/pidgin \ - $(DEBUG_CFLAGS) \ + $(DEBUG_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ $(GTK_CFLAGS) \ $(DBUS_CFLAGS)