changeset 6868:ab80de7a74d1

[gaim-migrate @ 7414] Commitinating the current MSNSLP code. It's not working.. I don't know why. No clients will respond to my messages, even though they appear very valid. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Wed, 17 Sep 2003 02:10:37 +0000
parents 1c4e4c725e0d
children 7ec9c81dfe72
files src/protocols/msn/msg.c src/protocols/msn/msg.h src/protocols/msn/msnslp.c src/protocols/msn/msnslp.h src/protocols/msn/switchboard.c
diffstat 5 files changed, 314 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/msn/msg.c	Wed Sep 17 01:50:15 2003 +0000
+++ b/src/protocols/msn/msg.c	Wed Sep 17 02:10:37 2003 +0000
@@ -98,6 +98,35 @@
 	msg->msnslp_message = TRUE;
 	msg->size += 52;
 
+	msn_message_set_flag(msg, 'D');
+	msn_message_set_content_type(msg, "application/x-msnmsgrp2p");
+	msn_message_set_charset(msg, NULL);
+
+	return msg;
+}
+
+MsnMessage *
+msn_message_new_msnslp_ack(MsnMessage *acked_msg)
+{
+	MsnMessage *msg;
+
+	g_return_val_if_fail(acked_msg != NULL, NULL);
+	g_return_val_if_fail(acked_msg->msnslp_message, NULL);
+
+	msg = msn_message_new_msnslp();
+
+	msg->msnslp_ack_message = TRUE;
+	msg->acked_msg = msn_message_ref(acked_msg);
+
+	msg->msnslp_header.session_id     = acked_msg->msnslp_header.session_id;
+	msg->msnslp_header.total_size_1   = acked_msg->msnslp_header.total_size_1;
+	msg->msnslp_header.total_size_2   = acked_msg->msnslp_header.total_size_2;
+	msg->msnslp_header.flags          = 0x02;
+	msg->msnslp_header.ack_session_id = acked_msg->msnslp_header.session_id;
+	msg->msnslp_header.ack_unique_id  = acked_msg->msnslp_header.ack_session_id;
+	msg->msnslp_header.ack_length_1   = acked_msg->msnslp_header.total_size_1;
+	msg->msnslp_header.ack_length_2   = acked_msg->msnslp_header.total_size_2;
+
 	return msg;
 }
 
@@ -219,20 +248,26 @@
 		/* Import the header. */
 		msg->msnslp_header.session_id     = msn_get32(tmp); tmp += 4;
 		msg->msnslp_header.id             = msn_get32(tmp); tmp += 4;
-		msg->msnslp_header.offset         = msn_get32(tmp); tmp += 8;
-		msg->msnslp_header.total_size     = msn_get32(tmp); tmp += 8;
+		msg->msnslp_header.offset_1       = msn_get32(tmp); tmp += 4;
+		msg->msnslp_header.offset_2       = msn_get32(tmp); tmp += 4;
+		msg->msnslp_header.total_size_1   = msn_get32(tmp); tmp += 4;
+		msg->msnslp_header.total_size_2   = msn_get32(tmp); tmp += 4;
 		msg->msnslp_header.length         = msn_get32(tmp); tmp += 4;
 		msg->msnslp_header.flags          = msn_get32(tmp); tmp += 4;
 		msg->msnslp_header.ack_session_id = msn_get32(tmp); tmp += 4;
 		msg->msnslp_header.ack_unique_id  = msn_get32(tmp); tmp += 4;
-		msg->msnslp_header.ack_length     = msn_get32(tmp); tmp += 8;
+		msg->msnslp_header.ack_length_1   = msn_get32(tmp); tmp += 4;
+		msg->msnslp_header.ack_length_2   = msn_get32(tmp); tmp += 4;
 
 		/* Convert to the right endianness */
 		msg->msnslp_header.session_id = ntohl(msg->msnslp_header.session_id);
 		msg->msnslp_header.id         = ntohl(msg->msnslp_header.id);
 		msg->msnslp_header.length     = ntohl(msg->msnslp_header.length);
 		msg->msnslp_header.flags      = ntohl(msg->msnslp_header.flags);
-		msg->msnslp_header.ack_length = ntohl(msg->msnslp_header.ack_length);
+		msg->msnslp_header.ack_length_1 =
+			ntohl(msg->msnslp_header.ack_length_1);
+		msg->msnslp_header.ack_length_2 =
+			ntohl(msg->msnslp_header.ack_length_2);
 		msg->msnslp_header.ack_session_id =
 			ntohl(msg->msnslp_header.ack_session_id);
 		msg->msnslp_header.ack_unique_id =
@@ -282,6 +317,9 @@
 	g_hash_table_destroy(msg->attr_table);
 	g_list_free(msg->attr_list);
 
+	if (msg->msnslp_ack_message)
+		msn_message_unref(msg->acked_msg);
+
 	gaim_debug(GAIM_DEBUG_INFO, "msn", "Destroying message\n");
 	g_free(msg);
 }
@@ -319,7 +357,6 @@
 msn_message_to_string(const MsnMessage *msg, size_t *ret_size)
 {
 	GList *l;
-	const char *body;
 	char *msg_start;
 	char *str;
 	char buf[MSN_BUF_LEN];
@@ -336,8 +373,6 @@
 	 */
 	g_return_val_if_fail(msg != NULL, NULL);
 
-	body = msn_message_get_body(msg);
-
 	if (msn_message_is_incoming(msg)) {
 		MsnUser *sender = msn_message_get_sender(msg);
 
@@ -391,42 +426,63 @@
 	if (msg->msnslp_message)
 	{
 		char *c;
-		long session_id, id, offset, total_size, length, flags;
-		long ack_session_id, ack_unique_id, ack_length;
+		long session_id, id, offset_1, offset_2, total_size_1, total_size_2;
+		long length, flags;
+		long ack_session_id, ack_unique_id, ack_length_1, ack_length_2;
 
 		c = str + strlen(str);
 
 		session_id      = htonl(msg->msnslp_header.session_id);
 		id              = htonl(msg->msnslp_header.id);
-		offset          = htonl(msg->msnslp_header.offset);
-		total_size      = htonl(msg->msnslp_header.total_size);
+		offset_1        = htonl(msg->msnslp_header.offset_1);
+		offset_2        = htonl(msg->msnslp_header.offset_2);
+		total_size_1    = htonl(msg->msnslp_header.total_size_1);
+		total_size_2    = htonl(msg->msnslp_header.total_size_2);
 		length          = htonl(msg->msnslp_header.length);
 		flags           = htonl(msg->msnslp_header.flags);
 		ack_session_id  = htonl(msg->msnslp_header.ack_session_id);
 		ack_unique_id   = htonl(msg->msnslp_header.ack_unique_id);
-		ack_length      = htonl(msg->msnslp_header.ack_length);
+		ack_length_1    = htonl(msg->msnslp_header.ack_length_1);
+		ack_length_2    = htonl(msg->msnslp_header.ack_length_2);
 
 		c += msn_put32(c, session_id);
 		c += msn_put32(c, id);
-		c += msn_put32(c, offset);
-		c += msn_put32(c, 0);
-		c += msn_put32(c, total_size);
-		c += msn_put32(c, 0);
+		c += msn_put32(c, offset_1);
+		c += msn_put32(c, offset_2);
+		c += msn_put32(c, total_size_1);
+		c += msn_put32(c, total_size_2);
 		c += msn_put32(c, length);
 		c += msn_put32(c, flags);
 		c += msn_put32(c, ack_session_id);
 		c += msn_put32(c, ack_unique_id);
-		c += msn_put32(c, ack_length);
-		c += msn_put32(c, 0);
+		c += msn_put32(c, ack_length_1);
+		c += msn_put32(c, ack_length_2);
 
-		if (body != NULL)
+		if (msg->bin_content)
 		{
-			g_strlcpy(c, body, msg->size - (c - msg_start));
+			size_t bin_len;
+			const void *body = msn_message_get_bin_data(msg, &bin_len);
+
+			if (body != NULL)
+			{
+				memcpy(c, body, msg->size - (c - msg_start));
 
-			c += strlen(body);
+				c += bin_len;
+			}
+		}
+		else
+		{
+			const char *body = msn_message_get_body(msg);
 
-			if (strlen(body) > 0)
-				*c++ = '\0';
+			if (body != NULL)
+			{
+				g_strlcpy(c, body, msg->size - (c - msg_start));
+
+				c += strlen(body);
+
+				if (strlen(body) > 0)
+					*c++ = '\0';
+			}
 		}
 
 		c += msn_put32(c, msg->msnslp_footer.app_id);
@@ -440,6 +496,8 @@
 	}
 	else
 	{
+		const char *body = msn_message_get_body(msg);
+
 		g_strlcat(str, body, len);
 
 		if (msg->size != strlen(msg_start)) {
@@ -498,6 +556,9 @@
 
 	msg->receiver = user;
 
+	if (msg->msnslp_message)
+		msn_message_set_attr(msg, "P2P-Dest", msn_user_get_passport(user));
+
 	msn_user_ref(msg->receiver);
 }
 
@@ -552,7 +613,9 @@
 	size_t new_len;
 
 	g_return_if_fail(msg  != NULL);
-	g_return_if_fail(body != NULL);
+
+	if (msg->bin_content)
+		msn_message_set_bin_data(msg, NULL, 0);
 
 	if (msg->body != NULL) {
 		msg->size -= strlen(msg->body);
@@ -562,36 +625,86 @@
 			msg->size--;
 	}
 
-	for (c = body; *c != '\0'; c++) {
-		if (*c == '\n' && (c == body || *(c - 1) != '\r'))
-			newline_count++;
-	}
+	if (body != NULL)
+	{
+		for (c = body; *c != '\0'; c++)
+		{
+			if (*c == '\n' && (c == body || *(c - 1) != '\r'))
+				newline_count++;
+		}
 
-	new_len = strlen(body) + newline_count;
+		new_len = strlen(body) + newline_count;
 
-	buf = g_new0(char, new_len + 1);
+		buf = g_new0(char, new_len + 1);
 
-	for (c = body, d = buf; *c != '\0'; c++) {
-		if (*c == '\n' && (c == body || *(c - 1) != '\r')) {
-			*d++ = '\r';
-			*d++ = '\n';
+		for (c = body, d = buf; *c != '\0'; c++) {
+			if (*c == '\n' && (c == body || *(c - 1) != '\r')) {
+				*d++ = '\r';
+				*d++ = '\n';
+			}
+			else
+				*d++ = *c;
 		}
-		else
-			*d++ = *c;
+
+		msg->body = buf;
+		msg->size += new_len;
+
+		msg->bin_content = FALSE;
+
+		if (msg->msnslp_message)
+			msg->size++;
 	}
-
-	msg->body = buf;
-
-	msg->size += new_len;
-
-	if (msg->msnslp_message)
-		msg->size++;
+	else
+		msg->body = NULL;
 }
 
 const char *
 msn_message_get_body(const MsnMessage *msg)
 {
 	g_return_val_if_fail(msg != NULL, NULL);
+	g_return_val_if_fail(!msg->bin_content, NULL);
+
+	return msg->body;
+}
+
+void
+msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len)
+{
+	g_return_if_fail(msg != NULL);
+
+	if (!msg->bin_content)
+		msn_message_set_body(msg, NULL);
+
+	msg->bin_content = TRUE;
+
+	if (msg->body != NULL)
+	{
+		msg->size -= msg->bin_len;
+		g_free(msg->body);
+	}
+
+	if (data != NULL && len > 0)
+	{
+		msg->body = g_memdup(data, len);
+		msg->bin_len = len;
+
+		msg->size += len;
+	}
+	else
+	{
+		msg->body = NULL;
+		msg->bin_len = 0;
+	}
+}
+
+const void *
+msn_message_get_bin_data(const MsnMessage *msg, size_t *len)
+{
+	g_return_val_if_fail(msg != NULL, NULL);
+	g_return_val_if_fail(len != NULL, NULL);
+	g_return_val_if_fail(msg->bin_content, NULL);
+
+	*len = msg->bin_len;
 
 	return msg->body;
 }
--- a/src/protocols/msn/msg.h	Wed Sep 17 01:50:15 2003 +0000
+++ b/src/protocols/msn/msg.h	Wed Sep 17 02:10:37 2003 +0000
@@ -31,13 +31,16 @@
 {
 	long session_id;
 	long id;
-	long offset;
-	long total_size;
+	long offset_1;
+	long offset_2;
+	long total_size_1;
+	long total_size_2;
 	long length;
 	long flags;
 	long ack_session_id;
 	long ack_unique_id;
-	long ack_length;
+	long ack_length_1;
+	long ack_length_2;
 
 } MsnSlpHeader;
 
@@ -55,6 +58,7 @@
 	size_t ref_count;           /**< The reference count.       */
 
 	gboolean msnslp_message;
+	gboolean msnslp_ack_message;
 
 	MsnUser *sender;
 	MsnUser *receiver;
@@ -66,12 +70,17 @@
 
 	size_t size;
 
+	gboolean bin_content;
+
 	char *content_type;
 	char *charset;
 	char *body;
+	size_t bin_len;
 
 	MsnSlpHeader msnslp_header;
 	MsnSlpFooter msnslp_footer;
+	
+	MsnMessage *acked_msg;
 
 	GHashTable *attr_table;
 	GList *attr_list;
@@ -94,6 +103,15 @@
 MsnMessage *msn_message_new_msnslp(void);
 
 /**
+ * Creates a MSNSLP ack message.
+ *
+ * @param acked_msg The message to acknowledge.
+ *
+ * @return A new MSNSLP ack message.
+ */
+MsnMessage *msn_message_new_msnslp_ack(MsnMessage *acked_msg);
+
+/**
  * Creates a new message based off a string.
  *
  * @param session The MSN session.
@@ -244,6 +262,25 @@
 const char *msn_message_get_body(const MsnMessage *msg);
 
 /**
+ * Sets the binary content of the message.
+ *
+ * @param msg  The message.
+ * @param data The binary data.
+ * @param len  The length of the data.
+ */
+void msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len);
+
+/**
+ * Returns the binary content of the message.
+ *
+ * @param msg The message.
+ * @param len The returned length of the data.
+ *
+ * @return The binary data.
+ */
+const void *msn_message_get_bin_data(const MsnMessage *msg, size_t *len);
+
+/**
  * Sets the content type in a message.
  *
  * @param msg  The message.
--- a/src/protocols/msn/msnslp.c	Wed Sep 17 01:50:15 2003 +0000
+++ b/src/protocols/msn/msnslp.c	Wed Sep 17 02:10:37 2003 +0000
@@ -22,25 +22,6 @@
 #include "msn.h"
 #include "msnslp.h"
 
-static void
-send_ack(MsnSlpSession *slpsession, MsnMessage *acked_msg)
-{
-	MsnMessage *msg;
-
-	msg = msn_message_new_msnslp();
-
-	msg->msnslp_header.length = acked_msg->msnslp_header.length;
-	msg->msnslp_header.flags = 0x02;
-	msg->msnslp_header.ack_session_id =
-		acked_msg->msnslp_header.ack_session_id;
-	msg->msnslp_header.ack_unique_id =
-		acked_msg->msnslp_header.id;
-	msg->msnslp_header.ack_length = acked_msg->msnslp_header.length;
-
-	/* Send this puppy. */
-	msn_slp_session_send_msg(slpsession, msg);
-}
-
 MsnSlpSession *
 msn_slp_session_new(MsnSwitchBoard *swboard, gboolean local_initiated)
 {
@@ -86,43 +67,127 @@
 	}
 
 	/* Now send an ack, since we got this. */
-	send_ack(slpsession, msg);
+	msn_slp_session_send_ack(slpsession, msg);
 
 	return FALSE;
 }
 
+static void
+send_msg_part(MsnSlpSession *slpsession, MsnMessage *msg)
+{
+	msg->msnslp_header.length =
+		(slpsession->orig_len - slpsession->offset > 1202
+		 ? 1202 : slpsession->orig_len - slpsession->offset);
+
+	if (slpsession->offset > 0)
+	{
+		if (msg->bin_content)
+		{
+			msn_message_set_bin_data(msg,
+				slpsession->orig_body + slpsession->offset,
+				msg->msnslp_header.length);
+		}
+		else
+		{
+			msn_message_set_body(msg,
+				slpsession->orig_body + slpsession->offset);
+		}
+	}
+
+	msg->msnslp_header.offset_1 = slpsession->offset;
+
+	msn_switchboard_send_msg(slpsession->swboard, msg);
+
+	if (slpsession->offset + msg->msnslp_header.length == slpsession->orig_len)
+	{
+		msn_message_destroy(msg);
+
+		g_free(slpsession->orig_body);
+
+		slpsession->offset       = 0;
+		slpsession->orig_len     = 0;
+		slpsession->orig_body    = NULL;
+		slpsession->outgoing_msg = NULL;
+	}
+	else
+		slpsession->offset += msg->msnslp_header.length;
+}
+
 void
 msn_slp_session_send_msg(MsnSlpSession *slpsession, MsnMessage *msg)
 {
 	g_return_if_fail(slpsession != NULL);
 	g_return_if_fail(msg != NULL);
 	g_return_if_fail(msg->msnslp_message);
+	g_return_if_fail(slpsession->outgoing_msg == NULL);
 
 	msg->msnslp_header.session_id = slpsession->session_id;
 
+	slpsession->outgoing_msg = msn_message_ref(msg);
+
 	if (slpsession->base_id == 0)
 	{
-		slpsession->base_id = rand() % 0xFFFFFF00 + 4;
+		slpsession->base_id = rand() % 0x0FFFFFF0 + 4;
 		slpsession->prev_msg_id = slpsession->base_id;
 	}
+	else if (slpsession->offset == 0)
+		slpsession->prev_msg_id = ++slpsession->base_id;
+
+	msg->msnslp_header.id = slpsession->prev_msg_id;
+//	msg->msnslp_header.ack_session_id = rand() % 0xFFFFFF00;
+	msg->msnslp_header.ack_session_id = 1980589;
+
+	msn_message_set_charset(msg, NULL);
+
+	if (msg->msnslp_header.session_id != 0)
+		msg->msnslp_footer.app_id = 1;
+
+	if (msg->bin_content)
+	{
+		const void *temp;
+
+		temp = msn_message_get_bin_data(msg, &slpsession->orig_len);
+
+		slpsession->orig_body = g_memdup(temp, slpsession->orig_len);
+	}
+	else
+	{
+		slpsession->orig_body = g_strdup(msn_message_get_body(msg));
+		slpsession->orig_len  = strlen(slpsession->orig_body);
+	}
+
+	msg->msnslp_header.total_size_1 = slpsession->orig_len;
+
+	send_msg_part(slpsession, msg);
+}
+
+void
+msn_slp_session_send_ack(MsnSlpSession *slpsession, MsnMessage *acked_msg)
+{
+	MsnMessage *msg;
+	gboolean new_base_id = FALSE;
+
+	g_return_if_fail(slpsession != NULL);
+	g_return_if_fail(acked_msg != NULL);
+	g_return_if_fail(acked_msg->msnslp_message);
+	g_return_if_fail(slpsession->outgoing_msg == NULL);
+
+	msg = msn_message_new_msnslp_ack(acked_msg);
+
+	if (slpsession->base_id == 0)
+	{
+		slpsession->base_id = rand() % 0x0FFFFE00 + 10;
+		slpsession->prev_msg_id = slpsession->base_id;
+
+		new_base_id = TRUE;
+	}
 	else
 		slpsession->prev_msg_id = ++slpsession->base_id;
 
 	msg->msnslp_header.id = slpsession->prev_msg_id;
-	msg->msnslp_header.ack_session_id = rand() % 0xFFFFFF00;
 
-	if (msn_message_get_body(msg) != NULL)
-		msg->msnslp_header.total_size = strlen(msn_message_get_body(msg));
-
-	msn_message_set_charset(msg, NULL);
-
-	msn_message_set_flag(msg, 'D');
-	msn_message_set_content_type(msg, "application/x-msnmsgrp2p");
-	msn_message_set_attr(msg, "P2P-Dest",
-			msn_user_get_passport(msn_message_get_receiver(msg)));
-
-	if (msg->msnslp_header.session_id != 0)
-		msg->msnslp_footer.app_id = 1;
+	if (new_base_id)
+		slpsession->prev_msg_id -= 4;
 
 	msn_switchboard_send_msg(slpsession->swboard, msg);
 }
@@ -141,7 +206,6 @@
 	char *call_id;
 	char *content;
 	char *body;
-	char *c;
 
 	g_return_if_fail(slpsession  != NULL);
 	g_return_if_fail(local_user  != NULL);
@@ -152,8 +216,10 @@
 	msnobj_base64 = tobase64(msnobj_data, strlen(msnobj_data));
 	g_free(msnobj_data);
 
+#if 0
 	if ((c = strchr(msnobj_base64, '=')) != NULL)
 		*c = '\0';
+#endif
 
 	session_id = rand() % 0xFFFFFF00 + 4;
 
--- a/src/protocols/msn/msnslp.h	Wed Sep 17 01:50:15 2003 +0000
+++ b/src/protocols/msn/msnslp.h	Wed Sep 17 02:10:37 2003 +0000
@@ -38,6 +38,13 @@
 	long session_id;
 	long base_id;
 	long prev_msg_id;
+
+	size_t offset;
+
+	void *orig_body;
+	size_t orig_len;
+
+	MsnMessage *outgoing_msg;
 };
 
 /**
@@ -80,6 +87,15 @@
 void msn_slp_session_send_msg(MsnSlpSession *session, MsnMessage *msg);
 
 /**
+ * Sends an acknowledgement message over a MSNSLP session for the
+ * specified message.
+ *
+ * @param slpsession The MSNSLP session to send the acknowledgement over.
+ * @param acked_msg  The message to acknowledge.
+ */
+void msn_slp_session_send_ack(MsnSlpSession *session, MsnMessage *acked_msg);
+
+/**
  * Requests a User Display image over a MSNSLP session.
  *
  * @param slpsession The MSNSLP session to request the image over.
--- a/src/protocols/msn/switchboard.c	Wed Sep 17 01:50:15 2003 +0000
+++ b/src/protocols/msn/switchboard.c	Wed Sep 17 02:10:37 2003 +0000
@@ -91,7 +91,7 @@
 
 	send_clientcaps(swboard);
 
-	if (0 && session->protocol_ver >= 9)
+	if (session->protocol_ver >= 9)
 	{
 		MsnUser *local_user, *remote_user;