comparison libpurple/protocols/msnp9/slpcall.c @ 21312:a07cfce78345

Add MSNP9 back as an alternative alongside the existing MSN prpl. Cowardly old fools like me who prefer the stability of our MSNP9 code over the features of MSNP14 can enable this using the --disable-msnp14 ./configure option. If we want to release from i.p.p and MSN stability is the only blocker, we can trivially flick the default to use MSNP9 in configure.ac
author Stu Tomlinson <stu@nosnilmot.com>
date Sun, 11 Nov 2007 12:57:52 +0000
parents
children c38d72677c8a
comparison
equal deleted inserted replaced
21311:7d031cec5ba2 21312:a07cfce78345
1 /**
2 * @file slpcall.c SLP Call Functions
3 *
4 * purple
5 *
6 * Purple is the legal property of its developers, whose names are too numerous
7 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * source distribution.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 */
24 #include "msn.h"
25 #include "slpcall.h"
26 #include "slpsession.h"
27
28 #include "slp.h"
29
30 /* #define MSN_DEBUG_SLPCALL */
31
32 /**************************************************************************
33 * Util
34 **************************************************************************/
35
36 static char *
37 rand_guid()
38 {
39 return g_strdup_printf("%4X%4X-%4X-%4X-%4X-%4X%4X%4X",
40 rand() % 0xAAFF + 0x1111,
41 rand() % 0xAAFF + 0x1111,
42 rand() % 0xAAFF + 0x1111,
43 rand() % 0xAAFF + 0x1111,
44 rand() % 0xAAFF + 0x1111,
45 rand() % 0xAAFF + 0x1111,
46 rand() % 0xAAFF + 0x1111,
47 rand() % 0xAAFF + 0x1111);
48 }
49
50 /**************************************************************************
51 * Main
52 **************************************************************************/
53
54 MsnSlpCall *
55 msn_slp_call_new(MsnSlpLink *slplink)
56 {
57 MsnSlpCall *slpcall;
58
59 g_return_val_if_fail(slplink != NULL, NULL);
60
61 slpcall = g_new0(MsnSlpCall, 1);
62
63 #ifdef MSN_DEBUG_SLPCALL
64 purple_debug_info("msn", "slpcall_new: slpcall(%p)\n", slpcall);
65 #endif
66
67 slpcall->slplink = slplink;
68
69 msn_slplink_add_slpcall(slplink, slpcall);
70
71 slpcall->timer = purple_timeout_add(MSN_SLPCALL_TIMEOUT, msn_slp_call_timeout, slpcall);
72
73 return slpcall;
74 }
75
76 void
77 msn_slp_call_destroy(MsnSlpCall *slpcall)
78 {
79 GList *e;
80 MsnSession *session;
81
82 #ifdef MSN_DEBUG_SLPCALL
83 purple_debug_info("msn", "slpcall_destroy: slpcall(%p)\n", slpcall);
84 #endif
85
86 g_return_if_fail(slpcall != NULL);
87
88 if (slpcall->timer)
89 purple_timeout_remove(slpcall->timer);
90
91 if (slpcall->id != NULL)
92 g_free(slpcall->id);
93
94 if (slpcall->branch != NULL)
95 g_free(slpcall->branch);
96
97 if (slpcall->data_info != NULL)
98 g_free(slpcall->data_info);
99
100 for (e = slpcall->slplink->slp_msgs; e != NULL; )
101 {
102 MsnSlpMessage *slpmsg = e->data;
103 e = e->next;
104
105 #ifdef MSN_DEBUG_SLPCALL_VERBOSE
106 purple_debug_info("msn", "slpcall_destroy: trying slpmsg(%p)\n",
107 slpmsg);
108 #endif
109
110 if (slpmsg->slpcall == slpcall)
111 {
112 msn_slpmsg_destroy(slpmsg);
113 }
114 }
115
116 session = slpcall->slplink->session;
117
118 msn_slplink_remove_slpcall(slpcall->slplink, slpcall);
119
120 if (slpcall->end_cb != NULL)
121 slpcall->end_cb(slpcall, session);
122
123 if (slpcall->xfer != NULL)
124 purple_xfer_unref(slpcall->xfer);
125
126 g_free(slpcall);
127 }
128
129 void
130 msn_slp_call_init(MsnSlpCall *slpcall, MsnSlpCallType type)
131 {
132 slpcall->session_id = rand() % 0xFFFFFF00 + 4;
133 slpcall->id = rand_guid();
134 slpcall->type = type;
135 }
136
137 void
138 msn_slp_call_session_init(MsnSlpCall *slpcall)
139 {
140 MsnSlpSession *slpsession;
141
142 slpsession = msn_slp_session_new(slpcall);
143
144 if (slpcall->session_init_cb)
145 slpcall->session_init_cb(slpsession);
146
147 slpcall->started = TRUE;
148 }
149
150 void
151 msn_slp_call_invite(MsnSlpCall *slpcall, const char *euf_guid,
152 int app_id, const char *context)
153 {
154 MsnSlpLink *slplink;
155 MsnSlpMessage *slpmsg;
156 char *header;
157 char *content;
158
159 g_return_if_fail(slpcall != NULL);
160 g_return_if_fail(context != NULL);
161
162 slplink = slpcall->slplink;
163
164 slpcall->branch = rand_guid();
165
166 content = g_strdup_printf(
167 "EUF-GUID: {%s}\r\n"
168 "SessionID: %lu\r\n"
169 "AppID: %d\r\n"
170 "Context: %s\r\n\r\n",
171 euf_guid,
172 slpcall->session_id,
173 app_id,
174 context);
175
176 header = g_strdup_printf("INVITE MSNMSGR:%s MSNSLP/1.0",
177 slplink->remote_user);
178
179 slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, slpcall->branch,
180 "application/x-msnmsgr-sessionreqbody", content);
181
182 #ifdef MSN_DEBUG_SLP
183 slpmsg->info = "SLP INVITE";
184 slpmsg->text_body = TRUE;
185 #endif
186
187 msn_slplink_send_slpmsg(slplink, slpmsg);
188
189 g_free(header);
190 g_free(content);
191 }
192
193 void
194 msn_slp_call_close(MsnSlpCall *slpcall)
195 {
196 g_return_if_fail(slpcall != NULL);
197 g_return_if_fail(slpcall->slplink != NULL);
198
199 send_bye(slpcall, "application/x-msnmsgr-sessionclosebody");
200 msn_slplink_unleash(slpcall->slplink);
201 msn_slp_call_destroy(slpcall);
202 }
203
204 gboolean
205 msn_slp_call_timeout(gpointer data)
206 {
207 MsnSlpCall *slpcall;
208
209 slpcall = data;
210
211 #ifdef MSN_DEBUG_SLPCALL
212 purple_debug_info("msn", "slpcall_timeout: slpcall(%p)\n", slpcall);
213 #endif
214
215 if (!slpcall->pending && !slpcall->progress)
216 {
217 msn_slp_call_destroy(slpcall);
218 return FALSE;
219 }
220
221 slpcall->progress = FALSE;
222
223 return TRUE;
224 }
225
226 MsnSlpCall *
227 msn_slp_process_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
228 {
229 MsnSlpCall *slpcall;
230 const guchar *body;
231 gsize body_len;
232
233 slpcall = NULL;
234 body = slpmsg->buffer;
235 body_len = slpmsg->size;
236
237 if (slpmsg->flags == 0x0)
238 {
239 char *body_str;
240
241 body_str = g_strndup((const char *)body, body_len);
242 slpcall = msn_slp_sip_recv(slplink, body_str);
243 g_free(body_str);
244 }
245 else if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030)
246 {
247 slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);
248
249 if (slpcall != NULL)
250 {
251 if (slpcall->timer)
252 purple_timeout_remove(slpcall->timer);
253
254 slpcall->cb(slpcall, body, body_len);
255
256 slpcall->wasted = TRUE;
257 }
258 }
259 #if 0
260 else if (slpmsg->flags == 0x100)
261 {
262 slpcall = slplink->directconn->initial_call;
263
264 if (slpcall != NULL)
265 msn_slp_call_session_init(slpcall);
266 }
267 #endif
268
269 return slpcall;
270 }