Mercurial > pidgin
comparison libgaim/protocols/qq/sendqueue.c @ 14192:60b1bc8dbf37
[gaim-migrate @ 16863]
Renamed 'core' to 'libgaim'
committer: Tailor Script <tailor@pidgin.im>
author | Evan Schoenberg <evan.s@dreskin.net> |
---|---|
date | Sat, 19 Aug 2006 01:50:10 +0000 |
parents | |
children | 6b8bc59414f0 |
comparison
equal
deleted
inserted
replaced
14191:009db0b357b5 | 14192:60b1bc8dbf37 |
---|---|
1 /** | |
2 * The QQ2003C protocol plugin | |
3 * | |
4 * for gaim | |
5 * | |
6 * Copyright (C) 2004 Puzzlebird | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 */ | |
22 | |
23 #include "connection.h" | |
24 #include "debug.h" | |
25 #include "internal.h" | |
26 #include "notify.h" | |
27 #include "prefs.h" | |
28 #include "request.h" | |
29 | |
30 #include "header_info.h" | |
31 #include "qq_proxy.h" | |
32 #include "sendqueue.h" | |
33 | |
34 #define QQ_RESEND_MAX 5 /* max resend per packet */ | |
35 | |
36 typedef struct _gc_and_packet gc_and_packet; | |
37 | |
38 struct _gc_and_packet { | |
39 GaimConnection *gc; | |
40 qq_sendpacket *packet; | |
41 }; | |
42 | |
43 /* Remove a packet with send_seq from sendqueue */ | |
44 void qq_sendqueue_remove(qq_data *qd, guint16 send_seq) | |
45 { | |
46 GList *list; | |
47 qq_sendpacket *p; | |
48 | |
49 g_return_if_fail(qd != NULL); | |
50 | |
51 list = qd->sendqueue; | |
52 while (list != NULL) { | |
53 p = (qq_sendpacket *) (list->data); | |
54 if (p->send_seq == send_seq) { | |
55 qd->sendqueue = g_list_remove(qd->sendqueue, p); | |
56 g_free(p->buf); | |
57 g_free(p); | |
58 break; | |
59 } | |
60 list = list->next; | |
61 } | |
62 } | |
63 | |
64 /* clean up sendqueue and free all contents */ | |
65 void qq_sendqueue_free(qq_data *qd) | |
66 { | |
67 qq_sendpacket *p; | |
68 gint i; | |
69 | |
70 i = 0; | |
71 while (qd->sendqueue != NULL) { | |
72 p = (qq_sendpacket *) (qd->sendqueue->data); | |
73 qd->sendqueue = g_list_remove(qd->sendqueue, p); | |
74 g_free(p->buf); | |
75 g_free(p); | |
76 i++; | |
77 } | |
78 gaim_debug(GAIM_DEBUG_INFO, "QQ", "%d packets in sendqueue are freed!\n", i); | |
79 } | |
80 | |
81 /* packet lost, agree to send again, (and will NOT prompt again) | |
82 * it is removed only when ack-ed by server */ | |
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 gboolean qq_sendqueue_timeout_callback(gpointer data) | |
129 { | |
130 GaimConnection *gc; | |
131 qq_data *qd; | |
132 GList *list; | |
133 qq_sendpacket *p; | |
134 gc_and_packet *gp; | |
135 time_t now; | |
136 gint wait_time; | |
137 gboolean need_action; | |
138 | |
139 gc = (GaimConnection *) data; | |
140 qd = (qq_data *) gc->proto_data; | |
141 now = time(NULL); | |
142 list = qd->sendqueue; | |
143 | |
144 /* empty queue, return TRUE so that timeout continues functioning */ | |
145 if (qd->sendqueue == NULL) | |
146 return TRUE; | |
147 | |
148 while (list != NULL) { /* remove all packet whose resend_times == -1 */ | |
149 p = (qq_sendpacket *) list->data; | |
150 if (p->resend_times == -1) { /* to remove */ | |
151 qd->sendqueue = g_list_remove(qd->sendqueue, p); | |
152 g_free(p->buf); | |
153 g_free(p); | |
154 list = qd->sendqueue; | |
155 } else { | |
156 list = list->next; | |
157 } | |
158 } | |
159 | |
160 list = qd->sendqueue; | |
161 while (list != NULL) { | |
162 p = (qq_sendpacket *) list->data; | |
163 if (p->resend_times >= QQ_RESEND_MAX) { | |
164 if (p->resend_times == QQ_RESEND_MAX) { /* reach max */ | |
165 switch (p->cmd) { | |
166 case QQ_CMD_KEEP_ALIVE: | |
167 if (qd->logged_in) { | |
168 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Connection lost!\n"); | |
169 gaim_connection_error(gc, _("Connection lost!")); | |
170 qd->logged_in = FALSE; | |
171 } | |
172 p->resend_times = -1; | |
173 break; | |
174 case QQ_CMD_LOGIN: | |
175 if (!qd->logged_in) /* cancel logging progress */ | |
176 gaim_connection_error(gc, _("Login failed, no reply!")); | |
177 p->resend_times = -1; | |
178 break; | |
179 case QQ_CMD_UPDATE_INFO: | |
180 gaim_notify_error(gc, NULL, | |
181 _("Connection timeout!"), _("User info is not updated")); | |
182 p->resend_times = -1; | |
183 break; | |
184 default:{ | |
185 need_action = | |
186 gaim_prefs_get_bool("/plugins/prpl/qq/prompt_for_missing_packet"); | |
187 if (!need_action) | |
188 p->resend_times = -1; /* it will be removed next time */ | |
189 else { /* prompt for action */ | |
190 gp = g_new0(gc_and_packet, 1); | |
191 gp->gc = gc; | |
192 gp->packet = p; | |
193 gaim_request_action | |
194 (gc, NULL, | |
195 _ | |
196 ("Send packet"), | |
197 _ | |
198 ("Packets lost, send again?"), | |
199 0, gp, 2, | |
200 _("Send"), | |
201 G_CALLBACK | |
202 (_qq_send_again), | |
203 _("Cancel"), G_CALLBACK(_qq_send_cancel)); | |
204 /* will send once more, but only once */ | |
205 p->resend_times++; | |
206 } | |
207 } | |
208 } | |
209 } | |
210 } else { /* resend_times < QQ_RESEND_MAX, so sent it again */ | |
211 wait_time = (gint) (QQ_SENDQUEUE_TIMEOUT / 1000); | |
212 if (difftime(now, p->sendtime) > (wait_time * (p->resend_times + 1))) { | |
213 qq_proxy_write(qd, p->buf, p->len); | |
214 p->resend_times++; | |
215 gaim_debug(GAIM_DEBUG_INFO, | |
216 "QQ", "<<< [%05d] send again for %d times!\n", | |
217 p->send_seq, p->resend_times); | |
218 } | |
219 } | |
220 list = list->next; | |
221 } | |
222 return TRUE; /* if we return FALSE, the timeout callback stops functioning */ | |
223 } |