Mercurial > pidgin.yaz
diff libpurple/protocols/msn/slplink.c @ 31292:47b6eda87723
propagate from branch 'im.pidgin.pidgin' (head 07d0765c444a097af45c2650f54323afb900a07b)
to branch 'im.pidgin.soc.2010.msn-tlc' (head f3998422a4724ab424e4e2328f58fc0504856557)
author | masca@cpw.pidgin.im |
---|---|
date | Mon, 19 Jul 2010 21:11:32 +0000 |
parents | 8c1a2ef5a713 e0c374ad8fd3 |
children | 6814678f3c63 |
line wrap: on
line diff
--- a/libpurple/protocols/msn/slplink.c Mon Jul 19 18:25:47 2010 +0000 +++ b/libpurple/protocols/msn/slplink.c Mon Jul 19 21:11:32 2010 +0000 @@ -21,30 +21,37 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + +#include "internal.h" +#include "debug.h" + #include "msn.h" #include "slplink.h" +#include "slpmsg_part.h" +#include "sbconn.h" #include "switchboard.h" #include "slp.h" +#include "p2p.h" #ifdef MSN_DEBUG_SLP_FILES static int m_sc = 0; static int m_rc = 0; static void -debug_msg_to_file(MsnMessage *msg, gboolean send) +debug_part_to_file(MsnSlpMessage *msg, gboolean send) { char *tmp; char *dir; - char *pload; + char *data; int c; - gsize pload_size; + gsize data_size; dir = send ? "send" : "recv"; c = send ? m_sc++ : m_rc++; tmp = g_strdup_printf("%s/msntest/%s/%03d", g_get_home_dir(), dir, c); - pload = msn_message_gen_payload(msg, &pload_size); - if (!purple_util_write_data_to_file_absolute(tmp, pload, pload_size)) + data = msn_slpmsg_serialize(msg, &data_size); + if (!purple_util_write_data_to_file_absolute(tmp, data, data_size)) { purple_debug_error("msn", "could not save debug file\n"); } @@ -81,7 +88,7 @@ return msn_slplink_ref(slplink); } -void +static void msn_slplink_destroy(MsnSlpLink *slplink) { MsnSession *session; @@ -265,77 +272,70 @@ } void -msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg) +msn_slplink_send_part(MsnSlpLink *slplink, MsnSlpMessagePart *part) { if (slplink->dc != NULL && slplink->dc->state == DC_STATE_ESTABLISHED) { - msn_dc_enqueue_msg(slplink->dc, msg); + msn_dc_enqueue_part(slplink->dc, part); } else { - if (slplink->swboard == NULL) - { - slplink->swboard = msn_session_get_swboard(slplink->session, - slplink->remote_user, MSN_SB_FLAG_FT); - - g_return_if_fail(slplink->swboard != NULL); - - /* If swboard is destroyed we will be too */ - slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink); - } - - msn_switchboard_send_msg(slplink->swboard, msg, TRUE); + msn_sbconn_send_part(slplink, part); } } void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { - MsnMessage *msg; + MsnSlpMessagePart *part; 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; + part = msn_slpmsgpart_new(slpmsg->header, slpmsg->footer); + part->ack_data = slpmsg; - real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; + real_size = (slpmsg->flags == P2P_ACK) ? 0 : slpmsg->size; if (slpmsg->offset < real_size) { if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) { - len = MIN(1202, slpmsg->slpcall->u.outgoing.len); - msn_message_set_bin_data(msg, slpmsg->slpcall->u.outgoing.data, len); + len = MIN(MSN_SBCONN_MAX_SIZE, slpmsg->slpcall->u.outgoing.len); + msn_slpmsgpart_set_bin_data(part, slpmsg->slpcall->u.outgoing.data, len); } else { len = slpmsg->size - slpmsg->offset; - if (len > 1202) - len = 1202; + if (len > MSN_SBCONN_MAX_SIZE) + len = MSN_SBCONN_MAX_SIZE; - msn_message_set_bin_data(msg, slpmsg->buffer + slpmsg->offset, len); + msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + slpmsg->offset, len); } - msg->msnslp_header.offset = slpmsg->offset; - msg->msnslp_header.length = len; + slpmsg->header->offset = slpmsg->offset; + slpmsg->header->length = len; } +#if 0 + /* TODO: port this function to SlpMessageParts */ if (purple_debug_is_verbose()) msn_message_show_readable(msg, slpmsg->info, slpmsg->text_body); +#endif #ifdef MSN_DEBUG_SLP_FILES - debug_msg_to_file(msg, TRUE); + debug_part_to_file(slpmsg, TRUE); #endif - slpmsg->msgs = - g_list_append(slpmsg->msgs, msn_message_ref(msg)); - msn_slplink_send_msg(slplink, msg); + slpmsg->parts = g_list_append(slpmsg->parts, part); + msn_slplink_send_part(slplink, part); - if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || - slpmsg->flags == 0x1000030) && + if ((slpmsg->flags == P2P_MSN_OBJ_DATA || + slpmsg->flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) || + slpmsg->flags == P2P_FILE_DATA) && (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; @@ -350,117 +350,50 @@ /* slpmsg->offset += len; */ } -/* We have received the message ack */ -static void -msg_ack(MsnMessage *msg, void *data) -{ - MsnSlpMessage *slpmsg; - long long real_size; - - slpmsg = data; - - real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; - - slpmsg->offset += msg->msnslp_header.length; - - slpmsg->msgs = g_list_remove(slpmsg->msgs, msg); - - if (slpmsg->offset < real_size) - { - if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) - { - slpmsg->slpcall->xfer_msg = slpmsg; - msn_message_ref(msg); - purple_xfer_prpl_ready(slpmsg->slpcall->xfer); - } - else - msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); - } - else - { - /* The whole message has been sent */ - if (slpmsg->flags == 0x20 || - slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) - { - if (slpmsg->slpcall != NULL) - { - if (slpmsg->slpcall->cb) - slpmsg->slpcall->cb(slpmsg->slpcall, - NULL, 0); - } - } - } - - msn_message_unref(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); - msn_message_unref(msg); -} - static void msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { - MsnMessage *msg; - const char *passport; - - slpmsg->msg = msg = msn_message_new_msnslp(); + slpmsg = slpmsg; + slpmsg->header = g_new0(MsnP2PHeader, 1); + slpmsg->footer = g_new0(MsnP2PFooter, 1); - if (slpmsg->flags == 0x0) + if (slpmsg->flags == P2P_NO_FLAG) { - msg->msnslp_header.session_id = slpmsg->session_id; - msg->msnslp_header.ack_id = rand() % 0xFFFFFF00; + slpmsg->header->session_id = slpmsg->session_id; + slpmsg->header->ack_id = rand() % 0xFFFFFF00; } - else if (slpmsg->flags == 0x2) + else if (slpmsg->flags == P2P_ACK) { - msg->msnslp_header.session_id = slpmsg->session_id; - msg->msnslp_header.ack_id = slpmsg->ack_id; - msg->msnslp_header.ack_size = slpmsg->ack_size; - msg->msnslp_header.ack_sub_id = slpmsg->ack_sub_id; + slpmsg->header->session_id = slpmsg->session_id; + slpmsg->header->ack_id = slpmsg->ack_id; + slpmsg->header->ack_size = slpmsg->ack_size; + slpmsg->header->ack_sub_id = slpmsg->ack_sub_id; } - else if (slpmsg->flags == 0x20 || - slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) + else if (slpmsg->flags == P2P_MSN_OBJ_DATA || + slpmsg->flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) || + slpmsg->flags == P2P_FILE_DATA) { MsnSlpCall *slpcall; slpcall = slpmsg->slpcall; g_return_if_fail(slpcall != NULL); - msg->msnslp_header.session_id = slpcall->session_id; - msg->msnslp_footer.value = slpcall->app_id; - msg->msnslp_header.ack_id = rand() % 0xFFFFFF00; + slpmsg->header->session_id = slpcall->session_id; + slpmsg->footer->value = slpcall->app_id; + slpmsg->header->ack_id = rand() % 0xFFFFFF00; } else if (slpmsg->flags == 0x100) { - msg->msnslp_header.ack_id = slpmsg->ack_id; - msg->msnslp_header.ack_sub_id = slpmsg->ack_sub_id; - msg->msnslp_header.ack_size = slpmsg->ack_size; + slpmsg->header->ack_id = slpmsg->ack_id; + slpmsg->header->ack_sub_id = slpmsg->ack_sub_id; + slpmsg->header->ack_size = slpmsg->ack_size; } - msg->msnslp_header.id = slpmsg->id; - msg->msnslp_header.flags = slpmsg->flags; - - msg->msnslp_header.total_size = slpmsg->size; + slpmsg->header->id = slpmsg->id; + slpmsg->header->flags = (guint32)slpmsg->flags; - passport = purple_normalize(slplink->session->account, slplink->remote_user); - msn_message_set_attr(msg, "P2P-Dest", passport); - - msg->ack_cb = msg_ack; - msg->nak_cb = msg_nak; - msg->ack_data = slpmsg; + slpmsg->header->total_size = slpmsg->size; msn_slplink_send_msgpart(slplink, slpmsg); - - msn_message_destroy(msg); } void @@ -494,25 +427,18 @@ } static MsnSlpMessage * -msn_slplink_create_ack(MsnSlpLink *slplink, MsnSlpHeader *header) +msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PHeader *header) { MsnSlpMessage *slpmsg; - slpmsg = msn_slpmsg_new(slplink); - - slpmsg->session_id = header->session_id; - slpmsg->size = header->total_size; - slpmsg->flags = 0x02; - slpmsg->ack_id = header->id; - slpmsg->ack_sub_id = header->ack_id; - slpmsg->ack_size = header->total_size; - slpmsg->info = "SLP ACK"; + slpmsg = msn_slpmsg_ack_new(header); + msn_slpmsg_set_slplink(slpmsg, slplink); return slpmsg; } static void -msn_slplink_send_ack(MsnSlpLink *slplink, MsnSlpHeader *header) +msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PHeader *header) { MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, header); @@ -520,33 +446,6 @@ msn_slpmsg_destroy(slpmsg); } -static void -send_file_cb(MsnSlpCall *slpcall) -{ - MsnSlpMessage *slpmsg; - PurpleXfer *xfer; - - xfer = (PurpleXfer *)slpcall->xfer; - if (purple_xfer_get_status(xfer) >= PURPLE_XFER_STATUS_STARTED) - return; - - purple_xfer_ref(xfer); - purple_xfer_start(xfer, -1, NULL, 0); - if (purple_xfer_get_status(xfer) != PURPLE_XFER_STATUS_STARTED) { - purple_xfer_unref(xfer); - return; - } - purple_xfer_unref(xfer); - - slpmsg = msn_slpmsg_new(slpcall->slplink); - slpmsg->slpcall = slpcall; - slpmsg->flags = 0x1000030; - slpmsg->info = "SLP FILE"; - slpmsg->size = purple_xfer_get_size(xfer); - - msn_slplink_send_slpmsg(slpcall->slplink, slpmsg); -} - static MsnSlpMessage * msn_slplink_message_find(MsnSlpLink *slplink, long session_id, long id) { @@ -564,16 +463,18 @@ } void -msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpHeader *header, const char *data, gsize len) +msn_slplink_process_msg(MsnSlpLink *slplink, MsnP2PHeader *header, const char *data, gsize len) { MsnSlpMessage *slpmsg; guint64 offset; - PurpleXfer *xfer = NULL; if (header->total_size < header->length) { - purple_debug_error("msn", "This can't be good\n"); - g_return_if_reached(); + /* We seem to have received a bad header */ + purple_debug_warning("msn", "Total size listed in SLP binary header " + "was less than length of this particular message. This " + "should not happen. Dropping message.\n"); + return; } offset = header->offset; @@ -588,15 +489,14 @@ if (slpmsg->session_id) { - if (slpmsg->slpcall == NULL) - slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id); - + slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id); if (slpmsg->slpcall != NULL) { - if (slpmsg->flags == 0x20 || - slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) + if (slpmsg->flags == P2P_MSN_OBJ_DATA || + slpmsg->flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) || + slpmsg->flags == P2P_FILE_DATA) { - xfer = slpmsg->slpcall->xfer; + PurpleXfer *xfer = slpmsg->slpcall->xfer; if (xfer != NULL) { slpmsg->ft = TRUE; @@ -640,10 +540,9 @@ if (slpmsg->ft) { - xfer = slpmsg->slpcall->xfer; slpmsg->slpcall->u.incoming_data = g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)data, len); - purple_xfer_prpl_ready(xfer); + purple_xfer_prpl_ready(slpmsg->slpcall->xfer); } else if (slpmsg->size && slpmsg->buffer) { @@ -659,8 +558,9 @@ } } - if ((slpmsg->flags == 0x20 || - slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) && + if ((slpmsg->flags == P2P_MSN_OBJ_DATA || + slpmsg->flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) || + slpmsg->flags == P2P_FILE_DATA) && (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; @@ -701,9 +601,10 @@ msn_directconn_send_handshake(directconn); #endif } - else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 || - slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || - slpmsg->flags == 0x1000030) + else if (slpmsg->flags == P2P_NO_FLAG || slpmsg->flags == P2P_WML2009_COMP || + slpmsg->flags == P2P_MSN_OBJ_DATA || + slpmsg->flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) || + slpmsg->flags == P2P_FILE_DATA) { /* Release all the messages and send the ACK */ @@ -732,106 +633,6 @@ } } -static gchar * -gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path) -{ - gsize size = 0; - MsnFileContext *header; - gchar *u8 = NULL; - gchar *ret; - gunichar2 *uni = NULL; - glong currentChar = 0; - glong len = 0; - const char *preview; - gsize preview_len; - - size = purple_xfer_get_size(xfer); - - purple_xfer_prepare_thumbnail(xfer, "png"); - - if (!file_name) { - gchar *basename = g_path_get_basename(file_path); - u8 = purple_utf8_try_convert(basename); - g_free(basename); - file_name = u8; - } - - uni = g_utf8_to_utf16(file_name, -1, NULL, &len, NULL); - - if (u8) { - g_free(u8); - file_name = NULL; - u8 = NULL; - } - - preview = purple_xfer_get_thumbnail(xfer, &preview_len); - header = g_malloc(sizeof(MsnFileContext) + preview_len); - - header->length = GUINT32_TO_LE(sizeof(MsnFileContext) - 1); - header->version = GUINT32_TO_LE(2); /* V.3 contains additional unnecessary data */ - header->file_size = GUINT64_TO_LE(size); - if (preview) - header->type = GUINT32_TO_LE(0); - else - header->type = GUINT32_TO_LE(1); - - len = MIN(len, MAX_FILE_NAME_LEN); - for (currentChar = 0; currentChar < len; currentChar++) { - header->file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]); - } - memset(&header->file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2); - - memset(&header->unknown1, 0, sizeof(header->unknown1)); - header->unknown2 = GUINT32_TO_LE(0xffffffff); - if (preview) { - memcpy(&header->preview, preview, preview_len); - } - header->preview[preview_len] = '\0'; - - g_free(uni); - ret = purple_base64_encode((const guchar *)header, sizeof(MsnFileContext) + preview_len); - g_free(header); - return ret; -} - -void -msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer) -{ - MsnSlpCall *slpcall; - char *context; - const char *fn; - const char *fp; - - fn = purple_xfer_get_filename(xfer); - fp = purple_xfer_get_local_filename(xfer); - - g_return_if_fail(slplink != NULL); - g_return_if_fail(fp != NULL); - - slpcall = msn_slpcall_new(slplink); - msn_slpcall_init(slpcall, MSN_SLPCALL_DC); - - slpcall->session_init_cb = send_file_cb; - slpcall->end_cb = msn_xfer_end_cb; - slpcall->cb = msn_xfer_completed_cb; - slpcall->xfer = xfer; - purple_xfer_ref(slpcall->xfer); - - slpcall->pending = TRUE; - - purple_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel); - purple_xfer_set_read_fnc(xfer, msn_xfer_read); - purple_xfer_set_write_fnc(xfer, msn_xfer_write); - - xfer->data = slpcall; - - context = gen_context(xfer, fn, fp); - - msn_slpcall_invite(slpcall, MSN_FT_GUID, 2, context); - - g_free(context); -} - void msn_slplink_request_object(MsnSlpLink *slplink, const char *info, @@ -857,7 +658,7 @@ slpcall->cb = cb; slpcall->end_cb = end_cb; - msn_slpcall_invite(slpcall, MSN_OBJ_GUID, 1, msnobj_base64); + msn_slpcall_invite(slpcall, MSN_OBJ_GUID, P2P_APPID_OBJ, msnobj_base64); g_free(msnobj_base64); }