Browse code

added Subscription-State header field parsing (only needed parts)

Vaclav Kubart authored on 21/06/2006 13:33:01
Showing 10 changed files
... ...
@@ -379,6 +379,7 @@ struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len )
379 379
 		case HDR_SIPIFMATCH_T:
380 380
 		case HDR_SESSIONEXPIRES_T:
381 381
 		case HDR_MIN_SE_T:
382
+		case HDR_SUBSCRIPTION_STATE_T:
382 383
 		case HDR_ACCEPTCONTACT_T:
383 384
 		case HDR_ALLOWEVENTS_T:
384 385
 		case HDR_CONTENTENCODING_T:
... ...
@@ -759,6 +760,11 @@ do { \
759 760
 				new_msg->min_se = new_hdr;
760 761
 			}
761 762
 			break;
763
+		case HDR_SUBSCRIPTION_STATE_T:
764
+			if (!HOOK_SET(subscription_state)) {
765
+				new_msg->subscription_state = new_hdr;
766
+			}
767
+			break;
762 768
 		case HDR_SIPIFMATCH_T:
763 769
 			if (!HOOK_SET(sipifmatch)) {
764 770
 				new_msg->sipifmatch = new_hdr;
765 771
new file mode 100644
... ...
@@ -0,0 +1,77 @@
1
+/* 
2
+ * $Id$ 
3
+ *
4
+ * Subject Header Field Name Parsing Macros
5
+ *
6
+ * Copyright (C) 2001-2003 FhG Fokus
7
+ *
8
+ * This file is part of ser, a free SIP server.
9
+ *
10
+ * ser is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ *
15
+ * For a license to use the ser software under conditions
16
+ * other than those described here, or to purchase support for this
17
+ * software, please contact iptel.org by e-mail at the following addresses:
18
+ *    info@iptel.org
19
+ *
20
+ * ser is distributed in the hope that it will be useful,
21
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
+ * GNU General Public License for more details.
24
+ *
25
+ * You should have received a copy of the GNU General Public License 
26
+ * along with this program; if not, write to the Free Software 
27
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
+ */
29
+
30
+
31
+#ifndef CASE_SUBS_H
32
+#define CASE_SUBS_H
33
+
34
+#define te_CASE                         \
35
+        if (LOWER_BYTE(*p) == 't') { \
36
+			p++;                   \
37
+            if (LOWER_BYTE(*p) == 'e') { \
38
+				p++;               \
39
+				hdr->type = HDR_SUBSCRIPTION_STATE_T;    \
40
+		        goto dc_end;       \
41
+			}                      \
42
+        }
43
+
44
+#define _sta_CASE                         \
45
+        switch(LOWER_DWORD(val)) { \
46
+        case __sta_:               \
47
+	        p += 4;            \
48
+			te_CASE;         \
49
+	        goto other;        \
50
+        }
51
+
52
+#define cription_CASE                         \
53
+        switch(LOWER_DWORD(val)) { \
54
+        case _tion_:               \
55
+	        p += 4;            \
56
+	        val = READ(p);     \
57
+			_sta_CASE;         \
58
+	        goto other;        \
59
+        }
60
+
61
+#define crip_CASE                         \
62
+        switch(LOWER_DWORD(val)) { \
63
+        case _crip_:               \
64
+	        p += 4;            \
65
+	        val = READ(p);     \
66
+			cription_CASE;     \
67
+	        goto other;        \
68
+        }
69
+
70
+#define subs_CASE        \
71
+        p += 4;          \
72
+        val = READ(p);   \
73
+        crip_CASE;        \
74
+        goto other;
75
+
76
+
77
+#endif /* CASE_SUBS_H */
... ...
@@ -44,6 +44,7 @@
44 44
 #include "parse_expires.h"
45 45
 #include "parse_sipifmatch.h"
46 46
 #include "parse_rr.h"
47
+#include "parse_subscription_state.h"
47 48
 #include "contact/parse_contact.h"
48 49
 #include "parse_disposition.h"
49 50
 #include "../ut.h"
... ...
@@ -166,6 +167,10 @@ void clean_hdr_field(struct hdr_field* hf)
166 167
 		case HDR_REFER_TO_T:
167 168
 			free_to(hf->parsed);
168 169
 			break;
170
+		
171
+		case HDR_SUBSCRIPTION_STATE_T:
172
+			free_subscription_state((subscription_state_t**)hf->parsed);
173
+			break;
169 174
 
170 175
 		case HDR_SESSIONEXPIRES_T:
171 176
 		case HDR_MIN_SE_T:
... ...
@@ -89,6 +89,7 @@ enum _hdr_types_t {
89 89
 	HDR_SIPIFMATCH_T                   /* SIP-If-Match header field */,
90 90
 	HDR_SESSIONEXPIRES_T                           /* Session-Expires header */,
91 91
 	HDR_MIN_SE_T                                   /* Min-SE */,
92
+	HDR_SUBSCRIPTION_STATE_T                       /* Subscription-State */,
92 93
 	HDR_ACCEPTCONTACT_T                            /* Accept-Contact header */,
93 94
 	HDR_ALLOWEVENTS_T                              /* Allow-Events header */,
94 95
 	HDR_CONTENTENCODING_T                          /* Content-Encoding header */,
... ...
@@ -148,6 +149,7 @@ typedef unsigned long long hdr_flags_t;
148 149
 #define HDR_SIPIFMATCH_F			HDR_F_DEF(SIPIFMATCH)
149 150
 #define HDR_SESSIONEXPIRES_F			HDR_F_DEF(SESSIONEXPIRES)
150 151
 #define HDR_MIN_SE_F				HDR_F_DEF(MIN_SE)
152
+#define HDR_SUBSCRIPTION_STATE_F	HDR_F_DEF(SUBSCRIPTION_STATE)
151 153
 #define HDR_ACCEPTCONTACT_F			HDR_F_DEF(HDR_ACCEPTCONTACT_T)
152 154
 #define HDR_ALLOWEVENTS_F			HDR_F_DEF(HDR_ALLOWEVENTS_T)
153 155
 #define HDR_CONTENTENCODING_F			HDR_F_DEF(HDR_CONTENTENCODING_T)
... ...
@@ -192,6 +194,7 @@ static inline int hdr_allocs_parse(struct hdr_field* hdr)
192 194
 		case HDR_DIVERSION_T:
193 195
 		case HDR_RPID_T:
194 196
 		case HDR_REFER_TO_T:
197
+		case HDR_SUBSCRIPTION_STATE_T:
195 198
 			return 1;
196 199
 		default:
197 200
 			return 0;
... ...
@@ -110,6 +110,9 @@
110 110
 #define _prio_ 0x6f697270   /* "prio" */
111 111
 #define _rity_ 0x79746972   /* "rity" */
112 112
 #define _subj_ 0x6a627573   /* "subj" */
113
+#define _subs_ 0x73627573   /* "subs" */
114
+#define _crip_ 0x70697263   /* "crip" */
115
+#define __sta_ 0x6174732d   /* "-sta" */
113 116
 #define _ect2_ 0x20746365   /* "ect " */
114 117
 #define _ect1_ 0x3a746365   /* "ect:" */
115 118
 #define _user_ 0x72657375   /* "user" */
... ...
@@ -210,6 +210,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
210 210
 		case HDR_REFER_TO_T:
211 211
 		case HDR_SESSIONEXPIRES_T:
212 212
 		case HDR_MIN_SE_T:
213
+		case HDR_SUBSCRIPTION_STATE_T:
213 214
 		case HDR_ACCEPTCONTACT_T:
214 215
 		case HDR_ALLOWEVENTS_T:
215 216
 		case HDR_CONTENTENCODING_T:
... ...
@@ -444,6 +445,10 @@ int parse_headers(struct sip_msg* msg, hdr_flags_t flags, int next)
444 445
 				if (msg->min_se==0) msg->min_se = hf;
445 446
 				msg->parsed_flag|=HDR_MIN_SE_F;
446 447
 				break;
448
+			case HDR_SUBSCRIPTION_STATE_T:
449
+				if (msg->subscription_state==0) msg->subscription_state = hf;
450
+				msg->parsed_flag|=HDR_SUBSCRIPTION_STATE_F;
451
+				break;
447 452
 			case HDR_VIA_T:
448 453
 				msg->parsed_flag|=HDR_VIA_F;
449 454
 				DBG("parse_headers: Via found, flags=%llx\n",
... ...
@@ -211,6 +211,7 @@ struct sip_msg {
211 211
 	struct hdr_field* session_expires;
212 212
 	struct hdr_field* min_se;
213 213
 	struct hdr_field* sipifmatch;
214
+	struct hdr_field* subscription_state;
214 215
 
215 216
 	char* eoh;        /* pointer to the end of header (if found) or null */
216 217
 	char* unparsed;   /* here we stopped parsing*/
... ...
@@ -89,6 +89,7 @@ static inline char* skip_ws(char* p, unsigned int size)
89 89
 #include "case_sess.h"     /* Session-Expires */
90 90
 #include "case_reje.h"     /* Reject-Contact */
91 91
 #include "case_min.h"      /* Min-SE */
92
+#include "case_subs.h"     /* Subscription-State */
92 93
 
93 94
 
94 95
 #define READ(val) \
... ...
@@ -118,6 +119,7 @@ static inline char* skip_ws(char* p, unsigned int size)
118 119
         case _orga_: orga_CASE; \
119 120
         case _prio_: prio_CASE; \
120 121
         case _subj_: subj_CASE; \
122
+        case _subs_: subs_CASE; \
121 123
         case _user_: user_CASE; \
122 124
         case _dive_: dive_CASE; \
123 125
         case _remo_: remo_CASE; \
124 126
new file mode 100644
... ...
@@ -0,0 +1,129 @@
1
+#include "parse_subscription_state.h"
2
+#include "../dprint.h"
3
+#include "../trim.h"
4
+#include "../mem/mem.h"
5
+#include "../ut.h"
6
+#include "parser_f.h"
7
+#include "parse_param.h"
8
+#include <string.h>
9
+
10
+void free_subscription_state(subscription_state_t**ss)
11
+{
12
+	if (ss) {
13
+		if (*ss) pkg_free(*ss);
14
+		*ss = 0;
15
+	}
16
+}
17
+
18
+static inline int str_cmp(const str *a, const str *b)
19
+{
20
+	int i;
21
+	
22
+	if (a->len != b->len) return 1;
23
+	
24
+	for (i = 0; i < a->len; i++) 
25
+		if (a->s[i] != b->s[i]) return 1;
26
+	return 0;
27
+}
28
+
29
+int ss_parse(str *src, subscription_state_t *ss)
30
+{
31
+	static str active = STR_STATIC_INIT("active");
32
+	static str pending = STR_STATIC_INIT("pending");
33
+	static str terminated = STR_STATIC_INIT("terminated");
34
+	
35
+	int res = 0;
36
+	param_hooks_t ph;
37
+	param_t *params;
38
+	str s = *src;
39
+	str state;
40
+	char *c, *end;
41
+	
42
+	/* initialization */
43
+	ss->expires_set = 0;
44
+	ss->expires = 0;
45
+	
46
+	trim_leading(&s);
47
+	end = s.s + s.len;
48
+		
49
+	state = s;
50
+	
51
+	c = find_not_quoted(&s, ';');
52
+	if (c) {
53
+		/* first parameter starts after c */
54
+		state.len = c - state.s;
55
+		s.len = s.len - (c - s.s) - 1;
56
+		s.s = c + 1;
57
+	}
58
+	else {
59
+		s.len = 0;
60
+	}
61
+
62
+	/* set state value */
63
+	if (str_cmp(&state, &active) == 0) {
64
+		ss->value = ss_active;
65
+	}
66
+	else if (str_cmp(&state, &pending) == 0) {
67
+		ss->value = ss_pending;
68
+	}
69
+	else if (str_cmp(&state, &terminated) == 0) {
70
+		ss->value = ss_terminated;
71
+	}
72
+	else { 
73
+		/* INFO("unknown subscription-State value :%.*s\n",
74
+					state.len, state.s); */
75
+		ss->value = ss_extension;
76
+	}
77
+
78
+	/* explore parameters */
79
+	
80
+	trim_leading(&s);
81
+	if (s.len > 0) {
82
+		params = NULL;
83
+		if (parse_params(&s, CLASS_CONTACT, &ph, &params) < 0) {
84
+			ERR("can't parse params\n");
85
+			res = -1;
86
+		}
87
+		else {
88
+			if (ph.contact.expires) {
89
+				ss->expires_set = 1;
90
+				res = str2int(&ph.contact.expires->body, &ss->expires);
91
+				if (res != 0) 
92
+					ERR("invalid expires value: \'%.*s\'\n", 
93
+						ph.contact.expires->body.len,
94
+						ph.contact.expires->body.s);
95
+			}
96
+			if (params) free_params(params);
97
+		}
98
+	}
99
+	/*
100
+	ss->value = ss_active;
101
+	ss->expires = 0;*/
102
+
103
+
104
+	return res;
105
+}
106
+
107
+int parse_subscription_state(struct hdr_field *h)
108
+{
109
+	subscription_state_t *ss;
110
+	if (h->parsed) return 0;
111
+
112
+	ss = (subscription_state_t*)pkg_malloc(sizeof(*ss));
113
+	if (!ss) {
114
+		ERR("No memory left\n");
115
+		return -1;
116
+	}
117
+
118
+	memset(ss, 0, sizeof(*ss));
119
+
120
+	if (ss_parse(&h->body, ss) < 0) {
121
+		ERR("Can't parse Subscription-State\n");
122
+		pkg_free(ss);
123
+		return -2;
124
+	}
125
+
126
+	h->parsed = (void*)ss;
127
+	
128
+	return 0;
129
+}
0 130
new file mode 100644
... ...
@@ -0,0 +1,26 @@
1
+#ifndef __PARSE_SUBSCRIPTION_STATE_H
2
+#define __PARSE_SUBSCRIPTION_STATE_H
3
+
4
+#include "hf.h"
5
+
6
+typedef enum {
7
+	ss_active,
8
+	ss_pending,
9
+	ss_terminated,
10
+	ss_extension
11
+} substate_value_t;
12
+
13
+typedef struct _subscription_state_t {
14
+	substate_value_t value;
15
+	unsigned int expires;
16
+	int expires_set; /* expires is valid if nonzero here */
17
+} subscription_state_t;
18
+
19
+/* FIXME: temporary only */
20
+int ss_parse(str *src, subscription_state_t *ss);
21
+
22
+int parse_subscription_state(struct hdr_field *h);
23
+
24
+void free_subscription_state(subscription_state_t **ss);
25
+
26
+#endif