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:
parent
7d1b1b88c4
commit
1657dafa0c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
15
configure.in
15
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 <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
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue