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