ソースを参照

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

Vaclav Kubart 19 年 前
コミット
701973de4c

+ 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);