2 * @file sipe-subscriptions.c
6 * Copyright (C) 2010 SIPE Project <http://sipe.sourceforge.net/>
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.
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.
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
27 #include "sipe-common.h"
29 #include "sip-transport.h"
30 #include "sipe-backend.h"
31 #include "sipe-core.h"
32 #include "sipe-core-private.h"
33 #include "sipe-dialog.h"
34 #include "sipe-utils.h"
37 gboolean
process_subscribe_response(struct sipe_core_private
*sipe_private
,
39 struct transaction
*trans
)
41 struct sipe_account_data
*sip
= SIPE_ACCOUNT_DATA_PRIVATE
;
42 gchar
*with
= parse_from(sipmsg_find_header(msg
, "To"));
43 const gchar
*event
= sipmsg_find_header(msg
, "Event");
46 /* The case with 2005 Public IM Connectivity (PIC) - no Event header */
48 struct sipmsg
*request_msg
= trans
->msg
;
49 event
= sipmsg_find_header(request_msg
, "Event");
52 key
= sipe_utils_subscription_key(event
, with
);
54 /* 200 OK; 481 Call Leg Does Not Exist */
55 if (key
&& (msg
->response
== 200 || msg
->response
== 481)) {
56 if (g_hash_table_lookup(sip
->subscriptions
, key
)) {
57 g_hash_table_remove(sip
->subscriptions
, key
);
58 SIPE_DEBUG_INFO("process_subscribe_response: subscription dialog removed for: %s", key
);
62 /* create/store subscription dialog if not yet */
63 if (msg
->response
== 200) {
64 const gchar
*callid
= sipmsg_find_header(msg
, "Call-ID");
65 gchar
*cseq
= sipmsg_find_part_of_header(sipmsg_find_header(msg
, "CSeq"), NULL
, " ", NULL
);
68 struct sip_subscription
*subscription
= g_new0(struct sip_subscription
, 1);
69 g_hash_table_insert(sip
->subscriptions
, g_strdup(key
), subscription
);
71 subscription
->dialog
.callid
= g_strdup(callid
);
72 subscription
->dialog
.cseq
= atoi(cseq
);
73 subscription
->dialog
.with
= g_strdup(with
);
74 subscription
->event
= g_strdup(event
);
75 sipe_dialog_parse(&subscription
->dialog
, msg
, TRUE
);
77 SIPE_DEBUG_INFO("process_subscribe_response: subscription dialog added for: %s", key
);
86 if (sipmsg_find_header(msg
, "ms-piggyback-cseq"))
88 process_incoming_notify(sipe_private
, msg
, FALSE
, FALSE
);
94 * common subscription code
96 static void subscribe(struct sipe_core_private
*sipe_private
,
99 const gchar
*addheaders
,
101 struct sip_dialog
*dialog
)
103 gchar
*to
= sip_uri_self(sipe_private
);
104 gchar
*contact
= get_contact(sipe_private
);
105 gchar
*hdr
= g_strdup_printf(
108 "Supported: com.microsoft.autoextend\r\n"
109 "Supported: ms-benotify\r\n"
110 "Proxy-Require: ms-benotify\r\n"
111 "Supported: ms-piggyback-first-notify\r\n"
116 addheaders
? addheaders
: "",
120 sip_transport_subscribe(sipe_private
,
125 process_subscribe_response
);
131 void sipe_subscribe_presence_wpending(struct sipe_core_private
*sipe_private
,
132 SIPE_UNUSED_PARAMETER
void *unused
)
134 struct sipe_account_data
*sip
= SIPE_ACCOUNT_DATA_PRIVATE
;
135 gchar
*key
= sipe_utils_subscription_key("presence.wpending", NULL
);
136 struct sip_dialog
*dialog
= (struct sip_dialog
*)g_hash_table_lookup(sip
->subscriptions
, key
);
138 SIPE_DEBUG_INFO("sipe_subscribe_presence_wpending: subscription dialog for: %s is %s", key
, dialog
? "Not NULL" : "NULL");
141 subscribe(sipe_private
,
143 "text/xml+msrtc.wpending",
150 * Subscribe roaming ACL
152 void sipe_subscribe_roaming_acl(struct sipe_core_private
*sipe_private
)
154 subscribe(sipe_private
,
155 "vnd-microsoft-roaming-ACL",
156 "application/vnd-microsoft-roaming-acls+xml",
163 * Subscribe roaming contacts
165 void sipe_subscribe_roaming_contacts(struct sipe_core_private
*sipe_private
)
167 subscribe(sipe_private
,
168 "vnd-microsoft-roaming-contacts",
169 "application/vnd-microsoft-roaming-contacts+xml",
178 void sipe_subscribe_roaming_provisioning(struct sipe_core_private
*sipe_private
)
180 subscribe(sipe_private
,
181 "vnd-microsoft-provisioning",
182 "application/vnd-microsoft-roaming-provisioning+xml",
189 * Subscription for provisioning information to help with initial
190 * configuration. This subscription is a one-time query (denoted by the
191 * Expires header, which asks for 0 seconds for the subscription lifetime).
192 * This subscription asks for server configuration, meeting policies, and
193 * policy settings that Communicator must enforce.
195 * @TODO: for what do we need this information?
197 void sipe_subscribe_roaming_provisioning_v2(struct sipe_core_private
*sipe_private
)
199 subscribe(sipe_private
,
200 "vnd-microsoft-provisioning-v2",
201 "application/vnd-microsoft-roaming-provisioning-v2+xml",
203 "Content-Type: application/vnd-microsoft-roaming-provisioning-v2+xml\r\n",
204 "<provisioningGroupList xmlns=\"http://schemas.microsoft.com/2006/09/sip/provisioninggrouplist\">"
205 "<provisioningGroup name=\"ServerConfiguration\"/><provisioningGroup name=\"meetingPolicy\"/>"
206 "<provisioningGroup name=\"ucPolicy\"/>"
207 "</provisioningGroupList>",
212 * To request for presence information about the user, access level settings
213 * that have already been configured by the user to control who has access to
214 * what information, and the list of contacts who currently have outstanding
217 * We wait for (BE)NOTIFY messages with some info change (categories,
218 * containers, subscribers)
220 void sipe_subscribe_roaming_self(struct sipe_core_private
*sipe_private
)
222 subscribe(sipe_private
,
223 "vnd-microsoft-roaming-self",
224 "application/vnd-microsoft-roaming-self+xml",
225 "Content-Type: application/vnd-microsoft-roaming-self+xml\r\n",
226 "<roamingList xmlns=\"http://schemas.microsoft.com/2006/09/sip/roaming-self\">"
227 "<roaming type=\"categories\"/>"
228 "<roaming type=\"containers\"/>"
229 "<roaming type=\"subscribers\"/></roamingList>",