*** empty log message ***

git-svn-id: http://voip.null.ro/svn/yate@321 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2005-05-02 18:31:05 +00:00
parent aa2cb0417f
commit 29675e4f37
14 changed files with 451 additions and 83 deletions

View File

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

View File

@ -13,7 +13,7 @@ INCFILES := @top_srcdir@/yateclass.h @srcdir@/yatertp.h
PROGS=
LIBS = libyatertp.a
OBJS =
OBJS = transport.o session.o
LOCALFLAGS =
LOCALLIBS =

55
contrib/yrtp/session.cpp Normal file
View File

@ -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: */

106
contrib/yrtp/transport.cpp Normal file
View File

@ -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: */

View File

@ -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;
};
}

View File

@ -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: */

View File

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

View File

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

View File

@ -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;

View File

@ -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:
/**

View File

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

View File

@ -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"

View File

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

View File

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