Added option to execute call diversion requested by a signalling protocol.

git-svn-id: http://voip.null.ro/svn/yate@2552 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2009-03-29 21:14:37 +00:00
parent 535a559422
commit 56a35abc3e
2 changed files with 60 additions and 39 deletions

View File

@ -22,6 +22,9 @@
; dialheld: bool: Dial back from held calls if the control call leg hangs up ; dialheld: bool: Dial back from held calls if the control call leg hangs up
;dialheld=no ;dialheld=no
; diversion: bool: Honor protocol requested diversion of calls
;diversion=no
; minlen: int: Minimum length of command sequences ; minlen: int: Minimum length of command sequences
;minlen=2 ;minlen=2

View File

@ -107,6 +107,9 @@ static bool s_pass = false;
// redial from calls that are left on hold or drop them? // redial from calls that are left on hold or drop them?
static bool s_dialHeld = false; static bool s_dialHeld = false;
// allow diversion requested through protocol
static bool s_divProto = false;
// interdigit timeout, clear collected digits if last was older than this // interdigit timeout, clear collected digits if last was older than this
static unsigned int s_timeout = 30000000; static unsigned int s_timeout = 30000000;
@ -196,6 +199,7 @@ void PBXList::initialize()
s_filter = s_cfg.getValue("general","filter"); s_filter = s_cfg.getValue("general","filter");
s_pass = s_cfg.getBoolValue("general","dtmfpass",false); s_pass = s_cfg.getBoolValue("general","dtmfpass",false);
s_dialHeld = s_cfg.getBoolValue("general","dialheld",false); s_dialHeld = s_cfg.getBoolValue("general","dialheld",false);
s_divProto = s_cfg.getBoolValue("general","diversion",false);
s_minlen = s_cfg.getIntValue("general","minlen",2); s_minlen = s_cfg.getIntValue("general","minlen",2);
if (s_minlen < 1) if (s_minlen < 1)
s_minlen = 1; s_minlen = 1;
@ -313,46 +317,60 @@ bool PBXAssist::msgDisconnect(Message& msg, const String& reason)
id().c_str(),transfer.c_str()); id().c_str(),transfer.c_str());
} }
if (reason) { String divertReason = reason;
// we have a reason, see if we should divert the call String called;
String called = m_keep.getValue("divert_"+reason); bool proto = s_divProto && msg.getBoolValue("redirect");
if (called && (called != m_keep.getValue("called"))) { if (proto) {
Message* m = new Message("call.preroute"); // protocol requested redirect or diversion
m->addParam("id",id()); divertReason = msg.getValue("divert_reason");
m->addParam("reason",reason); called = msg.getValue("called");
m->addParam("pbxstate",state()); }
m->copyParam(m_keep,"billid"); else if (reason) {
m->copyParam(m_keep,"caller"); // we have a disconnect reason, see if we should divert the call
copyParams(*m,msg,&m_keep); called = m_keep.getValue("divert_"+reason);
if (isE164(called)) { }
// divert target is a number so we have to route it if (called && (called != m_keep.getValue("called"))) {
m->addParam("called",called); Message* m = new Message("call.preroute");
Engine::dispatch(m); m->addParam("id",id());
*m = "call.route"; m->addParam("reason",divertReason);
if (!Engine::dispatch(m) || m->retValue().null() || (m->retValue() == "-") || (m->retValue() == "error")) { m->addParam("pbxstate",state());
// routing failed m->copyParam(m_keep,"billid");
TelEngine::destruct(m); m->copyParam(m_keep,"caller");
return errorBeep("no route"); if (proto) {
} m->copyParam(msg,"diverter");
called = m->retValue(); m->addParam("divert_reason",divertReason);
m->retValue().clear(); m->copyParam(msg,"divert_privacy");
m->msgTime() = Time::now(); m->copyParam(msg,"divert_screen");
}
else {
// diverting to resource, add old called for reference
m->copyParam(m_keep,"called");
}
Debug(list(),DebugCall,"Chan '%s' divert on '%s' to '%s'",
id().c_str(),reason.c_str(),called.c_str());
*m = "chan.masquerade";
m->setParam("id",id());
m->setParam("message","call.execute");
m->setParam("callto",called);
m->setParam("reason","divert_"+reason);
m->userData(msg.userData());
Engine::enqueue(m);
return true;
} }
copyParams(*m,msg,&m_keep);
if (isE164(called)) {
// divert target is a number so we have to route it
m->addParam("called",called);
Engine::dispatch(m);
*m = "call.route";
if (!Engine::dispatch(m) || m->retValue().null() || (m->retValue() == "-") || (m->retValue() == "error")) {
// routing failed
TelEngine::destruct(m);
return errorBeep("no route");
}
called = m->retValue();
m->retValue().clear();
m->msgTime() = Time::now();
}
else {
// diverting to resource, add old called for reference
m->copyParam(m_keep,"called");
}
Debug(list(),DebugCall,"Chan '%s' divert on '%s' to '%s'",
id().c_str(),divertReason.c_str(),called.c_str());
*m = "chan.masquerade";
m->setParam("id",id());
m->setParam("message","call.execute");
m->setParam("callto",called);
m->setParam("reason","divert_"+divertReason);
m->userData(msg.userData());
Engine::enqueue(m);
return true;
} }
if (!m_guest && (state() != "new")) { if (!m_guest && (state() != "new")) {