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://voip.null.ro/svn/yate@553 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2005-10-30 04:03:25 +00:00
parent 7d1b1b88c4
commit 1657dafa0c
12 changed files with 113 additions and 33 deletions

View File

@ -1,3 +1,10 @@
Sun Oct 30 2005 Paul Chitescu <paulc-devel@null.ro>
- 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 <paulc-devel@null.ro>
- Automatic authentication support in SIP transactions
- Some degree of NAT support in SIP and RTP

View File

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

View File

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

View File

@ -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 <dlfcn.h>],[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

View File

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

View File

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

View File

@ -25,6 +25,7 @@
#include <yatengine.h>
#include <string.h>
#include <stdio.h>
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;

View File

@ -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<Message*>(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<const YateH323EndPoint&>(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);

View File

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

View File

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

View File

@ -34,7 +34,7 @@
#if defined(__linux__)
#include <linux/soundcard.h>
#elif defined (__FreeBSD__)
#include <machine/soundcard.h>
#include <sys/soundcard.h>
#else
#include <soundcard.h>
#endif

View File

@ -110,6 +110,11 @@ typedef unsigned long in_addr_t;
#include <sys/time.h>
#include <sys/socket.h>
#if defined(__FreeBSD__)
#include <netinet/in_systm.h>
#endif
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>