Mercurial > pidgin.yaz
annotate libgaim/protocols/msn/switchboard.c @ 20392:9ba7dee775e1
The first msn-p13-merge-head.diff.gz from SF Patch #1621854 from Ka-Hing Cheung.
"uploaded a diff, this diff is unchanged from the last tarball that I
previously uploaded, except that it's against HEAD. This should be a little
easier for most people."
(This was apparently msn-p13-merge-head.diff, which SourceForge didn't allow to
be uploaded.)
PLUS
"Updated the diff with basically no change, except with simom's icon fix.
The previous diff was broken because some of the files were not added"
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Sun, 15 Apr 2007 03:01:41 +0000 |
parents | d634f88e25d8 |
children |
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" | |
20392
9ba7dee775e1
The first msn-p13-merge-head.diff.gz from SF Patch #1621854 from Ka-Hing Cheung.
Richard Laager <rlaager@wiktel.com>
parents:
20390
diff
changeset
|
28 #include "msnutils.h" |
14192 | 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 | |
20392
9ba7dee775e1
The first msn-p13-merge-head.diff.gz from SF Patch #1621854 from Ka-Hing Cheung.
Richard Laager <rlaager@wiktel.com>
parents:
20390
diff
changeset
|
649 /* cmdproc->data is set to NULL when the switchboard is destroyed; |
9ba7dee775e1
The first msn-p13-merge-head.diff.gz from SF Patch #1621854 from Ka-Hing Cheung.
Richard Laager <rlaager@wiktel.com>
parents:
20390
diff
changeset
|
650 * we may get a bye shortly thereafter. */ |
9ba7dee775e1
The first msn-p13-merge-head.diff.gz from SF Patch #1621854 from Ka-Hing Cheung.
Richard Laager <rlaager@wiktel.com>
parents:
20390
diff
changeset
|
651 g_return_if_fail(swboard != NULL); |
9ba7dee775e1
The first msn-p13-merge-head.diff.gz from SF Patch #1621854 from Ka-Hing Cheung.
Richard Laager <rlaager@wiktel.com>
parents:
20390
diff
changeset
|
652 |
14192 | 653 if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL)) |
654 gaim_debug_error("msn_switchboard", "bye_cmd: helper bug\n"); | |
655 | |
656 if (swboard->conv == NULL) | |
657 { | |
658 /* This is a helper switchboard */ | |
659 msn_switchboard_destroy(swboard); | |
660 } | |
661 else if ((swboard->current_users > 1) || | |
662 (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) | |
663 { | |
664 /* This is a switchboard used for a chat */ | |
665 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->conv), user, NULL); | |
666 swboard->current_users--; | |
667 if (swboard->current_users == 0) | |
668 msn_switchboard_destroy(swboard); | |
669 } | |
670 else | |
671 { | |
672 /* This is a switchboard used for a im session */ | |
673 msn_switchboard_destroy(swboard); | |
674 } | |
675 } | |
676 | |
677 static void | |
678 iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
679 { | |
680 GaimAccount *account; | |
681 GaimConnection *gc; | |
682 MsnSwitchBoard *swboard; | |
683 | |
684 account = cmdproc->session->account; | |
685 gc = account->gc; | |
686 swboard = cmdproc->data; | |
687 | |
688 swboard->total_users = atoi(cmd->params[2]); | |
689 | |
690 msn_switchboard_add_user(swboard, cmd->params[3]); | |
691 } | |
692 | |
693 static void | |
694 joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
695 { | |
696 MsnSession *session; | |
697 GaimAccount *account; | |
698 GaimConnection *gc; | |
699 MsnSwitchBoard *swboard; | |
700 const char *passport; | |
701 | |
702 passport = cmd->params[0]; | |
703 | |
704 session = cmdproc->session; | |
705 account = session->account; | |
706 gc = account->gc; | |
707 swboard = cmdproc->data; | |
708 | |
709 msn_switchboard_add_user(swboard, passport); | |
710 | |
711 process_queue(swboard); | |
712 | |
713 if (!session->http_method) | |
714 send_clientcaps(swboard); | |
715 | |
716 if (swboard->closed) | |
717 msn_switchboard_close(swboard); | |
718 } | |
719 | |
720 static void | |
721 msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) | |
722 { | |
723 MsnMessage *msg; | |
724 | |
725 msg = msn_message_new_from_cmd(cmdproc->session, cmd); | |
726 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
727 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
|
728 MSG_LINE_DEM,MSG_BODY_DEM); |
14192 | 729 #ifdef MSN_DEBUG_SB |
730 msn_message_show_readable(msg, "SB RECV", FALSE); | |
731 #endif | |
732 | |
733 if (msg->remote_user != NULL) | |
734 g_free (msg->remote_user); | |
735 | |
736 msg->remote_user = g_strdup(cmd->params[0]); | |
737 msn_cmdproc_process_msg(cmdproc, msg); | |
738 | |
739 msn_message_destroy(msg); | |
740 } | |
741 | |
742 static void | |
743 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
744 { | |
745 cmdproc->servconn->payload_len = atoi(cmd->params[2]); | |
746 cmdproc->last_cmd->payload_cb = msg_cmd_post; | |
747 } | |
748 | |
749 static void | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
750 ubm_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
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 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
|
753 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
|
754 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
|
755 } |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
756 |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
757 static void |
14192 | 758 nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
759 { | |
760 MsnMessage *msg; | |
761 | |
762 msg = cmd->trans->data; | |
763 g_return_if_fail(msg != NULL); | |
764 | |
765 msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_NAK); | |
766 } | |
767 | |
768 static void | |
769 ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
770 { | |
771 MsnSwitchBoard *swboard; | |
772 MsnMessage *msg; | |
773 | |
774 msg = cmd->trans->data; | |
775 | |
776 if (msg->ack_cb != NULL) | |
777 msg->ack_cb(msg, msg->ack_data); | |
778 | |
779 swboard = cmdproc->data; | |
780 swboard->ack_list = g_list_remove(swboard->ack_list, msg); | |
781 msn_message_unref(msg); | |
782 } | |
783 | |
784 static void | |
785 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
786 { | |
787 GaimConnection *gc; | |
788 MsnSwitchBoard *swboard; | |
789 | |
790 gc = cmdproc->session->account->gc; | |
791 swboard = cmdproc->data; | |
792 | |
793 if (swboard->current_users > 1) | |
794 serv_got_chat_left(gc, swboard->chat_id); | |
795 | |
796 msn_switchboard_disconnect(swboard); | |
797 } | |
798 | |
799 static void | |
800 usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
801 { | |
802 MsnSwitchBoard *swboard; | |
803 | |
804 swboard = cmdproc->data; | |
805 | |
806 #if 0 | |
807 GList *l; | |
808 | |
809 for (l = swboard->users; l != NULL; l = l->next) | |
810 { | |
811 const char *user; | |
812 user = l->data; | |
813 | |
814 msn_cmdproc_send(cmdproc, "CAL", "%s", user); | |
815 } | |
816 #endif | |
817 | |
818 swboard->ready = TRUE; | |
819 msn_cmdproc_process_queue(cmdproc); | |
820 } | |
821 | |
822 /************************************************************************** | |
823 * Message Handlers | |
824 **************************************************************************/ | |
825 static void | |
826 plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
827 { | |
828 GaimConnection *gc; | |
829 MsnSwitchBoard *swboard; | |
830 const char *body; | |
831 char *body_str; | |
832 char *body_enc; | |
833 char *body_final; | |
834 size_t body_len; | |
835 const char *passport; | |
836 const char *value; | |
837 | |
838 gc = cmdproc->session->account->gc; | |
839 swboard = cmdproc->data; | |
840 | |
841 body = msn_message_get_bin_data(msg, &body_len); | |
842 body_str = g_strndup(body, body_len); | |
843 body_enc = g_markup_escape_text(body_str, -1); | |
844 g_free(body_str); | |
845 | |
846 passport = msg->remote_user; | |
847 | |
848 if (!strcmp(passport, "messenger@microsoft.com") && | |
849 strstr(body, "immediate security update")) | |
850 { | |
851 return; | |
852 } | |
853 | |
854 #if 0 | |
855 if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL) | |
856 { | |
857 gaim_debug_misc("msn", "User-Agent = '%s'\n", value); | |
858 } | |
859 #endif | |
860 | |
861 if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL) | |
862 { | |
863 char *pre, *post; | |
864 | |
865 msn_parse_format(value, &pre, &post); | |
866 | |
867 body_final = g_strdup_printf("%s%s%s", pre ? pre : "", | |
868 body_enc ? body_enc : "", post ? post : ""); | |
869 | |
870 g_free(pre); | |
871 g_free(post); | |
872 g_free(body_enc); | |
873 } | |
874 else | |
875 { | |
876 body_final = body_enc; | |
877 } | |
878 | |
879 swboard->flag |= MSN_SB_FLAG_IM; | |
880 | |
881 if (swboard->current_users > 1 || | |
882 ((swboard->conv != NULL) && | |
883 gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) | |
884 { | |
885 /* If current_users is always ok as it should then there is no need to | |
886 * check if this is a chat. */ | |
887 if (swboard->current_users <= 1) | |
888 gaim_debug_misc("msn", "plain_msg: current_users(%d)\n", | |
889 swboard->current_users); | |
890 | |
891 serv_got_chat_in(gc, swboard->chat_id, passport, 0, body_final, | |
892 time(NULL)); | |
893 if (swboard->conv == NULL) | |
894 { | |
895 swboard->conv = gaim_find_chat(gc, swboard->chat_id); | |
896 swboard->flag |= MSN_SB_FLAG_IM; | |
897 } | |
898 } | |
899 else | |
900 { | |
901 serv_got_im(gc, passport, body_final, 0, time(NULL)); | |
902 if (swboard->conv == NULL) | |
903 { | |
904 swboard->conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, | |
905 passport, gaim_connection_get_account(gc)); | |
906 swboard->flag |= MSN_SB_FLAG_IM; | |
907 } | |
908 } | |
909 | |
910 g_free(body_final); | |
911 } | |
912 | |
913 static void | |
914 control_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
915 { | |
916 GaimConnection *gc; | |
917 MsnSwitchBoard *swboard; | |
918 char *passport; | |
919 | |
920 gc = cmdproc->session->account->gc; | |
921 swboard = cmdproc->data; | |
922 passport = msg->remote_user; | |
923 | |
924 if (swboard->current_users == 1 && | |
925 msn_message_get_attr(msg, "TypingUser") != NULL) | |
926 { | |
927 serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT, | |
928 GAIM_TYPING); | |
929 } | |
930 } | |
931 | |
932 static void | |
933 clientcaps_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
934 { | |
935 #if 0 | |
936 MsnSession *session; | |
937 MsnSwitchBoard *swboard; | |
938 MsnUser *user; | |
939 GHashTable *clientcaps; | |
940 const char *value; | |
941 | |
942 char *passport = msg->sender; | |
943 | |
944 session = cmdproc->session; | |
945 swboard = cmdproc->servconn->swboard; | |
946 | |
947 clientcaps = msn_message_get_hashtable_from_body(msg); | |
948 #endif | |
949 } | |
950 | |
951 static void | |
952 nudge_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
953 { | |
954 MsnSwitchBoard *swboard; | |
955 char *username, *str; | |
956 GaimAccount *account; | |
957 GaimBuddy *buddy; | |
958 const char *user; | |
959 | |
960 swboard = cmdproc->data; | |
961 account = cmdproc->session->account; | |
962 user = msg->remote_user; | |
963 | |
964 if ((buddy = gaim_find_buddy(account, user)) != NULL) | |
965 username = g_markup_escape_text(gaim_buddy_get_alias(buddy), -1); | |
966 else | |
967 username = g_markup_escape_text(user, -1); | |
968 | |
969 str = g_strdup_printf(_("%s just sent you a Nudge!"), username); | |
970 g_free(username); | |
971 msn_switchboard_report_user(swboard, GAIM_MESSAGE_SYSTEM, str); | |
972 g_free(str); | |
973 } | |
974 | |
975 /************************************************************************** | |
976 * Connect stuff | |
977 **************************************************************************/ | |
978 static void | |
979 connect_cb(MsnServConn *servconn) | |
980 { | |
981 MsnSwitchBoard *swboard; | |
982 MsnCmdProc *cmdproc; | |
983 GaimAccount *account; | |
984 | |
985 cmdproc = servconn->cmdproc; | |
986 g_return_if_fail(cmdproc != NULL); | |
987 | |
988 account = cmdproc->session->account; | |
989 swboard = cmdproc->data; | |
990 g_return_if_fail(swboard != NULL); | |
991 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
992 if (msn_switchboard_is_invited(swboard)){ |
14192 | 993 swboard->empty = FALSE; |
994 | |
995 msn_cmdproc_send(cmdproc, "ANS", "%s %s %s", | |
996 gaim_account_get_username(account), | |
997 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
|
998 }else{ |
14192 | 999 msn_cmdproc_send(cmdproc, "USR", "%s %s", |
1000 gaim_account_get_username(account), | |
1001 swboard->auth_key); | |
1002 } | |
1003 } | |
1004 | |
1005 static void | |
1006 disconnect_cb(MsnServConn *servconn) | |
1007 { | |
1008 MsnSwitchBoard *swboard; | |
1009 | |
1010 swboard = servconn->cmdproc->data; | |
1011 g_return_if_fail(swboard != NULL); | |
1012 | |
1013 msn_servconn_set_disconnect_cb(swboard->servconn, NULL); | |
1014 | |
1015 msn_switchboard_destroy(swboard); | |
1016 } | |
1017 | |
1018 gboolean | |
1019 msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port) | |
1020 { | |
1021 g_return_val_if_fail(swboard != NULL, FALSE); | |
1022 | |
1023 msn_servconn_set_connect_cb(swboard->servconn, connect_cb); | |
1024 msn_servconn_set_disconnect_cb(swboard->servconn, disconnect_cb); | |
1025 | |
1026 return msn_servconn_connect(swboard->servconn, host, port); | |
1027 } | |
1028 | |
1029 void | |
1030 msn_switchboard_disconnect(MsnSwitchBoard *swboard) | |
1031 { | |
1032 g_return_if_fail(swboard != NULL); | |
1033 | |
1034 msn_servconn_disconnect(swboard->servconn); | |
1035 } | |
1036 | |
1037 /************************************************************************** | |
1038 * Call stuff | |
1039 **************************************************************************/ | |
1040 static void | |
1041 got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
1042 { | |
1043 #if 0 | |
1044 MsnSwitchBoard *swboard; | |
1045 const char *user; | |
1046 | |
1047 swboard = cmdproc->data; | |
1048 | |
1049 user = cmd->params[0]; | |
1050 | |
1051 msn_switchboard_add_user(swboard, user); | |
1052 #endif | |
1053 } | |
1054 | |
1055 static void | |
1056 cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) | |
1057 { | |
1058 gaim_debug_warning("msn", "cal_timeout: command %s timed out\n", trans->command); | |
1059 | |
1060 cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN); | |
1061 } | |
1062 | |
1063 static void | |
1064 cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
1065 { | |
1066 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
|
1067 MsnMessage *msg; |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1068 MsnSwitchBoard *swboard = trans->data; |
14192 | 1069 |
1070 if (error == 215) | |
1071 { | |
1072 gaim_debug_info("msn", "Invited user already in switchboard\n"); | |
1073 return; | |
1074 } | |
1075 else if (error == 217) | |
1076 { | |
1077 reason = MSN_SB_ERROR_USER_OFFLINE; | |
1078 } | |
1079 | |
1080 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
|
1081 gaim_debug_warning("msn", "Will Use Offline Message to sendit\n"); |
14192 | 1082 |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1083 // cal_error_helper(trans, reason); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1084 /*offline Message send Process*/ |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1085 |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1086 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
|
1087 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
|
1088 /* 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
|
1089 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
|
1090 msg_error_helper(swboard->cmdproc, msg, |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1091 MSN_MSG_ERROR_SB); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1092 msn_message_unref(msg); |
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1093 } |
14192 | 1094 cal_error_helper(trans, reason); |
1095 } | |
1096 | |
1097 void | |
1098 msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user) | |
1099 { | |
1100 MsnTransaction *trans; | |
1101 MsnCmdProc *cmdproc; | |
1102 | |
1103 g_return_if_fail(swboard != NULL); | |
1104 | |
1105 cmdproc = swboard->cmdproc; | |
1106 | |
1107 trans = msn_transaction_new(cmdproc, "CAL", "%s", user); | |
1108 /* this doesn't do anything, but users seem to think that | |
1109 * 'Unhandled command' is some kind of error, so we don't report it */ | |
1110 msn_transaction_add_cb(trans, "CAL", got_cal); | |
1111 | |
1112 msn_transaction_set_data(trans, swboard); | |
1113 msn_transaction_set_timeout_cb(trans, cal_timeout); | |
1114 | |
1115 if (swboard->ready) | |
1116 msn_cmdproc_send_trans(cmdproc, trans); | |
1117 else | |
1118 msn_cmdproc_queue_trans(cmdproc, trans); | |
1119 } | |
1120 | |
1121 /************************************************************************** | |
1122 * Create & Transfer stuff | |
1123 **************************************************************************/ | |
1124 | |
1125 static void | |
1126 got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
1127 { | |
1128 MsnSwitchBoard *swboard; | |
1129 char *host; | |
1130 int port; | |
1131 swboard = cmd->trans->data; | |
1132 | |
1133 if (g_list_find(cmdproc->session->switches, swboard) == NULL) | |
1134 /* The conversation window was closed. */ | |
1135 return; | |
1136 | |
20389
e354528c4163
propagate from branch 'im.pidgin.gaim' (head 70ac931e4936c7916eec18a07fe46a0af0fd7403)
Richard Laager <rlaager@wiktel.com>
parents:
15286
diff
changeset
|
1137 gaim_debug_info("MaYuan","Switchboard:auth:{%s} socket:{%s}\n",cmd->params[4],cmd->params[2]); |
14192 | 1138 msn_switchboard_set_auth_key(swboard, cmd->params[4]); |
1139 | |
1140 msn_parse_socket(cmd->params[2], &host, &port); | |
1141 | |
1142 if (!msn_switchboard_connect(swboard, host, port)) | |
1143 msn_switchboard_destroy(swboard); | |
1144 | |
1145 g_free(host); | |
1146 } | |
1147 | |
1148 static void | |
1149 xfr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
1150 { | |
1151 MsnSwitchBoard *swboard; | |
1152 int reason = MSN_SB_ERROR_UNKNOWN; | |
1153 | |
1154 if (error == 913) | |
1155 reason = MSN_SB_ERROR_OFFLINE; | |
1156 else if (error == 800) | |
1157 reason = MSN_SB_ERROR_TOO_FAST; | |
1158 | |
1159 swboard = trans->data; | |
1160 | |
1161 gaim_debug_info("msn", "xfr_error %i for %s: trans %x, command %s, reason %i\n", | |
1162 error, (swboard->im_user ? swboard->im_user : "(null)"), trans, | |
1163 (trans->command ? trans->command : "(null)"), reason); | |
1164 | |
1165 swboard_error_helper(swboard, reason, swboard->im_user); | |
1166 } | |
1167 | |
1168 void | |
1169 msn_switchboard_request(MsnSwitchBoard *swboard) | |
1170 { | |
1171 MsnCmdProc *cmdproc; | |
1172 MsnTransaction *trans; | |
1173 | |
1174 g_return_if_fail(swboard != NULL); | |
1175 | |
1176 cmdproc = swboard->session->notification->cmdproc; | |
1177 | |
1178 trans = msn_transaction_new(cmdproc, "XFR", "%s", "SB"); | |
1179 msn_transaction_add_cb(trans, "XFR", got_swboard); | |
1180 | |
1181 msn_transaction_set_data(trans, swboard); | |
1182 msn_transaction_set_error_cb(trans, xfr_error); | |
1183 | |
1184 msn_cmdproc_send_trans(cmdproc, trans); | |
1185 } | |
1186 | |
1187 void | |
1188 msn_switchboard_close(MsnSwitchBoard *swboard) | |
1189 { | |
1190 g_return_if_fail(swboard != NULL); | |
1191 | |
1192 if (swboard->error != MSN_SB_ERROR_NONE) | |
1193 { | |
1194 msn_switchboard_destroy(swboard); | |
1195 } | |
1196 else if (g_queue_is_empty(swboard->msg_queue) || | |
1197 !swboard->session->connected) | |
1198 { | |
1199 MsnCmdProc *cmdproc; | |
1200 cmdproc = swboard->cmdproc; | |
1201 msn_cmdproc_send_quick(cmdproc, "OUT", NULL, NULL); | |
1202 | |
1203 msn_switchboard_destroy(swboard); | |
1204 } | |
1205 else | |
1206 { | |
1207 swboard->closed = TRUE; | |
1208 } | |
1209 } | |
1210 | |
1211 gboolean | |
1212 msn_switchboard_release(MsnSwitchBoard *swboard, MsnSBFlag flag) | |
1213 { | |
1214 g_return_val_if_fail(swboard != NULL, FALSE); | |
1215 | |
1216 swboard->flag &= ~flag; | |
1217 | |
1218 if (flag == MSN_SB_FLAG_IM) | |
1219 /* Forget any conversation that used to be associated with this | |
1220 * swboard. */ | |
1221 swboard->conv = NULL; | |
1222 | |
1223 if (swboard->flag == 0) | |
1224 { | |
1225 msn_switchboard_close(swboard); | |
1226 return TRUE; | |
1227 } | |
1228 | |
1229 return FALSE; | |
1230 } | |
1231 | |
1232 /************************************************************************** | |
1233 * Init stuff | |
1234 **************************************************************************/ | |
1235 | |
1236 void | |
1237 msn_switchboard_init(void) | |
1238 { | |
1239 cbs_table = msn_table_new(); | |
1240 | |
1241 msn_table_add_cmd(cbs_table, "ANS", "ANS", ans_cmd); | |
1242 msn_table_add_cmd(cbs_table, "ANS", "IRO", iro_cmd); | |
1243 | |
1244 msn_table_add_cmd(cbs_table, "MSG", "ACK", ack_cmd); | |
1245 msn_table_add_cmd(cbs_table, "MSG", "NAK", nak_cmd); | |
1246 | |
1247 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); | |
1248 | |
1249 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
|
1250 msn_table_add_cmd(cbs_table, NULL, "UBM", ubm_cmd); |
14192 | 1251 msn_table_add_cmd(cbs_table, NULL, "JOI", joi_cmd); |
1252 msn_table_add_cmd(cbs_table, NULL, "BYE", bye_cmd); | |
1253 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd); | |
1254 | |
1255 #if 0 | |
1256 /* They might skip the history */ | |
1257 msn_table_add_cmd(cbs_table, NULL, "ACK", NULL); | |
1258 #endif | |
1259 | |
1260 msn_table_add_error(cbs_table, "MSG", msg_error); | |
1261 msn_table_add_error(cbs_table, "CAL", cal_error); | |
1262 | |
1263 /* Register the message type callbacks. */ | |
1264 msn_table_add_msg_type(cbs_table, "text/plain", | |
1265 plain_msg); | |
1266 msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol", | |
1267 control_msg); | |
1268 msn_table_add_msg_type(cbs_table, "text/x-clientcaps", | |
1269 clientcaps_msg); | |
1270 msn_table_add_msg_type(cbs_table, "text/x-clientinfo", | |
1271 clientcaps_msg); | |
1272 msn_table_add_msg_type(cbs_table, "application/x-msnmsgrp2p", | |
1273 msn_p2p_msg); | |
1274 msn_table_add_msg_type(cbs_table, "text/x-mms-emoticon", | |
1275 msn_emoticon_msg); | |
1276 msn_table_add_msg_type(cbs_table, "text/x-mms-animemoticon", | |
1277 msn_emoticon_msg); | |
1278 msn_table_add_msg_type(cbs_table, "text/x-msnmsgr-datacast", | |
1279 nudge_msg); | |
1280 #if 0 | |
1281 msn_table_add_msg_type(cbs_table, "text/x-msmmsginvite", | |
1282 msn_invite_msg); | |
1283 #endif | |
1284 } | |
1285 | |
1286 void | |
1287 msn_switchboard_end(void) | |
1288 { | |
1289 msn_table_destroy(cbs_table); | |
1290 } |