yate/libs/ysdp/media.cpp

190 lines
5.0 KiB
C++

/**
* media.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* SDP media handling
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004-2009 Null Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <yatesdp.h>
namespace TelEngine {
/*
* SDPMedia
*/
SDPMedia::SDPMedia(const char* media, const char* transport, const char* formats,
int rport, int lport)
: NamedList(media),
m_audio(true), m_modified(false), m_securable(true), m_localChanged(false),
m_transport(transport), m_formats(formats),
m_rfc2833(String::boolText(false))
{
DDebug(DebugAll,"SDPMedia::SDPMedia('%s','%s','%s',%d,%d) [%p]",
media,transport,formats,rport,lport,this);
if (String::operator!=("audio")) {
m_audio = false;
m_suffix << "_" << media;
}
int q = m_formats.find(',');
m_format = m_formats.substr(0,q);
if (rport >= 0)
m_rPort = rport;
if (lport >= 0)
m_lPort = lport;
}
SDPMedia::~SDPMedia()
{
DDebug(DebugAll,"SDPMedia::~SDPMedia() '%s' [%p]",c_str(),this);
}
const char* SDPMedia::fmtList() const
{
if (m_formats)
return m_formats.c_str();
if (m_format)
return m_format.c_str();
// unspecified audio assumed to support G711
if (m_audio)
return "alaw,mulaw";
return 0;
}
// Update members with data taken from a SDP, return true if something changed
bool SDPMedia::update(const char* formats, int rport, int lport)
{
DDebug(DebugAll,"SDPMedia::update('%s',%d,%d) [%p]",formats,rport,lport,this);
bool chg = false;
String tmp(formats);
if (m_formats != tmp) {
if ((tmp.find(',') < 0) && m_formats && m_formats.find(tmp) < 0)
Debug(DebugInfo,"Not changing to '%s' from '%s' [%p]",
formats,m_formats.c_str(),this);
else {
chg = true;
m_formats = tmp;
int q = m_formats.find(',');
m_format = m_formats.substr(0,q);
}
}
if (rport >= 0) {
tmp = rport;
if (m_rPort != tmp) {
chg = true;
m_rPort = tmp;
}
}
if (lport >= 0) {
tmp = lport;
if (m_lPort != tmp) {
m_localChanged = true;
chg = true;
m_lPort = tmp;
}
}
return chg;
}
// Update members from a dispatched "chan.rtp" message
void SDPMedia::update(const NamedList& msg, bool pickFormat)
{
DDebug(DebugAll,"SDPMedia::update('%s',%s) [%p]",
msg.c_str(),String::boolText(pickFormat),this);
m_id = msg.getValue("rtpid",m_id);
m_lPort = msg.getValue("localport",m_lPort);
if (pickFormat) {
const char* format = msg.getValue("format");
if (format) {
m_format = format;
if ((m_formats != m_format) && (msg.getIntValue("remoteport") > 0)) {
Debug(DebugNote,"Choosing started '%s' format '%s' [%p]",
c_str(),format,this);
m_formats = m_format;
}
}
}
}
// Add or replace a parameter by name and value, set the modified flag
void SDPMedia::parameter(const char* name, const char* value, bool append)
{
if (!name)
return;
m_modified = true;
if (append)
addParam(name,value);
else
setParam(name,value);
}
// Add or replace a parameter, set the modified flag
void SDPMedia::parameter(NamedString* param, bool append)
{
if (!param)
return;
m_modified = true;
if (append)
addParam(param);
else
setParam(param);
}
void SDPMedia::crypto(const char* desc, bool remote)
{
String& sdes = remote ? m_rCrypto : m_lCrypto;
if (sdes != desc) {
sdes = desc;
m_modified = true;
}
if (remote && !desc)
m_securable = false;
}
// Put the list of net media in a parameter list
void SDPMedia::putMedia(NamedList& msg, bool putPort)
{
msg.addParam("media" + suffix(),"yes");
msg.addParam("formats" + suffix(),formats());
msg.addParam("transport" + suffix(),transport());
if (mappings())
msg.addParam("rtp_mapping" + suffix(),mappings());
if (isAudio())
msg.addParam("rtp_rfc2833",rfc2833());
if (putPort)
msg.addParam("rtp_port" + suffix(),remotePort());
if (remoteCrypto())
msg.addParam("crypto" + suffix(),remoteCrypto());
// must handle encryption differently
const char* enc = getValue("encryption");
if (enc)
msg.addParam("encryption" + suffix(),enc);
clearParam("encryption");
unsigned int n = length();
for (unsigned int i = 0; i < n; i++) {
const NamedString* param = getParam(i);
if (param)
msg.addParam("sdp" + suffix() + "_" + param->name(),*param);
}
}
}; // namespace TelEngine
/* vi: set ts=8 sw=4 sts=4 noet: */