| 76 i++; |
76 i++; |
| 77 } |
77 } |
| 78 gaim_debug(GAIM_DEBUG_INFO, "QQ", "%d packets in sendqueue are freed!\n", i); |
78 gaim_debug(GAIM_DEBUG_INFO, "QQ", "%d packets in sendqueue are freed!\n", i); |
| 79 } |
79 } |
| 80 |
80 |
| 81 /* packet lost, agree to send again. |
81 /* TODO drop get buddy list if we don't know about any buddies... |
| 82 * it is removed only when ack-ed by server */ |
82 * I think the server won't ACK a get buddies request if we have none */ |
| 83 static void _qq_send_again(gc_and_packet *gp) |
|
| 84 { |
|
| 85 GaimConnection *gc; |
|
| 86 qq_data *qd; |
|
| 87 qq_sendpacket *packet; |
|
| 88 GList *list; |
|
| 89 |
|
| 90 g_return_if_fail(gp != NULL && gp->gc != NULL && gp->packet != NULL); |
|
| 91 g_return_if_fail(gp->gc->proto_data != NULL); |
|
| 92 |
|
| 93 gc = gp->gc; |
|
| 94 packet = gp->packet; |
|
| 95 qd = (qq_data *) gc->proto_data; |
|
| 96 |
|
| 97 list = g_list_find(qd->sendqueue, packet); |
|
| 98 if (list != NULL) { |
|
| 99 packet->resend_times = 0; |
|
| 100 packet->sendtime = time(NULL); |
|
| 101 qq_proxy_write(qd, packet->buf, packet->len); |
|
| 102 } |
|
| 103 g_free(gp); |
|
| 104 } |
|
| 105 |
|
| 106 /* packet lost, do not send again */ |
|
| 107 static void _qq_send_cancel(gc_and_packet *gp) |
|
| 108 { |
|
| 109 GaimConnection *gc; |
|
| 110 qq_data *qd; |
|
| 111 qq_sendpacket *packet; |
|
| 112 GList *list; |
|
| 113 |
|
| 114 g_return_if_fail(gp != NULL && gp->gc != NULL && gp->packet != NULL); |
|
| 115 g_return_if_fail(gp->gc->proto_data != NULL); |
|
| 116 |
|
| 117 gc = gp->gc; |
|
| 118 packet = gp->packet; |
|
| 119 qd = (qq_data *) gc->proto_data; |
|
| 120 |
|
| 121 list = g_list_find(qd->sendqueue, packet); |
|
| 122 if (list != NULL) |
|
| 123 qq_sendqueue_remove(qd, packet->send_seq); |
|
| 124 |
|
| 125 g_free(gp); |
|
| 126 } |
|
| 127 |
|
| 128 static void _notify_packets_lost(GaimConnection *gc, const gchar *msg, qq_sendpacket *p) |
|
| 129 { |
|
| 130 gc_and_packet *gp; |
|
| 131 |
|
| 132 gp = g_new0(gc_and_packet, 1); |
|
| 133 gp->gc = gc; |
|
| 134 gp->packet = p; |
|
| 135 gaim_request_action |
|
| 136 (gc, NULL, _("Communication timed out"), msg, |
|
| 137 0, gp, 2, _("Try again"), G_CALLBACK(_qq_send_again), |
|
| 138 _("Cancel"), G_CALLBACK(_qq_send_cancel)); |
|
| 139 /* keep in sendqueue doing nothing until we hear back from the user */ |
|
| 140 p->resend_times++; |
|
| 141 } |
|
| 142 |
|
| 143 gboolean qq_sendqueue_timeout_callback(gpointer data) |
83 gboolean qq_sendqueue_timeout_callback(gpointer data) |
| 144 { |
84 { |
| 145 GaimConnection *gc; |
85 GaimConnection *gc; |
| 146 qq_data *qd; |
86 qq_data *qd; |
| 147 GList *list; |
87 GList *list; |
| 171 } |
111 } |
| 172 |
112 |
| 173 list = qd->sendqueue; |
113 list = qd->sendqueue; |
| 174 while (list != NULL) { |
114 while (list != NULL) { |
| 175 p = (qq_sendpacket *) list->data; |
115 p = (qq_sendpacket *) list->data; |
| 176 if (p->resend_times >= QQ_RESEND_MAX) { |
116 if (p->resend_times == QQ_RESEND_MAX) { /* reach max */ |
| 177 if (p->resend_times == QQ_RESEND_MAX) { /* reach max */ |
117 switch (p->cmd) { |
| 178 switch (p->cmd) { |
118 case QQ_CMD_KEEP_ALIVE: |
| 179 case QQ_CMD_KEEP_ALIVE: |
119 if (qd->logged_in) { |
| 180 if (qd->logged_in) { |
120 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Connection lost!\n"); |
| 181 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Connection lost!\n"); |
121 gaim_connection_error(gc, _("Connection lost")); |
| 182 gaim_connection_error(gc, _("Connection lost")); |
122 qd->logged_in = FALSE; |
| 183 qd->logged_in = FALSE; |
|
| 184 } |
|
| 185 p->resend_times = -1; |
|
| 186 break; |
|
| 187 case QQ_CMD_LOGIN: |
|
| 188 case QQ_CMD_REQUEST_LOGIN_TOKEN: |
|
| 189 if (!qd->logged_in) /* cancel logging progress */ |
|
| 190 gaim_connection_error(gc, _("Login failed, no reply")); |
|
| 191 p->resend_times = -1; |
|
| 192 break; |
|
| 193 case QQ_CMD_UPDATE_INFO: |
|
| 194 _notify_packets_lost(gc, |
|
| 195 _("Your attempt to update your info has timed out. Send the information again?"), p); |
|
| 196 break; |
|
| 197 case QQ_CMD_GET_USER_INFO: |
|
| 198 _notify_packets_lost(gc, |
|
| 199 _("Your attempt to view a user's info has timed out. Try again?"), p); |
|
| 200 break; |
|
| 201 case QQ_CMD_ADD_FRIEND_WO_AUTH: |
|
| 202 _notify_packets_lost(gc, |
|
| 203 _("Your attempt to add a buddy has timed out. Try again?"), p); |
|
| 204 break; |
|
| 205 case QQ_CMD_DEL_FRIEND: |
|
| 206 _notify_packets_lost(gc, |
|
| 207 _("Your attempt to remove a buddy has timed out. Try again?"), p); |
|
| 208 break; |
|
| 209 case QQ_CMD_BUDDY_AUTH: |
|
| 210 _notify_packets_lost(gc, |
|
| 211 _("Your attempt to add a buddy has timed out. Try again?"), p); |
|
| 212 break; |
|
| 213 case QQ_CMD_CHANGE_ONLINE_STATUS: |
|
| 214 _notify_packets_lost(gc, |
|
| 215 _("Your attempt to change your online status has timed out. Send the information again?"), p); |
|
| 216 break; |
|
| 217 case QQ_CMD_SEND_IM: |
|
| 218 _notify_packets_lost(gc, |
|
| 219 _("Your attempt to send an IM has timed out. Send it again?"), p); |
|
| 220 break; |
|
| 221 case QQ_CMD_REQUEST_KEY: |
|
| 222 _notify_packets_lost(gc, |
|
| 223 _("Your request for a file transfer key has timed out. Request it again?"), p); |
|
| 224 break; |
|
| 225 default:{ |
|
| 226 p->resend_times = -1; /* it will be removed next time */ |
|
| 227 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "%s packet lost!\n", qq_get_cmd_desc(p->cmd)); |
|
| 228 } |
|
| 229 } |
123 } |
| |
124 p->resend_times = -1; |
| |
125 break; |
| |
126 case QQ_CMD_LOGIN: |
| |
127 case QQ_CMD_REQUEST_LOGIN_TOKEN: |
| |
128 if (!qd->logged_in) /* cancel login progress */ |
| |
129 gaim_connection_error(gc, _("Login failed, no reply")); |
| |
130 p->resend_times = -1; |
| |
131 break; |
| |
132 default:{ |
| |
133 gaim_debug(GAIM_DEBUG_WARNING, "QQ", |
| |
134 "%s packet sent %d times but not acked. Resetting sendqueue life\n", |
| |
135 qq_get_cmd_desc(p->cmd), QQ_RESEND_MAX); |
| |
136 } |
| |
137 p->resend_times = 0; |
| 230 } |
138 } |
| 231 } else { /* resend_times < QQ_RESEND_MAX, so sent it again */ |
139 } else { /* resend_times < QQ_RESEND_MAX, so sent it again */ |
| 232 wait_time = (gint) (QQ_SENDQUEUE_TIMEOUT / 1000); |
140 wait_time = (gint) (QQ_SENDQUEUE_TIMEOUT / 1000); |
| 233 if (difftime(now, p->sendtime) > (wait_time * (p->resend_times + 1))) { |
141 if (difftime(now, p->sendtime) > (wait_time * (p->resend_times + 1))) { |
| 234 qq_proxy_write(qd, p->buf, p->len); |
142 qq_proxy_write(qd, p->buf, p->len); |