Browse code

Adding the supported parser from kamailio core

Jan Janak authored on 29/03/2009 19:50:15
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,143 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2006 Andreas Granig <agranig@linguin.org>
4
+ *
5
+ * This file is part of Kamailio, a free SIP server.
6
+ *
7
+ * Kamailio is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * Kamailio is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
+ */
21
+
22
+/*!
23
+ * \file
24
+ * \brief Supported parser
25
+ * \ingroup parser
26
+ */
27
+
28
+#include "../mem/mem.h"
29
+#include "keys.h"
30
+#include "parse_supported.h"
31
+
32
+#define IS_DELIM(c) (*(c) == ' ' || *(c) == '\t' || *(c) == '\r' || *(c) == '\n' || *(c) == ',')
33
+
34
+/* from parser/parse_hname2.c: */
35
+#define LOWER_BYTE(b) ((b) | 0x20)
36
+#define LOWER_DWORD(d) ((d) | 0x20202020)
37
+#define READ(val) \
38
+	(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
39
+
40
+
41
+/*!
42
+ * Parse Supported HF body.
43
+ */
44
+static inline int parse_supported_body(str *body, unsigned int *sup)
45
+{
46
+	register char* p;
47
+	register unsigned int val;
48
+	int len, pos = 0;
49
+
50
+	*sup = 0;
51
+
52
+	p = body->s;
53
+	len = body->len;
54
+
55
+	while (pos < len) {
56
+		/* skip spaces and commas */
57
+		for (; pos < len && IS_DELIM(p); ++pos, ++p);
58
+
59
+		val = LOWER_DWORD(READ(p));
60
+		switch (val) {
61
+
62
+			/* "path" */
63
+			case _path_:
64
+				if(pos + 4 <= len && IS_DELIM(p+4)) {
65
+					*sup |= F_SUPPORTED_PATH;
66
+					pos += 5; p += 5;
67
+				}
68
+				break;
69
+
70
+			/* "100rel" */
71
+			case _100r_:
72
+				if ( pos+6 <= len
73
+					 && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l'
74
+					 && IS_DELIM(p+6)) {
75
+					*sup |= F_SUPPORTED_100REL;
76
+					pos += SUPPORTED_100REL_LEN + 1;
77
+					p   += SUPPORTED_100REL_LEN + 1;
78
+				}
79
+				break;
80
+
81
+			/* "timer" */
82
+			case _time_:
83
+				if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r'
84
+					 && IS_DELIM(p+5) ) {
85
+					*sup |= F_SUPPORTED_TIMER;
86
+					pos += SUPPORTED_TIMER_LEN + 1;
87
+					p   += SUPPORTED_TIMER_LEN + 1;
88
+				}
89
+				break;
90
+
91
+			/* unknown */
92
+			default:
93
+				/* skip element */
94
+				for (; pos < len && !IS_DELIM(p); ++pos, ++p);
95
+				break;
96
+		}
97
+	}
98
+	
99
+	return 0;
100
+}
101
+
102
+/*!
103
+ * Parse all Supported headers
104
+ */
105
+int parse_supported( struct sip_msg *msg)
106
+{
107
+	unsigned int supported;
108
+	struct hdr_field  *hdr;
109
+	struct supported_body *sb;
110
+
111
+	/* maybe the header is already parsed! */
112
+	if (msg->supported && msg->supported->parsed)
113
+		return 0;
114
+
115
+	/* parse to the end in order to get all SUPPORTED headers */
116
+	if (parse_headers(msg,HDR_EOH_F,0)==-1 || !msg->supported)
117
+		return -1;
118
+
119
+	/* bad luck! :-( - we have to parse them */
120
+	supported = 0;
121
+	for( hdr=msg->supported ; hdr ; hdr=hdr->sibling) {
122
+		if (hdr->parsed) {
123
+			supported |= ((struct supported_body*)hdr->parsed)->supported;
124
+			continue;
125
+		}
126
+
127
+		sb = (struct supported_body*)pkg_malloc(sizeof(struct supported_body));
128
+		if (sb == 0) {
129
+			LM_ERR("out of pkg_memory\n");
130
+			return -1;
131
+		}
132
+
133
+		parse_supported_body(&(hdr->body), &(sb->supported));
134
+		sb->supported_all = 0;
135
+		hdr->parsed = (void*)sb;
136
+		supported |= sb->supported;
137
+	}
138
+
139
+	((struct supported_body*)msg->supported->parsed)->supported_all = 
140
+		supported;
141
+	return 0;
142
+}
0 143
new file mode 100644
... ...
@@ -0,0 +1,84 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2006 Andreas Granig <agranig@linguin.org>
4
+ *
5
+ * This file is part of Kamailio, a free SIP server.
6
+ *
7
+ * Kamailio is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * Kamailio is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
+ *
21
+ *
22
+ * History:
23
+ * -------
24
+ * 2006-03-02  parse_supported() parses and cumulates all SUPPORTED 
25
+ *             headers (bogdan)
26
+ */
27
+
28
+/*!
29
+ * \file
30
+ * \brief Supported parser
31
+ * \ingroup parser
32
+ */
33
+
34
+#ifndef PARSE_SUPPORTED_H
35
+#define PARSE_SUPPORTED_H
36
+
37
+#include "msg_parser.h"
38
+#include "../mem/mem.h"
39
+
40
+
41
+#define F_SUPPORTED_PATH	(1 << 0)
42
+#define F_SUPPORTED_100REL	(1 << 1)
43
+#define F_SUPPORTED_TIMER	(1 << 2)
44
+
45
+#define SUPPORTED_PATH_STR		"path"
46
+#define SUPPORTED_PATH_LEN		(sizeof(SUPPORTED_PATH_STR)-1)
47
+
48
+/* RFC 3262 */
49
+#define SUPPORTED_100REL_STR	"100rel"
50
+#define SUPPORTED_100REL_LEN	(sizeof(SUPPORTED_100REL_STR)-1)
51
+
52
+/* RFC 4028 */
53
+#define SUPPORTED_TIMER_STR		"timer"
54
+#define SUPPORTED_TIMER_LEN		(sizeof(SUPPORTED_TIMER_STR)-1)
55
+
56
+
57
+#define get_supported(p_msg) \
58
+	((p_msg)->supported ? ((struct supported_body*)(p_msg)->supported->parsed)->supported_all : 0)
59
+
60
+
61
+struct supported_body {
62
+	unsigned int supported;        /* supported mask for the current hdr */
63
+	unsigned int supported_all;    /* suppoted mask for the all "supported" hdr
64
+	                                *  - it's set only for the first hdr in 
65
+	                                *  sibling list*/
66
+};
67
+
68
+
69
+/*!
70
+ * Parse all Supported headers.
71
+ */
72
+int parse_supported( struct sip_msg *msg);
73
+
74
+
75
+static inline void free_supported(struct supported_body **sb)
76
+{
77
+	if (sb && *sb) {
78
+		pkg_free(*sb);
79
+		*sb = 0;
80
+	}
81
+}
82
+
83
+#endif /* PARSE_SUPPORTED_H */