Kaynağa Gözat

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

Vaclav Kubart 20 yıl önce
ebeveyn
işleme
17d8cc2bec

+ 12 - 0
db/schema/presentity_contact.xml

@@ -87,6 +87,18 @@
 	<size>10</size>
     </column>
 
+    <column>
+		<name>etag</name>
+		<type>string</type>
+		<size>64</size>
+    </column>
+    
+	<column>
+		<name>published_id</name>
+		<type>string</type>
+		<size>64</size>
+    </column>
+	
     <index>
 	<name>pc_idx1</name>
 	<colref linkend="prescontact.contactid"/>

+ 2 - 1
lib/Makefile.ser

@@ -1,3 +1,5 @@
+include ../Makefile.defs
+
 # variables to change
 
 CFLAGS   += -g -Wall
@@ -10,7 +12,6 @@ LIBS     += -L$(CURDIR)/cds -L$(CURDIR)/qsa
 ####################################
 # make rules
 
-include ../Makefile.defs
 
 # exports needed by libraries (this exports here allow to run make
 # in libraries independently on make in main ser directory)

+ 1 - 1
lib/Makefile.ser.defs

@@ -20,7 +20,7 @@ endif
 
 ifeq ($(OUT_TYPE),lib)
 $(OUT_NAME):	$(OBJS)
-		$(CC) -shared $(DEFS) $(CFLAGS) $(INCLUDES) -o $@ $(OBJS) $(LIBS)
+		$(CC) -shared $(DEFS) $(CFLAGS) $(INCLUDES) $(LIBS) -o $@ $(OBJS)
 
 install:	$(OUT_NAME) $(LIBDIR)
 			$(INSTALL-TOUCH) $(LIBDIR)/$(OUT_NAME)

+ 1 - 1
lib/cds/logger.h

@@ -43,7 +43,7 @@
 
 #define ERROR_LOG(a,args...)		LOG(L_ERR,a,##args)
 #define DEBUG_LOG(a,args...)		LOG(L_DBG,a,##args)
-#define TRACE_LOG(a,args...)		LOG(L_ERR,a,##args)
+#define TRACE_LOG(a,args...)		LOG(L_INFO,a,##args)
 #define WARN_LOG(a,args...)			LOG(L_WARN,a,##args)
 #define FLUSH_LOG()					do{}while(0)
 

+ 1 - 1
lib/cds/ref_cntr.c

@@ -26,7 +26,7 @@ void reference_counter_cleanup()
 {
 	if (ref_cntr_mutex) {
 		cds_mutex_destroy(ref_cntr_mutex);
-		cds_free(ref_cntr_mutex);
+		cds_free((void*)ref_cntr_mutex);
 		ref_cntr_mutex = NULL;
 	}
 }

+ 2 - 2
lib/presence/Makefile

@@ -1,6 +1,6 @@
 DEFS     += 
-INCLUDES +=
-LIBS     += -lcds
+INCLUDES += -I/usr/include/libxml2 -I/usr/local/include/libxml2 -I/usr/local/include
+LIBS     += -L/usr/local/lib -lxml2 -lcds
 
 # name of result executable or library
 NAME = presence

+ 3 - 0
lib/presence/Makefile.ser

@@ -2,5 +2,8 @@ LIBNAME  = presence
 OUT_NAME = libpresence.so
 OUT_TYPE = lib
 
+INCLUDES += -I/usr/include/libxml2
+LIBS     += -lxml2 -lcds
+
 include ../Makefile.ser.defs
 

+ 206 - 4
lib/presence/pidf.c

@@ -27,40 +27,73 @@
 #include <cds/dstring.h>
 #include <cds/memory.h>
 #include <cds/logger.h>
+#include <cds/list.h>
+#include <presence/xml_utils.h>
+#include <string.h>
+
+/* ------------------------------ PIDF document creation ------------------------------ */
 
 static void doc_add_tuple(dstring_t *buf, presentity_info_t *p, presence_tuple_info_t *t)
 {
+	char tmp[32];
 	DEBUG_LOG("doc_add_tuple()\n");
 	
 	dstr_append_zt(buf, "\t<tuple id=\"");
-	dstr_append_str(buf, &t->contact);
+	dstr_append_str(buf, &t->id);
 	dstr_append_zt(buf, "\">\r\n");
 	
 	if (t->status == presence_tuple_open) dstr_append_zt(buf, "\t\t<status><basic>open</basic></status>\r\n");
 	else dstr_append_zt(buf, "\t\t<status><basic>closed</basic></status>\r\n");
 	
-	dstr_append_zt(buf, "\t\t<contact>");
+	dstr_append_zt(buf, "\t\t<contact priority=\"");
+	sprintf(tmp, "%1.2f", t->priority);
+	dstr_append_zt(buf, tmp);
+	dstr_append_zt(buf, "\">");
 	dstr_append_str(buf, &t->contact);
 	dstr_append_zt(buf, "</contact>\r\n");
 
 	dstr_append_zt(buf, "\t</tuple>\r\n");
 }
 
+static void doc_add_note(dstring_t *buf, presentity_info_t *p, presence_note_t *n)
+{
+	DEBUG_LOG("doc_add_tuple()\n");
+	
+	dstr_append_zt(buf, "\t<note");
+	if (n->lang.len > 0) {
+		dstr_append_zt(buf, " lang=\"");
+		dstr_append_str(buf, &n->lang);
+		dstr_append_zt(buf, "\"");
+	}
+	dstr_append_zt(buf, ">");
+	dstr_append_str(buf, &n->value);	
+	dstr_append_zt(buf, "</note>\r\n");
+}
+
 static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
 {
 	presence_tuple_info_t *t;
+	presence_note_t *n;
 
-	DEBUG_LOG("doc_add_presentity()\r\n");
+	DEBUG_LOG("doc_add_presentity()\n");
 	dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"");
 	dstr_append_str(buf, &p->presentity);
 	dstr_append_zt(buf, "\">\r\n");
 	
-	DEBUG_LOG("doc_add_presentity(): adding tuples\r\n");
+	DEBUG_LOG("doc_add_presentity(): adding tuples\n");
 	t = p->first_tuple;
 	while (t) {
 		doc_add_tuple(buf, p, t);
 		t = t->next;
 	}
+	
+	DEBUG_LOG("doc_add_presentity(): adding notes\n");
+	n = p->first_note;
+	while (n) {
+		doc_add_note(buf, p, n);
+		n = n->next;
+	}
+
 	dstr_append_zt(buf, "</presence>");
 }
 
@@ -95,3 +128,172 @@ int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_ty
 	return 0;
 }
 
+/* ------------------------------ PIDF document parsing ------------------------------ */
+
+static char *pidf_ns = "urn:ietf:params:xml:ns:pidf";
+
+static int read_note(xmlNode *node, presence_note_t **dst)
+{
+	const char *note = NULL;
+	const char *lang = NULL;
+
+	note = get_node_value(node);
+	lang = get_attr_value(find_attr(node->properties, "lang"));
+
+	*dst = create_presence_note_zt(note, lang);
+	if (!dst) return -1;
+	
+	return 0;
+}
+
+
+static int read_tuple(xmlNode *tuple, presence_tuple_info_t **dst)
+{
+	str_t contact, id;
+	presence_tuple_status_t status;
+	xmlNode *n;
+	double priority = 0;
+	const char *s;
+	int res = 0;
+	presence_note_t *note;
+
+	*dst = NULL;
+
+	DEBUG_LOG("read_tuple()\n");
+	/* process contact (only one node) */
+	n = find_node(tuple, "contact", pidf_ns);
+	if (!n) {
+		ERROR_LOG("contact not found\n");
+		return -1;
+	}
+	s = get_attr_value(find_attr(n->properties, "priority"));
+	if (s) priority = atof(s);
+	s = get_node_value(n);
+	contact.s = (char *)s;
+	if (s) contact.len = strlen(s);
+	else contact.len = 0;
+	if (contact.len < 1) {
+		ERROR_LOG("empty contact\n");
+		return -1;
+	}	
+	
+	/* process status (only one node) */
+	n = find_node(tuple, "status", pidf_ns);
+	if (!n) {
+		ERROR_LOG("status not found\n");
+		return -1;
+	}
+	n = find_node(n, "basic", pidf_ns);
+	if (!n) {
+		ERROR_LOG("basic status not found\n");
+		return -1;
+	}
+	s = get_node_value(n);
+	if (!s) {
+		ERROR_LOG("basic status without value\n");
+		return -1;
+	}
+
+	/* translate status */
+	status = presence_tuple_closed; /* default value */
+	if (strcmp(s, "open") == 0) status = presence_tuple_open;
+	if (strcmp(s, "closed") == 0) status = presence_tuple_closed;
+	/* FIXME: handle not standardized variants too (add note to basic status) */
+	
+	/* get ID from tuple node attribute? */
+	id.s = (char *)get_attr_value(find_attr(tuple->properties, "id"));
+	if (id.s) id.len = strlen(id.s);
+	else id.len = 0;
+	
+	*dst = create_tuple_info(&contact, &id, status);
+	if (!(*dst)) return -1;
+
+	(*dst)->priority = priority;
+
+	/* handle notes */
+	n = tuple->children;
+	while (n) {
+		if (n->type == XML_ELEMENT_NODE) {
+			if (cmp_node(n, "note", pidf_ns) >= 0) {
+				res = read_note(n, &note);
+				if ((res == 0) && note) {
+					DOUBLE_LINKED_LIST_ADD((*dst)->first_note, 
+							(*dst)->last_note, note);
+				}
+				else break;
+			}
+		}
+		n = n->next;
+	}
+
+	return res;
+}
+
+static int read_presentity(xmlNode *root, presentity_info_t **dst)
+{
+	xmlNode *n;
+	str_t entity;
+	presence_tuple_info_t *t;
+	presence_note_t *note;
+	int res = 0;
+	
+	DEBUG_LOG("read_presentity()\n");
+	if (cmp_node(root, "presence", pidf_ns) < 0) {
+		ERROR_LOG("document is not presence \n");
+		return -1;
+	}
+
+	entity = zt2str((char*)get_attr_value(find_attr(root->properties, "entity")));
+	*dst = create_presentity_info(&entity);
+	if (!(*dst)) return -1; /* memory */
+
+	n = root->children;
+	while (n) {
+		if (n->type == XML_ELEMENT_NODE) {
+			if (cmp_node(n, "tuple", pidf_ns) >= 0) {
+				res = read_tuple(n, &t);
+				if ((res == 0) && t) add_tuple_info(*dst, t);
+				else break;
+			}
+			if (cmp_node(n, "note", pidf_ns) >= 0) {
+				res = read_note(n, &note);
+				if ((res == 0) && note) {
+					DOUBLE_LINKED_LIST_ADD((*dst)->first_note, 
+							(*dst)->last_note, note);
+				}
+				else break;
+			}
+		}
+		n = n->next;
+	}
+
+	return res;
+}
+
+/* libxml2 must be initialized before calling this function ! */
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len)
+{
+	int res = 0;
+	xmlDocPtr doc;
+	
+	if (!dst) return -1;
+	if ((!data) || (data_len < 1)) return -2;
+
+	*dst = NULL;
+	doc = xmlReadMemory(data, data_len, NULL, NULL, xml_parser_flags);
+	if (doc == NULL) {
+		ERROR_LOG("can't parse document\n");
+		return -1;
+	}
+	
+	res = read_presentity(xmlDocGetRootElement(doc), dst);
+	if (res != 0) {
+		/* may be set => must be freed */
+		if (*dst) free_presentity_info(*dst);
+		*dst = NULL;
+	}
+
+	xmlFreeDoc(doc);
+	return res;
+}
+

+ 1 - 0
lib/presence/pidf.h

@@ -30,5 +30,6 @@
 #include <presence/pres_doc.h>
 
 int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type);
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len);
 
 #endif

+ 66 - 3
lib/presence/pres_doc.c

@@ -49,11 +49,14 @@ presentity_info_t *create_presentity_info(const str_t *presentity)
 	else p->presentity.s = NULL;
 	p->first_tuple = NULL;
 	p->last_tuple = NULL;
+	p->first_note = NULL;
+	p->last_note = NULL;
+	p->auth = presence_auth_unresolved;
 	
 	return p;
 }
 
-presence_tuple_info_t *create_tuple_info(const str_t *contact, presence_tuple_status_t status)
+presence_tuple_info_t *create_tuple_info(const str_t *contact, const str_t *id, presence_tuple_status_t status)
 {
 	presence_tuple_info_t *t;
 	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
 	}
 	/* str_clear(&t->contact.s); */
 	str_dup(&t->contact, contact);
+	str_dup(&t->id, id);
 	str_clear(&t->extra_status);
 	t->prev = NULL;
 	t->next = NULL;
 	t->status = status;
 	t->priority = 0.0;
 	t->expires = 0;
+	t->first_note = NULL;
+	t->last_note = NULL;
 	return t;
 }
 
@@ -77,24 +83,54 @@ void add_tuple_info(presentity_info_t *p, presence_tuple_info_t *t)
 	DOUBLE_LINKED_LIST_ADD(p->first_tuple, p->last_tuple, t);
 }
 
+void free_presence_note(presence_note_t *n)
+{
+	if (n) {
+		str_free_content(&n->value);
+		str_free_content(&n->lang);
+		cds_free(n);
+	}
+}
+
 void free_tuple_info(presence_tuple_info_t *t)
 {
+	presence_note_t *n, *nn;
+	
 	if (!t) return;
 	str_free_content(&t->contact);
+	str_free_content(&t->id);
 	str_free_content(&t->extra_status);
+	
+	n = t->first_note;
+	while (n) {
+		nn = n->next;
+		free_presence_note(n);
+		n = nn;
+	}
+	
 	cds_free(t);
 }
 
 void free_presentity_info(presentity_info_t *p)
 {
-	presence_tuple_info_t *t;
+	presence_tuple_info_t *t, *tt;
+	presence_note_t *n, *nn;
 	
 	if (!p) return;
 	t = p->first_tuple;
 	while (t) {
+		tt = t->next;
 		free_tuple_info(t);
-		t = t->next;
+		t = tt;
+	}
+	
+	n = p->first_note;
+	while (n) {
+		nn = n->next;
+		free_presence_note(n);
+		n = nn;
 	}
+	
 	cds_free(p);
 }
 
@@ -134,3 +170,30 @@ void free_list_presence_info(list_presence_info_t *p)
 		cds_free(p);
 	}
 }
+
+presence_note_t *create_presence_note(const str_t *note, const str_t *lang)
+{
+	presence_note_t *t;
+	t = (presence_note_t*)cds_malloc(sizeof(*t));
+	if (!t) {
+		ERROR_LOG("can't allocate memory for presence note\n");
+		return t;
+	}
+	/* str_clear(&t->contact.s); */
+	str_dup(&t->value, note);
+	str_dup(&t->lang, lang);
+	t->prev = NULL;
+	t->next = NULL;
+	return t;
+}
+
+presence_note_t *create_presence_note_zt(const char *note, const char *lang)
+{
+	str_t note_s;
+	str_t lang_s;
+
+	note_s = zt2str((char*)note);
+	lang_s = zt2str((char*)lang);
+	
+	return create_presence_note(&note_s, &lang_s);
+}

+ 17 - 3
lib/presence/pres_doc.h

@@ -30,6 +30,12 @@
 #include <cds/ptr_vector.h>
 #include <time.h>
 
+typedef struct _presence_note_t {
+	str_t value;
+	str_t lang;
+	struct _presence_note_t *prev, *next;
+} presence_note_t;
+
 typedef enum {
 	presence_tuple_open,
 	presence_tuple_closed
@@ -42,19 +48,23 @@ typedef enum {
 	presence_auth_granted
 } presence_authorization_status_t;
 
-typedef struct _presence_typle_info_t {
+typedef struct _presence_tuple_info_t {
 	str_t contact;
+	str_t id;
 	double priority;
 	time_t expires;
 	presence_tuple_status_t status;
 	str_t extra_status;
-	struct _presence_typle_info_t *next, *prev;
+	struct _presence_tuple_info_t *next, *prev;
+	presence_note_t *first_note, *last_note;/* published notes */
 } presence_tuple_info_t;
 
 typedef struct {
 	str_t presentity; /* do not modify this !*/
 	presence_tuple_info_t *first_tuple, *last_tuple;
 	presence_authorization_status_t auth;
+	presence_note_t *first_note, *last_note;/* published notes */
+		
 	char presentity_data[1];
 } presentity_info_t;
 
@@ -74,11 +84,15 @@ typedef struct {
 } list_presence_info_t;
 
 presentity_info_t *create_presentity_info(const str_t *presentity);
-presence_tuple_info_t *create_tuple_info(const str_t *contact, presence_tuple_status_t status);
+presence_tuple_info_t *create_tuple_info(const str_t *contact, const str_t *id, presence_tuple_status_t status);
 void add_tuple_info(presentity_info_t *p, presence_tuple_info_t *t);
 void free_presentity_info(presentity_info_t *p);
 
 list_presence_info_t *create_list_presence_info(const str_t *uri);
 void free_list_presence_info(list_presence_info_t *p);
 
+presence_note_t *create_presence_note(const str_t *note, const str_t *lang);
+presence_note_t *create_presence_note_zt(const char *note, const char *lang);
+void free_presence_note(presence_note_t *n);
+
 #endif

+ 134 - 0
lib/presence/xml_utils.c

@@ -0,0 +1,134 @@
+/* 
+ * Copyright (C) 2005 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <cds/logger.h>
+#include <xcap/xml_utils.h>
+
+int xml_parser_flags = XML_PARSE_NOERROR | XML_PARSE_NOWARNING;
+
+static void str2int(const char *s, int *dst)
+{
+	/* if not null sets the given integer to value */
+	if (!s) return;
+	else *dst = atoi(s);
+}
+
+void get_int_attr(xmlNode *n, const char *attr_name, int *dst)
+{
+	str2int(get_attr_value(find_attr(n->properties, attr_name)), dst);
+}
+
+void get_str_attr(xmlNode *n, const char *attr_name, str_t *dst)
+{
+	const char *s = get_attr_value(find_attr(n->properties, attr_name));
+	if (!s) str_clear(dst);
+	else str_dup_zt(dst, s);
+}
+
+int xmlstrcmp(const xmlChar *xmls, const char *name)
+{
+	if (!xmls) return -1;
+	if (!name) return 1;
+	return strcmp((const char*)xmls, name);
+}
+
+/* xmlNode *find_node(xmlNode *parent, const char *name) */
+xmlNode *find_node(xmlNode *parent, const char *name, const char *nspace)
+{
+	if (!parent) return NULL;
+	xmlNode *n = parent->children;
+	while (n) {
+		if (cmp_node(n, name, nspace) >= 0) break;
+		n = n->next;
+	}
+	return n;
+}
+
+const char *find_value(xmlNode *first_child)
+{
+	const char *s = NULL;
+	
+	xmlNode *c = first_child;
+	while (c) {
+		if (c->type == XML_TEXT_NODE) {
+			if (c->content) s = (const char *)c->content;
+			break;
+		}
+		c = c->next;
+	}
+	
+	return s;
+}
+
+const char *get_node_value(xmlNode *n)
+{
+	if (!n) return NULL;
+	return find_value(n->children);
+}
+
+xmlAttr *find_attr(xmlAttr *first, const char *name)
+{
+	xmlAttr *a = first;
+	while (a) {
+		if (xmlstrcmp(a->name, name) == 0) break;
+		a = a->next;
+	}
+	return a;
+}
+
+const char *get_attr_value(xmlAttr *a) 
+{
+	if (!a) return NULL;
+	return find_value(a->children);
+}
+
+int cmp_node(xmlNode *node, const char *name, const char *nspace)
+{
+	if (!node) return -1;
+	if (node->type != XML_ELEMENT_NODE) return -1;
+	
+	if (xmlstrcmp(node->name, name) != 0) return -1;
+	if (!nspace) return 0;
+	if (!node->ns) {
+		/* DEBUG_LOG("nemam NS!!!!!!!\n"); */
+		return 1;
+	}
+	if (xmlstrcmp(node->ns->href, nspace) == 0) return 0;
+	return -1;
+}
+
+time_t xmltime2time(const char *xt)
+{
+	/* TODO: translate XML time in input parametr to time_t structure */
+	ERROR_LOG("can't translate xmltime to time_t: not finished yet!\n");
+	return 0;
+}
+

+ 52 - 0
lib/presence/xml_utils.h

@@ -0,0 +1,52 @@
+/* 
+ * Copyright (C) 2005 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <cds/sstr.h>
+
+int xmlstrcmp(const xmlChar *xmls, const char *name);
+xmlAttr *find_attr(xmlAttr *first, const char *name);
+const char *find_value(xmlNode *first_child);
+const char *get_node_value(xmlNode *n);
+xmlNode *find_node(xmlNode *parent, const char *name, const char *nspace);
+const char *get_attr_value(xmlAttr *a);
+int cmp_node(xmlNode *node, const char *name, const char *nspace);
+void get_int_attr(xmlNode *n, const char *attr_name, int *dst);
+void get_str_attr(xmlNode *n, const char *attr_name, str_t *dst);
+
+time_t xmltime2time(const char *xt);
+
+#define SEQUENCE(type)	type*
+#define SEQUENCE_ABLE(type)	type *__next;
+#define SEQUENCE_ADD(first,last,e) do { \
+	if (last) last->__next = e; \
+	else first = e; \
+	last = e; } while(0);
+#define SEQUENCE_FIRST(first) first
+#define SEQUENCE_NEXT(e) (e)->__next
+
+extern int xml_parser_flags;

+ 1 - 1
lib/xcap/Makefile.ser

@@ -2,7 +2,7 @@ LIBNAME  = xcap
 OUT_NAME = libxcap.so
 OUT_TYPE = lib
 INCLUDES += -I/usr/include/libxml2
-LIBS     += -lxml2 -lcurl
+LIBS     += -lxml2 -lcurl -lcds
 
 include ../Makefile.ser.defs
 

+ 4 - 4
lib/xcap/resource_list.c

@@ -577,8 +577,8 @@ int get_rls(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params,
 	if (data) cds_free(data);
 	
 	if (!service) {
-		ERROR_LOG("Empty service!\n");
-		return RES_INTERNAL_ERR;
+		DEBUG_LOG("Empty service!\n");
+		return RES_XCAP_QUERY_ERR;
 	}
 
 	/* verify the package */
@@ -652,8 +652,8 @@ int get_rls_from_full_doc(const char *xcap_root, const str_t *uri, xcap_query_t
 	
 	if (!service) {
 		if (rls) free_rls_services(rls);
-		ERROR_LOG("Empty service!\n");
-		return RES_INTERNAL_ERR;
+		DEBUG_LOG("Empty service!\n");
+		return RES_XCAP_QUERY_ERR;
 	}
 
 	/* verify the package */