Browse Source

PA module data structures change (based on structures from common libs now),
PA code cleanup

Vaclav Kubart 19 years ago
parent
commit
701973de4c
10 changed files with 311 additions and 40 deletions
  1. 35 0
      lib/cds/dbid.c
  2. 41 0
      lib/cds/dbid.h
  3. 25 2
      lib/cds/sstr.h
  4. 1 1
      lib/presence/lpidf.c
  5. 7 3
      lib/presence/pidf.c
  6. 129 10
      lib/presence/pres_doc.c
  7. 14 7
      lib/presence/pres_doc.h
  8. 2 2
      lib/presence/xpidf.c
  9. 48 13
      lib/xcap/xcap_client.c
  10. 9 2
      lib/xcap/xcap_client.h

+ 35 - 0
lib/cds/dbid.c

@@ -0,0 +1,35 @@
+#include <cds/dbid.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+void generate_dbid_ptr(dbid_t dst, void *data_ptr)
+{
+	/* TODO: add cluster distinctive member */
+	/* FIXME: replace sprintf by something more effective */
+	snprintf(dst, sizeof(dst), "%px%xx%x", 
+			data_ptr, (int)time(NULL), rand());
+}
+
+#ifdef SER
+
+/* only for SER (not for apps with threads) */
+void generate_dbid(dbid_t dst)
+{
+	static int cntr = 0;
+	static pid_t my_pid = -1;
+	
+	if (my_pid < 0) {
+		my_pid = getpid();
+	}
+
+	/* TODO: add cluster distinctive member */
+	/* FIXME: replace sprintf by something more effective */
+	snprintf(dst, sizeof(dst), "%xy%xy%xy%x", 
+			my_pid, cntr++, (int)time(NULL), rand());
+}
+
+#endif
+

+ 41 - 0
lib/cds/dbid.h

@@ -0,0 +1,41 @@
+#ifndef __DBID_H
+#define __DBID_H
+
+/* functions and structures for generating unique database IDs */
+
+#include <string.h>
+
+#define MAX_DBID_LEN	48
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef char dbid_t[MAX_DBID_LEN];
+
+/** generates ID for data in shared memory at address given by data_ptr */
+void generate_dbid_ptr(dbid_t dst, void *data_ptr);
+
+#ifdef SER
+void generate_dbid(dbid_t dst);
+#endif
+
+/* macros for conversion to string representation of DBID
+ * (if dbid becomes structure with binary information 
+ * these should be removed and replaced by functions) */
+#define dbid_strlen(id)	strlen(id)
+#define dbid_strptr(id)	((char*)(id))
+
+#define dbid_clear(id)	do { (id)[0] = 0; } while (0)
+
+#define is_dbid_empty(id) (!(id)[0])
+
+/** Copies dbid as string into destination. The destination string
+ * data buffer MUST be allocated in needed size! */
+#define dbid_strcpy(dst,id,len) memcpy((dst)->s,id,len)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 25 - 2
lib/cds/sstr.h

@@ -59,10 +59,10 @@ str_t zt2str(char *str);
 /** returns 1 if the string is empty */
 int is_str_empty(const str_t *s);
 
-/** duplicate string into given destination */
+/** duplicate string into given destination (data region is newly allocated) */
 int str_dup(str_t* dst, const str_t* src);
 
-/** duplicate string into newly allocated destination */
+/** duplicate string into newly allocated destination (data and str structure are newly allocated) */
 str_t *str_dup_new(const str_t* src);
 
 /** duplicate zero-terminated string */
@@ -119,6 +119,29 @@ int str_concat(str_t *dst, str_t *a, str_t *b);
 
 int replace_str(const str_t *src, str_t *dst, const str_t *sample, const str_t *value);
 
+/** Copies string into another one. The destination string buffer 
+ * MUST be allocated in needed size! */
+#define str_cpy(dst, src) do { \
+	memcpy((dst)->s, (src)->s, (src)->len); \
+	(dst)->len = (src)->len; \
+	} while (0)
+
+/* pointer after given string - often used when strings
+ * allocated together with data structure holding them */
+#define after_str_ptr(ss)	((ss)->s + (ss)->len)
+
+/*
+ * Append a string app with length app_len
+ * to the end of string str which is a str* pointer
+ * the buffer must be large enough
+ */
+#define str_append(str, app, app_len)                    \
+    do {                                                 \
+        memcpy((str)->s + (str)->len, (app), (app_len)); \
+        (str)->len += (app_len);                         \
+    } while(0)
+
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
lib/presence/lpidf.c

@@ -53,7 +53,7 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
 	/* presence_note_t *n; */
 
 	dstr_append_zt(buf, "To: ");
-	dstr_append_str(buf, &p->presentity);
+	dstr_append_str(buf, &p->uri);
 	dstr_append_zt(buf, "\r\n");
 	
 	t = p->first_tuple;

+ 7 - 3
lib/presence/pidf.c

@@ -60,8 +60,12 @@ static void doc_add_tuple(dstring_t *buf, presentity_info_t *p, presence_tuple_i
 	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");
+	if (t->status != presence_tuple_undefined_status) {
+		/* do not add unknown status it is not mandatory in PIDF */
+		dstr_append_zt(buf, "\t\t<status><basic>");
+		dstr_append_str(buf, tuple_status2str(t->status));
+		dstr_append_zt(buf, "</basic></status>\r\n");
+	}
 
 	dstr_append_zt(buf, "\t\t<contact priority=\"");
 	sprintf(tmp, "%1.2f", t->priority);
@@ -145,7 +149,7 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p, int use_cpi
 	else 
 		dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"");
 	/* !!! there SHOULD be pres URI of presentity !!! */
-	dstr_put_pres_uri(buf, &p->presentity);
+	dstr_put_pres_uri(buf, &p->uri);
 	/* dstr_append_str(buf, &p->presentity); */ /* only for test !!! */
 	dstr_append_zt(buf, "\">\r\n");
 	

+ 129 - 10
lib/presence/pres_doc.c

@@ -30,28 +30,53 @@
 
 #include <string.h>
 
-presentity_info_t *create_presentity_info(const str_t *presentity)
+/* ---------------------------------------------------------------- */
+/* Helper functions */
+
+static str_t open = STR_STATIC_INIT("open");
+static str_t closed = STR_STATIC_INIT("closed");
+static str_t unknown = STR_STATIC_INIT("undefined");
+
+str_t* tuple_status2str(presence_tuple_status_t status)
+{
+	switch (status) {
+		case presence_tuple_open: return &open;
+		case presence_tuple_closed: return &closed;
+		case presence_tuple_undefined_status: return &unknown;
+	}
+	return &unknown;
+}
+
+presence_tuple_status_t str2tuple_status(const str *s)
+{
+	if (str_nocase_equals(s, &open) == 0) return presence_tuple_open;
+	if (str_nocase_equals(s, &closed) == 0) return presence_tuple_closed;
+	return presence_tuple_undefined_status;
+}
+
+/* ---------------------------------------------------------------- */
+
+presentity_info_t *create_presentity_info(const str_t *presentity_uri)
 {
 	presentity_info_t *p;
 	int len = 0;
 	
-	if (!is_str_empty(presentity)) len = presentity->len;
+	if (!is_str_empty(presentity_uri)) len = presentity_uri->len;
 	p = (presentity_info_t*)cds_malloc(sizeof(presentity_info_t) + len);
 	if (!p) {
 		ERROR_LOG("can't allocate memory for presentity info\n");
 		return p;
 	}
-	p->presentity.len = len;
+	p->uri.len = len;
 	if (len > 0) {
-		p->presentity.s = p->presentity_data;
-		memcpy(p->presentity.s, presentity->s, len);
+		p->uri.s = p->presentity_data;
+		memcpy(p->uri.s, presentity_uri->s, len);
 	}
-	else p->presentity.s = NULL;
+	else p->uri.s = NULL;
 	p->first_tuple = NULL;
 	p->last_tuple = NULL;
 	p->first_note = NULL;
 	p->last_note = NULL;
-	p->auth = presence_auth_unresolved;
 
 	/* RPID extensions */
 	p->first_person = NULL;
@@ -79,12 +104,10 @@ presence_tuple_info_t *create_tuple_info(const str_t *contact, const str_t *id,
 		cds_free(t);
 		return NULL;
 	}
-	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;
@@ -111,7 +134,6 @@ void free_tuple_info(presence_tuple_info_t *t)
 	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) {
@@ -260,3 +282,100 @@ person_t *create_person(const str_t *element, const str_t *id)
 	t->next = NULL;
 	return t;
 }
+
+/*************************************************************/
+static int copy_tuple_notes(presence_tuple_info_t *dst_info, 
+		const presence_tuple_info_t *src)
+{
+	presence_note_t *n, *nn;
+
+	n = src->first_note;
+	while (n) {
+		nn = create_presence_note(&n->value, &n->lang);
+		if (!nn) {
+			ERR("can't create presence note\n");
+			return -1;
+		}
+		DOUBLE_LINKED_LIST_ADD(dst_info->first_note, dst_info->last_note, nn);
+		n = n->next;
+	}
+	return 0;
+}
+
+presentity_info_t *dup_presentity_info(presentity_info_t *p)
+{
+	presentity_info_t *pinfo;
+	presence_tuple_info_t *tinfo, *t;
+	presence_note_t *n, *pan;
+	person_t *ps, *last_ps, *paps;
+	int err = 0;
+
+	/* DBG("p2p_info()\n"); */
+	if (!p) return NULL;
+/*	pinfo = (presentity_info_t*)cds_malloc(sizeof(*pinfo)); */
+	pinfo = create_presentity_info(&p->uri);
+	if (!pinfo) {
+		ERROR_LOG("can't allocate memory\n");
+		return NULL;
+	}
+	/* DBG("p2p_info(): created presentity info\n"); */
+
+	t = p->first_tuple;
+	while (t) {
+		tinfo = create_tuple_info(&t->contact, &t->id, t->status);
+		if (!tinfo) {
+			ERROR_LOG("can't create tuple info\n");
+			err = 1;
+			break;
+		}
+		tinfo->priority = t->priority;
+		/* tinfo->expires = t->expires; ??? */
+		add_tuple_info(pinfo, tinfo);
+		if (copy_tuple_notes(tinfo, t) < 0) {
+			ERROR_LOG("can't copy tuple notes\n");
+			err = 1;
+			break;
+		}
+		t = t->next;
+	}
+
+	/* notes */
+	if (!err) {
+		pan = p->first_note;
+		while (pan) {
+			n = create_presence_note(&pan->value, &pan->lang);
+			if (n) DOUBLE_LINKED_LIST_ADD(pinfo->first_note, pinfo->last_note, n);
+			else {
+				ERROR_LOG("can't copy presence notes\n");
+				err = 1;
+				break;
+			}
+			pan = pan->next;
+		}
+	}
+	
+	/* person elements */
+	if (!err) {
+		last_ps = NULL;
+		paps = p->first_person;
+		while (paps) {
+			ps = create_person(&paps->person_element, &paps->id);
+			if (ps) LINKED_LIST_ADD(pinfo->first_person, last_ps, ps);
+			else {
+				ERROR_LOG("can't copy person elements\n");
+				err = 1;
+				break;
+			}
+			paps = paps->next;
+		}
+	}
+	
+	if (err) {
+		free_presentity_info(pinfo);
+		return NULL;
+	}
+	
+	/* DBG("p2p_info() finished\n"); */
+	return pinfo;
+}
+

+ 14 - 7
lib/presence/pres_doc.h

@@ -38,7 +38,8 @@ typedef struct _presence_note_t {
 
 typedef enum {
 	presence_tuple_open,
-	presence_tuple_closed
+	presence_tuple_closed,
+	presence_tuple_undefined_status
 } presence_tuple_status_t;
 
 typedef enum {
@@ -52,9 +53,7 @@ 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_tuple_info_t *next, *prev;
 	presence_note_t *first_note, *last_note;/* published notes */
 } presence_tuple_info_t;
@@ -71,15 +70,14 @@ typedef struct _person_t {
 /*	str_t activities;*/
 	str_t person_element;
 
-	struct _person_t *next; /* there can be more person elements in PIDF */
+	struct _person_t *next, *prev; /* there can be more person elements in PIDF */
 } person_t;
 
 typedef struct {
-	str_t presentity; /* do not modify this !*/
+	str_t uri; /* 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;
+	person_t *first_person, *last_person;
 		
 	char presentity_data[1];
 } presentity_info_t;
@@ -114,6 +112,15 @@ void free_presence_note(presence_note_t *n);
 
 person_t *create_person(const str_t *element, const str_t *id);
 
+/** returns pointer to constant string (do not free it!),
+ * the return value is never NULL */
+str_t* tuple_status2str(presence_tuple_status_t status);
+
+presence_tuple_status_t str2tuple_status(const str *s);
+
+/* duplicates presentity info */
+presentity_info_t *dup_presentity_info(presentity_info_t *p);
+
 /* content type names usable with QSA */
 #define CT_PRESENCE_INFO    "structured/presence-info" /* uses presence_info_t */
 #define CT_PIDF_XML         "application/pidf+xml" /* carries XML */

+ 2 - 2
lib/presence/xpidf.c

@@ -91,7 +91,7 @@ static void doc_add_empty_tuple(dstring_t *buf, presentity_info_t *p)
 	dstr_append_zt(buf, "\t<atom id=\"none\">\r\n");
 	
 	dstr_append_zt(buf, "\t\t<address uri=\"");
-	dstr_append_str(buf, &p->presentity);
+	dstr_append_str(buf, &p->uri);
 	dstr_append_zt(buf, "\" priority=\"1\">\r\n");
 /*	dstr_append_zt(buf, ";user=ip\" priority=\"1\">\r\n");*/
 	dstr_append_zt(buf, "\t\t\t<status status=\"closed\"/>\r\n");
@@ -109,7 +109,7 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
 	/* !!! there SHOULD be pres URI of presentity !!! */
 	dstr_append_zt(buf, "<presentity uri=\"");
 	/* dstr_put_pres_uri(buf, &p->presentity); */
-	dstr_append_str(buf, &p->presentity);
+	dstr_append_str(buf, &p->uri);
 	dstr_append_zt(buf, ";method=SUBSCRIBE\"/>\r\n");
 	
 	t = p->first_tuple;

+ 48 - 13
lib/xcap/xcap_client.c

@@ -220,8 +220,8 @@ int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bs
 
 	i = 0;
 	if (params) {
-		if (params->auth_user) i += strlen(params->auth_user);
-		if (params->auth_pass) i += strlen(params->auth_pass);
+		if (params->auth_user) i += params->auth_user->len;
+		if (params->auth_pass) i += params->auth_pass->len;
 	}
 	if (i > 0) {
 		/* do authentication */
@@ -299,8 +299,8 @@ void free_xcap_params_content(xcap_query_params_t *params)
 {
 	if (params) {
 		str_free_content(&params->xcap_root);
-		if (params->auth_user) cds_free(params->auth_user);
-		if (params->auth_pass) cds_free(params->auth_pass);
+		str_free_content(&params->auth_user);
+		str_free_content(&params->auth_pass);
 		memset(params, 0, sizeof(*params));
 	}
 }
@@ -315,29 +315,64 @@ int dup_xcap_params(xcap_query_params_t *dst, xcap_query_params_t *src)
 		res = 0;
 		
 		res = str_dup(&dst->xcap_root, &src->xcap_root);
+		if (res == 0) res = str_dup(&dst->auth_user, &src->auth_user);
+		if (res == 0) res = str_dup(&dst->auth_pass, &src->auth_pass);
 		
-		if ((res == 0) && (src->auth_user)) {
-			dst->auth_user = zt_strdup(src->auth_user);
-			if (!dst->auth_user) res = -1;
-		}
-		if ((res == 0) && (src->auth_pass)) {
-			dst->auth_pass = zt_strdup(src->auth_pass);
-			if (!dst->auth_pass) res= -2;
-		}
-
 		if (res != 0) free_xcap_params_content(dst);
 	}
 	
 	return res;
 }
 
+int get_inline_xcap_buf_len(xcap_query_params_t *params)
+{
+	int len;
+	
+	/* counts the length for data buffer storing values of
+	 * xcap parameter members */
+	if (!params) {
+		ERR("BUG: empty params given\n");
+		return 0;
+	}
+
+	len = params->xcap_root.len;
+	len += params->auth_user.len;
+	len += params->auth_pass.len;
+
+	return len;
+}
+
+int dup_xcap_params_inline(xcap_query_params_t *dst, xcap_query_params_t *src, char *data_buffer)
+{
+	int res = -10;
+	
+	/* copies structure into existing buffer */
+	if (dst) {
+		memset(dst, 0, sizeof(*dst));
+		res = 0;
+	}
+	
+	if (src && dst) {
+		dst->xcap_root.s = data_buffer;
+		str_cpy(&dst->xcap_root, &src->xcap_root);
+
+		dst->auth_user.s = after_str_ptr(&dst->xcap_root);
+		str_cpy(&dst->auth_user, &src->auth_user);
+		dst->auth_pass.s = after_str_ptr(&dst->auth_user);
+		str_cpy(&dst->auth_pass, &src->auth_pass);
+	}
+	return res;
+}
+
 int str2xcap_params(xcap_query_params_t *dst, const str_t *src)
 {
+	ERR("BUG: unimplemented yet");
 	return -1;
 }
 
 int xcap_params2str(str_t *dst, const xcap_query_params_t *src)
 {
+	ERR("BUG: unimplemented yet");
 	return -1;
 }
 

+ 9 - 2
lib/xcap/xcap_client.h

@@ -33,9 +33,9 @@ typedef struct {
 	/* "prefix" for XCAP query */
 	str_t xcap_root;
 	/** username for authentication */
-	char *auth_user;
+	str_t auth_user;
 	/** password used for authentication */
-	char *auth_pass;
+	str_t auth_pass;
 	/** Accept unverifiable peers (ignore information 
 	 * stored in certificate and trust a certificate
 	 * without know CA). */
@@ -72,6 +72,13 @@ typedef int (*xcap_query_func)(const char *uri,
 void free_xcap_params_content(xcap_query_params_t *params);
 int dup_xcap_params(xcap_query_params_t *dst, xcap_query_params_t *src);
 
+/* counts the length for data buffer storing values of
+ * xcap parameter members */
+int get_inline_xcap_buf_len(xcap_query_params_t *params);
+
+/* copies structure into existing buffer */
+int dup_xcap_params_inline(xcap_query_params_t *dst, xcap_query_params_t *src, char *data_buffer);
+
 int str2xcap_params(xcap_query_params_t *dst, const str_t *src);
 int xcap_params2str(str_t *dst, const xcap_query_params_t *src);