1 /*
2  * pua module - presence user agent module
3  *
4  * Copyright (C) 2007 Voice Sistem S.R.L.
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio 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
12  *
13  * Kamailio 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.
17  *
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <libxml/parser.h>
27 
28 #include "event_list.h"
29 #include "add_events.h"
30 #include "pua.h"
31 #include "pidf.h"
32 
33 extern int dlginfo_increase_version;
34 
pua_add_events(void)35 int pua_add_events(void)
36 {
37 	/* add presence */
38 	if(add_pua_event(PRESENCE_EVENT, "presence", "application/pidf+xml",
39 				pres_process_body)< 0)
40 	{
41 		LM_ERR("while adding event presence\n");
42 		return -1;
43 	}
44 
45 	/* add dialog */
46 	if (dlginfo_increase_version) {
47 		if(add_pua_event(DIALOG_EVENT, "dialog", "application/dialog-info+xml",
48 					bla_process_body)< 0)
49 		{
50 			LM_ERR("while adding event dialog w/ dlginfo_increase_version\n");
51 			return -1;
52 		}
53 	} else {
54 		if(add_pua_event(DIALOG_EVENT, "dialog", "application/dialog-info+xml",
55 					dlg_process_body)< 0)
56 		{
57 			LM_ERR("while adding event dialog w/o dlginfo_increase_version\n");
58 			return -1;
59 		}
60 	}
61 
62 	/* add dialog;sla */
63 	if(add_pua_event(BLA_EVENT, "dialog;sla", "application/dialog-info+xml",
64 				bla_process_body)< 0)
65 	{
66 		LM_ERR("while adding event dialog;sla\n");
67 		return -1;
68 	}
69 
70 	/* add message-summary*/
71 	if(add_pua_event(MSGSUM_EVENT, "message-summary",
72 				"application/simple-message-summary", mwi_process_body)< 0)
73 	{
74 		LM_ERR("while adding event message-summary\n");
75 		return -1;
76 	}
77 
78 	/* add presence;winfo */
79 	if(add_pua_event(PWINFO_EVENT, "presence.winfo", NULL, NULL)< 0)
80 	{
81 		LM_ERR("while adding event presence.winfo\n");
82 		return -1;
83 	}
84 
85 	/* add application/reginfo+xml */
86 	if (dlginfo_increase_version) {
87 		if(add_pua_event(REGINFO_EVENT, "reg", "application/reginfo+xml", reginfo_process_body)< 0) {
88 			LM_ERR("while adding event application/reginfo+xml with version increase\n");
89 			return -1;
90 		}
91 	} else {
92 		if(add_pua_event(REGINFO_EVENT, "reg", "application/reginfo+xml", dlg_process_body)< 0) {
93 			LM_ERR("while adding event application/reginfo+xml\n");
94 			return -1;
95 		}
96 	}
97 
98 	/* add xcap-diff */
99 	if(add_pua_event(XCAPDIFF_EVENT, "xcap-diff",
100 				"application/xcap-diff+xml", 0)< 0)
101 	{
102 		LM_ERR("while adding event xcap-diff\n");
103 		return -1;
104 	}
105 
106 	return 0;
107 
108 }
109 
pres_process_body(publ_info_t * publ,str ** fin_body,int ver,str ** tuple_param)110 int pres_process_body(publ_info_t* publ, str** fin_body, int ver, str** tuple_param)
111 {
112 
113 	xmlDocPtr doc= NULL;
114 	xmlNodePtr node= NULL;
115 	char* tuple_id= NULL, *person_id= NULL;
116 	int tuple_id_len= 0;
117 	char buf[50];
118 	str* body= NULL;
119 	int alloc_tuple= 0;
120 	str* tuple= NULL;
121 
122 	doc= xmlParseMemory(publ->body->s, publ->body->len );
123 	if(doc== NULL)
124 	{
125 		LM_ERR("while parsing xml memory\n");
126 		goto error;
127 	}
128 
129 	node= xmlDocGetNodeByName(doc, "tuple", NULL);
130 	if(node == NULL)
131 	{
132 		LM_ERR("while extracting tuple node\n");
133 		goto error;
134 	}
135 	tuple= *(tuple_param);
136 
137 	tuple_id= xmlNodeGetAttrContentByName(node, "id");
138 	if(tuple_id== NULL)
139 	{
140 
141 		if(tuple== NULL)	// generate a tuple_id
142 		{
143 			tuple_id= buf;
144 			tuple_id_len= sprintf(tuple_id, "%p", publ);
145 			tuple_id[tuple_id_len]= '\0';
146 
147 			tuple=(str*)pkg_malloc(sizeof(str));
148 			if(tuple== NULL)
149 			{
150 				PKG_MEM_ERROR;
151 				goto error;
152 			}
153 			alloc_tuple = 1;
154 			tuple->s= (char*)pkg_malloc(tuple_id_len* sizeof(char));
155 			if(tuple->s== NULL)
156 			{
157 				PKG_MEM_ERROR;
158 				goto error;
159 			}
160 			memcpy(tuple->s, tuple_id, tuple_id_len);
161 			tuple->len= tuple_id_len;
162 
163 			*tuple_param= tuple;
164 
165 			LM_DBG("allocated tuple_id\n\n");
166 		}
167 		else
168 		{
169 			tuple_id= buf;
170 			tuple_id_len= tuple->len;
171 			memcpy(tuple_id, tuple->s, tuple_id_len);
172 			tuple_id[tuple_id_len]= '\0';
173 		}
174 		/* add tuple id */
175 		if(!xmlNewProp(node, BAD_CAST "id", BAD_CAST tuple_id))
176 		{
177 			LM_ERR("while extracting xml"
178 						" node\n");
179 			goto error;
180 		}
181 	}
182 	else
183 	{
184 		if(tuple== NULL)
185 		{
186 			if(strlen(tuple_id)>=50) {
187 				LM_ERR("tuple id is too long: %s\n", tuple_id);
188 				goto error;
189 			}
190 			strcpy(buf, tuple_id);
191 			xmlFree(tuple_id);
192 			tuple_id= buf;
193 			tuple_id_len= strlen(tuple_id);
194 
195 			tuple=(str*)pkg_malloc(sizeof(str));
196 			if(tuple== NULL)
197 			{
198 				PKG_MEM_ERROR;
199 				goto error;
200 			}
201 			alloc_tuple= 1;
202 			tuple->s= (char*)pkg_malloc(tuple_id_len* sizeof(char));
203 			if(tuple->s== NULL)
204 			{
205 				PKG_MEM_ERROR;
206 				goto error;
207 			}
208 			memcpy(tuple->s, tuple_id, tuple_id_len);
209 			tuple->len= tuple_id_len;
210 			*tuple_param= tuple;
211 		}
212 	}
213 
214 	node= xmlDocGetNodeByName(doc, "person", NULL);
215 	if(node)
216 	{
217 		LM_DBG("found person node\n");
218 		person_id= xmlNodeGetAttrContentByName(node, "id");
219 		if(person_id== NULL)
220 		{
221 			if(!xmlNewProp(node, BAD_CAST "id", BAD_CAST tuple_id))
222 			{
223 				LM_ERR("while extracting xml"
224 						" node\n");
225 				goto error;
226 			}
227 		}
228 		else
229 		{
230 			xmlFree(person_id);
231 		}
232 	}
233 	body= (str*)pkg_malloc(sizeof(str));
234 	if(body== NULL)
235 	{
236 		PKG_MEM_ERROR;
237 		goto error;
238 	}
239 	memset(body, 0, sizeof(str));
240 	xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&body->s, &body->len, 1);
241 	if(body->s== NULL || body->len== 0)
242 	{
243 		LM_ERR("while dumping xml format\n");
244 		goto error;
245 	}
246 	xmlFreeDoc(doc);
247 	doc= NULL;
248 
249 	*fin_body= body;
250 	xmlMemoryDump();
251 	xmlCleanupParser();
252 	return 1;
253 
254 error:
255 	if(doc)
256 		xmlFreeDoc(doc);
257 	if(body)
258 		pkg_free(body);
259 	if(tuple && alloc_tuple) {
260 		if(tuple->s)
261 			pkg_free(tuple->s);
262 		pkg_free(tuple);
263 	}
264 	return -1;
265 
266 }
267 
bla_process_body(publ_info_t * publ,str ** fin_body,int ver,str ** tuple)268 int bla_process_body(publ_info_t* publ, str** fin_body, int ver, str** tuple)
269 {
270 	xmlNodePtr node= NULL;
271 	xmlDocPtr doc= NULL;
272 	char* version;
273 	str* body= NULL;
274 	int len;
275 	str* init_body;
276 
277 	init_body= publ->body;
278 
279 	doc= xmlParseMemory(init_body->s, init_body->len );
280 	if(doc== NULL)
281 	{
282 		LM_ERR("while parsing xml memory\n");
283 		goto error;
284 	}
285 	/* change version and state*/
286 	node= xmlDocGetNodeByName(doc, "dialog-info", NULL);
287 	if(node == NULL)
288 	{
289 		LM_ERR("while extracting dialog-info node\n");
290 		goto error;
291 	}
292 	version= int2str(ver,&len);
293 	version[len]= '\0';
294 
295 	if( xmlSetProp(node, (const xmlChar *)"version",(const xmlChar*)version)== NULL)
296 	{
297 		LM_ERR("while setting version attribute\n");
298 		goto error;
299 	}
300 	body= (str*)pkg_malloc(sizeof(str));
301 	if(body== NULL)
302 	{
303 		PKG_MEM_ERROR;
304 		goto error;
305 	}
306 	memset(body, 0, sizeof(str));
307 	xmlDocDumpFormatMemory(doc, (xmlChar**)(void*)&body->s, &body->len, 1);
308 
309 	xmlFreeDoc(doc);
310 	doc= NULL;
311 	*fin_body= body;
312 	if(*fin_body== NULL)
313 		LM_DBG("NULL fin_body\n");
314 
315 	xmlMemoryDump();
316 	xmlCleanupParser();
317 	LM_DBG("successful\n");
318 	return 1;
319 
320 error:
321 	if(doc)
322 		xmlFreeDoc(doc);
323 	if(body)
324 		pkg_free(body);
325 
326 	xmlMemoryDump();
327 	xmlCleanupParser();
328 	return -1;
329 }
330 
reginfo_process_body(publ_info_t * publ,str ** fin_body,int ver,str ** tuple)331 int reginfo_process_body(publ_info_t* publ, str** fin_body, int ver, str** tuple)
332 {
333 	xmlNodePtr node= NULL;
334 	xmlDocPtr doc= NULL;
335 	char* version;
336 	str* body= NULL;
337 	int len;
338 	str* init_body;
339 
340 	init_body= publ->body;
341 
342 	doc= xmlParseMemory(init_body->s, init_body->len );
343 	if(doc== NULL) {
344 		LM_ERR("while parsing xml memory\n");
345 		goto error;
346 	}
347 	/* change version and state*/
348 	node= xmlDocGetNodeByName(doc, "reginfo", NULL);
349 	if(node == NULL) {
350 		LM_ERR("while extracting dialog-info node\n");
351 		goto error;
352 	}
353 	version= int2str(ver,&len);
354 	version[len]= '\0';
355 
356 	if( xmlSetProp(node, (const xmlChar *)"version",(const xmlChar*)version)== NULL) {
357 		LM_ERR("while setting version attribute\n");
358 		goto error;
359 	}
360 	body= (str*)pkg_malloc(sizeof(str));
361 	if(body== NULL) {
362 		PKG_MEM_ERROR;
363 		goto error;
364 	}
365 	memset(body, 0, sizeof(str));
366 	xmlDocDumpFormatMemory(doc, (xmlChar**)(void*)&body->s, &body->len, 1);
367 
368 	xmlFreeDoc(doc);
369 	doc= NULL;
370 	*fin_body= body;
371 	if(*fin_body== NULL)
372 		LM_DBG("NULL fin_body\n");
373 
374 	xmlMemoryDump();
375 	xmlCleanupParser();
376 	LM_DBG("successful\n");
377 	return 1;
378 
379 error:
380 	if(doc)
381 		xmlFreeDoc(doc);
382 	if(body)
383 		pkg_free(body);
384 
385 	xmlMemoryDump();
386 	xmlCleanupParser();
387 	return -1;
388 }
389 
mwi_process_body(publ_info_t * publ,str ** fin_body,int ver,str ** tuple)390 int mwi_process_body(publ_info_t* publ, str** fin_body, int ver, str** tuple)
391 {
392 	*fin_body= publ->body;
393 	return 0;
394 }
395 
dlg_process_body(publ_info_t * publ,str ** fin_body,int ver,str ** tuple)396 int dlg_process_body(publ_info_t* publ, str** fin_body, int ver, str** tuple)
397 {
398 	*fin_body= publ->body;
399 	return 0;
400 }
401 
402