diff libpurple/protocols/msn/p2p.c @ 31322:b8e076d51817

Add P2Pv2 parsing and saving functions. Tested by compiling them! They aren't enabled yet, so we should still be doing v1 right now.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Thu, 10 Mar 2011 06:29:00 +0000
parents eeca86db288b
children 506b77a27a53
line wrap: on
line diff
--- a/libpurple/protocols/msn/p2p.c	Thu Mar 10 06:01:39 2011 +0000
+++ b/libpurple/protocols/msn/p2p.c	Thu Mar 10 06:29:00 2011 +0000
@@ -26,6 +26,7 @@
 #include "debug.h"
 
 #include "p2p.h"
+#include "tlv.h"
 #include "msnutils.h"
 
 MsnP2PInfo *
@@ -58,8 +59,13 @@
 
 	switch (info->version) {
 		case MSN_P2P_VERSION_ONE:
+			*new_info = *info;
+			break;
+
 		case MSN_P2P_VERSION_TWO:
 			*new_info = *info;
+			new_info->header.v2.header_tlv = msn_tlvlist_copy(info->header.v2.header_tlv);
+			new_info->header.v2.data_tlv = msn_tlvlist_copy(info->header.v2.data_tlv);
 			break;
 
 		default:
@@ -76,8 +82,12 @@
 {
 	switch (info->version) {
 		case MSN_P2P_VERSION_ONE:
+			/* Nothing to do! */
+			break;
+
 		case MSN_P2P_VERSION_TWO:
-			/* Nothing to do! */
+			msn_tlvlist_free(info->header.v2.header_tlv);
+			msn_tlvlist_free(info->header.v2.data_tlv);
 			break;
 
 		default:
@@ -116,8 +126,47 @@
 			break;
 		}
 
-		case MSN_P2P_VERSION_TWO:
+		case MSN_P2P_VERSION_TWO: {
+			MsnP2Pv2Header *header = &info->header.v2;
+
+			header->header_len = msn_pop8(wire);
+			header->opcode = msn_pop8(wire);
+			header->message_len = msn_pop16be(wire);
+			header->base_id = msn_pop32be(wire);
+			if (header->header_len + header->message_len + P2P_PACKET_FOOTER_SIZE > max_len) {
+				/* Invalid header and data length */
+				len = 0;
+				break;
+			}
+
+			if (header->header_len > 8) {
+				header->header_tlv = msn_tlvlist_read(wire, header->header_len - 8);
+				wire += header->header_len - 8;
+			}
+
+			if (header->message_len > 0) {
+				/* Parse Data packet */
+
+				header->data_header_len = msn_pop8(wire);
+				if (header->data_header_len > header->message_len) {
+					/* Invalid data header length */
+					len = 0;
+					break;
+				}
+				header->data_tf = msn_pop8(wire);
+				header->package_number = msn_pop16be(wire);
+				header->session_id = msn_pop32be(wire);
+
+				if (header->data_header_len > 8) {
+					header->data_tlv = msn_tlvlist_read(wire, header->data_header_len - 8);
+					wire += header->data_header_len - 8;
+				}
+			}
+
+			len = header->header_len + header->message_len;
+
 			break;
+		}
 
 		default:
 			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
@@ -153,11 +202,46 @@
 			break;
 		}
 
-		case MSN_P2P_VERSION_TWO:
+		case MSN_P2P_VERSION_TWO: {
+			MsnP2Pv2Header *header = &info->header.v2;
+
+			if (header->header_tlv != NULL)
+				header->header_len = msn_tlvlist_size(header->header_tlv) + 8;
+			else
+				header->header_len = 8;
+
+			if (header->data_tlv != NULL)
+				header->data_header_len = msn_tlvlist_size(header->data_tlv) + 8;
+			else
+				header->data_header_len = 8;
+
+			tmp = wire = g_new(char, header->header_len + header->data_header_len);
+
+			msn_push8(tmp, header->header_len);
+			msn_push8(tmp, header->opcode);
+			msn_push16be(tmp, header->data_header_len + header->message_len);
+			msn_push32be(tmp, header->base_id);
+
+			if (header->header_tlv != NULL) {
+				msn_tlvlist_write(tmp, header->header_len - 8, header->header_tlv);
+				tmp += header->header_len - 8;
+			}
+
+			msn_push8(tmp, header->data_header_len);
+			msn_push8(tmp, header->data_tf);
+			msn_push16be(tmp, header->package_number);
+			msn_push32be(tmp, header->session_id);
+
+			if (header->data_tlv != NULL) {
+				msn_tlvlist_write(tmp, header->data_header_len - 8, header->data_tlv);
+				tmp += header->data_header_len - 8;
+			}
+
 			if (len)
-				*len = 0;
+				*len = header->header_len + header->data_header_len;
 
 			break;
+		}
 
 		default:
 			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);