Browse code

improved handling presence documents in PA - added generating of cpim-pidf+xml (draft version 07) - improved parsing Accept header fields - clarified work with document types

Vaclav Kubart authored on 08/12/2005 15:39:22
Showing 4 changed files
... ...
@@ -44,7 +44,7 @@ static void doc_add_tuple(dstring_t *buf, presentity_info_t *p, presence_tuple_i
44 44
 	
45 45
 	if (t->status == presence_tuple_open) dstr_append_zt(buf, "\t\t<status><basic>open</basic></status>\r\n");
46 46
 	else dstr_append_zt(buf, "\t\t<status><basic>closed</basic></status>\r\n");
47
-	
47
+
48 48
 	dstr_append_zt(buf, "\t\t<contact priority=\"");
49 49
 	sprintf(tmp, "%1.2f", t->priority);
50 50
 	dstr_append_zt(buf, tmp);
... ...
@@ -70,14 +70,40 @@ static void doc_add_note(dstring_t *buf, presentity_info_t *p, presence_note_t *
70 70
 	dstr_append_zt(buf, "</note>\r\n");
71 71
 }
72 72
 
73
-static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
73
+static void dstr_put_pres_uri(dstring_t *buf, str_t *uri)
74
+{
75
+	char *c;
76
+	int len = 0;
77
+	
78
+	if (!uri) return;
79
+	
80
+	c = str_strchr(uri, ':');
81
+	if (c) {
82
+		len = uri->len - (c - uri->s) - 1;
83
+		if (len > 0) c++;
84
+	}
85
+	else {
86
+		c = uri->s;
87
+		len = uri->len;
88
+	}
89
+	if (len > 0) {
90
+		dstr_append_zt(buf, "pres:");
91
+		dstr_append(buf, c, len);
92
+	}
93
+}
94
+
95
+static void doc_add_presentity(dstring_t *buf, presentity_info_t *p, int use_cpim_pidf_ns)
74 96
 {
75 97
 	presence_tuple_info_t *t;
76 98
 	presence_note_t *n;
77 99
 
78 100
 	DEBUG_LOG("doc_add_presentity()\n");
79
-	dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"");
80
-	dstr_append_str(buf, &p->presentity);
101
+	if (use_cpim_pidf_ns)
102
+		dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:cpim-pidf\" entity=\"");
103
+	else 
104
+		dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"");
105
+	/* !!! there SHOULD be pres URI of presentity !!! */
106
+	dstr_put_pres_uri(buf, &p->presentity);
81 107
 	dstr_append_zt(buf, "\">\r\n");
82 108
 	
83 109
 	DEBUG_LOG("doc_add_presentity(): adding tuples\n");
... ...
@@ -97,8 +123,7 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
97 97
 	dstr_append_zt(buf, "</presence>");
98 98
 }
99 99
 
100
-		
101
-int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type)
100
+int create_pidf_document_ex(presentity_info_t *p, str_t *dst, str_t *dst_content_type, int use_cpim_pidf_ns)
102 101
 {
103 102
 	dstring_t buf;
104 103
 	
... ...
@@ -117,7 +142,7 @@ int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_ty
117 117
 	dstr_init(&buf, 2048);
118 118
 	
119 119
 	dstr_append_zt(&buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
120
-	doc_add_presentity(&buf, p);
120
+	doc_add_presentity(&buf, p, use_cpim_pidf_ns);
121 121
 	
122 122
 	dst->len = dstr_get_data_length(&buf);
123 123
 	dst->s = cds_malloc(dst->len);
... ...
@@ -128,6 +153,11 @@ int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_ty
128 128
 	return 0;
129 129
 }
130 130
 
131
+int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type)
132
+{
133
+	return create_pidf_document_ex(p, dst, dst_content_type, 0);
134
+}
135
+
131 136
 /* ------------------------------ PIDF document parsing ------------------------------ */
132 137
 
133 138
 static char *pidf_ns = "urn:ietf:params:xml:ns:pidf";
... ...
@@ -272,8 +302,8 @@ static int read_presentity(xmlNode *root, presentity_info_t **dst, int ignore_ns
272 272
 	return res;
273 273
 }
274 274
 
275
-/* libxml2 must be initialized before calling this function ! */
276
-int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len, int ignore_ns)
275
+/* ignore ns added for cpim-pidf+xml, draft version 07 (differs only in ns) */
276
+int parse_pidf_document_ex(presentity_info_t **dst, const char *data, int data_len, int ignore_ns)
277 277
 {
278 278
 	int res = 0;
279 279
 	xmlDocPtr doc;
... ...
@@ -299,3 +329,21 @@ int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len,
299 299
 	return res;
300 300
 }
301 301
 
302
+/* libxml2 must be initialized before calling this function ! */
303
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len)
304
+{
305
+	return parse_pidf_document_ex(dst, data, data_len, 0);
306
+}
307
+
308
+/* --------------- CPIM_PIDF document creation/parsing ---------------- */
309
+
310
+int parse_cpim_pidf_document(presentity_info_t **dst, const char *data, int data_len)
311
+{
312
+	return parse_pidf_document_ex(dst, data, data_len, 1);
313
+}
314
+
315
+int create_cpim_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type)
316
+{
317
+	return create_pidf_document_ex(p, dst, dst_content_type, 1);
318
+}
319
+
... ...
@@ -30,8 +30,9 @@
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 create_cpim_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type);
33 34
 
34
-/* ignore ns added for cpim-pidf+xml, draft version 07 (differs only in ns) */
35
-int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len, int ignore_ns);
35
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len);
36
+int parse_cpim_pidf_document(presentity_info_t **dst, const char *data, int data_len);
36 37
 
37 38
 #endif
... ...
@@ -405,7 +405,63 @@ error:
405 405
 	return -1;
406 406
 }
407 407
 
408
+int parse_accept_body(struct hdr_field *hdr)
409
+{
410
+	static unsigned int mimes[MAX_MIMES_NR];
411
+	int nr_mimes;
412
+	unsigned int mime;
413
+	char *end;
414
+	char *ret;
415
+
416
+	if (!hdr) return -1;
417
+	
418
+	/* maybe the header is already parsed! */
419
+	if (hdr->parsed!=0) return 1;
420
+	
421
+	/* it seams we have to parse it! :-( */
422
+	ret = hdr->body.s;
423
+	end = ret + hdr->body.len;
424
+	nr_mimes = 0;
425
+	while (1){
426
+		ret = decode_mime_type(ret, end , &mime);
427
+		if (ret==0)
428
+			goto error;
429
+		/* a new mime was found  -> put it into array */
430
+		if (nr_mimes==MAX_MIMES_NR) {
431
+			LOG(L_ERR,"ERROR:parse_accept_hdr: Accept hdr contains more than"
432
+				" %d mime type -> buffer overflow!!\n",MAX_MIMES_NR);
433
+			goto error;
434
+		}
435
+		mimes[nr_mimes++] = mime;
436
+		/* is another mime following? */
437
+		if (ret==end )
438
+			break;
439
+		/* parse the mime separator ',' */
440
+		if (*ret!=',' || ret+1==end) {
441
+			LOG(L_ERR,"ERROR:parse_accept_hdr: parse error between mimes at "
442
+				"char <%x> (offset=%d) in <%.*s>!\n",
443
+				*ret, (int)(ret-hdr->body.s),
444
+				hdr->body.len, hdr->body.s);
445
+			goto error;
446
+		}
447
+		/* skip the ',' */
448
+		ret++;
449
+	}
450
+
451
+	/* copy and link the mime buffer into the message */
452
+	hdr->parsed = (void*)pkg_malloc((nr_mimes+1)*sizeof(int));
453
+	if (hdr->parsed==0) {
454
+		LOG(L_ERR,"ERROR:parse_accept: no more pkg memory\n");
455
+		goto error;
456
+	}
457
+	memcpy(hdr->parsed,mimes,nr_mimes*sizeof(int));
458
+	/* make the buffer null terminated */
459
+	((int*)hdr->parsed)[nr_mimes] = 0;
408 460
 
461
+	return 1;
462
+error:
463
+	return -1;
464
+}
409 465
 
410 466
 /* returns: > 0 ok
411 467
  *          = 0 hdr not found
... ...
@@ -98,6 +98,8 @@ struct mime_type {
98 98
  */
99 99
 int parse_content_type_hdr( struct sip_msg *msg);
100 100
 
101
+int parse_accept_body(struct hdr_field *hdr);
102
+
101 103
 /*
102 104
  * parse the the body of the Accept header. It's values are also converted
103 105
  * as an null-terminated array of ints.