|
|
|
|
@ -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)
|
|
|
|
|
{
|
|
|
|
|
|