# HG changeset patch # User Elliott Sales de Andrade # Date 1299738540 0 # Node ID b8e076d518179eeeb4f5fe319723d474f0b43717 # Parent 40eb10487f8726f44e401838e83c3d707c90ea60 Add P2Pv2 parsing and saving functions. Tested by compiling them! They aren't enabled yet, so we should still be doing v1 right now. diff -r 40eb10487f87 -r b8e076d51817 libpurple/protocols/msn/p2p.c --- 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); diff -r 40eb10487f87 -r b8e076d51817 libpurple/protocols/msn/p2p.h --- a/libpurple/protocols/msn/p2p.h Thu Mar 10 06:01:39 2011 +0000 +++ b/libpurple/protocols/msn/p2p.h Thu Mar 10 06:29:00 2011 +0000 @@ -50,6 +50,13 @@ guint8 opcode; guint16 message_len; guint32 base_id; + GSList *header_tlv; + guint8 data_header_len; + guint8 data_tf; + guint16 package_number; + guint32 session_id; + GSList *data_tlv; +/* guint8 body[1]; */ } MsnP2Pv2Header; typedef struct @@ -103,6 +110,13 @@ P2P_APPID_DISPLAY = 0xC /**< Display Image */ } MsnP2PAppId; +typedef enum +{ + P2P_OPCODE_NONE = 0x00, + P2P_OPCODE_SYN = 0x01, + P2P_OPCODE_RAK = 0x02 +} MsnP2Pv2OpCode; + MsnP2PInfo * msn_p2p_info_new(MsnP2PVersion version); diff -r 40eb10487f87 -r b8e076d51817 libpurple/protocols/msn/tlv.c --- a/libpurple/protocols/msn/tlv.c Thu Mar 10 06:01:39 2011 +0000 +++ b/libpurple/protocols/msn/tlv.c Thu Mar 10 06:29:00 2011 +0000 @@ -46,7 +46,7 @@ } static GSList * -msn_tlv_read(GSList *list, char *bs, size_t *bs_len) +msn_tlv_read(GSList *list, const char *bs, size_t *bs_len) { guint8 type, length; msn_tlv_t *tlv; @@ -76,7 +76,7 @@ } GSList * -msn_tlvlist_read(char *bs, size_t bs_len) +msn_tlvlist_read(const char *bs, size_t bs_len) { GSList *list = NULL; @@ -302,10 +302,10 @@ } } +int +msn_tlvlist_write(char *bs, size_t bs_len, GSList *list) +{ #if 0 -int -msn_tlvlist_write(ByteStream *bs, GSList **list) -{ int goodbuflen; GSList *cur; msn_tlv_t *tlv; @@ -325,9 +325,9 @@ byte_stream_putraw(bs, tlv->value, tlv->length); } - return 1; /* TODO: This is a nonsensical return */ +#endif + return 0; /* TODO: This is a nonsensical return */ } -#endif msn_tlv_t * msn_tlv_gettlv(GSList *list, const guint16 type, const int nth) diff -r 40eb10487f87 -r b8e076d51817 libpurple/protocols/msn/tlv.h --- a/libpurple/protocols/msn/tlv.h Thu Mar 10 06:01:39 2011 +0000 +++ b/libpurple/protocols/msn/tlv.h Thu Mar 10 06:29:00 2011 +0000 @@ -46,13 +46,13 @@ guint32 msn_tlv_get32(GSList *list, const guint16 type, const int nth); /* TLV list handling functions */ -GSList *msn_tlvlist_read(char *bs, size_t bs_len); +GSList *msn_tlvlist_read(const char *bs, size_t bs_len); GSList *msn_tlvlist_copy(GSList *orig); int msn_tlvlist_count(GSList *list); size_t msn_tlvlist_size(GSList *list); gboolean msn_tlvlist_equal(GSList *one, GSList *two); -int msn_tlvlist_write(char *bs, size_t bs_len, GSList **list); +int msn_tlvlist_write(char *bs, size_t bs_len, GSList *list); void msn_tlvlist_free(GSList *list); int msn_tlvlist_add_raw(GSList **list, const guint16 type, const guint16 length, const char *value);