Mercurial > pidgin.yaz
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 } |