b/f: T38 streams in SBC/B2B (udptl transport); proper media direction passthrough

Conflicts:

	core/AmSdp.cpp
sayer/1.4-spce2.6
Stefan Sayer 15 years ago
parent 1d86e099d3
commit 8c10653865

@ -23,6 +23,9 @@
using std::string;
using std::map;
#include <cctype>
#include <algorithm>
// Not on Solaris!
#if !defined (__SVR4) && !defined (__sun)
#include "strings.h"
@ -42,8 +45,8 @@ 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);
static int media_type(std::string media);
static int transport_type(std::string transport);
static MediaType media_type(std::string media);
static TransProt transport_type(std::string transport);
static bool attr_check(std::string attr);
enum parse_st {SDP_DESCR, SDP_MEDIA};
@ -81,6 +84,7 @@ inline string media_t_2_str(int mt)
case MT_APPLICATION: return "application";
case MT_TEXT: return "text";
case MT_MESSAGE: return "message";
case MT_IMAGE: return "image";
default: return "<unknown media type>";
}
}
@ -91,6 +95,7 @@ inline string transport_p_2_str(int tp)
case TP_RTPAVP: return "RTP/AVP";
case TP_UDP: return "udp";
case TP_RTPSAVP: return "RTP/SAVP";
case TP_UDPTL: return "udptl";
default: return "<unknown media type>";
}
}
@ -205,9 +210,10 @@ void AmSdp::print(string& body) const
out_buf += "m=" + media_t_2_str(media_it->type) + " " + int2str(media_it->port) + " " + transport_p_2_str(media_it->transport);
string options;
for(std::vector<SdpPayload>::const_iterator pl_it = media_it->payloads.begin();
pl_it != media_it->payloads.end(); pl_it++) {
if (media_it->transport == TP_RTPAVP || media_it->transport == TP_RTPSAVP) {
string options;
for(std::vector<SdpPayload>::const_iterator pl_it = media_it->payloads.begin();
pl_it != media_it->payloads.end(); pl_it++) {
out_buf += " " + int2str(pl_it->payload_type);
@ -215,30 +221,32 @@ void AmSdp::print(string& body) const
options += "c=IN IP4 "+media_it->conn.address+"\r\n";
if (pl_it->encoding_name.empty()) // don't add rtpmap if no encoding name given
continue;
continue;
// "a=rtpmap:" line
options += "a=rtpmap:" + int2str(pl_it->payload_type) + " "
+ pl_it->encoding_name + "/" + int2str(pl_it->clock_rate);
+ pl_it->encoding_name + "/" + int2str(pl_it->clock_rate);
if(pl_it->encoding_param > 0){
options += "/" + int2str(pl_it->encoding_param);
options += "/" + int2str(pl_it->encoding_param);
}
options += "\r\n";
// "a=fmtp:" line
if(pl_it->sdp_format_parameters.size()){
options += "a=fmtp:" + int2str(pl_it->payload_type) + " "
+ pl_it->sdp_format_parameters + "\r\n";
options += "a=fmtp:" + int2str(pl_it->payload_type) + " "
+ pl_it->sdp_format_parameters + "\r\n";
}
}
}
out_buf += "\r\n" + options;
out_buf += "\r\n" + options;
if(remote_active /* dir == SdpMedia::DirActive */)
out_buf += "a=direction:passive\r\n";
} else {
// for other transports (UDP/UDPTL) just print out fmt
out_buf += " " + media_it->fmt + "\r\n";
}
// add attributes (media level)
for (std::vector<SdpAttribute>::const_iterator a_it=
@ -246,6 +254,12 @@ void AmSdp::print(string& body) const
out_buf += a_it->print();
}
switch (media_it->dir) {
case SdpMedia::DirActive: out_buf += "a=direction:active\r\n"; break;
case SdpMedia::DirPassive: out_buf += "a=direction:passive\r\n"; break;
case SdpMedia::DirBoth: out_buf += "a=direction:both\r\n"; break;
case SdpMedia::DirUndefined: break;
}
}
body = out_buf;
@ -742,7 +756,6 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
SdpPayload payload;
unsigned int payload_type;
DBG("parse_sdp_line_ex: parse_sdp_media: parsing media description...\n");
m.dir = SdpMedia::DirBoth;
while(parsing){
switch(state){
@ -753,7 +766,7 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
if (next > media_line)
media = string(media_line, int(next-media_line)-1);
m.type = media_type(media);
if(m.type < 0) {
if(m.type == MT_NONE) {
ERROR("parse_sdp_media: Unknown media type\n");
}
media_line = next;
@ -802,7 +815,7 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
// break;
// }
m.transport = transport_type(proto);
if(m.transport < 0){
if(m.transport == TP_NONE){
DBG("Unknown transport protocol: %s\n",proto.c_str());
}
media_line = next;
@ -811,41 +824,49 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
}
case FMT:
{
if (contains(media_line, line_end, ' ')) {
next = parse_until(media_line, ' ');
string value;
if (next > media_line)
value = string(media_line, int(next-media_line)-1);
if (!value.empty()) {
payload.type = m.type;
str2i(value, payload_type);
payload.payload_type = payload_type;
m.payloads.push_back(payload);
}
media_line = next;
state = FMT;
} else {
string last_value;
if (line_end>media_line) {
if (*line_end == '\0') {
// last line in message
last_value = string(media_line, int(line_end-media_line));
} else {
last_value = string(media_line, int(line_end-media_line)-1);
if (m.transport == TP_RTPAVP || m.transport == TP_RTPSAVP) {
if (contains(media_line, line_end, ' ')) {
next = parse_until(media_line, ' ');
string value;
if (next > media_line)
value = string(media_line, int(next-media_line)-1);
if (!value.empty()) {
payload.type = m.type;
str2i(value, payload_type);
payload.payload_type = payload_type;
m.payloads.push_back(payload);
}
media_line = next;
} else {
string last_value;
if (line_end>media_line) {
if (*line_end == '\0') {
// last line in message
last_value = string(media_line, int(line_end-media_line));
} else {
last_value = string(media_line, int(line_end-media_line)-1);
}
}
if (!last_value.empty()) {
payload.type = m.type;
str2i(last_value, payload_type);
payload.payload_type = payload_type;
m.payloads.push_back(payload);
}
parsing = 0;
}
if (!last_value.empty()) {
payload.type = m.type;
str2i(last_value, payload_type);
payload.payload_type = payload_type;
m.payloads.push_back(payload);
}
} else {
line_end--;
while (line_end > media_line &&
(*line_end == '\r' || *line_end == '\n'))
line_end--;
if (line_end>media_line)
m.fmt = string(media_line, line_end-media_line+1);
DBG("set media fmt to '%s'\n", m.fmt.c_str());
parsing = 0;
}
break;
}
} break;
}
}
sdp_msg->media.push_back(m);
@ -1278,32 +1299,39 @@ inline char* get_next_line(char* s)
/*
*Check if known media type is used
*/
static int media_type(std::string media)
static MediaType media_type(std::string media)
{
if(media == "audio")
return 1;
return MT_AUDIO;
else if(media == "video")
return 2;
return MT_VIDEO;
else if(media == "application")
return 3;
return MT_APPLICATION;
else if(media == "text")
return 4;
return MT_TEXT;
else if(media == "message")
return 5;
return MT_MESSAGE;
else if(media == "image")
return MT_IMAGE;
else
return -1;
return MT_NONE;
}
static int transport_type(std::string transport)
static TransProt transport_type(string transport)
{
if(transport == "RTP/AVP")
return 1;
else if(transport == "UDP")
return 2;
else if(transport == "RTP/SAVP")
return 3;
string transport_uc = transport;
std::transform(transport_uc.begin(), transport_uc.end(), transport_uc.begin(), toupper);
if(transport_uc == "RTP/AVP")
return TP_RTPAVP;
else if(transport_uc == "UDP")
return TP_UDP;
else if(transport_uc == "RTP/SAVP")
return TP_RTPSAVP;
else if(transport_uc == "UDPTL")
return TP_UDPTL;
else
return -1;
return TP_NONE;
}
/*

@ -53,9 +53,9 @@ enum NetworkType { NT_OTHER=0, NT_IN };
/** address type */
enum AddressType { AT_NONE=0, AT_V4, AT_V6 };
/** media type */
enum MediaType { MT_NONE=0, MT_AUDIO, MT_VIDEO, MT_APPLICATION, MT_TEXT, MT_MESSAGE };
enum MediaType { MT_NONE=0, MT_AUDIO, MT_VIDEO, MT_APPLICATION, MT_TEXT, MT_MESSAGE, MT_IMAGE };
/** transport protocol */
enum TransProt { TP_NONE=0, TP_RTPAVP, TP_UDP, TP_RTPSAVP };
enum TransProt { TP_NONE=0, TP_RTPAVP, TP_UDP, TP_RTPSAVP, TP_UDPTL };
/** \brief c=... line in SDP*/
struct SdpConnection
@ -131,7 +131,8 @@ struct SdpMedia
enum Direction {
DirBoth=0,
DirActive=1,
DirPassive=2
DirPassive=2,
DirUndefined=3
};
int type;
@ -140,12 +141,13 @@ struct SdpMedia
int transport;
SdpConnection conn; // c=
Direction dir; // a=direction
string fmt; // format in case proto != RTP/AVP or RTP/SAVP
std::vector<SdpPayload> payloads;
std::vector<SdpAttribute> attributes; // unknown attributes
SdpMedia() : conn() {}
SdpMedia() : conn(), dir(DirUndefined), type(MT_NONE), transport(TP_NONE) {}
};
/**

Loading…
Cancel
Save