belle_sdp.g 11.7 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 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
    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_sdp;


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

jehan's avatar
jehan committed
31 32 33 34 35
session_description returns [belle_sdp_session_description_t* ret]     
scope { belle_sdp_session_description_t* current; }
@init {$session_description::current = belle_sdp_session_description_new(); $ret=$session_description::current; }
                    :    version CR LF
                         origin CR LF
jehan's avatar
jehan committed
36
                         session_name_field
37
                         (info CR LF)?
jehan's avatar
jehan committed
38
                         uri_field?
39
                         (email CR LF)*
jehan's avatar
jehan committed
40 41
                         phone_field*
                         (connection CR LF)?
42 43 44 45 46
                         (bandwidth CR LF)*
                         time_field
                         (repeat_time CR LF)?
                         (zone_adjustments CR LF)?
                         (key_field CR LF)?
jehan's avatar
jehan committed
47 48
                         (attribute CR LF)*
                         media_descriptions;
jehan's avatar
jehan committed
49

jehan's avatar
jehan committed
50 51 52
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
53 54
                       //  ;this memo describes version 0

jehan's avatar
jehan committed
55 56 57 58
origin returns [belle_sdp_origin_t* ret]     
scope { belle_sdp_origin_t* current; }
@init {$origin::current = belle_sdp_origin_new(); $ret=$origin::current; }
:        {IS_TOKEN(o)}?alpha_num EQUAL username SPACE
jehan's avatar
jehan committed
59 60
                         sess_id SPACE sess_version SPACE
                         nettype SPACE addrtype SPACE
jehan's avatar
jehan committed
61
                         addr ;
jehan's avatar
jehan committed
62 63 64

session_name_field:  {IS_TOKEN(s)}? alpha_num EQUAL text CR LF;

65 66 67 68 69 70
info returns [belle_sdp_info_t* ret]     
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
71 72 73

uri_field:           {IS_TOKEN(u)}?alpha_num EQUAL uri CR LF;

74 75 76 77
email returns [belle_sdp_email_t* ret]     
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
78 79 80 81 82 83

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

connection returns [belle_sdp_connection_t* ret]     
scope { belle_sdp_connection_t* current; }
@init {$connection::current = belle_sdp_connection_new(); $ret=$connection::current; }
jehan's avatar
jehan committed
84
:    {IS_TOKEN(c)}?alpha_num EQUAL nettype { belle_sdp_connection_set_network_type($connection::current,(const char*)$nettype.text->chars);} 
jehan's avatar
jehan committed
85 86 87 88 89 90 91
                  SPACE addrtype{ belle_sdp_connection_set_address_type($connection::current,(const char*)$addrtype.text->chars);} 
                  SPACE connection_address {belle_sdp_connection_set_address($connection::current,(const char*)$connection_address.text->chars);}
                  ;
                         //;a connection field must be present
                         //;in every media description or at the
                         //;session-level
                         
92 93 94 95 96
bandwidth returns [belle_sdp_bandwidth_t* ret]     
scope { belle_sdp_bandwidth_t* current; }
@init {$bandwidth::current = belle_sdp_bandwidth_new(); $ret=$bandwidth::current; }
  :    {IS_TOKEN(b)}?alpha_num EQUAL bwtype {belle_sdp_bandwidth_set_type($bandwidth::current,(const char*)$bwtype.text->chars); } 
      COLON bandwidth_value {belle_sdp_bandwidth_set_value($bandwidth::current,atoi((const char*)$bandwidth_value.text->chars));};
jehan's avatar
jehan committed
97

98
time_field:          {IS_TOKEN(t)}?alpha_num EQUAL start_time SPACE stop_time;
jehan's avatar
jehan committed
99

100
repeat_time:       {IS_TOKEN(r)}?alpha_num EQUAL repeat_interval (SPACE typed_time)+;
jehan's avatar
jehan committed
101 102 103 104

zone_adjustments:    sdp_time SPACE '-'? typed_time
                         (SPACE sdp_time SPACE '-'? typed_time)*;

105 106 107 108 109 110 111 112
key_field:           {IS_TOKEN(k)}?alpha_num EQUAL key_value ;
key_value options { greedy = false; }:        ~(CR|LF)*;
//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
113 114 115 116


attribute returns [belle_sdp_attribute_t* ret]     
scope { belle_sdp_attribute_t* current; }
117
@init {$attribute::current = belle_sdp_attribute_new(); $ret=$attribute::current; }: {IS_TOKEN(a)}?alpha_num EQUAL attribute_value;
jehan's avatar
jehan committed
118 119

media_descriptions: media_description*; 
jehan's avatar
jehan committed
120 121 122 123 124 125 126
media_description  returns [belle_sdp_media_description_t* ret]     
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)*
127
                     key_field ?
jehan's avatar
jehan committed
128
                     (attribute {belle_sdp_media_description_add_attribute($media_description::current,$attribute.ret);} CR LF)*;
jehan's avatar
jehan committed
129 130
                       

131 132 133 134
media returns [belle_sdp_media_t* ret]     
scope { belle_sdp_media_t* current; }
@init {$media::current = belle_sdp_media_new(); $ret=$media::current; }
:         {IS_TOKEN(m)}?alpha_num EQUAL 
jehan's avatar
jehan committed
135
          media_value {belle_sdp_media_set_media_type($media::current,(const char*)$media_value.text->chars);} 
136 137
          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
138 139
          SPACE proto {belle_sdp_media_set_protocol($media::current,(const char*)$proto.text->chars);}
          (SPACE fmt)*;
140 141

media_value:               alpha_num+;
jehan's avatar
jehan committed
142 143 144
                     //    ;typically "audio", "video", "application"
                     //    ;or "data"

jehan's avatar
jehan committed
145 146
fmt:                 DIGIT+ {belle_sdp_media_set_media_formats($media::current
                                                              ,belle_sip_list_append(belle_sdp_media_get_media_formats($media::current)
Simon Morlat's avatar
Simon Morlat committed
147
                                                              ,(void*)(long)atoi((const char*)$fmt.text->chars)));};
jehan's avatar
jehan committed
148 149
                     //;typically an RTP payload type for audio
                     //;and video media
150
proto              options { greedy = false; }:        ~(SPACE|CR|LF)*;
jehan's avatar
jehan committed
151 152
                     //;typically "RTP/AVP" or "udp" for IP4

153
port:                DIGIT+;
jehan's avatar
jehan committed
154 155 156 157 158 159 160
                     //    ;should in the range "1024" to "65535" inclusive
                     //    ;for UDP based media

attribute_value:           (att_field {belle_sdp_attribute_set_name($attribute::current,(const char*)$att_field.text->chars);} 
                            COLON att_value {belle_sdp_attribute_set_value($attribute::current,(const char*)$att_value.text->chars);}) 
                            | att_field {belle_sdp_attribute_set_name($attribute::current,(const char*)$att_field.text->chars);};

161
att_field:           alpha_num+;
jehan's avatar
jehan committed
162

163
att_value            options { greedy = false; }:        ~(CR|LF)*;
jehan's avatar
jehan committed
164 165 166 167

sess_id:             DIGIT*;
                        // ;should be unique for this originating username/host

168
sess_version:        DIGIT+;
jehan's avatar
jehan committed
169 170 171 172 173 174 175 176 177 178 179
                         //;0 is a new session

connection_address:  multicast_address
                         | addr;

multicast_address:   (decimal_uchar decimal_uchar decimal_uchar DOT) decimal_uchar '/' ttl  ( '/' integer )?;
                         //;multicast addresses may be in the range
                         //;224.0.0.0 to 239.255.255.255

ttl:                 decimal_uchar;

180
start_time:           DIGIT+  ;
jehan's avatar
jehan committed
181

182
stop_time:           DIGIT+  ;
jehan's avatar
jehan committed
183

184
sdp_time:                 DIGIT+;
jehan's avatar
jehan committed
185 186 187 188 189 190 191 192 193 194 195 196 197
                     //    ;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+;

198
bandwidth_value:           DIGIT+;
jehan's avatar
jehan committed
199 200 201 202

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

203
email_address       options { greedy = false; }:        ~(CR|LF)* ;  //| email '(' email_safe ')' |
jehan's avatar
jehan committed
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
                         //email_safe '<' email '>';


uri:          text        ;//defined in RFC1630

phone_number:         phone;/*(phone '(') => (phone '(') email_safe ')'
                      | (phone) => phone 
                      | 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

addrtype:            alpha_num+; //'IP4' | 'IP6';
                         //;list to be extended

addr:                (fqdn)=>fqdn | unicast_address ;
  
fqdn:                (alpha_num |'-'|DOT)*;
                     //    ;fully qualified domain name as specified in RFC1035

unicast_address:     ipv4_address ;//| ipv6_address

ipv4_address :         b1 DOT decimal_uchar DOT decimal_uchar DOT b4;
b1:                  decimal_uchar;
                      //;less than "224"; not "0" or "127"
b4:                  decimal_uchar;
                      //;not "0"

//ip6_address :         ;//to be defined

text :                byte_string;
                      //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

243
byte_string options { greedy = false; }:        (.)* ; 
jehan's avatar
jehan committed
244 245 246 247 248 249
                         //any byte except NUL, CR or LF

decimal_uchar:        d+=DIGIT+ {$d->count<=3}?  ; 

integer:             POS_DIGIT DIGIT*;

250 251
email_safe : byte_string;

jehan's avatar
jehan committed
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269

alpha_num:       ALPHA | DIGIT;


DIGIT:           ZERO     | POS_DIGIT;
fragment ZERO: '0';
fragment POS_DIGIT :           '1'..'9';
ALPHA:               'a'..'z'|'A'..'Z';
SPACE: ' ';

//CRLF  : CR LF { USER1 = (int)(ctx->pLexer->input->currentLine - ctx->pLexer->input->data);};
LQUOTE: '<';
RQUOTE: '>';
CR:'\r';
LF:'\n';
DOT: '.';
EQUAL: '=';
COLON: ':';
270
SLASH: '/';
Simon Morlat's avatar
Simon Morlat committed
271
ANY_EXCEPT_CR_LF: ~(CR|LF);