Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/jabglue.c @ 1014:99c5278bf6b8
Keep the status and status messages when we're disconnected
Improve the automatic reconnection after a network failure.
- AutoConnection is only set to false when the user disconnects
explicitly (i.e. in do_disconnect()).
- AutoConnection is set to TRUE after the 1st successful connection.
- In jb_setstatus(), update the status message and the "wanted status"
even in offline mode. It helps with auto-away.
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sun, 12 Nov 2006 22:25:14 +0100 |
parents | f1a9ca2348e5 |
children | 579299b1c9b2 |
comparison
equal
deleted
inserted
replaced
1013:f1a9ca2348e5 | 1014:99c5278bf6b8 |
---|---|
37 #define JABBERSSLPORT 5223 | 37 #define JABBERSSLPORT 5223 |
38 | 38 |
39 #define RECONNECTION_TIMEOUT 60L | 39 #define RECONNECTION_TIMEOUT 60L |
40 | 40 |
41 jconn jc; | 41 jconn jc; |
42 guint AutoConnection; | |
42 enum enum_jstate jstate; | 43 enum enum_jstate jstate; |
43 | 44 |
44 char imstatus2char[imstatus_size+1] = { | 45 char imstatus2char[imstatus_size+1] = { |
45 '_', 'o', 'i', 'f', 'd', 'n', 'a', '\0' | 46 '_', 'o', 'i', 'f', 'd', 'n', 'a', '\0' |
46 }; | 47 }; |
47 | 48 |
48 static bool AutoConnection; | |
49 static time_t LastPingTime; | 49 static time_t LastPingTime; |
50 static unsigned int KeepaliveDelay; | 50 static unsigned int KeepaliveDelay; |
51 static enum imstatus mystatus = offline; | 51 static enum imstatus mystatus = offline; |
52 static enum imstatus mywantedstatus = available; | |
52 static gchar *mystatusmsg; | 53 static gchar *mystatusmsg; |
53 static unsigned char online; | 54 static unsigned char online; |
54 | 55 |
55 static void statehandler(jconn, int); | 56 static void statehandler(jconn, int); |
56 static void packethandler(jconn, jpacket); | 57 static void packethandler(jconn, jpacket); |
123 jstate = STATE_CONNECTING; | 124 jstate = STATE_CONNECTING; |
124 statehandler(0, -1); | 125 statehandler(0, -1); |
125 jab_start(jc); | 126 jab_start(jc); |
126 } | 127 } |
127 | 128 |
128 if (jc) | |
129 AutoConnection = true; | |
130 | |
131 return jc; | 129 return jc; |
132 } | 130 } |
133 | 131 |
134 void jb_disconnect(void) | 132 void jb_disconnect(void) |
135 { | 133 { |
138 if (online) { | 136 if (online) { |
139 // Announce it to everyone else | 137 // Announce it to everyone else |
140 jb_setstatus(offline, NULL, ""); | 138 jb_setstatus(offline, NULL, ""); |
141 // End the XML flow | 139 // End the XML flow |
142 jb_send_raw("</stream:stream>"); | 140 jb_send_raw("</stream:stream>"); |
141 /* | |
142 // Free status message | |
143 g_free(mystatusmsg); | |
144 mystatusmsg = NULL; | |
145 */ | |
143 } | 146 } |
144 | 147 |
145 // Announce it to the user | 148 // Announce it to the user |
146 statehandler(jc, JCONN_STATE_OFF); | 149 statehandler(jc, JCONN_STATE_OFF); |
147 | 150 |
148 jab_delete(jc); | 151 jab_delete(jc); |
149 jc = NULL; | 152 jc = NULL; |
150 AutoConnection = false; | |
151 } | 153 } |
152 | 154 |
153 inline void jb_reset_keepalive() | 155 inline void jb_reset_keepalive() |
154 { | 156 { |
155 time(&LastPingTime); | 157 time(&LastPingTime); |
179 static void check_connection(void) | 181 static void check_connection(void) |
180 { | 182 { |
181 static time_t disconnection_timestamp = 0L; | 183 static time_t disconnection_timestamp = 0L; |
182 time_t now; | 184 time_t now; |
183 | 185 |
186 // Maybe we're voluntarily offline... | |
187 if (!AutoConnection) | |
188 return; | |
189 | |
184 // Are we totally disconnected? | 190 // Are we totally disconnected? |
185 if (jc && jc->state != JCONN_STATE_OFF) { | 191 if (jc && jc->state != JCONN_STATE_OFF) { |
186 disconnection_timestamp = 0L; | 192 disconnection_timestamp = 0L; |
187 return; | 193 return; |
188 } | 194 } |
189 | |
190 // Maybe we're voluntarily offline... | |
191 if (!AutoConnection) | |
192 return; | |
193 | 195 |
194 time(&now); | 196 time(&now); |
195 if (!disconnection_timestamp) { | 197 if (!disconnection_timestamp) { |
196 disconnection_timestamp = now; | 198 disconnection_timestamp = now; |
197 return; | 199 return; |
401 } | 403 } |
402 | 404 |
403 void jb_setstatus(enum imstatus st, const char *recipient, const char *msg) | 405 void jb_setstatus(enum imstatus st, const char *recipient, const char *msg) |
404 { | 406 { |
405 xmlnode x; | 407 xmlnode x; |
406 | |
407 if (!online) return; | |
408 | 408 |
409 if (msg) { | 409 if (msg) { |
410 // The status message has been specified. We'll use it, unless it is | 410 // The status message has been specified. We'll use it, unless it is |
411 // "-" which is a special case (option meaning "no status message"). | 411 // "-" which is a special case (option meaning "no status message"). |
412 if (!strcmp(msg, "-")) | 412 if (!strcmp(msg, "-")) |
423 else | 423 else |
424 msg = ""; | 424 msg = ""; |
425 } | 425 } |
426 } | 426 } |
427 | 427 |
428 x = presnew(st, recipient, (st != invisible ? msg : NULL)); | 428 // Only send the packet if we're online. |
429 jab_send(jc, x); | 429 // (But we want to update internal status even when disconnected, |
430 xmlnode_free(x); | 430 // in order to avoid some problems during network failures) |
431 if (online) { | |
432 x = presnew(st, recipient, (st != invisible ? msg : NULL)); | |
433 jab_send(jc, x); | |
434 xmlnode_free(x); | |
435 } | |
431 | 436 |
432 // If we didn't change our _global_ status, we are done | 437 // If we didn't change our _global_ status, we are done |
433 if (recipient) return; | 438 if (recipient) return; |
434 | 439 |
435 // Send presence to chatrooms | 440 if (online) { |
436 if (st != invisible) { | 441 // Send presence to chatrooms |
437 struct T_presence room_presence; | 442 if (st != invisible) { |
438 room_presence.st = st; | 443 struct T_presence room_presence; |
439 room_presence.msg = msg; | 444 room_presence.st = st; |
440 foreach_buddy(ROSTER_TYPE_ROOM, &roompresence, &room_presence); | 445 room_presence.msg = msg; |
441 } | 446 foreach_buddy(ROSTER_TYPE_ROOM, &roompresence, &room_presence); |
442 | 447 } |
443 // We'll need to update the roster if we switch to/from offline because | 448 } |
444 // we don't know the presences of buddies when offline... | 449 |
445 if (mystatus == offline || st == offline) | 450 if (online) { |
446 update_roster = TRUE; | 451 // We'll need to update the roster if we switch to/from offline because |
447 | 452 // we don't know the presences of buddies when offline... |
448 hk_mystatuschange(0, mystatus, st, (st != invisible ? msg : "")); | 453 if (mystatus == offline || st == offline) |
449 mystatus = st; | 454 update_roster = TRUE; |
455 | |
456 hk_mystatuschange(0, mystatus, st, (st != invisible ? msg : "")); | |
457 mystatus = st; | |
458 } | |
459 if (st) | |
460 mywantedstatus = st; | |
450 if (msg != mystatusmsg) { | 461 if (msg != mystatusmsg) { |
451 g_free(mystatusmsg); | 462 g_free(mystatusmsg); |
452 if (*msg) | 463 if (*msg) |
453 mystatusmsg = g_strdup(msg); | 464 mystatusmsg = g_strdup(msg); |
454 else | 465 else |
455 mystatusmsg = NULL; | 466 mystatusmsg = NULL; |
456 } | 467 } |
457 | 468 |
458 // Update status line | 469 // Update status line |
459 scr_UpdateMainStatus(TRUE); | 470 scr_UpdateMainStatus(TRUE); |
471 } | |
472 | |
473 // jb_setprevstatus() | |
474 // Set previous status. This wrapper function is used after a disconnection. | |
475 inline void jb_setprevstatus(void) | |
476 { | |
477 jb_setstatus(mywantedstatus, NULL, mystatusmsg); | |
460 } | 478 } |
461 | 479 |
462 // new_msgid() | 480 // new_msgid() |
463 // Generate a new id string. The caller should free it. | 481 // Generate a new id string. The caller should free it. |
464 static char *new_msgid(void) | 482 static char *new_msgid(void) |
1370 switch(state) { | 1388 switch(state) { |
1371 case JCONN_STATE_OFF: | 1389 case JCONN_STATE_OFF: |
1372 if (previous_state != JCONN_STATE_OFF) | 1390 if (previous_state != JCONN_STATE_OFF) |
1373 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Not connected to the server"); | 1391 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Not connected to the server"); |
1374 | 1392 |
1393 // Sometimes the state isn't correctly updated | |
1394 if (jc) | |
1395 jc->state = JCONN_STATE_OFF; | |
1375 online = FALSE; | 1396 online = FALSE; |
1376 mystatus = offline; | 1397 mystatus = offline; |
1377 // Free status message | |
1378 g_free(mystatusmsg); | |
1379 mystatusmsg = NULL; | |
1380 // Free bookmarks | 1398 // Free bookmarks |
1381 xmlnode_free(bookmarks); | 1399 xmlnode_free(bookmarks); |
1382 bookmarks = NULL; | 1400 bookmarks = NULL; |
1383 // Free roster | 1401 // Free roster |
1384 roster_free(); | 1402 roster_free(); |
1397 | 1415 |
1398 case JCONN_STATE_ON: | 1416 case JCONN_STATE_ON: |
1399 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Communication with the server " | 1417 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Communication with the server " |
1400 "established"); | 1418 "established"); |
1401 online = TRUE; | 1419 online = TRUE; |
1420 // We set AutoConnection to true after the 1st successful connection | |
1421 AutoConnection = true; | |
1402 break; | 1422 break; |
1403 | 1423 |
1404 case JCONN_STATE_CONNECTING: | 1424 case JCONN_STATE_CONNECTING: |
1405 if (previous_state != state) | 1425 if (previous_state != state) |
1406 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connecting to the server"); | 1426 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connecting to the server"); |