1 /*
2 * $Id: parse_common.h 1486 2009-08-29 14:40:38Z rco $
3 *
4 * Copyright (C) 2007 Raphael Coeffic
5 *
6 * This file is part of SEMS, a free SIP media server.
7 *
8 * SEMS is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. This program is released under
12 * the GPL with the additional exemption that compiling, linking,
13 * and/or using OpenSSL is allowed.
14 *
15 * For a license to use the SEMS 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 * SEMS 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 #ifndef _parse_common_h
31 #define _parse_common_h
32
33 #include "cstring.h"
34
35 #include <list>
36 using std::list;
37
38 //
39 // Constants
40 //
41
42 #define UNDEFINED_ERR -1
43 #define UNEXPECTED_EOT -2
44 #define UNEXPECTED_EOL -3
45 #define MALFORMED_SIP_MSG -4
46 #define INCOMPLETE_SIP_MSG -5
47 #define MALFORMED_URI -6
48 #define MALFORMED_FLINE -7
49
50 #define IS_IN(c,l,r) (((c)>=(l))&&((c)<=(r)))
51
52 #define CR (0x0d) // '\r'
53 #define LF (0x0a) // '\n'
54 #define SP (0x20) // ' '
55 #define HTAB (0x09) // '\t'
56 #define IS_WSP(c) (SP==(c) || HTAB==(c))
57
58 #define HCOLON (':')
59 #define SEMICOLON (';')
60 #define COMMA (',')
61 #define DQUOTE ('"')
62 #define SLASH ('/')
63 #define BACKSLASH ('\\')
64 #define HYPHEN ('-')
65
66 #define IS_ALPHA(c) (IS_IN(c,0x41,0x5a) || IS_IN(c,0x61,0x7a))
67 #define IS_DIGIT(c) IS_IN(c,0x30,0x39)
68 #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_DIGIT(c))
69
70 //#define IS_UPPER(c) IS_IN(c,0x41,0x5a)
71 //#define LOWER_B(c) (IS_UPPER(c) ? ((c)+0x20) : (c))
72 #define IS_UPPER(c) (c & 0x20 == 0)
73 #define LOWER_B(c) (c | 0x20)
74
75 // TODO: wouldn't a switch work quicker?
76 #define IS_TOKEN(c) \
77 (IS_ALPHANUM(c) || \
78 ((c)=='-') || ((c)=='.') || ((c)=='!') || ((c)=='%') || \
79 ((c)=='*') || ((c)=='_') || ((c)=='+') || ((c)=='`') || \
80 ((c)=='\'') || ((c)=='~') )
81
82 #define IS_MARK(c) \
83 (((c)=='-') || ((c)=='_') || ((c)=='.') || ((c)=='!') || \
84 ((c)=='~') || ((c)=='*') || ((c)=='\'') || ((c)=='(') || \
85 ((c)==')') )
86
87 #define IS_UNRESERVED(c) \
88 (IS_ALPHANUM(c) || IS_MARK(c))
89
90 #define IS_USER_UNRESERVED(c) \
91 (((c)=='&') || ((c)=='=') || ((c)=='+') || ((c)=='$') || \
92 ((c)==',') || ((c)==';') || ((c)=='?') || ((c)=='/'))
93
94 #define IS_USER(c) \
95 (IS_UNRESERVED(c) || IS_USER_UNRESERVED(c)) // Escaped chars missing
96
97 //
98 // SIP version constants
99 //
100
101 #define SIP_str "SIP"
102 #define SUP_SIPVER "/2.0"
103
104 #define SIP_len (sizeof(SIP_str)-/*0-term*/1)
105 #define SUP_SIPVER_len (sizeof(SUP_SIPVER)-/*0-term*/1)
106
107 #define SIPVER_len (SIP_len+SUP_SIPVER_len)
108
109 //
110 // Common states: (>100)
111 //
112
113 enum {
114 ST_CR=100,
115 ST_LF,
116 ST_CRLF
117 };
118
119 #define case_CR_LF \
120 case CR:\
121 saved_st = st;\
122 st = ST_CR;\
123 break;\
124 case LF:\
125 saved_st = st;\
126 st = ST_LF;\
127 break
128
129 #define case_ST_CR(c) \
130 case ST_CR:\
131 if((c) == LF){\
132 st = ST_CRLF;\
133 }\
134 else {\
135 DBG("CR without LF\n");\
136 return MALFORMED_SIP_MSG;\
137 }\
138 break
139
140 //
141 // Structs
142 //
143
144 struct sip_avp
145 {
146 cstring name;
147 cstring value;
148
sip_avpsip_avp149 sip_avp()
150 : name(), value()
151 {}
152
sip_avpsip_avp153 sip_avp(const cstring& n,
154 const cstring& v)
155 : name(n),value(v)
156 {}
157 };
158
159
160 //
161 // Functions
162 //
163
lower_cmp(const char * l,const char * r,int len)164 inline int lower_cmp(const char* l, const char* r, int len)
165 {
166 const char* end = l+len;
167
168 while(l!=end){
169 if( LOWER_B(*l) == LOWER_B(*r) ){
170 l++; r++;
171 continue;
172 }
173 else if(LOWER_B(*l) < LOWER_B(*r)) {
174 return -1;
175 }
176 else {
177 return 1;
178 }
179 }
180
181 return 0;
182 }
183
lower_cmp_n(const char * l,int llen,const char * r,int rlen)184 inline int lower_cmp_n(const char* l, int llen, const char* r, int rlen)
185 {
186 if(llen == rlen)
187 return lower_cmp(l,r,rlen);
188 else if(llen < rlen)
189 return -1;
190
191 return 1;
192 }
193
lower_cmp_n(const cstring & l,const cstring & r)194 inline int lower_cmp_n(const cstring& l, const cstring& r)
195 {
196 return lower_cmp_n(l.s,l.len,r.s,r.len);
197 }
198
199 int parse_sip_version(const char* beg, int len);
200
201 /**
202 * Parse a list of Attribute-Value pairs beginning with
203 * and separated by semi-colons until stop_char or the
204 * end of the string is reached.
205 */
206 int parse_gen_params_sc(list<sip_avp*>* params, const char** c,
207 int len, char stop_char);
208
209 /**
210 * Parse a list of Attribute-Value pairs separated
211 * by semi-colons until stop_char or the end of
212 * the string is reached.
213 */
214 int parse_gen_params(list<sip_avp*>* params, const char** c, int len, char stop_char);
215
216 /** Free the parameters in the list (NOT the list itself) */
217 void free_gen_params(list<sip_avp*>* params);
218
219 #endif
220
221 /** EMACS **
222 * Local variables:
223 * mode: c++
224 * c-basic-offset: 4
225 * End:
226 */
227