comparison libpurple/protocols/msn/slpmsg.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 237e2c2874e6
children 6814678f3c63
comparison
equal deleted inserted replaced
30698:e874875a74a7 31292:47b6eda87723
19 * 19 *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 */ 23 */
24 #include "msn.h" 24
25 #include "internal.h"
26 #include "debug.h"
27
25 #include "slpmsg.h" 28 #include "slpmsg.h"
29 #include "slpmsg_part.h"
26 #include "slplink.h" 30 #include "slplink.h"
27 31
28 /************************************************************************** 32 /**************************************************************************
29 * SLP Message 33 * SLP Message
30 **************************************************************************/ 34 **************************************************************************/
37 slpmsg = g_new0(MsnSlpMessage, 1); 41 slpmsg = g_new0(MsnSlpMessage, 1);
38 42
39 if (purple_debug_is_verbose()) 43 if (purple_debug_is_verbose())
40 purple_debug_info("msn", "slpmsg new (%p)\n", slpmsg); 44 purple_debug_info("msn", "slpmsg new (%p)\n", slpmsg);
41 45
42 slpmsg->slplink = slplink; 46 if (slplink)
43 47 msn_slpmsg_set_slplink(slpmsg, slplink);
44 slplink->slp_msgs = 48 else
45 g_list_append(slplink->slp_msgs, slpmsg); 49 slpmsg->slplink = NULL;
50
51 slpmsg->header = NULL;
52 slpmsg->footer = NULL;
53
54 return slpmsg;
55 }
56
57 MsnSlpMessage *msn_slpmsg_new_from_data(const char *data, size_t data_len)
58 {
59 MsnSlpMessage *slpmsg;
60 MsnP2PHeader *header;
61 const char *tmp;
62 int body_len;
63
64 tmp = data;
65 slpmsg = msn_slpmsg_new(NULL);
66
67 if (data_len < sizeof(*header)) {
68 return NULL;
69 }
70
71 /* Extract the binary SLP header */
72 slpmsg->header = msn_p2p_header_from_wire((MsnP2PHeader*)tmp);
73
74 /* Extract the body */
75 body_len = data_len - (tmp - data);
76 /* msg->body_len = msg->msnslp_header.length; */
77
78 if (body_len > 0) {
79 slpmsg->size = body_len;
80 slpmsg->buffer = g_malloc(body_len);
81 memcpy(slpmsg->buffer, tmp, body_len);
82 tmp += body_len;
83 }
84
85 /* Extract the footer */
86 if (body_len >= 0)
87 slpmsg->footer = msn_p2p_footer_from_wire((MsnP2PFooter*)tmp);
46 88
47 return slpmsg; 89 return slpmsg;
48 } 90 }
49 91
50 void 92 void
65 /* We don't want to free the data of the PurpleStoredImage, 107 /* We don't want to free the data of the PurpleStoredImage,
66 * but to avoid code duplication, it's sharing buffer. */ 108 * but to avoid code duplication, it's sharing buffer. */
67 if (slpmsg->img == NULL) 109 if (slpmsg->img == NULL)
68 g_free(slpmsg->buffer); 110 g_free(slpmsg->buffer);
69 111
70 for (cur = slpmsg->msgs; cur != NULL; cur = g_list_delete_link(cur, cur)) 112 for (cur = slpmsg->parts; cur != NULL; cur = g_list_delete_link(cur, cur))
71 { 113 {
72 /* Something is pointing to this slpmsg, so we should remove that 114 /* Something is pointing to this slpmsg, so we should remove that
73 * pointer to prevent a crash. */ 115 * pointer to prevent a crash. */
74 /* Ex: a user goes offline and after that we receive an ACK */ 116 /* Ex: a user goes offline and after that we receive an ACK */
75 117
76 MsnMessage *msg = cur->data; 118 MsnSlpMessagePart *part = cur->data;
77 119
78 msg->ack_cb = NULL; 120 part->ack_cb = NULL;
79 msg->nak_cb = NULL; 121 part->nak_cb = NULL;
80 msg->ack_data = NULL; 122 part->ack_data = NULL;
81 msn_message_unref(msg); 123 msn_slpmsgpart_destroy(part);
82 } 124 }
83 125
84 slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg); 126 slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg);
85 127
128 g_free(slpmsg->header);
129 g_free(slpmsg->footer);
130
86 g_free(slpmsg); 131 g_free(slpmsg);
132 }
133
134 void
135 msn_slpmsg_set_slplink(MsnSlpMessage *slpmsg, MsnSlpLink *slplink)
136 {
137 g_return_if_fail(slplink != NULL);
138
139 slpmsg->slplink = slplink;
140
141 slplink->slp_msgs =
142 g_list_append(slplink->slp_msgs, slpmsg);
143
87 } 144 }
88 145
89 void 146 void
90 msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body, 147 msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body,
91 long long size) 148 long long size)
114 slpmsg->img = purple_imgstore_ref(img); 171 slpmsg->img = purple_imgstore_ref(img);
115 slpmsg->buffer = (guchar *)purple_imgstore_get_data(img); 172 slpmsg->buffer = (guchar *)purple_imgstore_get_data(img);
116 slpmsg->size = purple_imgstore_get_size(img); 173 slpmsg->size = purple_imgstore_get_size(img);
117 } 174 }
118 175
119 void
120 msn_slpmsg_show(MsnMessage *msg)
121 {
122 const char *info;
123 gboolean text;
124 guint32 flags;
125
126 text = FALSE;
127
128 flags = GUINT32_TO_LE(msg->msnslp_header.flags);
129
130 switch (flags)
131 {
132 case 0x0:
133 info = "SLP CONTROL";
134 text = TRUE;
135 break;
136 case 0x2:
137 info = "SLP ACK"; break;
138 case 0x20:
139 case 0x1000030:
140 info = "SLP DATA"; break;
141 default:
142 info = "SLP UNKNOWN"; break;
143 }
144
145 msn_message_show_readable(msg, info, text);
146 }
147 176
148 MsnSlpMessage * 177 MsnSlpMessage *
149 msn_slpmsg_sip_new(MsnSlpCall *slpcall, int cseq, 178 msn_slpmsg_sip_new(MsnSlpCall *slpcall, int cseq,
150 const char *header, const char *branch, 179 const char *header, const char *branch,
151 const char *content_type, const char *content) 180 const char *content_type, const char *content)
204 233
205 g_free(body); 234 g_free(body);
206 235
207 return slpmsg; 236 return slpmsg;
208 } 237 }
238
239 MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PHeader *header)
240 {
241 MsnSlpMessage *slpmsg;
242
243 slpmsg = msn_slpmsg_new(NULL);
244
245 slpmsg->session_id = header->session_id;
246 slpmsg->size = header->total_size;
247 slpmsg->flags = P2P_ACK;
248 slpmsg->ack_id = header->id;
249 slpmsg->ack_sub_id = header->ack_id;
250 slpmsg->ack_size = header->total_size;
251 slpmsg->info = "SLP ACK";
252
253 return slpmsg;
254 }
255
256 MsnSlpMessage *msn_slpmsg_obj_new(MsnSlpCall *slpcall, PurpleStoredImage *img)
257 {
258 MsnSlpMessage *slpmsg;
259
260 slpmsg = msn_slpmsg_new(NULL);
261 slpmsg->slpcall = slpcall;
262 slpmsg->flags = P2P_MSN_OBJ_DATA;
263 slpmsg->info = "SLP DATA";
264
265 msn_slpmsg_set_image(slpmsg, img);
266
267 return slpmsg;
268 }
269
270 MsnSlpMessage *msn_slpmsg_dataprep_new(MsnSlpCall *slpcall)
271 {
272 MsnSlpMessage *slpmsg;
273
274 slpmsg = msn_slpmsg_new(NULL);
275 slpmsg->slpcall = slpcall;
276 slpmsg->session_id = slpcall->session_id;
277 msn_slpmsg_set_body(slpmsg, NULL, 4);
278 slpmsg->info = "SLP DATA PREP";
279
280 return slpmsg;
281
282 }
283
284 MsnSlpMessage *msn_slpmsg_file_new(MsnSlpCall *slpcall, size_t size)
285 {
286 MsnSlpMessage *slpmsg;
287
288 slpmsg = msn_slpmsg_new(NULL);
289
290 slpmsg->slpcall = slpcall;
291 slpmsg->flags = P2P_FILE_DATA;
292 slpmsg->info = "SLP FILE";
293 slpmsg->size = size;
294
295 return slpmsg;
296 }
297
298 char *msn_slpmsg_serialize(MsnSlpMessage *slpmsg, size_t *ret_size)
299 {
300 MsnP2PHeader *header;
301 MsnP2PFooter *footer;
302 char *base;
303 char *tmp;
304 size_t siz;
305
306 base = g_malloc(P2P_PACKET_HEADER_SIZE + slpmsg->size + sizeof(MsnP2PFooter));
307 tmp = base;
308
309 header = msn_p2p_header_to_wire(slpmsg->header);
310 footer = msn_p2p_footer_to_wire(slpmsg->footer);
311
312 siz = sizeof(MsnP2PHeader);
313 /* Copy header */
314 memcpy(tmp, (char*)header, siz);
315 tmp += siz;
316
317 /* Copy body */
318 memcpy(tmp, slpmsg->buffer, slpmsg->size);
319 tmp += slpmsg->size;
320
321 /* Copy footer */
322 siz = sizeof(MsnP2PFooter);
323 memcpy(tmp, (char*)footer, siz);
324 tmp += siz;
325
326 *ret_size = tmp - base;
327
328 return base;
329 }
330
331 void msn_slpmsg_show_readable(MsnSlpMessage *slpmsg)
332 {
333 GString *str;
334
335 str = g_string_new(NULL);
336
337 g_string_append_printf(str, "Session ID: %u\r\n", slpmsg->header->session_id);
338 g_string_append_printf(str, "ID: %u\r\n", slpmsg->header->id);
339 g_string_append_printf(str, "Offset: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->offset);
340 g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->total_size);
341 g_string_append_printf(str, "Length: %u\r\n", slpmsg->header->length);
342 g_string_append_printf(str, "Flags: 0x%x\r\n", slpmsg->header->flags);
343 g_string_append_printf(str, "ACK ID: %u\r\n", slpmsg->header->ack_id);
344 g_string_append_printf(str, "SUB ID: %u\r\n", slpmsg->header->ack_sub_id);
345 g_string_append_printf(str, "ACK Size: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->ack_size);
346
347 if (purple_debug_is_verbose() && slpmsg->buffer != NULL) {
348 g_string_append_len(str, slpmsg->buffer, slpmsg->size);
349
350 if (slpmsg->buffer[slpmsg->size - 1] == '\0') {
351 str->len--;
352 g_string_append(str, " 0x00");
353 }
354 g_string_append(str, "\r\n");
355
356 }
357
358 g_string_append_printf(str, "Footer: %u\r\n", slpmsg->footer->value);
359
360 purple_debug_info("msn", "SlpMessage %s:\n{%s}\n", slpmsg->info, str->str);
361 }