add unknown attributes (a=) parsing

both session and media level
sayer/1.4-spce2.6
Stefan Sayer 16 years ago
parent 5e74930489
commit 10ba13bf80

@ -28,6 +28,7 @@ using std::map;
#include "strings.h"
#endif
static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next);
static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s);
static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t);
static void parse_sdp_media(AmSdp* sdp_msg, char* s);
@ -37,6 +38,7 @@ static void parse_sdp_origin(AmSdp* sdp_masg, char* s);
inline char* get_next_line(char* s);
static char* is_eql_next(char* s);
static char* parse_until(char* s, char end);
static char* parse_until(char* s, char* end, char c);
static bool contains(char* s, char* next_line, char c);
static bool is_wsp(char s);
@ -99,6 +101,13 @@ bool SdpPayload::operator == (int r)
return payload_type == r;
}
string SdpAttribute::print() const {
if (value.empty())
return "a="+attribute+CRLF;
else
return "a="+attribute+":"+value+CRLF;
}
//
// class AmSdp: Methods
//
@ -167,6 +176,12 @@ void AmSdp::print(string& body) const
"c=IN IP4 "+conn.address+"\r\n"
"t=0 0\r\n";
// add attributes (session level)
for (std::vector<SdpAttribute>::const_iterator a_it=
attributes.begin(); a_it != attributes.end(); a_it++) {
out_buf += a_it->print();
}
for(std::vector<SdpMedia>::const_iterator media_it = media.begin();
media_it != media.end(); media_it++) {
@ -200,6 +215,13 @@ void AmSdp::print(string& body) const
if(remote_active /* dir == SdpMedia::DirActive */)
out_buf += "a=direction:passive\r\n";
// add attributes (media level)
for (std::vector<SdpAttribute>::const_iterator a_it=
media_it->attributes.begin(); a_it != media_it->attributes.end(); a_it++) {
out_buf += a_it->print();
}
}
body = out_buf;
@ -508,7 +530,8 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s)
case 'a':
DBG("parse_sdp_line_ex: found attributes\n");
s = is_eql_next(s);
next = get_next_line(s);
parse_session_attr(sdp_msg, s, &next);
// next = get_next_line(s);
// parse_sdp_attr(sdp_msg, s);
s = next;
state = SDP_DESCR;
@ -776,6 +799,40 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
return;
}
static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next) {
*next = get_next_line(s);
if (*next == s) {
WARN("premature end of SDP in session attr\n");
while (**next != '\0') (*next)++;
return;
}
char* attr_end = *next-1;
while (attr_end >= s &&
((*attr_end == 10) || (*attr_end == 13)))
attr_end--;
if (*attr_end == ':') {
WARN("incorrect SDP: value attrib without value: '%s'\n",
string(s, attr_end-s+1).c_str());
return;
}
char* col = parse_until(s, attr_end, ':');
if (col == attr_end) {
// property attribute
sdp_msg->attributes.push_back(SdpAttribute(string(s, attr_end-s+1)));
DBG("got session attribute '%.*s\n", attr_end-s+1, s);
} else {
// value attribute
sdp_msg->attributes.push_back(SdpAttribute(string(s, col-s-1),
string(col, attr_end-col+1)));
DBG("got session attribute '%.*s:%.*s'\n", col-s-1, s, attr_end-col+1, col);
}
}
static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
{
@ -960,6 +1017,7 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
string value(attr_line, int(next-attr_line)-1);
DBG("found media attr '%s' value '%s'\n",
(char*)attr.c_str(), (char*)value.c_str());
media.attributes.push_back(SdpAttribute(attr, value));
} else {
DBG("found media attr '%s', but value is not followed by cr\n",
(char *)attr.c_str());
@ -973,6 +1031,7 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
string attr(attr_line, int(next-attr_line)-1);
attr_check(attr);
DBG("found media attr '%s'\n", (char*)attr.c_str());
media.attributes.push_back(SdpAttribute(attr));
} else {
DBG("found media attr line '%s', which is not followed by cr\n",
attr_line);
@ -1120,6 +1179,16 @@ static char* parse_until(char* s, char end)
return line;
}
static char* parse_until(char* s, char* end, char c)
{
char* line=s;
while(line<end && *line && *line != c ){
line++;
}
if (line<end)
line++;
return line;
}
static char* is_eql_next(char* s)
{

@ -106,6 +106,23 @@ struct SdpPayload
bool operator == (int r);
};
/** \brief a=... line in SDP */
struct SdpAttribute
{
string attribute;
string value;
// property attribute
SdpAttribute(const string& attribute,
const string& value)
: attribute(attribute), value(value) { }
// value attribute
SdpAttribute(const string& attribute)
: attribute(attribute) { }
string print() const;
};
/** \brief m=... line in SDP */
struct SdpMedia
@ -125,6 +142,8 @@ struct SdpMedia
std::vector<SdpPayload> payloads;
std::vector<SdpAttribute> attributes; // unknown attributes
SdpMedia() : conn() {}
};
@ -152,6 +171,8 @@ public:
string sessionName; // s=
string uri; // u=
SdpConnection conn; // c=
std::vector<SdpAttribute> attributes; // unknown session level attributes
std::vector<SdpMedia> media; // m= ... [a=rtpmap:...]+
// Supported payloads

Loading…
Cancel
Save