Browse code

- new module does specific handling for notify-subscribe events using xml bodies. It is used with the general event handling module, presence. It constructs and adds 3 events to it: presence, presence.winfo, dialog;sla.

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@2037 689a6050-402a-0410-94f2-e92a70836424

Anca Vamanu authored on 19/04/2007 17:02:48
Showing 18 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+# $Id: Makefile 1856 2007-03-15 21:06:00Z jblache $
2
+#
3
+# Presence_XML 
4
+# 
5
+# 
6
+# WARNING: do not run this directly, it should be run by the master Makefile
7
+
8
+include ../../Makefile.defs
9
+auto_gen=
10
+NAME=presence_xml.so
11
+LIBS=
12
+
13
+DEFS+=-I$(SYSBASE)/include/libxml2 -I$(LOCALBASE)/include/libxml2 \
14
+      -I$(LOCALBASE)/include
15
+LIBS+=-L$(SYSBASE)/include/lib  -L$(LOCALBASE)/lib -lxml2
16
+
17
+include ../../Makefile.modules
0 18
new file mode 100644
... ...
@@ -0,0 +1,205 @@
1
+
2
+Presence_XML Module
3
+
4
+Anca-Maria Vamanu
5
+
6
+   voice-system.ro
7
+
8
+Edited by
9
+
10
+Anca-Maria Vamanu
11
+
12
+   Copyright � 2007 voice-system.ro
13
+     _________________________________________________________
14
+
15
+   Table of Contents
16
+   1. User's Guide
17
+
18
+        1.1. Overview
19
+        1.2. Dependencies
20
+
21
+              1.2.1. OpenSER Modules
22
+              1.2.2. External Libraries or Applications
23
+
24
+        1.3. Exported Parameters
25
+
26
+              1.3.1. db_url(str)
27
+              1.3.2. xcap_table(str)
28
+              1.3.3. force_active (int)
29
+
30
+        1.4. Exported Functions
31
+        1.5. Installation
32
+
33
+   2. Developer's Guide
34
+
35
+        2.1. bind_libxml_api(libxml_api_t* api)
36
+
37
+   3. Frequently Asked Questions
38
+
39
+   List of Examples
40
+   1-1. Set db_url parameter
41
+   1-2. Set xcap_table parameter
42
+   1-3. Set force_active parameter
43
+   1-4. PRESECE_XML tables
44
+   2-1. libxml_api structure
45
+     _________________________________________________________
46
+
47
+Chapter 1. User's Guide
48
+
49
+1.1. Overview
50
+
51
+   The module does specific handling for notify-subscribe events
52
+   using xml bodies. It is used with the general event handling
53
+   module, presence. It constructs and add 3 events to it:
54
+   presence, presence.winfo, dialog;sla.
55
+
56
+   This module uses xcap_table with permission rules to deal with
57
+   authorization rules for presence.
58
+     _________________________________________________________
59
+
60
+1.2. Dependencies
61
+
62
+1.2.1. OpenSER Modules
63
+
64
+   The following modules must be loaded before this module:
65
+
66
+     * a database module.
67
+     * presence.
68
+     * sl.
69
+     _________________________________________________________
70
+
71
+1.2.2. External Libraries or Applications
72
+
73
+   The following libraries or applications must be installed
74
+   before running OpenSER with this module loaded:
75
+
76
+     * libxml.
77
+     _________________________________________________________
78
+
79
+1.3. Exported Parameters
80
+
81
+1.3.1. db_url(str)
82
+
83
+   The database url.
84
+
85
+   Default value is "NULL". 
86
+
87
+   Example 1-1. Set db_url parameter
88
+...
89
+modparam("presence_xml", "db_url",
90
+        "mysql://openser:openserrw@192.168.2.132/openser")
91
+...
92
+     _________________________________________________________
93
+
94
+1.3.2. xcap_table(str)
95
+
96
+   The name of the db table where XCAP XMLs are stored.
97
+
98
+   Default value is "xcap_xml". 
99
+
100
+   Example 1-2. Set xcap_table parameter
101
+...
102
+modparam("presence_xml", "xcap_table", "xcaps")
103
+...
104
+     _________________________________________________________
105
+
106
+1.3.3. force_active (int)
107
+
108
+   This parameter is used for permissions when handling Subscribe
109
+   messages. If set to 1, subscription state is considered active
110
+   and the presentity is not queried for permissions. Otherwise,
111
+   the xcap_table is queried and the state is extracted from
112
+   there. If no record exists, the subscriptions remains in
113
+   pending state and the watcher receives Notify messages with no
114
+   body. ( If not using an xcap server, you should set this
115
+   parameter to 1).
116
+
117
+   Default value is "0". 
118
+
119
+   Example 1-3. Set force_active parameter
120
+...
121
+modparam("presence_xml", "force_active", 1)
122
+...
123
+     _________________________________________________________
124
+
125
+1.4. Exported Functions
126
+
127
+   None to be used in configuration file.
128
+     _________________________________________________________
129
+
130
+1.5. Installation
131
+
132
+   The module requires 1 table in OpenSER database. Next SQL
133
+   statements shows the syntax to create it.
134
+
135
+   Example 1-4. PRESECE_XML tables
136
+...
137
+
138
+use openser;
139
+
140
+CREATE TABLE `xcap_xml` (
141
+  `id` int(10) NOT NULL auto_increment,
142
+  `username` varchar(66) NOT NULL,
143
+  `domain` varchar(128) NOT NULL,
144
+  `xcap` text NOT NULL,
145
+  `doc_type` int(11) NOT NULL,
146
+  UNIQUE KEY udd_xcap (`username`,`domain`,`doc_type`),
147
+  PRIMARY KEY (id)
148
+) ENGINE=MyISAM;
149
+
150
+...
151
+     _________________________________________________________
152
+
153
+Chapter 2. Developer's Guide
154
+
155
+   The module provides an imporved xml library on top of libxml
156
+   that can be used in other OpenSER modules.
157
+     _________________________________________________________
158
+
159
+2.1. bind_libxml_api(libxml_api_t* api)
160
+
161
+   This function binds the presece_xml modules and fills the
162
+   structure with the 4 exported function.
163
+
164
+   Example 2-1. libxml_api structure
165
+...
166
+typedef struct libxml_api {
167
+        xmlDocGetNodeByName_t xmlDocGetNodeByName;
168
+        xmlNodeGetChildByName_t xmlNodeGetChildByName;
169
+        xmlNodeGetNodeContentByName_t xmlNodeGetNodeContentByName;
170
+        xmlNodeGetAttrContentByName_t xmlNodeGetAttrContentByName;
171
+} libxml_api_t;
172
+...
173
+     _________________________________________________________
174
+
175
+Chapter 3. Frequently Asked Questions
176
+
177
+   3.1. Where can I find more about OpenSER?
178
+   3.2. Where can I post a question about this module?
179
+   3.3. How can I report a bug?
180
+
181
+   3.1. Where can I find more about OpenSER?
182
+
183
+   Take a look at http://openser.org/.
184
+
185
+   3.2. Where can I post a question about this module?
186
+
187
+   First at all check if your question was already answered on
188
+   one of our mailing lists:
189
+
190
+     * User Mailing List -
191
+       http://openser.org/cgi-bin/mailman/listinfo/users
192
+     * Developer Mailing List -
193
+       http://openser.org/cgi-bin/mailman/listinfo/devel
194
+
195
+   E-mails regarding any stable OpenSER release should be sent to
196
+   <users@openser.org> and e-mails regarding development versions
197
+   should be sent to <devel@openser.org>.
198
+
199
+   If you want to keep the mail private, send it to
200
+   <team@openser.org>.
201
+
202
+   3.3. How can I report a bug?
203
+
204
+   Please follow the guidelines provided at:
205
+   http://sourceforge.net/tracker/?group_id=139143.
0 206
new file mode 100644
... ...
@@ -0,0 +1,151 @@
1
+/*
2
+ * $Id: add_events.c 2006-12-07 18:05:05Z anca_vamanu $
3
+ *
4
+ * presence_xml module - 
5
+ *
6
+ * Copyright (C) 2006 Voice Sistem S.R.L.
7
+ *
8
+ * This file is part of openser, a free SIP server.
9
+ *
10
+ * openser 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
14
+ *
15
+ * openser 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.
19
+ *
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
23
+ *
24
+ * History:
25
+ * --------
26
+ *  2007-04-17  initial version (anca)
27
+ */
28
+
29
+/*
30
+ *	add 3 events: presence, presence.winfo, dialog;sla
31
+ * */
32
+#include <stdio.h>
33
+#include <stdlib.h>
34
+#include <string.h>
35
+#include <libxml/parser.h>
36
+#include "../../parser/parse_content.h"
37
+#include "../../data_lump_rpl.h"
38
+#include "xcap_auth.h"
39
+#include "notify_body.h"
40
+#include "add_events.h"
41
+#include "presence_xml.h"
42
+
43
+static str pu_415_rpl  = str_init("Unsupported media type");
44
+extern add_event_t pres_add_event;
45
+
46
+int xml_add_events()
47
+{
48
+	ev_t event;
49
+	str param;
50
+	
51
+	/* constructing presence event */
52
+	memset(&event, 0, sizeof(ev_t));
53
+	event.name.s= "presence";
54
+	event.name.len= 8;
55
+
56
+	event.content_type.s= "application/pidf+xml";
57
+	event.content_type.len= 20;
58
+
59
+	event.type= PUBL_TYPE;
60
+	event.req_auth= 1;
61
+	event.apply_auth_nbody= pres_apply_auth;
62
+	event.is_watcher_allowed= pres_watcher_allowed;
63
+	event.agg_nbody= pres_agg_nbody;
64
+	event.evs_publ_handl= xml_publ_handl;
65
+
66
+	if(pres_add_event(&event)< 0)
67
+	{
68
+		LOG(L_ERR, "PRESENCE_XML: ERROR while adding event presence\n");
69
+		return -1;
70
+	}		
71
+
72
+	/* constructing presence.winfo event */
73
+	memset(&event, 0, sizeof(ev_t));
74
+	event.name.s= "presence.winfo";
75
+	event.name.len= 14;
76
+
77
+	event.content_type.s= "application/watcherinfo+xml";
78
+	event.content_type.len= 27;
79
+	event.type= WINFO_TYPE;
80
+
81
+	if(pres_add_event(&event)< 0)
82
+	{
83
+		LOG(L_ERR, "PRESENCE_XML: ERROR while adding event presence.winfo\n");
84
+		return -1;
85
+	}
86
+	
87
+	/* constructing bla event */
88
+	memset(&event, 0, sizeof(ev_t));
89
+	event.name.s= "dialog";
90
+	event.name.len= 6;
91
+
92
+	param.s= "sla";
93
+	param.len= 3;
94
+	event.param= &param;
95
+	event.evs_publ_handl= xml_publ_handl;
96
+	event.content_type.s= "application/dialog-info+xml";
97
+	event.content_type.len= 27;
98
+	event.type= PUBL_TYPE;
99
+
100
+	if(pres_add_event(&event)< 0)
101
+	{
102
+		LOG(L_ERR, "PRESENCE_XML: ERROR while adding event dialog;sla\n");
103
+		return -1;
104
+	}
105
+	
106
+	return 0;
107
+}
108
+/*
109
+ * in event specific publish handling - only check is good body format
110
+ */
111
+int	xml_publ_handl(struct sip_msg* msg)
112
+{	
113
+	str body= {0, 0};
114
+	xmlDocPtr doc= NULL;
115
+
116
+	if ( get_content_length(msg) == 0 )
117
+		return 1;
118
+	
119
+	body.s=get_body(msg);
120
+	if (body.s== NULL) 
121
+	{
122
+		LOG(L_ERR,"PRESENCE_XML:xml_publ_handl: ERROR cannot extract body"
123
+				" from msg\n");
124
+		goto error;
125
+	}
126
+	/* content-length (if present) must be already parsed */
127
+
128
+	body.len = get_content_length( msg );
129
+	doc= xmlParseMemory( body.s , body.len );
130
+	if(doc== NULL)
131
+	{
132
+		LOG(L_ERR, "PRESENCE: xml_publ_handl: bad body format\n");
133
+		if( slb.reply( msg, 415, &pu_415_rpl)== -1)
134
+		{
135
+			LOG(L_ERR,"PRESENCE: handle_publish: ERORR while sending"
136
+					" reply\n");
137
+		}
138
+		goto error;
139
+	}
140
+	xmlFreeDoc(doc);
141
+	xmlCleanupParser();
142
+	xmlMemoryDump();
143
+	return 1;
144
+
145
+error:
146
+	xmlFreeDoc(doc);
147
+	xmlCleanupParser();
148
+	xmlMemoryDump();
149
+	return -1;
150
+
151
+}	
0 152
new file mode 100644
... ...
@@ -0,0 +1,35 @@
1
+/*
2
+ * $Id: add_events.h 2006-12-07 18:05:05Z anca_vamanu $
3
+ *
4
+ * presence_xml module - 
5
+ *
6
+ * Copyright (C) 2006 Voice Sistem S.R.L.
7
+ *
8
+ * This file is part of openser, a free SIP server.
9
+ *
10
+ * openser 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
14
+ *
15
+ * openser 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.
19
+ *
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
23
+ *
24
+ * History:
25
+ * --------
26
+ *  2007-04-18  initial version (anca)
27
+ */
28
+
29
+#ifndef _XML_ADD_EV_H_
30
+#define _XML_ADD_EV_H_
31
+
32
+int xml_add_events();
33
+int	xml_publ_handl(struct sip_msg* msg);
34
+
35
+#endif
0 36
new file mode 100644
1 37
Binary files /dev/null and b/modules_k/presence_xml/doc/.presence_xml_user.sgml.swp differ
2 38
new file mode 100644
... ...
@@ -0,0 +1,58 @@
1
+<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
2
+
3
+
4
+<!ENTITY user SYSTEM "presence_xml_user.sgml">
5
+<!ENTITY devel SYSTEM "presence_xml_devel.sgml">
6
+<!ENTITY faq SYSTEM "presence_xml_faq.sgml">
7
+<!ENTITY sql SYSTEM "presence_xml.sql">
8
+
9
+<!-- Include general documentation entities -->
10
+<!ENTITY % docentities SYSTEM "../../../doc/entities.sgml">
11
+%docentities;
12
+
13
+]>
14
+
15
+<book>
16
+    <bookinfo>
17
+	<title>Presence_XML Module</title>
18
+	<productname class="trade">&sername;</productname>
19
+	<authorgroup>
20
+	    <author>
21
+		<firstname>Anca-Maria</firstname>
22
+		<surname>Vamanu</surname>
23
+		<affiliation><orgname>&voicesystem;</orgname></affiliation>
24
+		<address>
25
+		<email>anca@voice-system.ro</email>
26
+		<otheraddr>
27
+		<ulink url="http://www.voice-system.ro">http://www.voice-system.ro</ulink>
28
+		</otheraddr>
29
+		</address>
30
+	    </author>
31
+	    <editor>
32
+		<firstname>Anca-Maria</firstname>
33
+		<surname>Vamanu</surname>
34
+		<address>
35
+		    <email>anca@voice-system.ro</email>
36
+		</address>
37
+	    </editor>
38
+	</authorgroup>
39
+	<copyright>
40
+	    <year>2007</year>
41
+	    <holder>&voicesystem;</holder>
42
+	</copyright>
43
+	<revhistory>
44
+	    <revision>
45
+		<revnumber>$Revision: 1499 $</revnumber>
46
+		<date>$Date: 2007-01-12 14:05:57 +0200 (Fri, 12 Jan 2007) $</date>
47
+	    </revision>
48
+	</revhistory>
49
+  </bookinfo>
50
+    <toc></toc>
51
+    
52
+    &user;
53
+    &devel;
54
+    &faq;
55
+    
56
+</book>
57
+
58
+
0 59
new file mode 100644
... ...
@@ -0,0 +1,12 @@
1
+
2
+use openser;
3
+
4
+CREATE TABLE `xcap_xml` (
5
+  `id` int(10) NOT NULL auto_increment,
6
+  `username` varchar(66) NOT NULL,
7
+  `domain` varchar(128) NOT NULL,
8
+  `xcap` text NOT NULL,
9
+  `doc_type` int(11) NOT NULL,
10
+  UNIQUE KEY udd_xcap (`username`,`domain`,`doc_type`),
11
+  PRIMARY KEY (id)
12
+) ENGINE=MyISAM;
0 13
new file mode 100644
... ...
@@ -0,0 +1,46 @@
1
+<!-- Module Developer's Guide -->
2
+
3
+<chapter>
4
+    <chapterinfo>
5
+	<revhistory>
6
+	    <revision>
7
+		<revnumber>$Revision: 1168 $</revnumber>
8
+		<date>$Date: 2006-10-13 15:21:23 +0300 (Fri, 13 Oct 2006) $</date>
9
+	    </revision>
10
+	</revhistory>
11
+    </chapterinfo>
12
+    <title>Developer's Guide</title>
13
+	<para>
14
+		The module provides an imporved xml library on top of libxml that can
15
+		be used in other &ser; modules.
16
+   </para>
17
+ 		<section>
18
+				<title>
19
+				<function moreinfo="none">bind_libxml_api(libxml_api_t* api)</function>
20
+				</title>
21
+			<para>
22
+				This function binds the presece_xml modules and fills the structure 
23
+				with the 4 exported function.
24
+			</para>
25
+		<example>
26
+		<title><function>libxml_api</function> structure</title>
27
+	<programlisting format="linespecific">
28
+...
29
+typedef struct libxml_api {
30
+	xmlDocGetNodeByName_t xmlDocGetNodeByName;
31
+	xmlNodeGetChildByName_t xmlNodeGetChildByName;
32
+	xmlNodeGetNodeContentByName_t xmlNodeGetNodeContentByName;
33
+	xmlNodeGetAttrContentByName_t xmlNodeGetAttrContentByName;
34
+} libxml_api_t;
35
+...
36
+	</programlisting>
37
+	</example>
38
+	</section>
39
+
40
+</chapter>
41
+
42
+<!-- Keep this element at the end of the file
43
+Local Variables:
44
+sgml-parent-document: ("presence_xml.sgml" "book" "chapter")
45
+End:
46
+-->
0 47
new file mode 100644
... ...
@@ -0,0 +1,70 @@
1
+<!-- Module FAQ -->
2
+
3
+<chapter>
4
+    <chapterinfo>
5
+	<revhistory>
6
+	    <revision>
7
+		<revnumber>$Revision: 1168 $</revnumber>
8
+		<date>$Date: 2006-10-13 15:21:23 +0300 (Fri, 13 Oct 2006) $</date>
9
+	    </revision>
10
+	</revhistory>
11
+    </chapterinfo>
12
+    <title>Frequently Asked Questions</title>
13
+    <qandaset defaultlabel="number">
14
+	<qandaentry>
15
+	    <question>
16
+		<para>Where can I find more about OpenSER?</para>
17
+	    </question>
18
+	    <answer>
19
+		<para>
20
+			Take a look at &serhomelink;.
21
+		</para>
22
+	    </answer>
23
+	</qandaentry>
24
+	<qandaentry>
25
+	    <question>
26
+		<para>Where can I post a question about this module?</para>
27
+	    </question>
28
+	    <answer>
29
+		<para>
30
+			First at all check if your question was already answered on one of
31
+			our mailing lists: 
32
+		</para>
33
+		<itemizedlist>
34
+		    <listitem>
35
+			<para>User Mailing List - &seruserslink;</para>
36
+		    </listitem>
37
+		    <listitem>
38
+			<para>Developer Mailing List - &serdevlink;</para>
39
+		    </listitem>
40
+		</itemizedlist>
41
+		<para>
42
+			E-mails regarding any stable &ser; release should be sent to 
43
+			&serusersmail; and e-mails regarding development versions
44
+			should be sent to &serdevmail;.
45
+		</para>
46
+		<para>
47
+			If you want to keep the mail private, send it to 
48
+			&serhelpmail;.
49
+		</para>
50
+	    </answer>
51
+	</qandaentry>
52
+	<qandaentry>
53
+	    <question>
54
+		<para>How can I report a bug?</para>
55
+	    </question>
56
+	    <answer>
57
+		<para>
58
+			Please follow the guidelines provided at:
59
+			&serbugslink;.
60
+		</para>
61
+	    </answer>
62
+	</qandaentry>
63
+    </qandaset>
64
+</chapter>
65
+
66
+<!-- Keep this element at the end of the file
67
+Local Variables:
68
+sgml-parent-document: ("presence_xml.sgml" "Book" "chapter")
69
+End:
70
+-->
0 71
new file mode 100644
... ...
@@ -0,0 +1,166 @@
1
+<!-- Module User's Guide -->
2
+
3
+<chapter>
4
+	<chapterinfo>
5
+	<revhistory>
6
+		<revision>
7
+		<revnumber>$Revision: 1953 $</revnumber>
8
+		<date>$Date: 2007-04-04 11:50:33 +0300 (Wed, 04 Apr 2007) $</date>
9
+		</revision>
10
+	</revhistory>
11
+	</chapterinfo>
12
+	<title>User's Guide</title>
13
+	
14
+	<section>
15
+	<title>Overview</title>
16
+	<para> 
17
+	The module does specific handling for notify-subscribe events using xml bodies.
18
+	It is used with the general event handling module, presence. It constructs and add
19
+	3 events to it: presence, presence.winfo, dialog;sla. 
20
+	</para>
21
+	<para>
22
+	This module uses xcap_table with permission rules to deal with authorization rules 
23
+	for presence.
24
+	</para>
25
+	<para>
26
+	</section>
27
+
28
+	<section>
29
+	<title>Dependencies</title>
30
+	<section>
31
+		<title>&ser; Modules</title>
32
+		<para>
33
+		The following modules must be loaded before this module:
34
+			<itemizedlist>
35
+			<listitem>
36
+			<para>
37
+				<emphasis>a database module</emphasis>.
38
+			</para>
39
+			</listitem>
40
+			<listitem>
41
+			<para>
42
+				<emphasis>presence</emphasis>.
43
+			</para>
44
+			</listitem>
45
+			<listitem>
46
+			<para>
47
+				<emphasis>sl</emphasis>.
48
+			</para>
49
+			</listitem>
50
+			</itemizedlist>
51
+		</para>
52
+	</section>
53
+
54
+	<section>
55
+		<title>External Libraries or Applications</title>
56
+		<para>
57
+		The following libraries or applications must be installed before running
58
+		&ser; with this module loaded:
59
+			<itemizedlist>
60
+			<listitem>
61
+			<para>
62
+				<emphasis>libxml</emphasis>.
63
+			</para>
64
+			</listitem>
65
+			</itemizedlist>
66
+		</para>
67
+	</section>
68
+	</section>
69
+	
70
+	<section>
71
+	<title>Exported Parameters</title>
72
+	<section>
73
+		<title><varname>db_url</varname>(str)</title>
74
+		<para>
75
+		The database url.
76
+		</para>
77
+		<para>
78
+		<emphasis>	Default value is <quote>NULL</quote>.	
79
+		</emphasis>
80
+		</para>
81
+		<example>
82
+		<title>Set <varname>db_url</varname> parameter</title>
83
+		<programlisting format="linespecific">
84
+...
85
+modparam("presence_xml", "db_url", 
86
+	"mysql://openser:openserrw@192.168.2.132/openser")
87
+...
88
+</programlisting>
89
+		</example>
90
+	</section>
91
+	<section>
92
+		<title><varname>xcap_table</varname>(str)</title>
93
+		<para>
94
+		The name of the db table where XCAP XMLs are stored.
95
+		</para>
96
+		<para>
97
+		<emphasis>	Default value is <quote>xcap_xml</quote>.
98
+		</emphasis>
99
+		</para>
100
+		<example>
101
+		<title>Set <varname>xcap_table</varname> parameter</title>
102
+		<programlisting format="linespecific">
103
+...
104
+modparam("presence_xml", "xcap_table", "xcaps")
105
+...
106
+</programlisting>
107
+		</example>
108
+	</section>
109
+
110
+	<section>
111
+		<title><varname>force_active</varname> (int)</title>
112
+		<para>
113
+		This parameter is used for permissions when handling Subscribe messages.
114
+		If set to 1, subscription state is considered active and the presentity
115
+		is not queried for permissions. 
116
+		Otherwise, the xcap_table is queried and the state is extracted
117
+		from there. If no record exists, the subscriptions remains in pending
118
+		state and the watcher receives Notify messages with no body.
119
+		( If not using an xcap server, you should set this parameter to 1).
120
+		</para>
121
+		<para>
122
+		<emphasis>Default value is <quote>0</quote>.
123
+		</emphasis>
124
+		</para>
125
+		<example>
126
+		<title>Set <varname>force_active</varname> parameter</title>
127
+		<programlisting format="linespecific">
128
+...
129
+modparam("presence_xml", "force_active", 1)
130
+...
131
+</programlisting>
132
+		</example>
133
+	</section>
134
+</section>
135
+
136
+<section>
137
+	<title>Exported Functions</title>
138
+	<para>
139
+	None to be used in configuration file.
140
+	</para>
141
+</section>
142
+
143
+<section>
144
+	<title>Installation</title>
145
+	<para>
146
+	The module requires 1 table in OpenSER database. Next SQL statements
147
+	shows the syntax to create it.
148
+	</para>
149
+	<example>
150
+	<title>PRESECE_XML tables</title>
151
+	<programlisting format="linespecific">
152
+...
153
+&sql;
154
+...
155
+</programlisting>
156
+	</example>
157
+</section>
158
+
159
+</chapter>
160
+
161
+<!-- Keep this element at the end of the file
162
+Local Variables:
163
+sgml-parent-document: ("presence_xml.sgml" "Book" "chapter")
164
+End:
165
+-->
166
+
0 167
new file mode 100644
... ...
@@ -0,0 +1,1037 @@
1
+/*
2
+ * $Id: notify_body.c 1337 2006-12-07 18:05:05Z bogdan_iancu $
3
+ *
4
+ * presence_xml module -  
5
+ *
6
+ * Copyright (C) 2006 Voice Sistem S.R.L.
7
+ *
8
+ * This file is part of openser, a free SIP server.
9
+ *
10
+ * openser 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
14
+ *
15
+ * openser 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.
19
+ *
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
23
+ *
24
+ * History:
25
+ * --------
26
+ *  2007-04-11  initial version (anca)
27
+ */
28
+
29
+#include <string.h>
30
+#include <stdlib.h>
31
+#include <libxml/parser.h>
32
+
33
+#include "xcap_auth.h"
34
+#include "pidf.h"
35
+#include "notify_body.h"
36
+
37
+str* offline_nbody(str* body);
38
+str* agregate_xmls(str** body_array, int n);
39
+str* get_final_notify_body( subs_t *subs, str* notify_body, xmlNodePtr rule_node);
40
+
41
+str* pres_agg_nbody(str** body_array, int n, int off_index)
42
+{
43
+	str* n_body= NULL;
44
+
45
+	if(off_index>= 0)
46
+	{
47
+		body_array[off_index]= offline_nbody(body_array[off_index]);
48
+		if(body_array[off_index]== NULL || body_array[off_index]->s== NULL)
49
+		{
50
+			LOG(L_ERR, "PRESENCE_XML: ERROR while constructing offline body\n");
51
+			return NULL;
52
+		}
53
+	}
54
+	
55
+	n_body= agregate_xmls(body_array, n);
56
+	if(n_body== NULL)
57
+	{
58
+		LOG(L_ERR, "PRESENCE_XML: ERROR while constructing offline body\n");
59
+	}
60
+
61
+	if(off_index>= 0)
62
+	{
63
+		xmlFree(body_array[off_index]->s);
64
+		pkg_free(body_array[off_index]);
65
+	}
66
+
67
+	return n_body;
68
+}	
69
+
70
+int pres_apply_auth(str* notify_body, subs_t* subs, str* final_nbody)
71
+{
72
+	xmlDocPtr doc= NULL;
73
+	xmlNodePtr node= NULL;
74
+	str* n_body= NULL;
75
+
76
+	final_nbody= NULL;
77
+
78
+	doc= get_xcap_tree(subs->to_user, subs->to_domain);
79
+	if(doc== NULL)
80
+	{
81
+		DBG("PRESENCE_XML:pres_apply_auth: No xcap document found\n");
82
+		return 0;
83
+	}
84
+	
85
+	node= get_rule_node(subs, doc);
86
+	if(node== NULL)
87
+	{
88
+		DBG("PRESENCE_XML:pres_apply_auth: he subscriber didn't match"
89
+					" the conditions\n");
90
+		xmlFreeDoc(doc);
91
+		return 0;
92
+	}
93
+	
94
+	n_body= get_final_notify_body(subs, notify_body, node);
95
+	if(n_body== NULL)
96
+	{
97
+		LOG(L_ERR, "PRESENCE_XML:pres_apply_auth: ERROR in function"
98
+				" get_final_notify_body\n");
99
+		xmlFreeDoc(doc);
100
+		return -1;
101
+	}
102
+
103
+	xmlFreeDoc(doc);
104
+	final_nbody= n_body;
105
+	return 1;
106
+
107
+}	
108
+
109
+str* get_final_notify_body( subs_t *subs, str* notify_body, xmlNodePtr rule_node)
110
+{
111
+	xmlNodePtr transf_node = NULL, node = NULL, dont_provide = NULL;
112
+	xmlNodePtr doc_root = NULL, doc_node = NULL, provide_node = NULL;
113
+	xmlNodePtr all_node = NULL;
114
+	xmlDocPtr doc= NULL;
115
+	char name[15];
116
+	char service_uri_scheme[10];
117
+	int i= 0, found = 0;
118
+	str* new_body = NULL;
119
+    char* class_cont = NULL, *occurence_ID= NULL, *service_uri= NULL;
120
+	char* deviceID = NULL;
121
+	char* content = NULL;
122
+	char all_name[20];
123
+
124
+	strcpy(all_name, "all-");
125
+
126
+	new_body = (str*)pkg_malloc(sizeof(str));
127
+	if(new_body == NULL)
128
+	{
129
+		LOG(L_ERR,"get_final_notify_body: ERROR while allocating memory\n");
130
+		return NULL;
131
+	}	
132
+
133
+	memset(new_body, 0, sizeof(str));
134
+
135
+	doc = xmlParseMemory(notify_body->s, notify_body->len);
136
+	if(doc== NULL) 
137
+	{
138
+		LOG(L_ERR,"get_final_notify_body: ERROR while parsing the xml body"
139
+				" message\n");
140
+		goto error;
141
+	}
142
+	doc_root = xmlDocGetNodeByName(doc,"presence", NULL);
143
+	if(doc_root == NULL)
144
+	{
145
+		LOG(L_ERR,"PRESENCE_XML:get_final_notify_body:ERROR while extracting"
146
+				" the transformation node\n");
147
+		goto error;
148
+	}
149
+
150
+	transf_node = xmlNodeGetChildByName(rule_node, "transformations");
151
+	if(transf_node == NULL)
152
+	{
153
+		LOG(L_ERR,"PRESENCE_XML:get_final_notify_body:ERROR while extracting"
154
+				" the transformation node\n");
155
+		goto error;
156
+	}
157
+	
158
+	for(node = transf_node->children; node; node = node->next )
159
+	{
160
+		if(xmlStrcasecmp(node->name, (unsigned char*)"text")== 0)
161
+			continue;
162
+
163
+		DBG("PRESENCE_XML:get_final_notify_body:transf_node->name:%s\n",node->name);
164
+
165
+		strcpy((char*)name ,(char*)(node->name + 8));
166
+		strcpy(all_name+4, name);
167
+		
168
+		if(xmlStrcasecmp((unsigned char*)name,(unsigned char*)"services") == 0)
169
+			strcpy(name, "tuple");
170
+		if(strncmp((char*)name,"person", 6) == 0)
171
+			name[6] = '\0';
172
+
173
+		doc_node = xmlNodeGetNodeByName(doc_root, name, NULL);
174
+		if(doc_node == NULL)
175
+			continue;
176
+		DBG("PRESENCE_XML:get_final_notify_body:searched doc_node->name:%s\n",name);
177
+	
178
+		content = (char*)xmlNodeGetContent(node);
179
+		if(content)
180
+		{
181
+			DBG("PRESENCE_XML:get_final_notify_body: content = %s\n", content);
182
+		
183
+			if(xmlStrcasecmp((unsigned char*)content,
184
+					(unsigned char*) "FALSE") == 0)
185
+			{
186
+				DBG("PRESENCE_XML:get_final_notify_body:found content false\n");
187
+				while( doc_node )
188
+				{
189
+					xmlUnlinkNode(doc_node);	
190
+					xmlFreeNode(doc_node);
191
+					doc_node = xmlNodeGetChildByName(doc_root, name);
192
+				}
193
+				xmlFree(content);
194
+				continue;
195
+			}
196
+		
197
+			if(xmlStrcasecmp((unsigned char*)content,
198
+					(unsigned char*) "TRUE") == 0)
199
+			{
200
+				DBG("PRESENCE_XML:get_final_notify_body:found content true\n");
201
+				xmlFree(content);
202
+				continue;
203
+			}
204
+			xmlFree(content);
205
+		}
206
+
207
+		while (doc_node )
208
+		{
209
+			if (xmlStrcasecmp(doc_node->name,(unsigned char*)"text")==0)
210
+			{
211
+				doc_node = doc_node->next;
212
+				continue;
213
+			}
214
+
215
+			if (xmlStrcasecmp(doc_node->name,(unsigned char*)name)!=0)
216
+			{
217
+				break;
218
+			}
219
+			all_node = xmlNodeGetChildByName(node, all_name) ;
220
+		
221
+			if( all_node )
222
+			{
223
+				DBG("PRESENCE_XML:get_final_notify_body: must provide all\n");
224
+				doc_node = doc_node->next;
225
+				continue;
226
+			}
227
+
228
+			found = 0;
229
+			class_cont = xmlNodeGetNodeContentByName(doc_node, "class", 
230
+					NULL);
231
+			if(class_cont == NULL)
232
+				DBG("PRESENCE_XML:get_final_notify_body: no class tag found\n");
233
+			else
234
+				DBG("PRESENCE_XML:get_final_notify_body found class = %s\n",
235
+						class_cont);
236
+
237
+			occurence_ID = xmlNodeGetAttrContentByName(doc_node, "id");
238
+			if(occurence_ID == NULL)
239
+				DBG("PRESENCE_XML:get_final_notify_body: no id found\n");
240
+			else
241
+				DBG("PRESENCE_XML:get_final_notify_body found id = %s\n",
242
+						occurence_ID);
243
+
244
+
245
+			deviceID = xmlNodeGetNodeContentByName(doc_node, "deviceID",
246
+					NULL);	
247
+			if(deviceID== NULL)
248
+				DBG("PRESENCE_XML:get_final_notify_body: no deviceID found\n");
249
+			else
250
+				DBG("PRESENCE_XML:get_final_notify_body found deviceID = %s\n",
251
+						deviceID);
252
+
253
+
254
+			service_uri = xmlNodeGetNodeContentByName(doc_node, "contact",
255
+					NULL);	
256
+			if(service_uri == NULL)
257
+				DBG("PRESENCE_XML:get_final_notify_body: no service_uri found\n");
258
+			else
259
+				DBG("PRESENCE_XML:get_final_notify_body found service_uri = %s\n",
260
+						service_uri);
261
+
262
+			if(service_uri!= NULL)
263
+			{
264
+				while(service_uri[i]!= ':')
265
+				{
266
+					service_uri_scheme[i] = service_uri[i];
267
+					i++;
268
+				}
269
+				service_uri_scheme[i] = '\0';
270
+				DBG("PRESENCE_XML:get_final_notify_body:service_uri_scheme: %s\n",
271
+						service_uri_scheme);
272
+			}
273
+
274
+			provide_node = node->children;
275
+				
276
+			while ( provide_node!= NULL )
277
+			{
278
+				if(xmlStrcasecmp(provide_node->name,(unsigned char*) "text")==0)
279
+				{
280
+					provide_node = 	provide_node->next;
281
+					continue;
282
+				}
283
+
284
+				if(xmlStrcasecmp(provide_node->name,(unsigned char*)"class")== 0
285
+						&& class_cont )
286
+				{
287
+					content = (char*)xmlNodeGetContent(provide_node);
288
+
289
+					if(content&& xmlStrcasecmp((unsigned char*)content,
290
+								(unsigned char*)class_cont) == 0)
291
+					{
292
+						found = 1;
293
+						DBG("PRESENCE_XML:get_final_notify_body: found class= %s",
294
+								class_cont);
295
+						xmlFree(content);
296
+						break;
297
+					}
298
+					if(content)
299
+						xmlFree(content);
300
+				}
301
+				if(xmlStrcasecmp(provide_node->name,
302
+							(unsigned char*) "deviceID")==0&&deviceID )
303
+				{
304
+					content = (char*)xmlNodeGetContent(provide_node);
305
+
306
+					if(content && xmlStrcasecmp ((unsigned char*)content,
307
+								(unsigned char*)deviceID) == 0)
308
+					{
309
+						found = 1;
310
+						DBG("PRESENCE_XML:get_final_notify_body: found deviceID="
311
+								" %s", deviceID);
312
+						xmlFree(content);
313
+						break;
314
+					}
315
+					if(content)
316
+						xmlFree(content);
317
+
318
+				}
319
+				if(xmlStrcasecmp(provide_node->name,
320
+							(unsigned char*)"occurence-id")== 0&& occurence_ID)
321
+				{
322
+					content = (char*)xmlNodeGetContent(provide_node);
323
+					if(content && xmlStrcasecmp ((unsigned char*)content,
324
+								(unsigned char*)occurence_ID) == 0)
325
+					{
326
+						found = 1;
327
+						DBG("PRESENCE_XML:get_final_notify_body:" 
328
+								" found occurenceID= %s\n", occurence_ID);
329
+						xmlFree(content);
330
+						break;
331
+					}
332
+					if(content)
333
+						xmlFree(content);
334
+
335
+				}
336
+				if(xmlStrcasecmp(provide_node->name,
337
+							(unsigned char*)"service-uri")== 0 && service_uri)
338
+				{
339
+					content = (char*)xmlNodeGetContent(provide_node);
340
+					if(content&& xmlStrcasecmp ((unsigned char*)content,
341
+								(unsigned char*)service_uri) == 0)
342
+					{
343
+						found = 1;
344
+						DBG("PRESENCE_XML:get_final_notify_body: found"
345
+								" service_uri= %s", service_uri);
346
+						xmlFree(content);
347
+						break;
348
+					}
349
+					if(content)
350
+						xmlFree(content);
351
+
352
+				}
353
+			
354
+				if(xmlStrcasecmp(provide_node->name,
355
+							(unsigned char*)"service-uri-scheme")==0
356
+						&& service_uri_scheme)
357
+				{
358
+					content = (char*)xmlNodeGetContent(provide_node);
359
+					DBG("PRESENCE_XML:get_final_notify_body:"
360
+							" service_uri_scheme=%s\n",content);
361
+					if(content && xmlStrcasecmp((unsigned char*)content,
362
+								(unsigned char*)service_uri_scheme) == 0)
363
+					{
364
+						found = 1;
365
+						DBG("PRESENCE_XML:get_final_notify_body: found"
366
+								" service_uri_scheme= %s", service_uri_scheme);
367
+						xmlFree(content);
368
+						break;
369
+					}	
370
+					if(content)
371
+						xmlFree(content);
372
+
373
+				}
374
+
375
+				provide_node = provide_node->next;
376
+			}
377
+			
378
+			if(found == 0)
379
+			{
380
+				DBG("PRESENCE_XML:get_final_notify_body: delete node: %s\n",
381
+						doc_node->name);
382
+				dont_provide = doc_node;
383
+				doc_node = doc_node->next;
384
+				xmlUnlinkNode(dont_provide);	
385
+				xmlFreeNode(dont_provide);
386
+			}	
387
+			else
388
+				doc_node = doc_node->next;
389
+	
390
+		}
391
+	}
392
+	xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&new_body->s,
393
+			&new_body->len, 1);
394
+	DBG("PRESENCE_XML:get_final_notify_body: body = \n%.*s\n", new_body->len,
395
+			new_body->s);
396
+
397
+    xmlFreeDoc(doc);
398
+
399
+    xmlCleanupParser();
400
+
401
+    xmlMemoryDump();
402
+
403
+	xmlFree(class_cont);
404
+	xmlFree(occurence_ID);
405
+	xmlFree(deviceID);
406
+	xmlFree(service_uri);
407
+
408
+    return new_body;
409
+error:
410
+    if(doc)
411
+		xmlFreeDoc(doc);
412
+	if(new_body)
413
+	{
414
+		if(new_body->s)
415
+			xmlFree(new_body->s);
416
+		pkg_free(new_body);
417
+	}
418
+	if(class_cont)
419
+		xmlFree(class_cont);
420
+	if(occurence_ID)
421
+		xmlFree(occurence_ID);
422
+	if(deviceID)
423
+		xmlFree(deviceID);
424
+	if(service_uri)
425
+		xmlFree(service_uri);
426
+
427
+	return NULL;
428
+}	
429
+
430
+/*
431
+if(strncmp(subs->status.s, "active", 6)==0 && subs->reason.s
432
+					&& strncmp(subs->reason.s, "polite-block", 12)==0)
433
+				{
434
+					if(event->polite_block_nbody== NULL)
435
+					{
436
+						LOG(L_ERR, "PRESENCE_XML:notify: ERROR no plite_bloc_nbody hadling" 
437
+								" procedure defined for this event\n");
438
+						goto error;
439
+					}	
440
+					notify_body = event->polite_block_nbody(subs->to_user,subs->to_domain);
441
+					if(notify_body == NULL)
442
+					{
443
+						LOG(L_ERR, "PRESENCE_XML:notify: ERROR while building"
444
+							" polite-block body\n");
445
+						goto error;
446
+					}	
447
+
448
+
449
+
450
+if(xcap_tree!=NULL)
451
+		xmlFreeDoc(xcap_tree);
452
+
453
+
454
+
455
+int add_event(ev_t* event)
456
+{
457
+	ev_t* ev= NULL;
458
+	int size;
459
+	str str_name;
460
+	str* str_param= NULL;
461
+	char* sep= NULL;
462
+	str wipeer_name;
463
+	char buf[50];
464
+	int ret_code= 1;
465
+
466
+	str_name.s= name;
467
+	str_name.len= strlen(name);
468
+
469
+	if(param)
470
+	{
471
+		str_param= (str*)pkg_malloc(sizeof(str));
472
+		if(str_param== NULL)
473
+		{
474
+			LOG(L_ERR, "PRESENCE_XML: add_event: ERROR No more memory\n");
475
+			return -1;
476
+		}
477
+		str_param->s= param;
478
+		str_param->len= strlen(param);
479
+	}
480
+
481
+	if(contains_event(&str_name, str_param))
482
+	{
483
+		DBG("PRESENCE_XML: add_event: Found prevoius record for event\n");
484
+		ret_code= -1;
485
+		goto done;
486
+	}	
487
+	size= sizeof(ev_t)+ (str_name.len+ strlen(content_type))
488
+		*sizeof(char);
489
+
490
+	if(param)
491
+		size+= sizeof(str)+ ( 2*strlen(param) + str_name.len+ 1)* sizeof(char);
492
+
493
+	ev= (ev_t*)shm_malloc(size);
494
+	if(ev== NULL)
495
+	{
496
+		LOG(L_ERR, "PRESENCE_XML: add_event: ERROR while allocating memory\n");
497
+		ret_code= -1;
498
+		goto done;
499
+	}
500
+	memset(ev, 0, sizeof(ev_t));
501
+
502
+	size= sizeof(ev_t);
503
+	ev->name.s= (char*)ev+ size;
504
+	ev->name.len= str_name.len;
505
+	memcpy(ev->name.s, name, str_name.len);
506
+	size+= str_name.len;
507
+
508
+	if(str_param)
509
+	{	
510
+		ev->param= (str*)((char*)ev+ size);
511
+		size+= sizeof(str);
512
+		ev->param->s= (char*)ev+ size;
513
+		memcpy(ev->param->s, str_param->s, str_param->len);
514
+		ev->param->len= str_param->len;
515
+		size+= str_param->len;
516
+
517
+		ev->stored_name.s= (char*)ev+ size;
518
+		memcpy(ev->stored_name.s, name, str_name.len);
519
+		ev->stored_name.len= str_name.len;
520
+		memcpy(ev->stored_name.s+ ev->stored_name.len, ";", 1);
521
+		ev->stored_name.len+= 1;
522
+		memcpy(ev->stored_name.s+ ev->stored_name.len, str_param->s, str_param->len);
523
+		ev->stored_name.len+= str_param->len;
524
+		size+= ev->stored_name.len;
525
+	}
526
+	else
527
+	{
528
+		ev->stored_name.s= ev->name.s;
529
+		ev->stored_name.len= ev->name.len;
530
+	}	
531
+
532
+	ev->content_type.s= (char*)ev+ size;
533
+	ev->content_type.len= strlen(content_type);
534
+	memcpy(ev->content_type.s, content_type, ev->content_type.len);
535
+	size+= ev->content_type.len;
536
+	
537
+	ev->agg_body= agg_body;
538
+	
539
+	sep= strchr(name, '.');
540
+	if(sep)
541
+	{
542
+		if(strncmp(sep+1, "winfo", 5)== 0)
543
+		{	
544
+			ev->type= WINFO_TYPE;
545
+			wipeer_name.s= name;
546
+			wipeer_name.len= sep - name;
547
+			
548
+			ev->wipeer= contains_event(&wipeer_name, ev->param );
549
+		}
550
+		else
551
+		{	
552
+			ev->type= PUBL_TYPE;
553
+			wipeer_name.s= buf;
554
+			wipeer_name.len= sprintf(wipeer_name.s, "%s", name);
555
+			memcpy(wipeer_name.s+ wipeer_name.len, ".winfo", 5);
556
+			wipeer_name.len+= 5;
557
+			ev->wipeer= contains_event(&wipeer_name, ev->param);
558
+		}
559
+
560
+	}	
561
+	else
562
+		ev->type= PUBL_TYPE;
563
+
564
+	ev->next= EvList->events;
565
+	EvList->events= ev;
566
+	EvList->ev_count++;
567
+
568
+done:
569
+	if(str_param)
570
+		pkg_free(str_param);
571
+	return ret_code; 
572
+}
573
+
574
+*/
575
+
576
+str* agregate_xmls(str** body_array, int n)
577
+
578
+{
579
+	int i, j= 0, append ;
580
+	xmlNodePtr p_root= NULL, new_p_root= NULL ;
581
+	xmlDocPtr* xml_array ;
582
+	xmlNodePtr node = NULL;
583
+	xmlNodePtr add_node = NULL ;
584
+	str *body= NULL;
585
+	char* id= NULL, *tuple_id = NULL;
586
+
587
+	xml_array = (xmlDocPtr*)pkg_malloc( (n+1)*sizeof(xmlDocPtr));
588
+
589
+	if(xml_array== NULL)
590
+	{
591
+	
592
+		LOG(L_ERR,"PRESENCE:agregate_xmls: Error while alocating memory");
593
+		return NULL;
594
+	}
595
+	
596
+	memset(xml_array, 0, (n+1)*sizeof(xmlDocPtr)) ;
597
+
598
+	for(i=0; i<n;i++)
599
+	{
600
+		if(body_array[i] == NULL )
601
+			continue;
602
+
603
+		xml_array[j] = NULL;
604
+		xml_array[j] = xmlParseMemory( body_array[i]->s, body_array[i]->len );
605
+		
606
+		if( xml_array[j]== NULL)
607
+		{
608
+			LOG(L_ERR,"PRESENCE:agregate_xmls: ERROR while parsing xml body message\n");
609
+			goto error;
610
+		}
611
+		j++;
612
+
613
+	} 	
614
+
615
+	j--;
616
+	p_root = xmlDocGetNodeByName( xml_array[j], "presence", NULL);
617
+	if(p_root ==NULL)
618
+	{
619
+		LOG(L_ERR,"PRESENCE:agregate_xmls: ERROR while geting the xml_tree root\n");
620
+		goto error;
621
+	}
622
+
623
+	for(i= j; i>=0; i--)
624
+	{
625
+		new_p_root= xmlDocGetNodeByName( xml_array[i], "presence", NULL);
626
+		if(new_p_root ==NULL)
627
+		{
628
+			LOG(L_ERR,"PRESENCE:agregate_xmls: ERROR while geting the xml_tree root\n");
629
+			goto error;
630
+		}
631
+
632
+		node= xmlNodeGetChildByName(new_p_root, "tuple");