*** 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)
|
engine: tables library libyate.so $(PROGS)
|
||||||
|
|
||||||
apidocs-build: check-topdir
|
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
|
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
|
$(MAKE) apidocs-build
|
||||||
|
|
||||||
.PHONY: strip sex love war
|
.PHONY: strip sex love war
|
||||||
|
|
|
@ -13,7 +13,7 @@ INCFILES := @top_srcdir@/yateclass.h @srcdir@/yatertp.h
|
||||||
|
|
||||||
PROGS=
|
PROGS=
|
||||||
LIBS = libyatertp.a
|
LIBS = libyatertp.a
|
||||||
OBJS =
|
OBJS = transport.o session.o
|
||||||
|
|
||||||
LOCALFLAGS =
|
LOCALFLAGS =
|
||||||
LOCALLIBS =
|
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>
|
#include <yateclass.h>
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
|
|
||||||
#ifdef LIBYRTP_EXPORTS
|
#ifdef LIBYRTP_EXPORTS
|
||||||
#define YRTP_API __declspec(dllexport)
|
#define YRTP_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
|
#ifndef LIBYRTP_STATIC
|
||||||
#define YRTP_API __declspec(dllimport)
|
#define YRTP_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#endif
|
||||||
#define YRTP_API
|
|
||||||
#endif /* _WINDOWS */
|
#endif /* _WINDOWS */
|
||||||
|
|
||||||
|
#ifndef YRTP_API
|
||||||
|
#define YRTP_API
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace TelEngine {
|
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")
|
if (type == "application/sdp")
|
||||||
return new SDPBody(type,buf,len);
|
return new SDPBody(type,buf,len);
|
||||||
if (type.startsWith("text/"))
|
if (type.startsWith("text/"))
|
||||||
return new StringBody(type,buf,len);
|
return new SIPStringBody(type,buf,len);
|
||||||
return new BinaryBody(type,buf,len);
|
return new SIPBinaryBody(type,buf,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDPBody::SDPBody()
|
SDPBody::SDPBody()
|
||||||
|
@ -123,56 +123,56 @@ const NamedString* SDPBody::getLine(const char *name) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryBody::BinaryBody(const String& type, const char *buf, int len)
|
SIPBinaryBody::SIPBinaryBody(const String& type, const char *buf, int len)
|
||||||
: SIPBody(type)
|
: SIPBody(type)
|
||||||
{
|
{
|
||||||
m_body.assign((void*)buf,len);
|
m_body.assign((void*)buf,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryBody::BinaryBody(const BinaryBody& original)
|
SIPBinaryBody::SIPBinaryBody(const SIPBinaryBody& original)
|
||||||
: SIPBody(original.getType())
|
: SIPBody(original.getType())
|
||||||
{
|
{
|
||||||
m_body = original.m_body;
|
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
|
// 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)
|
: SIPBody(type), m_text(buf,len)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBody::StringBody(const StringBody& original)
|
SIPStringBody::SIPStringBody(const SIPStringBody& original)
|
||||||
: SIPBody(original.getType()), m_text(original.m_text)
|
: 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());
|
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: */
|
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||||
|
|
|
@ -239,7 +239,7 @@ SIPTransaction* SIPEngine::addMessage(SIPMessage* message)
|
||||||
if (message->isOutgoing())
|
if (message->isOutgoing())
|
||||||
message->complete(this);
|
message->complete(this);
|
||||||
// locate the branch parameter of last Via header - added by the UA
|
// 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;
|
const NamedString* br = hl ? hl->getParam("branch") : 0;
|
||||||
String branch(br ? *br : String::empty());
|
String branch(br ? *br : String::empty());
|
||||||
if (!branch.startsWith("z9hG4bK"))
|
if (!branch.startsWith("z9hG4bK"))
|
||||||
|
|
|
@ -30,10 +30,10 @@
|
||||||
|
|
||||||
using namespace TelEngine;
|
using namespace TelEngine;
|
||||||
|
|
||||||
HeaderLine::HeaderLine(const char *name, const String& value)
|
SIPHeaderLine::SIPHeaderLine(const char *name, const String& value)
|
||||||
: NamedString(name)
|
: 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())
|
if (value.null())
|
||||||
return;
|
return;
|
||||||
int sp = value.find(';');
|
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)
|
: 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();
|
const ObjList* l = &original.params();
|
||||||
for (; l; l = l->next()) {
|
for (; l; l = l->next()) {
|
||||||
const NamedString* t = static_cast<const NamedString*>(l->get());
|
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))
|
if (!(name && *name))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -106,7 +106,7 @@ const NamedString* HeaderLine::getParam(const char *name) const
|
||||||
return 0;
|
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);
|
ObjList* p = m_params.find(name);
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -115,7 +115,7 @@ void HeaderLine::setParam(const char *name, const char *value)
|
||||||
m_params.append(new NamedString(name,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);
|
ObjList* p = m_params.find(name);
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -187,12 +187,12 @@ SIPMessage::SIPMessage(const SIPMessage* message, bool newtran)
|
||||||
version = message->version;
|
version = message->version;
|
||||||
uri = message->uri;
|
uri = message->uri;
|
||||||
copyAllHeaders(message,"Via");
|
copyAllHeaders(message,"Via");
|
||||||
HeaderLine* hl = const_cast<HeaderLine*>(getHeader("Via"));
|
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("Via"));
|
||||||
if (!hl) {
|
if (!hl) {
|
||||||
String tmp;
|
String tmp;
|
||||||
tmp << version << "/" << getParty()->getProtoName();
|
tmp << version << "/" << getParty()->getProtoName();
|
||||||
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
||||||
hl = new HeaderLine("Via",tmp);
|
hl = new SIPHeaderLine("Via",tmp);
|
||||||
header.append(hl);
|
header.append(hl);
|
||||||
}
|
}
|
||||||
if (newtran) {
|
if (newtran) {
|
||||||
|
@ -237,7 +237,7 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
||||||
|
|
||||||
// only set the dialog tag on ACK
|
// only set the dialog tag on ACK
|
||||||
if (isACK()) {
|
if (isACK()) {
|
||||||
HeaderLine* hl = const_cast<HeaderLine*>(getHeader("To"));
|
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("To"));
|
||||||
if (dlgTag && hl && !hl->getParam("tag"))
|
if (dlgTag && hl && !hl->getParam("tag"))
|
||||||
hl->setParam("tag",dlgTag);
|
hl->setParam("tag",dlgTag);
|
||||||
return;
|
return;
|
||||||
|
@ -248,12 +248,12 @@ void SIPMessage::complete(SIPEngine* engine, const char* user, const char* domai
|
||||||
if (!domain)
|
if (!domain)
|
||||||
domain = getParty()->getLocalAddr();
|
domain = getParty()->getLocalAddr();
|
||||||
|
|
||||||
HeaderLine* hl = const_cast<HeaderLine*>(getHeader("Via"));
|
SIPHeaderLine* hl = const_cast<SIPHeaderLine*>(getHeader("Via"));
|
||||||
if (!hl) {
|
if (!hl) {
|
||||||
String tmp;
|
String tmp;
|
||||||
tmp << version << "/" << getParty()->getProtoName();
|
tmp << version << "/" << getParty()->getProtoName();
|
||||||
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
tmp << " " << getParty()->getLocalAddr() << ":" << getParty()->getLocalPort();
|
||||||
hl = new HeaderLine("Via",tmp);
|
hl = new SIPHeaderLine("Via",tmp);
|
||||||
header.append(hl);
|
header.append(hl);
|
||||||
}
|
}
|
||||||
if (!(isAnswer() || hl->getParam("branch"))) {
|
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->setParam("rport",String(getParty()->getPartyPort()));
|
||||||
}
|
}
|
||||||
|
|
||||||
hl = const_cast<HeaderLine*>(getHeader("From"));
|
hl = const_cast<SIPHeaderLine*>(getHeader("From"));
|
||||||
if (!hl) {
|
if (!hl) {
|
||||||
String tmp;
|
String tmp;
|
||||||
tmp << "<sip:" << user << "@" << domain << ">";
|
tmp << "<sip:" << user << "@" << domain << ">";
|
||||||
hl = new HeaderLine("From",tmp);
|
hl = new SIPHeaderLine("From",tmp);
|
||||||
header.append(hl);
|
header.append(hl);
|
||||||
}
|
}
|
||||||
if (!(isAnswer() || hl->getParam("tag")))
|
if (!(isAnswer() || hl->getParam("tag")))
|
||||||
hl->setParam("tag",String((int)::random()));
|
hl->setParam("tag",String((int)::random()));
|
||||||
|
|
||||||
hl = const_cast<HeaderLine*>(getHeader("To"));
|
hl = const_cast<SIPHeaderLine*>(getHeader("To"));
|
||||||
if (!hl) {
|
if (!hl) {
|
||||||
String tmp;
|
String tmp;
|
||||||
tmp << "<" << uri << ">";
|
tmp << "<" << uri << ">";
|
||||||
hl = new HeaderLine("To",tmp);
|
hl = new SIPHeaderLine("To",tmp);
|
||||||
header.append(hl);
|
header.append(hl);
|
||||||
}
|
}
|
||||||
if (dlgTag && !hl->getParam("tag"))
|
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)
|
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) {
|
if (hl) {
|
||||||
header.append(new HeaderLine(*hl));
|
header.append(new SIPHeaderLine(*hl));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -341,10 +341,10 @@ int SIPMessage::copyAllHeaders(const SIPMessage* message, const char* name)
|
||||||
int c = 0;
|
int c = 0;
|
||||||
const ObjList* l = &message->header;
|
const ObjList* l = &message->header;
|
||||||
for (; l; l = l->next()) {
|
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)) {
|
if (hl && (hl->name() &= name)) {
|
||||||
++c;
|
++c;
|
||||||
header.append(new HeaderLine(*hl));
|
header.append(new SIPHeaderLine(*hl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
|
@ -427,7 +427,7 @@ bool SIPMessage::parse(const char* buf, int len)
|
||||||
*line >> ":";
|
*line >> ":";
|
||||||
line->trimBlanks();
|
line->trimBlanks();
|
||||||
DDebug("SIPMessage::parse",DebugAll,"header='%s' value='%s'",name.c_str(),line->c_str());
|
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")) {
|
if (content.null() && (name &= "Content-Type")) {
|
||||||
content = *line;
|
content = *line;
|
||||||
content.toLower();
|
content.toLower();
|
||||||
|
@ -458,27 +458,27 @@ SIPMessage* SIPMessage::fromParsing(SIPParty* ep, const char *buf, int len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HeaderLine* SIPMessage::getHeader(const char* name) const
|
const SIPHeaderLine* SIPMessage::getHeader(const char* name) const
|
||||||
{
|
{
|
||||||
if (!(name && *name))
|
if (!(name && *name))
|
||||||
return 0;
|
return 0;
|
||||||
const ObjList* l = &header;
|
const ObjList* l = &header;
|
||||||
for (; l; l = l->next()) {
|
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))
|
if (t && (t->name() &= name))
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HeaderLine* SIPMessage::getLastHeader(const char* name) const
|
const SIPHeaderLine* SIPMessage::getLastHeader(const char* name) const
|
||||||
{
|
{
|
||||||
if (!(name && *name))
|
if (!(name && *name))
|
||||||
return 0;
|
return 0;
|
||||||
const HeaderLine* res = 0;
|
const SIPHeaderLine* res = 0;
|
||||||
const ObjList* l = &header;
|
const ObjList* l = &header;
|
||||||
for (; l; l = l->next()) {
|
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))
|
if (t && (t->name() &= name))
|
||||||
res = t;
|
res = t;
|
||||||
}
|
}
|
||||||
|
@ -492,7 +492,7 @@ int SIPMessage::countHeaders(const char* name) const
|
||||||
int res = 0;
|
int res = 0;
|
||||||
const ObjList* l = &header;
|
const ObjList* l = &header;
|
||||||
for (; l; l = l->next()) {
|
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))
|
if (t && (t->name() &= name))
|
||||||
++res;
|
++res;
|
||||||
}
|
}
|
||||||
|
@ -501,13 +501,13 @@ int SIPMessage::countHeaders(const char* name) const
|
||||||
|
|
||||||
const NamedString* SIPMessage::getParam(const char* name, const char* param) 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;
|
return hl ? hl->getParam(param) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const String& SIPMessage::getHeaderValue(const char* name) const
|
const String& SIPMessage::getHeaderValue(const char* name) const
|
||||||
{
|
{
|
||||||
const HeaderLine* hl = getHeader(name);
|
const SIPHeaderLine* hl = getHeader(name);
|
||||||
return hl ? *hl : String::empty();
|
return hl ? *hl : String::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ const String& SIPMessage::getHeaders() const
|
||||||
|
|
||||||
const ObjList* l = &header;
|
const ObjList* l = &header;
|
||||||
for (; l; l = l->next()) {
|
for (; l; l = l->next()) {
|
||||||
HeaderLine* t = static_cast<HeaderLine*>(l->get());
|
SIPHeaderLine* t = static_cast<SIPHeaderLine*>(l->get());
|
||||||
if (t) {
|
if (t) {
|
||||||
m_string << t->name() << ": " << t->c_str();
|
m_string << t->name() << ": " << t->c_str();
|
||||||
const ObjList* p = &(t->params());
|
const ObjList* p = &(t->params());
|
||||||
|
@ -630,7 +630,7 @@ SIPDialog::SIPDialog(const SIPMessage& message)
|
||||||
{
|
{
|
||||||
Regexp r("<\\([^>]\\+\\)>");
|
Regexp r("<\\([^>]\\+\\)>");
|
||||||
bool local = message.isOutgoing() ^ message.isAnswer();
|
bool local = message.isOutgoing() ^ message.isAnswer();
|
||||||
const HeaderLine* hl = message.getHeader(local ? "From" : "To");
|
const SIPHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||||
localURI = hl;
|
localURI = hl;
|
||||||
if (localURI.matches(r))
|
if (localURI.matches(r))
|
||||||
localURI = localURI.matchString(1);
|
localURI = localURI.matchString(1);
|
||||||
|
@ -651,7 +651,7 @@ SIPDialog& SIPDialog::operator=(const SIPMessage& message)
|
||||||
String::operator=(message.getHeaderValue("Call-ID"));
|
String::operator=(message.getHeaderValue("Call-ID"));
|
||||||
Regexp r("<\\([^>]\\+\\)>");
|
Regexp r("<\\([^>]\\+\\)>");
|
||||||
bool local = message.isOutgoing() ^ message.isAnswer();
|
bool local = message.isOutgoing() ^ message.isAnswer();
|
||||||
const HeaderLine* hl = message.getHeader(local ? "From" : "To");
|
const SIPHeaderLine* hl = message.getHeader(local ? "From" : "To");
|
||||||
localURI = hl;
|
localURI = hl;
|
||||||
if (localURI.matches(r))
|
if (localURI.matches(r))
|
||||||
localURI = localURI.matchString(1);
|
localURI = localURI.matchString(1);
|
||||||
|
|
|
@ -47,7 +47,7 @@ SIPTransaction::SIPTransaction(SIPMessage* message, SIPEngine* engine, bool outg
|
||||||
if (ns)
|
if (ns)
|
||||||
m_tag = *ns;
|
m_tag = *ns;
|
||||||
|
|
||||||
const HeaderLine* hl = message->getHeader("Call-ID");
|
const SIPHeaderLine* hl = message->getHeader("Call-ID");
|
||||||
if (hl)
|
if (hl)
|
||||||
m_callid = *hl;
|
m_callid = *hl;
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,21 @@
|
||||||
#include <yateclass.h>
|
#include <yateclass.h>
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
|
|
||||||
#ifdef LIBYSIP_EXPORTS
|
#ifdef LIBYSIP_EXPORTS
|
||||||
#define YSIP_API __declspec(dllexport)
|
#define YSIP_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
|
#ifndef LIBYSIP_STATIC
|
||||||
#define YSIP_API __declspec(dllimport)
|
#define YSIP_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#endif
|
||||||
#define YSIP_API
|
|
||||||
#endif /* _WINDOWS */
|
#endif /* _WINDOWS */
|
||||||
|
|
||||||
|
#ifndef YSIP_API
|
||||||
|
#define YSIP_API
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We use Telephony Engine namespace, which in fact holds just the
|
* We use Telephony Engine namespace, which in fact holds just the
|
||||||
* generic classes
|
* generic classes
|
||||||
|
@ -147,35 +153,35 @@ protected:
|
||||||
ObjList m_lines;
|
ObjList m_lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
class YSIP_API BinaryBody : public SIPBody
|
class YSIP_API SIPBinaryBody : public SIPBody
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BinaryBody(const String& type, const char *buf, int len);
|
SIPBinaryBody(const String& type, const char *buf, int len);
|
||||||
virtual ~BinaryBody();
|
virtual ~SIPBinaryBody();
|
||||||
virtual SIPBody* clone() const;
|
virtual SIPBody* clone() const;
|
||||||
protected:
|
protected:
|
||||||
BinaryBody(const BinaryBody& original);
|
SIPBinaryBody(const SIPBinaryBody& original);
|
||||||
virtual void buildBody() const;
|
virtual void buildBody() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class YSIP_API StringBody : public SIPBody
|
class YSIP_API SIPStringBody : public SIPBody
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StringBody(const String& type, const char *buf, int len);
|
SIPStringBody(const String& type, const char *buf, int len);
|
||||||
virtual ~StringBody();
|
virtual ~SIPStringBody();
|
||||||
virtual SIPBody* clone() const;
|
virtual SIPBody* clone() const;
|
||||||
protected:
|
protected:
|
||||||
StringBody(const StringBody& original);
|
SIPStringBody(const SIPStringBody& original);
|
||||||
virtual void buildBody() const;
|
virtual void buildBody() const;
|
||||||
String m_text;
|
String m_text;
|
||||||
};
|
};
|
||||||
|
|
||||||
class YSIP_API HeaderLine : public NamedString
|
class YSIP_API SIPHeaderLine : public NamedString
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeaderLine(const char *name, const String& value);
|
SIPHeaderLine(const char *name, const String& value);
|
||||||
HeaderLine(const HeaderLine& original);
|
SIPHeaderLine(const SIPHeaderLine& original);
|
||||||
virtual ~HeaderLine();
|
virtual ~SIPHeaderLine();
|
||||||
inline const ObjList& params() const
|
inline const ObjList& params() const
|
||||||
{ return m_params; }
|
{ return m_params; }
|
||||||
void setParam(const char *name, const char *value = 0);
|
void setParam(const char *name, const char *value = 0);
|
||||||
|
@ -302,14 +308,14 @@ public:
|
||||||
* @param name Name of the header to locate
|
* @param name Name of the header to locate
|
||||||
* @return A pointer to the first matching header line or 0 if not found
|
* @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
|
* Find the last header line that matches a given name name
|
||||||
* @param name Name of the header to locate
|
* @param name Name of the header to locate
|
||||||
* @return A pointer to the last matching header line or 0 if not found
|
* @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
|
* Count the header lines matching a specific name
|
||||||
|
@ -345,12 +351,12 @@ public:
|
||||||
* Append a new header line constructed from name and content
|
* Append a new header line constructed from name and content
|
||||||
*/
|
*/
|
||||||
inline void addHeader(const char* name, const char* value = 0)
|
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
|
* Append an already constructed header line
|
||||||
*/
|
*/
|
||||||
inline void addHeader(HeaderLine* line)
|
inline void addHeader(SIPHeaderLine* line)
|
||||||
{ header.append(line); }
|
{ header.append(line); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -806,7 +812,7 @@ protected:
|
||||||
/**
|
/**
|
||||||
* This object can be one for each SIPListener.
|
* This object can be one for each SIPListener.
|
||||||
*/
|
*/
|
||||||
class SIPEngine
|
class YSIP_API SIPEngine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -93,7 +93,7 @@ void SocketAddr::assign(const struct sockaddr* addr, socklen_t len)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (addr && len) {
|
if (addr && (len >= sizeof(struct sockaddr))) {
|
||||||
void* tmp = ::malloc(len);
|
void* tmp = ::malloc(len);
|
||||||
::memcpy(tmp,addr,len);
|
::memcpy(tmp,addr,len);
|
||||||
m_address = (struct sockaddr*)tmp;
|
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)
|
bool SocketAddr::host(const String& name)
|
||||||
{
|
{
|
||||||
if (name.null())
|
if (name.null())
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
# Filter the Yate header files so they can be parsed by kdoc
|
# 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"
|
test -f "$2" && sed "$filter" "$2"
|
||||||
|
|
|
@ -525,7 +525,7 @@ void YateSIPEndPoint::regreq(SIPEvent* e, SIPTransaction* t)
|
||||||
e->getTransaction()->setResponse(500, "Server Shutting Down");
|
e->getTransaction()->setResponse(500, "Server Shutting Down");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const HeaderLine* hl = e->getMessage()->getHeader("Contact");
|
const SIPHeaderLine* hl = e->getMessage()->getHeader("Contact");
|
||||||
if (!hl) {
|
if (!hl) {
|
||||||
e->getTransaction()->setResponse(400);
|
e->getTransaction()->setResponse(400);
|
||||||
return;
|
return;
|
||||||
|
@ -705,12 +705,12 @@ void YateSIPConnection::hangup()
|
||||||
m->addHeader("Call-ID",m_callid);
|
m->addHeader("Call-ID",m_callid);
|
||||||
String tmp;
|
String tmp;
|
||||||
tmp << "<" << m_dialog.localURI << ">";
|
tmp << "<" << m_dialog.localURI << ">";
|
||||||
HeaderLine* hl = new HeaderLine("From",tmp);
|
SIPHeaderLine* hl = new SIPHeaderLine("From",tmp);
|
||||||
hl->setParam("tag",m_dialog.localTag);
|
hl->setParam("tag",m_dialog.localTag);
|
||||||
m->addHeader(hl);
|
m->addHeader(hl);
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
tmp << "<" << m_dialog.remoteURI << ">";
|
tmp << "<" << m_dialog.remoteURI << ">";
|
||||||
hl = new HeaderLine("To",tmp);
|
hl = new SIPHeaderLine("To",tmp);
|
||||||
hl->setParam("tag",m_dialog.remoteTag);
|
hl->setParam("tag",m_dialog.remoteTag);
|
||||||
m->addHeader(hl);
|
m->addHeader(hl);
|
||||||
plugin.ep()->engine()->addMessage(m);
|
plugin.ep()->engine()->addMessage(m);
|
||||||
|
|
29
yateclass.h
29
yateclass.h
|
@ -90,8 +90,10 @@ typedef unsigned long in_addr_t;
|
||||||
#ifdef LIBYATE_EXPORTS
|
#ifdef LIBYATE_EXPORTS
|
||||||
#define YATE_API __declspec(dllexport)
|
#define YATE_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
|
#ifndef LIBYATE_STATIC
|
||||||
#define YATE_API __declspec(dllimport)
|
#define YATE_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FMT64 "%I64d"
|
#define FMT64 "%I64d"
|
||||||
#define FMT64U "%I64u"
|
#define FMT64U "%I64u"
|
||||||
|
@ -110,13 +112,15 @@ typedef unsigned long in_addr_t;
|
||||||
typedef int SOCKET;
|
typedef int SOCKET;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define YATE_API
|
|
||||||
|
|
||||||
#define FMT64 "%lld"
|
#define FMT64 "%lld"
|
||||||
#define FMT64U "%llu"
|
#define FMT64U "%llu"
|
||||||
|
|
||||||
#endif /* ! _WINDOWS */
|
#endif /* ! _WINDOWS */
|
||||||
|
|
||||||
|
#ifndef YATE_API
|
||||||
|
#define YATE_API
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef IPTOS_LOWDELAY
|
#ifndef IPTOS_LOWDELAY
|
||||||
#define IPTOS_LOWDELAY 0x10
|
#define IPTOS_LOWDELAY 0x10
|
||||||
#define IPTOS_THROUGHPUT 0x08
|
#define IPTOS_THROUGHPUT 0x08
|
||||||
|
@ -2339,6 +2343,27 @@ public:
|
||||||
*/
|
*/
|
||||||
void assign(const struct sockaddr* addr, socklen_t len = 0);
|
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
|
* Get the family of the stored address
|
||||||
* @return Address family of the stored address or zero (AF_UNSPEC)
|
* @return Address family of the stored address or zero (AF_UNSPEC)
|
||||||
|
|
Loading…
Reference in New Issue