belle_sip_message.g 42.6 KB
Newer Older
jehan's avatar
jehan committed
1
/*
2
    belle-sip - SIP (RFC3261) library.
jehan's avatar
jehan committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    Copyright (C) 2010  Belledonne Communications SARL

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
grammar belle_sip_message;

20
 
jehan's avatar
jehan committed
21 22 23 24 25 26 27 28 29 30
options {	
	language = C;
	
} 
@header { 
#include "belle-sip/belle-sip.h"
#include "belle_sip_internal.h"
}


jehan's avatar
jehan committed
31

32 33 34 35 36 37
message returns [belle_sip_message_t* ret]
scope { size_t message_length; }
  : message_raw[&($message::message_length)] {$ret=$message_raw.ret;};
message_raw [size_t* length]  returns [belle_sip_message_t* ret]
scope { size_t* message_length; }
@init {$message_raw::message_length=length; }
jehan's avatar
jehan committed
38
	:	  request {$ret = BELLE_SIP_MESSAGE($request.ret);} 
39
	   | response {$ret = BELLE_SIP_MESSAGE($response.ret);} ;
jehan's avatar
jehan committed
40 41 42
request	returns [belle_sip_request_t* ret]
scope { belle_sip_request_t* current; }
@init {$request::current = belle_sip_request_new(); $ret=$request::current; }
43
	:	  request_line  message_header[BELLE_SIP_MESSAGE($request::current)]+ last_crlf=CRLF {*($message_raw::message_length)=$last_crlf->user1;} /*message_body ?*/ ;
jehan's avatar
jehan committed
44 45

request_line   
jehan's avatar
jehan committed
46
	:	  method {belle_sip_request_set_method($request::current,(const char*)($method.text->chars));} 
jehan's avatar
jehan committed
47
	    (SP)=>LWS 
jehan's avatar
jehan committed
48
	    uri {belle_sip_request_set_uri($request::current,$uri.ret);}
jehan's avatar
jehan committed
49
	    LWS 
jehan's avatar
jehan committed
50 51
	    sip_version 
	    CRLF ;
jehan's avatar
jehan committed
52 53

sip_version   
54
	:	word;// 'SIP/' DIGIT '.' DIGIT;
jehan's avatar
jehan committed
55

jehan's avatar
jehan committed
56 57 58
message_header [belle_sip_message_t* message] 

	:	           (/*accept
jehan's avatar
jehan committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//                |  accept_encoding
//                |  accept_language
//                |  alert_info
//                |  allow
//                |  authentication_info
//                |  authorization
//                |  header_call_id {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_call_id.ret));}/*
//                |  call_info
//                |  header_contact {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_contact.ret));}
//                |  content_disposition
//                |  content_encoding
//                |  content_language*/
//                |  header_content_length  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_content_length.ret));}
//                |  header_content_type  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_content_type.ret));}
//                |  header_cseq  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_cseq.ret));}/*
//                |  date
//                |  error_info
//                |  expires*/
//                |  header_from  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_from.ret));}/*
//                |  in_reply_to
//                |  max_forwards
//                |  mime_version
//                |  min_expires
//                |  organization
//                |  priority
//                |  proxy_authenticate
//                |  proxy_authorization
//                |  proxy_require*/
//                |  header_record_route  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_record_route.ret));}/*
//                |  reply_to
//                |  require
//                |  retry_after*/
//                |  header_route  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_route.ret));}/*
//                |  server
//                |  subject
//                |  supported
//                |  timestamp*/
//                |  header_to  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_to.ret));}/*
//                |  unsupported
//                |  user_agent*/
//                |  header_via  {belle_sip_message_add_header(message,BELLE_SIP_HEADER($header_via.ret));}/*
//                |  warning
//                |  www_authenticate*/
jehan's avatar
jehan committed
102 103 104 105 106
                  header_extension[TRUE] {
                    belle_sip_header_t* lheader = BELLE_SIP_HEADER($header_extension.ret);
                    do {
                      belle_sip_message_add_header(message,lheader);
                      }
107
                    while((lheader=belle_sip_header_get_next(lheader)) != NULL); } 
108
                ) CRLF 
jehan's avatar
jehan committed
109
               ;
jehan's avatar
jehan committed
110 111

       
jehan's avatar
jehan committed
112
/*
jehan's avatar
jehan committed
113 114 115 116 117 118 119 120 121
invitem           
	:	'INVITE' ; //INVITE in caps
ackm 	:	'ACK'; //ACK in caps
optionsm:	'OPTION'; //OPTIONS in caps
byem	:	'BYE' ; //BYE in caps
cancelm :	'CANCEL' ; //CANCEL in caps
registerm
	:	'REGISTER' ; //REGISTER in caps
optionm :	'OPTION';
122 123
*/
method 	:	          /* invitem | ackm | optionm | byem | cancelm | registerm |*/extension_method ;
jehan's avatar
jehan committed
124 125 126

extension_method  
	:	  token;
127 128 129

response  returns [belle_sip_response_t* ret]
scope { belle_sip_response_t* current; }
jehan's avatar
jehan committed
130
@init {$response::current = belle_sip_response_new(); $ret=$response::current; }         
jehan's avatar
jehan committed
131
	:	  status_line message_header[BELLE_SIP_MESSAGE($response::current)]+ last_crlf=CRLF {*($message_raw::message_length)=$last_crlf->user1;} /*message_body*/ ;
jehan's avatar
jehan committed
132 133

status_line     
jehan's avatar
jehan committed
134
	:	  sip_version 
135 136
	   LWS status_code {belle_sip_response_set_status_code($response::current,atoi((char*)$status_code.text->chars));}
	   LWS reason_phrase {belle_sip_response_set_reason_phrase($response::current,(char*)$reason_phrase.text->chars);}
jehan's avatar
jehan committed
137
	   CRLF ;
jehan's avatar
jehan committed
138 139 140 141 142 143 144
	
status_code     
	: extension_code;

extension_code  
	:	  DIGIT DIGIT DIGIT;
reason_phrase   
145 146
	:	  ~(CRLF)*;
/*
jehan's avatar
jehan committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
utf8cont
	:
	;

utf8_non_ascii
	:
	;


	
accept         
	:	  'Accept' HCOLON ( accept_range (COMMA accept_range)* )?;
accept_range   
	:	  media_range (SEMI accept_param)*;
*/
//media_range    
//	:	  ( '*/*'
//                  | ( m_type SLASH '*' )
//                  | ( m_type SLASH m_subtype )
//                  ) ( SEMI m_parameter )* ;

//accept_param   
//	:	  ('q' EQUAL qvalue) | generic_param;
/*
qvalue         
	:	  ( '0' ( '.' DIGIT+)? )
                  | ( '1'( '.'DIGIT+)? );
*/
jehan's avatar
jehan committed
175
generic_param [belle_sip_parameters_t* object]  returns [belle_sip_param_pair_t* ret]
176 177
scope{int is_value;} 
@init { $generic_param::is_value=0; }
jehan's avatar
jehan committed
178
	:	   token (  equal gen_value {$generic_param::is_value = 1;} )? {
jehan's avatar
jehan committed
179 180
	                                                   if (object == NULL) {
	                                                     $ret=belle_sip_param_pair_new((const char*)($token.text->chars)
181
	                                                                                 ,$generic_param::is_value?(const char*)($gen_value.text->chars):NULL);
jehan's avatar
jehan committed
182 183 184
	                                                   } else {
	                                                     belle_sip_parameters_set_parameter(object
	                                                                                       ,(const char*)($token.text->chars)
185
	                                                                                       ,$generic_param::is_value?(const char*)($gen_value.text->chars):NULL);
jehan's avatar
jehan committed
186 187
	                                                     $ret=NULL;
	                                                   }
188
	                                                   };
jehan's avatar
jehan committed
189 190 191 192 193
gen_value      
	:	  token |  quoted_string;

quoted_string 
options { greedy = false; }
jehan's avatar
jehan committed
194
	: DQUOTE unquoted_value=(.*) DQUOTE ;
jehan's avatar
jehan committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220

/*
accept_encoding  
	:	  'Accept-Encoding' HCOLON ( encoding (COMMA encoding)* );
encoding         
	:	  codings (SEMI accept_param)*;
codings          
	:	  content_coding | '*';
content_coding   :  token;

accept_language  
	:	  'Accept-Language' HCOLON
                     ( language (COMMA language)* )?;
language         
	:	  language_range (SEMI accept_param)*;
language_range   
	:	  ( ( alpha alpha alpha alpha alpha alpha alpha alpha ( '-' alpha alpha alpha alpha alpha alpha alpha alpha )* ) | '*' );

alert_info   
	:	  'Alert-Info' HCOLON alert_param (COMMA alert_param)*;
	
alert_param  
	:	  LAQUOT absoluteURI RAQUOT ( SEMI generic_param )*;

absoluteURI    
	:	  token ':' token;
221
*/
jehan's avatar
jehan committed
222 223 224 225 226 227
header_allow returns [belle_sip_header_allow_t* ret]     
scope { belle_sip_header_allow_t* current; }
@init {$header_allow::current = belle_sip_header_allow_new(); $ret=$header_allow::current; }
    	
:	   {IS_TOKEN(Allow)}? token /*'Allow'*/ hcolon methods {belle_sip_header_allow_set_method($header_allow::current,(const char*)($methods.text->chars));} ;
methods : LWS? method (comma method)*;
228 229
authorization_token: {IS_TOKEN(Authorization)}? token;
digest_token: {IS_TOKEN(Digest)}? token;
jehan's avatar
jehan committed
230

231 232 233
header_authorization  returns [belle_sip_header_authorization_t* ret]     
scope { belle_sip_header_authorization_t* current; }
@init {$header_authorization::current = belle_sip_header_authorization_new(); $ret=$header_authorization::current; }
234 235
	:	  authorization_token /*'Authorization'*/ hcolon credentials[$header_authorization::current];
credentials  [belle_sip_header_authorization_t* header_authorization_base]     
jehan's avatar
jehan committed
236 237 238
	:	  (digest_token /*'Digest'*/ {belle_sip_header_authorization_set_scheme(header_authorization_base,"Digest");} 
	   LWS digest_response[header_authorization_base])
                     | other_response[header_authorization_base];
239 240 241 242
digest_response  [belle_sip_header_authorization_t* header_authorization_base]  
	:	  dig_resp[header_authorization_base] (comma dig_resp[header_authorization_base])*;
dig_resp  [belle_sip_header_authorization_t* header_authorization_base]         
	:	  username { belle_sip_header_authorization_set_username(header_authorization_base,$username.ret);
jehan's avatar
jehan committed
243 244
	               belle_sip_free($username.ret);
	             }
245
	| realm { belle_sip_header_authorization_set_realm(header_authorization_base,(char*)$realm.ret);
jehan's avatar
jehan committed
246 247
                 belle_sip_free($realm.ret);
           } 
248
	| nonce { belle_sip_header_authorization_set_nonce(header_authorization_base,(char*)$nonce.ret);
jehan's avatar
jehan committed
249 250
                 belle_sip_free($nonce.ret);
           }
251
	| digest_uri[header_authorization_base]
252
  | dresponse  { belle_sip_header_authorization_set_response(header_authorization_base,(char*)$dresponse.ret);
jehan's avatar
jehan committed
253 254
                 belle_sip_free($dresponse.ret);
               }
255
  | algorithm  {
256
                belle_sip_header_authorization_set_algorithm(header_authorization_base,(char*)$algorithm.ret);
jehan's avatar
jehan committed
257
               } 
258
  | cnonce{
259
            belle_sip_header_authorization_set_cnonce(header_authorization_base,(char*)$cnonce.ret);
260 261 262
            belle_sip_free($cnonce.ret);
           }
  | opaque {
263
            belle_sip_header_authorization_set_opaque(header_authorization_base,(char*)$opaque.ret);
264 265 266
            belle_sip_free($opaque.ret);
           }
  | message_qop{
jehan's avatar
jehan committed
267
            belle_sip_header_authorization_set_qop(header_authorization_base,$message_qop.ret);
268 269
           }
  | nonce_count{
270
            belle_sip_header_authorization_set_nonce_count(header_authorization_base,atoi((char*)$nonce_count.ret));
271 272 273
           } 
  | auth_param[header_authorization_base]
   ;
274
username_token: {IS_TOKEN(username)}? token;
jehan's avatar
jehan committed
275
username returns [char* ret]          
276
	:	  username_token /*'username'*/ equal username_value {
277
                      $ret = _belle_sip_str_dup_and_unquote_string((char*)$username_value.text->chars);
jehan's avatar
jehan committed
278 279
                       };

jehan's avatar
jehan committed
280
username_value    :  quoted_string;
281 282

uri_token: {IS_TOKEN(uri)}? token;
283
digest_uri [belle_sip_header_authorization_t* header_authorization_base]        
jehan's avatar
jehan committed
284
	:	  uri_token /*'uri'*/ equal DQUOTE uri DQUOTE  
285
	{belle_sip_header_authorization_set_uri(header_authorization_base,$uri.ret);
jehan's avatar
jehan committed
286 287
	 };
/*
jehan's avatar
jehan committed
288 289
digest_uri_value  :  rquest_uri ;
rquest_uri
290
	: uri;
jehan's avatar
jehan committed
291
*/	
jehan's avatar
jehan committed
292
// Equal to request-uri as specified by HTTP/1.1
293
message_qop  returns [const char* ret]     
jehan's avatar
jehan committed
294
	:	  {IS_TOKEN(qop)}? token/*'qop'*/ equal  qop_value {$ret = (const char*)$qop_value.text->chars;};
jehan's avatar
jehan committed
295 296

qop_value
jehan's avatar
jehan committed
297
	:  token;
jehan's avatar
jehan committed
298

299 300
cnonce returns [char* ret]            
	:	  {IS_TOKEN(cnonce)}? token /*'cnonce'*/ equal cnonce_value {
301
                                              $ret = _belle_sip_str_dup_and_unquote_string((char*)$cnonce_value.text->chars);
302
                                              };
jehan's avatar
jehan committed
303 304
cnonce_value      
	:	  nonce_value;
305
nonce_count returns [const char* ret]       
306
	:	  {IS_TOKEN(nc)}? token /*'nc'*/ equal nc_value {$ret=(char*)$nc_value.text->chars;};
jehan's avatar
jehan committed
307
nc_value          
308
	:	  huit_lhex; 
jehan's avatar
jehan committed
309 310
dresponse  returns [char* ret]       
	:	  {IS_TOKEN(response)}? token /*'response'*/ equal request_digest{
311
                      $ret = _belle_sip_str_dup_and_unquote_string((char*)$request_digest.text->chars);
jehan's avatar
jehan committed
312
                     };
jehan's avatar
jehan committed
313
request_digest    
jehan's avatar
jehan committed
314 315
	:	  quoted_string ;/*sp_laquot_sp huit_lhex huit_lhex huit_lhex huit_lhex sp_raquot_sp;
*/
jehan's avatar
jehan committed
316 317 318
huit_lhex
	: hexdigit+;

319
auth_param [belle_sip_header_authorization_t* header_authorization_base]        
320
	:	  auth_param_name equal
321
                     auth_param_value {belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(header_authorization_base)
322 323
                                                                         ,(char*)$auth_param_name.text->chars
                                                                         ,(char*)$auth_param_value.text->chars);
324 325 326
                                       }
          ;
auth_param_value : token | quoted_string ;          
jehan's avatar
jehan committed
327 328
auth_param_name   
	:	  token;
jehan's avatar
jehan committed
329 330 331 332 333
other_response [belle_sip_header_authorization_t* header_authorization_base]    
	:	  auth_scheme {belle_sip_header_authorization_set_scheme(header_authorization_base,(const char*)$auth_scheme.text->chars);} 
	   LWS auth_param[header_authorization_base]
                     (comma auth_param[header_authorization_base])*;

jehan's avatar
jehan committed
334 335
auth_scheme       
	:	  token;
jehan's avatar
jehan committed
336
/*
jehan's avatar
jehan committed
337 338 339 340 341 342 343 344
authentication_info  :  'Authentication-Info' HCOLON ainfo
                        (COMMA ainfo)*;
ainfo                
	:	  nextnonce | message_qop
                         | response_auth | cnonce
                         | nonce_count;
nextnonce            
	:	  'nextnonce' EQUAL nonce_value;
345
	*/
jehan's avatar
jehan committed
346
nonce_value         :  quoted_string;
347
/*
jehan's avatar
jehan committed
348 349 350 351
response_auth        
	:	  'rspauth' EQUAL response_digest;
response_digest      
	:	  LDQUOT hexdigit* RDQUOT;
352 353
*/
/*callid header*/
354
call_id_token: {IS_TOKEN(Call-ID)}? token;
jehan's avatar
jehan committed
355 356 357 358 359 360 361

header_call_id  returns [belle_sip_header_call_id_t* ret]     
scope { belle_sip_header_call_id_t* current; }
@init {$header_call_id::current = belle_sip_header_call_id_new(); $ret=$header_call_id::current; }
  :  call_id_token /*( 'Call-ID' | 'i' )*/ hcolon call_id;
call_id   
	:	  word ( '@' word )? {belle_sip_header_call_id_set_call_id($header_call_id::current,(const char*) $text->chars); };
362
/*
jehan's avatar
jehan committed
363 364 365 366 367 368 369 370
call_info   
	:	  'Call-Info' HCOLON info (COMMA info)*;
info        
	:	  LAQUOT absoluteURI RAQUOT ( SEMI info_param)*;
info_param  
	:	  ( 'purpose' EQUAL ( 'icon' | 'info'
               | 'card' | token ) ) | generic_param;
*/
jehan's avatar
jehan committed
371
/* contact header */
372
contact_token: {IS_TOKEN(Contact)}? token;
jehan's avatar
jehan committed
373 374

header_contact      returns [belle_sip_header_contact_t* ret]   
jehan's avatar
jehan committed
375 376
scope { belle_sip_header_contact_t* current; belle_sip_header_contact_t* first; }
@init { $header_contact::current =NULL; }
377
	:	  (contact_token /*'Contact'*/ /*| 'm'*/ ) hcolon
jehan's avatar
jehan committed
378 379 380 381 382 383 384 385
                  ( STAR  { $header_contact::current = belle_sip_header_contact_new();
                            belle_sip_header_contact_set_wildcard($header_contact::current,1);}
                  | (contact_param (comma contact_param)*)) {$ret = $header_contact::first; };
contact_param 
@init { if ($header_contact::current == NULL) {
            $header_contact::current = belle_sip_header_contact_new();
             $header_contact::first = $header_contact::current; 
         } else {
386 387
            belle_sip_header_set_next(BELLE_SIP_HEADER($header_contact::current),(belle_sip_header_t*)belle_sip_header_contact_new());
            $header_contact::current = (belle_sip_header_contact_t*)belle_sip_header_get_next(BELLE_SIP_HEADER($header_contact::current));
jehan's avatar
jehan committed
388 389
         } 
      }
jehan's avatar
jehan committed
390
	:	  (name_addr[BELLE_SIP_HEADER_ADDRESS($header_contact::current)] 
jehan's avatar
jehan committed
391
	   | addr_spec[BELLE_SIP_HEADER_ADDRESS($header_contact::current)]) (semi contact_params)*;
jehan's avatar
jehan committed
392 393 394 395
	   
name_addr[belle_sip_header_address_t* object]      
	:	  ( display_name[object] )? sp_laquot_sp addr_spec[object] sp_raquot_sp;
addr_spec[belle_sip_header_address_t* object]      
Simon Morlat's avatar
Simon Morlat committed
396
  :  uri {belle_sip_header_address_set_uri(object,$uri.ret);};//| absoluteURI;
jehan's avatar
jehan committed
397 398

display_name[belle_sip_header_address_t* object]   
399 400
  :  token {belle_sip_header_address_set_displayname(object,(const char*)($token.text->chars));}
     | quoted_string {belle_sip_header_address_set_quoted_displayname(object,(const char*)($quoted_string.text->chars));}
jehan's avatar
jehan committed
401
     ;
jehan's avatar
jehan committed
402 403 404 405 406 407 408 409 410

contact_params     
	:	  /*c_p_q | c_p_expires
                      |*/ contact_extension;
/*c_p_q              
	:	  'q' EQUAL qvalue;
c_p_expires        
	:	  'expires' EQUAL delta_seconds;*/
contact_extension  
jehan's avatar
jehan committed
411
	:	  generic_param [BELLE_SIP_PARAMETERS($header_contact::current)];
jehan's avatar
jehan committed
412

jehan's avatar
jehan committed
413
delta_seconds      
jehan's avatar
jehan committed
414
	:	  DIGIT+;
jehan's avatar
jehan committed
415
/*
jehan's avatar
jehan committed
416

jehan's avatar
jehan committed
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
content_disposition   
	:	  'Content-Disposition' HCOLON
                         disp_type ( SEMI disp_param )*;
disp_type             :  'render' | 'session' | 'icon' | 'alert'
                         | disp_extension_token;

disp_param            
	:	  handling_param | generic_param;
handling_param        
	:	  'handling' EQUAL
                         ( 'optional' | 'required'
                         | other_handling );
other_handling        
	:	  token;
disp_extension_token  
	:	  token;

content_encoding  
	:	  ( 'Content-Encoding' | 'e' ) HCOLON
                     content_coding (COMMA content_coding)*;

content_language  
	:	  'Content-Language' HCOLON
                     language_tag (COMMA language_tag)*;
language_tag      
	:	  primary_tag ( '-' subtag )*;
primary_tag       
	:	  huit_alpha;
subtag            
	:	  huit_alpha;

huit_alpha
	: alpha+;
	;
451
*/
452 453
/*content_length_token :  {strcmp("Content-Length",(const char*)(INPUT->toStringTT(INPUT,LT(1),LT(14)))->chars) == 0}? token;*/
content_length_token :  {IS_TOKEN(Content-Length)}? token;
jehan's avatar
jehan committed
454 455 456 457 458 459 460 461
header_content_length  returns [belle_sip_header_content_length_t* ret]     
scope { belle_sip_header_content_length_t* current; }
@init {$header_content_length::current = belle_sip_header_content_length_new(); $ret=$header_content_length::current; }
	:	 content_length_token /*( 'Content-Length' | 'l' )*/ 
	   hcolon 
	   content_length {belle_sip_header_content_length_set_content_length($header_content_length::current,atoi((const char*)$content_length.text->chars));};
content_length:DIGIT+;

462
content_type_token :  {IS_TOKEN(Content-Type)}? token;
463 464 465 466
header_content_type  returns [belle_sip_header_content_type_t* ret]   
scope { belle_sip_header_content_type_t* current;}
@init { $header_content_type::current = belle_sip_header_content_type_new();$ret=$header_content_type::current; }
	:	 content_type_token/* ( 'Content-Type' | 'c' )*/ hcolon media_type;
jehan's avatar
jehan committed
467
media_type       
jehan's avatar
jehan committed
468
	:	 m_type {belle_sip_header_content_type_set_type($header_content_type::current,(const char*)$m_type.text->chars);} 
469
	   slash 
jehan's avatar
jehan committed
470
	   m_subtype {belle_sip_header_content_type_set_subtype($header_content_type::current,(const char*)$m_subtype.text->chars);} 
jehan's avatar
jehan committed
471
	   (semi  generic_param [BELLE_SIP_PARAMETERS($header_content_type::current)])*;
jehan's avatar
jehan committed
472
m_type           
473
	:	token; /*  discrete_type | composite_type;
jehan's avatar
jehan committed
474 475 476 477 478 479 480 481 482 483
discrete_type    
	:	  'text' | 'image' | 'audio' | 'video'
                    | 'application' | extension_token;
composite_type   
	:	  'message' | 'multipart' | extension_token;
extension_token  
	:	  ietf_token | x_token;
ietf_token       
	:	  token;
x_token          
484 485
	:	  'x-' token;*/
m_subtype        : token ;/* extension_token | iana_token;
jehan's avatar
jehan committed
486 487 488 489 490 491 492 493
iana_token       
	:	  token;
m_parameter      
	:	  m_attribute EQUAL m_value;
m_attribute      
	:	  token;
m_value          
	:	  token | quoted_string;
494
*/
jehan's avatar
jehan committed
495

496
cseq_token :  {IS_TOKEN(CSeq)}? token;
497 498 499 500 501 502
header_cseq  returns [belle_sip_header_cseq_t* ret]   
scope { belle_sip_header_cseq_t* current; }
@init { $header_cseq::current = belle_sip_header_cseq_new();$ret = $header_cseq::current; }
  :	cseq_token
    hcolon 
    seq_number {belle_sip_header_cseq_set_seq_number($header_cseq::current,atoi((const char*)$seq_number.text->chars));} 
jehan's avatar
jehan committed
503
    LWS 
504 505 506
    method {belle_sip_header_cseq_set_method($header_cseq::current,(const char*)$method.text->chars);} ;
seq_number:DIGIT+;
/*
jehan's avatar
jehan committed
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
date          
	:	  'Date' HCOLON sip_date;
sip_date      
	:	token;//  rfc1123-date
//rfc1123-date  =  wkday "," SP date1 SP time SP "GMT"
//date1         =  2DIGIT SP month SP 4DIGIT
//                 ; day month year (e.g., 02 Jun 1982)
//time          =  2DIGIT ":" 2DIGIT ":" 2DIGIT
//                 ; 00:00:00 - 23:59:59
//wkday         =  "Mon" / "Tue" / "Wed"
//                 / "Thu" / "Fri" / "Sat" / "Sun"
//month         =  "Jan" / "Feb" / "Mar" / "Apr"
//                 / "May" / "Jun" / "Jul" / "Aug"
//                 / "Sep" / "Oct" / "Nov" / "Dec"

error_info  
	:	  'Error-Info' HCOLON error_uri (COMMA error_uri)*;

error_uri   
	:	  LAQUOT absoluteURI RAQUOT ( SEMI generic_param )*;
jehan's avatar
jehan committed
527
*/
jehan's avatar
jehan committed
528 529 530 531 532
header_expires returns [belle_sip_header_expires_t* ret]   
scope { belle_sip_header_expires_t* current; }
@init { $header_expires::current = belle_sip_header_expires_new();$ret = $header_expires::current; }     
	:	  {IS_TOKEN(Expires)}? token /*'Expires'*/ hcolon delta_seconds {belle_sip_header_expires_set_expires($header_expires::current,atoi((const char *)$delta_seconds.text->chars));};

533
from_token:  {IS_TOKEN(From)}? token;
534
header_from  returns [belle_sip_header_from_t* ret]   
jehan's avatar
jehan committed
535
scope { belle_sip_header_from_t* current; }
536
@init { $header_from::current = belle_sip_header_from_new();$ret = $header_from::current; }
jehan's avatar
jehan committed
537
        
538
	:	  from_token/* ( 'From' | 'f' )*/ hcolon from_spec ;
jehan's avatar
jehan committed
539
from_spec   
jehan's avatar
jehan committed
540
	:	  ( name_addr[BELLE_SIP_HEADER_ADDRESS($header_from::current)] | addr_spec[BELLE_SIP_HEADER_ADDRESS($header_from::current)] )
jehan's avatar
jehan committed
541 542
               ( SEMI from_param )*;
from_param  
jehan's avatar
jehan committed
543
	:	  /*tag_param |*/ generic_param [BELLE_SIP_PARAMETERS($header_from::current)];
jehan's avatar
jehan committed
544 545
                       
/*
jehan's avatar
jehan committed
546 547
tag_param   
	:	  'tag' EQUAL token;
jehan's avatar
jehan committed
548 549
*/
/*
jehan's avatar
jehan committed
550 551
in_reply_to  
	:	  'In-Reply-To' HCOLON callid (COMMA callid);
jehan's avatar
jehan committed
552 553 554 555 556 557 558 559
*/
header_max_forwards  returns [belle_sip_header_max_forwards_t* ret]   
scope { belle_sip_header_max_forwards_t* current; }
@init { $header_max_forwards::current = belle_sip_header_max_forwards_new();$ret = $header_max_forwards::current; } 
  :   {IS_TOKEN(Max-Forwards)}? token /*'Max-Forwards'*/ hcolon 
    max_forwards {belle_sip_header_max_forwards_set_max_forwards($header_max_forwards::current,atoi((const char*)$max_forwards.text->chars));};
max_forwards:DIGIT+;
/*
jehan's avatar
jehan committed
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
mime_version  
	:	  'MIME-Version' HCOLON DIGIT+ '.' DIGIT+;

min_expires  
	:	  'Min-Expires' HCOLON delta_seconds;

organization  
	:	  'Organization' HCOLON (text_utf8_trim)?;

text_utf8_trim
	:
	;

priority        
	:	  'Priority' HCOLON priority_value;
priority_value  
	:	  'emergency' | 'urgent' | 'normal'
                   | 'non-urgent' | other_priority;
other_priority  
	:	  token;
jehan's avatar
jehan committed
580
*/
jehan's avatar
jehan committed
581 582 583 584 585 586
header_proxy_authenticate   returns [belle_sip_header_proxy_authenticate_t* ret]   
scope { belle_sip_header_proxy_authenticate_t* current; }
@init { $header_proxy_authenticate::current = belle_sip_header_proxy_authenticate_new();$ret = $header_proxy_authenticate::current; } 
	:	  {IS_TOKEN(Proxy-Authenticate)}? token /*'Proxy-Authenticate'*/ 
	hcolon challenge[BELLE_SIP_HEADER_WWW_AUTHENTICATE($header_proxy_authenticate::current)];

jehan's avatar
jehan committed
587 588 589 590 591
challenge [belle_sip_header_www_authenticate_t* www_authenticate]           
	:	  ({IS_TOKEN(Digest)}? token /*'Digest'*/ {belle_sip_header_www_authenticate_set_scheme(www_authenticate,"Digest");} 
	   LWS digest_cln[www_authenticate] (comma digest_cln[www_authenticate])*)
                       | other_challenge [www_authenticate];
other_challenge [belle_sip_header_www_authenticate_t* www_authenticate]    
592
	:	  auth_scheme {belle_sip_header_www_authenticate_set_scheme(www_authenticate,(char*)$auth_scheme.text->chars);} 
jehan's avatar
jehan committed
593 594 595 596
	   LWS auth_param[NULL]
                       (comma auth_param[NULL])*;
digest_cln [belle_sip_header_www_authenticate_t* www_authenticate]         
	:	
597
  | realm {belle_sip_header_www_authenticate_set_realm(www_authenticate,(char*)$realm.ret);
jehan's avatar
jehan committed
598
           belle_sip_free($realm.ret);} 
599
  | nonce {belle_sip_header_www_authenticate_set_nonce(www_authenticate,(char*)$nonce.ret);
jehan's avatar
jehan committed
600 601 602 603 604
           belle_sip_free($nonce.ret);}
  | algorithm {belle_sip_header_www_authenticate_set_algorithm(www_authenticate,$algorithm.ret);} 
  | opaque  {belle_sip_header_www_authenticate_set_opaque(www_authenticate,$opaque.ret);
             belle_sip_free($opaque.ret);}
  | qop_opts {belle_sip_header_www_authenticate_set_qop(www_authenticate,$qop_opts.ret);
jehan's avatar
jehan committed
605
              /*belle_sip_free($qop_opts.ret);*/}
jehan's avatar
jehan committed
606 607 608 609 610 611
	| domain {belle_sip_header_www_authenticate_set_domain(www_authenticate,$domain.ret);
             belle_sip_free($domain.ret);} 
	| stale { if (strcmp("true",$stale.ret)==0) {
	             belle_sip_header_www_authenticate_set_stale(www_authenticate,1);
	           }
	        }
612 613
     | auth_param[(belle_sip_header_authorization_t*)www_authenticate];
/* the cast above is very BAD, but auth_param works on fields common to the two structures*/
jehan's avatar
jehan committed
614

jehan's avatar
jehan committed
615 616
realm returns [char* ret]              
	:	  {IS_TOKEN(realm)}? token /*'realm'*/ equal realm_value {
617
	                    $ret = _belle_sip_str_dup_and_unquote_string((char*)$realm_value.text->chars);
jehan's avatar
jehan committed
618
	                     };
jehan's avatar
jehan committed
619
realm_value         
jehan's avatar
jehan committed
620
	:	  quoted_string ;
jehan's avatar
jehan committed
621 622 623

domain returns [char* ret]              
	:	  {IS_TOKEN(domain)}? token /*'domain'*/ equal quoted_string {
624
                      $ret = _belle_sip_str_dup_and_unquote_string((char*)$quoted_string.text->chars);};
jehan's avatar
jehan committed
625
	/* LDQUOT uri
jehan's avatar
jehan committed
626 627 628
                       ( SP+ uri )* RDQUOT;
uri                 
	:	  absoluteURI | '/'.;
jehan's avatar
jehan committed
629 630 631
*/
nonce  returns [char* ret]             
	:	  {IS_TOKEN(nonce)}? token /*'nonce'*/ equal nonce_value{
632
                      $ret = _belle_sip_str_dup_and_unquote_string((char*)$nonce_value.text->chars);
jehan's avatar
jehan committed
633
                       };
634 635
opaque returns [char* ret]             
  :   {IS_TOKEN(opaque)}? token /*'opaque'*/ equal quoted_string{
636
                      $ret = _belle_sip_str_dup_and_unquote_string((char*)$quoted_string.text->chars);
637
                       };
jehan's avatar
jehan committed
638 639

stale  returns [const char* ret]             
640
	:	  {IS_TOKEN(stale)}? token /*'stale'*/ equal stale_value {$ret=(char*)$stale_value.text->chars;} /* ( 'true' | 'false' )*/;
jehan's avatar
jehan committed
641 642 643

stale_value:token;

jehan's avatar
jehan committed
644
algorithm returns [const char* ret]           
645
	:	  {IS_TOKEN(algorithm)}? token /*'algorithm'*/ equal /* ( 'MD5' | 'MD5-sess'
646
                       |*/ alg_value=token {$ret=(char*)$alg_value.text->chars;}/*)*/
jehan's avatar
jehan committed
647
  ;
jehan's avatar
jehan committed
648

jehan's avatar
jehan committed
649 650 651 652 653 654 655 656 657 658
qop_opts returns [belle_sip_list_t* ret]        
scope { belle_sip_list_t* list; }
@init{$qop_opts::list=NULL;}
	:	  {IS_TOKEN(qop)}? token /*'qop'*/ equal 
	ldquot 
	qop_opts_value 
  (COMMA qop_opts_value)* 
  rdquot {$ret=$qop_opts::list;} ;
  
qop_opts_value 	
jehan's avatar
jehan committed
659
: token {$qop_opts::list=belle_sip_list_append($qop_opts::list,belle_sip_strdup((const char*)$token.text->chars));};
jehan's avatar
jehan committed
660

661 662 663
header_proxy_authorization  returns [belle_sip_header_proxy_authorization_t* ret]
scope { belle_sip_header_proxy_authorization_t* current; }
@init { $header_proxy_authorization::current = belle_sip_header_proxy_authorization_new();$ret = $header_proxy_authorization::current; }
664
	:	  {IS_TOKEN(Proxy-Authorization)}? token /*'Proxy-Authorization'*/ hcolon credentials[(belle_sip_header_authorization_t*)$header_proxy_authorization::current];
665
/*
jehan's avatar
jehan committed
666 667 668 669 670
proxy_require  
	:	  'Proxy-Require' HCOLON option_tag
                  (COMMA option_tag)*;
option_tag     
	:	  token;
jehan's avatar
jehan committed
671
*/
672
record_route_token:  {IS_TOKEN(Record-Route)}? token;
jehan's avatar
jehan committed
673
header_record_route  returns [belle_sip_header_record_route_t* ret]   
jehan's avatar
jehan committed
674 675 676 677 678 679 680 681
scope { belle_sip_header_record_route_t* current; belle_sip_header_record_route_t* first;}
@init { $header_record_route::current = NULL;}
	:	  record_route_token /*'Record-Route'*/ hcolon rec_route (comma rec_route)* {$ret = $header_record_route::first;};
rec_route
@init { if ($header_record_route::current == NULL) {
            $header_record_route::first = $header_record_route::current = belle_sip_header_record_route_new();
         } else {
            belle_sip_header_t* header = BELLE_SIP_HEADER($header_record_route::current); 
682
            belle_sip_header_set_next(header,(belle_sip_header_t*)($header_record_route::current = belle_sip_header_record_route_new()));
jehan's avatar
jehan committed
683 684
         } 
      }     
jehan's avatar
jehan committed
685
	:	  name_addr[BELLE_SIP_HEADER_ADDRESS($header_record_route::current)] ( semi rr_param )*;
jehan's avatar
jehan committed
686
rr_param      
jehan's avatar
jehan committed
687 688
	:	  generic_param[BELLE_SIP_PARAMETERS($header_record_route::current)];
/*
jehan's avatar
jehan committed
689 690 691 692 693 694 695 696 697 698 699 700 701
reply_to      
	:	  'Reply-To' HCOLON rplyto_spec;
rplyto_spec   
	:	  ( name_addr | addr_spec )
                 ( SEMI rplyto_param )*;
rplyto_param  
	:	  generic_param;
require       
	:	  'Require' HCOLON option_tag (COMMA option_tag)*;

retry_after  
	:	  'Retry-After' HCOLON delta_seconds
                 comment? ( SEMI retry_param )*;
jehan's avatar
jehan committed
702
*/
jehan's avatar
jehan committed
703
comment	: '(' . ')';
jehan's avatar
jehan committed
704 705
	
/*
jehan's avatar
jehan committed
706 707 708
retry_param  
	:	  ('duration' EQUAL delta_seconds)
                | generic_param;
jehan's avatar
jehan committed
709
*/
710
route_token:  {IS_TOKEN(Route)}? token;
jehan's avatar
jehan committed
711
header_route  returns [belle_sip_header_route_t* ret]   
jehan's avatar
jehan committed
712 713 714 715 716 717 718 719
scope { belle_sip_header_route_t* current;belle_sip_header_route_t* first; }
@init { $header_route::current = NULL; }
  :   route_token /*'Route'*/ hcolon route_param (comma route_param)*{$ret = $header_route::first;};
route_param 
@init { if ($header_route::current == NULL) {
            $header_route::first = $header_route::current = belle_sip_header_route_new();
         } else {
            belle_sip_header_t* header = BELLE_SIP_HEADER($header_route::current); 
720
            belle_sip_header_set_next(header,(belle_sip_header_t*)($header_route::current = belle_sip_header_route_new()));
jehan's avatar
jehan committed
721 722
         } 
      }      
jehan's avatar
jehan committed
723
  :   name_addr[BELLE_SIP_HEADER_ADDRESS($header_route::current)] ( semi r_param )*;
jehan's avatar
jehan committed
724 725 726
r_param      
  :   generic_param[BELLE_SIP_PARAMETERS($header_route::current)];
/*
jehan's avatar
jehan committed
727 728
server           
	:	  'Server' HCOLON server_val (LWS server_val)*;
jehan's avatar
jehan committed
729
*/
jehan's avatar
jehan committed
730

jehan's avatar
jehan committed
731
/*
jehan's avatar
jehan committed
732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747
subject  
	:	  ( 'Subject' | 's' ) HCOLON (text_utf_huit)?;

text_utf_huit
	:
	;

supported  
	:	  ( 'Supported' | 'k' ) HCOLON
              (option_tag (COMMA option_tag)*)?;

timestamp  
	:	  'Timestamp' HCOLON (DIGIT)+
               ( '.' (DIGIT)* )? ( LWS delay )?;
delay      
	:	  (DIGIT)* ( '.' (DIGIT)* )?;
jehan's avatar
jehan committed
748
*/
749
to_token:  {IS_TOKEN(To)}? token;
jehan's avatar
jehan committed
750 751 752 753
header_to  returns [belle_sip_header_to_t* ret]   
scope { belle_sip_header_to_t* current; }
@init { $header_to::current = belle_sip_header_to_new(); }
        
jehan's avatar
jehan committed
754
  :   to_token /*'To' ( 'To' | 't' )*/ hcolon to_spec {$ret = $header_to::current;};
jehan's avatar
jehan committed
755 756
to_spec   
  :   ( name_addr[BELLE_SIP_HEADER_ADDRESS($header_to::current)] | addr_spec[BELLE_SIP_HEADER_ADDRESS($header_to::current)] )
jehan's avatar
jehan committed
757
               ( semi to_param )*;
jehan's avatar
jehan committed
758
to_param  
jehan's avatar
jehan committed
759 760
  :   /*tag_param |*/ generic_param [BELLE_SIP_PARAMETERS($header_to::current)];
/*
jehan's avatar
jehan committed
761 762
unsupported  
	:	  'Unsupported' HCOLON option_tag (COMMA option_tag)*;
jehan's avatar
jehan committed
763
*/
jehan's avatar
jehan committed
764 765 766 767 768 769 770 771 772 773 774 775 776
header_user_agent  returns [belle_sip_header_user_agent_t* ret]   
scope { belle_sip_header_user_agent_t* current; }
@init { $header_user_agent::current = belle_sip_header_user_agent_new();$ret = $header_user_agent::current;}
	:	  {IS_TOKEN(User-Agent)}? token /*'User-Agent'*/ hcolon server_val (LWS server_val)*;

server_val    : word {belle_sip_header_user_agent_add_product($header_user_agent::current,(const char*)$word.text->chars); };
serval_item    
  :   product | comment  ;
product          
  :   token (SLASH product_version)?;
product_version  
  :   token;
  
777
via_token:  {IS_TOKEN(Via)}? token;
jehan's avatar
jehan committed
778
header_via  returns [belle_sip_header_via_t* ret]   
jehan's avatar
jehan committed
779 780
scope { belle_sip_header_via_t* current; belle_sip_header_via_t* first; }
@init { $header_via::current = NULL;}
jehan's avatar
jehan committed
781
        
jehan's avatar
jehan committed
782 783 784 785 786 787 788
  :   via_token/* ( 'via' | 'v' )*/ hcolon via_parm (comma via_parm)* {$ret = $header_via::first;};

via_parm
@init { if ($header_via::current == NULL) {
            $header_via::first = $header_via::current = belle_sip_header_via_new();
         } else {
            belle_sip_header_t* header = BELLE_SIP_HEADER($header_via::current); 
789
            belle_sip_header_set_next(header,(belle_sip_header_t*)($header_via::current = belle_sip_header_via_new()));
jehan's avatar
jehan committed
790 791
         } 
      }          
jehan's avatar
jehan committed
792
	:	  sent_protocol  LWS sent_by ( semi via_params )*;
jehan's avatar
jehan committed
793
via_params        
jehan's avatar
jehan committed
794
	:	  /*via_ttl | via_maddr
jehan's avatar
jehan committed
795
                     | via_received | via_branch
jehan's avatar
jehan committed
796 797
                     | via_extension */ generic_param [BELLE_SIP_PARAMETERS($header_via::current)];
/*via_ttl           
jehan's avatar
jehan committed
798 799 800 801 802 803 804 805
	:	  'ttl' EQUAL ttl;
via_maddr         
	:	  'maddr' EQUAL host;
via_received      
	:	  'received' EQUAL (ipv4address | ipv6address);
via_branch        
	:	  'branch' EQUAL token;
via_extension     
jehan's avatar
jehan committed
806
	:	  generic_param;*/
jehan's avatar
jehan committed
807
sent_protocol     
jehan's avatar
jehan committed
808 809
	:	  (protocol_name slash protocol_version) {belle_sip_header_via_set_protocol($header_via::current,(const char*)$text->chars);}
                     slash transport {belle_sip_header_via_set_transport($header_via::current,(const char*)$transport.text->chars);} ;
jehan's avatar
jehan committed
810
protocol_name     
jehan's avatar
jehan committed
811
	:	  /*'SIP' |*/ token;
jehan's avatar
jehan committed
812 813 814
protocol_version  
	:	  token;
transport         
jehan's avatar
jehan committed
815 816
	:	 /* 'UDP' | 'TCP' | 'TLS' | 'SCTP'
                     | */ other_transport;
jehan's avatar
jehan committed
817 818 819 820
other_transport
	: token;

sent_by           
821 822
	:	  host {belle_sip_header_via_set_host($header_via::current,(const char*)$host.text->chars);}
	   ( COLON port {belle_sip_header_via_set_port($header_via::current,$port.ret);} )? ;
jehan's avatar
jehan committed
823
/*
jehan's avatar
jehan committed
824 825 826 827 828 829 830 831 832 833 834 835 836 837
warning        
	:	  'Warning' HCOLON warning_value (COMMA warning_value)*;
warning_value  
	:	  warn_code SP warn_agent SP warn_text;
warn_code      
	:	  DIGIT DIGIT DIGIT;
warn_agent     
	:	  hostport | pseudonym;
                  //  the name or pseudonym of the server adding
                  //  the Warning header, for use in debugging
warn_text      
	:	  quoted_string;
pseudonym      
	:	  token;
jehan's avatar
jehan committed
838
*/
jehan's avatar
jehan committed
839 840 841 842 843
header_www_authenticate returns [belle_sip_header_www_authenticate_t* ret]   
scope { belle_sip_header_www_authenticate_t* current; }
@init { $header_www_authenticate::current = belle_sip_header_www_authenticate_new();$ret = $header_www_authenticate::current; } 
	:	  {IS_TOKEN(WWW-Authenticate)}? token /*'WWW-Authenticate'*/ hcolon challenge[$header_www_authenticate::current];

jehan's avatar
jehan committed
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
header_extension[ANTLR3_BOOLEAN check_for_known_header]  returns [belle_sip_header_t* ret]
	:	   header_name 
	     hcolon 
	     header_value {if (check_for_known_header && strcmp("Contact",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_contact_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("From",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_from_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("To",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_to_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Call-ID",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_call_id_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Content-Length",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_content_length_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Content-Type",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_content_type_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("CSeq",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_cseq_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Route",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_route_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Record-Route",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_record_route_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Via",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_via_parse((const char*)$header_extension.text->chars));
jehan's avatar
jehan committed
867 868 869 870 871 872
                    } else if (check_for_known_header && strcmp("Authorization",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_authorization_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Proxy-Authorization",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_proxy_authorization_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("WWW-Authenticate",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_www_authenticate_parse((const char*)$header_extension.text->chars));
jehan's avatar
jehan committed
873 874
                    } else if (check_for_known_header && strcmp("Max-Forwards",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_max_forwards_parse((const char*)$header_extension.text->chars));
jehan's avatar
jehan committed
875 876 877 878 879 880
                    } else if (check_for_known_header && strcmp("User-Agent",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_user_agent_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Expires",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_expires_parse((const char*)$header_extension.text->chars));
                    } else if (check_for_known_header && strcmp("Allow",(const char*)$header_name.text->chars) == 0) {
                     $ret = BELLE_SIP_HEADER(belle_sip_header_allow_parse((const char*)$header_extension.text->chars));
jehan's avatar
jehan committed
881
                    }else {
jehan's avatar
jehan committed
882
                      $ret =  BELLE_SIP_HEADER(belle_sip_header_extension_new());
883
                      belle_sip_header_extension_set_value((belle_sip_header_extension_t*)$ret,(const char*)$header_value.text->chars);
jehan's avatar
jehan committed
884 885 886
                      belle_sip_header_set_name($ret,(const char*)$header_name.text->chars);
                     }
                   } ;
jehan's avatar
jehan committed
887 888
header_name       
	:	  token;
jehan's avatar
jehan committed
889

jehan's avatar
jehan committed
890
header_value      
jehan's avatar
jehan committed
891
	:	  ~(CRLF)* ;
jehan's avatar
jehan committed
892 893 894 895 896
	
message_body
options { greedy = false; }  
	:	  OCTET+;

jehan's avatar
jehan committed
897 898 899 900
uri  returns [belle_sip_uri_t* ret]    
scope { belle_sip_uri_t* current; }
@init { $uri::current = belle_sip_uri_new(); }
   :  sip_schema ((userinfo hostport) | hostport ) uri_parameters? headers? {$ret = $uri::current;}; 
901 902
sip_token:  {IS_TOKEN(sip)}? token;
sips_token:  {IS_TOKEN(sips)}? token;
jehan's avatar
jehan committed
903 904 905

sip_schema : (sips_token {belle_sip_uri_set_secure($uri::current,1);}
            | sip_token) COLON ;
jehan's avatar
jehan committed
906 907 908 909
userinfo        :	user ( COLON password )? '@' ;
user            :	  ( unreserved  | escaped | user_unreserved )+ {belle_sip_uri_set_user($uri::current,(const char *)$text->chars);};
user_unreserved :  '&' | EQUAL | '+' | '$' | COMMA | SEMI | '?' | SLASH;
password        :	  ( unreserved  |'&' | EQUAL | '+' | '$' | COMMA )*;
910
hostport        :	  host ( COLON port {belle_sip_uri_set_port($uri::current,$port.ret);})? {belle_sip_uri_set_host($uri::current,(const char *)$host.text->chars);};
jehan's avatar
jehan committed
911 912 913 914 915 916 917 918 919 920 921 922 923
host            :	  (hostname | ipv4address | ipv6reference) ;
hostname        :	  ( domainlabel '.' )* toplabel '.'? ;
	
domainlabel     :	  alphanum | (alphanum ( alphanum | '-' )* alphanum) ;
toplabel        :	  alpha | (alpha ( alphanum | '-' )* alphanum) ;

ipv4address    :  three_digit '.' three_digit '.' three_digit '.' three_digit;
ipv6reference  :  '[' ipv6address ']';
ipv6address    :  hexpart ( COLON ipv4address )?;
hexpart        :  hexseq | hexseq '::' ( hexseq )? | '::' ( hexseq )?;
hexseq         :  hex4 ( COLON hex4)*;
hex4           :  hexdigit hexdigit hexdigit hexdigit ;

924
port	returns [int ret]:	DIGIT+ { $ret=atoi((const char *)$text->chars); };
jehan's avatar
jehan committed
925 926 927


uri_parameters    
jehan's avatar
jehan committed
928
	:	  ( semi uri_parameter )+;
jehan's avatar
jehan committed
929 930
uri_parameter  //all parameters are considered as other     
	:	   other_param ;
jehan's avatar
jehan committed
931 932 933 934 935 936 937 938 939 940 941
other_param       
:  pname {    belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS($uri::current)
                                      ,(const char *)$pname.text->chars
                                      ,NULL);}
  |
   (pname EQUAL pvalue)  {
    belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS($uri::current)
                                      ,(const char *)$pname.text->chars
                                      ,(const char *)$pvalue.text->chars);}
   ;

jehan's avatar
jehan committed
942 943 944 945 946 947 948
pname             
	:	  paramchar+;
pvalue            
	:	  paramchar+;
paramchar         
	:	  param_unreserved | unreserved | escaped; 
param_unreserved  
jehan's avatar
jehan committed
949
	:	  '[' | ']' | SLASH | COLON | '&' | PLUS | '$' | '.';
jehan's avatar
jehan committed
950 951 952 953 954 955 956

headers         :  '?' header ( '&' header )* ;
header          :  hname EQUAL hvalue? {belle_sip_uri_set_header($uri::current,(const char *)$hname.text->chars,(const char *)$hvalue.text->chars);};
hname           :  ( hnv_unreserved | unreserved | escaped )+;
hvalue          :  ( hnv_unreserved | unreserved | escaped )+;


jehan's avatar
jehan committed
957
hnv_unreserved  :  '[' | ']' | '|' | '?' | COLON | PLUS | '$' ;
jehan's avatar
jehan committed
958 959 960 961
escaped     :  '%' hexdigit hexdigit;
ttl : three_digit;
three_digit: DIGIT | (DIGIT DIGIT) | (DIGIT DIGIT DIGIT) ;	
token       
jehan's avatar
jehan committed
962
	:	  (alphanum | mark | '%' | PLUS | '`'  )+;
jehan's avatar
jehan committed
963 964

reserved    
jehan's avatar
jehan committed
965
	:	  SEMI | SLASH | '?' | COLON | '@' | '&' | EQUAL | PLUS
jehan's avatar
jehan committed
966 967 968 969 970 971 972 973 974
                     | '$' | COMMA;
                     
unreserved :	  alphanum |mark;  
alphanum :	   alpha | DIGIT ;                      
hexdigit 
	:	HEX_CHAR|DIGIT; 
alpha	: HEX_CHAR | COMMON_CHAR; 
 
word        
jehan's avatar
jehan committed
975 976
	:	  (alphanum | mark   | '%'  
                      | PLUS | '`' |
jehan's avatar
jehan committed
977 978 979 980 981 982 983 984 985 986 987 988
                     LPAREN | RPAREN | LAQUOT | RAQUOT |
                     COLON | '\\' | DQUOTE | SLASH | '[' | ']' | '?' | '{' | '}' )+;
                 

COMMON_CHAR
	:	'g'..'z' | 'G'..'Z' ;	
mark	:	         '-' | '_' | '.' | '!' | '~' | STAR | '\'' ; 


HEX_CHAR:	'a'..'f' |'A'..'F';
DIGIT	: '0'..'9' ;

989
CRLF	: '\r\n' { USER1 = (int)(ctx->pLexer->input->currentLine - ctx->pLexer->input->data); /*GETCHARINDEX()*/;};
jehan's avatar
jehan committed
990 991 992 993 994





jehan's avatar
jehan committed
995 996
hcolon	: ( LWS | HTAB )* COLON  LWS? //SWS;
	       ;//|( SP | HTAB )* COLON LWS+;
jehan's avatar
jehan committed
997 998 999 1000 1001 1002 1003
HTAB	: '	';




  
 
jehan's avatar
jehan committed
1004 1005
ldquot  :  LWS? DQUOTE ;
rdquot : DQUOTE LWS?;
jehan's avatar
jehan committed
1006 1007 1008

DQUOTE	: '"';
// open double quotation mark
jehan's avatar
jehan committed
1009
//SWS   :   LWS? ; 
jehan's avatar
jehan committed
1010 1011


jehan's avatar
jehan committed
1012
LWS  	:	(SP* CRLF)? SP+ ; //linear whitespace
jehan's avatar
jehan committed
1013 1014 1015 1016 1017





jehan's avatar
jehan committed
1018 1019 1020
PLUS: '+';


jehan's avatar
jehan committed
1021 1022 1023
COLON
	:	':'
	;
jehan's avatar
jehan committed
1024 1025
semi: LWS? SEMI LWS?;

jehan's avatar
jehan committed
1026 1027 1028 1029
SEMI
	:	';'
	;

1030
comma : LWS? COMMA LWS?;
jehan's avatar
jehan committed
1031 1032 1033 1034 1035
COMMA
	:	','
	;

sp_laquot_sp
jehan's avatar
jehan committed
1036
	:	LWS? LAQUOT LWS?;
jehan's avatar
jehan committed
1037
sp_raquot_sp
jehan's avatar
jehan committed
1038
	:	LWS? RAQUOT LWS?;
jehan's avatar
jehan committed
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
LAQUOT
	:	'<'
	;

RAQUOT
	:	'>'
	;

RPAREN
	:	')'
	;

LPAREN
	:	'('
	;

jehan's avatar
jehan committed
1055 1056
equal:
   LWS? EQUAL LWS?;
jehan's avatar
jehan committed
1057 1058 1059 1060
EQUAL
	:	'='
	;

jehan's avatar
jehan committed
1061
slash : LWS? SLASH LWS?;
jehan's avatar
jehan committed
1062 1063 1064 1065 1066 1067 1068
SLASH
	:	'/'
	;

STAR
	:	'*'
	;
jehan's avatar
jehan committed
1069
fragment 
jehan's avatar
jehan committed
1070 1071 1072
SP
	:	' '
	;
1073
OCTET	: . ;