From 9e29ce8476c5f85645910211baffb3fcc62fd4be Mon Sep 17 00:00:00 2001 From: paulc Date: Mon, 2 May 2005 18:31:05 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: http://yate.null.ro/svn/yate/trunk@321 acf43c95-373e-0410-b603-e72c3f656dc1 --- Makefile.in | 4 +- contrib/yrtp/Makefile.in | 2 +- contrib/yrtp/session.cpp | 55 ++++++++++++ contrib/yrtp/transport.cpp | 106 ++++++++++++++++++++++ contrib/yrtp/yatertp.h | 165 ++++++++++++++++++++++++++++++++++- contrib/ysip/body.cpp | 32 +++---- contrib/ysip/engine.cpp | 2 +- contrib/ysip/message.cpp | 68 +++++++-------- contrib/ysip/transaction.cpp | 2 +- contrib/ysip/yatesip.h | 44 ++++++---- engine/Socket.cpp | 17 +++- kdoc-filter.sh | 2 +- modules/ysipchan.cpp | 6 +- yateclass.h | 29 +++++- 14 files changed, 451 insertions(+), 83 deletions(-) create mode 100644 contrib/yrtp/session.cpp create mode 100644 contrib/yrtp/transport.cpp diff --git a/Makefile.in b/Makefile.in index 7db4d0e0..d4eafa1b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/contrib/yrtp/Makefile.in b/contrib/yrtp/Makefile.in index 3641384e..a08340df 100644 --- a/contrib/yrtp/Makefile.in +++ b/contrib/yrtp/Makefile.in @@ -13,7 +13,7 @@ INCFILES := @top_srcdir@/yateclass.h @srcdir@/yatertp.h PROGS= LIBS = libyatertp.a -OBJS = +OBJS = transport.o session.o LOCALFLAGS = LOCALLIBS = diff --git a/contrib/yrtp/session.cpp b/contrib/yrtp/session.cpp new file mode 100644 index 00000000..049dcc69 --- /dev/null +++ b/contrib/yrtp/session.cpp @@ -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 + +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: */ diff --git a/contrib/yrtp/transport.cpp b/contrib/yrtp/transport.cpp new file mode 100644 index 00000000..48841145 --- /dev/null +++ b/contrib/yrtp/transport.cpp @@ -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 + +#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: */ diff --git a/contrib/yrtp/yatertp.h b/contrib/yrtp/yatertp.h index 8dbb45d8..e7b03086 100644 --- a/contrib/yrtp/yatertp.h +++ b/contrib/yrtp/yatertp.h @@ -27,17 +27,178 @@ #include #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; +}; } diff --git a/contrib/ysip/body.cpp b/contrib/ysip/body.cpp index c59fa8c1..83ed2a35 100644 --- a/contrib/ysip/body.cpp +++ b/contrib/ysip/body.cpp @@ -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: */ diff --git a/contrib/ysip/engine.cpp b/contrib/ysip/engine.cpp index 72b40bc2..f2e43c9d 100644 --- a/contrib/ysip/engine.cpp +++ b/contrib/ysip/engine.cpp @@ -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")) diff --git a/contrib/ysip/message.cpp b/contrib/ysip/message.cpp index cc19d974..97ee891a 100644 --- a/contrib/ysip/message.cpp +++ b/contrib/ysip/message.cpp @@ -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(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(getHeader("Via")); + SIPHeaderLine* hl = const_cast(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(getHeader("To")); + SIPHeaderLine* hl = const_cast(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(getHeader("Via")); + SIPHeaderLine* hl = const_cast(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(getHeader("From")); + hl = const_cast(getHeader("From")); if (!hl) { String tmp; tmp << ""; - 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(getHeader("To")); + hl = const_cast(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(l->get()); + const SIPHeaderLine* hl = static_cast(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(l->get()); + const SIPHeaderLine* t = static_cast(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(l->get()); + const SIPHeaderLine* t = static_cast(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(l->get()); + const SIPHeaderLine* t = static_cast(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(l->get()); + SIPHeaderLine* t = static_cast(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); diff --git a/contrib/ysip/transaction.cpp b/contrib/ysip/transaction.cpp index 3be27d54..4989ec0e 100644 --- a/contrib/ysip/transaction.cpp +++ b/contrib/ysip/transaction.cpp @@ -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; diff --git a/contrib/ysip/yatesip.h b/contrib/ysip/yatesip.h index 4d2dd0a8..18e60f17 100644 --- a/contrib/ysip/yatesip.h +++ b/contrib/ysip/yatesip.h @@ -27,15 +27,21 @@ #include #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: /** diff --git a/engine/Socket.cpp b/engine/Socket.cpp index 847280f3..dee3f687 100644 --- a/engine/Socket.cpp +++ b/engine/Socket.cpp @@ -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()) diff --git a/kdoc-filter.sh b/kdoc-filter.sh index b9f33fc3..1d134d41 100755 --- a/kdoc-filter.sh +++ b/kdoc-filter.sh @@ -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" diff --git a/modules/ysipchan.cpp b/modules/ysipchan.cpp index 16fb23a7..5f5820a5 100644 --- a/modules/ysipchan.cpp +++ b/modules/ysipchan.cpp @@ -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); diff --git a/yateclass.h b/yateclass.h index a5618c6a..611ce31f 100644 --- a/yateclass.h +++ b/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)