Updated to release 1.7.1
[siplcs.git] / src / sipe.h
blob5d616939183b89ef42a8b55e9ad62ca59ffb318a
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 #ifdef _WIN32
32 #include "internal.h"
33 #endif
35 #include "cipher.h"
36 #include "circbuffer.h"
37 #include "dnsquery.h"
38 #include "dnssrv.h"
39 #include "network.h"
40 #include "proxy.h"
41 #include "prpl.h"
42 #include "sslconn.h"
44 #include "sipmsg.h"
45 #include "sip-sec.h"
46 #include "uuid.h"
48 #define SIPE_UNUSED_PARAMETER __attribute__((unused))
50 #define SIMPLE_BUF_INC 4096
52 #define SIPE_TYPING_RECV_TIMEOUT 6
53 #define SIPE_TYPING_SEND_TIMEOUT 4
55 struct sipe_buddy {
56 gchar *name;
57 gchar *activity;
58 gchar *meeting_subject;
59 gchar *meeting_location;
60 gchar *annotation;
61 gchar *device_name;
62 GSList *groups;
63 /** flag to control sending 'context' element in 2007 subscriptions */
64 gboolean just_added;
67 struct sip_auth {
68 SipSecAuthType type;
69 SipSecContext gssapi_context;
70 gchar *gssapi_data;
71 gchar *opaque;
72 gchar *realm;
73 gchar *target;
74 int nc;
75 int retries;
76 int ntlm_num;
77 int expires;
80 typedef enum {
81 SIPE_TRANSPORT_TLS,
82 SIPE_TRANSPORT_TCP,
83 SIPE_TRANSPORT_UDP,
84 } sipe_transport_type;
86 struct sipe_service_data {
87 const char *service;
88 const char *transport;
89 sipe_transport_type type;
92 /** MS-PRES publication */
93 struct sipe_publication {
94 gchar *category;
95 guint instance;
96 guint container;
97 guint version;
98 /** for 'state' category */
99 int availability;
100 /** for 'note' category */
101 gchar *note;
104 /** MS-PRES container */
105 struct sipe_container {
106 guint id;
107 guint version;
108 GSList *members;
110 /** MS-PRES container member */
111 struct sipe_container_member {
112 /** user, domain, sameEnterprise, federated, publicCloud; everyone */
113 const gchar *type;
114 const gchar *value;
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 gchar *focus_factory_uri;
126 /** Allowed server events to subscribe. From register OK response. */
127 GSList *allow_events;
128 PurpleDnsQueryData *query_data;
129 PurpleSrvQueryData *srv_query_data;
130 const struct sipe_service_data *service_data;
131 PurpleNetworkListenData *listen_data;
132 int fd;
133 int cseq;
134 time_t last_keepalive;
135 int registerstatus; /* 0 nothing, 1 first registration send, 2 auth received, 3 registered */
136 struct sip_auth registrar;
137 struct sip_auth proxy;
138 struct sip_csta *csta; /* For RCC - Remote Call Control */
139 gboolean reregister_set; /* whether reregister timer set */
140 gboolean reauthenticate_set; /* whether reauthenticate timer set */
141 gboolean subscribed; /* whether subscribed to events, except buddies presence */
142 gboolean subscribed_buddies; /* whether subscribed to buddies presence */
143 gboolean access_level_set; /* whether basic access level set */
144 gboolean initial_state_published; /* whether we published our initial state */
145 GSList *our_publication_keys; /* [MS-PRES] */
146 GHashTable *our_publications; /* [MS-PRES] */
147 GHashTable *subscriptions;
148 int listenfd;
149 int listenport;
150 int listenpa;
151 int contacts_delta;
152 int acl_delta;
153 int presence_method_version;
154 gchar *status;
155 gboolean is_idle;
156 gboolean was_idle;
157 gchar *contact;
158 gchar *server_version;
159 gboolean ocs2007; /*if there is support for batched category subscription [SIP-PRES]*/
160 gboolean batched_support; /*if there is support for batched subscription*/
161 GSList *containers; /* MS-PRES containers */
162 GHashTable *buddies;
163 guint resendtimeout;
164 guint keepalive_timeout;
165 GSList *timeouts;
166 gboolean connecting;
167 PurpleAccount *account;
168 PurpleCircBuffer *txbuf;
169 guint tx_handler;
170 gchar *regcallid;
171 GSList *transactions;
172 GSList *sessions;
173 GSList *openconns;
174 GSList *groups;
175 sipe_transport_type transport;
176 gboolean auto_transport;
177 PurpleSslConnection *gsc;
178 struct sockaddr *serveraddr;
179 gchar *realhostname;
180 int realport; /* port and hostname from SRV record */
181 gboolean processing_input;
184 struct sip_connection {
185 int fd;
186 gchar *inbuf;
187 int inbuflen;
188 int inbufused;
189 int inputhandler;
192 struct sipe_auth_job {
193 gchar * who;
194 struct sipe_account_data * sip;
197 struct transaction;
199 typedef gboolean (*TransCallback) (struct sipe_account_data *, struct sipmsg *, struct transaction *);
201 struct transaction_payload {
202 GDestroyNotify destroy;
203 void *data;
206 struct transaction {
207 time_t time;
208 int retries;
209 int transport; /* 0 = tcp, 1 = udp */
210 int fd;
211 /** Not yet perfect, but surely better then plain CSeq
212 * Format is: <Call-ID><CSeq>
213 * (RFC3261 17.2.3 for matching server transactions: Request-URI, To tag, From tag, Call-ID, CSeq, and top Via)
215 gchar *key;
216 struct sipmsg *msg;
217 TransCallback callback;
218 struct transaction_payload *payload;
221 typedef void (*Action) (struct sipe_account_data *, void *);
224 * Do schedule action for execution in the future.
225 * Non repetitive execution.
227 * @param name of action (will be copied)
228 * @param timeout in seconds
229 * @param action callback function
230 * @param destroy payload destroy function
231 * @param sip
232 * @param payload callback data (can be NULL, otherwise caller must allocate memory)
234 void
235 sipe_schedule_action(const gchar *name,
236 int timeout,
237 Action action,
238 GDestroyNotify destroy,
239 struct sipe_account_data *sip,
240 void *payload);
242 struct sipe_group {
243 gchar *name;
244 int id;
245 PurpleGroup *purple_group;
248 struct group_user_context {
249 gchar * group_name;
250 gchar * user_name;
253 GSList * slist_insert_unique_sorted(GSList *list, gpointer data, GCompareFunc func);
255 GList *sipe_actions(PurplePlugin *plugin, gpointer context);
257 gboolean purple_init_plugin(PurplePlugin *plugin);
260 * THE BIG SPLIT - temporary interfaces
262 * Previously private functions in sipe.c that are
263 * - waiting to be factored out to an appropriate module
264 * - are needed by the already created new modules
267 /* pier11:
269 * Since SIP (RFC3261) is extensible by its design,
270 * and MS specs prove just that (they all are defined as SIP extensions),
271 * it make sense to split functionality by extension (or close extension group).
272 * For example: conference, presence (MS-PRES), etc.
274 * This way our code will not be monolithic, but potentially _reusable_. May be
275 * a top of other SIP core, and/or other front-end (Telepathy framework?).
277 /* Forward declarations */
278 struct sip_session;
279 struct sip_dialog;
281 /* SIP send module? */
282 struct transaction *
283 send_sip_request(PurpleConnection *gc, const gchar *method,
284 const gchar *url, const gchar *to, const gchar *addheaders,
285 const gchar *body, struct sip_dialog *dialog, TransCallback tc);
286 void
287 send_sip_response(PurpleConnection *gc, struct sipmsg *msg, int code,
288 const char *text, const char *body);
289 void
290 sipe_invite(struct sipe_account_data *sip, struct sip_session *session,
291 const gchar *who, const gchar *msg_body,
292 const gchar *referred_by, const gboolean is_triggered);
293 /* ??? module */
294 gboolean process_subscribe_response(struct sipe_account_data *sip,
295 struct sipmsg *msg,
296 struct transaction *tc);
297 /* Chat module */
298 void
299 sipe_invite_to_chat(struct sipe_account_data *sip,
300 struct sip_session *session,
301 const gchar *who);
302 /* Session module? */
303 void
304 sipe_present_message_undelivered_err(struct sipe_account_data *sip,
305 struct sip_session *session,
306 int sip_error,
307 const gchar *who,
308 const gchar *message);
310 void
311 sipe_present_info(struct sipe_account_data *sip,
312 struct sip_session *session,
313 const gchar *message);
316 void
317 sipe_process_pending_invite_queue(struct sipe_account_data *sip,
318 struct sip_session *session);
320 /*** THE BIG SPLIT END ***/
322 #define SIPE_INVITE_TEXT "ms-text-format: text/plain; charset=UTF-8%s;ms-body=%s\r\n"
324 #define SIPE_SEND_TYPING \
325 "<?xml version=\"1.0\"?>"\
326 "<KeyboardActivity>"\
327 "<status status=\"type\" />"\
328 "</KeyboardActivity>"
331 * Publishes categories.
332 * @param uri (%s) Self URI. Ex.: sip:alice7@boston.local
333 * @param publications (%s) XML publications
335 #define SIPE_SEND_PRESENCE \
336 "<publish xmlns=\"http://schemas.microsoft.com/2006/09/sip/rich-presence\">"\
337 "<publications uri=\"%s\">"\
338 "%s"\
339 "</publications>"\
340 "</publish>"
343 * Publishes 'device' category.
344 * @param instance (%u) Ex.: 1938468728
345 * @param version (%u) Ex.: 1
346 * @param endpointId (%s) Ex.: C707E38E-1E10-5413-94D9-ECAC260A0269
347 * @param uri (%s) Self URI. Ex.: sip:alice7@boston.local
348 * @param timezone (%s) Ex.: 00:00:00+01:00
349 * @param machineName (%s) Ex.: BOSTON-OCS07
351 #define SIPE_PUB_XML_DEVICE \
352 "<publication categoryName=\"device\" instance=\"%u\" container=\"2\" version=\"%u\" expireType=\"endpoint\">"\
353 "<device xmlns=\"http://schemas.microsoft.com/2006/09/sip/device\" endpointId=\"%s\">"\
354 "<capabilities preferred=\"false\" uri=\"%s\">"\
355 "<text capture=\"true\" render=\"true\" publish=\"false\"/>"\
356 "<gifInk capture=\"false\" render=\"true\" publish=\"false\"/>"\
357 "<isfInk capture=\"false\" render=\"true\" publish=\"false\"/>"\
358 "</capabilities>"\
359 "<timezone>%s</timezone>"\
360 "<machineName>%s</machineName>"\
361 "</device>"\
362 "</publication>"
365 * Publishes 'machineState' category.
366 * @param instance (%u) Ex.: 926460663
367 * @param version (%u) Ex.: 22
368 * @param availability (%d) Ex.: 3500
369 * @param instance (%u) Ex.: 926460663
370 * @param version (%u) Ex.: 22
371 * @param availability (%d) Ex.: 3500
373 #define SIPE_PUB_XML_STATE_MACHINE \
374 "<publication categoryName=\"state\" instance=\"%u\" container=\"2\" version=\"%u\" expireType=\"endpoint\">"\
375 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"machineState\">"\
376 "<availability>%d</availability>"\
377 "<endpointLocation/>"\
378 "</state>"\
379 "</publication>"\
380 "<publication categoryName=\"state\" instance=\"%u\" container=\"3\" version=\"%u\" expireType=\"endpoint\">"\
381 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"machineState\">"\
382 "<availability>%d</availability>"\
383 "<endpointLocation/>"\
384 "</state>"\
385 "</publication>"
388 * Publishes 'userState' category.
389 * @param instance (%u) User. Ex.: 536870912
390 * @param version (%u) User Container 2. Ex.: 22
391 * @param availability (%d) User Container 2. Ex.: 15500
392 * @param instance (%u) User. Ex.: 536870912
393 * @param version (%u) User Container 3.Ex.: 22
394 * @param availability (%d) User Container 3. Ex.: 15500
396 #define SIPE_PUB_XML_STATE_USER \
397 "<publication categoryName=\"state\" instance=\"%u\" container=\"2\" version=\"%u\" expireType=\"static\">"\
398 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"userState\">"\
399 "<availability>%d</availability>"\
400 "<endpointLocation/>"\
401 "</state>"\
402 "</publication>"\
403 "<publication categoryName=\"state\" instance=\"%u\" container=\"3\" version=\"%u\" expireType=\"static\">"\
404 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"userState\">"\
405 "<availability>%d</availability>"\
406 "<endpointLocation/>"\
407 "</state>"\
408 "</publication>"\
411 * Publishes 'note' category.
412 * @param version (%u) Ex.: 2
413 * @param body (%s) Ex.: In the office
414 * @param version (%u) Ex.: 2
415 * @param body (%s) Ex.: In the office
416 * @param version (%u) Ex.: 2
417 * @param body (%s) Ex.: In the office
419 #define SIPE_PUB_XML_NOTE \
420 "<publication categoryName=\"note\" instance=\"0\" container=\"200\" version=\"%d\" expireType=\"static\">"\
421 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
422 "<body type=\"personal\" uri=\"\">%s</body>"\
423 "</note>"\
424 "</publication>"\
425 "<publication categoryName=\"note\" instance=\"0\" container=\"300\" version=\"%d\" expireType=\"static\">"\
426 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
427 "<body type=\"personal\" uri=\"\">%s</body>"\
428 "</note>"\
429 "</publication>"\
430 "<publication categoryName=\"note\" instance=\"0\" container=\"400\" version=\"%d\" expireType=\"static\">"\
431 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
432 "<body type=\"personal\" uri=\"\">%s</body>"\
433 "</note>"\
434 "</publication>"
437 #define sipe_soap(method, body) \
438 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
439 "<SOAP-ENV:Body>" \
440 "<m:" method " xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\">" \
441 body \
442 "</m:" method ">" \
443 "</SOAP-ENV:Body>" \
444 "</SOAP-ENV:Envelope>"
446 #define SIPE_SOAP_SET_CONTACT sipe_soap("setContact", \
447 "<m:displayName>%s</m:displayName>"\
448 "<m:groups>%s</m:groups>"\
449 "<m:subscribed>%s</m:subscribed>"\
450 "<m:URI>%s</m:URI>"\
451 "<m:externalURI />"\
452 "<m:deltaNum>%d</m:deltaNum>")
454 #define SIPE_SOAP_DEL_CONTACT sipe_soap("deleteContact", \
455 "<m:URI>%s</m:URI>"\
456 "<m:deltaNum>%d</m:deltaNum>")
458 #define SIPE_SOAP_ADD_GROUP sipe_soap("addGroup", \
459 "<m:name>%s</m:name>"\
460 "<m:externalURI />"\
461 "<m:deltaNum>%d</m:deltaNum>")
463 #define SIPE_SOAP_MOD_GROUP sipe_soap("modifyGroup", \
464 "<m:groupID>%d</m:groupID>"\
465 "<m:name>%s</m:name>"\
466 "<m:externalURI />"\
467 "<m:deltaNum>%d</m:deltaNum>")
469 #define SIPE_SOAP_DEL_GROUP sipe_soap("deleteGroup", \
470 "<m:groupID>%d</m:groupID>"\
471 "<m:deltaNum>%d</m:deltaNum>")
473 // first/mask arg is sip:user@domain.com
474 // second/rights arg is AA for allow, BD for deny
475 #define SIPE_SOAP_ALLOW_DENY sipe_soap("setACE", \
476 "<m:type>USER</m:type>"\
477 "<m:mask>%s</m:mask>"\
478 "<m:rights>%s</m:rights>"\
479 "<m:deltaNum>%d</m:deltaNum>")
481 #define SIPE_SOAP_SET_PRESENCE_NOTE_XML "<note>%s</note>"
482 #define SIPE_SOAP_SET_PRESENCE_NOTE_XML_EMPTY "%s"
483 #define SIPE_SOAP_SET_PRESENCE(note_xml) sipe_soap("setPresence", \
484 "<m:presentity m:uri=\"sip:%s\">"\
485 "<m:availability m:aggregate=\"%d\"/>"\
486 "<m:activity m:aggregate=\"%d\" m:note=\"%s\"/>"\
487 "<deviceName xmlns=\"http://schemas.microsoft.com/2002/09/sip/presence\" name=\"USER-DESKTOP\"/>"\
488 "<rtc:devicedata xmlns:rtc=\"http://schemas.microsoft.com/winrtc/2002/11/sip\" namespace=\"rtcService\">"\
489 "&lt;![CDATA[<caps><renders_gif/><renders_isf/></caps>]]&gt;</rtc:devicedata>"\
490 "<userInfo xmlns=\"http://schemas.microsoft.com/2002/09/sip/presence\">"\
491 note_xml \
492 "</userInfo>"\
493 "</m:presentity>")
495 #define SIPE_SOAP_SEARCH_CONTACT \
496 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
497 "<SOAP-ENV:Body>" \
498 "<m:directorySearch xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\">" \
499 "<m:filter m:href=\"#searchArray\"/>"\
500 "<m:maxResults>%d</m:maxResults>"\
501 "</m:directorySearch>"\
502 "<m:Array xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\" m:id=\"searchArray\">"\
503 "%s"\
504 "</m:Array>"\
505 "</SOAP-ENV:Body>"\
506 "</SOAP-ENV:Envelope>"
508 #define SIPE_SOAP_SEARCH_ROW "<m:row m:attrib=\"%s\" m:value=\"%s\"/>"
510 #endif /* _PIDGIN_SIPE_H */