From 9b0a4adf0c51d7f216d1d6bccc11a84fc140d28d Mon Sep 17 00:00:00 2001 From: paulc Date: Sun, 30 Oct 2005 04:03:25 +0000 Subject: [PATCH] Fixed IAX, H.323, ISDN and CDR to include caller/called and time in msec. Fixed a bug in H.323 connection cleanup. Some patches for FreeBSD compatibility. git-svn-id: http://yate.null.ro/svn/yate/trunk@553 acf43c95-373e-0410-b603-e72c3f656dc1 --- ChangeLog | 7 ++++++ conf.d/accfile.conf.sample | 3 +++ conf.d/ysipchan.conf.sample | 6 ++++++ configure.in | 15 +++++++++++-- engine/Makefile.in | 2 +- engine/Mutex.cpp | 7 +++++- modules/cdrbuild.cpp | 36 +++++++++++++++++++++++++------ modules/h323chan.cpp | 43 +++++++++++++++++++++++-------------- modules/iaxchan.cpp | 17 +++++++++------ modules/libypri.cpp | 3 +++ modules/osschan.cpp | 2 +- yateclass.h | 5 +++++ 12 files changed, 113 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8dd4f9d2..38af82e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sun Oct 30 2005 Paul Chitescu +- Fixed H.323, IAX and ISDN to include outgoing caller and called in CDR +- The CDR builder emits time and intervals in milliseconds +- Fixed yet another bug in H.323 connection cleanup +- H.323 sends the in_line parameter for named endpoints +- Applied some of the FreeBSD patches by Alex Rodin + Fri Oct 28 2005 Paul Chitescu - Automatic authentication support in SIP transactions - Some degree of NAT support in SIP and RTP diff --git a/conf.d/accfile.conf.sample b/conf.d/accfile.conf.sample index 875ea613..e60a5006 100644 --- a/conf.d/accfile.conf.sample +++ b/conf.d/accfile.conf.sample @@ -9,11 +9,13 @@ protocol=sip description=Test SIP account ;interval=600 ;formats=alaw,mulaw,gsm +;authname=metoo ;password=1234 ;number=1234 ;domain=somewhere.org ;registrar=10.0.0.1:5060 ;outbound=10.0.0.1:5061 +;localaddress=192.168.0.1:5062 [test_h323] enabled=no @@ -28,6 +30,7 @@ description=Test H.323 account ;gateway=10.0.0.1:1720 [test_iax] +; IAX has no user.login support yet! enabled=no protocol=iax ;username=me diff --git a/conf.d/ysipchan.conf.sample b/conf.d/ysipchan.conf.sample index 61bb6036..1ce167ed 100644 --- a/conf.d/ysipchan.conf.sample +++ b/conf.d/ysipchan.conf.sample @@ -22,6 +22,12 @@ ; generate: bool: Allow Yate messages to send arbitrary SIP client transactions ;generate=disable +; nat: bool: Enable automatic NAT support +;nat=enable + +; ignorevia: bool: Ignore Via headers and send answer back to the source +;ignorevia=enable + [codecs] ; This section allows to individually enable or disable the codecs diff --git a/configure.in b/configure.in index b54658bb..f3bc4bba 100644 --- a/configure.in +++ b/configure.in @@ -49,9 +49,20 @@ AC_CHECK_FUNCS([gettimeofday inet_ntoa memmove regcomp strerror], , [AC_MSG_ERRO AC_CACHE_SAVE # Checks for required libraries. -AC_CHECK_LIB([dl], [dlopen], , [AC_MSG_ERROR([This library is required.])]) AC_CHECK_LIB([pthread], [pthread_mutexattr_settype], , [AC_MSG_ERROR([This library is required.])]) +AC_MSG_CHECKING([for dlopen in default libs]) +AC_LANG_SAVE +AC_LANG_C +AC_TRY_LINK([#include ],[dlopen("",0);],[have_dl=yes],[have_dl=no]) +AC_LANG_RESTORE +AC_MSG_RESULT([$have_dl]) +if [[ "x$have_dl" != "xyes" ]]; then +AC_CHECK_LIB([dl], [dlopen], , [AC_MSG_ERROR([This library is required.])]) +DLOPEN_LIB="-ldl" +fi +AC_SUBST(DLOPEN_LIB) + MUTEX_HACK="" AC_MSG_CHECKING([for pthread_mutexattr_settype declaration]) AC_LANG_SAVE @@ -199,7 +210,7 @@ HAVE_GSM=no GSM_INC="" AC_ARG_WITH(libgsm,AC_HELP_STRING([--with-libgsm],[use GSM codec if available (default)]),[ac_cv_use_libgsm=$withval],[ac_cv_use_libgsm=yes]) if [[ "x$ac_cv_use_libgsm" = "xyes" ]]; then -for i in /usr/include /usr/include/gsm; do +for i in /usr/include /usr/include/gsm /usr/local/include /usr/local/include/gsm; do ac_cv_use_libgsm="$i" test -f "$ac_cv_use_libgsm/gsm.h" && break done diff --git a/engine/Makefile.in b/engine/Makefile.in index 6ba60ddc..426be08d 100644 --- a/engine/Makefile.in +++ b/engine/Makefile.in @@ -7,7 +7,7 @@ DEBUG := CXX := @CXX@ -Wall SED := sed DEFS := -LIBAUX:= -ldl +LIBAUX:= @DLOPEN_LIB@ LIBTHR:= -lpthread INCLUDES := -I.. -I@top_srcdir@ CFLAGS := -O2 @MODULE_CPPFLAGS@ @INLINE_FLAGS@ diff --git a/engine/Mutex.cpp b/engine/Mutex.cpp index 4b5caa96..1232b080 100644 --- a/engine/Mutex.cpp +++ b/engine/Mutex.cpp @@ -32,7 +32,12 @@ typedef HANDLE HMUTEX; #ifdef MUTEX_HACK extern "C" { -extern int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __kind) __THROW; +#if defined(__FreeBSD__) +extern int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __kind); +#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE +#else +extern int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __kind) __THROW; +#endif } #endif diff --git a/modules/cdrbuild.cpp b/modules/cdrbuild.cpp index f2164bb7..77065733 100644 --- a/modules/cdrbuild.cpp +++ b/modules/cdrbuild.cpp @@ -25,6 +25,7 @@ #include #include +#include using namespace TelEngine; @@ -66,8 +67,6 @@ public: static CdrBuilder *find(String &id); private: void emit(const char *operation = 0); - inline static int sec(u_int64_t usec) - { return (int)((usec + 500000) / 1000000); } u_int64_t m_start, m_call, @@ -85,6 +84,27 @@ private: }; static ObjList cdrs; +static int s_res = 1; + +static const char* printTime(char* buf,u_int64_t usec) +{ + switch (s_res) { + case 2: + // microsecond resolution + sprintf(buf,"%u.%06u",(unsigned int)(usec / 1000000),(unsigned int)(usec % 1000000)); + break; + case 1: + // millisecond resolution + usec = (usec + 500) / 1000; + sprintf(buf,"%u.%03u",(unsigned int)(usec / 1000),(unsigned int)(usec % 1000)); + break; + default: + // 1-second resolution + usec = (usec + 500000) / 1000000; + sprintf(buf,"%u",(unsigned int)usec); + } + return buf; +} CdrBuilder::CdrBuilder(const char *name) : String(name), m_dir("unknown"), m_status("unknown"), m_first(true) @@ -117,18 +137,19 @@ void CdrBuilder::emit(const char *operation) operation = m_first ? "initialize" : "update"; m_first = false; + char buf[64]; Message *m = new Message("call.cdr"); m->addParam("operation",operation); - m->addParam("time",String(sec(t_start))); + m->addParam("time",printTime(buf,t_start)); m->addParam("chan",c_str()); m->addParam("address",m_address); m->addParam("direction",m_dir); m->addParam("billid",m_billid); m->addParam("caller",m_caller); m->addParam("called",m_called); - m->addParam("duration",String(sec(t_hangup - t_start))); - m->addParam("billtime",String(sec(t_hangup - t_answer))); - m->addParam("ringtime",String(sec(t_answer - t_ringing))); + m->addParam("duration",printTime(buf,t_hangup - t_start)); + m->addParam("billtime",printTime(buf,t_hangup - t_answer)); + m->addParam("ringtime",printTime(buf,t_answer - t_ringing)); m->addParam("status",m_status); m->addParam("reason",m_reason); Engine::enqueue(m); @@ -161,6 +182,9 @@ void CdrBuilder::update(const Message& msg, int type, u_int64_t val) if ((m_status == "incoming") || (m_status == "outgoing")) m_dir = m_status; } + p = msg.getValue("direction"); + if (p) + m_dir = p; p = msg.getValue("reason"); if (p) m_reason = p; diff --git a/modules/h323chan.cpp b/modules/h323chan.cpp index 25e4cfcd..da18f295 100644 --- a/modules/h323chan.cpp +++ b/modules/h323chan.cpp @@ -396,7 +396,7 @@ public: BOOL startExternalRTP(const char* remoteIP, WORD remotePort, H323Channel::Directions dir, YateH323_ExternalRTPChannel* chan); void stoppedExternal(H323Channel::Directions dir); void setRemoteAddress(const char* remoteIP, WORD remotePort); - void cleanups(bool closeChans = true); + void cleanups(bool closeChans = true, bool dropChan = true); bool sendTone(Message& msg, const char* tone); void setCallerID(const char* number, const char* name); void rtpExecuted(Message& msg); @@ -449,11 +449,11 @@ class YateH323Chan : public Channel { friend class YateH323Connection; public: - YateH323Chan(YateH323Connection* conn,bool outgoing,const char* addr); + YateH323Chan(YateH323Connection* conn,Message* msg,const char* addr); ~YateH323Chan(); BOOL openAudioChannel(BOOL isEncoding, H323AudioCodec &codec); bool stopDataLinks(); - void hangup(); + void hangup(bool dropChan = true); void finish(); virtual void zeroRefs(); @@ -901,7 +901,7 @@ YateH323Connection::YateH323Connection(YateH323EndPoint& endpoint, // outgoing calls get the "call.execute" message as user data Message* msg = static_cast(userdata); - m_chan = new YateH323Chan(this,(userdata != 0), + m_chan = new YateH323Chan(this,msg, ((transport && !userdata) ? (const char*)transport->GetRemoteAddress() : 0)); if (!msg) { m_passtrough = s_passtrough; @@ -939,9 +939,10 @@ void YateH323Connection::CleanUpOnCallEnd() H323Connection::CleanUpOnCallEnd(); } -void YateH323Connection::cleanups(bool closeChans) +void YateH323Connection::cleanups(bool closeChans, bool dropChan) { - m_chan = 0; + if (dropChan) + m_chan = 0; if (closeChans) { CloseAllLogicalChannels(true); CloseAllLogicalChannels(false); @@ -960,7 +961,10 @@ H323Connection::AnswerCallResponse YateH323Connection::OnAnswerCall(const PStrin return H323Connection::AnswerCallDenied; } + const YateH323EndPoint& ep = static_cast(GetEndPoint()); Message *m = m_chan->message("call.route",false,true); + if (ep.c_str()) + m->setParam("in_line",ep.c_str()); const char *s = s_cfg.getValue("incoming","context"); if (s) m->setParam("context",s); @@ -1375,8 +1379,8 @@ BOOL YateH323Connection::startExternalRTP(const char* remoteIP, WORD remotePort, void YateH323Connection::stoppedExternal(H323Channel::Directions dir) { - Debug(m_chan,DebugInfo,"YateH323Connection::stoppedExternal(%s) [%p]", - lookup(dir,dict_h323_dir),this); + Debug(m_chan,DebugInfo,"YateH323Connection::stoppedExternal(%s) chan=%p [%p]", + lookup(dir,dict_h323_dir),m_chan,this); if (!m_chan) return; switch (dir) { @@ -1751,14 +1755,20 @@ void YateH323Connection::setCallerID(const char* number, const char* name) } } -YateH323Chan::YateH323Chan(YateH323Connection* conn,bool outgoing,const char* addr) - : Channel(hplugin,0,outgoing), m_conn(conn), m_hungup(false) +YateH323Chan::YateH323Chan(YateH323Connection* conn,Message* msg,const char* addr) + : Channel(hplugin,0,(msg != 0)), m_conn(conn), m_hungup(false) { Debug(this,DebugAll,"YateH323Chan::YateH323Chan(%p,%s) %s [%p]", conn,addr,direction(),this); m_address = addr; m_address.startSkip("ip$",false); - Engine::enqueue(message("chan.startup")); + Message* s = message("chan.startup"); + if (msg) { + s->setParam("caller",msg->getValue("caller")); + s->setParam("called",msg->getValue("called")); + s->setParam("billid",msg->getValue("billid")); + } + Engine::enqueue(s); } YateH323Chan::~YateH323Chan() @@ -1775,13 +1785,13 @@ YateH323Chan::~YateH323Chan() void YateH323Chan::zeroRefs() { - XDebug(this,DebugAll,"YateH323Chan::zeroRefs() [%p]",this); + DDebug(this,DebugAll,"YateH323Chan::zeroRefs() conn=%p [%p]",m_conn,this); stopDataLinks(); if (m_conn) { // let the OpenH323 cleaner thread to do the cleanups so we don't have // to block until the native data threads terminate dropChan(); - hangup(); + hangup(false); cleanup(); return; } @@ -1790,7 +1800,7 @@ void YateH323Chan::zeroRefs() void YateH323Chan::finish() { - XDebug(this,DebugAll,"YateH323Chan::finish() [%p]",this); + DDebug(this,DebugAll,"YateH323Chan::finish() [%p]",this); m_conn = 0; if (m_hungup) delete this; @@ -1800,8 +1810,9 @@ void YateH323Chan::finish() } } -void YateH323Chan::hangup() +void YateH323Chan::hangup(bool dropChan) { + DDebug(this,DebugAll,"YateH323Chan::hangup() [%p]",this); if (m_hungup) return; m_hungup = true; @@ -1820,7 +1831,7 @@ void YateH323Chan::hangup() m->setParam("error",err); if (txt) m->setParam("reason",txt); - tmp->cleanups(false); + tmp->cleanups(false,dropChan); tmp->ClearCall(); } Engine::enqueue(m); diff --git a/modules/iaxchan.cpp b/modules/iaxchan.cpp index aaa599da..5c47c931 100644 --- a/modules/iaxchan.cpp +++ b/modules/iaxchan.cpp @@ -121,7 +121,7 @@ public: class IAXConnection : public Channel { public: - IAXConnection(Driver* driver, const char* addr, iax_session *session = 0); + IAXConnection(Driver* driver, const char* addr, iax_session* session, Message* msg = 0); ~IAXConnection(); virtual void disconnected(bool final, const char *reason); void abort(int type = 0); @@ -484,7 +484,7 @@ void IAXEndPoint::reg(iax_event *e) s_mutex.unlock(); } -IAXConnection::IAXConnection(Driver* driver, const char* addr, iax_session *session) +IAXConnection::IAXConnection(Driver* driver, const char* addr, iax_session* session, Message* msg) : Channel(driver,0,(session == 0)), m_session(session), m_final(false), m_muted(false), m_ast_format(0), m_format(0), m_capab(0), m_reason(0) @@ -496,9 +496,14 @@ IAXConnection::IAXConnection(Driver* driver, const char* addr, iax_session *sess m_session = ::iax_session_new(); ::iax_set_private(m_session,this); s_mutex.unlock(); - Message* m = message("chan.startup"); - m->addParam("direction",status()); - Engine::enqueue(m); + Message* s = message("chan.startup"); + s->setParam("direction",status()); + if (msg) { + s->setParam("caller",msg->getValue("caller")); + s->setParam("called",msg->getValue("called")); + s->setParam("billid",msg->getValue("billid")); + } + Engine::enqueue(s); } @@ -854,7 +859,7 @@ bool IAXDriver::msgExecute(Message& msg, String& dest) Debug(DebugWarn,"IAX call found but no data channel!"); return false; } - IAXConnection *conn = new IAXConnection(this,dest); + IAXConnection *conn = new IAXConnection(this,dest,0,&msg); /* i do this to setup the peercallid by getting id * from the other party */ int i = conn->makeCall(msg.getValue("id"),(char *)msg.getValue("caller"),(char *)msg.getValue("callername"),(char *)dest.c_str()); diff --git a/modules/libypri.cpp b/modules/libypri.cpp index 2a869b9d..86b81273 100644 --- a/modules/libypri.cpp +++ b/modules/libypri.cpp @@ -834,6 +834,9 @@ bool PriChan::call(Message &msg, const char *called) setTimeout(30000000); status(chanStatus()); Message *m = message("chan.startup"); + m->setParam("caller",msg.getValue("caller")); + m->setParam("called",msg.getValue("called")); + m->setParam("billid",msg.getValue("billid")); m->addParam("span",String(m_span->span())); m->addParam("channel",String(m_chan)); m->addParam("direction","outgoing"); diff --git a/modules/osschan.cpp b/modules/osschan.cpp index 1ae36cb9..a9cf8f92 100644 --- a/modules/osschan.cpp +++ b/modules/osschan.cpp @@ -34,7 +34,7 @@ #if defined(__linux__) #include #elif defined (__FreeBSD__) -#include +#include #else #include #endif diff --git a/yateclass.h b/yateclass.h index 4f5f34f0..ab48ca76 100644 --- a/yateclass.h +++ b/yateclass.h @@ -110,6 +110,11 @@ typedef unsigned long in_addr_t; #include #include + +#if defined(__FreeBSD__) +#include +#endif + #include #include #include