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 }