sbc:rtp_relay: dynamic number of RTP relay streams

sayer/1.4-spce2.6
Stefan Sayer 15 years ago committed by Raphael Coeffic
parent d8e68b90aa
commit ce352a7726

@ -547,8 +547,7 @@ void SBCDialog::onInvite(const AmSipRequest& req)
}
if (call_profile.rtprelay_enabled) {
DBG("Enabling RTP relay mode\n");
rtp_relay_enabled = true;
DBG("Enabling RTP relay mode for SBC call\n");
// force symmetric RTP?
if (!call_profile.force_symmetric_rtp.empty()) {
@ -576,11 +575,14 @@ void SBCDialog::onInvite(const AmSipRequest& req)
}
}
}
enableRtpRelay(req);
}
m_state = BB_Dialing;
invite_req = req;
est_invite_cseq = req.cseq;
removeHeader(invite_req.hdrs,PARAM_HDR);
removeHeader(invite_req.hdrs,"P-App-Name");

@ -42,7 +42,9 @@ AmB2BSession::AmB2BSession()
: sip_relay_only(true),
b2b_mode(B2BMode_Transparent),
rtp_relay_enabled(false),
rtp_relay_force_symmetric_rtp(false)
rtp_relay_force_symmetric_rtp(false),
relay_rtp_streams(NULL), relay_rtp_streams_cnt(0),
est_invite_cseq(0)
{
for (unsigned int i=0; i<MAX_RELAY_STREAMS; i++)
other_stream_fds[i] = 0;
@ -52,7 +54,9 @@ AmB2BSession::AmB2BSession(const string& other_local_tag)
: other_id(other_local_tag),
sip_relay_only(true),
rtp_relay_enabled(false),
rtp_relay_force_symmetric_rtp(false)
rtp_relay_force_symmetric_rtp(false),
relay_rtp_streams(NULL), relay_rtp_streams_cnt(0),
est_invite_cseq(0)
{
for (unsigned int i=0; i<MAX_RELAY_STREAMS; i++)
other_stream_fds[i] = 0;
@ -63,6 +67,9 @@ AmB2BSession::~AmB2BSession()
if (rtp_relay_enabled)
clearRtpReceiverRelay();
if (NULL != relay_rtp_streams)
delete[] relay_rtp_streams;
DBG("relayed_req.size() = %u\n",(unsigned int)relayed_req.size());
DBG("recvd_req.size() = %u\n",(unsigned int)recvd_req.size());
}
@ -204,28 +211,46 @@ void AmB2BSession::onSipRequest(const AmSipRequest& req)
B2BSipRequestEvent* r_ev = new B2BSipRequestEvent(req,fwd);
AmSdp filter_sdp;
auto_ptr<AmSdp> req_sdp;
// filter relayed INVITE/UPDATE body
if (fwd && b2b_mode != B2BMode_Transparent &&
(req.method == SIP_METH_INVITE || req.method == SIP_METH_UPDATE ||
req.method == SIP_METH_ACK)) {
if (req.cseq == est_invite_cseq && req.method == SIP_METH_INVITE)
req_sdp.reset(invite_sdp.release());
if (NULL == req_sdp.get())
req_sdp.reset(new AmSdp());
DBG("filtering body for request '%s' (c/t '%s')\n",
req.method.c_str(), req.content_type.c_str());
// todo: handle filtering errors
filterBody(r_ev->req.content_type, r_ev->req.body, filter_sdp, a_leg);
filterBody(r_ev->req.content_type, r_ev->req.body, *req_sdp.get(), a_leg);
}
if (rtp_relay_enabled &&
(req.method == SIP_METH_INVITE || req.method == SIP_METH_UPDATE ||
req.method == SIP_METH_ACK || req.method == SIP_METH_ACK)) {
updateRelayStreams(r_ev->req.content_type, r_ev->req.body, filter_sdp);
req.method == SIP_METH_ACK || req.method == SIP_METH_ACK)
// don't update for initial INVITE again
&& (!(req.cseq == est_invite_cseq && req.method == SIP_METH_INVITE))
) {
if (NULL == req_sdp.get()) {
if (req.cseq == est_invite_cseq && req.method == SIP_METH_INVITE)
req_sdp.reset(invite_sdp.release());
if (NULL == req_sdp.get())
req_sdp.reset(new AmSdp());
}
updateRelayStreams(r_ev->req.content_type, r_ev->req.body, *req_sdp.get());
}
relayEvent(r_ev);
}
/** update RTP relay streams with address/port from SDP body */
/** update RTP relay streams with address/port from SDP body
create rtp_relay_streams if not existing
*/
void AmB2BSession::updateRelayStreams(const string& content_type, const string& body,
AmSdp& parser_sdp) {
if (body.empty() || (content_type != SIP_APPLICATION_SDP))
@ -240,13 +265,25 @@ void AmB2BSession::updateRelayStreams(const string& content_type, const string&
}
}
if (NULL == relay_rtp_streams) {
relay_rtp_streams_cnt = parser_sdp.media.size();
if (relay_rtp_streams_cnt > MAX_RELAY_STREAMS) {
WARN("got SDP with more media streams (%zd) than MAX_RELAY_STREAMS (%u),"
"consider changing MAX_RELAY_STREAMS and rebuilding SEMS.\n",
relay_rtp_streams_cnt, MAX_RELAY_STREAMS);
relay_rtp_streams_cnt = MAX_RELAY_STREAMS;
}
relay_rtp_streams = new AmRtpStream[relay_rtp_streams_cnt];
DBG("Created %u RTP relay streams\n", relay_rtp_streams_cnt);
}
unsigned int media_index = 0;
for (std::vector<SdpMedia>::iterator it =
parser_sdp.media.begin(); it != parser_sdp.media.end(); it++) {
if (media_index >= MAX_RELAY_STREAMS) {
ERROR("trying to relay SDP with more media lines than MAX_RELAY_STREAMS (%u)"
"(consider increasing MAX_RELAY_STREAMS and rebuilding SEMS)\n",
MAX_RELAY_STREAMS);
if (media_index >= relay_rtp_streams_cnt) {
WARN("trying to relay SDP with more media lines than "
"relay streams initialized (%u)\n", relay_rtp_streams_cnt);
break;
}
string r_addr = it->conn.address;
@ -291,10 +328,9 @@ bool AmB2BSession::replaceConnectionAddress(const string& content_type,
unsigned int media_index = 0;
for (std::vector<SdpMedia>::iterator it =
parser_sdp.media.begin(); it != parser_sdp.media.end(); it++) {
if (media_index >= MAX_RELAY_STREAMS) {
ERROR("trying to relay SDP with more media lines than MAX_RELAY_STREAMS (%u)"
"(consider increasing MAX_RELAY_STREAMS and rebuilding SEMS)\n",
MAX_RELAY_STREAMS);
if (media_index >= relay_rtp_streams_cnt) {
WARN("trying to relay SDP with more media lines than "
"relay streams initialized (%u)\n", relay_rtp_streams_cnt);
break;
}
if (!it->conn.address.empty())
@ -654,6 +690,17 @@ int AmB2BSession::filterBody(AmSdp& sdp, bool is_a2b) {
return 0;
}
void AmB2BSession::enableRtpRelay(const AmSipRequest& initial_invite_req) {
DBG("enabled RTP relay mode for B2B call '%s'\n",
getLocalTag().c_str());
rtp_relay_enabled = true;
// save AmSdp object of initial INVITE body
invite_sdp.reset(new AmSdp());
updateRelayStreams(initial_invite_req.content_type, initial_invite_req.body,
*invite_sdp.get());
}
void AmB2BSession::enableRtpRelay() {
DBG("enabled RTP relay mode for B2B call '%s'\n",
getLocalTag().c_str());
@ -675,8 +722,16 @@ void AmB2BSession::setupRelayStreams(AmB2BSession* other_session) {
return;
}
if (NULL == relay_rtp_streams) {
relay_rtp_streams_cnt = other_session->relay_rtp_streams_cnt;
DBG("creating %u RTP streams from other_session\n",
relay_rtp_streams_cnt);
relay_rtp_streams = new AmRtpStream[relay_rtp_streams_cnt];
}
// link the other streams as our relay streams
for (unsigned int i=0; i<MAX_RELAY_STREAMS; i++) {
for (unsigned int i=0; i<relay_rtp_streams_cnt; i++) {
other_session->relay_rtp_streams[i].setRelayStream(&relay_rtp_streams[i]);
other_stream_fds[i] = other_session->relay_rtp_streams[i].getLocalSocket();
// set local IP (todo: option for other interface!)
@ -686,7 +741,7 @@ void AmB2BSession::setupRelayStreams(AmB2BSession* other_session) {
}
void AmB2BSession::clearRtpReceiverRelay() {
for (unsigned int i=0; i<MAX_RELAY_STREAMS; i++) {
for (unsigned int i=0; i<relay_rtp_streams_cnt; i++) {
// clear the other call's RTP relay streams from RTP receiver
if (other_stream_fds[i]) {
AmRtpReceiver::instance()->removeStream(other_stream_fds[i]);
@ -919,9 +974,8 @@ void AmB2BCallerSession::initializeRTPRelay(AmB2BCalleeSession* callee_session)
setupRelayStreams(callee_session);
// bind caller session's relay_streams to a port
for (unsigned int i=0; i<MAX_RELAY_STREAMS; i++)
for (unsigned int i=0; i<relay_rtp_streams_cnt; i++)
relay_rtp_streams[i].getLocalPort();
}
AmB2BCalleeSession::AmB2BCalleeSession(const string& other_local_tag)
@ -994,6 +1048,9 @@ void AmB2BCalleeSession::onB2BEvent(B2BEvent* ev)
if (refresh_method != REFRESH_UPDATE)
saveSessionDescription(co_ev->content_type, co_ev->body);
// save CSeq of establising INVITE
est_invite_cseq = dlg.cseq - 1;
return;
}

@ -142,6 +142,10 @@ class AmB2BSession: public AmSession
/** Requests received for relaying */
std::map<int,AmSipRequest> recvd_req;
/** CSeq of the INVITE that established this call */
unsigned int est_invite_cseq;
auto_ptr<AmSdp> invite_sdp;
/** content-type of established session */
string established_content_type;
/** body of established session */
@ -220,9 +224,12 @@ class AmB2BSession: public AmSession
/** force symmetric RTP */
bool rtp_relay_force_symmetric_rtp;
/** RTP streams which receive from our side and are used
for relaying RTP from the other side */
AmRtpStream relay_rtp_streams[MAX_RELAY_STREAMS];
AmRtpStream* relay_rtp_streams;
/** number of relay RTP streams */
unsigned int relay_rtp_streams_cnt;
/** fd of the other streams' sockets (to remove from
RtpReceiver at end of relaying) */
int other_stream_fds[MAX_RELAY_STREAMS];
@ -239,6 +246,8 @@ class AmB2BSession: public AmSession
void set_sip_relay_only(bool r);
B2BMode getB2BMode() const;
/** set RTP relay mode enabled for initial INVITE */
void enableRtpRelay(const AmSipRequest& initial_invite_req);
/** set RTP relay mode enabled */
void enableRtpRelay();
/** set RTP relay mode disabled */

Loading…
Cancel
Save