# HG changeset patch # User Sulabh Mahajan # Date 1213737449 0 # Node ID d11d1ac96a0de4aabcb966e2818e387e3f7b5a3c # Parent f1de4ccc433efa93b1e038cac30bed2d39799d0d Send IMs and Typing notifications through p2p, Redesign p2p user_data structure, Close p2p connections at sign out. diff -r f1de4ccc433e -r d11d1ac96a0d libpurple/protocols/yahoo/yahoo.c --- a/libpurple/protocols/yahoo/yahoo.c Sat Jun 14 08:53:43 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Tue Jun 17 21:17:29 2008 +0000 @@ -2214,6 +2214,22 @@ g_free(decoded_group); } +/*destroy p2p_data associated with a peer and close p2p connection*/ +static void yahoo_p2p_disconnect_destroy_data(gpointer data) +{ + struct yahoo_p2p_data *user_data; + struct yahoo_data *yd; + if(!(user_data = data)) + return ; + yd = user_data->gc->proto_data; + + purple_input_remove(user_data->input_event); + close(user_data->source); + g_free(user_data->host_ip); + g_free(user_data->host_username); + g_free(user_data); +} + /*write pkt to the source*/ static void yahoo_p2p_write_pkt(gint source, struct yahoo_packet *pkt) { @@ -2295,9 +2311,11 @@ struct yahoo_packet *pkt; guchar *start = NULL; struct yahoo_p2p_data *user_data; + struct yahoo_data *yd; if(!(user_data = data)) return ; + yd = user_data->gc->proto_data; len = read(source, buf, sizeof(buf)); @@ -2307,12 +2325,8 @@ else if (len <= 0) { purple_debug_warning("yahoo","p2p: Error in connection, or host disconnected\n"); - purple_input_remove(user_data->input_event); - close(source); - /*free user data*/ - g_free(user_data->host_ip); - g_free(user_data->host_username); - g_free(user_data); + /*remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data*/ + g_hash_table_remove(yd->peers,user_data->host_username); return; } @@ -2382,6 +2396,7 @@ /*Add an Input Read event to the file descriptor*/ user_data->input_event = purple_input_add(source, PURPLE_INPUT_READ, yahoo_p2p_read_pkt_cb, data); + user_data->source = source; account = purple_connection_get_account(user_data->gc); @@ -2400,14 +2415,16 @@ static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = gc->proto_data; GSList *l = pkt->hash; char *who = NULL; char *base64 = NULL; guchar *decoded; gsize len; gint val_13 = 0; + gint val_11; PurpleAccount *account; - struct yahoo_p2p_data *user_data = g_new0(struct yahoo_p2p_data, 1); /*yet to decide when to free this up*/ + struct yahoo_p2p_data *user_data = g_new0(struct yahoo_p2p_data, 1); while (l) { struct yahoo_pair *pair = l->data; @@ -2433,7 +2450,10 @@ val_13 = strtol(pair->value, NULL, 10); /*Value always 0*/ user_data->val_13 = val_13; break; - + case 11: + val_11 = strtol(pair->value, NULL, 10); /*sent with IMs and notifications over p2p*/ + user_data->val_11 = val_11; + break; /* TODO: figure these out yahoo: Key: 61 Value: 0 @@ -2441,7 +2461,6 @@ yahoo: Key: 13 Value: 0 packet count ?? yahoo: Key: 49 Value: PEERTOPEER yahoo: Key: 140 Value: 1 - yahoo: Key: 11 Value: -1786225828 */ } @@ -2479,6 +2498,8 @@ user_data->session_id = pkt->id; user_data->gc = gc; + g_hash_table_insert(yd->peers, g_strdup(who), user_data); + /*connect to host*/ if((purple_proxy_connect(NULL, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, user_data))==NULL) purple_debug_info("yahoo","p2p: Connection to %s failed\n", host_ip); @@ -3199,6 +3220,7 @@ yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); yd->xfer_peer_idstring_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); + yd->peers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_p2p_disconnect_destroy_data); yd->confs = NULL; yd->conf_id = 2; @@ -3266,6 +3288,7 @@ g_hash_table_destroy(yd->friends); g_hash_table_destroy(yd->imvironments); g_hash_table_destroy(yd->xfer_peer_idstring_map); + g_hash_table_destroy(yd->peers); g_free(yd->chat_name); g_free(yd->cookie_y); @@ -3824,6 +3847,7 @@ PurpleWhiteboard *wb; int ret = 1; YahooFriend *f = NULL; + struct yahoo_p2p_data *user_data; msg2 = yahoo_string_encode(gc, msg, &utf8); @@ -3868,8 +3892,15 @@ yahoo_packet_hash_str(pkt, 206, "2"); /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */ - if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) - yahoo_packet_send(pkt, yd); + if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) { + /*if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p*/ + if( (user_data = g_hash_table_lookup(yd->peers, who)) ) { + yahoo_packet_hash_int(pkt, 11, user_data->val_11); + yahoo_p2p_write_pkt(user_data->source, pkt); + } + else + yahoo_packet_send(pkt, yd); + } else ret = -E2BIG; @@ -3884,12 +3915,24 @@ static unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) { struct yahoo_data *yd = gc->proto_data; + struct yahoo_p2p_data *user_data; + struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); - yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), + + /*check to see if p2p link exists, send through it*/ + if( (user_data = g_hash_table_lookup(yd->peers, who)) ) { + yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc), + 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", + 5, who, 11, user_data->val_11, 1002, "1"); /*To-do: key 15 to be sent in case of p2p*/ + yahoo_p2p_write_pkt(user_data->source, pkt); + yahoo_packet_free(pkt); + } + else { /*send through yahoo server*/ + yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", 5, who, 1002, "1"); - - yahoo_packet_send_and_free(pkt, yd); + yahoo_packet_send_and_free(pkt, yd); + } return 0; } diff -r f1de4ccc433e -r d11d1ac96a0d libpurple/protocols/yahoo/yahoo.h --- a/libpurple/protocols/yahoo/yahoo.h Sat Jun 14 08:53:43 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.h Tue Jun 17 21:17:29 2008 +0000 @@ -121,6 +121,8 @@ char *host_username; int val_13; guint input_event; + gint source; + int val_11; }; struct _YchtConn; @@ -186,6 +188,7 @@ * the server expects us to keep track of the group for which it is sending us contact names. */ char *current_list15_grp; + GHashTable *peers; /*information about p2p data*/ }; #define YAHOO_MAX_STATUS_MESSAGE_LENGTH (255)