Mercurial > pidgin.yaz
annotate libgaim/protocols/msn/switchboard.c @ 20390:d634f88e25d8
msn.tgz from SF Patch #1621854 from Ka-Hing Cheung
"This tarball brings soc-2006-msnp13 up to head. In addition to that it also
fixes a crash with sending offline messages.
I wasn't able to generate a diff against that branch, svn seems to insist
on diff'ing against HEAD after I run the merge command. After running `svn
merge -r 16309:HEAD https://gaim.svn.sourceforge.net/svnroot/gaim/trunk` on
the soc-2006-msnp13 you can replace the msn directory with the attached
tarball. The fix for offline messaging is on msn.c:901:
if (!session->oim)
session->oim = msn_oim_new(session)"
committer: Richard Laager <rlaager@wiktel.com>
author | Ka-Hing Cheung <khc@hxbc.us> |
---|---|
date | Sun, 15 Apr 2007 02:18:17 +0000 |
parents | e354528c4163 |
children | 9ba7dee775e1 |
rev | line source |
---|---|
14192 | 1 /** |
2 * @file switchboard.c MSN switchboard functions | |
3 * | |
4 * gaim | |
5 * | |
6 * Gaim is the legal property of its developers, whose names are too numerous | |
7 * to list here. Please refer to the COPYRIGHT file distributed with this | |
8 * source distribution. | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
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 | |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 */ | |
24 #include "msn.h" | |
25 #include "prefs.h" | |
26 #include "switchboard.h" | |
27 #include "notification.h" | |
28 #include "msn-utils.h" | |
29 | |
30 #include "error.h" | |
31 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
32 #define MSN_DEBUG_SB |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
33 |
14192 | 34 static MsnTable *cbs_table; |
35 | |
36 static void msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, | |
37 MsnMsgErrorType error); | |
38 | |
39 /************************************************************************** | |
40 * Main | |
41 **************************************************************************/ | |
42 | |
43 MsnSwitchBoard * | |
44 msn_switchboard_new(MsnSession *session) | |
45 { | |
46 MsnSwitchBoard *swboard; | |
47 MsnServConn *servconn; | |
48 | |
49 g_return_val_if_fail(session != NULL, NULL); | |
50 | |
51 swboard = g_new0(MsnSwitchBoard, 1); | |
52 | |
53 swboard->session = session; | |
54 swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_SB); | |
55 swboard->cmdproc = servconn->cmdproc; | |
56 | |
57 swboard->msg_queue = g_queue_new(); | |
58 swboard->empty = TRUE; | |
59 | |
60 swboard->cmdproc->data = swboard; | |
61 swboard->cmdproc->cbs_table = cbs_table; | |
62 | |
63 session->switches = g_list_append(session->switches, swboard); | |
64 | |
65 return swboard; | |
66 } | |
67 | |
68 void | |
69 msn_switchboard_destroy(MsnSwitchBoard *swboard) | |
70 { | |
71 MsnSession *session; | |
72 MsnMessage *msg; | |
73 GList *l; | |
74 | |
75 #ifdef MSN_DEBUG_SB | |
76 gaim_debug_info("msn", "switchboard_destroy: swboard(%p)\n", swboard); | |
77 #endif | |
78 | |
79 g_return_if_fail(swboard != NULL); | |
80 | |
81 if (swboard->destroying) | |
82 return; | |
83 | |
84 swboard->destroying = TRUE; | |
85 | |
86 /* If it linked us is because its looking for trouble */ | |
20390
d634f88e25d8
msn.tgz from SF Patch #1621854 from Ka-Hing Cheung
Ka-Hing Cheung <khc@hxbc.us>
parents:
20389
diff
changeset
|
87 if (swboard->slplink != NULL) |
d634f88e25d8
msn.tgz from SF Patch #1621854 from Ka-Hing Cheung
Ka-Hing Cheung <khc@hxbc.us>
parents:
20389
diff
changeset
|
88 msn_slplink_destroy(swboard->slplink); |
14192 | 89 |
90 /* Destroy the message queue */ | |
91 while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL) | |
92 { | |
93 if (swboard->error != MSN_SB_ERROR_NONE) | |
94 { | |
95 /* The messages could not be sent due to a switchboard error */ | |
96 msg_error_helper(swboard->cmdproc, msg, | |
97 MSN_MSG_ERROR_SB); | |
98 } | |
99 msn_message_unref(msg); | |
100 } | |
101 | |
102 g_queue_free(swboard->msg_queue); | |
103 | |
104 /* msg_error_helper will both remove the msg from ack_list and | |
105 unref it, so we don't need to do either here */ | |
106 while ((l = swboard->ack_list) != NULL) | |
107 msg_error_helper(swboard->cmdproc, l->data, MSN_MSG_ERROR_SB); | |
108 | |
109 g_free(swboard->im_user); | |
110 g_free(swboard->auth_key); | |
111 g_free(swboard->session_id); | |
112 | |
113 for (l = swboard->users; l != NULL; l = l->next) | |
114 g_free(l->data); | |
115 | |
116 session = swboard->session; | |
117 session->switches = g_list_remove(session->switches, swboard); | |
118 | |
119 #if 0 | |
120 /* This should never happen or we are in trouble. */ | |
121 if (swboard->servconn != NULL) | |
122 msn_servconn_destroy(swboard->servconn); | |
123 #endif | |
124 | |
125 swboard->cmdproc->data = NULL; | |
126 | |
127 msn_servconn_set_disconnect_cb(swboard->servconn, NULL); | |
128 | |
129 msn_servconn_destroy(swboard->servconn); | |
130 | |
131 g_free(swboard); | |
132 } | |
133 | |
134 void | |
135 msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key) | |
136 { | |
137 g_return_if_fail(swboard != NULL); | |
138 g_return_if_fail(key != NULL); | |
139 | |
140 swboard->auth_key = g_strdup(key); | |
141 } | |
142 | |
143 const char * | |
144 msn_switchboard_get_auth_key(MsnSwitchBoard *swboard) | |
145 { | |
146 g_return_val_if_fail(swboard != NULL, NULL); | |
147 | |
148 return swboard->auth_key; | |
149 } | |
150 | |
151 void | |
152 msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id) | |
153 { | |
154 g_return_if_fail(swboard != NULL); | |
155 g_return_if_fail(id != NULL); | |
156 | |
157 if (swboard->session_id != NULL) | |
158 g_free(swboard->session_id); | |
159 | |
160 swboard->session_id = g_strdup(id); | |
161 } | |
162 | |
163 const char * | |
164 msn_switchboard_get_session_id(MsnSwitchBoard *swboard) | |
165 { | |
166 g_return_val_if_fail(swboard != NULL, NULL); | |
167 | |
168 return swboard->session_id; | |
169 } | |
170 | |
171 void | |
172 msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited) | |
173 { | |
174 g_return_if_fail(swboard != NULL); | |
175 | |
176 swboard->invited = invited; | |
177 } | |
178 | |
179 gboolean | |
180 msn_switchboard_is_invited(MsnSwitchBoard *swboard) | |
181 { | |
182 g_return_val_if_fail(swboard != NULL, FALSE); | |
183 | |
184 return swboard->invited; | |
185 } | |
186 | |
187 /************************************************************************** | |
188 * Utility | |
189 **************************************************************************/ | |
190 | |
191 static void | |
192 send_clientcaps(MsnSwitchBoard *swboard) | |
193 { | |
194 MsnMessage *msg; | |
195 | |
196 msg = msn_message_new(MSN_MSG_CAPS); | |
197 msn_message_set_content_type(msg, "text/x-clientcaps"); | |
198 msn_message_set_flag(msg, 'U'); | |
199 msn_message_set_bin_data(msg, MSN_CLIENTINFO, strlen(MSN_CLIENTINFO)); | |
200 | |
201 msn_switchboard_send_msg(swboard, msg, TRUE); | |
202 | |
203 msn_message_destroy(msg); | |
204 } | |
205 | |
206 static void | |
207 msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user) | |
208 { | |
209 MsnCmdProc *cmdproc; | |
210 GaimAccount *account; | |
211 | |
212 g_return_if_fail(swboard != NULL); | |
213 | |
214 cmdproc = swboard->cmdproc; | |
215 account = cmdproc->session->account; | |
216 | |
217 swboard->users = g_list_prepend(swboard->users, g_strdup(user)); | |
218 swboard->current_users++; | |
219 swboard->empty = FALSE; | |
220 | |
221 #ifdef MSN_DEBUG_CHAT | |
222 gaim_debug_info("msn", "user=[%s], total=%d\n", user, | |
223 swboard->current_users); | |
224 #endif | |
225 | |
226 if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL)) | |
227 { | |
228 /* This is a helper switchboard. */ | |
229 gaim_debug_error("msn", "switchboard_add_user: conv != NULL\n"); | |
230 return; | |
231 } | |
232 | |
233 if ((swboard->conv != NULL) && | |
234 (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) | |
235 { | |
236 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL, | |
237 GAIM_CBFLAGS_NONE, TRUE); | |
238 } | |
239 else if (swboard->current_users > 1 || swboard->total_users > 1) | |
240 { | |
241 if (swboard->conv == NULL || | |
242 gaim_conversation_get_type(swboard->conv) != GAIM_CONV_TYPE_CHAT) | |
243 { | |
244 GList *l; | |
245 | |
246 #ifdef MSN_DEBUG_CHAT | |
247 gaim_debug_info("msn", "[chat] Switching to chat.\n"); | |
248 #endif | |
249 | |
250 #if 0 | |
251 /* this is bad - it causes msn_switchboard_close to be called on the | |
252 * switchboard we're in the middle of using :( */ | |
253 if (swboard->conv != NULL) | |
254 gaim_conversation_destroy(swboard->conv); | |
255 #endif | |
256 | |
14278 | 257 swboard->chat_id = cmdproc->session->conv_seq++; |
14192 | 258 swboard->flag |= MSN_SB_FLAG_IM; |
259 swboard->conv = serv_got_joined_chat(account->gc, | |
260 swboard->chat_id, | |
261 "MSN Chat"); | |
262 | |
263 for (l = swboard->users; l != NULL; l = l->next) | |
264 { | |
265 const char *tmp_user; | |
266 | |
267 tmp_user = l->data; | |
268 | |
269 #ifdef MSN_DEBUG_CHAT | |
270 gaim_debug_info("msn", "[chat] Adding [%s].\n", tmp_user); | |
271 #endif | |
272 | |
273 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), | |
274 tmp_user, NULL, GAIM_CBFLAGS_NONE, TRUE); | |
275 } | |
276 | |
277 #ifdef MSN_DEBUG_CHAT | |
278 gaim_debug_info("msn", "[chat] We add ourselves.\n"); | |
279 #endif | |
280 | |
281 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), | |
282 gaim_account_get_username(account), | |
283 NULL, GAIM_CBFLAGS_NONE, TRUE); | |
284 | |
285 g_free(swboard->im_user); | |
286 swboard->im_user = NULL; | |
287 } | |
288 } | |
289 else if (swboard->conv == NULL) | |
290 { | |
291 swboard->conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, | |
292 user, account); | |
293 } | |
294 else | |
295 { | |
296 gaim_debug_warning("msn", "switchboard_add_user: This should not happen!\n"); | |
297 } | |
298 } | |
299 | |
300 static GaimConversation * | |
301 msn_switchboard_get_conv(MsnSwitchBoard *swboard) | |
302 { | |
303 GaimAccount *account; | |
304 | |
305 g_return_val_if_fail(swboard != NULL, NULL); | |
306 | |
307 if (swboard->conv != NULL) | |
308 return swboard->conv; | |
309 | |
310 gaim_debug_error("msn", "Switchboard with unassigned conversation\n"); | |
311 | |
312 account = swboard->session->account; | |
313 | |
314 return (swboard->conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, | |
315 account, swboard->im_user)); | |
316 } | |
317 | |
318 static void | |
319 msn_switchboard_report_user(MsnSwitchBoard *swboard, GaimMessageFlags flags, const char *msg) | |
320 { | |
321 GaimConversation *conv; | |
322 | |
323 g_return_if_fail(swboard != NULL); | |
324 g_return_if_fail(msg != NULL); | |
325 | |
326 if ((conv = msn_switchboard_get_conv(swboard)) != NULL) | |
327 { | |
328 gaim_conversation_write(conv, NULL, msg, flags, time(NULL)); | |
329 } | |
330 } | |
331 | |
332 static void | |
333 swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport) | |
334 { | |
335 g_return_if_fail(swboard != NULL); | |
336 | |
337 gaim_debug_warning("msg", "Error: Unable to call the user %s for reason %i\n", | |
338 passport ? passport : "(null)", reason); | |
339 | |
340 /* TODO: if current_users > 0, this is probably a chat and an invite failed, | |
341 * we should report that in the chat or something */ | |
342 if (swboard->current_users == 0) | |
343 { | |
344 swboard->error = reason; | |
345 msn_switchboard_close(swboard); | |
346 } | |
347 } | |
348 | |
349 static void | |
350 cal_error_helper(MsnTransaction *trans, int reason) | |
351 { | |
352 MsnSwitchBoard *swboard; | |
353 const char *passport; | |
354 char **params; | |
355 | |
356 params = g_strsplit(trans->params, " ", 0); | |
357 | |
358 passport = params[0]; | |
359 | |
360 swboard = trans->data; | |
361 | |
362 gaim_debug_warning("msn", "cal_error_helper: command %s failed for reason %i\n",trans->command,reason); | |
363 | |
364 swboard_error_helper(swboard, reason, passport); | |
365 | |
366 g_strfreev(params); | |
367 } | |
368 | |
369 static void | |
370 msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error) | |
371 { | |
372 MsnSwitchBoard *swboard; | |
373 | |
374 g_return_if_fail(cmdproc != NULL); | |
375 g_return_if_fail(msg != NULL); | |
376 | |
377 if ((error != MSN_MSG_ERROR_SB) && (msg->nak_cb != NULL)) | |
378 msg->nak_cb(msg, msg->ack_data); | |
379 | |
380 swboard = cmdproc->data; | |
381 | |
382 /* This is not good, and should be fixed somewhere else. */ | |
383 g_return_if_fail(swboard != NULL); | |
384 | |
385 if (msg->type == MSN_MSG_TEXT) | |
386 { | |
387 const char *format, *str_reason; | |
388 char *body_str, *body_enc, *pre, *post; | |
389 | |
390 #if 0 | |
391 if (swboard->conv == NULL) | |
392 { | |
393 if (msg->ack_ref) | |
394 msn_message_unref(msg); | |
395 | |
396 return; | |
397 } | |
398 #endif | |
399 | |
400 if (error == MSN_MSG_ERROR_TIMEOUT) | |
401 { | |
402 str_reason = _("Message may have not been sent " | |
403 "because a timeout occurred:"); | |
404 } | |
405 else if (error == MSN_MSG_ERROR_SB) | |
406 { | |
407 switch (swboard->error) | |
408 { | |
409 case MSN_SB_ERROR_OFFLINE: | |
410 str_reason = _("Message could not be sent, " | |
411 "not allowed while invisible:"); | |
412 break; | |
413 case MSN_SB_ERROR_USER_OFFLINE: | |
414 str_reason = _("Message could not be sent " | |
415 "because the user is offline:"); | |
416 break; | |
417 case MSN_SB_ERROR_CONNECTION: | |
418 str_reason = _("Message could not be sent " | |
419 "because a connection error occurred:"); | |
420 break; | |
421 case MSN_SB_ERROR_TOO_FAST: | |
422 str_reason = _("Message could not be sent " | |
423 "because we are sending too quickly:"); | |
424 break; | |
425 default: | |
426 str_reason = _("Message could not be sent " | |
427 "because an error with " | |
428 "the switchboard occurred:"); | |
429 break; | |
430 } | |
431 } | |
432 else | |
433 { | |
434 str_reason = _("Message may have not been sent " | |
435 "because an unknown error occurred:"); | |
436 } | |
437 | |
438 body_str = msn_message_to_string(msg); | |
439 body_enc = g_markup_escape_text(body_str, -1); | |
440 g_free(body_str); | |
441 | |
442 format = msn_message_get_attr(msg, "X-MMS-IM-Format"); | |
443 msn_parse_format(format, &pre, &post); | |
444 body_str = g_strdup_printf("%s%s%s", pre ? pre : "", | |
445 body_enc ? body_enc : "", post ? post : ""); | |
446 g_free(body_enc); | |
447 g_free(pre); | |
448 g_free(post); | |
449 | |
450 msn_switchboard_report_user(swboard, GAIM_MESSAGE_ERROR, | |
451 str_reason); | |
452 msn_switchboard_report_user(swboard, GAIM_MESSAGE_RAW, | |
453 body_str); | |
454 | |
455 g_free(body_str); | |
456 } | |
457 | |
458 /* If a timeout occures we will want the msg around just in case we | |
459 * receive the ACK after the timeout. */ | |
460 if (msg->ack_ref && error != MSN_MSG_ERROR_TIMEOUT) | |
461 { | |
462 swboard->ack_list = g_list_remove(swboard->ack_list, msg); | |
463 msn_message_unref(msg); | |
464 } | |
465 } | |
466 | |
467 /************************************************************************** | |
468 * Message Stuff | |
469 **************************************************************************/ | |
470 | |
471 /** Called when a message times out. */ | |
472 static void | |
473 msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) | |
474 { | |
475 MsnMessage *msg; | |
476 | |
477 msg = trans->data; | |
478 | |
479 msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT); | |
480 } | |
481 | |
482 /** Called when we receive an error of a message. */ | |
483 static void | |
484 msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
485 { | |
486 msg_error_helper(cmdproc, trans->data, MSN_MSG_ERROR_UNKNOWN); | |
487 } | |
488 | |
489 #if 0 | |
490 /** Called when we receive an ack of a special message. */ | |
491 static void | |
492 msg_ack(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
493 { | |
494 MsnMessage *msg; | |
495 | |
496 msg = cmd->trans->data; | |
497 | |
498 if (msg->ack_cb != NULL) | |
499 msg->ack_cb(msg->ack_data); | |
500 | |
501 msn_message_unref(msg); | |
502 } | |
503 | |
504 /** Called when we receive a nak of a special message. */ | |
505 static void | |
506 msg_nak(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
507 { | |
508 MsnMessage *msg; | |
509 | |
510 msg = cmd->trans->data; | |
511 | |
512 msn_message_unref(msg); | |
513 } | |
514 #endif | |
515 | |
516 static void | |
517 release_msg(MsnSwitchBoard *swboard, MsnMessage *msg) | |
518 { | |
519 MsnCmdProc *cmdproc; | |
520 MsnTransaction *trans; | |
521 char *payload; | |
522 gsize payload_len; | |
523 | |
524 g_return_if_fail(swboard != NULL); | |
525 g_return_if_fail(msg != NULL); | |
526 | |
527 cmdproc = swboard->cmdproc; | |
528 | |
529 payload = msn_message_gen_payload(msg, &payload_len); | |
530 | |
531 #ifdef MSN_DEBUG_SB | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
532 gaim_debug_info("MaYuan","SB length:{%d}",payload_len); |
14192 | 533 msn_message_show_readable(msg, "SB SEND", FALSE); |
534 #endif | |
535 | |
536 trans = msn_transaction_new(cmdproc, "MSG", "%c %d", | |
537 msn_message_get_flag(msg), payload_len); | |
538 | |
539 /* Data for callbacks */ | |
540 msn_transaction_set_data(trans, msg); | |
541 | |
542 if (msg->type == MSN_MSG_TEXT) | |
543 { | |
544 msg->ack_ref = TRUE; | |
545 msn_message_ref(msg); | |
546 swboard->ack_list = g_list_append(swboard->ack_list, msg); | |
547 msn_transaction_set_timeout_cb(trans, msg_timeout); | |
548 } | |
549 else if (msg->type == MSN_MSG_SLP) | |
550 { | |
551 msg->ack_ref = TRUE; | |
552 msn_message_ref(msg); | |
553 swboard->ack_list = g_list_append(swboard->ack_list, msg); | |
554 msn_transaction_set_timeout_cb(trans, msg_timeout); | |
555 #if 0 | |
556 if (msg->ack_cb != NULL) | |
557 { | |
558 msn_transaction_add_cb(trans, "ACK", msg_ack); | |
559 msn_transaction_add_cb(trans, "NAK", msg_nak); | |
560 } | |
561 #endif | |
562 } | |
563 | |
564 trans->payload = payload; | |
565 trans->payload_len = payload_len; | |
566 | |
567 msg->trans = trans; | |
568 | |
569 msn_cmdproc_send_trans(cmdproc, trans); | |
570 } | |
571 | |
572 static void | |
573 queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg) | |
574 { | |
575 g_return_if_fail(swboard != NULL); | |
576 g_return_if_fail(msg != NULL); | |
577 | |
578 gaim_debug_info("msn", "Appending message to queue.\n"); | |
579 | |
580 g_queue_push_tail(swboard->msg_queue, msg); | |
581 | |
582 msn_message_ref(msg); | |
583 } | |
584 | |
585 static void | |
586 process_queue(MsnSwitchBoard *swboard) | |
587 { | |
588 MsnMessage *msg; | |
589 | |
590 g_return_if_fail(swboard != NULL); | |
591 | |
592 gaim_debug_info("msn", "Processing queue\n"); | |
593 | |
594 while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL) | |
595 { | |
596 gaim_debug_info("msn", "Sending message\n"); | |
597 release_msg(swboard, msg); | |
598 msn_message_unref(msg); | |
599 } | |
600 } | |
601 | |
602 gboolean | |
603 msn_switchboard_can_send(MsnSwitchBoard *swboard) | |
604 { | |
605 g_return_val_if_fail(swboard != NULL, FALSE); | |
606 | |
607 if (swboard->empty || !g_queue_is_empty(swboard->msg_queue)) | |
608 return FALSE; | |
609 | |
610 return TRUE; | |
611 } | |
612 | |
613 void | |
614 msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg, | |
615 gboolean queue) | |
616 { | |
617 g_return_if_fail(swboard != NULL); | |
618 g_return_if_fail(msg != NULL); | |
619 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
620 gaim_debug_info("Ma Yuan","switchboard send msg..\n"); |
14192 | 621 if (msn_switchboard_can_send(swboard)) |
622 release_msg(swboard, msg); | |
623 else if (queue) | |
624 queue_msg(swboard, msg); | |
625 } | |
626 | |
627 /************************************************************************** | |
628 * Switchboard Commands | |
629 **************************************************************************/ | |
630 | |
631 static void | |
632 ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
633 { | |
634 MsnSwitchBoard *swboard; | |
635 | |
636 swboard = cmdproc->data; | |
637 swboard->ready = TRUE; | |
638 } | |
639 | |
640 static void | |
641 bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
642 { | |
643 MsnSwitchBoard *swboard; | |
644 const char *user; | |
645 | |
646 swboard = cmdproc->data; | |
647 user = cmd->params[0]; | |
648 | |
649 if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL)) | |
650 gaim_debug_error("msn_switchboard", "bye_cmd: helper bug\n"); | |
651 | |
652 if (swboard->conv == NULL) | |
653 { | |
654 /* This is a helper switchboard */ | |
655 msn_switchboard_destroy(swboard); | |
656 } | |
657 else if ((swboard->current_users > 1) || | |
658 (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) | |
659 { | |
660 /* This is a switchboard used for a chat */ | |
661 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->conv), user, NULL); | |
662 swboard->current_users--; | |
663 if (swboard->current_users == 0) | |
664 msn_switchboard_destroy(swboard); | |
665 } | |
666 else | |
667 { | |
668 /* This is a switchboard used for a im session */ | |
669 msn_switchboard_destroy(swboard); | |
670 } | |
671 } | |
672 | |
673 static void | |
674 iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
675 { | |
676 GaimAccount *account; | |
677 GaimConnection *gc; | |
678 MsnSwitchBoard *swboard; | |
679 | |
680 account = cmdproc->session->account; | |
681 gc = account->gc; | |
682 swboard = cmdproc->data; | |
683 | |
684 swboard->total_users = atoi(cmd->params[2]); | |
685 | |
686 msn_switchboard_add_user(swboard, cmd->params[3]); | |
687 } | |
688 | |
689 static void | |
690 joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
691 { | |
692 MsnSession *session; | |
693 GaimAccount *account; | |
694 GaimConnection *gc; | |
695 MsnSwitchBoard *swboard; | |
696 const char *passport; | |
697 | |
698 passport = cmd->params[0]; | |
699 | |
700 session = cmdproc->session; | |
701 account = session->account; | |
702 gc = account->gc; | |
703 swboard = cmdproc->data; | |
704 | |
705 msn_switchboard_add_user(swboard, passport); | |
706 | |
707 process_queue(swboard); | |
708 | |
709 if (!session->http_method) | |
710 send_clientcaps(swboard); | |
711 | |
712 if (swboard->closed) | |
713 msn_switchboard_close(swboard); | |
714 } | |
715 | |
716 static void | |
717 msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) | |
718 { | |
719 MsnMessage *msg; | |
720 | |
721 msg = msn_message_new_from_cmd(cmdproc->session, cmd); | |
722 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
723 msn_message_parse_payload(msg, payload, len, |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
724 MSG_LINE_DEM,MSG_BODY_DEM); |
14192 | 725 #ifdef MSN_DEBUG_SB |
726 msn_message_show_readable(msg, "SB RECV", FALSE); | |
727 #endif | |
728 | |
729 if (msg->remote_user != NULL) | |
730 g_free (msg->remote_user); | |
731 | |
732 msg->remote_user = g_strdup(cmd->params[0]); | |
733 msn_cmdproc_process_msg(cmdproc, msg); | |
734 | |
735 msn_message_destroy(msg); | |
736 } | |
737 | |
738 static void | |
739 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
740 { | |
741 cmdproc->servconn->payload_len = atoi(cmd->params[2]); | |
742 cmdproc->last_cmd->payload_cb = msg_cmd_post; | |
743 } | |
744 | |
745 static void | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
746 ubm_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
747 { |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
748 gaim_debug_misc("MaYuan","get UBM...\n"); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
749 cmdproc->servconn->payload_len = atoi(cmd->params[4]); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
750 cmdproc->last_cmd->payload_cb = msg_cmd_post; |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
751 } |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
752 |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
753 static void |
14192 | 754 nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
755 { | |
756 MsnMessage *msg; | |
757 | |
758 msg = cmd->trans->data; | |
759 g_return_if_fail(msg != NULL); | |
760 | |
761 msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_NAK); | |
762 } | |
763 | |
764 static void | |
765 ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
766 { | |
767 MsnSwitchBoard *swboard; | |
768 MsnMessage *msg; | |
769 | |
770 msg = cmd->trans->data; | |
771 | |
772 if (msg->ack_cb != NULL) | |
773 msg->ack_cb(msg, msg->ack_data); | |
774 | |
775 swboard = cmdproc->data; | |
776 swboard->ack_list = g_list_remove(swboard->ack_list, msg); | |
777 msn_message_unref(msg); | |
778 } | |
779 | |
780 static void | |
781 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
782 { | |
783 GaimConnection *gc; | |
784 MsnSwitchBoard *swboard; | |
785 | |
786 gc = cmdproc->session->account->gc; | |
787 swboard = cmdproc->data; | |
788 | |
789 if (swboard->current_users > 1) | |
790 serv_got_chat_left(gc, swboard->chat_id); | |
791 | |
792 msn_switchboard_disconnect(swboard); | |
793 } | |
794 | |
795 static void | |
796 usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
797 { | |
798 MsnSwitchBoard *swboard; | |
799 | |
800 swboard = cmdproc->data; | |
801 | |
802 #if 0 | |
803 GList *l; | |
804 | |
805 for (l = swboard->users; l != NULL; l = l->next) | |
806 { | |
807 const char *user; | |
808 user = l->data; | |
809 | |
810 msn_cmdproc_send(cmdproc, "CAL", "%s", user); | |
811 } | |
812 #endif | |
813 | |
814 swboard->ready = TRUE; | |
815 msn_cmdproc_process_queue(cmdproc); | |
816 } | |
817 | |
818 /************************************************************************** | |
819 * Message Handlers | |
820 **************************************************************************/ | |
821 static void | |
822 plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
823 { | |
824 GaimConnection *gc; | |
825 MsnSwitchBoard *swboard; | |
826 const char *body; | |
827 char *body_str; | |
828 char *body_enc; | |
829 char *body_final; | |
830 size_t body_len; | |
831 const char *passport; | |
832 const char *value; | |
833 | |
834 gc = cmdproc->session->account->gc; | |
835 swboard = cmdproc->data; | |
836 | |
837 body = msn_message_get_bin_data(msg, &body_len); | |
838 body_str = g_strndup(body, body_len); | |
839 body_enc = g_markup_escape_text(body_str, -1); | |
840 g_free(body_str); | |
841 | |
842 passport = msg->remote_user; | |
843 | |
844 if (!strcmp(passport, "messenger@microsoft.com") && | |
845 strstr(body, "immediate security update")) | |
846 { | |
847 return; | |
848 } | |
849 | |
850 #if 0 | |
851 if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL) | |
852 { | |
853 gaim_debug_misc("msn", "User-Agent = '%s'\n", value); | |
854 } | |
855 #endif | |
856 | |
857 if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL) | |
858 { | |
859 char *pre, *post; | |
860 | |
861 msn_parse_format(value, &pre, &post); | |
862 | |
863 body_final = g_strdup_printf("%s%s%s", pre ? pre : "", | |
864 body_enc ? body_enc : "", post ? post : ""); | |
865 | |
866 g_free(pre); | |
867 g_free(post); | |
868 g_free(body_enc); | |
869 } | |
870 else | |
871 { | |
872 body_final = body_enc; | |
873 } | |
874 | |
875 swboard->flag |= MSN_SB_FLAG_IM; | |
876 | |
877 if (swboard->current_users > 1 || | |
878 ((swboard->conv != NULL) && | |
879 gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) | |
880 { | |
881 /* If current_users is always ok as it should then there is no need to | |
882 * check if this is a chat. */ | |
883 if (swboard->current_users <= 1) | |
884 gaim_debug_misc("msn", "plain_msg: current_users(%d)\n", | |
885 swboard->current_users); | |
886 | |
887 serv_got_chat_in(gc, swboard->chat_id, passport, 0, body_final, | |
888 time(NULL)); | |
889 if (swboard->conv == NULL) | |
890 { | |
891 swboard->conv = gaim_find_chat(gc, swboard->chat_id); | |
892 swboard->flag |= MSN_SB_FLAG_IM; | |
893 } | |
894 } | |
895 else | |
896 { | |
897 serv_got_im(gc, passport, body_final, 0, time(NULL)); | |
898 if (swboard->conv == NULL) | |
899 { | |
900 swboard->conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, | |
901 passport, gaim_connection_get_account(gc)); | |
902 swboard->flag |= MSN_SB_FLAG_IM; | |
903 } | |
904 } | |
905 | |
906 g_free(body_final); | |
907 } | |
908 | |
909 static void | |
910 control_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
911 { | |
912 GaimConnection *gc; | |
913 MsnSwitchBoard *swboard; | |
914 char *passport; | |
915 | |
916 gc = cmdproc->session->account->gc; | |
917 swboard = cmdproc->data; | |
918 passport = msg->remote_user; | |
919 | |
920 if (swboard->current_users == 1 && | |
921 msn_message_get_attr(msg, "TypingUser") != NULL) | |
922 { | |
923 serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT, | |
924 GAIM_TYPING); | |
925 } | |
926 } | |
927 | |
928 static void | |
929 clientcaps_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
930 { | |
931 #if 0 | |
932 MsnSession *session; | |
933 MsnSwitchBoard *swboard; | |
934 MsnUser *user; | |
935 GHashTable *clientcaps; | |
936 const char *value; | |
937 | |
938 char *passport = msg->sender; | |
939 | |
940 session = cmdproc->session; | |
941 swboard = cmdproc->servconn->swboard; | |
942 | |
943 clientcaps = msn_message_get_hashtable_from_body(msg); | |
944 #endif | |
945 } | |
946 | |
947 static void | |
948 nudge_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
949 { | |
950 MsnSwitchBoard *swboard; | |
951 char *username, *str; | |
952 GaimAccount *account; | |
953 GaimBuddy *buddy; | |
954 const char *user; | |
955 | |
956 swboard = cmdproc->data; | |
957 account = cmdproc->session->account; | |
958 user = msg->remote_user; | |
959 | |
960 if ((buddy = gaim_find_buddy(account, user)) != NULL) | |
961 username = g_markup_escape_text(gaim_buddy_get_alias(buddy), -1); | |
962 else | |
963 username = g_markup_escape_text(user, -1); | |
964 | |
965 str = g_strdup_printf(_("%s just sent you a Nudge!"), username); | |
966 g_free(username); | |
967 msn_switchboard_report_user(swboard, GAIM_MESSAGE_SYSTEM, str); | |
968 g_free(str); | |
969 } | |
970 | |
971 /************************************************************************** | |
972 * Connect stuff | |
973 **************************************************************************/ | |
974 static void | |
975 connect_cb(MsnServConn *servconn) | |
976 { | |
977 MsnSwitchBoard *swboard; | |
978 MsnCmdProc *cmdproc; | |
979 GaimAccount *account; | |
980 | |
981 cmdproc = servconn->cmdproc; | |
982 g_return_if_fail(cmdproc != NULL); | |
983 | |
984 account = cmdproc->session->account; | |
985 swboard = cmdproc->data; | |
986 g_return_if_fail(swboard != NULL); | |
987 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
988 if (msn_switchboard_is_invited(swboard)){ |
14192 | 989 swboard->empty = FALSE; |
990 | |
991 msn_cmdproc_send(cmdproc, "ANS", "%s %s %s", | |
992 gaim_account_get_username(account), | |
993 swboard->auth_key, swboard->session_id); | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
994 }else{ |
14192 | 995 msn_cmdproc_send(cmdproc, "USR", "%s %s", |
996 gaim_account_get_username(account), | |
997 swboard->auth_key); | |
998 } | |
999 } | |
1000 | |
1001 static void | |
1002 disconnect_cb(MsnServConn *servconn) | |
1003 { | |
1004 MsnSwitchBoard *swboard; | |
1005 | |
1006 swboard = servconn->cmdproc->data; | |
1007 g_return_if_fail(swboard != NULL); | |
1008 | |
1009 msn_servconn_set_disconnect_cb(swboard->servconn, NULL); | |
1010 | |
1011 msn_switchboard_destroy(swboard); | |
1012 } | |
1013 | |
1014 gboolean | |
1015 msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port) | |
1016 { | |
1017 g_return_val_if_fail(swboard != NULL, FALSE); | |
1018 | |
1019 msn_servconn_set_connect_cb(swboard->servconn, connect_cb); | |
1020 msn_servconn_set_disconnect_cb(swboard->servconn, disconnect_cb); | |
1021 | |
1022 return msn_servconn_connect(swboard->servconn, host, port); | |
1023 } | |
1024 | |
1025 void | |
1026 msn_switchboard_disconnect(MsnSwitchBoard *swboard) | |
1027 { | |
1028 g_return_if_fail(swboard != NULL); | |
1029 | |
1030 msn_servconn_disconnect(swboard->servconn); | |
1031 } | |
1032 | |
1033 /************************************************************************** | |
1034 * Call stuff | |
1035 **************************************************************************/ | |
1036 static void | |
1037 got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
1038 { | |
1039 #if 0 | |
1040 MsnSwitchBoard *swboard; | |
1041 const char *user; | |
1042 | |
1043 swboard = cmdproc->data; | |
1044 | |
1045 user = cmd->params[0]; | |
1046 | |
1047 msn_switchboard_add_user(swboard, user); | |
1048 #endif | |
1049 } | |
1050 | |
1051 static void | |
1052 cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) | |
1053 { | |
1054 gaim_debug_warning("msn", "cal_timeout: command %s timed out\n", trans->command); | |
1055 | |
1056 cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN); | |
1057 } | |
1058 | |
1059 static void | |
1060 cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
1061 { | |
1062 int reason = MSN_SB_ERROR_UNKNOWN; | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1063 MsnMessage *msg; |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1064 MsnSwitchBoard *swboard = trans->data; |
14192 | 1065 |
1066 if (error == 215) | |
1067 { | |
1068 gaim_debug_info("msn", "Invited user already in switchboard\n"); | |
1069 return; | |
1070 } | |
1071 else if (error == 217) | |
1072 { | |
1073 reason = MSN_SB_ERROR_USER_OFFLINE; | |
1074 } | |
1075 | |
1076 gaim_debug_warning("msn", "cal_error: command %s gave error %i\n", trans->command, error); | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1077 gaim_debug_warning("msn", "Will Use Offline Message to sendit\n"); |
14192 | 1078 |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1079 // cal_error_helper(trans, reason); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1080 /*offline Message send Process*/ |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1081 |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1082 while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL){ |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1083 gaim_debug_warning("Ma Yuan","offline msg to send:{%s}\n",msg->body); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1084 /* The messages could not be sent due to a switchboard error */ |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1085 swboard->error = MSN_SB_ERROR_USER_OFFLINE; |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1086 msg_error_helper(swboard->cmdproc, msg, |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1087 MSN_MSG_ERROR_SB); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1088 msn_message_unref(msg); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1089 } |
14192 | 1090 cal_error_helper(trans, reason); |
1091 } | |
1092 | |
1093 void | |
1094 msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user) | |
1095 { | |
1096 MsnTransaction *trans; | |
1097 MsnCmdProc *cmdproc; | |
1098 | |
1099 g_return_if_fail(swboard != NULL); | |
1100 | |
1101 cmdproc = swboard->cmdproc; | |
1102 | |
1103 trans = msn_transaction_new(cmdproc, "CAL", "%s", user); | |
1104 /* this doesn't do anything, but users seem to think that | |
1105 * 'Unhandled command' is some kind of error, so we don't report it */ | |
1106 msn_transaction_add_cb(trans, "CAL", got_cal); | |
1107 | |
1108 msn_transaction_set_data(trans, swboard); | |
1109 msn_transaction_set_timeout_cb(trans, cal_timeout); | |
1110 | |
1111 if (swboard->ready) | |
1112 msn_cmdproc_send_trans(cmdproc, trans); | |
1113 else | |
1114 msn_cmdproc_queue_trans(cmdproc, trans); | |
1115 } | |
1116 | |
1117 /************************************************************************** | |
1118 * Create & Transfer stuff | |
1119 **************************************************************************/ | |
1120 | |
1121 static void | |
1122 got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
1123 { | |
1124 MsnSwitchBoard *swboard; | |
1125 char *host; | |
1126 int port; | |
1127 swboard = cmd->trans->data; | |
1128 | |
1129 if (g_list_find(cmdproc->session->switches, swboard) == NULL) | |
1130 /* The conversation window was closed. */ | |
1131 return; | |
1132 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1133 gaim_debug_info("MaYuan","Switchboard:auth:{%s} socket:{%s}\n",cmd->params[4],cmd->params[2]); |
14192 | 1134 msn_switchboard_set_auth_key(swboard, cmd->params[4]); |
1135 | |
1136 msn_parse_socket(cmd->params[2], &host, &port); | |
1137 | |
1138 if (!msn_switchboard_connect(swboard, host, port)) | |
1139 msn_switchboard_destroy(swboard); | |
1140 | |
1141 g_free(host); | |
1142 } | |
1143 | |
1144 static void | |
1145 xfr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
1146 { | |
1147 MsnSwitchBoard *swboard; | |
1148 int reason = MSN_SB_ERROR_UNKNOWN; | |
1149 | |
1150 if (error == 913) | |
1151 reason = MSN_SB_ERROR_OFFLINE; | |
1152 else if (error == 800) | |
1153 reason = MSN_SB_ERROR_TOO_FAST; | |
1154 | |
1155 swboard = trans->data; | |
1156 | |
1157 gaim_debug_info("msn", "xfr_error %i for %s: trans %x, command %s, reason %i\n", | |
1158 error, (swboard->im_user ? swboard->im_user : "(null)"), trans, | |
1159 (trans->command ? trans->command : "(null)"), reason); | |
1160 | |
1161 swboard_error_helper(swboard, reason, swboard->im_user); | |
1162 } | |
1163 | |
1164 void | |
1165 msn_switchboard_request(MsnSwitchBoard *swboard) | |
1166 { | |
1167 MsnCmdProc *cmdproc; | |
1168 MsnTransaction *trans; | |
1169 | |
1170 g_return_if_fail(swboard != NULL); | |
1171 | |
1172 cmdproc = swboard->session->notification->cmdproc; | |
1173 | |
1174 trans = msn_transaction_new(cmdproc, "XFR", "%s", "SB"); | |
1175 msn_transaction_add_cb(trans, "XFR", got_swboard); | |
1176 | |
1177 msn_transaction_set_data(trans, swboard); | |
1178 msn_transaction_set_error_cb(trans, xfr_error); | |
1179 | |
1180 msn_cmdproc_send_trans(cmdproc, trans); | |
1181 } | |
1182 | |
1183 void | |
1184 msn_switchboard_close(MsnSwitchBoard *swboard) | |
1185 { | |
1186 g_return_if_fail(swboard != NULL); | |
1187 | |
1188 if (swboard->error != MSN_SB_ERROR_NONE) | |
1189 { | |
1190 msn_switchboard_destroy(swboard); | |
1191 } | |
1192 else if (g_queue_is_empty(swboard->msg_queue) || | |
1193 !swboard->session->connected) | |
1194 { | |
1195 MsnCmdProc *cmdproc; | |
1196 cmdproc = swboard->cmdproc; | |
1197 msn_cmdproc_send_quick(cmdproc, "OUT", NULL, NULL); | |
1198 | |
1199 msn_switchboard_destroy(swboard); | |
1200 } | |
1201 else | |
1202 { | |
1203 swboard->closed = TRUE; | |
1204 } | |
1205 } | |
1206 | |
1207 gboolean | |
1208 msn_switchboard_release(MsnSwitchBoard *swboard, MsnSBFlag flag) | |
1209 { | |
1210 g_return_val_if_fail(swboard != NULL, FALSE); | |
1211 | |
1212 swboard->flag &= ~flag; | |
1213 | |
1214 if (flag == MSN_SB_FLAG_IM) | |
1215 /* Forget any conversation that used to be associated with this | |
1216 * swboard. */ | |
1217 swboard->conv = NULL; | |
1218 | |
1219 if (swboard->flag == 0) | |
1220 { | |
1221 msn_switchboard_close(swboard); | |
1222 return TRUE; | |
1223 } | |
1224 | |
1225 return FALSE; | |
1226 } | |
1227 | |
1228 /************************************************************************** | |
1229 * Init stuff | |
1230 **************************************************************************/ | |
1231 | |
1232 void | |
1233 msn_switchboard_init(void) | |
1234 { | |
1235 cbs_table = msn_table_new(); | |
1236 | |
1237 msn_table_add_cmd(cbs_table, "ANS", "ANS", ans_cmd); | |
1238 msn_table_add_cmd(cbs_table, "ANS", "IRO", iro_cmd); | |
1239 | |
1240 msn_table_add_cmd(cbs_table, "MSG", "ACK", ack_cmd); | |
1241 msn_table_add_cmd(cbs_table, "MSG", "NAK", nak_cmd); | |
1242 | |
1243 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); | |
1244 | |
1245 msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd); | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1246 msn_table_add_cmd(cbs_table, NULL, "UBM", ubm_cmd); |
14192 | 1247 msn_table_add_cmd(cbs_table, NULL, "JOI", joi_cmd); |
1248 msn_table_add_cmd(cbs_table, NULL, "BYE", bye_cmd); | |
1249 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd); | |
1250 | |
1251 #if 0 | |
1252 /* They might skip the history */ | |
1253 msn_table_add_cmd(cbs_table, NULL, "ACK", NULL); | |
1254 #endif | |
1255 | |
1256 msn_table_add_error(cbs_table, "MSG", msg_error); | |
1257 msn_table_add_error(cbs_table, "CAL", cal_error); | |
1258 | |
1259 /* Register the message type callbacks. */ | |
1260 msn_table_add_msg_type(cbs_table, "text/plain", | |
1261 plain_msg); | |
1262 msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol", | |
1263 control_msg); | |
1264 msn_table_add_msg_type(cbs_table, "text/x-clientcaps", | |
1265 clientcaps_msg); | |
1266 msn_table_add_msg_type(cbs_table, "text/x-clientinfo", | |
1267 clientcaps_msg); | |
1268 msn_table_add_msg_type(cbs_table, "application/x-msnmsgrp2p", | |
1269 msn_p2p_msg); | |
1270 msn_table_add_msg_type(cbs_table, "text/x-mms-emoticon", | |
1271 msn_emoticon_msg); | |
1272 msn_table_add_msg_type(cbs_table, "text/x-mms-animemoticon", | |
1273 msn_emoticon_msg); | |
1274 msn_table_add_msg_type(cbs_table, "text/x-msnmsgr-datacast", | |
1275 nudge_msg); | |
1276 #if 0 | |
1277 msn_table_add_msg_type(cbs_table, "text/x-msmmsginvite", | |
1278 msn_invite_msg); | |
1279 #endif | |
1280 } | |
1281 | |
1282 void | |
1283 msn_switchboard_end(void) | |
1284 { | |
1285 msn_table_destroy(cbs_table); | |
1286 } |