belle_sdp.g 24.4 KB
Newer Older
jehan's avatar
jehan committed
1
/*
jehan's avatar
jehan committed
2
    belle-sdp - SDP (RFC4566) library.
jehan's avatar
jehan committed
3 4 5 6
    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
7
    the Free Software Foundation, either version 2 of the License, or
jehan's avatar
jehan committed
8 9 10 11 12 13 14 15 16 17 18
    (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_sdp;
19 20 21


options {
jehan's avatar
jehan committed
22
	language = C;
jehan's avatar
jehan committed
23
	output=AST;
24 25

}
26
@lexer::header {
jehan's avatar
jehan committed
27 28 29 30 31 32
/*
    belle-sip - SIP (RFC3261) library.
    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
33
    the Free Software Foundation, either version 2 of the License, or
jehan's avatar
jehan committed
34 35 36 37 38 39 40 41 42 43
    (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/>.
*/
44 45 46

#pragma GCC diagnostic ignored "-Wparentheses"
#pragma GCC diagnostic ignored "-Wunused"
jehan's avatar
jehan committed
47
#ifdef __clang__
48
#pragma GCC diagnostic ignored "-Wtautological-compare"
jehan's avatar
jehan committed
49 50
#endif
#ifndef __clang__
51
#pragma GCC diagnostic ignored "-Wunused-variable"
jehan's avatar
jehan committed
52
#endif
53 54 55 56 57 58 59 60
}
@parser::header {
/*
    belle-sip - SIP (RFC3261) library.
    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
jehan's avatar
jehan committed
61
    the Free Software Foundation, either version 2 of the License, or
62 63 64 65 66 67 68 69 70 71 72 73 74
    (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/>.
*/

#pragma GCC diagnostic ignored "-Wparentheses"
#pragma GCC diagnostic ignored "-Wunused"
jehan's avatar
jehan committed
75
#ifndef __clang__
76 77 78
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-function"
jehan's avatar
jehan committed
79
#endif
jehan's avatar
jehan committed
80
}
jehan's avatar
jehan committed
81

82
@rulecatch
83 84 85 86 87 88 89 90 91 92
{
    if (HASEXCEPTION())
    {

    // This is ugly.  We set the exception type to ANTLR3_RECOGNITION_EXCEPTION so we can always
    // catch them.
    //PREPORTERROR();
    EXCEPTION->type = ANTLR3_RECOGNITION_EXCEPTION;
    }
}
jehan's avatar
jehan committed
93

94

95
@includes {
Simon Morlat's avatar
Simon Morlat committed
96 97
#include "belle-sip/defs.h"
#include "belle-sip/types.h"
jehan's avatar
jehan committed
98
#include "belle-sip/belle-sdp.h"
99
#include "parserutils.h"
jehan's avatar
jehan committed
100 101
}

102
session_description returns [belle_sdp_session_description_t* ret]
jehan's avatar
jehan committed
103 104 105
scope { belle_sdp_session_description_t* current; }
@init {$session_description::current = belle_sdp_session_description_new(); $ret=$session_description::current; }
                    :    version CR LF
106 107
                         origin {belle_sdp_session_description_set_origin($session_description::current,$origin.ret);}CR LF
                         session_name CR LF
108
                         (info CR LF)?
109
                         (uri_field CR LF)?
110
                         (email CR LF)*
jehan's avatar
jehan committed
111
                         phone_field*
112 113 114
                         (connection {belle_sdp_session_description_set_connection($session_description::current,$connection.ret);} CR LF)?
                         (bandwidth {belle_sdp_session_description_add_bandwidth($session_description::current,$bandwidth.ret);} CR LF)*
                         time_field CR LF
115
                         (repeat_time CR LF)*
116 117
                         (zone_adjustments CR LF)?
                         (key_field CR LF)?
118 119
                         (attribute {belle_sdp_session_description_add_attribute($session_description::current,$attribute.ret);} CR LF)*
                         (media_description {belle_sdp_session_description_add_media_description($session_description::current,$media_description.ret);}) *;
jehan's avatar
jehan committed
120

jehan's avatar
jehan committed
121 122
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
123
	ANTLR3_LOG_EXCEPTION();
jehan's avatar
jehan committed
124 125
   belle_sip_object_unref($session_description::current);
   $ret=NULL;
126
}
jehan's avatar
jehan committed
127

jehan's avatar
jehan committed
128 129 130
version:       {IS_TOKEN(v)}?alpha_num EQUAL v=DIGIT+  {belle_sdp_version_t* version =belle_sdp_version_new();
                                                        belle_sdp_version_set_version(version,atoi((const char*)$v.text->chars));
                                                        belle_sdp_session_description_set_version($session_description::current,version);};
jehan's avatar
jehan committed
131 132
                       //  ;this memo describes version 0

133 134

origin returns [belle_sdp_origin_t* ret]
jehan's avatar
jehan committed
135 136
scope { belle_sdp_origin_t* current; }
@init {$origin::current = belle_sdp_origin_new(); $ret=$origin::current; }
137
:        {IS_TOKEN(o)}?alpha_num EQUAL username {belle_sdp_origin_set_username($origin::current,(const char*)$username.text->chars);}
138 139
                         SPACE sess_id {if ($sess_id.text->chars) belle_sdp_origin_set_session_id($origin::current,strtoul((const char*)$sess_id.text->chars,NULL,10));}
                         SPACE sess_version {if ($sess_version.text->chars) belle_sdp_origin_set_session_version($origin::current,strtoul((const char*)$sess_version.text->chars,NULL,10));}
140 141
                         SPACE nettype {belle_sdp_origin_set_network_type($origin::current,(const char*)$nettype.text->chars);}
                         SPACE addrtype  {belle_sdp_origin_set_address_type($origin::current,(const char*)$addrtype.text->chars);}
142
                         SPACE addr {belle_sdp_origin_set_address($origin::current,(const char*)$addr.text->chars);} ;
jehan's avatar
jehan committed
143

jehan's avatar
jehan committed
144 145
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
146
	ANTLR3_LOG_EXCEPTION();
jehan's avatar
jehan committed
147 148
   belle_sip_object_unref($origin::current);
   $ret=NULL;
149
}
jehan's avatar
jehan committed
150

151 152 153
session_name:  {IS_TOKEN(s)}? alpha_num EQUAL text {belle_sdp_session_name_t* session_name =belle_sdp_session_name_new();
                                                        belle_sdp_session_name_set_value(session_name,(const char*)$text.text->chars);
                                                        belle_sdp_session_description_set_session_name($session_description::current,session_name);};
jehan's avatar
jehan committed
154

155
info returns [belle_sdp_info_t* ret]
156 157 158 159 160
scope { belle_sdp_info_t* current; }
@init {$info::current = belle_sdp_info_new(); $ret=$info::current; }
:   {IS_TOKEN(i)}? alpha_num EQUAL info_value {belle_sdp_info_set_value($info::current,(const char*) $info_value.text->chars);} ;

info_value            options { greedy = false; }:        ~(CR|LF)*;
jehan's avatar
jehan committed
161

162
uri_field:           {IS_TOKEN(u)}?alpha_num EQUAL uri ;
jehan's avatar
jehan committed
163

164
email returns [belle_sdp_email_t* ret]
165 166 167
scope { belle_sdp_email_t* current; }
@init {$email::current = belle_sdp_email_new(); $ret=$email::current; }
  :        {IS_TOKEN(e)}?alpha_num EQUAL email_address {belle_sdp_email_set_value($email::current,(const char*)$email_address.text->chars);};
jehan's avatar
jehan committed
168 169 170

phone_field:        {IS_TOKEN(p)}?alpha_num EQUAL phone_number CR LF;

171
connection returns [belle_sdp_connection_t* ret]
jehan's avatar
jehan committed
172 173
scope { belle_sdp_connection_t* current; }
@init {$connection::current = belle_sdp_connection_new(); $ret=$connection::current; }
174 175 176
:    {IS_TOKEN(c)}?alpha_num EQUAL nettype { belle_sdp_connection_set_network_type($connection::current,(const char*)$nettype.text->chars);}
                  SPACE addrtype{ belle_sdp_connection_set_address_type($connection::current,(const char*)$addrtype.text->chars);}
                  SPACE connection_address
jehan's avatar
jehan committed
177 178 179 180
                  ;
                         //;a connection field must be present
                         //;in every media description or at the
                         //;session-level
181 182
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
183
	ANTLR3_LOG_EXCEPTION();
184 185
  belle_sip_object_unref($ret);
  $ret=NULL;
186 187 188
}

bandwidth returns [belle_sdp_bandwidth_t* ret]
189 190
scope { belle_sdp_bandwidth_t* current; }
@init {$bandwidth::current = belle_sdp_bandwidth_new(); $ret=$bandwidth::current; }
191
  :    {IS_TOKEN(b)}?alpha_num EQUAL bwtype {belle_sdp_bandwidth_set_type($bandwidth::current,(const char*)$bwtype.text->chars); }
192
      COLON bandwidth_value {belle_sdp_bandwidth_set_value($bandwidth::current,atoi((const char*)$bandwidth_value.text->chars));};
193 194
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
195
	ANTLR3_LOG_EXCEPTION();
196 197
  belle_sip_object_unref($ret);
  $ret=NULL;
198 199 200 201
}
time_field:   {IS_TOKEN(t)}?alpha_num EQUAL
              start_time
              SPACE
202 203
              stop_time {belle_sdp_time_description_t* time_description =belle_sdp_time_description_new();
                         belle_sdp_time_t* time_value =belle_sdp_time_new();
204
						 belle_sip_list_t* time_description_list;
205 206 207
                         belle_sdp_time_set_start(time_value,atoi((const char*)$start_time.text->chars));
                         belle_sdp_time_set_stop(time_value,atoi((const char*)$stop_time.text->chars));
                         belle_sdp_time_description_set_time(time_description,time_value);
208
                         time_description_list = belle_sip_list_append(NULL,time_description);
209
                         belle_sdp_session_description_set_time_descriptions($session_description::current,time_description_list);};
jehan's avatar
jehan committed
210

211
repeat_time:       {IS_TOKEN(r)}?alpha_num EQUAL repeat_interval (SPACE typed_time)+;
jehan's avatar
jehan committed
212

213
zone_adjustments:    {IS_TOKEN(z)}? alpha_num EQUAL sdp_time SPACE '-'? typed_time
jehan's avatar
jehan committed
214 215
                         (SPACE sdp_time SPACE '-'? typed_time)*;

216
key_field:           {IS_TOKEN(k)}?alpha_num EQUAL key_value ;
jehan's avatar
jehan committed
217
key_value options { greedy = false; }:        (~(CR|LF))*;
218 219 220 221 222 223
//key_type:            {IS_TOKEN(prompt)}? alpha_num*  /*'prompt'*/ |
//                     {IS_TOKEN(clear)}? alpha_num* /*'clear'*/  COLON key_data |
//                     {IS_TOKEN(base64)}? alpha_num* /*'base64*/ COLON key_data |
//                     {IS_TOKEN(base64)}? alpha_num* /*'uri*/ COLON uri;
//
//key_data:            email_safe;
jehan's avatar
jehan committed
224 225


226 227 228 229 230 231
attribute returns [belle_sdp_attribute_t* ret]
scope {int has_value;}
@init {$ret=NULL;}
: {IS_TOKEN(a)}?alpha_num EQUAL attribute_content{$ret=$attribute_content.ret;};
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
232
	ANTLR3_LOG_EXCEPTION();
233 234 235 236 237
   if ($ret) belle_sip_object_unref($ret);
   $ret=NULL;
}

attribute_content returns [belle_sdp_attribute_t* ret]
jehan's avatar
jehan committed
238
@init {$ret=NULL; }
239
: attribute_name (COLON val=attribute_value {$ret=belle_sdp_attribute_create((const char*)$attribute_name.text->chars,(const char*)$attribute_value.text->chars);})?
jehan's avatar
jehan committed
240 241
	{
	if (!val.tree) $ret=belle_sdp_attribute_create((const char*)$attribute_name.text->chars,NULL);
242 243 244 245 246 247 248 249
};

rtcp_xr_attribute returns [belle_sdp_rtcp_xr_attribute_t* ret]
scope { belle_sdp_rtcp_xr_attribute_t* current; }
@init { $rtcp_xr_attribute::current = belle_sdp_rtcp_xr_attribute_new();$ret = $rtcp_xr_attribute::current;}
: {IS_TOKEN(a)}?alpha_num EQUAL {IS_TOKEN(rtcp-xr)}? attribute_name /*'rtcp-xr'*/ (COLON rtcp_xr_attribute_value (SPACE rtcp_xr_attribute_value)*)?;
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
250
	ANTLR3_LOG_EXCEPTION();
251 252
   belle_sip_object_unref($ret);
   $ret=NULL;
253
}
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
rtcp_xr_attribute_value :
	(pkt_loss_rle)=> pkt_loss_rle
|	(pkt_dup_rle)=> pkt_dup_rle
|	(pkt_rcpt_times)=> pkt_rcpt_times
|	(rcvr_rtt)=> rcvr_rtt
|	(stat_summary)=> stat_summary
|	(voip_metrics)=> voip_metrics;

pkt_loss_rle :
	{IS_TOKEN(pkt-loss-rle)}? rtcp_xr_attribute_name /*'pkt-loss-rle'*/ (EQUAL rtcp_xr_max_size)? ;

pkt_dup_rle :
	{IS_TOKEN(pkt-dup-rle)}? rtcp_xr_attribute_name /*'pkt-dup-rle'*/ (EQUAL rtcp_xr_max_size)? ;

pkt_rcpt_times :
	{IS_TOKEN(pkt-rcpt-times)}? rtcp_xr_attribute_name /*'pkt-rcpt-times'*/ (EQUAL rtcp_xr_max_size)? ;

rcvr_rtt :
	{IS_TOKEN(rcvr-rtt)}? rtcp_xr_attribute_name /*'rcvr-rtt'*/ EQUAL {IS_TOKEN(all) || IS_TOKEN(sender)}? rtcp_xr_rcvr_rtt_mode (COLON val=rtcp_xr_max_size)? {
		belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_mode($rtcp_xr_attribute::current,(const char*)$rtcp_xr_rcvr_rtt_mode.text->chars);
		if (val.tree) belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_max_size($rtcp_xr_attribute::current,atoi((const char*)$rtcp_xr_max_size.text->chars));
jehan's avatar
jehan committed
275 276 277 278 279 280
	};

stat_summary :
	{IS_TOKEN(stat-summary)}? rtcp_xr_attribute_name /*'stat-summary'*/ {
		belle_sdp_rtcp_xr_attribute_set_stat_summary($rtcp_xr_attribute::current,1);
	} (EQUAL rtcp_xr_stat_summary_flag (COMMA rtcp_xr_stat_summary_flag)*)?;
281

jehan's avatar
jehan committed
282
voip_metrics :
283 284 285 286 287 288 289 290 291 292
	{IS_TOKEN(voip-metrics)}? rtcp_xr_attribute_name /*'voip-metrics'*/ {
		belle_sdp_rtcp_xr_attribute_set_voip_metrics($rtcp_xr_attribute::current,1);
	};

rtcp_xr_stat_summary_flag :
	{IS_TOKEN(loss) || IS_TOKEN(dup) || IS_TOKEN(jitt) || IS_TOKEN(TTL) || IS_TOKEN(HL)}?rtcp_xr_stat_summary_flag_value {
		belle_sdp_rtcp_xr_attribute_add_stat_summary_flag($rtcp_xr_attribute::current,(const char*)$rtcp_xr_stat_summary_flag_value.text->chars);
	};

rtcp_xr_max_size : DIGIT+;
293

294 295 296 297 298 299
rtcp_fb_attribute returns [belle_sdp_rtcp_fb_attribute_t* ret]
scope { belle_sdp_rtcp_fb_attribute_t* current; }
@init { $rtcp_fb_attribute::current = belle_sdp_rtcp_fb_attribute_new();$ret = $rtcp_fb_attribute::current;}
: {IS_TOKEN(a)}?alpha_num EQUAL {IS_TOKEN(rtcp-fb)}? attribute_name /*'rtcp-fb'*/ COLON rtcp_fb_pt SPACE rtcp_fb_val;
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
300
	ANTLR3_LOG_EXCEPTION();
301 302 303 304 305 306 307 308 309 310 311 312 313 314
	belle_sip_object_unref($ret);
	$ret=NULL;
}

rtcp_fb_pt: STAR {
	belle_sdp_rtcp_fb_attribute_set_id($rtcp_fb_attribute::current,-1);
} | integer {
	belle_sdp_rtcp_fb_attribute_set_id($rtcp_fb_attribute::current,atoi((const char*)$integer.text->chars));
};

rtcp_fb_val :
	(rtcp_fb_ack_val)=>rtcp_fb_ack_val
|	(rtcp_fb_nack_val)=>rtcp_fb_nack_val
|	(rtcp_fb_trr_int_val)=>rtcp_fb_trr_int_val
315
|	(rtcp_fb_ccm_val)=>rtcp_fb_ccm_val
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
|	(rtcp_fb_id_val)=>rtcp_fb_id_val;

rtcp_fb_ack_val:
	{IS_TOKEN(ack)}? rtcp_fb_attribute_name /*'ack'*/ (SPACE rtcp_fb_ack_param)? {
		belle_sdp_rtcp_fb_attribute_set_type($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_ACK);
	};

rtcp_fb_nack_val:
	{IS_TOKEN(nack)}? rtcp_fb_attribute_name /*'nack'*/ (SPACE rtcp_fb_nack_param)? {
		belle_sdp_rtcp_fb_attribute_set_type($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_NACK);
	};

rtcp_fb_trr_int_val:
	{IS_TOKEN(trr-int)}? rtcp_fb_attribute_name /*'trr-int'*/ SPACE integer {
		belle_sdp_rtcp_fb_attribute_set_type($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_TRR_INT);
331
		belle_sdp_rtcp_fb_attribute_set_trr_int($rtcp_fb_attribute::current,(uint16_t)atoi((const char*)$integer.text->chars));
332 333
	};

334
rtcp_fb_ccm_val:
335
	{IS_TOKEN(ccm)}? rtcp_fb_attribute_name /*'ccm'*/ (SPACE rtcp_fb_ccm_param)? { /* TODO: rtcp_fb_ccm_param should be mandatory */
336 337 338
		belle_sdp_rtcp_fb_attribute_set_type($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_CCM);
	};

339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
rtcp_fb_id_val:
	rtcp_fb_attribute_name (SPACE rtcp_fb_param)?;

rtcp_fb_param:
	(rtcp_fb_app_param)=>rtcp_fb_app_param
|	(rtcp_fb_token_param)=>rtcp_fb_token_param;

rtcp_fb_ack_param:
	(rtcp_fb_rpsi_param)=>rtcp_fb_rpsi_param
|	(rtcp_fb_app_param)=>rtcp_fb_app_param
|	(rtcp_fb_token_param)=>rtcp_fb_token_param;

rtcp_fb_nack_param:
	(rtcp_fb_pli_param)=>rtcp_fb_pli_param
|	(rtcp_fb_sli_param)=>rtcp_fb_sli_param
|	(rtcp_fb_rpsi_param)=>rtcp_fb_rpsi_param
|	(rtcp_fb_app_param)=>rtcp_fb_app_param
|	(rtcp_fb_token_param)=>rtcp_fb_token_param;

rtcp_fb_pli_param:
	{IS_TOKEN(pli)}? rtcp_fb_attribute_name /*'pli'*/ {
		belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_PLI);
	};

rtcp_fb_sli_param:
	{IS_TOKEN(sli)}? rtcp_fb_attribute_name /*'sli'*/ {
		belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_SLI);
	};

rtcp_fb_rpsi_param:
	{IS_TOKEN(rpsi)}? rtcp_fb_attribute_name /*'rpsi'*/ {
		belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_RPSI);
	};

rtcp_fb_app_param:
	{IS_TOKEN(app)}? rtcp_fb_attribute_name /*'app'*/ (SPACE byte_string) {
		belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_APP);
	};

378 379
rtcp_fb_ccm_param:
	(rtcp_fb_fir_param)=>rtcp_fb_fir_param
380
|	(rtcp_fb_tmmbr_param)=>rtcp_fb_tmmbr_param
381 382 383 384 385 386 387
|	(rtcp_fb_token_param)=>rtcp_fb_token_param;

rtcp_fb_fir_param:
	{IS_TOKEN(fir)}? rtcp_fb_attribute_name /*'fir'*/ {
		belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_FIR);
	};

388 389 390 391 392 393 394 395 396 397 398 399
rtcp_fb_tmmbr_param:
	{IS_TOKEN(tmmbr)}? rtcp_fb_attribute_name /*'tmmbr'*/ (SPACE rtcp_fb_tmmbr_smaxpr_param)? {
		belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_TMMBR);
	};

rtcp_fb_tmmbr_smaxpr_param:
	{IS_TOKEN(smaxpr)}? rtcp_fb_attribute_name /*'smaxpr'*/ EQUAL val=rtcp_fb_tmmbr_smaxpr {
		if (val.tree) belle_sdp_rtcp_fb_attribute_set_smaxpr($rtcp_fb_attribute::current,atoi((const char*)$rtcp_fb_tmmbr_smaxpr.text->chars));
	};

rtcp_fb_tmmbr_smaxpr : DIGIT+;

400 401 402
rtcp_fb_token_param:
	rtcp_fb_attribute_name (SPACE byte_string)?;

403
media_description  returns [belle_sdp_media_description_t* ret]
jehan's avatar
jehan committed
404 405 406 407 408 409
scope { belle_sdp_media_description_t* current; }
@init {$media_description::current = belle_sdp_media_description_new(); $ret=$media_description::current; }
:                    media CR LF  {belle_sdp_media_description_set_media($media_description::current,$media.ret);}
                    (info {belle_sdp_media_description_set_info($media_description::current,$info.ret);} CR LF)?
                     (connection { belle_sdp_media_description_set_connection($media_description::current,$connection.ret);} CR LF)?
                     (bandwidth {belle_sdp_media_description_add_bandwidth($media_description::current,$bandwidth.ret);} CR LF)*
jehan's avatar
jehan committed
410
                     (key_field CR LF)?
411
                     (attribute {if ($attribute.ret)belle_sdp_media_description_add_attribute($media_description::current,$attribute.ret);} CR LF)*;
412

413 414
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
415
	ANTLR3_LOG_EXCEPTION();
416 417
  belle_sip_object_unref($ret);
  $ret=NULL;
418
}
419
media returns [belle_sdp_media_t* ret]
420 421
scope { belle_sdp_media_t* current; }
@init {$media::current = belle_sdp_media_new(); $ret=$media::current; }
422 423 424 425
:         {IS_TOKEN(m)}?alpha_num EQUAL
          media_value {belle_sdp_media_set_media_type($media::current,(const char*)$media_value.text->chars);}
          SPACE port {belle_sdp_media_set_media_port($media::current,atoi((const char*)$port.text->chars));}
          (SLASH integer{belle_sdp_media_set_port_count($media::current,atoi((const char*)$integer.text->chars));})?
jehan's avatar
jehan committed
426
          SPACE proto {belle_sdp_media_set_protocol($media::current,(const char*)$proto.text->chars);}
427 428 429
          (SPACE fmt)+;
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
430
	ANTLR3_LOG_EXCEPTION();
431 432
  belle_sip_object_unref($ret);
  $ret=NULL;
433
}
434
media_value:               alpha_num+;
jehan's avatar
jehan committed
435 436 437
                     //    ;typically "audio", "video", "application"
                     //    ;or "data"

438 439
fmt
scope { int is_number; }
440
@init { $fmt::is_number=0;}:                 ((DIGIT+)=>(DIGIT+){$fmt::is_number=1;} | token )
441 442
                                                                          {belle_sdp_media_set_media_formats($media::current
                                                                          ,belle_sip_list_append(belle_sdp_media_get_media_formats($media::current)
443
                                                                          ,(void*)($fmt::is_number?(void*)(intptr_t)atoi((const char*)$fmt.text->chars):$fmt.text->chars)));};
jehan's avatar
jehan committed
444 445
                     //;typically an RTP payload type for audio
                     //;and video media
446
proto              options { greedy = false; }:        ~(SPACE|CR|LF)*;
jehan's avatar
jehan committed
447 448
                     //;typically "RTP/AVP" or "udp" for IP4

449
port:                DIGIT+;
jehan's avatar
jehan committed
450 451 452
                     //    ;should in the range "1024" to "65535" inclusive
                     //    ;for UDP based media

453 454 455 456 457
attribute_name: token;

attribute_value options { greedy = false; }: ~(CR|LF)*;

rtcp_xr_attribute_name: word;
jehan's avatar
jehan committed
458

459
rtcp_xr_rcvr_rtt_mode: word;
jehan's avatar
jehan committed
460

461
rtcp_xr_stat_summary_flag_value: word;
jehan's avatar
jehan committed
462

463 464
rtcp_fb_attribute_name: word;

jehan's avatar
jehan committed
465
sess_id:             DIGIT+;
jehan's avatar
jehan committed
466 467
                        // ;should be unique for this originating username/host

468
sess_version:        DIGIT+;
469
                         //;0 is a new session
jehan's avatar
jehan committed
470

471
connection_address:
jehan's avatar
jehan committed
472

473
                  /*multicast_address
474
                  |*/addr {belle_sdp_connection_set_address($connection::current,(const char*)$addr.text->chars);} multicast_part?;
475 476 477

multicast_address:   unicast_address '/' ttl;
                          // (decimal_uchar DOT decimal_uchar DOT decimal_uchar DOT) decimal_uchar '/' ttl  ( '/' integer )?;
jehan's avatar
jehan committed
478 479 480 481 482
                         //;multicast addresses may be in the range
                         //;224.0.0.0 to 239.255.255.255

ttl:                 decimal_uchar;

483
start_time:           DIGIT+  ;
jehan's avatar
jehan committed
484

485
stop_time:           DIGIT+  ;
jehan's avatar
jehan committed
486

487
sdp_time:                 DIGIT+;
jehan's avatar
jehan committed
488 489 490 491 492 493 494 495 496 497 498 499 500
                     //    ;sufficient for 2 more centuries

repeat_interval:     typed_time;

typed_time:          DIGIT* fixed_len_time_unit?;

fixed_len_time_unit: {IS_TOKEN(d)}? alpha_num
                      | {IS_TOKEN(h)}? alpha_num
                      | {IS_TOKEN(m)}? alpha_num
                      | {IS_TOKEN(s)}? alpha_num;

bwtype:              alpha_num+;

501
bandwidth_value:           DIGIT+;
jehan's avatar
jehan committed
502 503 504 505

username:            email_safe;
                         //;pretty wide definition, but doesn't include SPACE

506
email_address       options { greedy = false; }:        ~(CR|LF)* ;  //| email '(' email_safe ')' |
jehan's avatar
jehan committed
507 508 509 510 511 512
                         //email_safe '<' email '>';


uri:          text        ;//defined in RFC1630

phone_number:         phone;/*(phone '(') => (phone '(') email_safe ')'
513
                      | (phone) => phone
jehan's avatar
jehan committed
514 515 516 517 518 519 520 521 522
                      | email_safe LQUOTE phone RQUOTE;*/

phone:               text;//'+' DIGIT*POS_DIGIT (SPACE | '-' | DIGIT)*;
                         //;there must be a SPACE or hyphen between the
                         //;international code and the rest of the number.

nettype:             alpha_num+;//'IN';
                        // ;list to be extended

523
addrtype:            alpha_num+ ; //'IP4' | 'IP6';
jehan's avatar
jehan committed
524 525
                         //;list to be extended

526
addr:                 unicast_address ;
527

528 529 530
 multicast_part: (SLASH num+=integer 	{
 			if (strcmp( belle_sdp_connection_get_address_type($connection::current),"IP6")==0)
 				belle_sdp_connection_set_range($connection::current,atoi((const char*)$integer.text->chars));
531
 			else if ($num->count ==1)
532
				belle_sdp_connection_set_ttl($connection::current,atoi((const char*)$integer.text->chars));
533
			else if ($num->count ==2)
534 535
				belle_sdp_connection_set_range($connection::current,atoi((const char*)$integer.text->chars));
			})+;
536 537

fqdn        :   ( domainlabel DOT )* toplabel DOT? ;
538

539 540 541 542
domainlabel     :   alpha_num | (alpha_num ( alpha_num | DASH )* alpha_num) ;
toplabel        :   alpha | (alpha ( alpha_num | DASH )* alpha_num) ;

unicast_address :   (alpha_num | DOT | COLON| DASH)*;   /*might be better defined*/
543
                   /* ipv4_address
544
                    |ipv6_address
545
                    |fqdn*/
jehan's avatar
jehan committed
546

547
ipv4_address :         decimal_uchar DOT decimal_uchar DOT decimal_uchar DOT decimal_uchar ;
jehan's avatar
jehan committed
548 549 550



551 552 553 554 555 556
ipv6_address    :  (hexpart)=>hexpart ( COLON ipv4_address )? ;
hexpart        :  hexseq | hexseq COLON COLON hexseq? | COLON COLON hexseq? ;
hexseq         :  hex4 ( COLON hex4)* ;
hex4           :  hexdigit+; /* hexdigit hexdigit hexdigit ;*/

text :                ~(CR|LF)* ;
jehan's avatar
jehan committed
557 558 559 560
                      //default is to interpret this as IS0-10646 UTF8
                      //ISO 8859-1 requires a "a=charset:ISO-8859-1"
                      //session-level attribute to be used

561
byte_string options { greedy = false; }:        (OCTET)* ;
jehan's avatar
jehan committed
562 563
                         //any byte except NUL, CR or LF

564
decimal_uchar:       integer;// (d+=DIGIT+ {$d !=NULL && $d->count<=3}?)
jehan's avatar
jehan committed
565

566
integer:             DIGIT+;
jehan's avatar
jehan committed
567

jehan's avatar
jehan committed
568
email_safe : ~(SPACE)*;
569

570
token : (alpha_num | '!' | '#' | '$' |'&'| '%'| '\'' | '*' |'+' | DASH | DOT | '^' | '_' | '`' | '{' | '|' | '}' | '~')+;
jehan's avatar
jehan committed
571

572 573
alpha_num:    (alpha | DIGIT) ;
hexdigit: (HEX_CHAR | DIGIT) ;
574
word: (alpha | DASH)+;
jehan's avatar
jehan committed
575 576
alpha: COMMON_CHAR | HEX_CHAR;

jehan's avatar
jehan committed
577 578 579 580

DIGIT:           ZERO     | POS_DIGIT;
fragment ZERO: '0';
fragment POS_DIGIT :           '1'..'9';
581 582
//ALPHA:               'a'..'z'|'A'..'Z';
COMMON_CHAR
583
  : 'g'..'z' | 'G'..'Z' ;
584 585
HEX_CHAR: 'a'..'f' |'A'..'F';

jehan's avatar
jehan committed
586 587 588 589 590 591 592 593 594 595
SPACE: ' ';

//CRLF  : CR LF { USER1 = (int)(ctx->pLexer->input->currentLine - ctx->pLexer->input->data);};
LQUOTE: '<';
RQUOTE: '>';
CR:'\r';
LF:'\n';
DOT: '.';
EQUAL: '=';
COLON: ':';
596
SLASH: '/';
597
DASH: '-';
598
COMMA: ',';
599
STAR: '*';
jehan's avatar
jehan committed
600
OCTET	:	.;