pidgin.vv.yahoo.voice: 5f6b18d2: Partially implement initiating a Yahoo v...

maiku at pidgin.im maiku at pidgin.im
Wed Sep 23 06:05:37 EDT 2009


-----------------------------------------------------------------
Revision: 5f6b18d25c3f658381c3384efe089784c1f23fb4
Ancestor: 08e4a831499420be69e36def51e8b42d9ddc3cb8
Author: maiku at pidgin.im
Date: 2009-09-06T08:41:57
Branch: im.pidgin.pidgin.vv.yahoo.voice
URL: http://d.pidgin.im/viewmtn/revision/info/5f6b18d25c3f658381c3384efe089784c1f23fb4

Modified files:
        libpurple/protocols/yahoo/libyahoo.c
        libpurple/protocols/yahoo/libymsg.c
        libpurple/protocols/yahoo/libymsg.h
        libpurple/protocols/yahoo/yahoo_sip.c
        libpurple/protocols/yahoo/yahoo_sip.h

ChangeLog: 

Partially implement initiating a Yahoo voice call. At least with Yahoo
Messenger 10 beta, it shows Pidgin as being "anonymous" when Pidgin initates.

-------------- next part --------------
============================================================
--- libpurple/protocols/yahoo/libyahoo.c	e23838eefed8d9932940f9d15fe9506e9cc6b4b1
+++ libpurple/protocols/yahoo/libyahoo.c	274b4f8e0ca69bb598abfdd2809d556c8d29d1db
@@ -263,8 +263,8 @@ static PurplePluginProtocolInfo prpl_inf
 
 	sizeof(PurplePluginProtocolInfo),       /* struct_size */
 	yahoo_get_account_text_table,    /* get_account_text_table */
-	NULL, /* initiate_media */
-	NULL  /* can_do_media */
+	yahoo_initiate_media,            /* initiate_media */
+	yahoo_get_media_caps,            /* can_do_media */
 };
 
 static PurplePluginInfo info =
============================================================
--- libpurple/protocols/yahoo/libymsg.c	6951ffbe2b6cb25524db29fa13e5a8955d5d161c
+++ libpurple/protocols/yahoo/libymsg.c	ba9987024423e47ec2dfb7a6477ca3a38db789de
@@ -4914,6 +4914,24 @@ void yahoo_rename_group(PurpleConnection
 	g_free(gpo);
 }
 
+gboolean
+yahoo_initiate_media(PurpleAccount *account, const char *who,
+		      PurpleMediaSessionType type)
+{
+	return yahoo_sip_initiate_media(account, who, type);
+}
+
+PurpleMediaCaps
+yahoo_get_media_caps(PurpleAccount *account, const char *who)
+{
+	/* Needs to be none for webmessenger clients.. however you check */
+#ifdef USE_SOFIASIP
+	return PURPLE_MEDIA_CAPS_AUDIO;
+#else
+	return PURPLE_MEDIA_CAPS_NONE;
+#endif
+}
+
 /********************************* Commands **********************************/
 
 PurpleCmdRet
============================================================
--- libpurple/protocols/yahoo/libymsg.h	3984d233277f011c6c54dce56483d75370e7b3b7
+++ libpurple/protocols/yahoo/libymsg.h	fd36cb584fcb0bfbdd29565eb7b61b320e278940
@@ -383,4 +383,8 @@ void yahoo_send_p2p_pkt(PurpleConnection
 /* send p2p pkt containing our encoded ip, asking peer to connect to us */
 void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13);
 
+gboolean yahoo_initiate_media(PurpleAccount *account, const char *who,
+		      PurpleMediaSessionType type);
+PurpleMediaCaps yahoo_get_media_caps(PurpleAccount *account, const char *who);
+
 #endif /* _LIBYMSG_H_ */
============================================================
--- libpurple/protocols/yahoo/yahoo_sip.c	3de7305bc4d88fcf01927217ae4d27e38313195c
+++ libpurple/protocols/yahoo/yahoo_sip.c	f567c3965163f611f97b5594de7116bb6d1f889d
@@ -50,6 +50,7 @@ struct _YahooSip {
 	guint yahooref_timeout_handle;
 	gchar *to_str;
 	gboolean shutdown;
+	gchar *sip_ip;
 	gchar *stun_ip;
 	PurpleDnsQueryData *sip_host_query;
 	PurpleDnsQueryData *stun_host_query;
@@ -324,7 +325,11 @@ yahoo_sip_ready(PurpleMedia *media, nua_
 			(purple_media_is_initiator(media, NULL, NULL) ||
 			purple_media_accepted(media, NULL, NULL))) {
 		if (purple_media_is_initiator(media, NULL, NULL)) {
-			/* send initiate */
+			nua_invite(nh,
+					NUTAG_MEDIA_ENABLE(0),
+					SIPTAG_HEADER_STR("Y-Need-Token: Yes"),
+					SIPTAG_HEADER_STR("Y-Token-Num: 2"),
+					TAG_END());
 		} else {
 			const gchar *name = purple_url_decode(
 					nua_handle_remote(nh)->a_display);
@@ -359,14 +364,13 @@ yahoo_sip_candidates_prepared_cb(PurpleM
 yahoo_sip_candidates_prepared_cb(PurpleMedia *media,
 		gchar *sid, gchar *name, nua_handle_t *nh)
 {
-	if (sid == NULL && name == NULL)
-		yahoo_sip_ready(media, nh);
+	yahoo_sip_ready(media, nh);
 }
 
 static void
 yahoo_sip_codecs_changed_cb(PurpleMedia *media, gchar *sid, nua_handle_t *nh)
 {
-		
+	yahoo_sip_ready(media, nh);
 }
 
 static void
@@ -572,6 +576,56 @@ event_callback(nua_event_t event, int st
 			purple_debug_error("yahoo", "Error parsing SDP.\n");
 			return;
 		}
+	} else if (event == nua_r_invite && status == 401) {
+		PurpleAccount *account = magic;
+		PurpleConnection *pc = purple_account_get_connection(account);
+		YahooData *yd = purple_connection_get_protocol_data(pc);
+		YahooSip *ysip = yd->ysip;
+		const gchar *name = purple_url_decode(
+				nua_handle_remote(nh)->a_display);
+		const gchar *encoded_to = purple_url_encode(name);
+		const sip_www_authenticate_t *wa = sip->sip_www_authenticate;
+		const gchar *method = NULL, *realm = NULL;	
+		gchar *sdp_str, *to_str = NULL;
+
+		if (!wa) {
+			purple_debug_error("yahoo", "sip www authenticate "
+					"structure is NULL\n");
+			return;
+		}
+
+		realm = msg_params_find(wa->au_params, "realm=");
+		method = wa->au_scheme;
+		if (!realm || !method) {
+			purple_debug_error("yahoo", "sip: unable to retrieve "
+					"authentication parameters\n");
+			return;
+		}
+
+		to_str = g_strdup_printf("%s <sip:%s@%s:443;transport=tcp>",
+				encoded_to, encoded_to, ysip->sip_ip);
+		nua_handle_destroy(nh);
+		nh = nua_handle(ysip->nua, NULL,
+			SIPTAG_TO_STR(to_str),
+			SIPTAG_FROM_STR(ysip->to_str),
+			SIPTAG_CONTACT_STR(ysip->to_str),
+			TAG_END());
+		g_free(to_str);
+
+		purple_media_set_prpl_data(hmagic, nh);
+		nua_handle_bind(nh, hmagic);
+
+		sdp_str = yahoo_sdp_generate_media(hmagic, name);
+		if (!sdp_str) {
+			purple_debug_error("yahoo", "Error generating"
+					"SDP media string\n");
+			return;
+		}
+		nua_invite(nh,
+			NUTAG_MEDIA_ENABLE(1),
+			SOATAG_USER_SDP_STR(sdp_str),
+			TAG_END());
+		g_free(sdp_str);
 	} else if ((event == nua_i_bye || event == nua_i_cancel)
 			&& status >= 200) {
 		PurpleMedia *media = hmagic;
@@ -615,6 +669,7 @@ yahoo_start_sip(GSList *hosts, gpointer 
 		inet_ntop(addr->sa_family, &((struct sockaddr_in *) addr)->sin_addr,
 			sip_host, sizeof(sip_host));
 	}
+	ysip->sip_ip = g_strdup(sip_host);
 
 	purple_debug_info("yahoo", "Starting Sofia-SIP\n");
 
@@ -751,8 +806,74 @@ yahoo_sip_uninit(PurpleAccount *account)
 
 	nua_destroy(ysip->nua);
 	g_free(ysip->to_str);
+	g_free(ysip->sip_ip);
 	g_free(ysip->stun_ip);
 	g_free(ysip);
 	yd->ysip = NULL;
 #endif /* defined(USE_VV) && defined(USE_SOFIASIP) */
 }
+
+gboolean
+yahoo_sip_initiate_media(PurpleAccount *account,
+		const char *who, PurpleMediaSessionType type)
+{
+#if defined(USE_VV) && defined(USE_SOFIASIP)
+	PurpleConnection *pc = purple_account_get_connection(account);
+	YahooData *yd = purple_connection_get_protocol_data(pc);
+	YahooSip *ysip = yd->ysip;
+	PurpleMedia *media;
+	const gchar *encoded_to = purple_url_encode(who);
+	gchar *to_str;
+	nua_handle_t *nh;
+	guint num_params;
+	GParameter *params;
+
+	media = purple_media_manager_create_media(
+			purple_media_manager_get(),
+			account, "fsrtpconference",
+			who, TRUE);
+
+	if (!media) {
+		purple_debug_error("yahoo",
+				"Couldn't create media session\n");
+		return FALSE;
+	}
+
+	to_str = g_strdup_printf("%s <sip:%s@%s:443;transport=tcp>",
+			encoded_to, encoded_to, ysip->sip_ip);
+	nh = nua_handle(ysip->nua, NULL,
+			SIPTAG_TO_STR(to_str),
+			SIPTAG_FROM_STR(ysip->to_str),
+			SIPTAG_CONTACT_STR(ysip->to_str),
+			TAG_END());
+	g_free(to_str);
+
+	purple_media_set_prpl_data(media, nh);
+	nua_handle_bind(nh, media);
+
+	/* connect callbacks */
+	g_signal_connect(G_OBJECT(media), "candidates-prepared",
+			G_CALLBACK(yahoo_sip_candidates_prepared_cb), nh);
+	g_signal_connect(G_OBJECT(media), "codecs-changed",
+			G_CALLBACK(yahoo_sip_codecs_changed_cb), nh);
+	g_signal_connect(G_OBJECT(media), "state-changed",
+			G_CALLBACK(yahoo_sip_state_changed_cb), nh);
+	g_signal_connect(G_OBJECT(media), "stream-info",
+			G_CALLBACK(yahoo_sip_stream_info_cb), nh);
+
+	params = yahoo_get_media_params(ysip, &num_params);
+	if (type & PURPLE_MEDIA_AUDIO)
+		purple_media_add_stream(media, "yahoo-voice", who,
+				PURPLE_MEDIA_AUDIO, TRUE, "nice",
+				num_params, params);
+	if (type & PURPLE_MEDIA_VIDEO)
+		purple_media_add_stream(media, "yahoo-video", who,
+				PURPLE_MEDIA_VIDEO, TRUE, "nice",
+				num_params, params);
+	g_free(params);
+
+	return TRUE;
+#else
+	return FALSE;
+#endif /* defined(USE_VV) && defined(USE_SOFIASIP) */
+}
============================================================
--- libpurple/protocols/yahoo/yahoo_sip.h	8e8e3abad02fa3680dbe8f40df75539ee7ce2460
+++ libpurple/protocols/yahoo/yahoo_sip.h	3aeb212180ed6e0d279a4153b4f2ca228d63602d
@@ -31,5 +31,7 @@ void yahoo_sip_uninit(PurpleAccount *acc
 
 void yahoo_sip_init(PurpleAccount *account);
 void yahoo_sip_uninit(PurpleAccount *account);
+gboolean yahoo_sip_initiate_media(PurpleAccount *account,
+		const char *who, PurpleMediaSessionType type);
 
 #endif  /* _YAHOO_SIP_H_ */


More information about the Commits mailing list