core cleanup: move subscription handling out of sipe.c
[siplcs.git] / src / core / sipe-subscriptions.c
blob76c80a69666e8520237ebb29715ed5552945289a
1 /**
2 * @file sipe-subscriptions.c
4 * pidgin-sipe
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
23 #include <stdlib.h>
25 #include <glib.h>
27 #include "sipe-common.h"
28 #include "sipmsg.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"
35 #include "sipe.h"
37 gboolean process_subscribe_response(struct sipe_core_private *sipe_private,
38 struct sipmsg *msg,
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");
44 gchar *key;
46 /* The case with 2005 Public IM Connectivity (PIC) - no Event header */
47 if (!event) {
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);
67 if (key) {
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);
80 g_free(cseq);
83 g_free(key);
84 g_free(with);
86 if (sipmsg_find_header(msg, "ms-piggyback-cseq"))
88 process_incoming_notify(sipe_private, msg, FALSE, FALSE);
90 return TRUE;
93 /**
94 * common subscription code
96 static void subscribe(struct sipe_core_private *sipe_private,
97 const gchar *event,
98 const gchar *accept,
99 const gchar *addheaders,
100 const gchar *body,
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(
106 "Event: %s\r\n"
107 "Accept: %s\r\n"
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"
112 "%s"
113 "Contact: %s\r\n",
114 event,
115 accept,
116 addheaders ? addheaders : "",
117 contact);
118 g_free(contact);
120 sip_transport_subscribe(sipe_private,
122 hdr,
123 body,
124 dialog,
125 process_subscribe_response);
127 g_free(hdr);
128 g_free(to);
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");
139 g_free(key);
141 subscribe(sipe_private,
142 "presence.wpending",
143 "text/xml+msrtc.wpending",
144 NULL,
145 NULL,
146 dialog);
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",
157 NULL,
158 NULL,
159 NULL);
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",
170 NULL,
171 NULL,
172 NULL);
176 * OCS 2005 version
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",
183 "Expires: 0\r\n",
184 NULL,
185 NULL);
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",
202 "Expires: 0\r\n"
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>",
208 NULL);
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
215 * subscriptions.
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>",
230 NULL);
234 Local Variables:
235 mode: c
236 c-file-style: "bsd"
237 indent-tabs-mode: t
238 tab-width: 8
239 End: