*** empty log message ***
git-svn-id: http://yate.null.ro/svn/yate/trunk@321 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
b52a90a618
commit
9e29ce8476
|
@ -81,11 +81,11 @@ cvsclean: check-topdir clean clean-tables clean-apidocs clean-config-files
|
|||
engine: tables library libyate.so $(PROGS)
|
||||
|
||||
apidocs-build: check-topdir
|
||||
kdoc -C ./kdoc-filter.sh -d docs/api/ $(INCS)
|
||||
kdoc -C ./kdoc-filter.sh -d docs/api/ $(INCS) contrib/ysip/yatesip.h contrib/yrtp/yatertp.h
|
||||
|
||||
apidocs: @srcdir@/docs/api/index.html
|
||||
|
||||
@srcdir@/docs/api/index.html: @srcdir@/yatengine.h @srcdir@/yatephone.h
|
||||
@srcdir@/docs/api/index.html: @srcdir@/yateclass.h @srcdir@/yatengine.h @srcdir@/yatephone.h @srcdir@/contrib/ysip/yatesip.h @srcdir@/contrib/yrtp/yatertp.h
|
||||
$(MAKE) apidocs-build
|
||||
|
||||
.PHONY: strip sex love war
|
||||
|
|
|
@ -13,7 +13,7 @@ INCFILES := @top_srcdir@/yateclass.h @srcdir@/yatertp.h
|
|||
|
||||
PROGS=
|
||||
LIBS = libyatertp.a
|
||||
OBJS =
|
||||
OBJS = transport.o session.o
|
||||
|
||||
LOCALFLAGS =
|
||||
LOCALLIBS =
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* session.cpp
|
||||
* Yet Another RTP Stack
|
||||
* This file is part of the YATE Project http://YATE.null.ro
|
||||
*
|
||||
* Yet Another Telephony Engine - a fully featured software PBX and IVR
|
||||
* Copyright (C) 2004, 2005 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <yatertp.h>
|
||||
|
||||
using namespace TelEngine;
|
||||
|
||||
RTPSession::RTPSession()
|
||||
: m_transport(0)
|
||||
{
|
||||
}
|
||||
|
||||
RTPSession::~RTPSession()
|
||||
{
|
||||
if (m_transport) {
|
||||
m_transport->setProcessor(0);
|
||||
m_transport = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RTPSession::timerTick(const Time& when)
|
||||
{
|
||||
if (m_transport)
|
||||
m_transport->timerTick(when);
|
||||
}
|
||||
|
||||
void RTPSession::rtpData(const void* data, int len)
|
||||
{
|
||||
}
|
||||
|
||||
void RTPSession::rtcpData(const void* data, int len)
|
||||
{
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* transport.cpp
|
||||
* Yet Another RTP Stack
|
||||
* This file is part of the YATE Project http://YATE.null.ro
|
||||
*
|
||||
* Yet Another Telephony Engine - a fully featured software PBX and IVR
|
||||
* Copyright (C) 2004, 2005 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <yatertp.h>
|
||||
|
||||
#define BUF_SIZE 1500
|
||||
|
||||
using namespace TelEngine;
|
||||
|
||||
RTPTransport::RTPTransport()
|
||||
: m_processor(0)
|
||||
{
|
||||
}
|
||||
|
||||
void RTPTransport::timerTick(const Time& when)
|
||||
{
|
||||
if (m_rtpSock.valid()) {
|
||||
bool ok = false;
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
if (m_rtpSock.select(&ok,0,0,&tv) && ok) {
|
||||
char buf[BUF_SIZE];
|
||||
SocketAddr addr;
|
||||
int len = m_rtpSock.recvFrom(buf,sizeof(buf),addr);
|
||||
if (m_processor && (len >= 12) && (addr == m_remoteAddr))
|
||||
m_processor->rtpData(buf,len);
|
||||
}
|
||||
}
|
||||
if (m_rtcpSock.valid()) {
|
||||
bool ok = false;
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
if (m_rtcpSock.select(&ok,0,0,&tv) && ok) {
|
||||
char buf[BUF_SIZE];
|
||||
SocketAddr addr;
|
||||
int len = m_rtcpSock.recvFrom(buf,sizeof(buf),addr);
|
||||
if (m_processor && (len >= 8) && (addr == m_remoteRTCP))
|
||||
m_processor->rtcpData(buf,len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RTPTransport::rtpData(const void* data, int len)
|
||||
{
|
||||
if (m_rtpSock.valid() && m_remoteAddr.valid())
|
||||
m_rtpSock.sendTo(data,len,m_remoteAddr);
|
||||
}
|
||||
|
||||
void RTPTransport::rtcpData(const void* data, int len)
|
||||
{
|
||||
if (m_rtcpSock.valid() && m_remoteRTCP.valid())
|
||||
m_rtcpSock.sendTo(data,len,m_remoteRTCP);
|
||||
}
|
||||
|
||||
void RTPTransport::setProcessor(RTPProcessor* processor)
|
||||
{
|
||||
m_processor = processor;
|
||||
}
|
||||
|
||||
bool RTPTransport::localAddr(SocketAddr& addr)
|
||||
{
|
||||
int p = addr.port();
|
||||
// make sure we don't have a port or it's an even one
|
||||
if ((p & 1) == 0) {
|
||||
m_localAddr = addr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RTPTransport::remoteAddr(SocketAddr& addr)
|
||||
{
|
||||
int p = addr.port();
|
||||
// make sure we have a port and it's an even one
|
||||
if (p && ((p & 1) == 0)) {
|
||||
m_remoteAddr = addr;
|
||||
m_remoteRTCP = addr;
|
||||
m_remoteRTCP.port(addr.port()+1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
|
@ -27,17 +27,178 @@
|
|||
#include <yateclass.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
#ifdef LIBYRTP_EXPORTS
|
||||
#define YRTP_API __declspec(dllexport)
|
||||
#else
|
||||
#ifndef LIBYRTP_STATIC
|
||||
#define YRTP_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define YRTP_API
|
||||
#endif
|
||||
|
||||
#endif /* _WINDOWS */
|
||||
|
||||
#ifndef YRTP_API
|
||||
#define YRTP_API
|
||||
#endif
|
||||
|
||||
namespace TelEngine {
|
||||
|
||||
/**
|
||||
* A base class that contains just placeholders to process raw RTP and RTCP packets.
|
||||
* @short Base class to ease creation of RTP forwarders
|
||||
*/
|
||||
class YRTP_API RTPProcessor : public GenObject
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Do-nothing constructor
|
||||
*/
|
||||
inline RTPProcessor()
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Do-nothing destructor
|
||||
*/
|
||||
inline ~RTPProcessor()
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Method called periodically to keep the data flowing
|
||||
* @param when Time to use as base in all computing
|
||||
*/
|
||||
virtual void timerTick(const Time& when) = 0;
|
||||
|
||||
/**
|
||||
* This method is called to send or process a RTP packet
|
||||
* @param data Pointer to raw RTP data
|
||||
* @param len Length of the data packet
|
||||
*/
|
||||
virtual void rtpData(const void* data, int len) = 0;
|
||||
|
||||
/**
|
||||
* This method is called to send or process a RTCP packet
|
||||
* @param data Pointer to raw RTCP data
|
||||
* @param len Length of the data packet
|
||||
*/
|
||||
virtual void rtcpData(const void* data, int len) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that holds sockets and addresses for transporting RTP and RTCP packets.
|
||||
* @short Low level transport for RTP and RTCP
|
||||
*/
|
||||
class YRTP_API RTPTransport : public RTPProcessor
|
||||
{
|
||||
public:
|
||||
enum Activation {
|
||||
Inactive,
|
||||
Bound,
|
||||
Active
|
||||
};
|
||||
|
||||
RTPTransport();
|
||||
|
||||
/**
|
||||
* Method called periodically to read data out of sockets
|
||||
* @param when Time to use as base in all computing
|
||||
*/
|
||||
virtual void timerTick(const Time& when);
|
||||
|
||||
/**
|
||||
* This method is called to send a RTP packet
|
||||
* @param data Pointer to raw RTP data
|
||||
* @param len Length of the data packet
|
||||
*/
|
||||
virtual void rtpData(const void* data, int len);
|
||||
|
||||
/**
|
||||
* This method is called to send a RTCP packet
|
||||
* @param data Pointer to raw RTCP data
|
||||
* @param len Length of the data packet
|
||||
*/
|
||||
virtual void rtcpData(const void* data, int len);
|
||||
|
||||
/**
|
||||
* Set the RTP/RTCP processor of data received by this transport
|
||||
* @param processor A pointer to the RTPProcessor for this transport
|
||||
*/
|
||||
void setProcessor(RTPProcessor* processor);
|
||||
|
||||
/**
|
||||
* Get the local network address of the RTP transport
|
||||
* @return Reference to the local RTP transport address
|
||||
*/
|
||||
inline const SocketAddr& localAddr() const
|
||||
{ return m_localAddr; }
|
||||
|
||||
/**
|
||||
* Get the remote network address of the RTP transport
|
||||
* @return Reference to the remote RTP transport address
|
||||
*/
|
||||
inline const SocketAddr& remoteAddr() const
|
||||
{ return m_remoteAddr; }
|
||||
|
||||
/**
|
||||
* Set the local network address of the RTP transport
|
||||
* @param addr New local RTP transport address
|
||||
* @return True if address set, false if a failure occured
|
||||
*/
|
||||
bool localAddr(SocketAddr& addr);
|
||||
|
||||
/**
|
||||
* Set the remote network address of the RTP transport
|
||||
* @param addr New remote RTP transport address
|
||||
* @return True if address set, false if a failure occured
|
||||
*/
|
||||
bool remoteAddr(SocketAddr& addr);
|
||||
|
||||
protected:
|
||||
RTPProcessor* m_processor;
|
||||
Socket m_rtpSock;
|
||||
Socket m_rtcpSock;
|
||||
SocketAddr m_localAddr;
|
||||
SocketAddr m_remoteAddr;
|
||||
SocketAddr m_remoteRTCP;
|
||||
};
|
||||
|
||||
class YRTP_API RTPSession : public RTPProcessor
|
||||
{
|
||||
public:
|
||||
enum Direction {
|
||||
FullStop,
|
||||
RecvOnly,
|
||||
SendOnly,
|
||||
SendRecv
|
||||
};
|
||||
|
||||
RTPSession();
|
||||
|
||||
virtual ~RTPSession();
|
||||
|
||||
/**
|
||||
* Method called periodically to push any asynchronous data or statistics
|
||||
* @param when Time to use as base in all computing
|
||||
*/
|
||||
virtual void timerTick(const Time& when);
|
||||
|
||||
/**
|
||||
* This method is called to process a RTP packet
|
||||
* @param data Pointer to raw RTP data
|
||||
* @param len Length of the data packet
|
||||
*/
|
||||
virtual void rtpData(const void* data, int len);
|
||||
|
||||
/**
|
||||
* This method is called to process a RTCP packet
|
||||
* @param data Pointer to raw RTCP data
|
||||
* @param len Length of the data packet
|
||||
*/
|
||||
virtual void rtcpData(const void* data, int len);
|
||||
|
||||
protected:
|
||||
RTPTransport* m_transport;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ SIPBody* SIPBody::build(const char *buf, int len, const String& type)
|
|||
if (type == "application/sdp")
|
||||
return new SDPBody(type,buf,len);
|
||||
if (type.startsWith("text/"))
|
||||
return new StringBody(type,buf,len);
|
||||
return new BinaryBody(type,buf,len);
|
||||
return new SIPStringBody(type,buf,len);
|
||||
return new SIPBinaryBody(type,buf,len);
|
||||
}
|
||||
|
||||
SDPBody::SDPBody()
|
||||
|
@ -123,56 +123,56 @@ const NamedString* SDPBody::getLine(const char *name) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
BinaryBody::BinaryBody(const String& type, const char *buf, int len)
|
||||
SIPBinaryBody::SIPBinaryBody(const String& type, const char *buf, int len)
|
||||
: SIPBody(type)
|
||||
{
|
||||
m_body.assign((void*)buf,len);
|
||||
}
|
||||
|
||||
BinaryBody::BinaryBody(const BinaryBody& original)
|
||||
SIPBinaryBody::SIPBinaryBody(const SIPBinaryBody& original)
|
||||
: SIPBody(original.getType())
|
||||
{
|
||||
m_body = original.m_body;
|
||||
}
|
||||
|
||||
BinaryBody::~BinaryBody()
|
||||
SIPBinaryBody::~SIPBinaryBody()
|
||||
{
|
||||
}
|
||||
|
||||
void BinaryBody::buildBody() const
|
||||
void SIPBinaryBody::buildBody() const
|
||||
{
|
||||
Debug(DebugAll,"BinaryBody::buildBody() [%p]",this);
|
||||
Debug(DebugAll,"SIPBinaryBody::buildBody() [%p]",this);
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
SIPBody* BinaryBody::clone() const
|
||||
SIPBody* SIPBinaryBody::clone() const
|
||||
{
|
||||
return new BinaryBody(*this);
|
||||
return new SIPBinaryBody(*this);
|
||||
}
|
||||
|
||||
StringBody::StringBody(const String& type, const char *buf, int len)
|
||||
SIPStringBody::SIPStringBody(const String& type, const char *buf, int len)
|
||||
: SIPBody(type), m_text(buf,len)
|
||||
{
|
||||
}
|
||||
|
||||
StringBody::StringBody(const StringBody& original)
|
||||
SIPStringBody::SIPStringBody(const SIPStringBody& original)
|
||||
: SIPBody(original.getType()), m_text(original.m_text)
|
||||
{
|
||||
}
|
||||
|
||||
StringBody::~StringBody()
|
||||
SIPStringBody::~SIPStringBody()
|
||||
{
|
||||
}
|
||||
|
||||
void StringBody::buildBody() const
|
||||
void SIPStringBody::buildBody() const
|
||||
{
|
||||
Debug(DebugAll,"StringBody::buildBody() [%p]",this);
|
||||
Debug(DebugAll,"SIPStringBody::buildBody() [%p]",this);
|
||||
m_body.assign((void*)m_text.c_str(),m_text.length());
|
||||
}
|
||||
|
||||
SIPBody* StringBody::clone() const
|
||||
SIPBody* SIPStringBody::clone() const
|
||||
{
|
||||
return new StringBody(*this);
|
||||
return new SIPStringBody(*this);
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
|
@ -239,7 +239,7 @@ SIPTransaction* SIPEngine::addMessage(SIPMessage* message)
|
|||
if (message->isOutgoing())
|
||||
message->complete(this);
|
||||
// locate the branch parameter of last Via header - added by the UA
|
||||
const HeaderLine* hl = message->getLastHeader("Via");
|
||||
const SIPHeaderLine* hl = message->getLastHeader("Via");
|
||||
const NamedString* br = hl ? hl->getParam("branch") : 0;
|
||||
String branch(br ? *br : String::empty());
|
||||
if (!branch.startsWith("z9hG4bK"))
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
|
||||
using namespace TelEngine;
|
||||
|
||||
HeaderLine::HeaderLine(const char *name, const String& value)
|
||||
SIPHeaderLine::SIPHeaderLine(const char *name, const String& value)
|
||||
: NamedString(name)
|
||||
{
|
||||
DDebug(DebugAll,"HeaderLine::HeaderLine('%s','%s') [%p]",name,value.c_str(),this);
|
||||
DDebug(DebugAll,"SIPHeaderLine::SIPHeaderLine('%s','%s') [%p]",name,value.c_str(),this);
|
||||
if (value.null())
|
||||
return;
|
||||
int sp = value.find(';');
|
||||
|
@ -76,10 +76,10 @@ HeaderLine::HeaderLine(const char *name, const String& value)
|
|||
}
|
||||
}
|
||||
|
||||
HeaderLine::HeaderLine(const HeaderLine& original)
|
||||
SIPHeaderLine::SIPHeaderLine(const SIPHeaderLine& original)
|
||||
: NamedString(original.name(),original)
|
||||
{
|
||||
DDebug(DebugAll,"HeaderLine::HeaderLine(%p '%s') [%p]",&original,name().c_str(),this);
|
||||
DDebug(DebugAll,"SIPHeaderLine::SIPHeaderLine(%p '%s') [%p]",&original,name().c_str(),this);
|
||||
const ObjList* l = &original.params();
|
||||
for (; l; l = l->next()) {
|
||||
const NamedString* t = static_cast<const NamedString*>(l->get());
|
||||
|
@ -88,12 +88,12 @@ HeaderLine::HeaderLine(const HeaderLine& original)
|
|||
}
|
||||
}
|
||||
|
||||
HeaderLine::~HeaderLine()
|
||||
SIPHeaderLine::~SIPHeaderLine()
|
||||
{
|
||||
DDebug(DebugAll,"HeaderLine::~HeaderLine() [%p]",this);
|
||||
DDebug(DebugAll,"SIPHeaderLine::~SIPHeaderLine() [%p]",this);
|
||||
}
|
||||
|
||||
const NamedString* HeaderLine::getParam(const char *name) const
|
||||
const NamedString* SIPHeaderLine::getParam(const char *name) const
|
||||
{
|
||||
if (!(name && *name))
|
||||
return 0;
|
||||
|
@ -106,7 +106,7 @@ const NamedString* HeaderLine::getParam(const char *name) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void HeaderLine::setParam(const char *name, const char *value)
|
||||
void SIPHeaderLine::setParam(const char *name, const char *value)
|
||||
{
|
||||
ObjList* p = m_params.find(name);
|
||||
if (p)
|
||||
|
@ -115,7 +115,7 @@ void HeaderLine::setParam(const char *name, const char *value)
|
|||
m_params.append(new NamedString(name,value));
|
||||
}
|
||||
|
||||
void HeaderLine::delParam(const char *name)
|
||||
void SIPHeaderLine::delParam(const char *name)
|
||||
{
|
||||
ObjList* p = m_params.find(name);
|
||||
if (p)
|
||||
|
@ -187,12 +187,12 @@ SIPMessage::SIPMessage(const SIPMessage* message, bool newtran)
|
|||
version = message->version;
|
||||
uri = message->uri;
|
||||
copyAllHeaders(message,"Via");
|
||||
HeaderLine* hl = const_cast<HeaderLine*>(getHeader("Via"));
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("Via"));
|
||||
if (!hl) {
|
||||
String tmp;
|
||||
tmp << version << "/" << getParty()->getProtoName();
|
||||
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
||||
hl = new HeaderLine("Via",tmp);
|
||||
hl = new SIPHeaderLine("Via",tmp);
|
||||
header.append(hl);
|
||||
}
|
||||
if (newtran) {
|
||||
|
@ -237,7 +237,7 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
|
||||
// only set the dialog tag on ACK
|
||||
if (isACK()) {
|
||||
HeaderLine* hl = const_cast<HeaderLine*>(getHeader("To"));
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("To"));
|
||||
if (dlgTag && hl && !hl->getParam("tag"))
|
||||
hl->setParam("tag",dlgTag);
|
||||
return;
|
||||
|
@ -248,12 +248,12 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
if (!domain)
|
||||
domain = getParty()->getLocalAddr();
|
||||
|
||||
HeaderLine* hl = const_cast<HeaderLine*>(getHeader("Via"));
|
||||
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("Via"));
|
||||
if (!hl) {
|
||||
String tmp;
|
||||
tmp << version << "/" << getParty()->getProtoName();
|
||||
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
||||
hl = new HeaderLine("Via",tmp);
|
||||
hl = new SIPHeaderLine("Via",tmp);
|
||||
header.append(hl);
|
||||
}
|
||||
if (!(isAnswer() || hl->getParam("branch"))) {
|
||||
|
@ -266,21 +266,21 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
hl->setParam("rport",String(getParty()->getPartyPort()));
|
||||
}
|
||||
|
||||
hl = const_cast<HeaderLine*>(getHeader("From"));
|
||||
hl = const_cast<SIPHeaderLine*>(getHeader("From"));
|
||||
if (!hl) {
|
||||
String tmp;
|
||||
tmp << "<sip:" << user << "@" << domain << ">";
|
||||
hl = new HeaderLine("From",tmp);
|
||||
hl = new SIPHeaderLine("From",tmp);
|
||||
header.append(hl);
|
||||
}
|
||||
if (!(isAnswer() || hl->getParam("tag")))
|
||||
hl->setParam("tag",String((int)::random()));
|
||||
|
||||
hl = const_cast<HeaderLine*>(getHeader("To"));
|
||||
hl = const_cast<SIPHeaderLine*>(getHeader("To"));
|
||||
if (!hl) {
|
||||
String tmp;
|
||||
tmp << "<" << uri << ">";
|
||||
hl = new HeaderLine("To",tmp);
|
||||
hl = new SIPHeaderLine("To",tmp);
|
||||
header.append(hl);
|
||||
}
|
||||
if (dlgTag && !hl->getParam("tag"))
|
||||
|
@ -326,9 +326,9 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
|||
|
||||
bool SIPMessage::copyHeader(const SIPMessage* message, const char* name)
|
||||
{
|
||||
const HeaderLine* hl = message ? message->getHeader(name) : 0;
|
||||
const SIPHeaderLine* hl = message ? message->getHeader(name) : 0;
|
||||
if (hl) {
|
||||
header.append(new HeaderLine(*hl));
|
||||
header.append(new SIPHeaderLine(*hl));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -341,10 +341,10 @@ int SIPMessage::copyAllHeaders(const SIPMessage* message, const char* name)
|
|||
int c = 0;
|
||||
const ObjList* l = &message->header;
|
||||
for (; l; l = l->next()) {
|
||||
const HeaderLine* hl = static_cast<const HeaderLine*>(l->get());
|
||||
const SIPHeaderLine* hl = static_cast<const SIPHeaderLine*>(l->get());
|
||||
if (hl && (hl->name() &= name)) {
|
||||
++c;
|
||||
header.append(new HeaderLine(*hl));
|
||||
header.append(new SIPHeaderLine(*hl));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
|
@ -427,7 +427,7 @@ bool SIPMessage::parse(const char* buf, int len)
|
|||
*line >> ":";
|
||||
line->trimBlanks();
|
||||
DDebug("SIPMessage::parse",DebugAll,"header='%s' value='%s'",name.c_str(),line->c_str());
|
||||
header.append(new HeaderLine(uncompactForm(name.c_str()),*line));
|
||||
header.append(new SIPHeaderLine(uncompactForm(name.c_str()),*line));
|
||||
if (content.null() && (name &= "Content-Type")) {
|
||||
content = *line;
|
||||
content.toLower();
|
||||
|
@ -458,27 +458,27 @@ SIPMessage* SIPMessage::fromParsing(SIPParty* ep, const char *buf, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const HeaderLine* SIPMessage::getHeader(const char* name) const
|
||||
const SIPHeaderLine* SIPMessage::getHeader(const char* name) const
|
||||
{
|
||||
if (!(name && *name))
|
||||
return 0;
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const HeaderLine* t = static_cast<const HeaderLine*>(l->get());
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
return t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const HeaderLine* SIPMessage::getLastHeader(const char* name) const
|
||||
const SIPHeaderLine* SIPMessage::getLastHeader(const char* name) const
|
||||
{
|
||||
if (!(name && *name))
|
||||
return 0;
|
||||
const HeaderLine* res = 0;
|
||||
const SIPHeaderLine* res = 0;
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const HeaderLine* t = static_cast<const HeaderLine*>(l->get());
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
res = t;
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ int SIPMessage::countHeaders(const char* name) const
|
|||
int res = 0;
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
const HeaderLine* t = static_cast<const HeaderLine*>(l->get());
|
||||
const SIPHeaderLine* t = static_cast<const SIPHeaderLine*>(l->get());
|
||||
if (t && (t->name() &= name))
|
||||
++res;
|
||||
}
|
||||
|
@ -501,13 +501,13 @@ int SIPMessage::countHeaders(const char* name) const
|
|||
|
||||
const NamedString* SIPMessage::getParam(const char* name, const char* param) const
|
||||
{
|
||||
const HeaderLine* hl = getHeader(name);
|
||||
const SIPHeaderLine* hl = getHeader(name);
|
||||
return hl ? hl->getParam(param) : 0;
|
||||
}
|
||||
|
||||
const String& SIPMessage::getHeaderValue(const char* name) const
|
||||
{
|
||||
const HeaderLine* hl = getHeader(name);
|
||||
const SIPHeaderLine* hl = getHeader(name);
|
||||
return hl ? *hl : String::empty();
|
||||
}
|
||||
|
||||
|
@ -527,7 +527,7 @@ const String& SIPMessage::getHeaders() const
|
|||
|
||||
const ObjList* l = &header;
|
||||
for (; l; l = l->next()) {
|
||||
HeaderLine* t = static_cast<HeaderLine*>(l->get());
|
||||
SIPHeaderLine* t = static_cast<SIPHeaderLine*>(l->get());
|
||||
if (t) {
|
||||
m_string << t->name() << ": " << t->c_str();
|
||||
const ObjList* p = &(t->params());
|
||||
|
@ -630,7 +630,7 @@ SIPDialog::SIPDialog(const SIPMessage& message)
|
|||
{
|
||||
Regexp r("<\\([^>]\\+\\)>");
|
||||
bool local = message.isOutgoing() ^ message.isAnswer();
|
||||
const HeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
const SIPHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
localURI = hl;
|
||||
if (localURI.matches(r))
|
||||
localURI = localURI.matchString(1);
|
||||
|
@ -651,7 +651,7 @@ SIPDialog& SIPDialog::operator=(const SIPMessage& message)
|
|||
String::operator=(message.getHeaderValue("Call-ID"));
|
||||
Regexp r("<\\([^>]\\+\\)>");
|
||||
bool local = message.isOutgoing() ^ message.isAnswer();
|
||||
const HeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
const SIPHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||
localURI = hl;
|
||||
if (localURI.matches(r))
|
||||
localURI = localURI.matchString(1);
|
||||
|
|
|
@ -47,7 +47,7 @@ SIPTransaction::SIPTransaction(SIPMessage* message, SIPEngine* engine, bool outg
|
|||
if (ns)
|
||||
m_tag = *ns;
|
||||
|
||||
const HeaderLine* hl = message->getHeader("Call-ID");
|
||||
const SIPHeaderLine* hl = message->getHeader("Call-ID");
|
||||
if (hl)
|
||||
m_callid = *hl;
|
||||
|
||||
|
|
|
@ -27,15 +27,21 @@
|
|||
#include <yateclass.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
#ifdef LIBYSIP_EXPORTS
|
||||
#define YSIP_API __declspec(dllexport)
|
||||
#else
|
||||
#ifndef LIBYSIP_STATIC
|
||||
#define YSIP_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define YSIP_API
|
||||
#endif
|
||||
|
||||
#endif /* _WINDOWS */
|
||||
|
||||
#ifndef YSIP_API
|
||||
#define YSIP_API
|
||||
#endif
|
||||
|
||||
/**
|
||||
* We use Telephony Engine namespace, which in fact holds just the
|
||||
* generic classes
|
||||
|
@ -147,35 +153,35 @@ protected:
|
|||
ObjList m_lines;
|
||||
};
|
||||
|
||||
class YSIP_API BinaryBody : public SIPBody
|
||||
class YSIP_API SIPBinaryBody : public SIPBody
|
||||
{
|
||||
public:
|
||||
BinaryBody(const String& type, const char *buf, int len);
|
||||
virtual ~BinaryBody();
|
||||
SIPBinaryBody(const String& type, const char *buf, int len);
|
||||
virtual ~SIPBinaryBody();
|
||||
virtual SIPBody* clone() const;
|
||||
protected:
|
||||
BinaryBody(const BinaryBody& original);
|
||||
SIPBinaryBody(const SIPBinaryBody& original);
|
||||
virtual void buildBody() const;
|
||||
};
|
||||
|
||||
class YSIP_API StringBody : public SIPBody
|
||||
class YSIP_API SIPStringBody : public SIPBody
|
||||
{
|
||||
public:
|
||||
StringBody(const String& type, const char *buf, int len);
|
||||
virtual ~StringBody();
|
||||
SIPStringBody(const String& type, const char *buf, int len);
|
||||
virtual ~SIPStringBody();
|
||||
virtual SIPBody* clone() const;
|
||||
protected:
|
||||
StringBody(const StringBody& original);
|
||||
SIPStringBody(const SIPStringBody& original);
|
||||
virtual void buildBody() const;
|
||||
String m_text;
|
||||
};
|
||||
|
||||
class YSIP_API HeaderLine : public NamedString
|
||||
class YSIP_API SIPHeaderLine : public NamedString
|
||||
{
|
||||
public:
|
||||
HeaderLine(const char *name, const String& value);
|
||||
HeaderLine(const HeaderLine& original);
|
||||
virtual ~HeaderLine();
|
||||
SIPHeaderLine(const char *name, const String& value);
|
||||
SIPHeaderLine(const SIPHeaderLine& original);
|
||||
virtual ~SIPHeaderLine();
|
||||
inline const ObjList& params() const
|
||||
{ return m_params; }
|
||||
void setParam(const char *name, const char *value = 0);
|
||||
|
@ -302,14 +308,14 @@ public:
|
|||
* @param name Name of the header to locate
|
||||
* @return A pointer to the first matching header line or 0 if not found
|
||||
*/
|
||||
const HeaderLine* getHeader(const char* name) const;
|
||||
const SIPHeaderLine* getHeader(const char* name) const;
|
||||
|
||||
/**
|
||||
* Find the last header line that matches a given name name
|
||||
* @param name Name of the header to locate
|
||||
* @return A pointer to the last matching header line or 0 if not found
|
||||
*/
|
||||
const HeaderLine* getLastHeader(const char* name) const;
|
||||
const SIPHeaderLine* getLastHeader(const char* name) const;
|
||||
|
||||
/**
|
||||
* Count the header lines matching a specific name
|
||||
|
@ -345,12 +351,12 @@ public:
|
|||
* Append a new header line constructed from name and content
|
||||
*/
|
||||
inline void addHeader(const char* name, const char* value = 0)
|
||||
{ header.append(new HeaderLine(name,value)); }
|
||||
{ header.append(new SIPHeaderLine(name,value)); }
|
||||
|
||||
/**
|
||||
* Append an already constructed header line
|
||||
*/
|
||||
inline void addHeader(HeaderLine* line)
|
||||
inline void addHeader(SIPHeaderLine* line)
|
||||
{ header.append(line); }
|
||||
|
||||
/**
|
||||
|
@ -806,7 +812,7 @@ protected:
|
|||
/**
|
||||
* This object can be one for each SIPListener.
|
||||
*/
|
||||
class SIPEngine
|
||||
class YSIP_API SIPEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
|
|
@ -93,7 +93,7 @@ void SocketAddr::assign(const struct sockaddr* addr, socklen_t len)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
if (addr && len) {
|
||||
if (addr && (len >= sizeof(struct sockaddr))) {
|
||||
void* tmp = ::malloc(len);
|
||||
::memcpy(tmp,addr,len);
|
||||
m_address = (struct sockaddr*)tmp;
|
||||
|
@ -102,6 +102,21 @@ void SocketAddr::assign(const struct sockaddr* addr, socklen_t len)
|
|||
}
|
||||
}
|
||||
|
||||
bool SocketAddr::local(const SocketAddr& remote)
|
||||
{
|
||||
if (!remote.valid())
|
||||
return false;
|
||||
SocketAddr tmp(remote);
|
||||
if (!tmp.port())
|
||||
tmp.port(16384);
|
||||
Socket sock(tmp.family(),SOCK_DGRAM);
|
||||
if (sock.valid() && sock.connect(tmp) && sock.getSockName(*this)) {
|
||||
port(0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SocketAddr::host(const String& name)
|
||||
{
|
||||
if (name.null())
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
# Filter the Yate header files so they can be parsed by kdoc
|
||||
|
||||
filter='s/FORMAT_CHECK(.*)//'
|
||||
filter='s/FORMAT_CHECK(.*)//; s/[A-Z]*_API//'
|
||||
|
||||
test -f "$2" && sed "$filter" "$2"
|
||||
|
|
|
@ -525,7 +525,7 @@ void YateSIPEndPoint::regreq(SIPEvent* e, SIPTransaction* t)
|
|||
e->getTransaction()->setResponse(500, "Server Shutting Down");
|
||||
return;
|
||||
}
|
||||
const HeaderLine* hl = e->getMessage()->getHeader("Contact");
|
||||
const SIPHeaderLine* hl = e->getMessage()->getHeader("Contact");
|
||||
if (!hl) {
|
||||
e->getTransaction()->setResponse(400);
|
||||
return;
|
||||
|
@ -705,12 +705,12 @@ void YateSIPConnection::hangup()
|
|||
m->addHeader("Call-ID",m_callid);
|
||||
String tmp;
|
||||
tmp << "<" << m_dialog.localURI << ">";
|
||||
HeaderLine* hl = new HeaderLine("From",tmp);
|
||||
SIPHeaderLine* hl = new SIPHeaderLine("From",tmp);
|
||||
hl->setParam("tag",m_dialog.localTag);
|
||||
m->addHeader(hl);
|
||||
tmp.clear();
|
||||
tmp << "<" << m_dialog.remoteURI << ">";
|
||||
hl = new HeaderLine("To",tmp);
|
||||
hl = new SIPHeaderLine("To",tmp);
|
||||
hl->setParam("tag",m_dialog.remoteTag);
|
||||
m->addHeader(hl);
|
||||
plugin.ep()->engine()->addMessage(m);
|
||||
|
|
29
yateclass.h
29
yateclass.h
|
@ -90,8 +90,10 @@ typedef unsigned long in_addr_t;
|
|||
#ifdef LIBYATE_EXPORTS
|
||||
#define YATE_API __declspec(dllexport)
|
||||
#else
|
||||
#ifndef LIBYATE_STATIC
|
||||
#define YATE_API __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FMT64 "%I64d"
|
||||
#define FMT64U "%I64u"
|
||||
|
@ -110,13 +112,15 @@ typedef unsigned long in_addr_t;
|
|||
typedef int SOCKET;
|
||||
#endif
|
||||
|
||||
#define YATE_API
|
||||
|
||||
#define FMT64 "%lld"
|
||||
#define FMT64U "%llu"
|
||||
|
||||
#endif /* ! _WINDOWS */
|
||||
|
||||
#ifndef YATE_API
|
||||
#define YATE_API
|
||||
#endif
|
||||
|
||||
#ifndef IPTOS_LOWDELAY
|
||||
#define IPTOS_LOWDELAY 0x10
|
||||
#define IPTOS_THROUGHPUT 0x08
|
||||
|
@ -2339,6 +2343,27 @@ public:
|
|||
*/
|
||||
void assign(const struct sockaddr* addr, socklen_t len = 0);
|
||||
|
||||
/**
|
||||
* Attempt to guess a local address that will be used to reach a remote one
|
||||
* @param remote Remote address to reach
|
||||
* @return True if guessed an address, false if failed
|
||||
*/
|
||||
bool local(const SocketAddr& remote);
|
||||
|
||||
/**
|
||||
* Check if a non-null address is held
|
||||
* @return True if a valid address is held, false if null
|
||||
*/
|
||||
inline bool valid() const
|
||||
{ return m_length && m_address; }
|
||||
|
||||
/**
|
||||
* Check if a null address is held
|
||||
* @return True if a null address is held
|
||||
*/
|
||||
inline bool null() const
|
||||
{ return !(m_length && m_address); }
|
||||
|
||||
/**
|
||||
* Get the family of the stored address
|
||||
* @return Address family of the stored address or zero (AF_UNSPEC)
|
||||
|
|
Loading…
Reference in New Issue