Added final parameter to disconnect. Renamed most messages.
Version header file is generated at configure time. Added soname in library. Proper handling of DTMF in IAX, H.323 and Zap. git-svn-id: http://voip.null.ro/svn/yate@133 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
3a8e0a6406
commit
f619a3765f
|
@ -3,6 +3,7 @@ Makefile
|
|||
configure
|
||||
config.*
|
||||
yatepaths.h
|
||||
yateversn.h
|
||||
run
|
||||
yate.spec
|
||||
yate
|
||||
|
|
15
Makefile.in
15
Makefile.in
|
@ -12,7 +12,7 @@ SED := sed
|
|||
DEFS :=
|
||||
LIBAUX:= -ldl
|
||||
LIBTHR:= -lpthread
|
||||
INCLUDES := -I@srcdir@
|
||||
INCLUDES := -I. -I@srcdir@
|
||||
CFLAGS := -O2 @MODULE_CFLAGS@ @INLINE_FLAGS@
|
||||
LDFLAGS:=
|
||||
LDCONFIG:=true
|
||||
|
@ -20,7 +20,8 @@ LDCONFIG:=true
|
|||
MKDEPS := ./config.status
|
||||
PROGS:= yate
|
||||
SLIBS:= libyate.so
|
||||
INCS := telengine.h telephony.h yateversn.h
|
||||
INCS := telengine.h telephony.h
|
||||
GENS := yateversn.h
|
||||
LIBS :=
|
||||
MAN8 := yate.8
|
||||
DOCS := README COPYING ChangeLog
|
||||
|
@ -126,6 +127,9 @@ install install-root: all apidocs
|
|||
for i in $(INCS) ; do \
|
||||
install -m 0644 @srcdir@/$$i "$(DESTDIR)$(incdir)/" ; \
|
||||
done
|
||||
for i in $(GENS) ; do \
|
||||
install -m 0644 $$i "$(DESTDIR)$(incdir)/" ; \
|
||||
done
|
||||
@mkdir -p "$(DESTDIR)$(docdir)/api/" && \
|
||||
for i in $(DOCS) ; do \
|
||||
install -m 0644 @srcdir@/$$i "$(DESTDIR)$(docdir)/" ; \
|
||||
|
@ -144,7 +148,7 @@ uninstall uninstall-root:
|
|||
done
|
||||
@-rm "$(DESTDIR)$(libdir)/pkgconfig/yate.pc" && \
|
||||
rmdir $(DESTDIR)$(libdir)/pkgconfig
|
||||
@-for i in $(INCS) ; do \
|
||||
@-for i in $(INCS) $(GENS) ; do \
|
||||
rm "$(DESTDIR)$(incdir)/$$i" ; \
|
||||
done; \
|
||||
rmdir "$(DESTDIR)$(incdir)"
|
||||
|
@ -183,6 +187,7 @@ snapshot tarball: check-topdir clean tables apidocs
|
|||
--exclude $$wd/yate-config \
|
||||
--exclude $$wd/yate.pc \
|
||||
--exclude $$wd/yatepaths.h \
|
||||
--exclude $$wd/yateversn.h \
|
||||
-X $$wd/tar-exclude \
|
||||
$$wd; \
|
||||
rm $$wd/tar-exclude
|
||||
|
@ -191,7 +196,7 @@ snapshot tarball: check-topdir clean tables apidocs
|
|||
check-topdir:
|
||||
@test -f configure || (echo "Must make this target in the top source directory"; exit 1)
|
||||
|
||||
Engine.o: @srcdir@/Engine.cpp $(MKDEPS) @srcdir@/telengine.h @srcdir@/yateversn.h yatepaths.h
|
||||
Engine.o: @srcdir@/Engine.cpp $(MKDEPS) @srcdir@/telengine.h yateversn.h yatepaths.h
|
||||
$(COMPILE) -c $<
|
||||
|
||||
DataBlock.o: @srcdir@/DataBlock.cpp $(MKDEPS) @srcdir@/telengine.h @srcdir@/telephony.h
|
||||
|
@ -213,7 +218,7 @@ yate: $(OBJS) libyate.so $(LIBS)
|
|||
$(LINK) -o $@ $(LIBTHR) $^
|
||||
|
||||
libyate.so: $(ENGOBJS) $(LIBS)
|
||||
$(LINK) -shared -o $@ $(LIBTHR) $^ $(LIBAUX)
|
||||
$(LINK) -shared -o $@ -Wl,--soname=$@ $(LIBTHR) $^ $(LIBAUX)
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
|
|
|
@ -445,7 +445,7 @@ void GtkClient::gtk_call (GtkWidget *button, gpointer data)
|
|||
{
|
||||
case STATUS_IDLE:
|
||||
{
|
||||
Message m("call");
|
||||
Message m("call.execute");
|
||||
gchar *address = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(s_client->m_address)->entry));
|
||||
if (::strchr(address,'/'))
|
||||
m.addParam("direct",address);
|
||||
|
@ -475,7 +475,7 @@ void GtkClient::gtk_hangup (GtkWidget *button, gpointer data)
|
|||
break;
|
||||
case STATUS_RINGOUT:
|
||||
case STATUS_INCALL:
|
||||
Message m("drop");
|
||||
Message m("call.drop");
|
||||
m.addParam("id","oss/");
|
||||
Engine::dispatch(m);
|
||||
break;
|
||||
|
@ -538,7 +538,7 @@ class GtkClientHandler : public MessageHandler
|
|||
{
|
||||
public:
|
||||
GtkClientHandler(int prio)
|
||||
: MessageHandler("route",prio) { }
|
||||
: MessageHandler("call.route",prio) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
|
11
configure.in
11
configure.in
|
@ -1,8 +1,16 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(YATE, 0.8.5)
|
||||
AC_INIT(YATE, 0.8.6)
|
||||
AC_CONFIG_SRCDIR([README])
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
PACKAGE_VERSION_MAJOR="${PACKAGE_VERSION%%.*}"
|
||||
PACKAGE_VERSION_MINOR="${PACKAGE_VERSION#*.}"
|
||||
PACKAGE_VERSION_MINOR="${PACKAGE_VERSION_MINOR%.*}"
|
||||
PACKAGE_VERSION_BUILD="${PACKAGE_VERSION##*.}"
|
||||
AC_SUBST(PACKAGE_VERSION_MAJOR)
|
||||
AC_SUBST(PACKAGE_VERSION_MINOR)
|
||||
AC_SUBST(PACKAGE_VERSION_BUILD)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC
|
||||
|
@ -466,6 +474,7 @@ AC_SUBST(MODULE_SYMBOLS)
|
|||
|
||||
AC_CONFIG_FILES([yate.spec
|
||||
yate.pc
|
||||
yateversn.h
|
||||
Makefile
|
||||
modules/Makefile
|
||||
scripts/Makefile
|
||||
|
|
|
@ -314,7 +314,7 @@ DataSource::~DataSource()
|
|||
|
||||
DataEndpoint::~DataEndpoint()
|
||||
{
|
||||
disconnect();
|
||||
disconnect(true,0);
|
||||
setSource();
|
||||
setConsumer();
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ bool DataEndpoint::connect(DataEndpoint *peer)
|
|||
return true;
|
||||
}
|
||||
|
||||
void DataEndpoint::disconnect(const char *reason)
|
||||
void DataEndpoint::disconnect(bool final, const char *reason)
|
||||
{
|
||||
if (!m_peer)
|
||||
return;
|
||||
|
@ -373,7 +373,7 @@ void DataEndpoint::disconnect(const char *reason)
|
|||
m_peer = 0;
|
||||
temp->setPeer(0,reason);
|
||||
temp->deref();
|
||||
disconnected(reason);
|
||||
disconnected(final,reason);
|
||||
deref();
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ void DataEndpoint::setPeer(DataEndpoint *peer, const char *reason)
|
|||
if (m_peer)
|
||||
connected();
|
||||
else
|
||||
disconnected(reason);
|
||||
disconnected(false,reason);
|
||||
}
|
||||
|
||||
void DataEndpoint::setSource(DataSource *source)
|
||||
|
|
|
@ -164,7 +164,7 @@ public:
|
|||
class EngineStatusHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
EngineStatusHandler() : MessageHandler("status",0) { }
|
||||
EngineStatusHandler() : MessageHandler("engine.status",0) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
|
|
@ -10,12 +10,12 @@ DEBUG :=
|
|||
CXX := @CXX@ -Wall
|
||||
SED := sed
|
||||
DEFS :=
|
||||
INCLUDES := -I@top_srcdir@
|
||||
INCLUDES := -I.. -I@top_srcdir@
|
||||
CFLAGS := -O2 @MODULE_CFLAGS@ @INLINE_FLAGS@
|
||||
LDFLAGS:= -L.. -lyate
|
||||
MODFLAGS:= @MODULE_LDFLAGS@
|
||||
MODSTRIP:= @MODULE_SYMBOLS@
|
||||
INCFILES := @top_srcdir@/telengine.h @top_srcdir@/telephony.h @top_srcdir@/yateversn.h
|
||||
INCFILES := @top_srcdir@/telengine.h @top_srcdir@/telephony.h ../yateversn.h
|
||||
|
||||
SUBDIRS :=
|
||||
MKDEPS := ../config.status
|
||||
|
|
|
@ -52,7 +52,7 @@ private:
|
|||
class StatusHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
StatusHandler() : MessageHandler("status") { }
|
||||
StatusHandler() : MessageHandler("engine.status") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
@ -67,6 +67,7 @@ public:
|
|||
String getStatus() const;
|
||||
static CdrBuilder *find(String &id);
|
||||
private:
|
||||
void emit(const char *operation = 0);
|
||||
inline static int sec(unsigned long long usec)
|
||||
{ return (usec + 500000) / 1000000; }
|
||||
unsigned long long
|
||||
|
@ -78,42 +79,55 @@ private:
|
|||
String m_caller;
|
||||
String m_called;
|
||||
String m_status;
|
||||
bool m_first;
|
||||
};
|
||||
|
||||
static ObjList cdrs;
|
||||
|
||||
CdrBuilder::CdrBuilder(const char *name, const char *caller, const char *called)
|
||||
: String(name), m_caller(caller), m_called(called), m_status("unknown")
|
||||
: String(name), m_caller(caller), m_called(called), m_status("unknown"), m_first(true)
|
||||
{
|
||||
m_ring = m_call = m_ringing = m_answer = m_hangup = 0;
|
||||
}
|
||||
|
||||
CdrBuilder::~CdrBuilder()
|
||||
{
|
||||
emit("finalize");
|
||||
}
|
||||
|
||||
void CdrBuilder::emit(const char *operation)
|
||||
{
|
||||
unsigned long long t_hangup = m_hangup ? m_hangup : Time::now();
|
||||
const char *dir = m_ring ?
|
||||
(m_call ? "bidir" : "incoming") :
|
||||
(m_call ? "outgoing" : "unknown");
|
||||
|
||||
if (!m_hangup)
|
||||
m_hangup = Time::now();
|
||||
if (!m_ring)
|
||||
m_ring = m_call;
|
||||
if (!m_call)
|
||||
m_call = m_ring;
|
||||
if (!m_ringing)
|
||||
m_ringing = m_call;
|
||||
if (!m_answer)
|
||||
m_answer = m_hangup;
|
||||
unsigned long long
|
||||
t_ring = m_ring, t_call = m_call,
|
||||
t_ringing = m_ringing, t_answer = m_answer;
|
||||
if (!t_ring)
|
||||
t_ring = t_call;
|
||||
if (!t_call)
|
||||
t_call = t_ring;
|
||||
if (!t_ringing)
|
||||
t_ringing = t_call;
|
||||
if (!t_answer)
|
||||
t_answer = t_hangup;
|
||||
|
||||
Message *m = new Message("cdr");
|
||||
m->addParam("time",String(sec(m_ring)));
|
||||
if (!operation)
|
||||
operation = m_first ? "initialize" : "update";
|
||||
m_first = false;
|
||||
|
||||
Message *m = new Message("call.cdr");
|
||||
m->addParam("operation",operation);
|
||||
m->addParam("time",String(sec(t_ring)));
|
||||
m->addParam("chan",c_str());
|
||||
m->addParam("direction",dir);
|
||||
m->addParam("caller",m_caller);
|
||||
m->addParam("called",m_called);
|
||||
m->addParam("duration",String(sec(m_hangup - m_ring)));
|
||||
m->addParam("billtime",String(sec(m_hangup - m_answer)));
|
||||
m->addParam("ringtime",String(sec(m_answer - m_ringing)));
|
||||
m->addParam("duration",String(sec(t_hangup - t_ring)));
|
||||
m->addParam("billtime",String(sec(t_hangup - t_answer)));
|
||||
m->addParam("ringtime",String(sec(t_answer - t_ringing)));
|
||||
m->addParam("status",m_status);
|
||||
Engine::enqueue(m);
|
||||
}
|
||||
|
@ -143,8 +157,10 @@ void CdrBuilder::update(int type, unsigned long long val)
|
|||
break;
|
||||
case CdrHangup:
|
||||
m_hangup = val;
|
||||
break;
|
||||
cdrs.remove(this);
|
||||
return;
|
||||
}
|
||||
emit();
|
||||
}
|
||||
|
||||
CdrBuilder *CdrBuilder::find(String &id)
|
||||
|
@ -186,10 +202,6 @@ bool CdrHandler::received(Message &msg)
|
|||
if (s)
|
||||
b->setStatus(s);
|
||||
b->update(m_type,msg.msgTime().usec());
|
||||
if (m_type == CdrHangup) {
|
||||
cdrs.remove(b);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
Debug("CdrBuilder",DebugGoOn,"Got message '%s' for untracked id '%s'",
|
||||
|
@ -205,10 +217,15 @@ bool StatusHandler::received(Message &msg)
|
|||
String st("name=cdrbuild,type=cdr,format=Status|Caller|Called");
|
||||
st << ";cdrs=" << cdrs.count() << ";";
|
||||
ObjList *l = &cdrs;
|
||||
bool first = true;
|
||||
for (; l; l=l->next()) {
|
||||
CdrBuilder *b = static_cast<CdrBuilder *>(l->get());
|
||||
if (b) {
|
||||
st << "," << *b << "=" << b->getStatus();
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
st << ",";
|
||||
st << *b << "=" << b->getStatus();
|
||||
}
|
||||
}
|
||||
msg.retValue() << st << "\n";
|
||||
|
@ -236,12 +253,12 @@ void CdrBuildPlugin::initialize()
|
|||
Output("Initializing module CdrBuild");
|
||||
if (m_first) {
|
||||
m_first = false;
|
||||
Engine::install(new CdrHandler("ring",CdrRing));
|
||||
Engine::install(new CdrHandler("call",CdrCall));
|
||||
Engine::install(new CdrHandler("ringing",CdrRinging));
|
||||
Engine::install(new CdrHandler("answer",CdrAnswer));
|
||||
Engine::install(new CdrHandler("hangup",CdrHangup));
|
||||
Engine::install(new CdrHandler("dropcdr",CdrDrop));
|
||||
Engine::install(new CdrHandler("call.preroute",CdrRing));
|
||||
Engine::install(new CdrHandler("call.execute",CdrCall));
|
||||
Engine::install(new CdrHandler("call.ringing",CdrRinging));
|
||||
Engine::install(new CdrHandler("call.answered",CdrAnswer));
|
||||
Engine::install(new CdrHandler("call.hangup",CdrHangup));
|
||||
Engine::install(new CdrHandler("call.dropcdr",CdrDrop));
|
||||
Engine::install(new CdrHandler("engine.halt",EngHalt));
|
||||
Engine::install(new StatusHandler);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ void CdrFileHandler::init(const char *fname, bool tabsep)
|
|||
|
||||
bool CdrFileHandler::received(Message &msg)
|
||||
{
|
||||
String op(msg.getValue("operation"));
|
||||
if (op != "finalize")
|
||||
return false;
|
||||
|
||||
Lock lock(m_lock);
|
||||
if (m_file) {
|
||||
const char *format = m_tabs
|
||||
|
@ -104,7 +108,7 @@ void CdrFilePlugin::initialize()
|
|||
Configuration cfg(Engine::configFile("cdrfile"));
|
||||
const char *file = cfg.getValue("general","file");
|
||||
if (file && !m_handler) {
|
||||
m_handler = new CdrFileHandler("cdr");
|
||||
m_handler = new CdrFileHandler("call.cdr");
|
||||
Engine::install(m_handler);
|
||||
}
|
||||
if (m_handler)
|
||||
|
|
|
@ -43,6 +43,10 @@ private:
|
|||
|
||||
bool CdrPgsqlHandler::received(Message &msg)
|
||||
{
|
||||
String op(msg.getValue("operation"));
|
||||
if (op != "finalize")
|
||||
return false;
|
||||
|
||||
// const char *calltime = c_safe(msg.getValue("time"));
|
||||
const char *channel = c_safe(msg.getValue("channel"));
|
||||
const char *called = c_safe(msg.getValue("called"));
|
||||
|
@ -134,9 +138,9 @@ void CdrPgsqlPlugin::initialize()
|
|||
}
|
||||
if (!m_handler) {
|
||||
Output("Installing Cdr for PostgreSQL handler");
|
||||
m_handler = new CdrPgsqlHandler("cdr");
|
||||
m_handler = new CdrPgsqlHandler("call.cdr");
|
||||
Engine::install(m_handler);
|
||||
Engine::install(new StatusHandler("status"));
|
||||
Engine::install(new StatusHandler("engine.status"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
};
|
||||
static ExtModChan* build(const char *file, const char *args, int type);
|
||||
~ExtModChan();
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
inline ExtModReceiver* receiver() const
|
||||
{ return m_recv; }
|
||||
inline void setRecv(ExtModReceiver* recv)
|
||||
|
@ -303,7 +303,7 @@ ExtModChan::~ExtModChan()
|
|||
m_recv->die(false);
|
||||
}
|
||||
|
||||
void ExtModChan::disconnected(const char *reason)
|
||||
void ExtModChan::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debugger debug("ExtModChan::disconnected()"," '%s' [%p]",reason,this);
|
||||
}
|
||||
|
@ -837,9 +837,9 @@ void ExtModulePlugin::initialize()
|
|||
s_cfg = Engine::configFile("extmodule");
|
||||
s_cfg.load();
|
||||
if (!m_handler) {
|
||||
m_handler = new ExtModHandler("call");
|
||||
m_handler = new ExtModHandler("call.execute");
|
||||
Engine::install(m_handler);
|
||||
Engine::install(new ExtModCommand("command"));
|
||||
Engine::install(new ExtModCommand("engine.command"));
|
||||
NamedList *list = s_cfg.getSection("scripts");
|
||||
if (list)
|
||||
{
|
||||
|
|
|
@ -58,7 +58,7 @@ class FaxChan : public DataEndpoint
|
|||
public:
|
||||
FaxChan(const char *file, bool receive, bool iscaller, const char *ident = 0);
|
||||
~FaxChan();
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
void rxData(const DataBlock &data);
|
||||
void rxBlock(void *buff, int len);
|
||||
int txBlock();
|
||||
|
@ -303,7 +303,7 @@ void FaxChan::phaseE(int result)
|
|||
m_eof = true;
|
||||
}
|
||||
|
||||
void FaxChan::disconnected(const char *reason)
|
||||
void FaxChan::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debug(DebugInfo,"FaxChan::disconnected() '%s' [%p]",reason,this);
|
||||
}
|
||||
|
@ -350,15 +350,15 @@ bool FaxHandler::received(Message &msg)
|
|||
fc->destruct();
|
||||
return false;
|
||||
}
|
||||
Message m("preroute");
|
||||
Message m("call.preroute");
|
||||
m.addParam("id",dest);
|
||||
m.addParam("caller",dest);
|
||||
m.addParam("called",targ);
|
||||
m.userData(fc);
|
||||
Engine::dispatch(m);
|
||||
m = "route";
|
||||
m = "call.route";
|
||||
if (Engine::dispatch(m)) {
|
||||
m = "call";
|
||||
m = "call.execute";
|
||||
m.addParam("callto",m.retValue());
|
||||
m.retValue() = 0;
|
||||
if (Engine::dispatch(m)) {
|
||||
|
@ -384,7 +384,7 @@ void FaxPlugin::initialize()
|
|||
{
|
||||
Output("Initializing module Fax");
|
||||
if (!m_handler) {
|
||||
m_handler = new FaxHandler("call");
|
||||
m_handler = new FaxHandler("call.execute");
|
||||
Engine::install(m_handler);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,19 +225,22 @@ public:
|
|||
BOOL OnCreateLogicalChannel(const H323Capability & capability, H323Channel::Directions dir, unsigned & errorCode ) ;
|
||||
BOOL StartExternalRTP(const char* remoteIP, WORD remotePort, H323Channel::Directions dir, YateH323_ExternalRTPChannel* chan);
|
||||
void OnStoppedExternal(H323Channel::Directions dir);
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
inline const String &id() const
|
||||
{ return m_id; }
|
||||
inline const String &status() const
|
||||
{ return m_status; }
|
||||
inline void setStatus(const char *status)
|
||||
{ m_status = status; }
|
||||
inline void setTarget(const char *target = 0)
|
||||
{ m_targetid = target; }
|
||||
inline static int total()
|
||||
{ return s_total; }
|
||||
private:
|
||||
bool m_nativeRtp;
|
||||
String m_id;
|
||||
String m_status;
|
||||
String m_targetid;
|
||||
static int s_total;
|
||||
};
|
||||
|
||||
|
@ -280,6 +283,20 @@ public:
|
|||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class H323DTMF : public MessageHandler
|
||||
{
|
||||
public:
|
||||
H323DTMF(const char *name) : MessageHandler(name) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class H323Text : public MessageHandler
|
||||
{
|
||||
public:
|
||||
H323Text(const char *name) : MessageHandler(name) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class H323Stopper : public MessageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -309,7 +326,7 @@ private:
|
|||
class StatusHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
StatusHandler() : MessageHandler("status") { }
|
||||
StatusHandler() : MessageHandler("engine.status") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
@ -321,7 +338,7 @@ public:
|
|||
virtual void initialize();
|
||||
virtual bool isBusy() const;
|
||||
void cleanup();
|
||||
YateH323Connection *findConnectionLock(const char *id);
|
||||
YateH323Connection *findConnectionLock(const String& id);
|
||||
inline YateH323EndPoint *ep()
|
||||
{ return m_endpoint; }
|
||||
inline ObjList &calls()
|
||||
|
@ -346,9 +363,7 @@ bool H323MsgThread::route()
|
|||
{
|
||||
Debug(DebugAll,"Routing thread for %s [%p]",m_id.c_str(),this);
|
||||
Engine::dispatch(m_msg);
|
||||
*m_msg = "preroute";
|
||||
Engine::dispatch(m_msg);
|
||||
*m_msg = "route";
|
||||
*m_msg = "call.route";
|
||||
bool ok = Engine::dispatch(m_msg) && !m_msg->retValue().null();
|
||||
YateH323Connection *conn = hplugin.findConnectionLock(m_id);
|
||||
if (!conn) {
|
||||
|
@ -357,13 +372,14 @@ bool H323MsgThread::route()
|
|||
}
|
||||
if (ok) {
|
||||
conn->AnsweringCall(H323Connection::AnswerCallPending);
|
||||
*m_msg = "call";
|
||||
*m_msg = "call.execute";
|
||||
m_msg->addParam("callto",m_msg->retValue());
|
||||
m_msg->retValue() = 0;
|
||||
m_msg->userData(static_cast<DataEndpoint *>(conn));
|
||||
if (Engine::dispatch(m_msg)) {
|
||||
Debug(DebugInfo,"Routing H.323 call %s [%p] to '%s'",m_id.c_str(),conn,m_msg->getValue("callto"));
|
||||
conn->setStatus("routed");
|
||||
conn->setTarget(m_msg->getValue("targetid"));
|
||||
conn->AnsweringCall(H323Connection::AnswerCallNow);
|
||||
conn->deref();
|
||||
}
|
||||
|
@ -617,7 +633,7 @@ H323Connection::AnswerCallResponse YateH323Connection::OnAnswerCall(const PStrin
|
|||
return H323Connection::AnswerCallDenied;
|
||||
}
|
||||
|
||||
Message *m = new Message("ring");
|
||||
Message *m = new Message("call.preroute");
|
||||
m->addParam("driver","h323");
|
||||
m->addParam("id",m_id);
|
||||
const char *s = s_cfg.getValue("incoming","context");
|
||||
|
@ -667,11 +683,13 @@ void YateH323Connection::OnEstablished()
|
|||
s_total++;
|
||||
setStatus("connected");
|
||||
s_calls.unlock();
|
||||
if (!HadAnsweredCall())
|
||||
if (HadAnsweredCall())
|
||||
return;
|
||||
Message *m = new Message("answer");
|
||||
Message *m = new Message("call.answered");
|
||||
m->addParam("driver","h323");
|
||||
m->addParam("id",m_id);
|
||||
if (m_targetid)
|
||||
m->addParam("targetid",m_targetid);
|
||||
m->addParam("status","answered");
|
||||
Engine::enqueue(m);
|
||||
}
|
||||
|
@ -680,23 +698,24 @@ void YateH323Connection::OnCleared()
|
|||
{
|
||||
Debug(DebugInfo,"YateH323Connection::OnCleared() [%p]",this);
|
||||
setStatus("cleared");
|
||||
bool ans = HadAnsweredCall();
|
||||
disconnect();
|
||||
if (!ans)
|
||||
return;
|
||||
Message *m = new Message("hangup");
|
||||
Message *m = new Message("call.hangup");
|
||||
m->addParam("driver","h323");
|
||||
m->addParam("id",m_id);
|
||||
if (m_targetid)
|
||||
m->addParam("targetid",m_targetid);
|
||||
Engine::enqueue(m);
|
||||
disconnect();
|
||||
}
|
||||
|
||||
BOOL YateH323Connection::OnAlerting(const H323SignalPDU &alertingPDU, const PString &user)
|
||||
{
|
||||
Debug(DebugInfo,"YateH323Connection::OnAlerting '%s' [%p]",(const char *)user,this);
|
||||
setStatus("ringing");
|
||||
Message *m = new Message("ringing");
|
||||
Message *m = new Message("call.ringing");
|
||||
m->addParam("driver","h323");
|
||||
m->addParam("id",m_id);
|
||||
if (m_targetid)
|
||||
m->addParam("targetid",m_targetid);
|
||||
Engine::enqueue(m);
|
||||
return true;
|
||||
}
|
||||
|
@ -704,11 +723,31 @@ BOOL YateH323Connection::OnAlerting(const H323SignalPDU &alertingPDU, const PStr
|
|||
void YateH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
|
||||
{
|
||||
Debug(DebugInfo,"YateH323Connection::OnUserInputTone '%c' duration=%u [%p]",tone,duration,this);
|
||||
char buf[2];
|
||||
buf[0] = tone;
|
||||
buf[1] = 0;
|
||||
Message *m = new Message("chan.dtmf");
|
||||
m->addParam("driver","h323");
|
||||
m->addParam("id",m_id);
|
||||
if (m_targetid)
|
||||
m->addParam("targetid",m_targetid);
|
||||
m->addParam("text",buf);
|
||||
m->addParam("duration",String(duration));
|
||||
Engine::enqueue(m);
|
||||
}
|
||||
|
||||
void YateH323Connection::OnUserInputString(const PString &value)
|
||||
{
|
||||
Debug(DebugInfo,"YateH323Connection::OnUserInputString '%s' [%p]",(const char *)value,this);
|
||||
String text((const char *)value);
|
||||
const char *type = text.startSkip("MSG") ? "chan.text" : "chan.dtmf";
|
||||
Message *m = new Message(type);
|
||||
m->addParam("driver","h323");
|
||||
m->addParam("id",m_id);
|
||||
if (m_targetid)
|
||||
m->addParam("targetid",m_targetid);
|
||||
m->addParam("text",text);
|
||||
Engine::enqueue(m);
|
||||
}
|
||||
|
||||
BOOL YateH323Connection::OpenAudioChannel(BOOL isEncoding, unsigned bufferSize,
|
||||
|
@ -743,10 +782,11 @@ BOOL YateH323Connection::OpenAudioChannel(BOOL isEncoding, unsigned bufferSize,
|
|||
return false;
|
||||
}
|
||||
|
||||
void YateH323Connection::disconnected(const char *reason)
|
||||
void YateH323Connection::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debugger debug("YateH323Connection::disconnected()"," '%s' [%p]",reason,this);
|
||||
setStatus("disconnected");
|
||||
setTarget();
|
||||
// we must bypass the normal Yate refcounted destruction as OpenH323 will destroy the object
|
||||
ref();
|
||||
if (getSource() && m_nativeRtp)
|
||||
|
@ -770,7 +810,7 @@ H323Channel *YateH323Connection::CreateRealTimeLogicalChannel(const H323Capabili
|
|||
// GetControlChannel().GetLocalAddress().GetIpAndPort(externalIpAddress, port);
|
||||
GetControlChannel().GetLocalAddress().GetIpAddress(externalIpAddress);
|
||||
Debug(DebugInfo,"address '%s'",(const char *)externalIpAddress.AsString());
|
||||
Message m("rtp");
|
||||
Message m("chan.rtp");
|
||||
m.addParam("localip",externalIpAddress.AsString());
|
||||
m.userData(static_cast<DataEndpoint *>(this));
|
||||
Debug(DebugAll,"userData=%p this=%p",m.userData(),this);
|
||||
|
@ -812,7 +852,7 @@ BOOL YateH323Connection::StartExternalRTP(const char* remoteIP, WORD remotePort,
|
|||
const char* sdir = lookup(dir,dict_h323_dir);
|
||||
Debug(DebugAll,"YateH323Connection::StartExternalRTP(\"%s\",%u,%s,%p) [%p]",
|
||||
remoteIP,remotePort,sdir,chan,this);
|
||||
Message m("rtp");
|
||||
Message m("chan.rtp");
|
||||
m.userData(static_cast<DataEndpoint *>(this));
|
||||
Debug(DebugAll,"userData=%p this=%p",m.userData(),this);
|
||||
if (sdir)
|
||||
|
@ -1019,7 +1059,7 @@ BOOL YateH323AudioSource::Write(const void *buf, PINDEX len)
|
|||
|
||||
BOOL YateGatekeeperServer::GetUsersPassword(const PString & alias,PString & password) const
|
||||
{
|
||||
Message *m = new Message("auth");
|
||||
Message *m = new Message("user.auth");
|
||||
m->addParam("username",alias);
|
||||
Engine::dispatch(m);
|
||||
if (m->retValue() != NULL)
|
||||
|
@ -1056,7 +1096,7 @@ H323GatekeeperRequest::Response YateGatekeeperServer::OnRegistration(H323Gatekee
|
|||
* we deal just with the first callSignalAddress, since openh323
|
||||
* don't give a shit for multi hosted boxes.
|
||||
*/
|
||||
Message *m = new Message("regist");
|
||||
Message *m = new Message("user.register");
|
||||
m->addParam("username",alias);
|
||||
m->addParam("techno","h323gk");
|
||||
m->addParam("data",ips);
|
||||
|
@ -1077,7 +1117,7 @@ H323GatekeeperRequest::Response YateGatekeeperServer::OnUnregistration(H323Gatek
|
|||
PString alias = H323GetAliasAddressString(request.urq.m_endpointAlias[j]);
|
||||
if (alias.IsEmpty())
|
||||
return H323GatekeeperRequest::Reject;
|
||||
Message *m = new Message("unregist");
|
||||
Message *m = new Message("user.unregister");
|
||||
m->addParam("username",alias);
|
||||
Engine::dispatch(m);
|
||||
}
|
||||
|
@ -1089,7 +1129,7 @@ H323GatekeeperRequest::Response YateGatekeeperServer::OnUnregistration(H323Gatek
|
|||
BOOL YateGatekeeperServer::TranslateAliasAddressToSignalAddress(const H225_AliasAddress & alias,H323TransportAddress & address)
|
||||
{
|
||||
PString aliasString = H323GetAliasAddressString(alias);
|
||||
Message m("route");
|
||||
Message m("call.route");
|
||||
m.addParam("called",aliasString);
|
||||
Engine::dispatch(m);
|
||||
String s = m.retValue();
|
||||
|
@ -1172,7 +1212,9 @@ bool H323Handler::received(Message &msg)
|
|||
Debug(DebugInfo,"Found call to H.323 target='%s'",
|
||||
dest.matchString(1).c_str());
|
||||
PString p;
|
||||
H323Connection *conn = hplugin.ep()->MakeCallLocked(dest.matchString(1).c_str(),p,msg.userData());
|
||||
YateH323Connection* conn = static_cast<YateH323Connection*>(
|
||||
hplugin.ep()->MakeCallLocked(dest.matchString(1).c_str(),p,msg.userData())
|
||||
);
|
||||
if (conn) {
|
||||
String caller(msg.getValue("caller"));
|
||||
if (caller.null())
|
||||
|
@ -1183,6 +1225,8 @@ bool H323Handler::received(Message &msg)
|
|||
Debug(DebugInfo,"Setting H.323 caller name to '%s'",caller.c_str());
|
||||
conn->SetLocalPartyName(caller.c_str());
|
||||
}
|
||||
conn->setTarget(msg.getValue("id"));
|
||||
msg.addParam("targetid",conn->id());
|
||||
conn->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -1216,6 +1260,39 @@ bool H323Dropper::received(Message &msg)
|
|||
return false;
|
||||
};
|
||||
|
||||
bool H323DTMF::received(Message &msg)
|
||||
{
|
||||
String id(msg.getValue("targetid"));
|
||||
if (!id.startsWith("h323"))
|
||||
return false;
|
||||
String text(msg.getValue("text"));
|
||||
YateH323Connection *conn = hplugin.findConnectionLock(id);
|
||||
if (conn) {
|
||||
Debug("H323DTMF",DebugInfo,"Text '%s' for %s [%p]",text.c_str(),conn->id().c_str(),conn);
|
||||
for (unsigned int i = 0; i < text.length(); i++)
|
||||
conn->SendUserInputTone(text[i]);
|
||||
conn->Unlock();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool H323Text::received(Message &msg)
|
||||
{
|
||||
String id(msg.getValue("targetid"));
|
||||
if (!id.startsWith("h323"))
|
||||
return false;
|
||||
String text(msg.getValue("text"));
|
||||
YateH323Connection *conn = hplugin.findConnectionLock(id);
|
||||
if (conn) {
|
||||
Debug("H323Text",DebugInfo,"Text '%s' for %s [%p]",text.c_str(),conn->id().c_str(),conn);
|
||||
conn->SendUserInputIndicationString(text.safe());
|
||||
conn->Unlock();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool StatusHandler::received(Message &msg)
|
||||
{
|
||||
const char *sel = msg.getValue("module");
|
||||
|
@ -1277,7 +1354,7 @@ H323Plugin::~H323Plugin()
|
|||
}
|
||||
}
|
||||
|
||||
YateH323Connection *H323Plugin::findConnectionLock(const char *id)
|
||||
YateH323Connection *H323Plugin::findConnectionLock(const String& id)
|
||||
{
|
||||
s_calls.lock();
|
||||
ObjList *l = &m_calls;
|
||||
|
@ -1334,8 +1411,10 @@ void H323Plugin::initialize()
|
|||
s_externalRtp = s_cfg.getBoolValue("general","external_rtp",false);
|
||||
if (m_first) {
|
||||
m_first = false;
|
||||
Engine::install(new H323Handler("call"));
|
||||
Engine::install(new H323Dropper("drop"));
|
||||
Engine::install(new H323Handler("call.execute"));
|
||||
Engine::install(new H323Dropper("call.drop"));
|
||||
Engine::install(new H323DTMF("chan.dtmf"));
|
||||
Engine::install(new H323Text("chan.text"));
|
||||
Engine::install(new H323Stopper("engine.halt"));
|
||||
Engine::install(new StatusHandler);
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ class YateIAXConnection : public DataEndpoint
|
|||
public:
|
||||
YateIAXConnection(iax_session *session = 0);
|
||||
~YateIAXConnection();
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
void abort();
|
||||
int makeCall(char *cidnum, char *cidname, char *target = 0, char *lang = 0);
|
||||
void hangup(char *reason = "Unexpected problem");
|
||||
|
@ -139,7 +139,7 @@ public:
|
|||
inline iax_session *session() const
|
||||
{ return m_session; }
|
||||
String ourcallid;
|
||||
String partycallid;
|
||||
String targetid;
|
||||
String calleraddress;
|
||||
String calledaddress;
|
||||
private:
|
||||
|
@ -390,7 +390,7 @@ bool YateIAXEndPoint::accepting(iax_event *e)
|
|||
s_mutex.unlock();
|
||||
return 1;
|
||||
}
|
||||
Message m("auth");
|
||||
Message m("user.auth");
|
||||
if (e->ies.username)
|
||||
m.addParam("username",e->ies.username);
|
||||
else
|
||||
|
@ -459,7 +459,7 @@ void YateIAXEndPoint::answer(iax_event *e)
|
|||
{
|
||||
if (!accepting(e))
|
||||
return;
|
||||
Message *m = new Message("route");
|
||||
Message *m = new Message("call.route");
|
||||
m->addParam("driver","iax");
|
||||
// m->addParam("id",String(e->did));
|
||||
if (e->ies.calling_name)
|
||||
|
@ -477,10 +477,10 @@ void YateIAXEndPoint::answer(iax_event *e)
|
|||
//this have to be here to get the right called_address.
|
||||
conn->calledaddress = m->retValue();
|
||||
|
||||
*m = "call";
|
||||
*m = "call.execute";
|
||||
m->userData(conn);
|
||||
m->addParam("callto",m->retValue());
|
||||
m->addParam("ourcallid",conn->ourcallid);
|
||||
m->addParam("id",conn->ourcallid);
|
||||
m->retValue().clear();
|
||||
if (!Engine::dispatch(m))
|
||||
{
|
||||
|
@ -490,10 +490,10 @@ void YateIAXEndPoint::answer(iax_event *e)
|
|||
return;
|
||||
}
|
||||
/* i do this to setup the peercallid by getting
|
||||
* partycallid (that mean ourcallid from the other party) */
|
||||
String partycallid(m->getValue("partycallid"));
|
||||
Debug(DebugInfo,"partycallid %s",partycallid.c_str());
|
||||
conn->partycallid = partycallid;
|
||||
* targetid (that mean ourcallid from the other party) */
|
||||
String targetid(m->getValue("targetid"));
|
||||
Debug(DebugInfo,"targetid %s",targetid.c_str());
|
||||
conn->targetid = targetid;
|
||||
conn->deref();
|
||||
s_mutex.lock();
|
||||
::iax_answer(e->session);
|
||||
|
@ -526,7 +526,7 @@ void YateIAXEndPoint::answer(iax_event *e)
|
|||
|
||||
void YateIAXEndPoint::reg(iax_event *e)
|
||||
{
|
||||
Message m("auth");
|
||||
Message m("user.auth");
|
||||
if (e->ies.username)
|
||||
m.addParam("username",e->ies.username);
|
||||
else
|
||||
|
@ -652,30 +652,30 @@ void YateIAXConnection::handleEvent(iax_event *event)
|
|||
break;
|
||||
case IAX_EVENT_TEXT:
|
||||
{
|
||||
Message m("sms");
|
||||
Message m("chan.text");
|
||||
m.addParam("text",(char *)event->data);
|
||||
m.addParam("ourcallid",ourcallid.c_str());
|
||||
m.addParam("partycallid",partycallid.c_str());
|
||||
m.addParam("id",ourcallid.c_str());
|
||||
m.addParam("targetid",targetid.c_str());
|
||||
m.addParam("callerid",event->session->callerid);
|
||||
m.addParam("calledid",event->session->dnid);
|
||||
Engine::dispatch(m);
|
||||
Debug(DebugInfo,"this text is inside a call: %s",(char *)event->data);
|
||||
Debug("IAX EVENT TEXT",DebugInfo,"this text is inside a call: %s",(char *)event->data);
|
||||
}
|
||||
break;
|
||||
case IAX_EVENT_DTMF:
|
||||
{
|
||||
Message m("dtmf");
|
||||
Message m("chan.dtmf");
|
||||
/* this is because Paul wants this to be usable on non i386 */
|
||||
char buf[2];
|
||||
buf[0] = event->subclass;
|
||||
buf[1] = 0;
|
||||
m.addParam("text",buf);
|
||||
m.addParam("ourcallid",ourcallid.c_str());
|
||||
m.addParam("partycallid",partycallid.c_str());
|
||||
m.addParam("id",ourcallid.c_str());
|
||||
m.addParam("targetid",targetid.c_str());
|
||||
m.addParam("callerid",event->session->callerid);
|
||||
m.addParam("calledid",event->session->dnid);
|
||||
Engine::dispatch(m);
|
||||
Debug(DebugInfo,"this text is inside a call: %d",event->subclass);
|
||||
Debug("IAX EVENT DTMF",DebugInfo,"this text is inside a call: %d",event->subclass);
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
|
@ -783,19 +783,19 @@ void YateIAXConnection::sourceAudio(void *buffer, int len, int format)
|
|||
}
|
||||
}
|
||||
|
||||
void YateIAXConnection::disconnected(const char *reason)
|
||||
void YateIAXConnection::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debug(DebugAll,"YateIAXConnection::disconnected() '%s'",reason);
|
||||
// If we still have a connection this is the last chance to get transferred
|
||||
if (!m_final) {
|
||||
Message m("disconnected");
|
||||
m.addParam("ourcallid",ourcallid.c_str());
|
||||
if (!(final || m_final)) {
|
||||
Message m("chan.disconnected");
|
||||
m.addParam("id",ourcallid.c_str());
|
||||
if (reason)
|
||||
m.addParam("reason",reason);
|
||||
if (partycallid) {
|
||||
if (targetid) {
|
||||
// Announce our old party but at this point it may be destroyed
|
||||
m.addParam("partycallid",partycallid.c_str());
|
||||
partycallid.clear();
|
||||
m.addParam("targetid",targetid.c_str());
|
||||
targetid.clear();
|
||||
}
|
||||
m.userData(this);
|
||||
Engine::dispatch(m);
|
||||
|
@ -849,13 +849,13 @@ void YateIAXAudioConsumer::Consume(const DataBlock &data, unsigned long timeDelt
|
|||
|
||||
bool SMSHandler::received(Message &msg)
|
||||
{
|
||||
String ourcallid(msg.getValue("partycallid"));
|
||||
String ourcallid(msg.getValue("targetid"));
|
||||
if (!ourcallid)
|
||||
return false;
|
||||
String text(msg.getValue("text"));
|
||||
if (!text)
|
||||
return false;
|
||||
Debug(DebugInfo,"text %s ourcallid %s",text.c_str(),ourcallid.c_str());
|
||||
Debug("IAX TEXT",DebugInfo,"text %s ourcallid %s",text.c_str(),ourcallid.c_str());
|
||||
YateIAXConnection *conn= iplugin.m_endpoint->findconn(ourcallid);
|
||||
if (conn){
|
||||
s_mutex.lock();
|
||||
|
@ -868,13 +868,13 @@ bool SMSHandler::received(Message &msg)
|
|||
|
||||
bool DTMFHandler::received(Message &msg)
|
||||
{
|
||||
String ourcallid(msg.getValue("partycallid"));
|
||||
String ourcallid(msg.getValue("targetid"));
|
||||
if (!ourcallid)
|
||||
return false;
|
||||
String text(msg.getValue("text"));
|
||||
if (!text)
|
||||
return false;
|
||||
Debug(DebugInfo,"text %s ourcallid %s",text.c_str(), ourcallid.c_str());
|
||||
Debug("IAX DTMF",DebugInfo,"text %s ourcallid %s",text.c_str(), ourcallid.c_str());
|
||||
YateIAXConnection *conn= iplugin.m_endpoint->findconn(ourcallid);
|
||||
if (conn){
|
||||
s_mutex.lock();
|
||||
|
@ -902,8 +902,8 @@ bool IAXHandler::received(Message &msg)
|
|||
YateIAXConnection *conn = new YateIAXConnection();
|
||||
/* i do this to setup the peercallid by getting ourcallid
|
||||
* from the other party */
|
||||
String partycallid(msg.getValue("ourcallid"));
|
||||
conn->partycallid = partycallid;
|
||||
String targetid(msg.getValue("id"));
|
||||
conn->targetid = targetid;
|
||||
conn->calledaddress = dest;
|
||||
int i = conn->makeCall((char *)msg.getValue("caller"),(char *)msg.getValue("callername"),(char *)dest.matchString(1).safe());
|
||||
if (i < 0) {
|
||||
|
@ -914,7 +914,7 @@ bool IAXHandler::received(Message &msg)
|
|||
DataEndpoint *dd = static_cast<DataEndpoint *>(msg.userData());
|
||||
if (dd && conn->connect(dd))
|
||||
{
|
||||
msg.addParam("partycallid",conn->ourcallid);
|
||||
msg.addParam("targetid",conn->ourcallid);
|
||||
conn->deref();
|
||||
}
|
||||
return true;
|
||||
|
@ -936,7 +936,7 @@ bool StatusHandler::received(Message &msg)
|
|||
first = false;
|
||||
else
|
||||
st << ",";
|
||||
st << c->ourcallid << "=" << c->calledaddress << "|" << c->partycallid;
|
||||
st << c->ourcallid << "=" << c->calledaddress << "|" << c->targetid;
|
||||
}
|
||||
}
|
||||
msg.retValue() << st << "\n";
|
||||
|
@ -945,7 +945,7 @@ bool StatusHandler::received(Message &msg)
|
|||
|
||||
bool DropHandler::received(Message &msg)
|
||||
{
|
||||
String ourcallid(msg.getValue("ourcallid"));
|
||||
String ourcallid(msg.getValue("id"));
|
||||
if (ourcallid.null()) {
|
||||
Debug("IAXDroper",DebugInfo,"Dropping all calls");
|
||||
ObjList *l = &iplugin.m_endpoint->calls();
|
||||
|
@ -969,7 +969,7 @@ bool DropHandler::received(Message &msg)
|
|||
|
||||
bool TransferHandler::received(Message &msg)
|
||||
{
|
||||
String ourcallid(msg.getValue("partycallid"));
|
||||
String ourcallid(msg.getValue("targetid"));
|
||||
if (!ourcallid)
|
||||
return false;
|
||||
String callto(msg.getValue("callto"));
|
||||
|
@ -979,15 +979,15 @@ bool TransferHandler::received(Message &msg)
|
|||
if (conn) {
|
||||
Debug(DebugInfo,"Transferring connection '%s' [%p] to '%s'",
|
||||
ourcallid.c_str(),conn,callto.c_str());
|
||||
Message m("call");
|
||||
Message m("call.execute");
|
||||
m.addParam("callto",callto.c_str());
|
||||
m.addParam("ourcallid",conn->ourcallid);
|
||||
m.addParam("id",conn->ourcallid);
|
||||
m.userData(conn);
|
||||
if (Engine::dispatch(m)) {
|
||||
String partycallid(m.getValue("partycallid"));
|
||||
Debug(DebugInfo,"IAX [%p] transferred, new partyid '%s'",
|
||||
conn,partycallid.c_str());
|
||||
conn->partycallid = partycallid;
|
||||
String targetid(m.getValue("targetid"));
|
||||
Debug(DebugInfo,"IAX [%p] transferred, new targetid '%s'",
|
||||
conn,targetid.c_str());
|
||||
conn->targetid = targetid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1033,12 +1033,12 @@ void IAXPlugin::initialize()
|
|||
YateIAXEndPoint::Setup();
|
||||
if (m_first) {
|
||||
m_first = false;
|
||||
Engine::install(new IAXHandler("call"));
|
||||
Engine::install(new SMSHandler("sms"));
|
||||
Engine::install(new DTMFHandler("dtmf"));
|
||||
Engine::install(new StatusHandler("status"));
|
||||
Engine::install(new DropHandler("drop"));
|
||||
Engine::install(new TransferHandler("transfer"));
|
||||
Engine::install(new IAXHandler("call.execute"));
|
||||
Engine::install(new SMSHandler("chan.text"));
|
||||
Engine::install(new DTMFHandler("chan.dtmf"));
|
||||
Engine::install(new StatusHandler("engine.status"));
|
||||
Engine::install(new DropHandler("call.drop"));
|
||||
Engine::install(new TransferHandler("call.transfer"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
bool init();
|
||||
~OssChan();
|
||||
int setformat();
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
int soundcard_setinput(bool force);
|
||||
int soundcard_setoutput(bool force);
|
||||
int time_has_passed(void);
|
||||
|
@ -116,7 +116,7 @@ public:
|
|||
class StatusHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
StatusHandler() : MessageHandler("status") { }
|
||||
StatusHandler() : MessageHandler("engine.status") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
@ -358,7 +358,6 @@ int OssChan::soundcard_setinput(bool force)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int OssChan::soundcard_setoutput(bool force)
|
||||
{
|
||||
/* Make sure the soundcard is in output mode. */
|
||||
|
@ -384,10 +383,10 @@ int OssChan::soundcard_setoutput(bool force)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void OssChan::disconnected(const char *reason)
|
||||
void OssChan::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debugger debug("OssChan::disconnected()"," '%s' [%p]",reason,this);
|
||||
destruct();
|
||||
// destruct();
|
||||
}
|
||||
|
||||
bool OssHandler::received(Message &msg)
|
||||
|
@ -414,7 +413,7 @@ bool OssHandler::received(Message &msg)
|
|||
const char *direct = msg.getValue("direct");
|
||||
if (direct)
|
||||
{
|
||||
Message m("call");
|
||||
Message m("call.execute");
|
||||
m.addParam("id",dest);
|
||||
m.addParam("caller",dest);
|
||||
m.addParam("callto",direct);
|
||||
|
@ -429,12 +428,12 @@ bool OssHandler::received(Message &msg)
|
|||
Debug(DebugWarn,"OSS outgoing call with no target!");
|
||||
return false;
|
||||
}
|
||||
Message m("preroute");
|
||||
Message m("call.preroute");
|
||||
m.addParam("id",dest);
|
||||
m.addParam("caller",dest);
|
||||
m.addParam("called",targ);
|
||||
Engine::dispatch(m);
|
||||
m = "route";
|
||||
m = "call.route";
|
||||
if (Engine::dispatch(m)) {
|
||||
m = "call";
|
||||
m.addParam("callto",m.retValue());
|
||||
|
@ -486,8 +485,8 @@ void OssPlugin::initialize()
|
|||
{
|
||||
Output("Initializing module OssChan");
|
||||
if (!m_handler) {
|
||||
m_handler = new OssHandler("call");
|
||||
Engine::install(new DropHandler("drop"));
|
||||
m_handler = new OssHandler("call.execute");
|
||||
Engine::install(new DropHandler("call.drop"));
|
||||
Engine::install(m_handler);
|
||||
Engine::install(new StatusHandler);
|
||||
}
|
||||
|
|
|
@ -223,9 +223,9 @@ void PGSQLRoutePlugin::initialize()
|
|||
if (m_first && conn) {
|
||||
m_first = false;
|
||||
unsigned prio = cfg.getIntValue("general","priority",100);
|
||||
Engine::install(new PrerouteHandler("preroute",prio));
|
||||
Engine::install(new RouteHandler("route",prio));
|
||||
Engine::install(new StatusHandler("status"));
|
||||
Engine::install(new PrerouteHandler("call.preroute",prio));
|
||||
Engine::install(new RouteHandler("call.route",prio));
|
||||
Engine::install(new StatusHandler("engine.status"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class RouteHandler : public MessageHandler
|
|||
{
|
||||
public:
|
||||
RouteHandler(int prio)
|
||||
: MessageHandler("route",prio) { }
|
||||
: MessageHandler("call.route",prio) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
@ -191,7 +191,7 @@ class PrerouteHandler : public MessageHandler
|
|||
{
|
||||
public:
|
||||
PrerouteHandler(int prio)
|
||||
: MessageHandler("preroute",prio) { }
|
||||
: MessageHandler("call.preroute",prio) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
|
|
@ -141,9 +141,21 @@ bool RouteHandler::received(Message &msg)
|
|||
|
||||
bool StatusHandler::received(Message &msg)
|
||||
{
|
||||
msg.retValue() << "Regfile,users=";
|
||||
for (int i=0;i<s_cfg.sections();i++)
|
||||
msg.retValue() << s_cfg.getSection(i);
|
||||
unsigned int n = s_cfg.sections();
|
||||
if (!s_cfg.getSection(0))
|
||||
--n;
|
||||
msg.retValue() << "name=regfile,type=misc;users=" << n << ";";
|
||||
bool first = true;
|
||||
for (unsigned int i=0;i<s_cfg.sections();i++) {
|
||||
NamedList *user = s_cfg.getSection(i);
|
||||
if (!user)
|
||||
continue;
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
msg.retValue() << ",";
|
||||
msg.retValue() << *user << "=" << s_cfg.getBoolValue(*user,"register");
|
||||
}
|
||||
msg.retValue() <<"\n";
|
||||
return false;
|
||||
}
|
||||
|
@ -160,23 +172,23 @@ void RegfilePlugin::initialize()
|
|||
if (!m_authhandler) {
|
||||
s_cfg.load();
|
||||
Output("Installing Authentification handler");
|
||||
Engine::install(m_authhandler = new AuthHandler("auth",s_cfg.getIntValue("general","auth",10)));
|
||||
Engine::install(m_authhandler = new AuthHandler("user.auth",s_cfg.getIntValue("general","auth",10)));
|
||||
}
|
||||
if (!m_registhandler) {
|
||||
Output("Installing Registering handler");
|
||||
Engine::install(new RegistHandler("regist"));
|
||||
Engine::install(new RegistHandler("user.register"));
|
||||
}
|
||||
if (!m_unregisthandler) {
|
||||
Output("Installing UnRegistering handler");
|
||||
Engine::install(new UnRegistHandler("unregist"));
|
||||
Engine::install(new UnRegistHandler("user.unregister"));
|
||||
}
|
||||
if (!m_routehandler) {
|
||||
Output("Installing Route handler");
|
||||
Engine::install(new RouteHandler("route",s_cfg.getIntValue("general","route",100)));
|
||||
Engine::install(new RouteHandler("call.route",s_cfg.getIntValue("general","route",100)));
|
||||
}
|
||||
if (!m_statushandler) {
|
||||
Output("Installing Status handler");
|
||||
Engine::install(new StatusHandler("status"));
|
||||
Engine::install(new StatusHandler("engine.status"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,23 +288,23 @@ void RegistPlugin::initialize()
|
|||
}
|
||||
if (!m_registhandler) {
|
||||
Output("Installing Registering handler");
|
||||
Engine::install(m_registhandler = new RegistHandler("regist"));
|
||||
Engine::install(m_registhandler = new RegistHandler("user.register"));
|
||||
}
|
||||
if (!m_unregisthandler) {
|
||||
Output("Installing UnRegistering handler");
|
||||
Engine::install(m_unregisthandler = new UnRegistHandler("unregist"));
|
||||
Engine::install(m_unregisthandler = new UnRegistHandler("user.unregister"));
|
||||
}
|
||||
if (!m_authhandler) {
|
||||
Output("Installing Authentification handler");
|
||||
Engine::install(m_authhandler = new AuthHandler("auth"));
|
||||
Engine::install(m_authhandler = new AuthHandler("user.auth"));
|
||||
}
|
||||
if (!m_routehandler) {
|
||||
Output("Installing Route handler");
|
||||
Engine::install(m_routehandler = new RouteHandler("route"));
|
||||
Engine::install(m_routehandler = new RouteHandler("call.route"));
|
||||
}
|
||||
if (!m_statushandler) {
|
||||
Output("Installing Status handler");
|
||||
Engine::install(m_statushandler = new StatusHandler("status"));
|
||||
Engine::install(m_statushandler = new StatusHandler("engine.status"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ void Connection::processLine(const char *line)
|
|||
|
||||
if (str.startSkip("status"))
|
||||
{
|
||||
Message m("status");
|
||||
Message m("engine.status");
|
||||
if (!str.null()) {
|
||||
m.addParam("module",str);
|
||||
str = ":" + str;
|
||||
|
@ -250,7 +250,7 @@ void Connection::processLine(const char *line)
|
|||
write(m_machine ? "%%=drop:fail=noarg\n" : "You must specify what connection to drop!\n");
|
||||
return;
|
||||
}
|
||||
Message m("drop");
|
||||
Message m("call.drop");
|
||||
bool all = false;
|
||||
if (str == "*" || str == "all") {
|
||||
all = true;
|
||||
|
@ -273,7 +273,7 @@ void Connection::processLine(const char *line)
|
|||
write(m_machine ? "%%=call:fail=noarg\n" : "You must specify source and target!\n");
|
||||
return;
|
||||
}
|
||||
Message m("call");
|
||||
Message m("call.execute");
|
||||
m.addParam("callto",str.substr(0,pos));
|
||||
m.addParam("target",str.substr(pos+1));
|
||||
|
||||
|
@ -328,7 +328,7 @@ void Connection::processLine(const char *line)
|
|||
}
|
||||
else if (str.startSkip("help") || str.startSkip("?"))
|
||||
{
|
||||
Message m("help");
|
||||
Message m("engine.help");
|
||||
if (!str.null())
|
||||
{
|
||||
m.addParam("line",str);
|
||||
|
@ -346,7 +346,7 @@ void Connection::processLine(const char *line)
|
|||
}
|
||||
else
|
||||
{
|
||||
Message m("command");
|
||||
Message m("engine.command");
|
||||
m.addParam("line",str);
|
||||
if (Engine::dispatch(m))
|
||||
write(m.retValue());
|
||||
|
|
|
@ -63,7 +63,7 @@ class ToneChan : public DataEndpoint
|
|||
public:
|
||||
ToneChan(const String &tone);
|
||||
~ToneChan();
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
inline const String &id() const
|
||||
{ return m_id; }
|
||||
private:
|
||||
|
@ -74,21 +74,21 @@ private:
|
|||
class ToneHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
ToneHandler(const char *name) : MessageHandler(name) { }
|
||||
ToneHandler() : MessageHandler("call.execute") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class AttachHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
AttachHandler() : MessageHandler("attach") { }
|
||||
AttachHandler() : MessageHandler("chan.attach") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class StatusHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
StatusHandler() : MessageHandler("status") { }
|
||||
StatusHandler() : MessageHandler("engine.status") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
@ -263,7 +263,7 @@ ToneChan::~ToneChan()
|
|||
mutex.unlock();
|
||||
}
|
||||
|
||||
void ToneChan::disconnected(const char *reason)
|
||||
void ToneChan::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debugger debug("ToneChan::disconnected()"," '%s' [%p]",reason,this);
|
||||
}
|
||||
|
@ -293,14 +293,14 @@ bool ToneHandler::received(Message &msg)
|
|||
Debug(DebugWarn,"Tone outgoing call with no target!");
|
||||
return false;
|
||||
}
|
||||
Message m("preroute");
|
||||
Message m("call.preroute");
|
||||
m.addParam("id",dest);
|
||||
m.addParam("caller",dest);
|
||||
m.addParam("called",targ);
|
||||
Engine::dispatch(m);
|
||||
m = "route";
|
||||
m = "call.route";
|
||||
if (Engine::dispatch(m)) {
|
||||
m = "call";
|
||||
m = "call.execute";
|
||||
m.addParam("callto",m.retValue());
|
||||
m.retValue() = 0;
|
||||
ToneChan *tc = new ToneChan(dest.matchString(1).c_str());
|
||||
|
@ -382,7 +382,7 @@ void ToneGenPlugin::initialize()
|
|||
{
|
||||
Output("Initializing module ToneGen");
|
||||
if (!m_handler) {
|
||||
m_handler = new ToneHandler("call");
|
||||
m_handler = new ToneHandler;
|
||||
Engine::install(m_handler);
|
||||
Engine::install(new AttachHandler);
|
||||
Engine::install(new StatusHandler);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -45,6 +46,8 @@ public:
|
|||
inline void setNotify(const String& id)
|
||||
{ m_id = id; }
|
||||
private:
|
||||
void detectAuFormat();
|
||||
void detectWavFormat();
|
||||
DataEndpoint *m_chan;
|
||||
DataBlock m_data;
|
||||
int m_fd;
|
||||
|
@ -77,7 +80,7 @@ class WaveChan : public DataEndpoint
|
|||
public:
|
||||
WaveChan(const String& file, bool record, unsigned maxlen = 0);
|
||||
~WaveChan();
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
inline const String &id() const
|
||||
{ return m_id; }
|
||||
private:
|
||||
|
@ -99,14 +102,14 @@ private:
|
|||
class WaveHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
WaveHandler(const char *name) : MessageHandler(name) { }
|
||||
WaveHandler() : MessageHandler("call.execute") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class AttachHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
AttachHandler() : MessageHandler("attach") { }
|
||||
AttachHandler() : MessageHandler("chan.attach") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
@ -123,24 +126,32 @@ WaveSource::WaveSource(const String& file, DataEndpoint *chan, bool autoclose)
|
|||
: m_chan(chan), m_fd(-1), m_brate(16000), m_total(0), m_time(0), m_autoclose(autoclose)
|
||||
{
|
||||
Debug(DebugAll,"WaveSource::WaveSource(\"%s\",%p) [%p]",file.c_str(),chan,this);
|
||||
m_fd = ::open(file.safe(),O_RDONLY|O_NOCTTY);
|
||||
if (m_fd < 0) {
|
||||
Debug(DebugGoOn,"Opening '%s': error %d: %s",
|
||||
file.c_str(), errno, ::strerror(errno));
|
||||
m_format = "";
|
||||
return;
|
||||
}
|
||||
if (file.endsWith(".gsm")) {
|
||||
m_format = "gsm";
|
||||
m_brate = 1650;
|
||||
}
|
||||
else if (file.endsWith(".alaw")) {
|
||||
else if (file.endsWith(".alaw") || file.endsWith(".A")) {
|
||||
m_format = "alaw";
|
||||
m_brate = 8000;
|
||||
}
|
||||
else if (file.endsWith(".mulaw")) {
|
||||
else if (file.endsWith(".mulaw") || file.endsWith(".u")) {
|
||||
m_format = "mulaw";
|
||||
m_brate = 8000;
|
||||
}
|
||||
m_fd = ::open(file.safe(),O_RDONLY|O_NOCTTY);
|
||||
if (m_fd >= 0)
|
||||
start("WaveSource");
|
||||
else
|
||||
Debug(DebugGoOn,"Opening '%s': error %d: %s",
|
||||
file.c_str(), errno, ::strerror(errno));
|
||||
else if (file.endsWith(".au"))
|
||||
detectAuFormat();
|
||||
else if (file.endsWith(".wav"))
|
||||
detectWavFormat();
|
||||
else if (!file.endsWith(".slin"))
|
||||
Debug(DebugMild,"Unknown format for file '%s', assuming signed linear",file.c_str());
|
||||
start("WaveSource");
|
||||
}
|
||||
|
||||
WaveSource::~WaveSource()
|
||||
|
@ -159,6 +170,50 @@ WaveSource::~WaveSource()
|
|||
}
|
||||
}
|
||||
|
||||
void WaveSource::detectAuFormat()
|
||||
{
|
||||
struct {
|
||||
uint32_t sign;
|
||||
uint32_t offs;
|
||||
uint32_t len;
|
||||
uint32_t form;
|
||||
uint32_t freq;
|
||||
uint32_t chan;
|
||||
} header;
|
||||
if ((::read(m_fd,&header,sizeof(header)) != sizeof(header)) ||
|
||||
(ntohl(header.sign) != 0x2E736E64)) {
|
||||
Debug(DebugMild,"Invalid .au file header, assuming raw signed linear");
|
||||
::lseek(m_fd,0,SEEK_SET);
|
||||
return;
|
||||
}
|
||||
::lseek(m_fd,ntohl(header.offs),SEEK_SET);
|
||||
int samp = ntohl(header.freq);
|
||||
int chan = ntohl(header.chan);
|
||||
m_brate = samp;
|
||||
switch (ntohl(header.form)) {
|
||||
case 1:
|
||||
m_format = "mulaw";
|
||||
break;
|
||||
case 27:
|
||||
m_format = "alaw";
|
||||
break;
|
||||
case 3:
|
||||
m_brate *= 2;
|
||||
break;
|
||||
default:
|
||||
Debug(DebugMild,"Unknown .au format 0x%0X, assuming signed linear",ntohl(header.form));
|
||||
}
|
||||
if (samp != 8000)
|
||||
m_format = String(samp) + "/" + m_format;
|
||||
if (chan != 1)
|
||||
m_format = String(chan) + "*" + m_format;
|
||||
}
|
||||
|
||||
void WaveSource::detectWavFormat()
|
||||
{
|
||||
Debug(DebugMild,".wav not supported yet, assuming raw signed linear");
|
||||
}
|
||||
|
||||
void WaveSource::run()
|
||||
{
|
||||
m_data.assign(0,(m_brate*20)/1000);
|
||||
|
@ -187,7 +242,7 @@ void WaveSource::run()
|
|||
} while (r > 0);
|
||||
Debug(DebugAll,"WaveSource [%p] end of data [%p] [%s] ",this,m_chan,m_id.c_str());
|
||||
if (m_chan && !m_id.null()) {
|
||||
Message *m = new Message("notify");
|
||||
Message *m = new Message("chan.notify");
|
||||
m->addParam("id",m_id);
|
||||
m->userData(m_chan);
|
||||
Engine::enqueue(m);
|
||||
|
@ -209,9 +264,9 @@ WaveConsumer::WaveConsumer(const String& file, DataEndpoint *chan, unsigned maxl
|
|||
file.c_str(),chan,maxlen,this);
|
||||
if (file.endsWith(".gsm"))
|
||||
m_format = "gsm";
|
||||
else if (file.endsWith(".alaw"))
|
||||
else if (file.endsWith(".alaw") || file.endsWith(".A"))
|
||||
m_format = "alaw";
|
||||
else if (file.endsWith(".mulaw"))
|
||||
else if (file.endsWith(".mulaw") || file.endsWith(".u"))
|
||||
m_format = "mulaw";
|
||||
m_fd = ::creat(file.safe(),S_IRUSR|S_IWUSR);
|
||||
if (m_fd < 0)
|
||||
|
@ -252,7 +307,7 @@ void WaveConsumer::Consume(const DataBlock &data, unsigned long timeDelta)
|
|||
}
|
||||
if (m_chan && !m_id.null()) {
|
||||
m_chan->setConsumer();
|
||||
Message *m = new Message("notify");
|
||||
Message *m = new Message("chan.notify");
|
||||
m->addParam("id",m_id);
|
||||
m->userData(m_chan);
|
||||
Engine::enqueue(m);
|
||||
|
@ -295,7 +350,7 @@ WaveChan::~WaveChan()
|
|||
Debug(DebugAll,"WaveChan::~WaveChan() %s [%p]",m_id.c_str(),this);
|
||||
}
|
||||
|
||||
void WaveChan::disconnected(const char *reason)
|
||||
void WaveChan::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debugger debug("WaveChan::disconnected()"," '%s' [%p]",reason,this);
|
||||
}
|
||||
|
@ -340,14 +395,14 @@ bool WaveHandler::received(Message &msg)
|
|||
Debug(DebugWarn,"Wave outgoing call with no target!");
|
||||
return false;
|
||||
}
|
||||
Message m("preroute");
|
||||
Message m("call.preroute");
|
||||
m.addParam("id",dest);
|
||||
m.addParam("caller",dest);
|
||||
m.addParam("called",targ);
|
||||
Engine::dispatch(m);
|
||||
m = "route";
|
||||
m = "call.route";
|
||||
if (Engine::dispatch(m)) {
|
||||
m = "call";
|
||||
m = "call.execute";
|
||||
m.addParam("callto",m.retValue());
|
||||
m.retValue() = 0;
|
||||
WaveChan *c = new WaveChan(dest.matchString(2),meth,maxlen);
|
||||
|
@ -449,7 +504,7 @@ void WaveFilePlugin::initialize()
|
|||
{
|
||||
Output("Initializing module WaveFile");
|
||||
if (!m_handler) {
|
||||
m_handler = new WaveHandler("call");
|
||||
m_handler = new WaveHandler;
|
||||
Engine::install(m_handler);
|
||||
Engine::install(new AttachHandler);
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ class ZapChan : public DataEndpoint
|
|||
public:
|
||||
ZapChan(PriSpan *parent, int chan, unsigned int bufsize);
|
||||
virtual ~ZapChan();
|
||||
virtual void disconnected(const char *reason);
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
virtual bool nativeConnect(DataEndpoint *peer);
|
||||
inline PriSpan *span() const
|
||||
{ return m_span; }
|
||||
|
@ -394,6 +394,7 @@ public:
|
|||
void ring(q931_call *call = 0);
|
||||
void hangup(int cause = PRI_CAUSE_INVALID_MSG_UNSPECIFIED);
|
||||
void sendDigit(char digit);
|
||||
void gotDigits(const char *digits);
|
||||
bool call(Message &msg, const char *called = 0);
|
||||
bool answer();
|
||||
void answered();
|
||||
|
@ -408,6 +409,10 @@ public:
|
|||
{ return m_fd; }
|
||||
inline int law() const
|
||||
{ return m_law; }
|
||||
const String& id() const
|
||||
{ return m_id; }
|
||||
inline void setTarget(const char *target = 0)
|
||||
{ m_targetid = target; }
|
||||
private:
|
||||
PriSpan *m_span;
|
||||
int m_chan;
|
||||
|
@ -419,6 +424,8 @@ private:
|
|||
int m_fd;
|
||||
int m_law;
|
||||
bool m_isdn;
|
||||
String m_id;
|
||||
String m_targetid;
|
||||
};
|
||||
|
||||
class ZapSource : public ThreadedSource
|
||||
|
@ -464,21 +471,28 @@ private:
|
|||
class ZapHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
ZapHandler(const char *name) : MessageHandler(name) { }
|
||||
ZapHandler() : MessageHandler("call.execute") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class ZapDropper : public MessageHandler
|
||||
{
|
||||
public:
|
||||
ZapDropper(const char *name) : MessageHandler(name) { }
|
||||
ZapDropper() : MessageHandler("call.drop") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class ZapDTMF : public MessageHandler
|
||||
{
|
||||
public:
|
||||
ZapDTMF() : MessageHandler("chan.dtmf") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class StatusHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
StatusHandler() : MessageHandler("status") { }
|
||||
StatusHandler() : MessageHandler("engine.status") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
@ -776,8 +790,9 @@ void PriSpan::ringChan(int chan, pri_event_ring &ev)
|
|||
ev.callednum,ev.redirectingnum,ev.calledplan);
|
||||
Debug(DebugInfo,"type=%d complete=%d format='%s'",
|
||||
ev.ctype,ev.complete,lookup(ev.layer1,dict_str2law,"unknown"));
|
||||
Message *m = new Message("ring");
|
||||
Message *m = new Message("call.preroute");
|
||||
m->addParam("driver","zap");
|
||||
m->addParam("id",getChan(chan)->id());
|
||||
m->addParam("span",String(m_span));
|
||||
m->addParam("channel",String(chan));
|
||||
if (ev.callingnum[0])
|
||||
|
@ -785,11 +800,9 @@ void PriSpan::ringChan(int chan, pri_event_ring &ev)
|
|||
if (ev.callednum[0])
|
||||
m->addParam("called",ev.callednum);
|
||||
Engine::dispatch(m);
|
||||
*m = "preroute";
|
||||
Engine::dispatch(m);
|
||||
*m = "route";
|
||||
*m = "call.route";
|
||||
if (Engine::dispatch(m)) {
|
||||
*m = "call";
|
||||
*m = "call.execute";
|
||||
m->addParam("callto",m->retValue());
|
||||
m->retValue() = 0;
|
||||
int dataLaw = -1;
|
||||
|
@ -803,8 +816,10 @@ void PriSpan::ringChan(int chan, pri_event_ring &ev)
|
|||
}
|
||||
getChan(chan)->open(dataLaw);
|
||||
m->userData(getChan(chan));
|
||||
if (Engine::dispatch(m))
|
||||
if (Engine::dispatch(m)) {
|
||||
getChan(chan)->setTarget(m->getValue("targetid"));
|
||||
getChan(chan)->answer();
|
||||
}
|
||||
else
|
||||
getChan(chan)->hangup(PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
|
||||
}
|
||||
|
@ -824,6 +839,7 @@ void PriSpan::infoChan(int chan, pri_event_ring &ev)
|
|||
ev.callingname,ev.callingnum,ev.callingplan);
|
||||
Debug(DebugInfo,"callednum='%s' redirectnum='%s' calledplan=%d",
|
||||
ev.callednum,ev.redirectingnum,ev.calledplan);
|
||||
getChan(chan)->gotDigits(ev.callednum);
|
||||
}
|
||||
|
||||
void PriSpan::hangupChan(int chan,pri_event_hangup &ev)
|
||||
|
@ -953,6 +969,7 @@ ZapChan::ZapChan(PriSpan *parent, int chan, unsigned int bufsize)
|
|||
// I hate counting from one...
|
||||
m_abschan = m_chan+m_span->chan1()-1;
|
||||
m_isdn = true;
|
||||
m_id << "zap/" << m_abschan;
|
||||
}
|
||||
|
||||
ZapChan::~ZapChan()
|
||||
|
@ -961,9 +978,22 @@ ZapChan::~ZapChan()
|
|||
hangup(PRI_CAUSE_NORMAL_UNSPECIFIED);
|
||||
}
|
||||
|
||||
void ZapChan::disconnected(const char *reason)
|
||||
void ZapChan::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debugger debug("ZapChan::disconnected()", " '%s' [%p]",reason,this);
|
||||
if (!final) {
|
||||
Message m("chan.disconnected");
|
||||
m.addParam("driver","zap");
|
||||
m.addParam("id",id());
|
||||
m.addParam("span",String(m_span->span()));
|
||||
m.addParam("channel",String(m_chan));
|
||||
if (m_targetid) {
|
||||
m.addParam("targetid",m_targetid);
|
||||
setTarget();
|
||||
}
|
||||
m.addParam("reason",reason);
|
||||
Engine::enqueue(m);
|
||||
}
|
||||
// FIXME: we can't know from which thread we got disconnected
|
||||
bool gotLock = zplugin.mutex.lock(1000);
|
||||
hangup(PRI_CAUSE_NORMAL_CLEARING);
|
||||
|
@ -1070,12 +1100,6 @@ bool ZapChan::answer()
|
|||
m_timeout = 0;
|
||||
Output("Answering on zap/%d (%d/%d)",m_abschan,m_span->span(),m_chan);
|
||||
::pri_answer(m_span->pri(),m_call,m_chan,!m_isdn);
|
||||
Message *m = new Message("answer");
|
||||
m->addParam("driver","zap");
|
||||
m->addParam("span",String(m_span->span()));
|
||||
m->addParam("channel",String(m_chan));
|
||||
m->addParam("status","answered");
|
||||
Engine::enqueue(m);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1086,6 +1110,7 @@ void ZapChan::hangup(int cause)
|
|||
Debug(DebugInfo,"Hanging up zap/%d in state %s: %s (%d)",
|
||||
m_abschan,status(),reason,cause);
|
||||
m_timeout = 0;
|
||||
setTarget();
|
||||
disconnect(reason);
|
||||
close();
|
||||
m_ring = false;
|
||||
|
@ -1093,8 +1118,9 @@ void ZapChan::hangup(int cause)
|
|||
::pri_hangup(m_span->pri(),m_call,cause);
|
||||
::pri_destroycall(m_span->pri(),m_call);
|
||||
m_call = 0;
|
||||
Message *m = new Message("hangup");
|
||||
Message *m = new Message("call.hangup");
|
||||
m->addParam("driver","zap");
|
||||
m->addParam("id",id());
|
||||
m->addParam("span",String(m_span->span()));
|
||||
m->addParam("channel",String(m_chan));
|
||||
m->addParam("reason",pri_cause2str(cause));
|
||||
|
@ -1111,14 +1137,30 @@ void ZapChan::answered()
|
|||
}
|
||||
m_timeout = 0;
|
||||
Output("Remote answered on zap/%d (%d/%d)",m_abschan,m_span->span(),m_chan);
|
||||
Message *m = new Message("answer");
|
||||
Message *m = new Message("call.answered");
|
||||
m->addParam("driver","zap");
|
||||
m->addParam("id",id());
|
||||
m->addParam("span",String(m_span->span()));
|
||||
m->addParam("channel",String(m_chan));
|
||||
if (m_targetid)
|
||||
m->addParam("targetid",m_targetid);
|
||||
m->addParam("status","answered");
|
||||
Engine::enqueue(m);
|
||||
}
|
||||
|
||||
void ZapChan::gotDigits(const char *digits)
|
||||
{
|
||||
Message *m = new Message("chan.dtmf");
|
||||
m->addParam("driver","zap");
|
||||
m->addParam("id",id());
|
||||
m->addParam("span",String(m_span->span()));
|
||||
m->addParam("channel",String(m_chan));
|
||||
if (m_targetid)
|
||||
m->addParam("targetid",m_targetid);
|
||||
m->addParam("text",digits);
|
||||
Engine::enqueue(m);
|
||||
}
|
||||
|
||||
void ZapChan::sendDigit(char digit)
|
||||
{
|
||||
if (m_call)
|
||||
|
@ -1158,6 +1200,7 @@ bool ZapChan::call(Message &msg, const char *called)
|
|||
break;
|
||||
}
|
||||
connect(dd);
|
||||
msg.addParam("targetid",id());
|
||||
}
|
||||
else
|
||||
msg.userData(this);
|
||||
|
@ -1272,6 +1315,28 @@ bool ZapDropper::received(Message &msg)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ZapDTMF::received(Message &msg)
|
||||
{
|
||||
String id(msg.getValue("targetid"));
|
||||
if (!id.startsWith("zap/"))
|
||||
return false;
|
||||
String text(msg.getValue("text"));
|
||||
ZapChan *c = 0;
|
||||
id >> "zap/";
|
||||
int n = id.toInteger();
|
||||
if ((n > 0) && (c = zplugin.findChan(n))) {
|
||||
Debug("ZapDTMF",DebugInfo,"Sending to zap/%d (%d/%d)",
|
||||
n,c->span()->span(),c->chan());
|
||||
zplugin.mutex.lock();
|
||||
for (unsigned int i = 0; i < text.length(); i++)
|
||||
c->sendDigit(text[i]);
|
||||
zplugin.mutex.unlock();
|
||||
return true;
|
||||
}
|
||||
Debug("ZapDTMF",DebugInfo,"Could not find zap/%s",id.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StatusHandler::received(Message &msg)
|
||||
{
|
||||
const char *sel = msg.getValue("module");
|
||||
|
@ -1305,7 +1370,7 @@ bool StatusHandler::received(Message &msg)
|
|||
first = false;
|
||||
else
|
||||
st << ",";
|
||||
st << "zap/" << c->absChan() << "=";
|
||||
st << c->id() << "=";
|
||||
st << s->span() << "|" << n << "|" << c->status();
|
||||
}
|
||||
}
|
||||
|
@ -1426,8 +1491,9 @@ void ZaptelPlugin::initialize()
|
|||
}
|
||||
if (m_spans.count()) {
|
||||
Output("Created %d spans",m_spans.count());
|
||||
Engine::install(new ZapHandler("call"));
|
||||
Engine::install(new ZapDropper("drop"));
|
||||
Engine::install(new ZapHandler);
|
||||
Engine::install(new ZapDropper);
|
||||
Engine::install(new ZapDTMF);
|
||||
Engine::install(new StatusHandler);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -16,7 +16,7 @@ sub OnNotify($) {
|
|||
}
|
||||
|
||||
my $message = new YateMessage();
|
||||
$message->install("dtmf",\&OnDTMF,10);
|
||||
$message->install("notify",\&OnNotify);
|
||||
$message->install("chan.dtmf",\&OnDTMF,10);
|
||||
$message->install("chan.notify",\&OnNotify);
|
||||
|
||||
$message->listen();
|
||||
|
|
|
@ -29,5 +29,5 @@ sub demo2($) {
|
|||
|
||||
my $message = new YateMessage();
|
||||
$message->install("engine.timer",\&demo);
|
||||
$message->install("route",\&demo2);
|
||||
$message->install("call.route",\&demo2);
|
||||
$message->listen();
|
||||
|
|
|
@ -13,8 +13,8 @@ Yate::Init();
|
|||
|
||||
/* Install a handler for the engine generated timer message */
|
||||
//Yate::Install("engine.timer",10);
|
||||
Yate::Install("dtmf",10);
|
||||
Yate::Install("sms",10);
|
||||
Yate::Install("chan.dtmf",10);
|
||||
Yate::Install("chan.text",10);
|
||||
|
||||
/* Create and dispatch an initial test message */
|
||||
/*$m=new Yate("test");
|
||||
|
@ -49,7 +49,7 @@ for (;;) {
|
|||
$ev->handled = true;
|
||||
/* This is extremely important.
|
||||
We MUST let messages return, handled or not */
|
||||
$m=new Yate("sms");
|
||||
$m=new Yate("chan.text");
|
||||
$m->params["ourcallid"]= $ev->params["partycallid"];
|
||||
$m->params["partycallid"]= $ev->params["ourcallid"];
|
||||
$m->params["text"] = $ev->params["text"];
|
||||
|
|
|
@ -1197,6 +1197,13 @@ public:
|
|||
inline unsigned int length() const
|
||||
{ return m_params.length(); }
|
||||
|
||||
/**
|
||||
* Get the number of non-null parameters
|
||||
* @return Count of existing named strings
|
||||
*/
|
||||
inline unsigned int count() const
|
||||
{ return m_params.count(); }
|
||||
|
||||
/**
|
||||
* Add a named string to the parameter list.
|
||||
* @param param Parameter to add
|
||||
|
|
|
@ -411,7 +411,8 @@ public:
|
|||
* Disconnect from the connected endpoint
|
||||
* @param reason Text that describes disconnect reason
|
||||
*/
|
||||
void disconnect(const char *reason = 0);
|
||||
inline void disconnect(const char *reason = 0)
|
||||
{ disconnect(false,reason); }
|
||||
|
||||
/**
|
||||
* Set the data source of this object
|
||||
|
@ -461,9 +462,10 @@ protected:
|
|||
|
||||
/**
|
||||
* Disconnect notification method
|
||||
* @param final True if this disconnect was called from the destructor
|
||||
* @param reason Text that describes disconnect reason
|
||||
*/
|
||||
virtual void disconnected(const char *reason) { }
|
||||
virtual void disconnected(bool final, const char *reason) { }
|
||||
|
||||
/**
|
||||
* Attempt to connect the endpoint to a peer of the same type
|
||||
|
@ -481,6 +483,7 @@ protected:
|
|||
void setPeer(DataEndpoint *peer, const char *reason = 0);
|
||||
|
||||
private:
|
||||
void disconnect(bool final, const char *reason);
|
||||
String m_name;
|
||||
DataSource *m_source;
|
||||
DataConsumer *m_consumer;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* yateversn.h
|
||||
* This file is part of the YATE Project http://YATE.null.ro
|
||||
*
|
||||
* This is a generated file. You should never need to modify it.
|
||||
*/
|
||||
|
||||
#ifndef __YATEVERSN_H
|
||||
#define __YATEVERSN_H
|
||||
|
||||
#define YATE_MAJOR @PACKAGE_VERSION_MAJOR@
|
||||
#define YATE_MINOR @PACKAGE_VERSION_MINOR@
|
||||
#define YATE_BUILD @PACKAGE_VERSION_BUILD@
|
||||
|
||||
#endif /* __YATEVERSN_H */
|
Loading…
Reference in New Issue