changeset 31599:34da321b60f1

Try to hide all P2P fields away behind accessor functions.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Thu, 20 Jan 2011 06:43:45 +0000
parents 19e89f916e69
children 66fe4bda9a85
files libpurple/protocols/msn/msg.c libpurple/protocols/msn/p2p.c libpurple/protocols/msn/p2p.h libpurple/protocols/msn/slpcall.c libpurple/protocols/msn/slplink.c libpurple/protocols/msn/slpmsg.c libpurple/protocols/msn/slpmsg.h libpurple/protocols/msn/slpmsg_part.c libpurple/protocols/msn/slpmsg_part.h
diffstat 9 files changed, 426 insertions(+), 168 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/msg.c	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/msg.c	Thu Jan 20 06:43:45 2011 +0000
@@ -613,15 +613,7 @@
 
 	if (msg->msnslp_message)
 	{
-		g_string_append_printf(str, "Session ID: %u\r\n", msg->part->header->session_id);
-		g_string_append_printf(str, "ID:         %u\r\n", msg->part->header->id);
-		g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", msg->part->header->offset);
-		g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", msg->part->header->total_size);
-		g_string_append_printf(str, "Length:     %u\r\n", msg->part->header->length);
-		g_string_append_printf(str, "Flags:      0x%x\r\n", msg->part->header->flags);
-		g_string_append_printf(str, "ACK ID:     %u\r\n", msg->part->header->ack_id);
-		g_string_append_printf(str, "SUB ID:     %u\r\n", msg->part->header->ack_sub_id);
-		g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", msg->part->header->ack_size);
+		msn_slpmsgpart_to_string(msg->part, str);
 
 		if (purple_debug_is_verbose() && body != NULL)
 		{
@@ -638,27 +630,17 @@
 			else
 			{
 				int i;
-				int bin_len;
 
-				if (msg->part->footer->value == P2P_APPID_SESSION)
-					bin_len = P2P_PACKET_HEADER_SIZE;
-				else
-					bin_len = body_len;
-
-				for (i = 0; i < bin_len; i++)
+				for (i = 0; i < body_len; i++)
 				{
 					g_string_append_printf(str, "%.2hhX ", body[i]);
 					if ((i % 16) == 15)
 						g_string_append(str, "\r\n");
 				}
 
-				if (bin_len == P2P_PACKET_HEADER_SIZE)
-					g_string_append_printf(str, "%s ", body + P2P_PACKET_HEADER_SIZE);
 				g_string_append(str, "\r\n");
 			}
 		}
-
-		g_string_append_printf(str, "Footer:     0x%08X\r\n", msg->part->footer->value);
 	}
 	else
 	{
--- a/libpurple/protocols/msn/p2p.c	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/p2p.c	Thu Jan 20 06:43:45 2011 +0000
@@ -27,12 +27,32 @@
 #include "p2p.h"
 #include "msnutils.h"
 
-MsnP2PHeader *
-msn_p2p_header_from_wire(const char *wire)
+MsnP2PInfo *
+msn_p2p_info_new(void)
+{
+	return g_new0(MsnP2PInfo, 1);
+}
+
+MsnP2PInfo *
+msn_p2p_info_dup(MsnP2PInfo *info)
+{
+	MsnP2PInfo *new_info = g_new0(MsnP2PInfo, 1);
+	*new_info = *info;
+	return new_info;
+}
+
+void
+msn_p2p_info_free(MsnP2PInfo *info)
+{
+	g_free(info);
+}
+
+size_t
+msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire)
 {
 	MsnP2PHeader *header;
 
-	header = g_new(MsnP2PHeader, 1);
+	header = &info->header;
 
 	header->session_id = msn_pop32le(wire);
 	header->id         = msn_pop32le(wire);
@@ -44,15 +64,17 @@
 	header->ack_sub_id = msn_pop32le(wire);
 	header->ack_size   = msn_pop64le(wire);
 
-	return header;
+	return P2P_PACKET_HEADER_SIZE;
 }
 
 char *
-msn_p2p_header_to_wire(MsnP2PHeader *header)
+msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len)
 {
+	MsnP2PHeader *header;
 	char *wire;
 	char *tmp;
 
+	header = &info->header;
 	tmp = wire = g_new(char, P2P_PACKET_HEADER_SIZE);
 
 	msn_push32le(tmp, header->session_id);
@@ -65,35 +87,58 @@
 	msn_push32le(tmp, header->ack_sub_id);
 	msn_push64le(tmp, header->ack_size);
 
+	if (len)
+		*len = P2P_PACKET_HEADER_SIZE;
+
 	return wire;
 
 }
 
-MsnP2PFooter *
-msn_p2p_footer_from_wire(const char *wire)
+size_t
+msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire)
 {
 	MsnP2PFooter *footer;
 
-	footer = g_new(MsnP2PFooter, 1);
+	footer = &info->footer;
 
 	footer->value = msn_pop32be(wire);
 
-	return footer;
+	return P2P_PACKET_FOOTER_SIZE;
 }
 
 char *
-msn_p2p_footer_to_wire(MsnP2PFooter *footer)
+msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len)
 {
+	MsnP2PFooter *footer;
 	char *wire;
 	char *tmp;
 
+	footer = &info->footer;
 	tmp = wire = g_new(char, P2P_PACKET_FOOTER_SIZE);
 
 	msn_push32be(tmp, footer->value);
 
+	if (len)
+		*len = P2P_PACKET_FOOTER_SIZE;
+
 	return wire;
 }
 
+void
+msn_p2p_info_to_string(MsnP2PInfo *info, GString *str)
+{
+	g_string_append_printf(str, "Session ID: %u\r\n", info->header.session_id);
+	g_string_append_printf(str, "ID:         %u\r\n", info->header.id);
+	g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", info->header.offset);
+	g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", info->header.total_size);
+	g_string_append_printf(str, "Length:     %u\r\n", info->header.length);
+	g_string_append_printf(str, "Flags:      0x%x\r\n", info->header.flags);
+	g_string_append_printf(str, "ACK ID:     %u\r\n", info->header.ack_id);
+	g_string_append_printf(str, "SUB ID:     %u\r\n", info->header.ack_sub_id);
+	g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", info->header.ack_size);
+	g_string_append_printf(str, "Footer:     0x%08X\r\n", info->footer.value);
+}
+
 gboolean
 msn_p2p_msg_is_data(const MsnP2PHeaderFlag flags)
 {
@@ -102,3 +147,135 @@
 	        flags == P2P_FILE_DATA);
 }
 
+gboolean
+msn_p2p_info_is_valid(MsnP2PInfo *info)
+{
+	return info->header.total_size >= info->header.length;
+}
+
+gboolean
+msn_p2p_info_is_final(MsnP2PInfo *info)
+{
+	return info->header.offset + info->header.length >= info->header.total_size;
+}
+
+guint32
+msn_p2p_info_get_session_id(MsnP2PInfo *info)
+{
+	return info->header.session_id;
+}
+
+guint32
+msn_p2p_info_get_id(MsnP2PInfo *info)
+{
+	return info->header.id;
+}
+
+guint64
+msn_p2p_info_get_offset(MsnP2PInfo *info)
+{
+	return info->header.offset;
+}
+
+guint64
+msn_p2p_info_get_total_size(MsnP2PInfo *info)
+{
+	return info->header.total_size;
+}
+
+guint32
+msn_p2p_info_get_length(MsnP2PInfo *info)
+{
+	return info->header.length;
+}
+
+guint32
+msn_p2p_info_get_flags(MsnP2PInfo *info)
+{
+	return info->header.flags;
+}
+
+guint32
+msn_p2p_info_get_ack_id(MsnP2PInfo *info)
+{
+	return info->header.ack_id;
+}
+
+guint32
+msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info)
+{
+	return info->header.ack_sub_id;
+}
+
+guint64
+msn_p2p_info_get_ack_size(MsnP2PInfo *info)
+{
+	return info->header.ack_size;
+}
+
+guint32
+msn_p2p_info_get_app_id(MsnP2PInfo *info)
+{
+	return info->footer.value;
+}
+
+void
+msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id)
+{
+	info->header.session_id = session_id;
+}
+
+void
+msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id)
+{
+	info->header.id = id;
+}
+
+void
+msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset)
+{
+	info->header.offset = offset;
+}
+
+void
+msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size)
+{
+	info->header.total_size = total_size;
+}
+
+void
+msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length)
+{
+	info->header.length = length;
+}
+
+void
+msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags)
+{
+	info->header.flags = flags;
+}
+
+void
+msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id)
+{
+	info->header.ack_id = ack_id;
+}
+
+void
+msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id)
+{
+	info->header.ack_sub_id = ack_sub_id;
+}
+
+void
+msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size)
+{
+	info->header.ack_size = ack_size;
+}
+
+void
+msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id)
+{
+	info->footer.value = app_id;
+}
+
--- a/libpurple/protocols/msn/p2p.h	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/p2p.h	Thu Jan 20 06:43:45 2011 +0000
@@ -58,6 +58,11 @@
 } MsnP2PFooter;
 #define P2P_PACKET_FOOTER_SIZE (1 * 4)
 
+typedef struct {
+	MsnP2PHeader header;
+	MsnP2PFooter footer;
+} MsnP2PInfo;
+
 typedef enum
 {
 	P2P_NO_FLAG         = 0x0,        /**< No flags specified */
@@ -88,19 +93,98 @@
 	P2P_APPID_DISPLAY   = 0xC         /**< Display Image */
 } MsnP2PAppId;
 
-MsnP2PHeader *
-msn_p2p_header_from_wire(const char *wire);
+MsnP2PInfo *
+msn_p2p_info_new(void);
+
+MsnP2PInfo *
+msn_p2p_info_dup(MsnP2PInfo *info);
+
+void
+msn_p2p_info_free(MsnP2PInfo *info);
+
+size_t
+msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire);
 
 char *
-msn_p2p_header_to_wire(MsnP2PHeader *header);
+msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len);
 
-MsnP2PFooter *
-msn_p2p_footer_from_wire(const char *wire);
+size_t
+msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire);
 
 char *
-msn_p2p_footer_to_wire(MsnP2PFooter *footer);
+msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len);
+
+void
+msn_p2p_info_to_string(MsnP2PInfo *info, GString *str);
 
 gboolean
 msn_p2p_msg_is_data(const MsnP2PHeaderFlag flags);
 
+gboolean
+msn_p2p_info_is_valid(MsnP2PInfo *info);
+
+gboolean
+msn_p2p_info_is_final(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_session_id(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_id(MsnP2PInfo *info);
+
+guint64
+msn_p2p_info_get_offset(MsnP2PInfo *info);
+
+guint64
+msn_p2p_info_get_total_size(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_length(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_flags(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_ack_id(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info);
+
+guint64
+msn_p2p_info_get_ack_size(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_app_id(MsnP2PInfo *info);
+
+void
+msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id);
+
+void
+msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id);
+
+void
+msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset);
+
+void
+msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size);
+
+void
+msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length);
+
+void
+msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags);
+
+void
+msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id);
+
+void
+msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id);
+
+void
+msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size);
+
+void
+msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id);
+
 #endif /* MSN_P2P_H */
+
--- a/libpurple/protocols/msn/slpcall.c	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Thu Jan 20 06:43:45 2011 +0000
@@ -1059,16 +1059,21 @@
 	MsnSlpCall *slpcall;
 	const guchar *body;
 	gsize body_len;
+	guint32 session_id;
+	guint32 flags;
 
 	slpcall = NULL;
 	body = slpmsg->buffer;
-	body_len = slpmsg->header->offset;
+	body_len = msn_p2p_info_get_offset(slpmsg->p2p_info);
 
-	if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP)
+	session_id = msn_p2p_info_get_session_id(slpmsg->p2p_info);
+	flags = msn_p2p_info_get_flags(slpmsg->p2p_info);
+
+	if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP)
 	{
 		char *body_str;
 
-		if (slpmsg->header->session_id == 64)
+		if (session_id == 64)
 		{
 			/* This is for handwritten messages (Ink) */
 			GError *error = NULL;
@@ -1125,9 +1130,9 @@
 		}
 		g_free(body_str);
 	}
-	 else if (msn_p2p_msg_is_data(slpmsg->header->flags))
+	 else if (msn_p2p_msg_is_data(flags))
 	{
-		slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->header->session_id);
+		slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
 
 		if (slpcall != NULL)
 		{
@@ -1142,13 +1147,13 @@
 			slpcall->wasted = TRUE;
 		}
 	}
-	else if (slpmsg->header->flags == P2P_ACK)
+	else if (flags == P2P_ACK)
 	{
 		/* Acknowledgement of previous message. Don't do anything currently. */
 	}
 	else
 		purple_debug_warning("msn", "Unprocessed SLP message with flags 0x%04x\n",
-		                     slpmsg->header->flags);
+		                     flags);
 
 	return slpcall;
 }
--- a/libpurple/protocols/msn/slplink.c	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/slplink.c	Thu Jan 20 06:43:45 2011 +0000
@@ -281,17 +281,21 @@
 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
 {
 	MsnSlpMessagePart *part;
+	MsnP2PInfo *info;
 	long long real_size;
 	size_t len = 0;
+	guint64 offset;
 
 	/* Maybe we will want to create a new msg for this slpmsg instead of
 	 * reusing the same one all the time. */
-	part = msn_slpmsgpart_new(slpmsg->header, slpmsg->footer);
+	info = slpmsg->p2p_info;
+	part = msn_slpmsgpart_new(info);
 	part->ack_data = slpmsg;
 
-	real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size;
+	real_size = (msn_p2p_info_get_flags(info) == P2P_ACK) ? 0 : slpmsg->size;
 
-	if (slpmsg->header->offset < real_size)
+	offset = msn_p2p_info_get_offset(info);
+	if (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)
@@ -301,15 +305,15 @@
 		}
 		else
 		{
-			len = slpmsg->size - slpmsg->header->offset;
+			len = slpmsg->size - offset;
 
 			if (len > MSN_SBCONN_MAX_SIZE)
 				len = MSN_SBCONN_MAX_SIZE;
 
-			msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + slpmsg->header->offset, len);
+			msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + offset, len);
 		}
 
-		slpmsg->header->length = len;
+		msn_p2p_info_set_length(slpmsg->p2p_info, len);
 	}
 
 #if 0
@@ -326,7 +330,7 @@
 	msn_slplink_send_part(slplink, part);
 
 
-	if (msn_p2p_msg_is_data(slpmsg->header->flags) &&
+	if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(info)) &&
 		(slpmsg->slpcall != NULL))
 	{
 		slpmsg->slpcall->progress = TRUE;
@@ -334,7 +338,7 @@
 		if (slpmsg->slpcall->progress_cb != NULL)
 		{
 			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
-										 len, slpmsg->header->offset);
+										 len, offset);
 		}
 	}
 
@@ -344,27 +348,30 @@
 static void
 msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
 {
-	slpmsg = slpmsg;
-	slpmsg->footer = g_new0(MsnP2PFooter, 1);
+	MsnP2PInfo *info;
+	guint32 flags;
+
+	info = slpmsg->p2p_info;
 
-	if (slpmsg->header->flags == P2P_NO_FLAG)
+	flags = msn_p2p_info_get_flags(info);
+	if (flags == P2P_NO_FLAG)
 	{
-		slpmsg->header->ack_id = rand() % 0xFFFFFF00;
+		msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00);
 	}
-	else if (msn_p2p_msg_is_data(slpmsg->header->flags))
+	else if (msn_p2p_msg_is_data(flags))
 	{
 		MsnSlpCall *slpcall;
 		slpcall = slpmsg->slpcall;
 
 		g_return_if_fail(slpcall != NULL);
-		slpmsg->header->session_id = slpcall->session_id;
-		slpmsg->footer->value = slpcall->app_id;
-		slpmsg->header->ack_id = rand() % 0xFFFFFF00;
+		msn_p2p_info_set_session_id(info, slpcall->session_id);
+		msn_p2p_info_set_app_id(info, slpcall->app_id);
+		msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00);
 	}
 
-	slpmsg->header->id = slpmsg->id;
+	msn_p2p_info_set_id(info, slpmsg->id);
 
-	slpmsg->header->total_size = slpmsg->size;
+	msn_p2p_info_set_total_size(info, slpmsg->size);
 
 	msn_slplink_send_msgpart(slplink, slpmsg);
 }
@@ -400,20 +407,20 @@
 }
 
 static MsnSlpMessage *
-msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PHeader *header)
+msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PInfo *info)
 {
 	MsnSlpMessage *slpmsg;
 
-	slpmsg = msn_slpmsg_ack_new(header);
+	slpmsg = msn_slpmsg_ack_new(info);
 	msn_slpmsg_set_slplink(slpmsg, slplink);
 
 	return slpmsg;
 }
 
 static void
-msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PHeader *header)
+msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PInfo *info)
 {
-	MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, header);
+	MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, info);
 
 	msn_slplink_send_slpmsg(slplink, slpmsg);
 	msn_slpmsg_destroy(slpmsg);
@@ -428,7 +435,7 @@
 	{
 		MsnSlpMessage *slpmsg = e->data;
 
-		if ((slpmsg->header->session_id == session_id) && (slpmsg->id == id))
+		if ((msn_p2p_info_get_session_id(slpmsg->p2p_info) == session_id) && (slpmsg->id == id))
 			return slpmsg;
 	}
 
@@ -436,22 +443,26 @@
 }
 
 static MsnSlpMessage *
-init_first_msg(MsnSlpLink *slplink, MsnP2PHeader *header)
+init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info)
 {
 	MsnSlpMessage *slpmsg;
+	guint32 session_id;
+	guint32 flags;
 
 	slpmsg = msn_slpmsg_new(slplink);
-	slpmsg->id = header->id;
-	slpmsg->header->session_id = header->session_id;
-	slpmsg->size = header->total_size;
-	slpmsg->header->flags = header->flags;
+	slpmsg->id = msn_p2p_info_get_id(info);
+	session_id = msn_p2p_info_get_session_id(info);
+	msn_p2p_info_set_session_id(slpmsg->p2p_info, session_id);
+	slpmsg->size = msn_p2p_info_get_total_size(info);
+	flags = msn_p2p_info_get_flags(info);
+	msn_p2p_info_set_flags(slpmsg->p2p_info, flags);
 
-	if (slpmsg->header->session_id)
+	if (session_id)
 	{
-		slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->header->session_id);
+		slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
 		if (slpmsg->slpcall != NULL)
 		{
-			if (msn_p2p_msg_is_data(header->flags))
+			if (msn_p2p_msg_is_data(flags))
 			{
 				PurpleXfer *xfer = slpmsg->slpcall->xfer;
 				if (xfer != NULL)
@@ -488,9 +499,10 @@
 }
 
 static void
-process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PHeader *header)
+process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PInfo *info)
 {
 	MsnSlpCall *slpcall;
+	guint32 flags;
 
 	slpcall = msn_slp_process_msg(slplink, slpmsg);
 
@@ -501,8 +513,10 @@
 
 	purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n");
 
-	if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP ||
-			msn_p2p_msg_is_data(slpmsg->header->flags))
+	flags = msn_p2p_info_get_flags(slpmsg->p2p_info);
+
+	if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP ||
+	    msn_p2p_msg_is_data(flags))
 	{
 		/* Release all the messages and send the ACK */
 
@@ -515,11 +529,11 @@
 			 */
 			purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n");
 
-			slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header);
+			slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, info);
 		} else if (!slpcall->wasted) {
 			purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n");
 
-			msn_slplink_send_ack(slplink, header);
+			msn_slplink_send_ack(slplink, info);
 			msn_slplink_send_queued_slpmsgs(slplink);
 		}
 	}
@@ -539,16 +553,17 @@
 		purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
 	}
 	else if (slpmsg->size && slpmsg->buffer) {
-		if (G_MAXSIZE - part->size < part->header->offset
-				|| (part->header->offset + part->size) > slpmsg->size
-				|| slpmsg->header->offset != part->header->offset) {
+		guint64 offset = msn_p2p_info_get_offset(part->info);
+		if (G_MAXSIZE - part->size < offset
+				|| (offset + part->size) > slpmsg->size
+				|| msn_p2p_info_get_offset(slpmsg->p2p_info) != offset) {
 			purple_debug_error("msn",
 				"Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
-				slpmsg->size, part->header->offset, part->size);
+				slpmsg->size, offset, part->size);
 			g_return_if_reached();
 		} else {
-			memcpy(slpmsg->buffer + part->header->offset, part->buffer, part->size);
-			slpmsg->header->offset += part->size;
+			memcpy(slpmsg->buffer + offset, part->buffer, part->size);
+			msn_p2p_info_set_offset(slpmsg->p2p_info, offset + part->size);
 		}
 	}
 }
@@ -557,12 +572,12 @@
 msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpMessagePart *part)
 {
 	MsnSlpMessage *slpmsg;
-	MsnP2PHeader *header;
+	MsnP2PInfo *info;
 	guint64 offset;
 
-	header = part->header;
+	info = part->info;
 
-	if (header->total_size < header->length)
+	if (!msn_p2p_info_is_valid(info))
 	{
 		/* We seem to have received a bad header */
 		purple_debug_warning("msn", "Total size listed in SLP binary header "
@@ -571,12 +586,15 @@
 		return;
 	}
 
-	offset = header->offset;
+	offset = msn_p2p_info_get_offset(info);
 
 	if (offset == 0)
-		slpmsg = init_first_msg(slplink, header);
+		slpmsg = init_first_msg(slplink, info);
 	else {
-		slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id);
+		guint32 session_id, id;
+		session_id = msn_p2p_info_get_session_id(info);
+		id = msn_p2p_info_get_id(info);
+		slpmsg = msn_slplink_message_find(slplink, session_id, id);
 		if (slpmsg == NULL)
 		{
 			/* Probably the transfer was cancelled */
@@ -587,8 +605,7 @@
 
 	slpmsg_add_part(slpmsg, part);
 
-
-	if (msn_p2p_msg_is_data(slpmsg->header->flags) &&
+	if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(slpmsg->p2p_info)) &&
 		(slpmsg->slpcall != NULL))
 	{
 		slpmsg->slpcall->progress = TRUE;
@@ -606,8 +623,8 @@
 #endif
 
 	/* All the pieces of the slpmsg have been received */
-	if (header->offset + header->length >= header->total_size)
-		process_complete_msg(slplink, slpmsg, header);
+	if (msn_p2p_info_is_final(info))
+		process_complete_msg(slplink, slpmsg, info);
 
 	/* NOTE: The slpmsg will be destroyed in process_complete_msg or left in
 	   the slplink until fully received. Don't free it here!
--- a/libpurple/protocols/msn/slpmsg.c	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg.c	Thu Jan 20 06:43:45 2011 +0000
@@ -48,8 +48,7 @@
 	else
 		slpmsg->slplink = NULL;
 
-	slpmsg->header = g_new0(MsnP2PHeader, 1);
-	slpmsg->footer = NULL;
+	slpmsg->p2p_info = msn_p2p_info_new();
 
 	return slpmsg;
 }
@@ -90,8 +89,7 @@
 
 	slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg);
 
-	g_free(slpmsg->header);
-	g_free(slpmsg->footer);
+	msn_p2p_info_free(slpmsg->p2p_info);
 
 	g_free(slpmsg);
 }
@@ -200,18 +198,20 @@
 	return slpmsg;
 }
 
-MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PHeader *header)
+MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PInfo *ack_info)
 {
 	MsnSlpMessage *slpmsg;
+	MsnP2PInfo *new_info;
 
 	slpmsg = msn_slpmsg_new(NULL);
 
-	slpmsg->header->session_id = header->session_id;
-	slpmsg->size       = header->total_size;
-	slpmsg->header->flags      = P2P_ACK;
-	slpmsg->header->ack_id     = header->id;
-	slpmsg->header->ack_sub_id = header->ack_id;
-	slpmsg->header->ack_size   = header->total_size;
+	new_info = slpmsg->p2p_info;
+	msn_p2p_info_set_session_id(new_info, msn_p2p_info_get_session_id(ack_info));
+	slpmsg->size = msn_p2p_info_get_total_size(ack_info);
+	msn_p2p_info_set_flags(new_info, P2P_ACK);
+	msn_p2p_info_set_ack_id(new_info, msn_p2p_info_get_id(ack_info));
+	msn_p2p_info_set_ack_sub_id(new_info, msn_p2p_info_get_ack_id(ack_info));
+	msn_p2p_info_set_ack_size(new_info, msn_p2p_info_get_total_size(ack_info));
 	slpmsg->info = "SLP ACK";
 
 	return slpmsg;
@@ -223,7 +223,7 @@
 
 	slpmsg = msn_slpmsg_new(NULL);
 	slpmsg->slpcall = slpcall;
-	slpmsg->header->flags = P2P_MSN_OBJ_DATA;
+	msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_MSN_OBJ_DATA);
 	slpmsg->info = "SLP DATA";
 
 	msn_slpmsg_set_image(slpmsg, img);
@@ -238,7 +238,7 @@
 	slpmsg = msn_slpmsg_new(NULL);
 
 	slpmsg->slpcall = slpcall;
-	slpmsg->header->session_id = slpcall->session_id;
+	msn_p2p_info_set_session_id(slpmsg->p2p_info, slpcall->session_id);
 	msn_slpmsg_set_body(slpmsg, NULL, 4);
 	slpmsg->info = "SLP DATA PREP";
 
@@ -253,7 +253,7 @@
 	slpmsg = msn_slpmsg_new(NULL);
 
 	slpmsg->slpcall = slpcall;
-	slpmsg->header->flags = P2P_FILE_DATA;
+	msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_FILE_DATA);
 	slpmsg->info = "SLP FILE";
 	slpmsg->size = size;
 
@@ -266,27 +266,25 @@
 	char *footer;
 	char *base;
 	char *tmp;
-	size_t siz;
+	size_t header_size, footer_size;
 
-	base = g_malloc(P2P_PACKET_HEADER_SIZE + slpmsg->size + P2P_PACKET_FOOTER_SIZE);
+	header = msn_p2p_header_to_wire(slpmsg->p2p_info, &header_size);
+	footer = msn_p2p_footer_to_wire(slpmsg->p2p_info, &footer_size);
+
+	base = g_malloc(header_size + slpmsg->size + footer_size);
 	tmp = base;
 
-	header = msn_p2p_header_to_wire(slpmsg->header);
-	footer = msn_p2p_footer_to_wire(slpmsg->footer);
-
-	siz = P2P_PACKET_HEADER_SIZE;
 	/* Copy header */
-	memcpy(tmp, header, siz);
-	tmp += siz;
+	memcpy(tmp, header, header_size);
+	tmp += header_size;
 
 	/* Copy body */
 	memcpy(tmp, slpmsg->buffer, slpmsg->size);
 	tmp += slpmsg->size;
 
 	/* Copy footer */
-	siz = P2P_PACKET_FOOTER_SIZE;
-	memcpy(tmp, footer, siz);
-	tmp += siz;
+	memcpy(tmp, footer, footer_size);
+	tmp += footer_size;
 
 	*ret_size = tmp - base;
 
@@ -302,15 +300,7 @@
 
 	str = g_string_new(NULL);
 
-	g_string_append_printf(str, "Session ID: %u\r\n", slpmsg->header->session_id);
-	g_string_append_printf(str, "ID:         %u\r\n", slpmsg->header->id);
-	g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", slpmsg->header->offset);
-	g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->total_size);
-	g_string_append_printf(str, "Length:     %u\r\n", slpmsg->header->length);
-	g_string_append_printf(str, "Flags:      0x%x\r\n", slpmsg->header->flags);
-	g_string_append_printf(str, "ACK ID:     %u\r\n", slpmsg->header->ack_id);
-	g_string_append_printf(str, "SUB ID:     %u\r\n", slpmsg->header->ack_sub_id);
-	g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", slpmsg->header->ack_size);
+	msn_p2p_info_to_string(slpmsg->p2p_info, str);
 
 	if (purple_debug_is_verbose() && slpmsg->buffer != NULL) {
 		g_string_append_len(str, (gchar*)slpmsg->buffer, slpmsg->size);
@@ -323,7 +313,5 @@
 
 	}
 
-	g_string_append_printf(str, "Footer:     %u\r\n", slpmsg->footer->value);
-
 	purple_debug_info("msn", "SlpMessage %s:\n{%s}\n", slpmsg->info, str->str);
 }
--- a/libpurple/protocols/msn/slpmsg.h	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg.h	Thu Jan 20 06:43:45 2011 +0000
@@ -45,8 +45,7 @@
 	MsnSlpLink *slplink; /**< The slplink through which this slp message is being sent. */
 	MsnSession *session;
 
-	MsnP2PHeader *header;
-	MsnP2PFooter *footer;
+	MsnP2PInfo *p2p_info;
 
 	long id;
 
@@ -105,7 +104,7 @@
  *
  * @return A new SlpMessage with ACK headers
  */
-MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PHeader *header);
+MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PInfo *info);
 
 /**
  * Create a new SLP message for MsnObject data.
--- a/libpurple/protocols/msn/slpmsg_part.c	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg_part.c	Thu Jan 20 06:43:45 2011 +0000
@@ -28,20 +28,14 @@
 #include "slpmsg.h"
 #include "slpmsg_part.h"
 
-MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer)
+MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info)
 {
 	MsnSlpMessagePart *part;
 
 	part = g_new0(MsnSlpMessagePart, 1);
 
-	if (header) {
-		part->header = g_new0(MsnP2PHeader, 1);
-		*part->header = *header;
-	}
-	if (footer) {
-		part->footer = g_new0(MsnP2PFooter, 1);
-		*part->footer = *footer;
-	}
+	if (info)
+		part->info = msn_p2p_info_dup(info);
 
 	part->ack_cb = msn_slpmsgpart_ack;
 	part->nak_cb = msn_slpmsgpart_nak;
@@ -52,20 +46,22 @@
 MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len)
 {
 	MsnSlpMessagePart *part;
+	size_t len;
 	int body_len;
 
 	if (data_len < P2P_PACKET_HEADER_SIZE) {
 		return NULL;
 	}
 
-	part = msn_slpmsgpart_new(NULL, NULL);
+	part = msn_slpmsgpart_new(NULL);
+	part->info = msn_p2p_info_new();
 
 	/* Extract the binary SLP header */
-	part->header = msn_p2p_header_from_wire(data);
-	data += P2P_PACKET_HEADER_SIZE;
+	len = msn_p2p_header_from_wire(part->info, data);
+	data += len;
 
 	/* Extract the body */
-	body_len = data_len - P2P_PACKET_HEADER_SIZE - P2P_PACKET_FOOTER_SIZE;
+	body_len = data_len - len - P2P_PACKET_FOOTER_SIZE;
 	/* msg->body_len = msg->msnslp_header.length; */
 
 	if (body_len > 0) {
@@ -77,15 +73,14 @@
 
 	/* Extract the footer */
 	if (body_len >= 0)
-		part->footer = msn_p2p_footer_from_wire(data);
+		msn_p2p_footer_from_wire(part->info, data);
 
 	return part;
 }
 
 static void msn_slpmsgpart_destroy(MsnSlpMessagePart *part)
 {
-	g_free(part->header);
-	g_free(part->footer);
+	g_free(part->info);
 	g_free(part->buffer);
 
 	g_free(part);
@@ -142,27 +137,25 @@
 	char *footer;
 	char *base;
 	char *tmp;
-	size_t siz;
+	size_t header_size, footer_size;
 
-	base = g_malloc(P2P_PACKET_HEADER_SIZE + part->size + P2P_PACKET_FOOTER_SIZE);
+	header = msn_p2p_header_to_wire(part->info, &header_size);
+	footer = msn_p2p_footer_to_wire(part->info, &footer_size);
+
+	base = g_malloc(header_size + part->size + footer_size);
 	tmp = base;
 
-	header = msn_p2p_header_to_wire(part->header);
-	footer = msn_p2p_footer_to_wire(part->footer);
-
-	siz = P2P_PACKET_HEADER_SIZE;
 	/* Copy header */
-	memcpy(tmp, header, siz);
-	tmp += siz;
+	memcpy(tmp, header, header_size);
+	tmp += header_size;
 
 	/* Copy body */
 	memcpy(tmp, part->buffer, part->size);
 	tmp += part->size;
 
 	/* Copy footer */
-	siz = P2P_PACKET_FOOTER_SIZE;
-	memcpy(tmp, footer, siz);
-	tmp += siz;
+	memcpy(tmp, footer, footer_size);
+	tmp += footer_size;
 
 	*ret_size = tmp - base;
 
@@ -171,23 +164,27 @@
 
 	return base;
 }
+
 /* We have received the message ack */
 void
 msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data)
 {
 	MsnSlpMessage *slpmsg;
+	guint64 offset;
 	long long real_size;
 
 	slpmsg = data;
 
-	real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size;
+	real_size = (msn_p2p_info_get_flags(slpmsg->p2p_info) == P2P_ACK) ? 0 : slpmsg->size;
 
-	slpmsg->header->offset += part->header->length;
+	offset = msn_p2p_info_get_offset(slpmsg->p2p_info);
+	offset += msn_p2p_info_get_length(part->info);
+	msn_p2p_info_set_offset(slpmsg->p2p_info, offset);
 
 	slpmsg->parts = g_list_remove(slpmsg->parts, part);
 	msn_slpmsgpart_unref(part);
 
-	if (slpmsg->header->offset < real_size)
+	if (offset < real_size)
 	{
 		if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
 		{
@@ -200,7 +197,7 @@
 	else
 	{
 		/* The whole message has been sent */
-		if (msn_p2p_msg_is_data(slpmsg->header->flags))
+		if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(slpmsg->p2p_info)))
 		{
 			if (slpmsg->slpcall != NULL)
 			{
@@ -226,3 +223,9 @@
 	msn_slpmsgpart_unref(part);
 }
 
+void
+msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str)
+{
+	msn_p2p_info_to_string(part->info, str);
+}
+
--- a/libpurple/protocols/msn/slpmsg_part.h	Thu Jan 20 06:41:34 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg_part.h	Thu Jan 20 06:43:45 2011 +0000
@@ -34,8 +34,7 @@
 {
 	guint ref_count;
 
-	MsnP2PHeader *header;
-	MsnP2PFooter *footer;
+	MsnP2PInfo *info;
 
 	MsnSlpPartCb ack_cb;
 	MsnSlpPartCb nak_cb;
@@ -45,7 +44,7 @@
 	size_t size;
 };
 
-MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer);
+MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info);
 
 MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len);
 
@@ -60,4 +59,8 @@
 void msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data);
 
 void msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data);
+
+void msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str);
+
 #endif /* MSN_SLPMSG_PART_H */
+