Browse Source

added simple handling of <person> elements (RPID)

Vaclav Kubart 19 years ago
parent
commit
de0394c424

+ 60 - 0
db/schema/presentity_persons.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//iptel.org//DTD DBSchema V1.0//EN"
+  "http://iptel.org/dbschema/dtd/1.0/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table role="presence"
+    xmlns:db="http://docbook.org/ns/docbook"
+    xmlns:my="http://iptel.org/dbschema/mysql"
+    xmlns:pg="http://iptel.org/dbschema/postgres"
+    xmlns:dt="http://iptel.org/dbschema/dbtext">
+    <name>presentity_persons</name>
+    <version>1</version>
+    
+    <column id="prespersons.dbid">
+		<name>dbid</name>
+		<type>string</type>
+		<size>64</size>
+    </column>
+	
+	<!-- foreign key (presentity) -->
+    <column>
+		<name>presid</name>
+		<type>unsigned int</type>
+		<size>10</size>
+    </column>
+    
+	<column>
+		<name>etag</name>
+		<type>string</type>
+		<size>64</size>
+    </column>
+    
+	<column>
+		<name>person_element</name>
+		<type>binary</type>
+    </column>
+	
+	<column>
+		<name>id</name>
+		<type>string</type>
+		<size>128</size>
+    </column>
+
+    <column>
+		<name>expires</name>
+		<type>datetime</type>
+		<default>2005-12-07 08:13:15</default>
+    </column>
+
+    <index>
+		<name>prespersons_idx1</name>
+		<colref linkend="prespersons.dbid"/>
+		<unique/>
+    </index>
+    
+</table>

+ 1 - 0
db/schema/ser.xml

@@ -67,6 +67,7 @@
     <!-- Presence related tables -->
     <xi:include href="presentity.xml"/>
     <xi:include href="presentity_notes.xml"/>
+    <xi:include href="presentity_persons.xml"/>
     <xi:include href="presentity_contact.xml"/>
     <xi:include href="watcherinfo.xml"/>
     <xi:include href="tuple_notes.xml"/>

+ 93 - 4
lib/presence/pidf.c

@@ -105,6 +105,12 @@ static void doc_add_note(dstring_t *buf, presentity_info_t *p, presence_note_t *
 	dstr_append_zt(buf, "</note>\r\n");
 }
 
+static void doc_add_person(dstring_t *buf, presentity_info_t *p, person_t *ps)
+{
+	dstr_append_str(buf, &ps->person_element);
+	dstr_append_zt(buf, "\r\n");
+}
+
 static void dstr_put_pres_uri(dstring_t *buf, str_t *uri)
 {
 	char *c;
@@ -131,6 +137,7 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p, int use_cpi
 {
 	presence_tuple_info_t *t;
 	presence_note_t *n;
+	person_t *ps;
 
 	DEBUG_LOG("doc_add_presentity()\n");
 	if (use_cpim_pidf_ns)
@@ -142,7 +149,7 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p, int use_cpi
 	/* dstr_append_str(buf, &p->presentity); */ /* only for test !!! */
 	dstr_append_zt(buf, "\">\r\n");
 	
-	DEBUG_LOG("doc_add_presentity(): adding tuples\n");
+	DEBUG_LOG("adding tuples\n");
 	t = p->first_tuple;
 	if (!t) doc_add_empty_tuple(buf); /* correction for some strange clients :-) */
 	while (t) {
@@ -150,12 +157,19 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p, int use_cpi
 		t = t->next;
 	}
 	
-	DEBUG_LOG("doc_add_presentity(): adding notes\n");
+	DEBUG_LOG("adding notes\n");
 	n = p->first_note;
 	while (n) {
 		doc_add_note(buf, p, n);
 		n = n->next;
 	}
+	
+	DEBUG_LOG("adding persons\n");
+	ps = p->first_person;
+	while (ps) {
+		doc_add_person(buf, p, ps);
+		ps = ps->next;
+	}
 
 	dstr_append_zt(buf, "</presence>\r\n");
 }
@@ -202,6 +216,8 @@ int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_ty
 /* ------------------------------ PIDF document parsing ------------------------------ */
 
 static char *pidf_ns = "urn:ietf:params:xml:ns:pidf";
+/* static char *rpid_ns = "urn:ietf:params:xml:ns:pidf:rpid"; */
+static char *data_model_ns = "urn:ietf:params:xml:ns:pidf:data-model";
 
 static int read_note(xmlNode *node, presence_note_t **dst)
 {
@@ -305,7 +321,68 @@ static int read_tuple(xmlNode *tuple, presence_tuple_info_t **dst, int ignore_ns
 	return res;
 }
 
-static int read_presentity(xmlNode *root, presentity_info_t **dst, int ignore_ns)
+static int get_whole_node_content(xmlNode *n, str_t *dst, xmlDocPtr doc)
+{
+	if (n) {
+		n = xmlCopyNode(n, 1); /* this inserts namespaces into element correctly */
+		if (!n) {
+			ERROR_LOG("can't duplicate XML node\n");
+			return -1;
+		}
+	}
+	if (n) {
+		xmlBufferPtr buf;
+		buf = xmlBufferCreate();
+		if (buf == NULL) {
+			ERROR_LOG("Error creating the xml buffer\n");
+			return -1;
+		}
+		xmlNodeDump(buf, doc, n, 0, 0);
+		if (buf->use > 0) {
+			str_t s;
+			s.s = (char *)buf->content;
+			s.len = buf->use;
+			str_dup(dst, &s);
+		}
+		xmlBufferFree(buf);
+		xmlFreeNode(n); /* was duplicated due to namespaces! */
+	}
+	return 0;
+}
+
+static int read_person(xmlNode *person, person_t **dst, xmlDocPtr doc)
+{
+	person_t *p;
+	/* xmlNode *n; */
+
+	if (!dst) return -1;
+	*dst = NULL;
+	
+	p = (person_t*)cds_malloc(sizeof(person_t));
+	if (!p) return -1;
+	
+	memset(p, 0, sizeof(*p));
+	*dst = p;
+
+	TRACE_LOG("reading person ()\n");
+	
+	str_dup_zt(&p->id, get_attr_value(find_attr(person->properties, "id")));
+	
+	/* try to find mood */
+/*	n = find_node(person, "mood", rpid_ns);
+	if (n) get_whole_node_content(n, &p->mood, doc);
+*/	
+	/* try to find activities */
+/*	n = find_node(person, "activities", rpid_ns);
+	if (n) get_whole_node_content(n, &p->activities, doc);
+*/
+	/* do not care about internals of person - take whole element ! */
+	get_whole_node_content(person, &p->person_element, doc);
+	
+	return 0;
+}
+
+static int read_presentity(xmlNode *root, presentity_info_t **dst, int ignore_ns, xmlDocPtr doc)
 {
 	xmlNode *n;
 	str_t entity;
@@ -313,6 +390,7 @@ static int read_presentity(xmlNode *root, presentity_info_t **dst, int ignore_ns
 	presence_note_t *note;
 	int res = 0;
 	char *ns = ignore_ns ? NULL: pidf_ns;
+	person_t *p, *lastp;
 	
 	DEBUG_LOG("read_presentity(ns=%s)\n", ns ? ns : "");
 	if (cmp_node(root, "presence", ns) < 0) {
@@ -324,6 +402,7 @@ static int read_presentity(xmlNode *root, presentity_info_t **dst, int ignore_ns
 	*dst = create_presentity_info(&entity);
 	if (!(*dst)) return -1; /* memory */
 
+	lastp = NULL;
 	n = root->children;
 	while (n) {
 		if (n->type == XML_ELEMENT_NODE) {
@@ -340,6 +419,16 @@ static int read_presentity(xmlNode *root, presentity_info_t **dst, int ignore_ns
 				}
 				else break;
 			}
+			
+			/* RPID extensions */
+			if (cmp_node(n, "person", data_model_ns) >= 0) {
+				p = NULL;
+				res = read_person(n, &p, doc);
+				if ((res == 0) && p) 
+					LINKED_LIST_ADD((*dst)->first_person, lastp, p);
+				/*if (res != 0) break; ignore errors there */
+			}
+			
 		}
 		n = n->next;
 	}
@@ -363,7 +452,7 @@ int parse_pidf_document_ex(presentity_info_t **dst, const char *data, int data_l
 		return -1;
 	}
 	
-	res = read_presentity(xmlDocGetRootElement(doc), dst, ignore_ns);
+	res = read_presentity(xmlDocGetRootElement(doc), dst, ignore_ns, doc);
 	if (res != 0) {
 		/* may be set => must be freed */
 		if (*dst) free_presentity_info(*dst);

+ 37 - 0
lib/presence/pres_doc.c

@@ -52,6 +52,9 @@ presentity_info_t *create_presentity_info(const str_t *presentity)
 	p->first_note = NULL;
 	p->last_note = NULL;
 	p->auth = presence_auth_unresolved;
+
+	/* RPID extensions */
+	p->first_person = NULL;
 	
 	return p;
 }
@@ -111,10 +114,22 @@ void free_tuple_info(presence_tuple_info_t *t)
 	cds_free(t);
 }
 
+void free_person(person_t *p)
+{
+	if (p) {
+		str_free_content(&p->person_element);
+		str_free_content(&p->id);
+		/* str_free_content(&p->mood);
+		str_free_content(&p->activities); */
+	}
+	cds_free(p);
+}
+
 void free_presentity_info(presentity_info_t *p)
 {
 	presence_tuple_info_t *t, *tt;
 	presence_note_t *n, *nn;
+	person_t *np, *ps;
 	
 	if (!p) return;
 	t = p->first_tuple;
@@ -131,6 +146,13 @@ void free_presentity_info(presentity_info_t *p)
 		n = nn;
 	}
 	
+	ps = p->first_person;
+	while (ps) {
+		np = ps->next;
+		free_person(ps);
+		ps = np;
+	}
+	
 	cds_free(p);
 }
 
@@ -197,3 +219,18 @@ presence_note_t *create_presence_note_zt(const char *note, const char *lang)
 	
 	return create_presence_note(&note_s, &lang_s);
 }
+
+person_t *create_person(const str_t *element, const str_t *id)
+{
+	person_t *t;
+	t = (person_t*)cds_malloc(sizeof(*t));
+	if (!t) {
+		ERROR_LOG("can't allocate memory for person\n");
+		return t;
+	}
+	/* str_clear(&t->contact.s); */
+	str_dup(&t->person_element, element);
+	str_dup(&t->id, id);
+	t->next = NULL;
+	return t;
+}

+ 18 - 0
lib/presence/pres_doc.h

@@ -59,11 +59,27 @@ typedef struct _presence_tuple_info_t {
 	presence_note_t *first_note, *last_note;/* published notes */
 } presence_tuple_info_t;
 
+/* additional data taken from RPID specification */
+typedef struct _person_t {
+	str_t id;
+
+	/* mood has absolutely no value for our processing - 
+	 * we hold there the content of <mood> element */
+/*	str_t mood;*/
+	
+	/* other such element */
+/*	str_t activities;*/
+	str_t person_element;
+
+	struct _person_t *next; /* there can be more person elements in PIDF */
+} person_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 */
+	person_t *first_person;
 		
 	char presentity_data[1];
 } presentity_info_t;
@@ -95,4 +111,6 @@ 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);
 
+person_t *create_person(const str_t *element, const str_t *id);
+
 #endif

+ 1 - 0
scripts/dbtext/ser_db/presentity_persons

@@ -0,0 +1 @@
+dbid(str) presid(int) etag(str) person_element(str) id(str) expires(int) 

+ 10 - 0
scripts/mysql/my_create.sql

@@ -335,6 +335,16 @@ CREATE TABLE presentity_notes (
     UNIQUE KEY pnotes_idx1 (dbid)
 );
 
+CREATE TABLE presentity_persons (
+    dbid VARCHAR(64) NOT NULL,
+    presid INT(10) UNSIGNED NOT NULL,
+    etag VARCHAR(64) NOT NULL,
+    person_element BLOB NOT NULL,
+    id VARCHAR(128) NOT NULL,
+    expires DATETIME NOT NULL DEFAULT '2005-12-07 08:13:15',
+    UNIQUE KEY prespersons_idx1 (dbid)
+);
+
 CREATE TABLE presentity_contact (
     contactid INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
     presid INT(10) UNSIGNED NOT NULL,

+ 10 - 0
scripts/oracle/or_create.sql

@@ -322,6 +322,16 @@ CREATE TABLE presentity_notes (
     pnotes_idx1 UNIQUE (dbid, )
 );
 
+CREATE TABLE presentity_persons (
+    dbid string(64) NOT NULL,
+    presid int(10) NOT NULL,
+    etag string(64) NOT NULL,
+    person_element binary NOT NULL,
+    id string(128) NOT NULL,
+    expires datetime NOT NULL DEFAULT '2005-12-07 08:13:15',
+    prespersons_idx1 UNIQUE (dbid, )
+);
+
 CREATE TABLE presentity_contact (
     contactid int(10) NOT NULL,
     presid int(10) NOT NULL,

+ 12 - 2
scripts/postgres/pg_create.sql

@@ -349,6 +349,16 @@ CREATE TABLE presentity_notes (
     CONSTRAINT pnotes_idx1 UNIQUE (dbid)
 );
 
+CREATE TABLE presentity_persons (
+    dbid VARCHAR(64) NOT NULL,
+    presid INTEGER NOT NULL,
+    etag VARCHAR(64) NOT NULL,
+    person_element BYTEA NOT NULL,
+    id VARCHAR(128) NOT NULL,
+    expires TIMESTAMP NOT NULL DEFAULT '2005-12-07 08:13:15',
+    CONSTRAINT prespersons_idx1 UNIQUE (dbid)
+);
+
 CREATE TABLE presentity_contact (
     contactid SERIAL NOT NULL,
     presid INTEGER NOT NULL,
@@ -563,5 +573,5 @@ CREATE TABLE customers (
 );
 
 
-GRANT ALL ON version,acc,missed_calls,credentials,attr_types,global_attrs,domain_attrs,user_attrs,domain,location,trusted,server_monitoring,server_monitoring_agg,phonebook,gw,gw_grp,lcr,grp,silo,uri,speed_dial,sd_attrs,presentity,presentity_notes,presentity_contact,watcherinfo,tuple_notes,offline_winfo,rls_subscription,rls_vs,rls_vs_names,i18n,pdt,customers TO ser;
-GRANT SELECT ON version,acc,missed_calls,credentials,attr_types,global_attrs,domain_attrs,user_attrs,domain,location,trusted,server_monitoring,server_monitoring_agg,phonebook,gw,gw_grp,lcr,grp,silo,uri,speed_dial,sd_attrs,presentity,presentity_notes,presentity_contact,watcherinfo,tuple_notes,offline_winfo,rls_subscription,rls_vs,rls_vs_names,i18n,pdt,customers TO serro;
+GRANT ALL ON version,acc,missed_calls,credentials,attr_types,global_attrs,domain_attrs,user_attrs,domain,location,trusted,server_monitoring,server_monitoring_agg,phonebook,gw,gw_grp,lcr,grp,silo,uri,speed_dial,sd_attrs,presentity,presentity_notes,presentity_persons,presentity_contact,watcherinfo,tuple_notes,offline_winfo,rls_subscription,rls_vs,rls_vs_names,i18n,pdt,customers TO ser;
+GRANT SELECT ON version,acc,missed_calls,credentials,attr_types,global_attrs,domain_attrs,user_attrs,domain,location,trusted,server_monitoring,server_monitoring_agg,phonebook,gw,gw_grp,lcr,grp,silo,uri,speed_dial,sd_attrs,presentity,presentity_notes,presentity_persons,presentity_contact,watcherinfo,tuple_notes,offline_winfo,rls_subscription,rls_vs,rls_vs_names,i18n,pdt,customers TO serro;