Mercurial > pidgin
comparison src/protocols/msn/switchboard.c @ 10345:2e01c503aa4f
[gaim-migrate @ 11556]
Patch 1078151 from Felipe Contreras to fix some more MSN bugs:
"User Dislpay messages, and other less used, did not set
an slpcall, so the callback that should not be called,
was called (in some very special cases)."
...
"Here it goes the real real one, as far as I can tell.
Cleaning + organizing + documentation + hard bug fix = big
patch." -- Felipe Contreras
I also fixed drag-and-drop to conversation window file transfers (which
I had broken when I fixed some other dnd thing), made the debug output
of the autoreconnect plugin more useful, and stopped the message
notification plugin notifying you for messages sent by ignored users.
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sat, 11 Dec 2004 20:01:58 +0000 |
parents | 56cc5d49472b |
children | bbf738a0ce7b |
comparison
equal
deleted
inserted
replaced
10344:5976491e07a7 | 10345:2e01c503aa4f |
---|---|
29 | 29 |
30 #include "error.h" | 30 #include "error.h" |
31 | 31 |
32 static MsnTable *cbs_table; | 32 static MsnTable *cbs_table; |
33 | 33 |
34 static void cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error); | 34 static void msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, |
35 MsnMsgErrorType error); | |
36 | |
37 /************************************************************************** | |
38 * Main stuff | |
39 **************************************************************************/ | |
40 MsnSwitchBoard * | |
41 msn_switchboard_new(MsnSession *session) | |
42 { | |
43 MsnSwitchBoard *swboard; | |
44 MsnServConn *servconn; | |
45 MsnCmdProc *cmdproc; | |
46 | |
47 g_return_val_if_fail(session != NULL, NULL); | |
48 | |
49 swboard = g_new0(MsnSwitchBoard, 1); | |
50 | |
51 swboard->session = session; | |
52 swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVER_SB); | |
53 cmdproc = servconn->cmdproc; | |
54 | |
55 swboard->im_queue = g_queue_new(); | |
56 swboard->empty = TRUE; | |
57 | |
58 servconn->data = swboard; | |
59 | |
60 session->switches = g_list_append(session->switches, swboard); | |
61 | |
62 cmdproc->cbs_table = cbs_table; | |
63 | |
64 return swboard; | |
65 } | |
66 | |
67 void | |
68 msn_switchboard_destroy(MsnSwitchBoard *swboard) | |
69 { | |
70 MsnSession *session; | |
71 MsnMessage *msg; | |
72 GList *l; | |
73 | |
74 g_return_if_fail(swboard != NULL); | |
75 | |
76 if (swboard->destroying) | |
77 return; | |
78 | |
79 swboard->destroying = TRUE; | |
80 | |
81 /* If it linked us is because its looking for trouble */ | |
82 if (swboard->slplink != NULL) | |
83 msn_slplink_destroy(swboard->slplink); | |
84 | |
85 /* Destroy the message queue */ | |
86 while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL) | |
87 { | |
88 if (swboard->error != MSN_SB_ERROR_NONE) | |
89 { | |
90 /* The messages could not be sent due to a switchboard error */ | |
91 msg_error_helper(swboard->servconn->cmdproc, msg, | |
92 MSN_MSG_ERROR_SB); | |
93 } | |
94 msn_message_destroy(msg); | |
95 } | |
96 | |
97 g_queue_free(swboard->im_queue); | |
98 | |
99 if (swboard->im_user != NULL) | |
100 g_free(swboard->im_user); | |
101 | |
102 if (swboard->auth_key != NULL) | |
103 g_free(swboard->auth_key); | |
104 | |
105 if (swboard->session_id != NULL) | |
106 g_free(swboard->session_id); | |
107 | |
108 for (l = swboard->users; l != NULL; l = l->next) | |
109 g_free(l->data); | |
110 | |
111 session = swboard->session; | |
112 session->switches = g_list_remove(session->switches, swboard); | |
113 | |
114 if (swboard->servconn != NULL) | |
115 msn_servconn_destroy(swboard->servconn); | |
116 | |
117 g_free(swboard); | |
118 } | |
119 | |
120 void | |
121 msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key) | |
122 { | |
123 g_return_if_fail(swboard != NULL); | |
124 g_return_if_fail(key != NULL); | |
125 | |
126 swboard->auth_key = g_strdup(key); | |
127 } | |
128 | |
129 const char * | |
130 msn_switchboard_get_auth_key(MsnSwitchBoard *swboard) | |
131 { | |
132 g_return_val_if_fail(swboard != NULL, NULL); | |
133 | |
134 return swboard->auth_key; | |
135 } | |
136 | |
137 void | |
138 msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id) | |
139 { | |
140 g_return_if_fail(swboard != NULL); | |
141 g_return_if_fail(id != NULL); | |
142 | |
143 if (swboard->session_id != NULL) | |
144 g_free(swboard->session_id); | |
145 | |
146 swboard->session_id = g_strdup(id); | |
147 } | |
148 | |
149 const char * | |
150 msn_switchboard_get_session_id(MsnSwitchBoard *swboard) | |
151 { | |
152 g_return_val_if_fail(swboard != NULL, NULL); | |
153 | |
154 return swboard->session_id; | |
155 } | |
156 | |
157 void | |
158 msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited) | |
159 { | |
160 g_return_if_fail(swboard != NULL); | |
161 | |
162 swboard->invited = invited; | |
163 } | |
164 | |
165 gboolean | |
166 msn_switchboard_is_invited(MsnSwitchBoard *swboard) | |
167 { | |
168 g_return_val_if_fail(swboard != NULL, FALSE); | |
169 | |
170 return swboard->invited; | |
171 } | |
35 | 172 |
36 /************************************************************************** | 173 /************************************************************************** |
37 * Utility functions | 174 * Utility functions |
38 **************************************************************************/ | 175 **************************************************************************/ |
39 static void | 176 static void |
66 swboard->current_users++; | 203 swboard->current_users++; |
67 | 204 |
68 /* gaim_debug_info("msn", "user=[%s], total=%d\n", user, | 205 /* gaim_debug_info("msn", "user=[%s], total=%d\n", user, |
69 * swboard->current_users); */ | 206 * swboard->current_users); */ |
70 | 207 |
71 if ((swboard->conv != NULL) && (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_CHAT)) | 208 if ((swboard->conv != NULL) && |
72 { | 209 (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_CHAT)) |
73 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL, GAIM_CBFLAGS_NONE, TRUE); | 210 { |
211 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL, | |
212 GAIM_CBFLAGS_NONE, TRUE); | |
74 } | 213 } |
75 else if (swboard->current_users > 1 || swboard->total_users > 1) | 214 else if (swboard->current_users > 1 || swboard->total_users > 1) |
76 { | 215 { |
77 if (swboard->conv == NULL || | 216 if (swboard->conv == NULL || |
78 gaim_conversation_get_type(swboard->conv) != GAIM_CONV_CHAT) | 217 gaim_conversation_get_type(swboard->conv) != GAIM_CONV_CHAT) |
125 gaim_debug_warning("msn", "This should not happen!" | 264 gaim_debug_warning("msn", "This should not happen!" |
126 "(msn_switchboard_add_user)\n"); | 265 "(msn_switchboard_add_user)\n"); |
127 } | 266 } |
128 } | 267 } |
129 | 268 |
269 GaimConversation * | |
270 msn_switchboard_get_conv(MsnSwitchBoard *swboard) | |
271 { | |
272 GaimAccount *account; | |
273 | |
274 g_return_val_if_fail(swboard != NULL, NULL); | |
275 | |
276 if (swboard->conv != NULL) | |
277 return swboard->conv; | |
278 | |
279 gaim_debug_error("msn", "Switchboard with unnasigned conversation\n"); | |
280 | |
281 account = swboard->session->account; | |
282 | |
283 /* XXX - I think this should probably be GAIM_CONV_IM, but I'm hedging */ | |
284 return gaim_find_conversation_with_account(GAIM_CONV_IM, | |
285 swboard->im_user, account); | |
286 } | |
287 | |
288 void | |
289 msn_switchboard_report_user(MsnSwitchBoard *swboard, GaimMessageFlags flags, const char *msg) | |
290 { | |
291 GaimConversation *conv; | |
292 | |
293 g_return_if_fail(swboard != NULL); | |
294 g_return_if_fail(msg != NULL); | |
295 | |
296 if ((conv = msn_switchboard_get_conv(swboard)) != NULL) | |
297 { | |
298 gaim_conversation_write(conv, NULL, msg, flags, time(NULL)); | |
299 } | |
300 } | |
301 | |
302 static void | |
303 swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport) | |
304 { | |
305 gaim_debug_info("msg", "Error: Unable to call the user %s\n", passport); | |
306 | |
307 if (swboard->total_users == 0) | |
308 { | |
309 swboard->error = reason; | |
310 msn_switchboard_destroy(swboard); | |
311 } | |
312 } | |
313 | |
314 static void | |
315 cal_error_helper(MsnTransaction *trans, int reason) | |
316 { | |
317 MsnSwitchBoard *swboard; | |
318 const char *passport; | |
319 char **params; | |
320 | |
321 params = g_strsplit(trans->params, " ", 0); | |
322 | |
323 passport = params[0]; | |
324 | |
325 swboard = trans->data; | |
326 | |
327 swboard_error_helper(swboard, reason, passport); | |
328 | |
329 g_strfreev(params); | |
330 } | |
331 | |
332 static void | |
333 msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error) | |
334 { | |
335 g_return_if_fail(cmdproc != NULL); | |
336 g_return_if_fail(msg != NULL); | |
337 | |
338 if (msg->nak_cb != NULL) | |
339 msg->nak_cb(msg, msg->ack_data); | |
340 | |
341 if (msg->type == MSN_MSG_TEXT) | |
342 { | |
343 MsnSwitchBoard *swboard; | |
344 char *body; | |
345 char *report; | |
346 char *str_reason; | |
347 | |
348 swboard = cmdproc->servconn->data; | |
349 | |
350 #if 0 | |
351 if (swboard->conv == NULL) | |
352 { | |
353 msn_message_unref(msg); | |
354 return; | |
355 } | |
356 #endif | |
357 | |
358 if (msg->error == MSN_MSG_ERROR_TIMEOUT) | |
359 { | |
360 str_reason = _("Message may have not been sent " | |
361 "because a time out occured."); | |
362 } | |
363 else if (msg->error == MSN_MSG_ERROR_SB) | |
364 { | |
365 switch (swboard->error) | |
366 { | |
367 case MSN_SB_ERROR_OFFLINE: | |
368 str_reason = _("Message could not be sent, " | |
369 "not allowed while invisible"); | |
370 break; | |
371 case MSN_SB_ERROR_USER_OFFLINE: | |
372 str_reason = _("Message could not be sent " | |
373 "because the user is offline"); | |
374 break; | |
375 case MSN_SB_ERROR_CONNECTION: | |
376 str_reason = _("Message could not be sent " | |
377 "because a connection error occured"); | |
378 break; | |
379 default: | |
380 str_reason = _("Message could not be sent " | |
381 "because an error with " | |
382 "the switchboard occured"); | |
383 break; | |
384 } | |
385 } | |
386 else | |
387 { | |
388 str_reason = _("Message may have not been sent " | |
389 "because an unkwown error occured"); | |
390 } | |
391 | |
392 body = msn_message_to_string(msg); | |
393 report = g_strdup_printf(_("%s:\n%s"), str_reason, body); | |
394 | |
395 msn_switchboard_report_user(cmdproc->servconn->data, | |
396 GAIM_MESSAGE_ERROR, report); | |
397 | |
398 g_free(report); | |
399 g_free(body); | |
400 | |
401 msn_message_unref(msg); | |
402 } | |
403 else if (msg->type == MSN_MSG_SLP) | |
404 { | |
405 msn_message_unref(msg); | |
406 } | |
407 | |
408 } | |
409 | |
130 /************************************************************************** | 410 /************************************************************************** |
131 * Switchboard Commands | 411 * Switchboard Commands |
132 **************************************************************************/ | 412 **************************************************************************/ |
133 static void | 413 static void |
134 ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | 414 ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
137 | 417 |
138 swboard = cmdproc->servconn->data; | 418 swboard = cmdproc->servconn->data; |
139 swboard->ready = TRUE; | 419 swboard->ready = TRUE; |
140 } | 420 } |
141 | 421 |
142 GaimConversation * | |
143 msn_switchboard_get_conv(MsnSwitchBoard *swboard) | |
144 { | |
145 GaimAccount *account; | |
146 | |
147 g_return_val_if_fail(swboard != NULL, NULL); | |
148 | |
149 if (swboard->conv != NULL) | |
150 return swboard->conv; | |
151 | |
152 account = swboard->session->account; | |
153 | |
154 /* XXX - I think this should probably be GAIM_CONV_IM, but I'm hedging */ | |
155 return gaim_find_conversation_with_account(GAIM_CONV_IM, | |
156 swboard->im_user, account); | |
157 } | |
158 | |
159 void | |
160 msn_switchboard_report_user(MsnSwitchBoard *swboard, GaimMessageFlags flags, const char *msg) | |
161 { | |
162 GaimConversation *conv; | |
163 | |
164 g_return_if_fail(swboard != NULL); | |
165 g_return_if_fail(msg != NULL); | |
166 | |
167 if ((conv = msn_switchboard_get_conv(swboard)) != NULL) | |
168 { | |
169 gaim_conversation_write(conv, NULL, msg, flags, time(NULL)); | |
170 } | |
171 } | |
172 | |
173 static void | 422 static void |
174 bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | 423 bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
175 { | 424 { |
176 MsnSwitchBoard *swboard; | 425 MsnSwitchBoard *swboard; |
177 const char *user; | 426 const char *user; |
178 | 427 |
179 swboard = cmdproc->servconn->data; | 428 swboard = cmdproc->servconn->data; |
180 user = cmd->params[0]; | 429 user = cmd->params[0]; |
181 | 430 |
182 if (swboard->hidden) | 431 if (swboard->conv == NULL) |
183 return; | 432 { |
184 | 433 /* This is a helper switchboard */ |
185 if (swboard->current_users > 1) | 434 msn_switchboard_disconnect(swboard); |
186 { | 435 } |
436 else if (swboard->current_users > 1) | |
437 { | |
438 /* This is a switchboard used for a chat */ | |
187 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->conv), user, NULL); | 439 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->conv), user, NULL); |
188 } | 440 } |
189 else | 441 else |
190 { | 442 { |
443 /* This is a switchboard used for a im session */ | |
444 | |
191 char *str = NULL; | 445 char *str = NULL; |
192 | 446 |
193 if (cmd->param_count == 2 && atoi(cmd->params[1]) == 1) | 447 if (cmd->param_count == 2 && atoi(cmd->params[1]) == 1) |
194 { | 448 { |
195 if (gaim_prefs_get_bool("/plugins/prpl/msn/conv_timeout_notice")) | 449 if (gaim_prefs_get_bool("/plugins/prpl/msn/conv_timeout_notice")) |
259 gc = account->gc; | 513 gc = account->gc; |
260 swboard = cmdproc->servconn->data; | 514 swboard = cmdproc->servconn->data; |
261 | 515 |
262 msn_switchboard_add_user(swboard, passport); | 516 msn_switchboard_add_user(swboard, passport); |
263 | 517 |
264 swboard->user_joined = TRUE; | 518 swboard->empty = FALSE; |
265 | |
266 /* msn_cmdproc_process_queue(cmdproc); */ | |
267 | 519 |
268 msn_switchboard_process_queue(swboard); | 520 msn_switchboard_process_queue(swboard); |
269 | 521 |
270 send_clientcaps(swboard); | 522 send_clientcaps(swboard); |
271 } | 523 } |
297 } | 549 } |
298 | 550 |
299 static void | 551 static void |
300 nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | 552 nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
301 { | 553 { |
302 /* | 554 MsnMessage *msg; |
303 gaim_notify_error(cmdproc->session->account->gc, NULL, | 555 |
304 _("A MSN message may not have been received."), NULL); | 556 msg = cmd->trans->data; |
305 */ | 557 g_return_if_fail(msg != NULL); |
558 | |
559 msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_NAK); | |
306 } | 560 } |
307 | 561 |
308 static void | 562 static void |
309 ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | 563 ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
310 { | 564 { |
311 #if 0 | |
312 MsnMessage *msg; | 565 MsnMessage *msg; |
313 const char *body; | 566 |
314 | 567 msg = cmd->trans->data; |
315 msg = msn_message_new(); | 568 |
316 msn_message_parse_payload(msg, cmd->trans->payload, cmd->trans->payload_len); | 569 if (msg->ack_cb != NULL) |
317 | 570 msg->ack_cb(msg, msg->ack_data); |
318 body = msn_message_get_body(msg); | 571 |
319 | 572 msn_message_unref(msg); |
320 gaim_debug_info("msn", "ACK: {%s}\n", body); | |
321 | |
322 msn_message_destroy(msg); | |
323 #endif | |
324 } | 573 } |
325 | 574 |
326 static void | 575 static void |
327 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | 576 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
328 { | 577 { |
360 swboard->ready = TRUE; | 609 swboard->ready = TRUE; |
361 msn_cmdproc_process_queue(cmdproc); | 610 msn_cmdproc_process_queue(cmdproc); |
362 } | 611 } |
363 | 612 |
364 /************************************************************************** | 613 /************************************************************************** |
365 * Message Types | 614 * Message Handlers |
366 **************************************************************************/ | 615 **************************************************************************/ |
367 static void | 616 static void |
368 plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | 617 plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
369 { | 618 { |
370 GaimConnection *gc; | 619 GaimConnection *gc; |
465 | 714 |
466 clientcaps = msn_message_get_hashtable_from_body(msg); | 715 clientcaps = msn_message_get_hashtable_from_body(msg); |
467 #endif | 716 #endif |
468 } | 717 } |
469 | 718 |
470 static void | 719 /************************************************************************** |
471 msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg) | 720 * Message stuff |
472 { | 721 **************************************************************************/ |
473 if (msg->type == MSN_MSG_TEXT) | 722 /** Called when a message times out. */ |
474 { | |
475 MsnSwitchBoard *swboard; | |
476 char *body; | |
477 char *report; | |
478 char *str_reason; | |
479 | |
480 swboard = cmdproc->servconn->data; | |
481 | |
482 switch (swboard->error) | |
483 { | |
484 case MSN_SB_ERROR_OFFLINE: | |
485 str_reason = _("Message could not be sent, not allowed while invisible"); | |
486 break; | |
487 case MSN_SB_ERROR_USER_OFFLINE: | |
488 str_reason = _("Message could not be sent because the user is offline"); | |
489 break; | |
490 case MSN_SB_ERROR_CONNECTION: | |
491 str_reason = _("Message could not be sent because a connection error occured"); | |
492 break; | |
493 default: | |
494 str_reason = _("Message could not be sent for an unknown reason"); | |
495 break; | |
496 } | |
497 | |
498 body = msn_message_to_string(msg); | |
499 report = g_strdup_printf(_("%s:\n%s"), str_reason, body); | |
500 gaim_debug_info("msn", "%s\n", report); | |
501 msn_switchboard_report_user(cmdproc->servconn->data, GAIM_MESSAGE_ERROR, report); | |
502 g_free(report); | |
503 g_free(body); | |
504 } | |
505 } | |
506 | |
507 static void | 723 static void |
508 msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) | 724 msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) |
509 { | 725 { |
510 MsnMessage *msg; | 726 MsnMessage *msg; |
511 | 727 |
512 msg = trans->data; | 728 msg = trans->data; |
513 g_return_if_fail(msg != NULL); | 729 |
514 | 730 msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT); |
515 gaim_debug_info("msn", "msg_timeout\n"); | 731 } |
516 msg_error_helper(cmdproc, msg); | 732 |
517 } | 733 /** Called when we receive an error of a message. */ |
518 | |
519 static void | 734 static void |
520 msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | 735 msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
521 { | 736 { |
522 msg_error_helper(cmdproc, trans->data); | 737 msg_error_helper(cmdproc, trans->data, MSN_MSG_ERROR_UNKNOWN); |
523 } | 738 } |
524 | 739 |
525 static void | 740 #if 0 |
526 msg_ack (MsnCmdProc *cmdproc, MsnCommand *cmd) | 741 /** Called when we receive an ack of a special message. */ |
742 static void | |
743 msg_ack(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
527 { | 744 { |
528 MsnMessage *msg; | 745 MsnMessage *msg; |
529 | 746 |
530 msg = cmd->trans->data; | 747 msg = cmd->trans->data; |
531 | 748 |
532 if (msg->ack_cb != NULL) | 749 if (msg->ack_cb != NULL) |
533 msg->ack_cb(msg->ack_data); | 750 msg->ack_cb(msg->ack_data); |
534 | 751 |
535 msn_message_unref(msg); | 752 msn_message_unref(msg); |
536 } | 753 } |
754 | |
755 /** Called when we receive a nak of a special message. */ | |
756 static void | |
757 msg_nak(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
758 { | |
759 MsnMessage *msg; | |
760 | |
761 msg = cmd->trans->data; | |
762 | |
763 msn_message_unref(msg); | |
764 } | |
765 #endif | |
537 | 766 |
538 void | 767 void |
539 msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg) | 768 msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg) |
540 { | 769 { |
541 MsnCmdProc *cmdproc; | 770 MsnCmdProc *cmdproc; |
555 trans = msn_transaction_new(cmdproc, "MSG", "%c %d", | 784 trans = msn_transaction_new(cmdproc, "MSG", "%c %d", |
556 msn_message_get_flag(msg), payload_len); | 785 msn_message_get_flag(msg), payload_len); |
557 | 786 |
558 /* Data for callbacks */ | 787 /* Data for callbacks */ |
559 msn_transaction_set_data(trans, msg); | 788 msn_transaction_set_data(trans, msg); |
560 msn_message_ref(msg); | 789 |
561 | 790 if (msg->type == MSN_MSG_TEXT) |
562 if (msg->ack_cb != NULL) | 791 { |
563 { | 792 msn_message_ref(msg); |
564 msn_transaction_add_cb(trans, "ACK", msg_ack); | |
565 msn_transaction_set_timeout_cb(trans, msg_timeout); | 793 msn_transaction_set_timeout_cb(trans, msg_timeout); |
566 } | 794 } |
567 else if (msg->type == MSN_MSG_TEXT) | 795 else if (msg->type == MSN_MSG_SLP) |
796 { | |
797 msn_message_ref(msg); | |
568 msn_transaction_set_timeout_cb(trans, msg_timeout); | 798 msn_transaction_set_timeout_cb(trans, msg_timeout); |
799 #if 0 | |
800 if (msg->ack_cb != NULL) | |
801 { | |
802 msn_transaction_add_cb(trans, "ACK", msg_ack); | |
803 msn_transaction_add_cb(trans, "NAK", msg_nak); | |
804 } | |
805 #endif | |
806 } | |
569 | 807 |
570 trans->payload = payload; | 808 trans->payload = payload; |
571 trans->payload_len = payload_len; | 809 trans->payload_len = payload_len; |
572 | 810 |
573 msg->trans = trans; | 811 msg->trans = trans; |
622 | 860 |
623 account = servconn->session->account; | 861 account = servconn->session->account; |
624 swboard = servconn->data; | 862 swboard = servconn->data; |
625 g_return_if_fail(swboard != NULL); | 863 g_return_if_fail(swboard != NULL); |
626 | 864 |
627 swboard->user_joined = TRUE; | 865 swboard->empty = FALSE; |
628 | 866 |
629 if (msn_switchboard_is_invited(swboard)) | 867 if (msn_switchboard_is_invited(swboard)) |
630 { | 868 { |
631 msn_cmdproc_send(cmdproc, "ANS", "%s %s %s", | 869 msn_cmdproc_send(cmdproc, "ANS", "%s %s %s", |
632 gaim_account_get_username(account), | 870 gaim_account_get_username(account), |
649 g_return_if_fail(swboard != NULL); | 887 g_return_if_fail(swboard != NULL); |
650 | 888 |
651 msn_switchboard_destroy(swboard); | 889 msn_switchboard_destroy(swboard); |
652 } | 890 } |
653 | 891 |
892 gboolean | |
893 msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port) | |
894 { | |
895 g_return_val_if_fail(swboard != NULL, FALSE); | |
896 | |
897 msn_servconn_set_connect_cb(swboard->servconn, connect_cb); | |
898 | |
899 return msn_servconn_connect(swboard->servconn, host, port); | |
900 } | |
901 | |
902 void | |
903 msn_switchboard_disconnect(MsnSwitchBoard *swboard) | |
904 { | |
905 g_return_if_fail(swboard != NULL); | |
906 | |
907 msn_servconn_set_disconnect_cb(swboard->servconn, disconnect_cb); | |
908 | |
909 msn_servconn_disconnect(swboard->servconn); | |
910 } | |
911 | |
912 /************************************************************************** | |
913 * Call stuff | |
914 **************************************************************************/ | |
915 #if 0 | |
916 static void | |
917 got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
918 { | |
919 MsnSwitchBoard *swboard; | |
920 const char *user; | |
921 | |
922 swboard = cmdproc->servconn->data; | |
923 | |
924 user = cmd->params[0]; | |
925 | |
926 msn_switchboard_add_user(swboard, user); | |
927 } | |
928 #endif | |
929 | |
930 static void | |
931 cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) | |
932 { | |
933 cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN); | |
934 } | |
935 | |
936 static void | |
937 cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
938 { | |
939 int reason = MSN_SB_ERROR_UNKNOWN; | |
940 | |
941 if (error == 217) | |
942 reason = MSN_SB_ERROR_USER_OFFLINE; | |
943 | |
944 cal_error_helper(trans, reason); | |
945 } | |
946 | |
947 void | |
948 msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user) | |
949 { | |
950 MsnTransaction *trans; | |
951 MsnCmdProc *cmdproc; | |
952 | |
953 g_return_if_fail(swboard != NULL); | |
954 | |
955 cmdproc = swboard->servconn->cmdproc; | |
956 | |
957 trans = msn_transaction_new(cmdproc, "CAL", "%s", user); | |
958 /* msn_transaction_add_cb(trans, "CAL", got_cal); */ | |
959 | |
960 msn_transaction_set_data(trans, swboard); | |
961 msn_transaction_set_timeout_cb(trans, cal_timeout); | |
962 | |
963 if (swboard->ready) | |
964 msn_cmdproc_send_trans(cmdproc, trans); | |
965 else | |
966 msn_cmdproc_queue_trans(cmdproc, trans); | |
967 } | |
968 | |
969 /************************************************************************** | |
970 * Create & Transfer stuff | |
971 **************************************************************************/ | |
972 static void | |
973 got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
974 { | |
975 MsnSwitchBoard *swboard; | |
976 char *host; | |
977 int port; | |
978 swboard = cmd->trans->data; | |
979 | |
980 msn_switchboard_set_auth_key(swboard, cmd->params[4]); | |
981 | |
982 msn_parse_socket(cmd->params[2], &host, &port); | |
983 | |
984 if (swboard->session->http_method) | |
985 { | |
986 GaimAccount *account; | |
987 MsnSession *session; | |
988 MsnServConn *servconn; | |
989 | |
990 port = 80; | |
991 | |
992 session = swboard->session; | |
993 servconn = swboard->servconn; | |
994 account = session->account; | |
995 | |
996 swboard->empty = FALSE; | |
997 | |
998 servconn->http_data->gateway_host = g_strdup(host); | |
999 | |
1000 #if 0 | |
1001 servconn->connected = TRUE; | |
1002 servconn->cmdproc->ready = TRUE; | |
1003 #endif | |
1004 | |
1005 if (msn_switchboard_is_invited(swboard)) | |
1006 { | |
1007 msn_cmdproc_send(servconn->cmdproc, "ANS", "%s %s %s", | |
1008 gaim_account_get_username(account), | |
1009 swboard->auth_key, swboard->session_id); | |
1010 } | |
1011 else | |
1012 { | |
1013 msn_cmdproc_send(servconn->cmdproc, "USR", "%s %s", | |
1014 gaim_account_get_username(account), | |
1015 swboard->auth_key); | |
1016 } | |
1017 } | |
1018 | |
1019 msn_switchboard_connect(swboard, host, port); | |
1020 | |
1021 g_free(host); | |
1022 } | |
1023 | |
1024 static void | |
1025 xfr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
1026 { | |
1027 MsnSwitchBoard *swboard; | |
1028 int reason = MSN_SB_ERROR_UNKNOWN; | |
1029 | |
1030 if (error == 913) | |
1031 reason = MSN_SB_ERROR_OFFLINE; | |
1032 | |
1033 swboard = trans->data; | |
1034 | |
1035 swboard_error_helper(swboard, reason, swboard->im_user); | |
1036 } | |
1037 | |
1038 void | |
1039 msn_switchboard_request(MsnSwitchBoard *swboard) | |
1040 { | |
1041 MsnCmdProc *cmdproc; | |
1042 MsnTransaction *trans; | |
1043 | |
1044 g_return_if_fail(swboard != NULL); | |
1045 | |
1046 cmdproc = swboard->session->notification->cmdproc; | |
1047 | |
1048 trans = msn_transaction_new(cmdproc, "XFR", "%s", "SB"); | |
1049 msn_transaction_add_cb(trans, "XFR", got_swboard); | |
1050 msn_transaction_set_data(trans, swboard); | |
1051 msn_transaction_set_error_cb(trans, xfr_error); | |
1052 | |
1053 msn_cmdproc_send_trans(cmdproc, trans); | |
1054 } | |
1055 | |
1056 /************************************************************************** | |
1057 * Init stuff | |
1058 **************************************************************************/ | |
654 void | 1059 void |
655 msn_switchboard_init(void) | 1060 msn_switchboard_init(void) |
656 { | 1061 { |
657 cbs_table = msn_table_new(); | 1062 cbs_table = msn_table_new(); |
658 | 1063 |
699 void | 1104 void |
700 msn_switchboard_end(void) | 1105 msn_switchboard_end(void) |
701 { | 1106 { |
702 msn_table_destroy(cbs_table); | 1107 msn_table_destroy(cbs_table); |
703 } | 1108 } |
704 | |
705 MsnSwitchBoard * | |
706 msn_switchboard_new(MsnSession *session) | |
707 { | |
708 MsnSwitchBoard *swboard; | |
709 MsnServConn *servconn; | |
710 MsnCmdProc *cmdproc; | |
711 | |
712 g_return_val_if_fail(session != NULL, NULL); | |
713 | |
714 swboard = g_new0(MsnSwitchBoard, 1); | |
715 | |
716 swboard->session = session; | |
717 swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVER_SB); | |
718 cmdproc = servconn->cmdproc; | |
719 | |
720 swboard->im_queue = g_queue_new(); | |
721 | |
722 if (session->http_method) | |
723 servconn->http_data->server_type = "SB"; | |
724 else | |
725 msn_servconn_set_connect_cb(servconn, connect_cb); | |
726 | |
727 msn_servconn_set_disconnect_cb(servconn, disconnect_cb); | |
728 | |
729 servconn->data = swboard; | |
730 | |
731 session->switches = g_list_append(session->switches, swboard); | |
732 | |
733 cmdproc->cbs_table = cbs_table; | |
734 | |
735 return swboard; | |
736 } | |
737 | |
738 void | |
739 msn_switchboard_destroy(MsnSwitchBoard *swboard) | |
740 { | |
741 MsnSession *session; | |
742 MsnMessage *msg; | |
743 GList *l; | |
744 | |
745 g_return_if_fail(swboard != NULL); | |
746 | |
747 if (swboard->destroying) | |
748 return; | |
749 | |
750 swboard->destroying = TRUE; | |
751 | |
752 /* Destroy the message queue */ | |
753 while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL) | |
754 { | |
755 if (swboard->error > 0) | |
756 { | |
757 /* The messages could not be sent due to an error */ | |
758 msg_error_helper(swboard->servconn->cmdproc, msg); | |
759 } | |
760 msn_message_destroy(msg); | |
761 } | |
762 | |
763 g_queue_free(swboard->im_queue); | |
764 | |
765 if (swboard->im_user != NULL) | |
766 g_free(swboard->im_user); | |
767 | |
768 if (swboard->auth_key != NULL) | |
769 g_free(swboard->auth_key); | |
770 | |
771 if (swboard->session_id != NULL) | |
772 g_free(swboard->session_id); | |
773 | |
774 for (l = swboard->users; l != NULL; l = l->next) | |
775 g_free(l->data); | |
776 | |
777 session = swboard->session; | |
778 session->switches = g_list_remove(session->switches, swboard); | |
779 | |
780 if (swboard->servconn != NULL) | |
781 msn_servconn_destroy(swboard->servconn); | |
782 | |
783 g_free(swboard); | |
784 } | |
785 | |
786 #if 0 | |
787 static void | |
788 got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
789 { | |
790 MsnSwitchBoard *swboard; | |
791 const char *user; | |
792 | |
793 swboard = cmdproc->servconn->data; | |
794 | |
795 user = cmd->params[0]; | |
796 | |
797 msn_switchboard_add_user(swboard, user); | |
798 } | |
799 #endif | |
800 | |
801 static void | |
802 swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport) | |
803 { | |
804 gaim_debug_info("msg", "Error: Unable to call the user %s\n", passport); | |
805 | |
806 if (swboard->total_users == 0) | |
807 { | |
808 swboard->error = reason; | |
809 msn_switchboard_destroy(swboard); | |
810 } | |
811 } | |
812 | |
813 static void | |
814 cal_error_helper(MsnTransaction *trans, int reason) | |
815 { | |
816 MsnSwitchBoard *swboard; | |
817 const char *passport; | |
818 char **params; | |
819 | |
820 params = g_strsplit(trans->params, " ", 0); | |
821 | |
822 passport = params[0]; | |
823 | |
824 swboard = trans->data; | |
825 | |
826 swboard_error_helper(swboard, reason, passport); | |
827 | |
828 g_strfreev(params); | |
829 } | |
830 | |
831 static void | |
832 cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) | |
833 { | |
834 cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN); | |
835 } | |
836 | |
837 static void | |
838 cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
839 { | |
840 int reason = MSN_SB_ERROR_UNKNOWN; | |
841 | |
842 if (error == 217) | |
843 reason = MSN_SB_ERROR_USER_OFFLINE; | |
844 | |
845 cal_error_helper(trans, reason); | |
846 } | |
847 | |
848 void | |
849 msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user) | |
850 { | |
851 MsnTransaction *trans; | |
852 MsnCmdProc *cmdproc; | |
853 | |
854 g_return_if_fail(swboard != NULL); | |
855 | |
856 cmdproc = swboard->servconn->cmdproc; | |
857 | |
858 trans = msn_transaction_new(cmdproc, "CAL", "%s", user); | |
859 /* msn_transaction_add_cb(trans, "CAL", got_cal); */ | |
860 | |
861 msn_transaction_set_data(trans, swboard); | |
862 msn_transaction_set_timeout_cb(trans, cal_timeout); | |
863 | |
864 if (swboard->ready) | |
865 msn_cmdproc_send_trans(cmdproc, trans); | |
866 else | |
867 msn_cmdproc_queue_trans(cmdproc, trans); | |
868 } | |
869 | |
870 void | |
871 msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key) | |
872 { | |
873 g_return_if_fail(swboard != NULL); | |
874 g_return_if_fail(key != NULL); | |
875 | |
876 swboard->auth_key = g_strdup(key); | |
877 } | |
878 | |
879 const char * | |
880 msn_switchboard_get_auth_key(MsnSwitchBoard *swboard) | |
881 { | |
882 g_return_val_if_fail(swboard != NULL, NULL); | |
883 | |
884 return swboard->auth_key; | |
885 } | |
886 | |
887 void | |
888 msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id) | |
889 { | |
890 g_return_if_fail(swboard != NULL); | |
891 g_return_if_fail(id != NULL); | |
892 | |
893 if (swboard->session_id != NULL) | |
894 g_free(swboard->session_id); | |
895 | |
896 swboard->session_id = g_strdup(id); | |
897 } | |
898 | |
899 const char * | |
900 msn_switchboard_get_session_id(MsnSwitchBoard *swboard) | |
901 { | |
902 g_return_val_if_fail(swboard != NULL, NULL); | |
903 | |
904 return swboard->session_id; | |
905 } | |
906 | |
907 void | |
908 msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited) | |
909 { | |
910 g_return_if_fail(swboard != NULL); | |
911 | |
912 swboard->invited = invited; | |
913 } | |
914 | |
915 gboolean | |
916 msn_switchboard_is_invited(MsnSwitchBoard *swboard) | |
917 { | |
918 g_return_val_if_fail(swboard != NULL, FALSE); | |
919 | |
920 return swboard->invited; | |
921 } | |
922 | |
923 gboolean | |
924 msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port) | |
925 { | |
926 g_return_val_if_fail(swboard != NULL, FALSE); | |
927 | |
928 return msn_servconn_connect(swboard->servconn, host, port); | |
929 } | |
930 | |
931 void | |
932 msn_switchboard_disconnect(MsnSwitchBoard *swboard) | |
933 { | |
934 g_return_if_fail(swboard != NULL); | |
935 | |
936 msn_servconn_disconnect(swboard->servconn); | |
937 } | |
938 | |
939 static void | |
940 got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
941 { | |
942 MsnSwitchBoard *swboard; | |
943 char *host; | |
944 int port; | |
945 swboard = cmd->trans->data; | |
946 | |
947 msn_switchboard_set_auth_key(swboard, cmd->params[4]); | |
948 | |
949 msn_parse_socket(cmd->params[2], &host, &port); | |
950 | |
951 if (swboard->session->http_method) | |
952 { | |
953 GaimAccount *account; | |
954 MsnSession *session; | |
955 MsnServConn *servconn; | |
956 | |
957 port = 80; | |
958 | |
959 session = swboard->session; | |
960 servconn = swboard->servconn; | |
961 account = session->account; | |
962 | |
963 swboard->user_joined = TRUE; | |
964 | |
965 servconn->http_data->gateway_host = g_strdup(host); | |
966 | |
967 #if 0 | |
968 servconn->connected = TRUE; | |
969 servconn->cmdproc->ready = TRUE; | |
970 #endif | |
971 | |
972 if (msn_switchboard_is_invited(swboard)) | |
973 { | |
974 msn_cmdproc_send(servconn->cmdproc, "ANS", "%s %s %s", | |
975 gaim_account_get_username(account), | |
976 swboard->auth_key, swboard->session_id); | |
977 } | |
978 else | |
979 { | |
980 msn_cmdproc_send(servconn->cmdproc, "USR", "%s %s", | |
981 gaim_account_get_username(account), | |
982 swboard->auth_key); | |
983 } | |
984 } | |
985 | |
986 msn_switchboard_connect(swboard, host, port); | |
987 | |
988 g_free(host); | |
989 } | |
990 | |
991 static void | |
992 xfr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) | |
993 { | |
994 MsnSwitchBoard *swboard; | |
995 int reason = MSN_SB_ERROR_UNKNOWN; | |
996 | |
997 if (error == 913) | |
998 reason = MSN_SB_ERROR_OFFLINE; | |
999 | |
1000 swboard = trans->data; | |
1001 | |
1002 swboard_error_helper(swboard, reason, swboard->im_user); | |
1003 } | |
1004 | |
1005 void | |
1006 msn_switchboard_request(MsnSwitchBoard *swboard) | |
1007 { | |
1008 MsnCmdProc *cmdproc; | |
1009 MsnTransaction *trans; | |
1010 | |
1011 g_return_if_fail(swboard != NULL); | |
1012 | |
1013 cmdproc = swboard->session->notification->cmdproc; | |
1014 | |
1015 trans = msn_transaction_new(cmdproc, "XFR", "%s", "SB"); | |
1016 msn_transaction_add_cb(trans, "XFR", got_swboard); | |
1017 msn_transaction_set_data(trans, swboard); | |
1018 msn_transaction_set_error_cb(trans, xfr_error); | |
1019 | |
1020 msn_cmdproc_send_trans(cmdproc, trans); | |
1021 } |