parse out rtcp attribute

2.2
Richard Fuchs 12 years ago
parent 1a2e0d75ea
commit 3faa9f8a8f

@ -56,6 +56,11 @@ struct sdp_media {
struct sdp_attributes attributes;
};
struct attribute_rtcp {
long int port_num;
struct network_address address;
};
struct sdp_attribute {
str full_line, /* including a= and \r\n */
line_value, /* without a= and without \r\n */
@ -63,6 +68,15 @@ struct sdp_attribute {
value, /* just "8 PCMA/8000" */
key, /* "rtpmap:8" */
param; /* "PCMA/8000" */
enum {
ATTR_OTHER = 0,
ATTR_RTCP,
} attr;
union {
struct attribute_rtcp rtcp;
} u;
};
@ -138,7 +152,7 @@ static inline int extract_token(char **sp, char *end, str *out) {
EXTRACT_TOKEN(field.network_type); \
EXTRACT_TOKEN(field.address_type); \
EXTRACT_TOKEN(field.address); \
if (parse_address(&output->address)) return -1
if (parse_address(&output->field)) return -1
static int parse_origin(char *start, char *end, struct sdp_origin *output) {
if (output->parsed)
@ -194,6 +208,62 @@ static void attrs_init(struct sdp_attributes *a) {
a->hash = g_hash_table_new(str_hash, str_equal);
}
static int parse_attribute_rtcp(struct sdp_attribute *output) {
char *ep, *start, *end;
end = output->value.s + output->value.len;
output->attr = ATTR_RTCP;
output->u.rtcp.port_num = strtol(output->value.s, &ep, 10);
if (ep == output->value.s)
return -1;
if (output->u.rtcp.port_num <= 0 || output->u.rtcp.port_num > 0xffff) {
output->u.rtcp.port_num = 0;
return -1;
}
if (*ep != ' ')
return 0;
ep++;
if (ep >= end)
return 0;
start = ep;
EXTRACT_NETWORK_ADDRESS(u.rtcp.address);
return 0;
}
static void parse_attribute(struct sdp_attribute *a) {
a->name = a->line_value;
str_chr_str(&a->value, &a->name, ':');
if (a->value.s) {
a->name.len -= a->value.len;
a->value.s++;
a->value.len--;
a->key = a->name;
str_chr_str(&a->param, &a->value, ' ');
if (a->param.s) {
a->key.len += 1 +
(a->value.len - a->param.len);
a->param.s++;
a->param.len--;
if (!a->param.len)
a->param.s = NULL;
}
else
a->key.len += 1 + a->value.len;
}
switch (a->name.len) {
case 4:
if (!str_cmp(&a->name, "rtcp"))
parse_attribute_rtcp(a);
break;
}
}
int sdp_parse(str *body, GQueue *sessions) {
char *b, *end, *value, *line_end, *next_line;
struct sdp_session *session = NULL;
@ -279,28 +349,7 @@ int sdp_parse(str *body, GQueue *sessions) {
attr->line_value.s = value;
attr->line_value.len = line_end - value;
attr->name = attr->line_value;
str_chr_str(&attr->value, &attr->name, ':');
if (attr->value.s) {
attr->name.len -= attr->value.len;
attr->value.s++;
attr->value.len--;
attr->key = attr->name;
str_chr_str(&attr->param, &attr->value, ' ');
if (attr->param.s) {
attr->key.len += 1 +
(attr->value.len - attr->param.len);
attr->param.s++;
attr->param.len--;
if (!attr->param.len)
attr->param.s = NULL;
}
else
attr->key.len += 1 + attr->value.len;
}
parse_attribute(attr);
attrs = media ? &media->attributes : &session->attributes;
g_queue_push_tail(&attrs->list, attr);
@ -385,6 +434,8 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, GHashTable *streamhash)
GList *l, *k;
const char *errstr;
int i, num;
str s;
struct sdp_attribute *attr;
num = 0;
for (l = sessions->head; l; l = l->next) {
@ -393,6 +444,7 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, GHashTable *streamhash)
for (k = session->media_streams.head; k; k = k->next) {
media = k->data;
si = NULL;
for (i = 0; i < media->port_count; i++) {
si = g_slice_alloc0(sizeof(*si));
@ -411,6 +463,13 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, GHashTable *streamhash)
g_hash_table_insert(streamhash, si, si);
g_queue_push_tail(streams, si);
}
if (!si || media->port_count != 1)
continue;
str_init(&s, "rtcp");
attr = g_hash_table_lookup(media->attributes.hash, &s);
if (!attr)
continue;
}
}
@ -762,6 +821,7 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call *call,
chopper_append_c(chop, " 2 UDP 2130706430 ");
insert_ice_address(chop, m, off, flags, 1);
chopper_append_c(chop, " typ host\r\n");
/* XXX handle rtcp here too */
}
}
}

Loading…
Cancel
Save