diff --git a/conf.d/lateroute.conf.sample b/conf.d/lateroute.conf.sample new file mode 100644 index 00000000..9668d478 --- /dev/null +++ b/conf.d/lateroute.conf.sample @@ -0,0 +1,14 @@ +[general] +; Global settings of the late routing module + +; enabled: boolean: Enable late routing module operation +;enabled=true if regexp and called are set, false if any is empty + +; priority: int: Priority of call.execute handler +;priority=75 + +; regexp: string: Regular expression describing callto match rules +;regexp= + +; called: string: Template for creating calling number from regexp match +;called=\0 diff --git a/modules/Makefile.in b/modules/Makefile.in index 7d935d22..aca9e8c8 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -30,7 +30,7 @@ PROGS := cdrbuild.yate cdrfile.yate regexroute.yate \ ysipchan.yate \ yiaxchan.yate \ yjinglechan.yate \ - server/pbxassist.yate server/dbpbx.yate \ + server/pbxassist.yate server/dbpbx.yate server/lateroute.yate \ server/park.yate server/queues.yate \ server/regfile.yate server/accfile.yate server/register.yate \ server/yradius.yate \ diff --git a/modules/server/lateroute.cpp b/modules/server/lateroute.cpp new file mode 100644 index 00000000..c4aa8a0f --- /dev/null +++ b/modules/server/lateroute.cpp @@ -0,0 +1,134 @@ +/** + * lateroute.cpp + * This file is part of the YATE Project http://YATE.null.ro + * + * Last chance routing in call.execute messages. + * + * Yet Another Telephony Engine - a fully featured software PBX and IVR + * Copyright (C) 2004-2006 Null Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +using namespace TelEngine; +namespace { // anonymous + +class LateRouter : public Plugin +{ +public: + LateRouter(); + ~LateRouter(); + virtual void initialize(); +}; + +class LateHandler : public MessageHandler +{ +public: + inline LateHandler(unsigned priority) + : MessageHandler("call.execute",priority) + { } + virtual bool received(Message& msg); +}; + +static Regexp s_regexp; +static String s_called; +static Mutex s_mutex; +static LateHandler* s_handler = 0; + +INIT_PLUGIN(LateRouter); + +UNLOAD_PLUGIN(unloadNow) +{ + if (unloadNow) { + if (!s_mutex.lock(500000)) + return false; + TelEngine::destruct(s_handler); + s_mutex.unlock(); + } + return true; +} + +bool LateHandler::received(Message& msg) +{ + String dest = msg.getValue("callto"); + if (dest.null() || !msg.getBoolValue("lateroute",true)) + return false; + Lock lock(s_mutex); + if (s_called.null() || !dest.matches(s_regexp)) + return false; + String callto = dest; + dest = dest.replaceMatches(s_called); + msg.replaceParams(dest); + if (dest.trimBlanks().null()) + return false; + + String called = msg.getValue("called"); + msg.clearParam("callto"); + msg.setParam("called",dest); + msg.setParam("lateroute",String::boolText(false)); + msg = "call.route"; + bool ok = Engine::dispatch(msg); + dest = msg.retValue(); + msg.retValue().clear(); + msg = "call.execute"; + ok = ok && dest && (dest != "-") && (dest != "error"); + if (ok && (dest == callto)) { + Debug(DebugMild,"Call to '%s' late routed back to itself!",callto.c_str()); + ok = false; + } + if (!ok) { + // restore most of what we changed and let it pass through + msg.setParam("called",called); + msg.setParam("callto",callto); + msg.clearParam("lateroute"); + return false; + } + Debug(DebugInfo,"Late routing call to '%s' via '%s'",callto.c_str(),dest.c_str()); + // let it pass through to the new target + msg.setParam("callto",dest); + return false; +} + + +LateRouter::LateRouter() + : Plugin("lateroute") +{ + Output("Loaded module Late Router"); +} + +LateRouter::~LateRouter() +{ + Output("Unloading module Late Router"); +} + +void LateRouter::initialize() +{ + Output("Initializing module Late Router"); + Configuration cfg(Engine::configFile("lateroute")); + s_mutex.lock(); + s_regexp = cfg.getValue("general","regexp"); + s_called = cfg.getValue("general","called","\\0"); + s_mutex.unlock(); + if (!s_handler && cfg.getBoolValue("general","enabled",(s_regexp && s_called))) { + s_handler = new LateHandler(cfg.getIntValue("general","priority",75)); + Engine::install(s_handler); + } +} + +}; // anonymous namespace + +/* vi: set ts=8 sw=4 sts=4 noet: */ diff --git a/windows/_lateroute.vcproj b/windows/_lateroute.vcproj new file mode 100644 index 00000000..bf2b8030 --- /dev/null +++ b/windows/_lateroute.vcproj @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +