# HG changeset patch # User Stu Tomlinson # Date 1102795318 0 # Node ID 2e01c503aa4fb45aace7ea70081a4ff7f098ace1 # Parent 5976491e07a71302eb05b63d26470c72769a59c3 [gaim-migrate @ 11556] Patch 1078151 from Felipe Contreras to fix some more MSN bugs: "User Dislpay messages, and other less used, did not set an slpcall, so the callback that should not be called, was called (in some very special cases)." ... "Here it goes the real real one, as far as I can tell. Cleaning + organizing + documentation + hard bug fix = big patch." -- Felipe Contreras I also fixed drag-and-drop to conversation window file transfers (which I had broken when I fixed some other dnd thing), made the debug output of the autoreconnect plugin more useful, and stopped the message notification plugin notifying you for messages sent by ignored users. committer: Tailor Script diff -r 5976491e07a7 -r 2e01c503aa4f COPYRIGHT --- a/COPYRIGHT Sat Dec 11 00:06:06 2004 +0000 +++ b/COPYRIGHT Sat Dec 11 20:01:58 2004 +0000 @@ -68,6 +68,7 @@ Ignacy Gawedzki Michael Golden Ryan C. Gordon +Miah Gregory Christian Hammond Andy Harrison Andrew Hart (arhart) @@ -77,6 +78,7 @@ Fernando Herrera Casey Ho Iain Holmes +Nigel Horne Karsten Huneycutt Rian Hunter Henry Jen diff -r 5976491e07a7 -r 2e01c503aa4f plugins/autorecon.c --- a/plugins/autorecon.c Sat Dec 11 00:06:06 2004 +0000 +++ b/plugins/autorecon.c Sat Dec 11 20:01:58 2004 +0000 @@ -108,14 +108,14 @@ && gaim_prefs_get_bool(OPT_HIDE_CONNECTED)) { /* this is a connected error, and we're hiding those */ gaim_debug(GAIM_DEBUG_INFO, "autorecon", - "hid disconnect error message\n"); + "hid disconnect error message (%s)\n", text); return; } else if(gc->state == GAIM_CONNECTING && gaim_prefs_get_bool(OPT_HIDE_CONNECTING)) { /* this is a connecting error, and we're hiding those */ gaim_debug(GAIM_DEBUG_INFO, "autorecon", - "hid error message while connecting\n"); + "hid error message while connecting (%s)\n", text); return; } diff -r 5976491e07a7 -r 2e01c503aa4f plugins/notify.c --- a/plugins/notify.c Sat Dec 11 00:06:06 2004 +0000 +++ b/plugins/notify.c Sat Dec 11 20:01:58 2004 +0000 @@ -224,6 +224,9 @@ chat_recv_im(GaimAccount *account, char *sender, char *message, GaimConversation *conv, int *flags) { + if (gaim_conv_chat_is_user_ignored(GAIM_CONV_CHAT(conv), sender)) + return FALSE; + notify(conv, TRUE); return FALSE; diff -r 5976491e07a7 -r 2e01c503aa4f src/gtkimhtml.c --- a/src/gtkimhtml.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/gtkimhtml.c Sat Dec 11 20:01:58 2004 +0000 @@ -1350,6 +1350,9 @@ /* Ignore blank lines */ } else { /* Special reasons, aka images being put in via other tag, etc. */ + /* ... don't pretend we handled it if we didn't */ + gtk_drag_finish(dc, FALSE, FALSE, t); + return; } } break; diff -r 5976491e07a7 -r 2e01c503aa4f src/gtkimhtml.h --- a/src/gtkimhtml.h Sat Dec 11 00:06:06 2004 +0000 +++ b/src/gtkimhtml.h Sat Dec 11 20:01:58 2004 +0000 @@ -200,11 +200,11 @@ }; #define GTK_IMHTML_DND_TARGETS \ + { "text/uri-list", 0, GTK_IMHTML_DRAG_URL }, \ { "_NETSCAPE_URL", 0, GTK_IMHTML_DRAG_URL }, \ { "text/html", 0, GTK_IMHTML_DRAG_HTML }, \ { "x-url/ftp", 0, GTK_IMHTML_DRAG_URL }, \ { "x-url/http", 0, GTK_IMHTML_DRAG_URL }, \ - { "text/uri-list", 0, GTK_IMHTML_DRAG_URL }, \ { "UTF8_STRING", 0, GTK_IMHTML_DRAG_UTF8_STRING }, \ { "COMPOUND_TEXT", 0, GTK_IMHTML_DRAG_COMPOUND_TEXT }, \ { "STRING", 0, GTK_IMHTML_DRAG_STRING }, \ diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/cmdproc.c --- a/src/protocols/msn/cmdproc.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/cmdproc.c Sat Dec 11 20:01:58 2004 +0000 @@ -222,7 +222,7 @@ void msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { - MsnMsgCb cb; + MsnMsgTypeCb cb; if (msn_message_get_content_type(msg) == NULL) { diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/msg.c --- a/src/protocols/msn/msg.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/msg.c Sat Dec 11 20:01:58 2004 +0000 @@ -32,6 +32,10 @@ msg = g_new0(MsnMessage, 1); msg->type = type; +#ifdef MSN_DEBUG_MSG + gaim_debug_info("msn", "message new (%p)(%d)\n", msg, type); +#endif + msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); @@ -40,6 +44,78 @@ return msg; } +void +msn_message_destroy(MsnMessage *msg) +{ + g_return_if_fail(msg != NULL); + + if (msg->ref_count > 0) + { + msn_message_unref(msg); + + return; + } + +#ifdef MSN_DEBUG_MSG + gaim_debug_info("msn", "message destroy (%p)\n", msg); +#endif + + if (msg->remote_user != NULL) + g_free(msg->remote_user); + + if (msg->body != NULL) + g_free(msg->body); + + if (msg->content_type != NULL) + g_free(msg->content_type); + + if (msg->charset != NULL) + g_free(msg->charset); + + g_hash_table_destroy(msg->attr_table); + g_list_free(msg->attr_list); + + g_free(msg); +} + +MsnMessage * +msn_message_ref(MsnMessage *msg) +{ + g_return_val_if_fail(msg != NULL, NULL); + + msg->ref_count++; + +#ifdef MSN_DEBUG_MSG + gaim_debug_info("msn", "message ref (%p)[%d]\n", msg, msg->ref_count); +#endif + + return msg; +} + +MsnMessage * +msn_message_unref(MsnMessage *msg) +{ + g_return_val_if_fail(msg != NULL, NULL); + + if (msg->ref_count <= 0) + return NULL; + + msg->ref_count--; + +#ifdef MSN_DEBUG_MSG + gaim_debug_info("msn", "message unref (%p)[%d]\n", msg, msg->ref_count); +#endif + + if (msg->ref_count == 0) + { + msn_message_destroy(msg); + + return NULL; + } + + return msg; +} + MsnMessage * msn_message_new_plain(const char *message) { @@ -241,66 +317,6 @@ return msg; } -void -msn_message_destroy(MsnMessage *msg) -{ - g_return_if_fail(msg != NULL); - - if (msg->ref_count > 0) - { - msn_message_unref(msg); - - return; - } - - if (msg->remote_user != NULL) - g_free(msg->remote_user); - - if (msg->body != NULL) - g_free(msg->body); - - if (msg->content_type != NULL) - g_free(msg->content_type); - - if (msg->charset != NULL) - g_free(msg->charset); - - g_hash_table_destroy(msg->attr_table); - g_list_free(msg->attr_list); - - g_free(msg); -} - -MsnMessage * -msn_message_ref(MsnMessage *msg) -{ - g_return_val_if_fail(msg != NULL, NULL); - - msg->ref_count++; - - return msg; -} - -MsnMessage * -msn_message_unref(MsnMessage *msg) -{ - g_return_val_if_fail(msg != NULL, NULL); - - if (msg->ref_count <= 0) - return NULL; - - msg->ref_count--; - - if (msg->ref_count == 0) - { - msn_message_destroy(msg); - - return NULL; - } - - return msg; -} - char * msn_message_gen_slp_body(MsnMessage *msg, size_t *ret_size) { @@ -691,7 +707,7 @@ g_string_append_printf(str, "SUB ID: %u\r\n", msg->msnslp_header.ack_sub_id); g_string_append_printf(str, "ACK Size: %" G_GUINT64_FORMAT "\r\n", msg->msnslp_header.ack_size); -#ifdef DEBUG_SLP_VERBOSE +#ifdef MSN_DEBUG_SLP_VERBOSE if (body != NULL) { if (text_body) diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/msg.h --- a/src/protocols/msn/msg.h Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/msg.h Sat Dec 11 20:01:58 2004 +0000 @@ -32,7 +32,7 @@ #include "command.h" #include "transaction.h" -typedef void (*MsnCb)(void *data); +typedef void (*MsnMsgCb)(MsnMessage *, void *data); /* typedef enum @@ -54,6 +54,16 @@ } MsnMsgType; +typedef enum +{ + MSN_MSG_ERROR_NONE, /**< No error. */ + MSN_MSG_ERROR_TIMEOUT, /**< The message timedout. */ + MSN_MSG_ERROR_NAK, /**< The message could not be sent. */ + MSN_MSG_ERROR_SB, /**< The error comes from the switchboard. */ + MSN_MSG_ERROR_UNKNOWN /**< An unknown error occured. */ + +} MsnMsgErrorType; + typedef struct { guint32 session_id; @@ -102,8 +112,13 @@ MsnCommand *cmd; MsnTransaction *trans; - MsnCb ack_cb; - void *ack_data; + MsnMsgCb ack_cb; /**< The callback to call when we receive an ACK of this + message. */ + MsnMsgCb nak_cb; /**< The callback to call when we receive a NAK of this + message. */ + void *ack_data; /**< The data used by callbacks. */ + + MsnMsgErrorType error; /**< The error of the message. */ }; /** diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/msn.c --- a/src/protocols/msn/msn.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/msn.c Sat Dec 11 20:01:58 2004 +0000 @@ -757,9 +757,7 @@ session = gc->proto_data; swboard = msn_session_get_swboard(session, who); - - if (!g_queue_is_empty(swboard->im_queue) || - !swboard->user_joined) + if (!g_queue_is_empty(swboard->im_queue) || swboard->empty) { msn_switchboard_queue_msg(swboard, msg); } @@ -767,7 +765,6 @@ { msn_switchboard_send_msg(swboard, msg); } - } else { @@ -824,7 +821,7 @@ if (swboard == NULL) return 0; - if (!swboard->user_joined) + if (swboard->empty) return 0; msg = msn_message_new(MSN_MSG_TYPING); @@ -834,7 +831,16 @@ gaim_account_get_username(account)); msn_message_set_bin_data(msg, "\r\n", 2); - msn_switchboard_send_msg(swboard, msg); + swboard = msn_session_get_swboard(session, who); + + if (!g_queue_is_empty(swboard->im_queue) || swboard->empty) + { + msn_switchboard_queue_msg(swboard, msg); + } + else + { + msn_switchboard_send_msg(swboard, msg); + } msn_message_destroy(msg); @@ -1155,30 +1161,30 @@ if (swboard == NULL) return -EINVAL; - if (swboard->ready) - { - msn_import_html(message, &msgformat, &msgtext); - - if (strlen(msgtext) + strlen(msgformat) + strlen(VERSION) > 1564) - { - g_free(msgformat); - g_free(msgtext); + if (!swboard->ready) + return 0; - return -E2BIG; - } + msn_import_html(message, &msgformat, &msgtext); - msg = msn_message_new_plain(msgtext); - msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat); - msn_switchboard_send_msg(swboard, msg); - msn_message_destroy(msg); - + if (strlen(msgtext) + strlen(msgformat) + strlen(VERSION) > 1564) + { g_free(msgformat); g_free(msgtext); - serv_got_chat_in(gc, id, gaim_account_get_username(account), 0, - message, time(NULL)); + return -E2BIG; } + msg = msn_message_new_plain(msgtext); + msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat); + msn_switchboard_send_msg(swboard, msg); + msn_message_destroy(msg); + + g_free(msgformat); + g_free(msgtext); + + serv_got_chat_in(gc, id, gaim_account_get_username(account), 0, + message, time(NULL)); + return 0; } diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/nexus.c --- a/src/protocols/msn/nexus.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/nexus.c Sat Dec 11 20:01:58 2004 +0000 @@ -132,7 +132,7 @@ (char *)g_hash_table_lookup(nexus->challenge_data, "tpf"), nexus->login_host); - gaim_debug(GAIM_DEBUG_MISC, "msn", "Sending: {%s}\n", request_str); + gaim_debug_misc("msn", "Sending: {%s}\n", request_str); g_free(username); g_free(password); @@ -151,7 +151,7 @@ gaim_ssl_close(gsc); - gaim_debug(GAIM_DEBUG_MISC, "msn", "ssl buffer: {%s}", buffer); + gaim_debug_misc("msn", "ssl buffer: {%s}", buffer); if (strstr(buffer, "HTTP/1.1 302") != NULL) { diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/notification.c --- a/src/protocols/msn/notification.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/notification.c Sat Dec 11 20:01:58 2004 +0000 @@ -810,9 +810,9 @@ if ((fd = gaim_mkstemp(&session->passport_info.file, FALSE)) == NULL) { - gaim_debug(GAIM_DEBUG_ERROR, "msn", - "Error opening temp passport file: %s\n", - strerror(errno)); + gaim_debug_error("msn", + "Error opening temp passport file: %s\n", + strerror(errno)); } else { diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/session.c --- a/src/protocols/msn/session.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/session.c Sat Dec 11 20:01:58 2004 +0000 @@ -25,8 +25,6 @@ #include "session.h" #include "notification.h" -#include "slplink.h" - #include "dialog.h" MsnSession * diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/slp.c --- a/src/protocols/msn/slp.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/slp.c Sat Dec 11 20:01:58 2004 +0000 @@ -205,7 +205,7 @@ "MSNSLP/1.0 200 OK", branch, type, content); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP 200 OK"; slpmsg->text_body = TRUE; #endif @@ -229,7 +229,7 @@ "MSNSLP/1.0 603 Decline", branch, type, content); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP 603 Decline"; slpmsg->text_body = TRUE; #endif @@ -295,19 +295,21 @@ /* DATA PREP */ slpmsg = msn_slpmsg_new(slplink); + slpmsg->slpcall = slpcall; slpmsg->slpsession = slpsession; slpmsg->session_id = slpsession->id; msn_slpmsg_set_body(slpmsg, NULL, 4); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP DATA PREP"; #endif msn_slplink_queue_slpmsg(slplink, slpmsg); /* DATA */ slpmsg = msn_slpmsg_new(slplink); + slpmsg->slpcall = slpcall; slpmsg->slpsession = slpsession; slpmsg->flags = 0x20; -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP DATA"; #endif msn_slpmsg_open_file(slpmsg, file_name); @@ -383,7 +385,7 @@ "\r\n"); g_free(header); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP BYE"; slpmsg->text_body = TRUE; #endif @@ -553,7 +555,7 @@ "application/x-msnmsgr-transreqbody", content); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP INVITE"; slpmsg->text_body = TRUE; #endif diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/slp.h --- a/src/protocols/msn/slp.h Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/slp.h Sat Dec 11 20:01:58 2004 +0000 @@ -24,9 +24,12 @@ #ifndef _MSN_SLP_H_ #define _MSN_SLP_H_ -/* #define DEBUG_SLP 1 */ -/* #define DEBUG_SLP_VERBOSE 1 */ -/* #define DEBUG_SLP_FILES 1 */ +/* #define MSN_DEBUG_MSG 1 */ +/* #define MSN_DEBUG_SLPMSG 1 */ + +/* #define MSN_DEBUG_SLP 1 */ +/* #define MSN_DEBUG_SLP_VERBOSE 1 */ +/* #define MSN_DEBUG_SLP_FILES 1 */ #include "slpcall.h" diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/slpcall.c --- a/src/protocols/msn/slpcall.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/slpcall.c Sat Dec 11 20:01:58 2004 +0000 @@ -68,27 +68,6 @@ } void -msn_slp_call_init(MsnSlpCall *slpcall, MsnSlpCallType type) -{ - slpcall->session_id = rand() % 0xFFFFFF00 + 4; - slpcall->id = rand_guid(); - slpcall->type = type; -} - -void -msn_slp_call_session_init(MsnSlpCall *slpcall) -{ - MsnSlpSession *slpsession; - - slpsession = msn_slp_session_new(slpcall); - - if (slpcall->session_init_cb) - slpcall->session_init_cb(slpsession); - - slpcall->started = TRUE; -} - -void msn_slp_call_destroy(MsnSlpCall *slpcall) { GList *e; @@ -117,14 +96,11 @@ g_return_if_fail(slpmsg != NULL); + gaim_debug_info("msn", "slpcall destroy: tryping slp_msg (%p)\n", + slpmsg); + if (slpmsg->slpcall == slpcall) - { -#if 1 msn_slpmsg_destroy(slpmsg); -#else - slpmsg->wasted = TRUE; -#endif - } } if (slpcall->end_cb != NULL) @@ -134,6 +110,27 @@ } void +msn_slp_call_init(MsnSlpCall *slpcall, MsnSlpCallType type) +{ + slpcall->session_id = rand() % 0xFFFFFF00 + 4; + slpcall->id = rand_guid(); + slpcall->type = type; +} + +void +msn_slp_call_session_init(MsnSlpCall *slpcall) +{ + MsnSlpSession *slpsession; + + slpsession = msn_slp_session_new(slpcall); + + if (slpcall->session_init_cb) + slpcall->session_init_cb(slpsession); + + slpcall->started = TRUE; +} + +void msn_slp_call_invite(MsnSlpCall *slpcall, const char *euf_guid, int app_id, const char *context) { @@ -164,7 +161,7 @@ slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, slpcall->branch, "application/x-msnmsgr-sessionreqbody", content); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP INVITE"; slpmsg->text_body = TRUE; #endif diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/slplink.c --- a/src/protocols/msn/slplink.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/slplink.c Sat Dec 11 20:01:58 2004 +0000 @@ -29,7 +29,7 @@ void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg); -#ifdef DEBUG_SLP_FILES +#ifdef MSN_DEBUG_SLP_FILES static int m_sc = 0; static int m_rc = 0; @@ -84,6 +84,9 @@ g_return_if_fail(slplink != NULL); + if (slplink->swboard != NULL) + slplink->swboard->slplink = NULL; + session = slplink->session; if (slplink->local_user != NULL) @@ -198,29 +201,33 @@ } else { - MsnSwitchBoard *swboard; + if (slplink->swboard == NULL) + { + slplink->swboard = msn_session_get_swboard(slplink->session, + slplink->remote_user); - swboard = msn_session_get_swboard(slplink->session, - slplink->remote_user); + if (slplink->swboard == NULL) + return; - if (swboard == NULL) - return; + /* If swboard is destroyed we will too */ + slplink->swboard->slplink = slplink; + } - if (!g_queue_is_empty(swboard->im_queue) || - !swboard->user_joined) + if (!g_queue_is_empty(slplink->swboard->im_queue) || + slplink->swboard->empty) { - msn_switchboard_queue_msg(swboard, msg); + msn_switchboard_queue_msg(slplink->swboard, msg); } else { - msn_switchboard_send_msg(swboard, msg); + msn_switchboard_send_msg(slplink->swboard, msg); } } } -/* We have received the message receive ack */ +/* We have received the message ack */ static void -msg_ack(void *data) +msg_ack(MsnMessage *msg, void *data) { MsnSlpMessage *slpmsg; long long real_size; @@ -229,6 +236,8 @@ real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; + slpmsg->offset += msg->msnslp_header.length; + if (slpmsg->offset < real_size) { msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); @@ -245,9 +254,22 @@ slpmsg->slpcall->cb(slpmsg->slpcall, NULL, 0); } } + } - msn_slpmsg_destroy(slpmsg); - } + slpmsg->msgs = g_list_remove(slpmsg->msgs, msg); +} + +/* We have received the message nak. */ +static void +msg_nak(MsnMessage *msg, void *data) +{ + MsnSlpMessage *slpmsg; + + slpmsg = data; + + msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); + + slpmsg->msgs = g_list_remove(slpmsg->msgs, msg); } void @@ -257,6 +279,8 @@ long long real_size; size_t len = 0; + /* Maybe we will want to create a new msg for this slpmsg instead of + * reusing the same one all the time. */ msg = slpmsg->msg; real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; @@ -283,17 +307,20 @@ msg->msnslp_header.length = len; } -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP msn_message_show_readable(msg, slpmsg->info, slpmsg->text_body); #endif -#ifdef DEBUG_SLP_FILES +#ifdef MSN_DEBUG_SLP_FILES debug_msg_to_file(msg, TRUE); #endif + slpmsg->msgs = + g_list_append(slpmsg->msgs, msg); msn_slplink_send_msg(slplink, msg); - if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && (slpmsg->slpcall != NULL)) + if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && + (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; @@ -304,11 +331,11 @@ } } - slpmsg->offset += len; + /* slpmsg->offset += len; */ } void -msn_slplink_release_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) +msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { MsnMessage *msg; @@ -350,6 +377,7 @@ msn_message_set_attr(msg, "P2P-Dest", slplink->remote_user); msg->ack_cb = msg_ack; + msg->nak_cb = msg_nak; msg->ack_data = slpmsg; msn_slplink_send_msgpart(slplink, slpmsg); @@ -370,7 +398,7 @@ { slpmsg->id = slplink->slp_seq_id++; - msn_slplink_release_msg(slplink, slpmsg); + msn_slplink_release_slpmsg(slplink, slpmsg); } void @@ -381,7 +409,9 @@ /* Send the queued msgs in the order they came. */ while ((slpmsg = g_queue_pop_tail(slplink->slp_msg_queue)) != NULL) - msn_slplink_release_msg(slplink, slpmsg); + { + msn_slplink_release_slpmsg(slplink, slpmsg); + } } void @@ -398,7 +428,7 @@ slpmsg->ack_sub_id = msg->msnslp_header.ack_id; slpmsg->ack_size = msg->msnslp_header.total_size; -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP ACK"; #endif @@ -413,12 +443,12 @@ slpcall = slpsession->slpcall; slpmsg = msn_slpmsg_new(slpcall->slplink); + slpmsg->slpcall = slpcall; slpmsg->flags = 0x1000030; slpmsg->slpsession = slpsession; -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP FILE"; #endif - slpmsg->slpcall = slpcall; msn_slpmsg_open_file(slpmsg, gaim_xfer_get_local_filename(slpcall->xfer)); msn_slplink_send_slpmsg(slpcall->slplink, slpmsg); @@ -432,11 +462,11 @@ gsize offset; gsize len; -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP msn_slpmsg_show(msg); #endif -#ifdef DEBUG_SLP_FILES +#ifdef MSN_DEBUG_SLP_FILES debug_msg_to_file(msg, FALSE); #endif @@ -501,31 +531,31 @@ slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id); } - if (slpmsg != NULL) + if (slpmsg == NULL) { - if (slpmsg->fp) - { - /* fseek(slpmsg->fp, offset, SEEK_SET); */ - len = fwrite(data, 1, len, slpmsg->fp); - } - else if (slpmsg->size) - { - if ((offset + len) > slpmsg->size) - { - gaim_debug_error("msn", "Oversized slpmsg\n"); - g_return_if_reached(); - } - else - memcpy(slpmsg->buffer + offset, data, len); - } - } - else - { + /* Probably the transfer was canceled */ gaim_debug_error("msn", "Couldn't find slpmsg\n"); - g_return_if_reached(); + return; } - if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && (slpmsg->slpcall != NULL)) + if (slpmsg->fp) + { + /* fseek(slpmsg->fp, offset, SEEK_SET); */ + len = fwrite(data, 1, len, slpmsg->fp); + } + else if (slpmsg->size) + { + if ((offset + len) > slpmsg->size) + { + gaim_debug_error("msn", "Oversized slpmsg\n"); + g_return_if_reached(); + } + else + memcpy(slpmsg->buffer + offset, data, len); + } + + if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && + (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/slplink.h --- a/src/protocols/msn/slplink.h Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/slplink.h Sat Dec 11 20:01:58 2004 +0000 @@ -31,11 +31,14 @@ #include "slpcall.h" #include "slpmsg.h" +#include "switchboard.h" + #include "ft.h" struct _MsnSlpLink { MsnSession *session; + MsnSwitchBoard *swboard; char *local_user; char *remote_user; @@ -54,33 +57,33 @@ MsnSlpLink *msn_slplink_new(MsnSession *session, const char *username); void msn_slplink_destroy(MsnSlpLink *slplink); MsnSlpLink *msn_session_find_slplink(MsnSession *session, - const char *who); + const char *who); MsnSlpLink *msn_session_get_slplink(MsnSession *session, const char *username); MsnSlpSession *msn_slplink_find_slp_session(MsnSlpLink *slplink, - long session_id); + long session_id); MsnSlpCall *msn_slplink_find_slp_call(MsnSlpLink *slplink, - const char *id); + const char *id); MsnSlpCall *msn_slplink_find_slp_call_with_session_id(MsnSlpLink *slplink, long id); void msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg); -void msn_slplink_release_msg(MsnSlpLink *slplink, - MsnSlpMessage *slpmsg); +void msn_slplink_release_slpmsg(MsnSlpLink *slplink, + MsnSlpMessage *slpmsg); void msn_slplink_queue_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg); void msn_slplink_send_slpmsg(MsnSlpLink *slplink, - MsnSlpMessage *slpmsg); + MsnSlpMessage *slpmsg); void msn_slplink_unleash(MsnSlpLink *slplink); void msn_slplink_send_ack(MsnSlpLink *slplink, MsnMessage *msg); void msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg); MsnSlpMessage *msn_slplink_message_find(MsnSlpLink *slplink, long session_id, long id); void msn_slplink_append_slp_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg); void msn_slplink_remove_slp_msg(MsnSlpLink *slplink, - MsnSlpMessage *slpmsg); + MsnSlpMessage *slpmsg); void msn_slplink_request_ft(MsnSlpLink *slplink, GaimXfer *xfer); void msn_slplink_request_object(MsnSlpLink *slplink, - const char *info, - MsnSlpCb cb, - MsnSlpEndCb end_cb, - const MsnObject *obj); + const char *info, + MsnSlpCb cb, + MsnSlpEndCb end_cb, + const MsnObject *obj); MsnSlpCall *msn_slp_process_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg); diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/slpmsg.c --- a/src/protocols/msn/slpmsg.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/slpmsg.c Sat Dec 11 20:01:58 2004 +0000 @@ -33,8 +33,13 @@ msn_slpmsg_new(MsnSlpLink *slplink) { MsnSlpMessage *slpmsg; + slpmsg = g_new0(MsnSlpMessage, 1); +#ifdef MSN_DEBUG_SLPMSG + gaim_debug_info("msn", "slpmsg new (%p)\n", slpmsg); +#endif + slpmsg->slplink = slplink; slplink->slp_msgs = @@ -47,6 +52,13 @@ msn_slpmsg_destroy(MsnSlpMessage *slpmsg) { MsnSlpLink *slplink; + GList *cur; + + g_return_if_fail(slpmsg != NULL); + +#ifdef MSN_DEBUG_SLPMSG + gaim_debug_info("msn", "slpmsg destroy (%p)\n", slpmsg); +#endif slplink = slpmsg->slplink; @@ -56,42 +68,31 @@ if (slpmsg->buffer != NULL) g_free(slpmsg->buffer); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP /* if (slpmsg->info != NULL) g_free(slpmsg->info); */ #endif - if (slpmsg->msg != NULL) + for (cur = slpmsg->msgs; cur != NULL; cur = cur->next) { /* Something is pointing to this slpmsg, so we should remove that * pointer to prevent a crash. */ /* Ex: a user goes offline and after that we receive an ACK */ - gaim_debug_info("msn", "Unlink slpmsg callbacks.\n"); - - slpmsg->msg->ack_cb = NULL; - slpmsg->msg->ack_data = NULL; - -#if 0 - MsnTransaction *trans; - - trans = slpmsg->msg->trans; + MsnMessage *msg = cur->data; - if (trans != NULL) - { - if (trans->callbacks != NULL && trans->has_custom_callbacks) - g_hash_table_destroy(trans->callbacks); - - trans->callbacks = NULL; - trans->data = NULL; - } +#ifdef MSN_DEBUG_SLPMSG + gaim_debug_info("msn", "Unlink slpmsg callbacks.\n"); #endif + + msg->ack_cb = NULL; + msg->nak_cb = NULL; + msg->ack_data = NULL; } - slplink->slp_msgs = - g_list_remove(slplink->slp_msgs, slpmsg); + slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg); g_free(slpmsg); } @@ -119,7 +120,7 @@ slpmsg->size = st.st_size; } -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP const void msn_slpmsg_show(MsnMessage *msg) { @@ -203,6 +204,7 @@ msn_slpmsg_set_body(slpmsg, body, body_len); slpmsg->sip = TRUE; + slpmsg->slpcall = slpcall; g_free(body); diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/slpmsg.h --- a/src/protocols/msn/slpmsg.h Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/slpmsg.h Sat Dec 11 20:01:58 2004 +0000 @@ -34,11 +34,15 @@ #include "slp.h" +/** + * A SLP Message This contains everything that we will need to send a SLP + * Message even if has to be sent in several parts. + */ struct _MsnSlpMessage { MsnSlpSession *slpsession; - MsnSlpCall *slpcall; - MsnSlpLink *slplink; + MsnSlpCall *slpcall; /**< The slpcall to which this slp message belongs (if applicable). */ + MsnSlpLink *slplink; /**< The slplink through which this slp message is being sent. */ MsnSession *session; long session_id; @@ -48,10 +52,8 @@ long long ack_size; long app_id; - gboolean sip; -#if 0 - gboolean wasted; -#endif + gboolean sip; /**< A flag that states if this is a SIP slp message. */ + int ref_count; /**< The reference count. */ long flags; FILE *fp; @@ -59,16 +61,33 @@ long long offset; long long size; - MsnMessage *msg; /* The temporary real message that will be sent */ + GList *msgs; /**< The real messages. */ -#ifdef DEBUG_SLP +#if 1 + MsnMessage *msg; /**< The temporary real message that will be sent. */ +#endif + +#ifdef MSN_DEBUG_SLP char *info; gboolean text_body; #endif }; +/** + * Creates a new slp message + * + * @param slplink The slplink through which this slp message will be sent. + * @return The created slp message. + */ MsnSlpMessage *msn_slpmsg_new(MsnSlpLink *slplink); + +/** + * Destroys a slp message + * + * @param slpmsg The slp message to destory. + */ void msn_slpmsg_destroy(MsnSlpMessage *slpmsg); + void msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body, long long size); void msn_slpmsg_open_file(MsnSlpMessage *slpmsg, @@ -79,7 +98,7 @@ const char *content_type, const char *content); -#ifdef DEBUG_SLP +#ifdef MSN_DEBUG_SLP const void msn_slpmsg_show(MsnMessage *msg); #endif diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/switchboard.c --- a/src/protocols/msn/switchboard.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/switchboard.c Sat Dec 11 20:01:58 2004 +0000 @@ -31,7 +31,144 @@ static MsnTable *cbs_table; -static void cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error); +static void msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, + MsnMsgErrorType error); + +/************************************************************************** + * Main stuff + **************************************************************************/ +MsnSwitchBoard * +msn_switchboard_new(MsnSession *session) +{ + MsnSwitchBoard *swboard; + MsnServConn *servconn; + MsnCmdProc *cmdproc; + + g_return_val_if_fail(session != NULL, NULL); + + swboard = g_new0(MsnSwitchBoard, 1); + + swboard->session = session; + swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVER_SB); + cmdproc = servconn->cmdproc; + + swboard->im_queue = g_queue_new(); + swboard->empty = TRUE; + + servconn->data = swboard; + + session->switches = g_list_append(session->switches, swboard); + + cmdproc->cbs_table = cbs_table; + + return swboard; +} + +void +msn_switchboard_destroy(MsnSwitchBoard *swboard) +{ + MsnSession *session; + MsnMessage *msg; + GList *l; + + g_return_if_fail(swboard != NULL); + + if (swboard->destroying) + return; + + swboard->destroying = TRUE; + + /* If it linked us is because its looking for trouble */ + if (swboard->slplink != NULL) + msn_slplink_destroy(swboard->slplink); + + /* Destroy the message queue */ + while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL) + { + if (swboard->error != MSN_SB_ERROR_NONE) + { + /* The messages could not be sent due to a switchboard error */ + msg_error_helper(swboard->servconn->cmdproc, msg, + MSN_MSG_ERROR_SB); + } + msn_message_destroy(msg); + } + + g_queue_free(swboard->im_queue); + + if (swboard->im_user != NULL) + g_free(swboard->im_user); + + if (swboard->auth_key != NULL) + g_free(swboard->auth_key); + + if (swboard->session_id != NULL) + g_free(swboard->session_id); + + for (l = swboard->users; l != NULL; l = l->next) + g_free(l->data); + + session = swboard->session; + session->switches = g_list_remove(session->switches, swboard); + + if (swboard->servconn != NULL) + msn_servconn_destroy(swboard->servconn); + + g_free(swboard); +} + +void +msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key) +{ + g_return_if_fail(swboard != NULL); + g_return_if_fail(key != NULL); + + swboard->auth_key = g_strdup(key); +} + +const char * +msn_switchboard_get_auth_key(MsnSwitchBoard *swboard) +{ + g_return_val_if_fail(swboard != NULL, NULL); + + return swboard->auth_key; +} + +void +msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id) +{ + g_return_if_fail(swboard != NULL); + g_return_if_fail(id != NULL); + + if (swboard->session_id != NULL) + g_free(swboard->session_id); + + swboard->session_id = g_strdup(id); +} + +const char * +msn_switchboard_get_session_id(MsnSwitchBoard *swboard) +{ + g_return_val_if_fail(swboard != NULL, NULL); + + return swboard->session_id; +} + +void +msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited) +{ + g_return_if_fail(swboard != NULL); + + swboard->invited = invited; +} + +gboolean +msn_switchboard_is_invited(MsnSwitchBoard *swboard) +{ + g_return_val_if_fail(swboard != NULL, FALSE); + + return swboard->invited; +} /************************************************************************** * Utility functions @@ -68,9 +205,11 @@ /* gaim_debug_info("msn", "user=[%s], total=%d\n", user, * swboard->current_users); */ - if ((swboard->conv != NULL) && (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_CHAT)) + if ((swboard->conv != NULL) && + (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_CHAT)) { - gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL, GAIM_CBFLAGS_NONE, TRUE); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL, + GAIM_CBFLAGS_NONE, TRUE); } else if (swboard->current_users > 1 || swboard->total_users > 1) { @@ -127,18 +266,6 @@ } } -/************************************************************************** - * Switchboard Commands - **************************************************************************/ -static void -ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) -{ - MsnSwitchBoard *swboard; - - swboard = cmdproc->servconn->data; - swboard->ready = TRUE; -} - GaimConversation * msn_switchboard_get_conv(MsnSwitchBoard *swboard) { @@ -149,6 +276,8 @@ if (swboard->conv != NULL) return swboard->conv; + gaim_debug_error("msn", "Switchboard with unnasigned conversation\n"); + account = swboard->session->account; /* XXX - I think this should probably be GAIM_CONV_IM, but I'm hedging */ @@ -171,6 +300,126 @@ } static void +swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport) +{ + gaim_debug_info("msg", "Error: Unable to call the user %s\n", passport); + + if (swboard->total_users == 0) + { + swboard->error = reason; + msn_switchboard_destroy(swboard); + } +} + +static void +cal_error_helper(MsnTransaction *trans, int reason) +{ + MsnSwitchBoard *swboard; + const char *passport; + char **params; + + params = g_strsplit(trans->params, " ", 0); + + passport = params[0]; + + swboard = trans->data; + + swboard_error_helper(swboard, reason, passport); + + g_strfreev(params); +} + +static void +msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error) +{ + g_return_if_fail(cmdproc != NULL); + g_return_if_fail(msg != NULL); + + if (msg->nak_cb != NULL) + msg->nak_cb(msg, msg->ack_data); + + if (msg->type == MSN_MSG_TEXT) + { + MsnSwitchBoard *swboard; + char *body; + char *report; + char *str_reason; + + swboard = cmdproc->servconn->data; + +#if 0 + if (swboard->conv == NULL) + { + msn_message_unref(msg); + return; + } +#endif + + if (msg->error == MSN_MSG_ERROR_TIMEOUT) + { + str_reason = _("Message may have not been sent " + "because a time out occured."); + } + else if (msg->error == MSN_MSG_ERROR_SB) + { + switch (swboard->error) + { + case MSN_SB_ERROR_OFFLINE: + str_reason = _("Message could not be sent, " + "not allowed while invisible"); + break; + case MSN_SB_ERROR_USER_OFFLINE: + str_reason = _("Message could not be sent " + "because the user is offline"); + break; + case MSN_SB_ERROR_CONNECTION: + str_reason = _("Message could not be sent " + "because a connection error occured"); + break; + default: + str_reason = _("Message could not be sent " + "because an error with " + "the switchboard occured"); + break; + } + } + else + { + str_reason = _("Message may have not been sent " + "because an unkwown error occured"); + } + + body = msn_message_to_string(msg); + report = g_strdup_printf(_("%s:\n%s"), str_reason, body); + + msn_switchboard_report_user(cmdproc->servconn->data, + GAIM_MESSAGE_ERROR, report); + + g_free(report); + g_free(body); + + msn_message_unref(msg); + } + else if (msg->type == MSN_MSG_SLP) + { + msn_message_unref(msg); + } + +} + +/************************************************************************** + * Switchboard Commands + **************************************************************************/ +static void +ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) +{ + MsnSwitchBoard *swboard; + + swboard = cmdproc->servconn->data; + swboard->ready = TRUE; +} + +static void bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnSwitchBoard *swboard; @@ -179,15 +428,20 @@ swboard = cmdproc->servconn->data; user = cmd->params[0]; - if (swboard->hidden) - return; - - if (swboard->current_users > 1) + if (swboard->conv == NULL) { + /* This is a helper switchboard */ + msn_switchboard_disconnect(swboard); + } + else if (swboard->current_users > 1) + { + /* This is a switchboard used for a chat */ gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->conv), user, NULL); } else { + /* This is a switchboard used for a im session */ + char *str = NULL; if (cmd->param_count == 2 && atoi(cmd->params[1]) == 1) @@ -261,9 +515,7 @@ msn_switchboard_add_user(swboard, passport); - swboard->user_joined = TRUE; - - /* msn_cmdproc_process_queue(cmdproc); */ + swboard->empty = FALSE; msn_switchboard_process_queue(swboard); @@ -299,28 +551,25 @@ static void nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { - /* - gaim_notify_error(cmdproc->session->account->gc, NULL, - _("A MSN message may not have been received."), NULL); - */ + MsnMessage *msg; + + msg = cmd->trans->data; + g_return_if_fail(msg != NULL); + + msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_NAK); } static void ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { -#if 0 MsnMessage *msg; - const char *body; - msg = msn_message_new(); - msn_message_parse_payload(msg, cmd->trans->payload, cmd->trans->payload_len); + msg = cmd->trans->data; - body = msn_message_get_body(msg); + if (msg->ack_cb != NULL) + msg->ack_cb(msg, msg->ack_data); - gaim_debug_info("msn", "ACK: {%s}\n", body); - - msn_message_destroy(msg); -#endif + msn_message_unref(msg); } static void @@ -362,7 +611,7 @@ } /************************************************************************** - * Message Types + * Message Handlers **************************************************************************/ static void plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg) @@ -467,63 +716,31 @@ #endif } -static void -msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg) -{ - if (msg->type == MSN_MSG_TEXT) - { - MsnSwitchBoard *swboard; - char *body; - char *report; - char *str_reason; - - swboard = cmdproc->servconn->data; - - switch (swboard->error) - { - case MSN_SB_ERROR_OFFLINE: - str_reason = _("Message could not be sent, not allowed while invisible"); - break; - case MSN_SB_ERROR_USER_OFFLINE: - str_reason = _("Message could not be sent because the user is offline"); - break; - case MSN_SB_ERROR_CONNECTION: - str_reason = _("Message could not be sent because a connection error occured"); - break; - default: - str_reason = _("Message could not be sent for an unknown reason"); - break; - } - - body = msn_message_to_string(msg); - report = g_strdup_printf(_("%s:\n%s"), str_reason, body); - gaim_debug_info("msn", "%s\n", report); - msn_switchboard_report_user(cmdproc->servconn->data, GAIM_MESSAGE_ERROR, report); - g_free(report); - g_free(body); - } -} - +/************************************************************************** + * Message stuff + **************************************************************************/ +/** Called when a message times out. */ static void msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) { MsnMessage *msg; msg = trans->data; - g_return_if_fail(msg != NULL); - gaim_debug_info("msn", "msg_timeout\n"); - msg_error_helper(cmdproc, msg); + msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT); } +/** Called when we receive an error of a message. */ static void msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) { - msg_error_helper(cmdproc, trans->data); + msg_error_helper(cmdproc, trans->data, MSN_MSG_ERROR_UNKNOWN); } +#if 0 +/** Called when we receive an ack of a special message. */ static void -msg_ack (MsnCmdProc *cmdproc, MsnCommand *cmd) +msg_ack(MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnMessage *msg; @@ -535,6 +752,18 @@ msn_message_unref(msg); } +/** Called when we receive a nak of a special message. */ +static void +msg_nak(MsnCmdProc *cmdproc, MsnCommand *cmd) +{ + MsnMessage *msg; + + msg = cmd->trans->data; + + msn_message_unref(msg); +} +#endif + void msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg) { @@ -557,15 +786,24 @@ /* Data for callbacks */ msn_transaction_set_data(trans, msg); - msn_message_ref(msg); - if (msg->ack_cb != NULL) + if (msg->type == MSN_MSG_TEXT) { - msn_transaction_add_cb(trans, "ACK", msg_ack); + msn_message_ref(msg); msn_transaction_set_timeout_cb(trans, msg_timeout); } - else if (msg->type == MSN_MSG_TEXT) + else if (msg->type == MSN_MSG_SLP) + { + msn_message_ref(msg); msn_transaction_set_timeout_cb(trans, msg_timeout); +#if 0 + if (msg->ack_cb != NULL) + { + msn_transaction_add_cb(trans, "ACK", msg_ack); + msn_transaction_add_cb(trans, "NAK", msg_nak); + } +#endif + } trans->payload = payload; trans->payload_len = payload_len; @@ -624,7 +862,7 @@ swboard = servconn->data; g_return_if_fail(swboard != NULL); - swboard->user_joined = TRUE; + swboard->empty = FALSE; if (msn_switchboard_is_invited(swboard)) { @@ -651,138 +889,29 @@ msn_switchboard_destroy(swboard); } -void -msn_switchboard_init(void) +gboolean +msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port) { - cbs_table = msn_table_new(); - - msn_table_add_cmd(cbs_table, "ANS", "ANS", ans_cmd); - msn_table_add_cmd(cbs_table, "ANS", "IRO", iro_cmd); - - msn_table_add_cmd(cbs_table, "MSG", "ACK", ack_cmd); - msn_table_add_cmd(cbs_table, "MSG", "NAK", nak_cmd); - - msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); - - msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd); - msn_table_add_cmd(cbs_table, NULL, "JOI", joi_cmd); - msn_table_add_cmd(cbs_table, NULL, "BYE", bye_cmd); - msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd); + g_return_val_if_fail(swboard != NULL, FALSE); -#if 0 - /* They might skip the history */ - msn_table_add_cmd(cbs_table, NULL, "ACK", NULL); -#endif - - msn_table_add_error(cbs_table, "MSG", msg_error); - msn_table_add_error(cbs_table, "CAL", cal_error); + msn_servconn_set_connect_cb(swboard->servconn, connect_cb); - /* Register the message type callbacks. */ - msn_table_add_msg_type(cbs_table, "text/plain", - plain_msg); - msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol", - control_msg); - msn_table_add_msg_type(cbs_table, "text/x-clientcaps", - clientcaps_msg); - msn_table_add_msg_type(cbs_table, "text/x-clientinfo", - clientcaps_msg); - msn_table_add_msg_type(cbs_table, "application/x-msnmsgrp2p", - msn_p2p_msg); - msn_table_add_msg_type(cbs_table, "text/x-mms-emoticon", - msn_emoticon_msg); -#if 0 - msn_table_add_msg_type(cbs_table, "text/x-msmmsginvite", - msn_invite_msg); -#endif + return msn_servconn_connect(swboard->servconn, host, port); } void -msn_switchboard_end(void) -{ - msn_table_destroy(cbs_table); -} - -MsnSwitchBoard * -msn_switchboard_new(MsnSession *session) +msn_switchboard_disconnect(MsnSwitchBoard *swboard) { - MsnSwitchBoard *swboard; - MsnServConn *servconn; - MsnCmdProc *cmdproc; - - g_return_val_if_fail(session != NULL, NULL); - - swboard = g_new0(MsnSwitchBoard, 1); + g_return_if_fail(swboard != NULL); - swboard->session = session; - swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVER_SB); - cmdproc = servconn->cmdproc; - - swboard->im_queue = g_queue_new(); + msn_servconn_set_disconnect_cb(swboard->servconn, disconnect_cb); - if (session->http_method) - servconn->http_data->server_type = "SB"; - else - msn_servconn_set_connect_cb(servconn, connect_cb); - - msn_servconn_set_disconnect_cb(servconn, disconnect_cb); - - servconn->data = swboard; - - session->switches = g_list_append(session->switches, swboard); - - cmdproc->cbs_table = cbs_table; - - return swboard; + msn_servconn_disconnect(swboard->servconn); } -void -msn_switchboard_destroy(MsnSwitchBoard *swboard) -{ - MsnSession *session; - MsnMessage *msg; - GList *l; - - g_return_if_fail(swboard != NULL); - - if (swboard->destroying) - return; - - swboard->destroying = TRUE; - - /* Destroy the message queue */ - while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL) - { - if (swboard->error > 0) - { - /* The messages could not be sent due to an error */ - msg_error_helper(swboard->servconn->cmdproc, msg); - } - msn_message_destroy(msg); - } - - g_queue_free(swboard->im_queue); - - if (swboard->im_user != NULL) - g_free(swboard->im_user); - - if (swboard->auth_key != NULL) - g_free(swboard->auth_key); - - if (swboard->session_id != NULL) - g_free(swboard->session_id); - - for (l = swboard->users; l != NULL; l = l->next) - g_free(l->data); - - session = swboard->session; - session->switches = g_list_remove(session->switches, swboard); - - if (swboard->servconn != NULL) - msn_servconn_destroy(swboard->servconn); - - g_free(swboard); -} - +/************************************************************************** + * Call stuff + **************************************************************************/ #if 0 static void got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd) @@ -799,36 +928,6 @@ #endif static void -swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport) -{ - gaim_debug_info("msg", "Error: Unable to call the user %s\n", passport); - - if (swboard->total_users == 0) - { - swboard->error = reason; - msn_switchboard_destroy(swboard); - } -} - -static void -cal_error_helper(MsnTransaction *trans, int reason) -{ - MsnSwitchBoard *swboard; - const char *passport; - char **params; - - params = g_strsplit(trans->params, " ", 0); - - passport = params[0]; - - swboard = trans->data; - - swboard_error_helper(swboard, reason, passport); - - g_strfreev(params); -} - -static void cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) { cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN); @@ -867,75 +966,9 @@ msn_cmdproc_queue_trans(cmdproc, trans); } -void -msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key) -{ - g_return_if_fail(swboard != NULL); - g_return_if_fail(key != NULL); - - swboard->auth_key = g_strdup(key); -} - -const char * -msn_switchboard_get_auth_key(MsnSwitchBoard *swboard) -{ - g_return_val_if_fail(swboard != NULL, NULL); - - return swboard->auth_key; -} - -void -msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id) -{ - g_return_if_fail(swboard != NULL); - g_return_if_fail(id != NULL); - - if (swboard->session_id != NULL) - g_free(swboard->session_id); - - swboard->session_id = g_strdup(id); -} - -const char * -msn_switchboard_get_session_id(MsnSwitchBoard *swboard) -{ - g_return_val_if_fail(swboard != NULL, NULL); - - return swboard->session_id; -} - -void -msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited) -{ - g_return_if_fail(swboard != NULL); - - swboard->invited = invited; -} - -gboolean -msn_switchboard_is_invited(MsnSwitchBoard *swboard) -{ - g_return_val_if_fail(swboard != NULL, FALSE); - - return swboard->invited; -} - -gboolean -msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port) -{ - g_return_val_if_fail(swboard != NULL, FALSE); - - return msn_servconn_connect(swboard->servconn, host, port); -} - -void -msn_switchboard_disconnect(MsnSwitchBoard *swboard) -{ - g_return_if_fail(swboard != NULL); - - msn_servconn_disconnect(swboard->servconn); -} - +/************************************************************************** + * Create & Transfer stuff + **************************************************************************/ static void got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd) { @@ -960,7 +993,7 @@ servconn = swboard->servconn; account = session->account; - swboard->user_joined = TRUE; + swboard->empty = FALSE; servconn->http_data->gateway_host = g_strdup(host); @@ -1019,3 +1052,57 @@ msn_cmdproc_send_trans(cmdproc, trans); } + +/************************************************************************** + * Init stuff + **************************************************************************/ +void +msn_switchboard_init(void) +{ + cbs_table = msn_table_new(); + + msn_table_add_cmd(cbs_table, "ANS", "ANS", ans_cmd); + msn_table_add_cmd(cbs_table, "ANS", "IRO", iro_cmd); + + msn_table_add_cmd(cbs_table, "MSG", "ACK", ack_cmd); + msn_table_add_cmd(cbs_table, "MSG", "NAK", nak_cmd); + + msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); + + msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd); + msn_table_add_cmd(cbs_table, NULL, "JOI", joi_cmd); + msn_table_add_cmd(cbs_table, NULL, "BYE", bye_cmd); + msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd); + +#if 0 + /* They might skip the history */ + msn_table_add_cmd(cbs_table, NULL, "ACK", NULL); +#endif + + msn_table_add_error(cbs_table, "MSG", msg_error); + msn_table_add_error(cbs_table, "CAL", cal_error); + + /* Register the message type callbacks. */ + msn_table_add_msg_type(cbs_table, "text/plain", + plain_msg); + msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol", + control_msg); + msn_table_add_msg_type(cbs_table, "text/x-clientcaps", + clientcaps_msg); + msn_table_add_msg_type(cbs_table, "text/x-clientinfo", + clientcaps_msg); + msn_table_add_msg_type(cbs_table, "application/x-msnmsgrp2p", + msn_p2p_msg); + msn_table_add_msg_type(cbs_table, "text/x-mms-emoticon", + msn_emoticon_msg); +#if 0 + msn_table_add_msg_type(cbs_table, "text/x-msmmsginvite", + msn_invite_msg); +#endif +} + +void +msn_switchboard_end(void) +{ + msn_table_destroy(cbs_table); +} diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/switchboard.h --- a/src/protocols/msn/switchboard.h Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/switchboard.h Sat Dec 11 20:01:58 2004 +0000 @@ -33,17 +33,26 @@ #include "servconn.h" +#include "slplink.h" + +/* + * A switchboard error + */ typedef enum { - MSN_SB_ERROR_NONE, - MSN_SB_ERROR_CAL, /* The user could not join (answer the call) */ - MSN_SB_ERROR_OFFLINE, /* The account is offline */ - MSN_SB_ERROR_USER_OFFLINE, /* The user to call is offline */ - MSN_SB_ERROR_CONNECTION, /* There was a connection error */ - MSN_SB_ERROR_UNKNOWN + MSN_SB_ERROR_NONE, /**< No error */ + MSN_SB_ERROR_CAL, /**< The user could not join (answer the call) */ + MSN_SB_ERROR_OFFLINE, /**< The account is offline */ + MSN_SB_ERROR_USER_OFFLINE, /**< The user to call is offline */ + MSN_SB_ERROR_CONNECTION, /**< There was a connection error */ + MSN_SB_ERROR_UNKNOWN /**< An unknown error occured */ } MsnSBErrorType; +/* + * A switchboard A place where a bunch of users send messages to the rest + * of the users. + */ struct _MsnSwitchBoard { MsnSession *session; @@ -53,13 +62,18 @@ char *auth_key; char *session_id; - gboolean invited; - gboolean destroying; + GaimConversation *conv; /**< The conversation that displays the + messages of this switchboard, or @c NULL if + this is a helper switchboard. */ - GaimConversation *conv; - - gboolean ready; /* When it's actually usable */ - /* gboolean in_use; */ + gboolean empty; /**< A flag that states if the swithcboard has no + users in it. */ + gboolean invited; /**< A flag that states if we were invited to the + switchboard. */ + gboolean destroying; /**< A flag that states if the switchboard is on + the process of being destroyed. */ + gboolean ready; /**< A flag that states if his switchboard is + ready to be used. */ int current_users; int total_users; @@ -67,12 +81,11 @@ int chat_id; - gboolean hidden; - - gboolean user_joined; GQueue *im_queue; - int error; + MsnSBErrorType error; /**< The error that occured in this switchboard + (if applicable). */ + MsnSlpLink *slplink; /**< The slplink that is using this switchboard. */ }; /** @@ -101,25 +114,6 @@ */ void msn_switchboard_destroy(MsnSwitchBoard *swboard); -#if 0 -/** - * Sets the user the switchboard is supposed to connect to. - * - * @param swboard The switchboard. - * @param user The user. - */ -void msn_switchboard_set_user(MsnSwitchBoard *swboard, const char *user); - -/** - * Returns the user the switchboard is supposed to connect to. - * - * @param swboard The switchboard. - * - * @return The user. - */ -const char *msn_switchboard_get_user(MsnSwitchBoard *swboard); -#endif - /** * Sets the auth key the switchboard must use when connecting. * @@ -155,7 +149,7 @@ const char *msn_switchboard_get_session_id(MsnSwitchBoard *swboard); /** - * Sets whether or not the user was invited to this switchboard. + * Sets whether or not we were invited to this switchboard. * * @param swboard The switchboard. * @param invite @c TRUE if invited, @c FALSE otherwise. @@ -163,7 +157,7 @@ void msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited); /** - * Returns whether or not the user was invited to this switchboard. + * Returns whether or not we were invited to this switchboard. * * @param swboard The switchboard. * @@ -182,16 +176,23 @@ */ gboolean msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port); + +/** + * Disconnects from a switchboard. + * + * @param swboard The switchboard to disconnect from. + */ void msn_switchboard_disconnect(MsnSwitchBoard *swboard); + void msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg); +void msn_switchboard_queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg); +void msn_switchboard_process_queue(MsnSwitchBoard *swboard); gboolean msn_switchboard_chat_leave(MsnSwitchBoard *swboard); gboolean msn_switchboard_chat_invite(MsnSwitchBoard *swboard, const char *who); void msn_switchboard_request(MsnSwitchBoard *swboard); void msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user); -void msn_switchboard_queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg); -void msn_switchboard_process_queue(MsnSwitchBoard *swboard); /** * Processes application/x-msnmsgrp2p messages. diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/table.c --- a/src/protocols/msn/table.c Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/table.c Sat Dec 11 20:01:58 2004 +0000 @@ -117,7 +117,7 @@ void msn_table_add_msg_type(MsnTable *table, - char *type, MsnMsgCb cb) + char *type, MsnMsgTypeCb cb) { g_return_if_fail(table != NULL); g_return_if_fail(type != NULL); diff -r 5976491e07a7 -r 2e01c503aa4f src/protocols/msn/table.h --- a/src/protocols/msn/table.h Sat Dec 11 00:06:06 2004 +0000 +++ b/src/protocols/msn/table.h Sat Dec 11 20:01:58 2004 +0000 @@ -30,7 +30,7 @@ #include "transaction.h" #include "msg.h" -typedef void (*MsnMsgCb)(MsnCmdProc *cmdproc, MsnMessage *msg); +typedef void (*MsnMsgTypeCb)(MsnCmdProc *cmdproc, MsnMessage *msg); struct _MsnTable { @@ -48,6 +48,6 @@ void msn_table_add_cmd(MsnTable *table, char *command, char *answer, MsnTransCb cb); void msn_table_add_error(MsnTable *table, char *answer, MsnErrorCb cb); -void msn_table_add_msg_type(MsnTable *table, char *type, MsnMsgCb cb); +void msn_table_add_msg_type(MsnTable *table, char *type, MsnMsgTypeCb cb); #endif /* _MSN_TABLE_H_ */