1 /*
2 * $Id: parse_cseq.cpp 850 2008-04-04 21:29:36Z sayer $
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 #include "parse_cseq.h"
31 #include "parse_common.h"
32
33 #include "log.h"
34
parse_cseq(sip_cseq * cseq,const char * beg,int len)35 int parse_cseq(sip_cseq* cseq, const char* beg, int len)
36 {
37 enum {
38 C_NUM=0,
39 C_NUM_SWS,
40 C_METHOD
41 };
42
43
44 const char* c = beg;
45 const char* end = c+len;
46
47 int saved_st=0, st=C_NUM;
48
49 for(;c!=end;c++){
50
51 switch(st){
52
53 case C_NUM:
54 switch(*c){
55
56 case_CR_LF;
57
58 case SP:
59 case HTAB:
60 st = C_NUM_SWS;
61 cseq->num_str.set(beg, c-beg);
62 break;
63
64 default:
65 if(!IS_DIGIT(*c)){
66 return MALFORMED_SIP_MSG;
67 }
68 cseq->num = cseq->num*10 + *c - '0';
69 break;
70 }
71 break;
72
73 case C_NUM_SWS:
74 switch(*c){
75
76 case_CR_LF;
77
78 case SP:
79 case HTAB:
80 break;
81
82 default:
83 st = C_METHOD;
84 beg = c;
85 break;
86 }
87 break;
88
89 case C_METHOD:
90 switch(*c){
91
92 case_CR_LF;
93
94 case SP:
95 case HTAB:
96 cseq->method_str.set(beg,c-beg);
97 return 0;
98 }
99 break;
100
101 case_ST_CR(*c);
102
103 case ST_LF:
104 case ST_CRLF:
105 switch(saved_st){
106 case C_NUM:
107 cseq->num_str.set(beg,c-(st==ST_CRLF?2:1)-beg);
108 break;
109 case C_METHOD:
110 cseq->method_str.set(beg,c-beg);
111 return 0;
112 }
113 st = saved_st;
114 break;
115 }
116 }
117
118 if(st != C_METHOD){
119 return MALFORMED_SIP_MSG;
120 }
121
122 cseq->method_str.set(beg,c-beg);
123 if(parse_method(&cseq->method, cseq->method_str.s, cseq->method_str.len) < 0){
124
125 DBG("Cseq method parsing failed\n");
126 return MALFORMED_SIP_MSG;
127 }
128
129 return 0;
130 }
131
132 /** EMACS **
133 * Local variables:
134 * mode: c++
135 * c-basic-offset: 4
136 * End:
137 */
138