Simplify keep alive timeout setting code
[siplcs.git] / src / sipe.h
blob1a69c5859d38cfb11a09724903467aef99c220f8
1 /**
2 * @file sipe.h
4 * pidgin-sipe
6 * Copyright (C) 2008 Novell, Inc.
7 * Copyright (C) 2007 Anibal Avelar <avelar@gmail.com>
8 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #ifndef _PIDGIN_SIPE_H
26 #define _PIDGIN_SIPE_H
28 #include <glib.h>
29 #include <time.h>
31 #include "cipher.h"
32 #include "circbuffer.h"
33 #include "dnsquery.h"
34 #include "dnssrv.h"
35 #include "network.h"
36 #include "proxy.h"
37 #include "prpl.h"
38 #include "sslconn.h"
40 #include "sipmsg.h"
41 #include "uuid.h"
43 #define SIMPLE_BUF_INC 4096
45 #define SIPE_TYPING_RECV_TIMEOUT 6
46 #define SIPE_TYPING_SEND_TIMEOUT 4
47 #ifndef _WIN32
48 #define PURPLE_WEBSITE "http://pidgin.sf.im/"
49 #endif
51 struct sip_im_session {
52 gchar * with;
53 struct sip_dialog * dialog;
54 struct transaction * outgoing_invite;
56 GSList *outgoing_message_queue;
57 /** Key is <Call-ID><CSeq><METHOD> */
58 GHashTable *unconfirmed_messages;
61 // dialog is the new term for call-leg
62 struct sip_dialog {
63 gchar *ourtag;
64 gchar *theirtag;
65 gchar *theirepid;
66 gchar *callid;
67 GSList *routes;
68 gchar *request;
69 GSList *supported; // counterparty capabilities
70 int cseq;
73 struct sipe_buddy {
74 gchar *name;
75 gchar *annotation;
76 gchar *device_name;
77 GSList *groups;
80 typedef enum sipe_auth_type
82 AUTH_TYPE_UNSET = 0,
83 AUTH_TYPE_DIGEST,
84 AUTH_TYPE_NTLM,
85 AUTH_TYPE_KERBEROS
86 } sipe_auth_type;
88 struct sip_auth {
89 sipe_auth_type type;
90 gchar *nonce;
91 gchar *opaque;
92 gchar *realm;
93 gchar *target;
94 gchar *rspauth;
95 gchar *srand;
96 guint32 flags;
97 int nc;
98 gchar *digest_session_key;
99 int retries;
100 gchar *ntlm_key;
101 int ntlm_num;
102 time_t expires;
105 typedef enum {
106 SIPE_TRANSPORT_TLS,
107 SIPE_TRANSPORT_TCP,
108 SIPE_TRANSPORT_UDP,
109 } sipe_transport_type;
111 struct sipe_service_data {
112 const char *service;
113 const char *transport;
114 sipe_transport_type type;
117 struct sipe_account_data {
118 PurpleConnection *gc;
119 gchar *sipdomain;
120 gchar *username;
121 gchar *authdomain;
122 gchar *authuser;
123 gchar *password;
124 gchar *epid;
125 /** Allowed server events to subscribe. From register OK response. */
126 GSList *allow_events;
127 PurpleDnsQueryData *query_data;
128 PurpleSrvQueryData *srv_query_data;
129 const struct sipe_service_data *service_data;
130 PurpleNetworkListenData *listen_data;
131 int fd;
132 int cseq;
133 time_t last_keepalive;
134 int registerstatus; /* 0 nothing, 1 first registration send, 2 auth received, 3 registered */
135 struct sip_auth registrar;
136 struct sip_auth proxy;
137 gboolean reregister_set; /* whether reregister timer set */
138 gboolean reauthenticate_set; /* whether reauthenticate timer set */
139 gboolean subscribed; /* whether subscribed to events, except buddies presence */
140 gboolean subscribed_buddies; /* whether subscribed to buddies presence */
141 int listenfd;
142 int listenport;
143 int listenpa;
144 int contacts_delta;
145 int acl_delta;
146 int presence_method_version;
147 gchar *status;
148 int status_version;
149 gchar *contact;
150 gboolean msrtc_event_categories; /*if there is support for batched category subscription [SIP-PRES]*/
151 GHashTable *buddies;
152 guint resendtimeout;
153 guint keepalive_timeout;
154 GSList *timeouts;
155 gboolean connecting;
156 PurpleAccount *account;
157 PurpleCircBuffer *txbuf;
158 guint tx_handler;
159 gchar *regcallid;
160 GSList *transactions;
161 GSList *im_sessions;
162 GSList *openconns;
163 GSList *groups;
164 sipe_transport_type transport;
165 gboolean auto_transport;
166 PurpleSslConnection *gsc;
167 struct sockaddr_in serveraddr;
168 gchar *realhostname;
169 int realport; /* port and hostname from SRV record */
170 gboolean processing_input;
173 struct sip_connection {
174 int fd;
175 gchar *inbuf;
176 int inbuflen;
177 int inbufused;
178 int inputhandler;
181 struct sipe_auth_job {
182 gchar * who;
183 struct sipe_account_data * sip;
186 struct scheduled_action;
188 typedef gboolean (*Action) (struct sipe_account_data *, struct scheduled_action *);
190 struct scheduled_action {
191 /**
192 * Name of action.
193 * Format is <Event>[<Data>...]
194 * Example: <presence><sip:user@domain.com> or <registration>
196 gchar *name;
197 guint timeout_handler;
198 gboolean repetitive;
199 Action action;
200 struct sipe_account_data *sip;
201 void *payload;
204 struct transaction;
206 typedef gboolean (*TransCallback) (struct sipe_account_data *, struct sipmsg *, struct transaction *);
208 struct transaction {
209 time_t time;
210 int retries;
211 int transport; /* 0 = tcp, 1 = udp */
212 int fd;
213 gchar *cseq;
214 struct sipmsg *msg;
215 TransCallback callback;
216 void * payload;
219 struct sipe_group {
220 gchar *name;
221 int id;
222 PurpleGroup *purple_group;
225 struct group_user_context {
226 gchar * group_name;
227 gchar * user_name;
230 GSList * slist_insert_unique_sorted(GSList *list, gpointer data, GCompareFunc func);
232 gboolean sipe_scheduled_exec(struct scheduled_action *sched_action);
234 void sipe_schedule_action(gchar *name, int timeout, Action action, struct sipe_account_data *sip, void * payload);
236 GList *sipe_actions(PurplePlugin *plugin, gpointer context);
238 gboolean purple_init_plugin(PurplePlugin *plugin);
240 #define SIPE_INVITE_TEXT "ms-text-format: text/plain; charset=UTF-8%s;ms-body=%s\r\n"
242 #define SIPE_SEND_TYPING \
243 "<?xml version=\"1.0\"?>"\
244 "<KeyboardActivity>"\
245 "<status status=\"type\" />"\
246 "</KeyboardActivity>"
248 #define SIPE_SEND_PRESENCE \
249 "<publish xmlns=\"http://schemas.microsoft.com/2006/09/sip/rich-presence\">"\
250 "<publications uri=\"%s\">"\
251 "<publication categoryName=\"state\" instance=\"906391354\" container=\"2\" version=\"%d\" expireType=\"endpoint\">"\
252 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"machineState\">"\
253 "<availability>%d</availability>"\
254 "<endpointLocation></endpointLocation>"\
255 "</state>"\
256 "</publication>"\
257 "<publication categoryName=\"state\" instance=\"906391356\" container=\"0\" version=\"%d\" expireType=\"endpoint\">"\
258 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"userState\">"\
259 "<availability>%d</availability>"\
260 "<endpointLocation></endpointLocation>"\
261 "</state>"\
262 "</publication>"\
263 "<publication categoryName=\"note\" instance=\"0\" container=\"400\" version=\"%d\" expireType=\"static\">"\
264 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
265 "<body type=\"personal\" uri=\"\">%s</body>"\
266 "</note>"\
267 "</publication>"\
268 "<publication categoryName=\"note\" instance=\"0\" container=\"200\" version=\"%d\" expireType=\"static\">"\
269 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
270 "<body type=\"personal\" uri=\"\">%s</body>"\
271 "</note>"\
272 "</publication>"\
273 "<publication categoryName=\"note\" instance=\"0\" container=\"300\" version=\"%d\" expireType=\"static\">"\
274 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
275 "<body type=\"personal\" uri=\"\">%s</body>"\
276 "</note>"\
277 "</publication>"\
278 "</publications>"\
279 "</publish>"
282 #define SIPE_SEND_CLEAR_PRESENCE \
283 "<publish xmlns=\"http://schemas.microsoft.com/2006/09/sip/rich-presence\">"\
284 "<publications uri=\"%s\">"\
285 "<publication categoryName=\"state\" instance=\"906391354\" container=\"2\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
286 "<publication categoryName=\"state\" instance=\"906391356\" container=\"0\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
287 "<publication categoryName=\"note\" instance=\"0\" container=\"300\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
288 "<publication categoryName=\"note\" instance=\"0\" container=\"200\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
289 "<publication categoryName=\"note\" instance=\"0\" container=\"400\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
290 "</publications>"\
291 "</publish>"
294 #define sipe_soap(method, body) \
295 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
296 "<SOAP-ENV:Body>" \
297 "<m:" method " xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\">" \
298 body \
299 "</m:" method ">" \
300 "</SOAP-ENV:Body>" \
301 "</SOAP-ENV:Envelope>"
303 #define SIPE_SOAP_SET_CONTACT sipe_soap("setContact", \
304 "<m:displayName>%s</m:displayName>"\
305 "<m:groups>%s</m:groups>"\
306 "<m:subscribed>%s</m:subscribed>"\
307 "<m:URI>%s</m:URI>"\
308 "<m:externalURI />"\
309 "<m:deltaNum>%d</m:deltaNum>")
311 #define SIPE_SOAP_DEL_CONTACT sipe_soap("deleteContact", \
312 "<m:URI>%s</m:URI>"\
313 "<m:deltaNum>%d</m:deltaNum>")
315 #define SIPE_SOAP_ADD_GROUP sipe_soap("addGroup", \
316 "<m:name>%s</m:name>"\
317 "<m:externalURI />"\
318 "<m:deltaNum>%d</m:deltaNum>")
320 #define SIPE_SOAP_MOD_GROUP sipe_soap("modifyGroup", \
321 "<m:groupID>%d</m:groupID>"\
322 "<m:name>%s</m:name>"\
323 "<m:externalURI />"\
324 "<m:deltaNum>%d</m:deltaNum>")
326 #define SIPE_SOAP_DEL_GROUP sipe_soap("deleteGroup", \
327 "<m:groupID>%d</m:groupID>"\
328 "<m:deltaNum>%d</m:deltaNum>")
330 // first/mask arg is sip:user@domain.com
331 // second/rights arg is AA for allow, BD for deny
332 #define SIPE_SOAP_ALLOW_DENY sipe_soap("setACE", \
333 "<m:type>USER</m:type>"\
334 "<m:mask>%s</m:mask>"\
335 "<m:rights>%s</m:rights>"\
336 "<m:deltaNum>%d</m:deltaNum>")
338 #define SIPE_SOAP_SET_PRESENCE sipe_soap("setPresence", \
339 "<m:presentity m:uri=\"%s\">"\
340 "<m:availability m:aggregate=\"%d\"/>"\
341 "<m:activity m:aggregate=\"%d\" m:note=\"%s\"/>"\
342 "<deviceName xmlns=\"http://schemas.microsoft.com/2002/09/sip/client/presence\" name=\"USER-DESKTOP\"/>"\
343 "<rtc:devicedata xmlns:rtc=\"http://schemas.microsoft.com/2002/09/sip/client/presence\" namespace=\"rtcService\">"\
344 "&lt;![CDATA[<caps><renders_gif/><renders_isf/></caps>]]&gt;</rtc:devicedata>"\
345 "</m:presentity>")
347 #define SIPE_SOAP_SEARCH_CONTACT \
348 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
349 "<SOAP-ENV:Body>" \
350 "<m:directorySearch xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\">" \
351 "<m:filter m:href=\"#searchArray\"/>"\
352 "<m:maxResults>%d</m:maxResults>"\
353 "</m:directorySearch>"\
354 "<m:Array xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\" m:id=\"searchArray\">"\
355 "%s"\
356 "</m:Array>"\
357 "</SOAP-ENV:Body>"\
358 "</SOAP-ENV:Envelope>"
360 #define SIPE_SOAP_SEARCH_ROW "<m:row m:attrib=\"%s\" m:value=\"%s\"/>"
362 #endif /* _PIDGIN_SIPE_H */