Refactor SIP session dialog API
[siplcs.git] / src / sipe.h
blob1497228da0fa0e38967c549b18d7be7e52d201e1
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 "sip-sec.h"
42 #include "uuid.h"
44 #define SIMPLE_BUF_INC 4096
46 #define SIPE_TYPING_RECV_TIMEOUT 6
47 #define SIPE_TYPING_SEND_TIMEOUT 4
48 #ifndef _WIN32
49 #define PURPLE_WEBSITE "http://pidgin.sf.im/"
50 #endif
52 /** Correspond to multy-party conversation */
53 struct sip_im_session {
54 gchar *with; /* For IM sessions only (not multi-party) . A URI.*/
55 int chat_id;
56 /** Human readable chat name */
57 gchar *chat_name;
58 /** Call-Id identifying the conversation */
59 gchar *callid; /* For multiparty conversations */
60 /** Roster Manager URI */
61 gchar *roster_manager;
62 int bid;
63 gboolean is_voting_in_progress;
64 gboolean is_multiparty;
65 gchar *focus_uri;
66 gchar *im_mcu_uri;
67 guint request_id;
68 struct sip_dialog *focus_dialog;
69 /** key is user (URI) */
70 GSList *dialogs;
71 //struct sip_dialog * dialog;
72 /** Link to purple chat or IM */
73 PurpleConversation *conv;
75 GSList *outgoing_message_queue;
76 /** Key is <Call-ID><CSeq><METHOD> */
77 GHashTable *unconfirmed_messages;
79 GSList *pending_invite_queue;
82 struct sipe_buddy {
83 gchar *name;
84 gchar *annotation;
85 gchar *device_name;
86 GSList *groups;
87 gboolean resubscribed;
90 struct sip_auth {
91 SipSecAuthType type;
92 SipSecContext gssapi_context;
93 gchar *gssapi_data;
94 gchar *opaque;
95 gchar *realm;
96 gchar *target;
97 int nc;
98 int retries;
99 int ntlm_num;
100 int expires;
103 typedef enum {
104 SIPE_TRANSPORT_TLS,
105 SIPE_TRANSPORT_TCP,
106 SIPE_TRANSPORT_UDP,
107 } sipe_transport_type;
109 struct sipe_service_data {
110 const char *service;
111 const char *transport;
112 sipe_transport_type type;
115 /** MS-PRES container */
116 struct sipe_container {
117 guint id;
118 guint version;
119 GSList *members;
121 /** MS-PRES container member */
122 struct sipe_container_member {
123 /** user, domain, sameEnterprise, federated, publicCloud; everyone */
124 const gchar *type;
125 const gchar *value;
128 struct sipe_account_data {
129 PurpleConnection *gc;
130 gchar *sipdomain;
131 gchar *username;
132 gchar *authdomain;
133 gchar *authuser;
134 gchar *password;
135 gchar *epid;
136 /** Allowed server events to subscribe. From register OK response. */
137 GSList *allow_events;
138 PurpleDnsQueryData *query_data;
139 PurpleSrvQueryData *srv_query_data;
140 const struct sipe_service_data *service_data;
141 PurpleNetworkListenData *listen_data;
142 int fd;
143 int cseq;
144 int chat_seq;
145 time_t last_keepalive;
146 int registerstatus; /* 0 nothing, 1 first registration send, 2 auth received, 3 registered */
147 struct sip_auth registrar;
148 struct sip_auth proxy;
149 gboolean reregister_set; /* whether reregister timer set */
150 gboolean reauthenticate_set; /* whether reauthenticate timer set */
151 gboolean subscribed; /* whether subscribed to events, except buddies presence */
152 gboolean subscribed_buddies; /* whether subscribed to buddies presence */
153 gboolean access_level_set; /* whether basic access level set */
154 int listenfd;
155 int listenport;
156 int listenpa;
157 int contacts_delta;
158 int acl_delta;
159 int presence_method_version;
160 gchar *status;
161 int status_version;
162 gchar *contact;
163 gboolean msrtc_event_categories; /*if there is support for batched category subscription [SIP-PRES]*/
164 gboolean batched_support; /*if there is support for batched subscription*/
165 GSList *containers; /* MS-PRES containers */
166 GHashTable *buddies;
167 guint resendtimeout;
168 guint keepalive_timeout;
169 GSList *timeouts;
170 gboolean connecting;
171 PurpleAccount *account;
172 PurpleCircBuffer *txbuf;
173 guint tx_handler;
174 gchar *regcallid;
175 GSList *transactions;
176 GSList *im_sessions;
177 GSList *openconns;
178 GSList *groups;
179 sipe_transport_type transport;
180 gboolean auto_transport;
181 PurpleSslConnection *gsc;
182 struct sockaddr *serveraddr;
183 gchar *realhostname;
184 int realport; /* port and hostname from SRV record */
185 gboolean processing_input;
188 struct sip_connection {
189 int fd;
190 gchar *inbuf;
191 int inbuflen;
192 int inbufused;
193 int inputhandler;
196 struct sipe_auth_job {
197 gchar * who;
198 struct sipe_account_data * sip;
201 struct transaction;
203 typedef gboolean (*TransCallback) (struct sipe_account_data *, struct sipmsg *, struct transaction *);
205 struct transaction {
206 time_t time;
207 int retries;
208 int transport; /* 0 = tcp, 1 = udp */
209 int fd;
210 /** Not yet perfect, but surely better then plain CSeq
211 * Format is: <Call-ID><CSeq>
212 * (RFC3261 17.2.3 for matching server transactions: Request-URI, To tag, From tag, Call-ID, CSeq, and top Via)
214 gchar *key;
215 struct sipmsg *msg;
216 TransCallback callback;
217 void * payload;
220 struct sipe_group {
221 gchar *name;
222 int id;
223 PurpleGroup *purple_group;
226 struct group_user_context {
227 gchar * group_name;
228 gchar * user_name;
231 GSList * slist_insert_unique_sorted(GSList *list, gpointer data, GCompareFunc func);
233 GList *sipe_actions(PurplePlugin *plugin, gpointer context);
235 gboolean purple_init_plugin(PurplePlugin *plugin);
238 * THE BIG SPLIT - temporary interfaces
240 * Previously private functions in sipe.c that are
241 * - waiting to be factored out to an appropriate module
242 * - are needed by the already created new modules
244 /* SIP send module? */
245 struct transaction *
246 send_sip_request(PurpleConnection *gc, const gchar *method,
247 const gchar *url, const gchar *to, const gchar *addheaders,
248 const gchar *body, struct sip_dialog *dialog, TransCallback tc);
249 void
250 send_sip_response(PurpleConnection *gc, struct sipmsg *msg, int code,
251 const char *text, const char *body);
252 void
253 sipe_invite(struct sipe_account_data *sip, struct sip_im_session *session,
254 const gchar *who, const gchar *msg_body,
255 const gchar *referred_by, const gboolean is_triggered);
256 /* ??? module */
257 gboolean process_subscribe_response(struct sipe_account_data *sip,
258 struct sipmsg *msg,
259 struct transaction *tc);
260 /* Session module? */
261 void
262 im_session_destroy(struct sipe_account_data *sip,
263 struct sip_im_session *session);
264 struct sip_im_session *
265 create_chat_session (struct sipe_account_data *sip);
266 /*** THE BIG SPLIT END ***/
268 #define SIPE_INVITE_TEXT "ms-text-format: text/plain; charset=UTF-8%s;ms-body=%s\r\n"
270 #define SIPE_SEND_TYPING \
271 "<?xml version=\"1.0\"?>"\
272 "<KeyboardActivity>"\
273 "<status status=\"type\" />"\
274 "</KeyboardActivity>"
276 #define SIPE_SEND_PRESENCE \
277 "<publish xmlns=\"http://schemas.microsoft.com/2006/09/sip/rich-presence\">"\
278 "<publications uri=\"%s\">"\
279 "<publication categoryName=\"state\" instance=\"906391354\" container=\"2\" version=\"%d\" expireType=\"endpoint\">"\
280 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"machineState\">"\
281 "<availability>%d</availability>"\
282 "<endpointLocation></endpointLocation>"\
283 "</state>"\
284 "</publication>"\
285 "<publication categoryName=\"state\" instance=\"906391356\" container=\"0\" version=\"%d\" expireType=\"endpoint\">"\
286 "<state xmlns=\"http://schemas.microsoft.com/2006/09/sip/state\" manual=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"userState\">"\
287 "<availability>%d</availability>"\
288 "<endpointLocation></endpointLocation>"\
289 "</state>"\
290 "</publication>"\
291 "<publication categoryName=\"note\" instance=\"0\" container=\"400\" version=\"%d\" expireType=\"static\">"\
292 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
293 "<body type=\"personal\" uri=\"\">%s</body>"\
294 "</note>"\
295 "</publication>"\
296 "<publication categoryName=\"note\" instance=\"0\" container=\"200\" version=\"%d\" expireType=\"static\">"\
297 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
298 "<body type=\"personal\" uri=\"\">%s</body>"\
299 "</note>"\
300 "</publication>"\
301 "<publication categoryName=\"note\" instance=\"0\" container=\"300\" version=\"%d\" expireType=\"static\">"\
302 "<note xmlns=\"http://schemas.microsoft.com/2006/09/sip/note\">"\
303 "<body type=\"personal\" uri=\"\">%s</body>"\
304 "</note>"\
305 "</publication>"\
306 "</publications>"\
307 "</publish>"
310 #define SIPE_SEND_CLEAR_PRESENCE \
311 "<publish xmlns=\"http://schemas.microsoft.com/2006/09/sip/rich-presence\">"\
312 "<publications uri=\"%s\">"\
313 "<publication categoryName=\"state\" instance=\"906391354\" container=\"2\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
314 "<publication categoryName=\"state\" instance=\"906391356\" container=\"0\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
315 "<publication categoryName=\"note\" instance=\"0\" container=\"300\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
316 "<publication categoryName=\"note\" instance=\"0\" container=\"200\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
317 "<publication categoryName=\"note\" instance=\"0\" container=\"400\" version=\"1\" expireType=\"static\" expires=\"0\" />"\
318 "</publications>"\
319 "</publish>"
322 #define sipe_soap(method, body) \
323 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
324 "<SOAP-ENV:Body>" \
325 "<m:" method " xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\">" \
326 body \
327 "</m:" method ">" \
328 "</SOAP-ENV:Body>" \
329 "</SOAP-ENV:Envelope>"
331 #define SIPE_SOAP_SET_CONTACT sipe_soap("setContact", \
332 "<m:displayName>%s</m:displayName>"\
333 "<m:groups>%s</m:groups>"\
334 "<m:subscribed>%s</m:subscribed>"\
335 "<m:URI>%s</m:URI>"\
336 "<m:externalURI />"\
337 "<m:deltaNum>%d</m:deltaNum>")
339 #define SIPE_SOAP_DEL_CONTACT sipe_soap("deleteContact", \
340 "<m:URI>%s</m:URI>"\
341 "<m:deltaNum>%d</m:deltaNum>")
343 #define SIPE_SOAP_ADD_GROUP sipe_soap("addGroup", \
344 "<m:name>%s</m:name>"\
345 "<m:externalURI />"\
346 "<m:deltaNum>%d</m:deltaNum>")
348 #define SIPE_SOAP_MOD_GROUP sipe_soap("modifyGroup", \
349 "<m:groupID>%d</m:groupID>"\
350 "<m:name>%s</m:name>"\
351 "<m:externalURI />"\
352 "<m:deltaNum>%d</m:deltaNum>")
354 #define SIPE_SOAP_DEL_GROUP sipe_soap("deleteGroup", \
355 "<m:groupID>%d</m:groupID>"\
356 "<m:deltaNum>%d</m:deltaNum>")
358 // first/mask arg is sip:user@domain.com
359 // second/rights arg is AA for allow, BD for deny
360 #define SIPE_SOAP_ALLOW_DENY sipe_soap("setACE", \
361 "<m:type>USER</m:type>"\
362 "<m:mask>%s</m:mask>"\
363 "<m:rights>%s</m:rights>"\
364 "<m:deltaNum>%d</m:deltaNum>")
366 #define SIPE_SOAP_SET_PRESENCE sipe_soap("setPresence", \
367 "<m:presentity m:uri=\"%s\">"\
368 "<m:availability m:aggregate=\"%d\"/>"\
369 "<m:activity m:aggregate=\"%d\" m:note=\"%s\"/>"\
370 "<deviceName xmlns=\"http://schemas.microsoft.com/2002/09/sip/client/presence\" name=\"USER-DESKTOP\"/>"\
371 "<rtc:devicedata xmlns:rtc=\"http://schemas.microsoft.com/2002/09/sip/client/presence\" namespace=\"rtcService\">"\
372 "&lt;![CDATA[<caps><renders_gif/><renders_isf/></caps>]]&gt;</rtc:devicedata>"\
373 "</m:presentity>")
375 #define SIPE_SOAP_SEARCH_CONTACT \
376 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" \
377 "<SOAP-ENV:Body>" \
378 "<m:directorySearch xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\">" \
379 "<m:filter m:href=\"#searchArray\"/>"\
380 "<m:maxResults>%d</m:maxResults>"\
381 "</m:directorySearch>"\
382 "<m:Array xmlns:m=\"http://schemas.microsoft.com/winrtc/2002/11/sip\" m:id=\"searchArray\">"\
383 "%s"\
384 "</m:Array>"\
385 "</SOAP-ENV:Body>"\
386 "</SOAP-ENV:Envelope>"
388 #define SIPE_SOAP_SEARCH_ROW "<m:row m:attrib=\"%s\" m:value=\"%s\"/>"
390 #endif /* _PIDGIN_SIPE_H */