Browse code

- improved PIDF document publishing (DB data storage not fully finished yet) partialy solves BUGS: SER-86, SER-49 - unified PIDF documents creation

Vaclav Kubart authored on 05/12/2005 17:43:13
Showing 15 changed files
... ...
@@ -87,6 +87,18 @@
87 87
 	<size>10</size>
88 88
     </column>
89 89
 
90
+    <column>
91
+		<name>etag</name>
92
+		<type>string</type>
93
+		<size>64</size>
94
+    </column>
95
+    
96
+	<column>
97
+		<name>published_id</name>
98
+		<type>string</type>
99
+		<size>64</size>
100
+    </column>
101
+	
90 102
     <index>
91 103
 	<name>pc_idx1</name>
92 104
 	<colref linkend="prescontact.contactid"/>
... ...
@@ -1,3 +1,5 @@
1
+include ../Makefile.defs
2
+
1 3
 # variables to change
2 4
 
3 5
 CFLAGS   += -g -Wall
... ...
@@ -10,7 +12,6 @@ LIBS     += -L$(CURDIR)/cds -L$(CURDIR)/qsa
10 12
 ####################################
11 13
 # make rules
12 14
 
13
-include ../Makefile.defs
14 15
 
15 16
 # exports needed by libraries (this exports here allow to run make
16 17
 # in libraries independently on make in main ser directory)
... ...
@@ -20,7 +20,7 @@ endif
20 20
 
21 21
 ifeq ($(OUT_TYPE),lib)
22 22
 $(OUT_NAME):	$(OBJS)
23
-		$(CC) -shared $(DEFS) $(CFLAGS) $(INCLUDES) -o $@ $(OBJS) $(LIBS)
23
+		$(CC) -shared $(DEFS) $(CFLAGS) $(INCLUDES) $(LIBS) -o $@ $(OBJS)
24 24
 
25 25
 install:	$(OUT_NAME) $(LIBDIR)
26 26
 			$(INSTALL-TOUCH) $(LIBDIR)/$(OUT_NAME)
... ...
@@ -43,7 +43,7 @@
43 43
 
44 44
 #define ERROR_LOG(a,args...)		LOG(L_ERR,a,##args)
45 45
 #define DEBUG_LOG(a,args...)		LOG(L_DBG,a,##args)
46
-#define TRACE_LOG(a,args...)		LOG(L_ERR,a,##args)
46
+#define TRACE_LOG(a,args...)		LOG(L_INFO,a,##args)
47 47
 #define WARN_LOG(a,args...)			LOG(L_WARN,a,##args)
48 48
 #define FLUSH_LOG()					do{}while(0)
49 49
 
... ...
@@ -26,7 +26,7 @@ void reference_counter_cleanup()
26 26
 {
27 27
 	if (ref_cntr_mutex) {
28 28
 		cds_mutex_destroy(ref_cntr_mutex);
29
-		cds_free(ref_cntr_mutex);
29
+		cds_free((void*)ref_cntr_mutex);
30 30
 		ref_cntr_mutex = NULL;
31 31
 	}
32 32
 }
... ...
@@ -1,6 +1,6 @@
1 1
 DEFS     += 
2
-INCLUDES +=
3
-LIBS     += -lcds
2
+INCLUDES += -I/usr/include/libxml2 -I/usr/local/include/libxml2 -I/usr/local/include
3
+LIBS     += -L/usr/local/lib -lxml2 -lcds
4 4
 
5 5
 # name of result executable or library
6 6
 NAME = presence
... ...
@@ -2,5 +2,8 @@ LIBNAME  = presence
2 2
 OUT_NAME = libpresence.so
3 3
 OUT_TYPE = lib
4 4
 
5
+INCLUDES += -I/usr/include/libxml2
6
+LIBS     += -lxml2 -lcds
7
+
5 8
 include ../Makefile.ser.defs
6 9
 
... ...
@@ -27,40 +27,73 @@
27 27
 #include <cds/dstring.h>
28 28
 #include <cds/memory.h>
29 29
 #include <cds/logger.h>
30
+#include <cds/list.h>
31
+#include <presence/xml_utils.h>
32
+#include <string.h>
33
+
34
+/* ------------------------------ PIDF document creation ------------------------------ */
30 35
 
31 36
 static void doc_add_tuple(dstring_t *buf, presentity_info_t *p, presence_tuple_info_t *t)
32 37
 {
38
+	char tmp[32];
33 39
 	DEBUG_LOG("doc_add_tuple()\n");
34 40
 	
35 41
 	dstr_append_zt(buf, "\t<tuple id=\"");
36
-	dstr_append_str(buf, &t->contact);
42
+	dstr_append_str(buf, &t->id);
37 43
 	dstr_append_zt(buf, "\">\r\n");
38 44
 	
39 45
 	if (t->status == presence_tuple_open) dstr_append_zt(buf, "\t\t<status><basic>open</basic></status>\r\n");
40 46
 	else dstr_append_zt(buf, "\t\t<status><basic>closed</basic></status>\r\n");
41 47
 	
42
-	dstr_append_zt(buf, "\t\t<contact>");
48
+	dstr_append_zt(buf, "\t\t<contact priority=\"");
49
+	sprintf(tmp, "%1.2f", t->priority);
50
+	dstr_append_zt(buf, tmp);
51
+	dstr_append_zt(buf, "\">");
43 52
 	dstr_append_str(buf, &t->contact);
44 53
 	dstr_append_zt(buf, "</contact>\r\n");
45 54
 
46 55
 	dstr_append_zt(buf, "\t</tuple>\r\n");
47 56
 }
48 57
 
58
+static void doc_add_note(dstring_t *buf, presentity_info_t *p, presence_note_t *n)
59
+{
60
+	DEBUG_LOG("doc_add_tuple()\n");
61
+	
62
+	dstr_append_zt(buf, "\t<note");
63
+	if (n->lang.len > 0) {
64
+		dstr_append_zt(buf, " lang=\"");
65
+		dstr_append_str(buf, &n->lang);
66
+		dstr_append_zt(buf, "\"");
67
+	}
68
+	dstr_append_zt(buf, ">");
69
+	dstr_append_str(buf, &n->value);	
70
+	dstr_append_zt(buf, "</note>\r\n");
71
+}
72
+
49 73
 static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
50 74
 {
51 75
 	presence_tuple_info_t *t;
76
+	presence_note_t *n;
52 77
 
53
-	DEBUG_LOG("doc_add_presentity()\r\n");
78
+	DEBUG_LOG("doc_add_presentity()\n");
54 79
 	dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"");
55 80
 	dstr_append_str(buf, &p->presentity);
56 81
 	dstr_append_zt(buf, "\">\r\n");
57 82
 	
58
-	DEBUG_LOG("doc_add_presentity(): adding tuples\r\n");
83
+	DEBUG_LOG("doc_add_presentity(): adding tuples\n");
59 84
 	t = p->first_tuple;
60 85
 	while (t) {
61 86
 		doc_add_tuple(buf, p, t);
62 87
 		t = t->next;
63 88
 	}
89
+	
90
+	DEBUG_LOG("doc_add_presentity(): adding notes\n");
91
+	n = p->first_note;
92
+	while (n) {
93
+		doc_add_note(buf, p, n);
94
+		n = n->next;
95
+	}
96
+
64 97
 	dstr_append_zt(buf, "</presence>");
65 98
 }
66 99
 
... ...
@@ -95,3 +128,172 @@ int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_ty
95 128
 	return 0;
96 129
 }
97 130
 
131
+/* ------------------------------ PIDF document parsing ------------------------------ */
132
+
133
+static char *pidf_ns = "urn:ietf:params:xml:ns:pidf";
134
+
135
+static int read_note(xmlNode *node, presence_note_t **dst)
136
+{
137
+	const char *note = NULL;
138
+	const char *lang = NULL;
139
+
140
+	note = get_node_value(node);
141
+	lang = get_attr_value(find_attr(node->properties, "lang"));
142
+
143
+	*dst = create_presence_note_zt(note, lang);
144
+	if (!dst) return -1;
145
+	
146
+	return 0;
147
+}
148
+
149
+
150
+static int read_tuple(xmlNode *tuple, presence_tuple_info_t **dst)
151
+{
152
+	str_t contact, id;
153
+	presence_tuple_status_t status;
154
+	xmlNode *n;
155
+	double priority = 0;
156
+	const char *s;
157
+	int res = 0;
158
+	presence_note_t *note;
159
+
160
+	*dst = NULL;
161
+
162
+	DEBUG_LOG("read_tuple()\n");
163
+	/* process contact (only one node) */
164
+	n = find_node(tuple, "contact", pidf_ns);
165
+	if (!n) {
166
+		ERROR_LOG("contact not found\n");
167
+		return -1;
168
+	}
169
+	s = get_attr_value(find_attr(n->properties, "priority"));
170
+	if (s) priority = atof(s);
171
+	s = get_node_value(n);
172
+	contact.s = (char *)s;
173
+	if (s) contact.len = strlen(s);
174
+	else contact.len = 0;
175
+	if (contact.len < 1) {
176
+		ERROR_LOG("empty contact\n");
177
+		return -1;
178
+	}	
179
+	
180
+	/* process status (only one node) */
181
+	n = find_node(tuple, "status", pidf_ns);
182
+	if (!n) {
183
+		ERROR_LOG("status not found\n");
184
+		return -1;
185
+	}
186
+	n = find_node(n, "basic", pidf_ns);
187
+	if (!n) {
188
+		ERROR_LOG("basic status not found\n");
189
+		return -1;
190
+	}
191
+	s = get_node_value(n);
192
+	if (!s) {
193
+		ERROR_LOG("basic status without value\n");
194
+		return -1;
195
+	}
196
+
197
+	/* translate status */
198
+	status = presence_tuple_closed; /* default value */
199
+	if (strcmp(s, "open") == 0) status = presence_tuple_open;
200
+	if (strcmp(s, "closed") == 0) status = presence_tuple_closed;
201
+	/* FIXME: handle not standardized variants too (add note to basic status) */
202
+	
203
+	/* get ID from tuple node attribute? */
204
+	id.s = (char *)get_attr_value(find_attr(tuple->properties, "id"));
205
+	if (id.s) id.len = strlen(id.s);
206
+	else id.len = 0;
207
+	
208
+	*dst = create_tuple_info(&contact, &id, status);
209
+	if (!(*dst)) return -1;
210
+
211
+	(*dst)->priority = priority;
212
+
213
+	/* handle notes */
214
+	n = tuple->children;
215
+	while (n) {
216
+		if (n->type == XML_ELEMENT_NODE) {
217
+			if (cmp_node(n, "note", pidf_ns) >= 0) {
218
+				res = read_note(n, &note);
219
+				if ((res == 0) && note) {
220
+					DOUBLE_LINKED_LIST_ADD((*dst)->first_note, 
221
+							(*dst)->last_note, note);
222
+				}
223
+				else break;
224
+			}
225
+		}
226
+		n = n->next;
227
+	}
228
+
229
+	return res;
230
+}
231
+
232
+static int read_presentity(xmlNode *root, presentity_info_t **dst)
233
+{
234
+	xmlNode *n;
235
+	str_t entity;
236
+	presence_tuple_info_t *t;
237
+	presence_note_t *note;
238
+	int res = 0;
239
+	
240
+	DEBUG_LOG("read_presentity()\n");
241
+	if (cmp_node(root, "presence", pidf_ns) < 0) {
242
+		ERROR_LOG("document is not presence \n");
243
+		return -1;
244
+	}
245
+
246
+	entity = zt2str((char*)get_attr_value(find_attr(root->properties, "entity")));
247
+	*dst = create_presentity_info(&entity);
248
+	if (!(*dst)) return -1; /* memory */
249
+
250
+	n = root->children;
251
+	while (n) {
252
+		if (n->type == XML_ELEMENT_NODE) {
253
+			if (cmp_node(n, "tuple", pidf_ns) >= 0) {
254
+				res = read_tuple(n, &t);
255
+				if ((res == 0) && t) add_tuple_info(*dst, t);
256
+				else break;
257
+			}
258
+			if (cmp_node(n, "note", pidf_ns) >= 0) {
259
+				res = read_note(n, &note);
260
+				if ((res == 0) && note) {
261
+					DOUBLE_LINKED_LIST_ADD((*dst)->first_note, 
262
+							(*dst)->last_note, note);
263
+				}
264
+				else break;
265
+			}
266
+		}
267
+		n = n->next;
268
+	}
269
+
270
+	return res;
271
+}
272
+
273
+/* libxml2 must be initialized before calling this function ! */
274
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len)
275
+{
276
+	int res = 0;
277
+	xmlDocPtr doc;
278
+	
279
+	if (!dst) return -1;
280
+	if ((!data) || (data_len < 1)) return -2;
281
+
282
+	*dst = NULL;
283
+	doc = xmlReadMemory(data, data_len, NULL, NULL, xml_parser_flags);
284
+	if (doc == NULL) {
285
+		ERROR_LOG("can't parse document\n");
286
+		return -1;
287
+	}
288
+	
289
+	res = read_presentity(xmlDocGetRootElement(doc), dst);
290
+	if (res != 0) {
291
+		/* may be set => must be freed */
292
+		if (*dst) free_presentity_info(*dst);
293
+		*dst = NULL;
294
+	}
295
+
296
+	xmlFreeDoc(doc);
297
+	return res;
298
+}
299
+
... ...
@@ -30,5 +30,6 @@
30 30
 #include <presence/pres_doc.h>
31 31
 
32 32
 int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type);
33
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len);
33 34
 
34 35
 #endif
... ...
@@ -49,11 +49,14 @@ presentity_info_t *create_presentity_info(const str_t *presentity)
49 49
 	else p->presentity.s = NULL;
50 50
 	p->first_tuple = NULL;
51 51
 	p->last_tuple = NULL;
52
+	p->first_note = NULL;
53
+	p->last_note = NULL;
54
+	p->auth = presence_auth_unresolved;
52 55
 	
53 56
 	return p;
54 57
 }
55 58
 
56
-presence_tuple_info_t *create_tuple_info(const str_t *contact, presence_tuple_status_t status)
59
+presence_tuple_info_t *create_tuple_info(const str_t *contact, const str_t *id, presence_tuple_status_t status)
57 60
 {
58 61
 	presence_tuple_info_t *t;
59 62
 	t = (presence_tuple_info_t*)cds_malloc(sizeof(*t));
... ...
@@ -63,12 +66,15 @@ presence_tuple_info_t *create_tuple_info(const str_t *contact, presence_tuple_st
63 66
 	}
64 67
 	/* str_clear(&t->contact.s); */
65 68
 	str_dup(&t->contact, contact);
69
+	str_dup(&t->id, id);
66 70
 	str_clear(&t->extra_status);
67 71
 	t->prev = NULL;
68 72
 	t->next = NULL;
69 73
 	t->status = status;
70 74
 	t->priority = 0.0;
71 75
 	t->expires = 0;
76
+	t->first_note = NULL;
77
+	t->last_note = NULL;
72 78
 	return t;
73 79
 }
74 80
 
... ...
@@ -77,24 +83,54 @@ void add_tuple_info(presentity_info_t *p, presence_tuple_info_t *t)
77 83
 	DOUBLE_LINKED_LIST_ADD(p->first_tuple, p->last_tuple, t);
78 84
 }
79 85
 
86
+void free_presence_note(presence_note_t *n)
87
+{
88
+	if (n) {
89
+		str_free_content(&n->value);
90
+		str_free_content(&n->lang);
91
+		cds_free(n);
92
+	}
93
+}
94
+
80 95
 void free_tuple_info(presence_tuple_info_t *t)
81 96
 {
97
+	presence_note_t *n, *nn;
98
+	
82 99
 	if (!t) return;
83 100
 	str_free_content(&t->contact);
101
+	str_free_content(&t->id);
84 102
 	str_free_content(&t->extra_status);
103
+	
104
+	n = t->first_note;
105
+	while (n) {
106
+		nn = n->next;
107
+		free_presence_note(n);
108
+		n = nn;
109
+	}
110
+	
85 111
 	cds_free(t);
86 112
 }
87 113
 
88 114
 void free_presentity_info(presentity_info_t *p)
89 115
 {
90
-	presence_tuple_info_t *t;
116
+	presence_tuple_info_t *t, *tt;
117
+	presence_note_t *n, *nn;
91 118
 	
92 119
 	if (!p) return;
93 120
 	t = p->first_tuple;
94 121
 	while (t) {
122
+		tt = t->next;
95 123
 		free_tuple_info(t);
96
-		t = t->next;
124
+		t = tt;
125
+	}
126
+	
127
+	n = p->first_note;
128
+	while (n) {
129
+		nn = n->next;
130
+		free_presence_note(n);
131
+		n = nn;
97 132
 	}
133
+	
98 134
 	cds_free(p);
99 135
 }
100 136
 
... ...
@@ -134,3 +170,30 @@ void free_list_presence_info(list_presence_info_t *p)
134 170
 		cds_free(p);
135 171
 	}
136 172
 }
173
+
174
+presence_note_t *create_presence_note(const str_t *note, const str_t *lang)
175
+{
176
+	presence_note_t *t;
177
+	t = (presence_note_t*)cds_malloc(sizeof(*t));
178
+	if (!t) {
179
+		ERROR_LOG("can't allocate memory for presence note\n");
180
+		return t;
181
+	}
182
+	/* str_clear(&t->contact.s); */
183
+	str_dup(&t->value, note);
184
+	str_dup(&t->lang, lang);
185
+	t->prev = NULL;
186
+	t->next = NULL;
187
+	return t;
188
+}
189
+
190
+presence_note_t *create_presence_note_zt(const char *note, const char *lang)
191
+{
192
+	str_t note_s;
193
+	str_t lang_s;
194
+
195
+	note_s = zt2str((char*)note);
196
+	lang_s = zt2str((char*)lang);
197
+	
198
+	return create_presence_note(&note_s, &lang_s);
199
+}
... ...
@@ -30,6 +30,12 @@
30 30
 #include <cds/ptr_vector.h>
31 31
 #include <time.h>
32 32
 
33
+typedef struct _presence_note_t {
34
+	str_t value;
35
+	str_t lang;
36
+	struct _presence_note_t *prev, *next;
37
+} presence_note_t;
38
+
33 39
 typedef enum {
34 40
 	presence_tuple_open,
35 41
 	presence_tuple_closed
... ...
@@ -42,19 +48,23 @@ typedef enum {
42 48
 	presence_auth_granted
43 49
 } presence_authorization_status_t;
44 50
 
45
-typedef struct _presence_typle_info_t {
51
+typedef struct _presence_tuple_info_t {
46 52
 	str_t contact;
53
+	str_t id;
47 54
 	double priority;
48 55
 	time_t expires;
49 56
 	presence_tuple_status_t status;
50 57
 	str_t extra_status;
51
-	struct _presence_typle_info_t *next, *prev;
58
+	struct _presence_tuple_info_t *next, *prev;
59
+	presence_note_t *first_note, *last_note;/* published notes */
52 60
 } presence_tuple_info_t;
53 61
 
54 62
 typedef struct {
55 63
 	str_t presentity; /* do not modify this !*/
56 64
 	presence_tuple_info_t *first_tuple, *last_tuple;
57 65
 	presence_authorization_status_t auth;
66
+	presence_note_t *first_note, *last_note;/* published notes */
67
+		
58 68
 	char presentity_data[1];
59 69
 } presentity_info_t;
60 70
 
... ...
@@ -74,11 +84,15 @@ typedef struct {
74 84
 } list_presence_info_t;
75 85
 
76 86
 presentity_info_t *create_presentity_info(const str_t *presentity);
77
-presence_tuple_info_t *create_tuple_info(const str_t *contact, presence_tuple_status_t status);
87
+presence_tuple_info_t *create_tuple_info(const str_t *contact, const str_t *id, presence_tuple_status_t status);
78 88
 void add_tuple_info(presentity_info_t *p, presence_tuple_info_t *t);
79 89
 void free_presentity_info(presentity_info_t *p);
80 90
 
81 91
 list_presence_info_t *create_list_presence_info(const str_t *uri);
82 92
 void free_list_presence_info(list_presence_info_t *p);
83 93
 
94
+presence_note_t *create_presence_note(const str_t *note, const str_t *lang);
95
+presence_note_t *create_presence_note_zt(const char *note, const char *lang);
96
+void free_presence_note(presence_note_t *n);
97
+
84 98
 #endif
85 99
new file mode 100644
... ...
@@ -0,0 +1,134 @@
1
+/* 
2
+ * Copyright (C) 2005 iptelorg GmbH
3
+ *
4
+ * This file is part of ser, a free SIP server.
5
+ *
6
+ * ser is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version
10
+ *
11
+ * For a license to use the ser software under conditions
12
+ * other than those described here, or to purchase support for this
13
+ * software, please contact iptel.org by e-mail at the following addresses:
14
+ *    info@iptel.org
15
+ *
16
+ * ser is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with this program; if not, write to the Free Software
23
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
+ */
25
+
26
+#include <stdio.h>
27
+#include <string.h>
28
+#include <time.h>
29
+
30
+#include <libxml/parser.h>
31
+#include <libxml/tree.h>
32
+#include <cds/logger.h>
33
+#include <xcap/xml_utils.h>
34
+
35
+int xml_parser_flags = XML_PARSE_NOERROR | XML_PARSE_NOWARNING;
36
+
37
+static void str2int(const char *s, int *dst)
38
+{
39
+	/* if not null sets the given integer to value */
40
+	if (!s) return;
41
+	else *dst = atoi(s);
42
+}
43
+
44
+void get_int_attr(xmlNode *n, const char *attr_name, int *dst)
45
+{
46
+	str2int(get_attr_value(find_attr(n->properties, attr_name)), dst);
47
+}
48
+
49
+void get_str_attr(xmlNode *n, const char *attr_name, str_t *dst)
50
+{
51
+	const char *s = get_attr_value(find_attr(n->properties, attr_name));
52
+	if (!s) str_clear(dst);
53
+	else str_dup_zt(dst, s);
54
+}
55
+
56
+int xmlstrcmp(const xmlChar *xmls, const char *name)
57
+{
58
+	if (!xmls) return -1;
59
+	if (!name) return 1;
60
+	return strcmp((const char*)xmls, name);
61
+}
62
+
63
+/* xmlNode *find_node(xmlNode *parent, const char *name) */
64
+xmlNode *find_node(xmlNode *parent, const char *name, const char *nspace)
65
+{
66
+	if (!parent) return NULL;
67
+	xmlNode *n = parent->children;
68
+	while (n) {
69
+		if (cmp_node(n, name, nspace) >= 0) break;
70
+		n = n->next;
71
+	}
72
+	return n;
73
+}
74
+
75
+const char *find_value(xmlNode *first_child)
76
+{
77
+	const char *s = NULL;
78
+	
79
+	xmlNode *c = first_child;
80
+	while (c) {
81
+		if (c->type == XML_TEXT_NODE) {
82
+			if (c->content) s = (const char *)c->content;
83
+			break;
84
+		}
85
+		c = c->next;
86
+	}
87
+	
88
+	return s;
89
+}
90
+
91
+const char *get_node_value(xmlNode *n)
92
+{
93
+	if (!n) return NULL;
94
+	return find_value(n->children);
95
+}
96
+
97
+xmlAttr *find_attr(xmlAttr *first, const char *name)
98
+{
99
+	xmlAttr *a = first;
100
+	while (a) {
101
+		if (xmlstrcmp(a->name, name) == 0) break;
102
+		a = a->next;
103
+	}
104
+	return a;
105
+}
106
+
107
+const char *get_attr_value(xmlAttr *a) 
108
+{
109
+	if (!a) return NULL;
110
+	return find_value(a->children);
111
+}
112
+
113
+int cmp_node(xmlNode *node, const char *name, const char *nspace)
114
+{
115
+	if (!node) return -1;
116
+	if (node->type != XML_ELEMENT_NODE) return -1;
117
+	
118
+	if (xmlstrcmp(node->name, name) != 0) return -1;
119
+	if (!nspace) return 0;
120
+	if (!node->ns) {
121
+		/* DEBUG_LOG("nemam NS!!!!!!!\n"); */
122
+		return 1;
123
+	}
124
+	if (xmlstrcmp(node->ns->href, nspace) == 0) return 0;
125
+	return -1;
126
+}
127
+
128
+time_t xmltime2time(const char *xt)
129
+{
130
+	/* TODO: translate XML time in input parametr to time_t structure */
131
+	ERROR_LOG("can't translate xmltime to time_t: not finished yet!\n");
132
+	return 0;
133
+}
134
+
0 135
new file mode 100644
... ...
@@ -0,0 +1,52 @@
1
+/* 
2
+ * Copyright (C) 2005 iptelorg GmbH
3
+ *
4
+ * This file is part of ser, a free SIP server.
5
+ *
6
+ * ser is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version
10
+ *
11
+ * For a license to use the ser software under conditions
12
+ * other than those described here, or to purchase support for this
13
+ * software, please contact iptel.org by e-mail at the following addresses:
14
+ *    info@iptel.org
15
+ *
16
+ * ser is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with this program; if not, write to the Free Software
23
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
+ */
25
+
26
+#include <libxml/parser.h>
27
+#include <libxml/tree.h>
28
+
29
+#include <cds/sstr.h>
30
+
31
+int xmlstrcmp(const xmlChar *xmls, const char *name);
32
+xmlAttr *find_attr(xmlAttr *first, const char *name);
33
+const char *find_value(xmlNode *first_child);
34
+const char *get_node_value(xmlNode *n);
35
+xmlNode *find_node(xmlNode *parent, const char *name, const char *nspace);
36
+const char *get_attr_value(xmlAttr *a);
37
+int cmp_node(xmlNode *node, const char *name, const char *nspace);
38
+void get_int_attr(xmlNode *n, const char *attr_name, int *dst);
39
+void get_str_attr(xmlNode *n, const char *attr_name, str_t *dst);
40
+
41
+time_t xmltime2time(const char *xt);
42
+
43
+#define SEQUENCE(type)	type*
44
+#define SEQUENCE_ABLE(type)	type *__next;
45
+#define SEQUENCE_ADD(first,last,e) do { \
46
+	if (last) last->__next = e; \
47
+	else first = e; \
48
+	last = e; } while(0);
49
+#define SEQUENCE_FIRST(first) first
50
+#define SEQUENCE_NEXT(e) (e)->__next
51
+
52
+extern int xml_parser_flags;
... ...
@@ -2,7 +2,7 @@ LIBNAME  = xcap
2 2
 OUT_NAME = libxcap.so
3 3
 OUT_TYPE = lib
4 4
 INCLUDES += -I/usr/include/libxml2
5
-LIBS     += -lxml2 -lcurl
5
+LIBS     += -lxml2 -lcurl -lcds
6 6
 
7 7
 include ../Makefile.ser.defs
8 8
 
... ...
@@ -577,8 +577,8 @@ int get_rls(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params,
577 577
 	if (data) cds_free(data);
578 578
 	
579 579
 	if (!service) {
580
-		ERROR_LOG("Empty service!\n");
581
-		return RES_INTERNAL_ERR;
580
+		DEBUG_LOG("Empty service!\n");
581
+		return RES_XCAP_QUERY_ERR;
582 582
 	}
583 583
 
584 584
 	/* verify the package */
... ...
@@ -652,8 +652,8 @@ int get_rls_from_full_doc(const char *xcap_root, const str_t *uri, xcap_query_t
652 652
 	
653 653
 	if (!service) {
654 654
 		if (rls) free_rls_services(rls);
655
-		ERROR_LOG("Empty service!\n");
656
-		return RES_INTERNAL_ERR;
655
+		DEBUG_LOG("Empty service!\n");
656
+		return RES_XCAP_QUERY_ERR;
657 657
 	}
658 658
 
659 659
 	/* verify the package */