Tue Aug 12 12:56:16 EDT 2008 Pekka Pessi <first.last@nokia.com>
* sdp_parse: the syntax is updated to RFC 4566 "The changes to the memo are intended to be backward-compatible clarifications." git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9280 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
55f7d3505a
commit
34c878ba94
|
@ -1 +1 @@
|
||||||
Tue Aug 12 13:07:50 EDT 2008
|
Tue Aug 12 13:08:36 EDT 2008
|
||||||
|
|
|
@ -11,7 +11,7 @@ tests="${2:-${sdp_path}/tests}"
|
||||||
|
|
||||||
if test -r $tests/message-1.sdp ; then
|
if test -r $tests/message-1.sdp ; then
|
||||||
|
|
||||||
for n in 1 2 3 4 5 6 7 8 9 10;
|
for n in 1 2 3 4 5 6 7 8 9 10 11;
|
||||||
do
|
do
|
||||||
echo -n "$n: "
|
echo -n "$n: "
|
||||||
"$test_sdp" < "$tests/message-$n.sdp" && echo OK
|
"$test_sdp" < "$tests/message-$n.sdp" && echo OK
|
||||||
|
|
|
@ -250,6 +250,7 @@ void sdp_parser_free(sdp_parser_t *p)
|
||||||
#define CRLF "\015\012"
|
#define CRLF "\015\012"
|
||||||
#define ALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
#define ALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
#define DIGIT "0123456789"
|
#define DIGIT "0123456789"
|
||||||
|
#define TOKEN ALPHA DIGIT "-!#$%&'*+.^_`{|}~"
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
/* Parsing functions */
|
/* Parsing functions */
|
||||||
|
@ -891,9 +892,7 @@ static void parse_bandwidth(sdp_parser_t *p, char *r, sdp_bandwidth_t **result)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
bandwidth-fields = *("b=" bwtype ":" bandwidth CRLF)
|
bandwidth-fields = *("b=" bwtype ":" bandwidth CRLF)
|
||||||
|
bwtype = token
|
||||||
bwtype = 1*(alpha-numeric)
|
|
||||||
; CT or AS
|
|
||||||
bandwidth = 1*(DIGIT)
|
bandwidth = 1*(DIGIT)
|
||||||
*/
|
*/
|
||||||
/* NOTE: bwtype can also be like X-barf */
|
/* NOTE: bwtype can also be like X-barf */
|
||||||
|
@ -901,7 +900,7 @@ static void parse_bandwidth(sdp_parser_t *p, char *r, sdp_bandwidth_t **result)
|
||||||
char *name;
|
char *name;
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
|
|
||||||
name = token(&r, ":", ALPHA DIGIT "-", SPACE TAB);
|
name = token(&r, ":", TOKEN, SPACE TAB);
|
||||||
|
|
||||||
if (name == NULL || parse_ul(p, &r, &value, 0)) {
|
if (name == NULL || parse_ul(p, &r, &value, 0)) {
|
||||||
parsing_error(p, "invalid bandwidth");
|
parsing_error(p, "invalid bandwidth");
|
||||||
|
@ -941,16 +940,21 @@ static void parse_bandwidth(sdp_parser_t *p, char *r, sdp_bandwidth_t **result)
|
||||||
static void parse_time(sdp_parser_t *p, char *r, sdp_time_t **result)
|
static void parse_time(sdp_parser_t *p, char *r, sdp_time_t **result)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
time-fields = 1*( "t=" start-time space stop-time
|
time-fields = 1*( "t=" start-time SP stop-time
|
||||||
*(CRLF repeat-fields) CRLF)
|
*(CRLF repeat-fields) CRLF)
|
||||||
[zone-adjustments CRLF]
|
[zone-adjustments CRLF]
|
||||||
|
|
||||||
start-time = time | "0"
|
start-time = time / "0"
|
||||||
|
|
||||||
stop-time = time | "0"
|
stop-time = time / "0"
|
||||||
|
|
||||||
time = POS-DIGIT 9*(DIGIT)
|
time = POS-DIGIT 9*DIGIT
|
||||||
;sufficient for 2 more centuries
|
; Decimal representation of NTP time in
|
||||||
|
; seconds since 1900. The representation
|
||||||
|
; of NTP time is an unbounded length field
|
||||||
|
; containing at least 10 digits. Unlike the
|
||||||
|
; 64-bit representation used elsewhere, time
|
||||||
|
; in SDP does not wrap in the year 2036.
|
||||||
*/
|
*/
|
||||||
PARSE_ALLOC(p, sdp_time_t, t);
|
PARSE_ALLOC(p, sdp_time_t, t);
|
||||||
*result = t;
|
*result = t;
|
||||||
|
@ -975,14 +979,13 @@ static void parse_time(sdp_parser_t *p, char *r, sdp_time_t **result)
|
||||||
static void parse_repeat(sdp_parser_t *p, char *d, sdp_repeat_t **result)
|
static void parse_repeat(sdp_parser_t *p, char *d, sdp_repeat_t **result)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
repeat-fields = "r=" repeat-interval space typed-time
|
repeat-fields = %x72 "=" repeat-interval 2*(SP typed-time)
|
||||||
1*(space typed-time)
|
|
||||||
|
|
||||||
repeat-interval = typed-time
|
repeat-interval = POS-DIGIT *DIGIT [fixed-len-time-unit]
|
||||||
|
|
||||||
typed-time = 1*(DIGIT) [fixed-len-time-unit]
|
typed-time = 1*DIGIT [fixed-len-time-unit]
|
||||||
|
|
||||||
fixed-len-time-unit = "d" | "h" | "m" | "s"
|
fixed-len-time-unit = %x64 / %x68 / %x6d / %x73 ; "d" | "h" | "m" | "s"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long tt, *interval;
|
unsigned long tt, *interval;
|
||||||
|
@ -1129,17 +1132,15 @@ static void parse_key(sdp_parser_t *p, char *r, sdp_key_t **result)
|
||||||
/*
|
/*
|
||||||
key-field = ["k=" key-type CRLF]
|
key-field = ["k=" key-type CRLF]
|
||||||
|
|
||||||
|
|
||||||
key-type = "prompt" |
|
key-type = "prompt" |
|
||||||
"clear:" key-data |
|
"clear:" key-data |
|
||||||
"base64:" key-data |
|
"base64:" key-data |
|
||||||
"uri:" uri
|
"uri:" uri
|
||||||
|
|
||||||
|
|
||||||
key-data = email-safe | "~" | "
|
key-data = email-safe | "~" | "
|
||||||
*/
|
*/
|
||||||
|
|
||||||
s = token(&r, ":", ALPHA DIGIT "-", SPACE TAB);
|
s = token(&r, ":", TOKEN, SPACE TAB);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
parsing_error(p, "invalid key method");
|
parsing_error(p, "invalid key method");
|
||||||
return;
|
return;
|
||||||
|
@ -1149,16 +1150,24 @@ static void parse_key(sdp_parser_t *p, char *r, sdp_key_t **result)
|
||||||
PARSE_ALLOC(p, sdp_key_t, k);
|
PARSE_ALLOC(p, sdp_key_t, k);
|
||||||
*result = k;
|
*result = k;
|
||||||
|
|
||||||
if (strcasecmp(s, "clear") == 0)
|
/* These are defined as key-sensitive in RFC 4566 */
|
||||||
|
#define MATCH(s, tok) \
|
||||||
|
(STRICT(p) ? strcmp((s), (tok)) == 0 : strcasecmp((s), (tok)) == 0)
|
||||||
|
|
||||||
|
if (MATCH(s, "clear"))
|
||||||
k->k_method = sdp_key_clear, k->k_method_name = "clear";
|
k->k_method = sdp_key_clear, k->k_method_name = "clear";
|
||||||
else if (strcasecmp(s, "base64") == 0)
|
else if (MATCH(s, "base64"))
|
||||||
k->k_method = sdp_key_base64, k->k_method_name = "base64";
|
k->k_method = sdp_key_base64, k->k_method_name = "base64";
|
||||||
else if (strcasecmp(s, "uri") == 0)
|
else if (MATCH(s, "uri"))
|
||||||
k->k_method = sdp_key_uri, k->k_method_name = "uri";
|
k->k_method = sdp_key_uri, k->k_method_name = "uri";
|
||||||
else if (strcasecmp(s, "prompt") == 0)
|
else if (MATCH(s, "prompt"))
|
||||||
k->k_method = sdp_key_prompt, k->k_method_name = "prompt";
|
k->k_method = sdp_key_prompt, k->k_method_name = "prompt";
|
||||||
else
|
else if (!STRICT(p))
|
||||||
k->k_method = sdp_key_x, k->k_method_name = s;
|
k->k_method = sdp_key_x, k->k_method_name = s;
|
||||||
|
else {
|
||||||
|
parsing_error(p, "invalid key method");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
k->k_material = r;
|
k->k_material = r;
|
||||||
}
|
}
|
||||||
|
@ -1180,16 +1189,16 @@ static void parse_session_attr(sdp_parser_t *p, char *r, sdp_attribute_t **resul
|
||||||
/*
|
/*
|
||||||
attribute-fields = *("a=" attribute CRLF)
|
attribute-fields = *("a=" attribute CRLF)
|
||||||
|
|
||||||
attribute = (att-field ":" att-value) | att-field
|
attribute = (att-field ":" att-value) / att-field
|
||||||
|
|
||||||
att-field = 1*(alpha-numeric)
|
att-field = token
|
||||||
|
|
||||||
att-value = byte-string
|
att-value = byte-string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char *name = NULL, *value = NULL;
|
char *name = NULL, *value = NULL;
|
||||||
|
|
||||||
if (!(name = token(&r, ":", ALPHA DIGIT "-", SPACE TAB))) {
|
if (!(name = token(&r, ":", TOKEN, SPACE TAB))) {
|
||||||
parsing_error(p,"invalid attribute name");
|
parsing_error(p,"invalid attribute name");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1248,15 +1257,15 @@ static void parse_media(sdp_parser_t *p, char *r, sdp_media_t **result)
|
||||||
media-field = "m=" media space port ["/" integer]
|
media-field = "m=" media space port ["/" integer]
|
||||||
space proto 1*(space fmt) CRLF
|
space proto 1*(space fmt) CRLF
|
||||||
|
|
||||||
media = 1*(alpha-numeric)
|
media = token
|
||||||
;typically "audio", "video", "application"
|
;typically "audio", "video", "application"
|
||||||
;or "data"
|
;or "data"
|
||||||
|
|
||||||
fmt = 1*(alpha-numeric)
|
fmt = token
|
||||||
;typically an RTP payload type for audio
|
;typically an RTP payload type for audio
|
||||||
;and video media
|
;and video media
|
||||||
|
|
||||||
proto = 1*(alpha-numeric)
|
proto = token *("/" token)
|
||||||
;typically "RTP/AVP" or "udp" for IP4
|
;typically "RTP/AVP" or "udp" for IP4
|
||||||
|
|
||||||
port = 1*(DIGIT)
|
port = 1*(DIGIT)
|
||||||
|
@ -1270,9 +1279,7 @@ static void parse_media(sdp_parser_t *p, char *r, sdp_media_t **result)
|
||||||
|
|
||||||
m->m_mode = sdp_sendrecv;
|
m->m_mode = sdp_sendrecv;
|
||||||
|
|
||||||
s = token(&r, SPACE, ALPHA DIGIT, NULL);
|
s = token(&r, SPACE, TOKEN, NULL);
|
||||||
if (s == NULL && p->pr_config)
|
|
||||||
s = token(&r, SPACE, "*", NULL);
|
|
||||||
if (!s) {
|
if (!s) {
|
||||||
parsing_error(p, "m= invalid media field");
|
parsing_error(p, "m= invalid media field");
|
||||||
return;
|
return;
|
||||||
|
@ -1304,10 +1311,7 @@ static void parse_media(sdp_parser_t *p, char *r, sdp_media_t **result)
|
||||||
m->m_number_of_ports = value;
|
m->m_number_of_ports = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alpha-numeric and "/" */
|
s = token(&r, SPACE, "/" TOKEN, SPACE);
|
||||||
s = token(&r, SPACE, ALPHA DIGIT "/", SPACE);
|
|
||||||
if (s == NULL && p->pr_config)
|
|
||||||
s = token(&r, SPACE, "*", SPACE);
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
parsing_error(p, "m= missing protocol");
|
parsing_error(p, "m= missing protocol");
|
||||||
return;
|
return;
|
||||||
|
@ -1331,7 +1335,7 @@ static void parse_media(sdp_parser_t *p, char *r, sdp_media_t **result)
|
||||||
while (r && *r) {
|
while (r && *r) {
|
||||||
PARSE_ALLOC(p, sdp_list_t, l);
|
PARSE_ALLOC(p, sdp_list_t, l);
|
||||||
*fmt = l;
|
*fmt = l;
|
||||||
l->l_text = next(&r, SPACE TAB, SPACE TAB);
|
l->l_text = token(&r, SPACE TAB, TOKEN, SPACE TAB);
|
||||||
fmt = &l->l_next;
|
fmt = &l->l_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1536,9 +1540,9 @@ static void parse_media_attr(sdp_parser_t *p, char *r, sdp_media_t *m,
|
||||||
/*
|
/*
|
||||||
attribute-fields = *("a=" attribute CRLF)
|
attribute-fields = *("a=" attribute CRLF)
|
||||||
|
|
||||||
attribute = (att-field ":" att-value) | att-field
|
attribute = (att-field ":" att-value) / att-field
|
||||||
|
|
||||||
att-field = 1*(alpha-numeric)
|
att-field = token
|
||||||
|
|
||||||
att-value = byte-string
|
att-value = byte-string
|
||||||
|
|
||||||
|
@ -1549,7 +1553,7 @@ static void parse_media_attr(sdp_parser_t *p, char *r, sdp_media_t *m,
|
||||||
char *name = NULL, *value = NULL;
|
char *name = NULL, *value = NULL;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (!(name = token(&r, ":", ALPHA DIGIT "-", SPACE TAB))) {
|
if (!(name = token(&r, ":", TOKEN, SPACE TAB))) {
|
||||||
parsing_error(p,"invalid attribute name");
|
parsing_error(p,"invalid attribute name");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1623,7 +1627,7 @@ static int parse_rtpmap(sdp_parser_t *p, char *r, sdp_media_t *m)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
encoding = token(&r, "/", ALPHA DIGIT "-", NULL);
|
encoding = token(&r, "/", TOKEN, NULL);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
parsing_error(p, "a=rtpmap:%lu: missing <clock rate>", pt);
|
parsing_error(p, "a=rtpmap:%lu: missing <clock rate>", pt);
|
||||||
return -2;
|
return -2;
|
||||||
|
|
Loading…
Reference in New Issue