140 lines
3.3 KiB
C++
140 lines
3.3 KiB
C++
|
/**
|
||
|
* regexroute.cpp
|
||
|
*
|
||
|
* This file is part of the YATE Project http://YATE.null.ro
|
||
|
* Regexp based routing
|
||
|
*/
|
||
|
|
||
|
#include <telengine.h>
|
||
|
#include <telephony.h>
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
using namespace TelEngine;
|
||
|
|
||
|
static Configuration s_cfg;
|
||
|
|
||
|
class RouteHandler : public MessageHandler
|
||
|
{
|
||
|
public:
|
||
|
RouteHandler(int prio)
|
||
|
: MessageHandler("route",prio) { }
|
||
|
virtual bool received(Message &msg);
|
||
|
};
|
||
|
|
||
|
bool RouteHandler::received(Message &msg)
|
||
|
{
|
||
|
unsigned long long tmr = Time::now();
|
||
|
String s(msg.getValue("called"));
|
||
|
if (s.null())
|
||
|
return false;
|
||
|
const char *context = msg.getValue("context","default");
|
||
|
NamedList *l = s_cfg.getSection(context);
|
||
|
if (l) {
|
||
|
unsigned int len = l->length();
|
||
|
for (unsigned int i=0; i<len; i++) {
|
||
|
NamedString *n = l->getParam(i);
|
||
|
if (n) {
|
||
|
Regexp r(n->name());
|
||
|
if (s.matches(r)) {
|
||
|
msg.retValue() = s.replaceMatches(*n);
|
||
|
Debug(DebugInfo,"Routing call to '%s' in context '%s' via `%s' by rule #%u '%s' in %llu usec",
|
||
|
s.c_str(),context,msg.retValue().c_str(),i+1,r.c_str(),Time::now()-tmr);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Debug(DebugInfo,"Could not route call to '%s' in context '%s', wasted %llu usec",
|
||
|
s.c_str(),context,Time::now()-tmr);
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
class PrerouteHandler : public MessageHandler
|
||
|
{
|
||
|
public:
|
||
|
PrerouteHandler(int prio)
|
||
|
: MessageHandler("preroute",prio) { }
|
||
|
virtual bool received(Message &msg);
|
||
|
};
|
||
|
|
||
|
bool PrerouteHandler::received(Message &msg)
|
||
|
{
|
||
|
unsigned long long tmr = Time::now();
|
||
|
// return immediately if there is already a context
|
||
|
if (msg.getValue("context"))
|
||
|
return false;
|
||
|
// String s(msg.getValue("caller"));
|
||
|
String s(msg.getValue("driver")); s+="/";
|
||
|
s+=msg.getValue("span"); s+="/";
|
||
|
s+=msg.getValue("channel"); s+="/";
|
||
|
s+=msg.getValue("caller");
|
||
|
|
||
|
if (s.null())
|
||
|
return false;
|
||
|
NamedList *l = s_cfg.getSection("contexts");
|
||
|
if (l) {
|
||
|
unsigned int len = l->length();
|
||
|
for (unsigned int i=0; i<len; i++) {
|
||
|
NamedString *n = l->getParam(i);
|
||
|
if (n) {
|
||
|
Regexp r(n->name());
|
||
|
if (s.matches(r)) {
|
||
|
msg.addParam("context",s.replaceMatches(*n));
|
||
|
Debug(DebugInfo,"Classifying caller '%s' in context '%s' by rule #%u '%s' in %llu usec",
|
||
|
s.c_str(),msg.getValue("context"),i+1,r.c_str(),Time::now()-tmr);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Debug(DebugInfo,"Could not classify call from '%s', wasted %llu usec",
|
||
|
s.c_str(),Time::now()-tmr);
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
|
||
|
class RegexRoutePlugin : public Plugin
|
||
|
{
|
||
|
public:
|
||
|
RegexRoutePlugin();
|
||
|
virtual void initialize();
|
||
|
private:
|
||
|
MessageHandler *m_preroute, *m_route;
|
||
|
};
|
||
|
|
||
|
RegexRoutePlugin::RegexRoutePlugin()
|
||
|
: m_preroute(0), m_route(0)
|
||
|
{
|
||
|
Output("Loaded module RegexRoute");
|
||
|
}
|
||
|
|
||
|
void RegexRoutePlugin::initialize()
|
||
|
{
|
||
|
Output("Initializing module RegexRoute");
|
||
|
s_cfg = Engine::configFile("regexroute");
|
||
|
s_cfg.load();
|
||
|
if (m_preroute) {
|
||
|
delete m_preroute;
|
||
|
m_preroute = 0;
|
||
|
}
|
||
|
if (m_route) {
|
||
|
delete m_route;
|
||
|
m_route = 0;
|
||
|
}
|
||
|
unsigned priority = s_cfg.getIntValue("priorities","preroute",100);
|
||
|
if (priority) {
|
||
|
m_preroute = new PrerouteHandler(priority);
|
||
|
Engine::install(m_preroute);
|
||
|
}
|
||
|
priority = s_cfg.getIntValue("priorities","route",100);
|
||
|
if (priority) {
|
||
|
m_route = new RouteHandler(priority);
|
||
|
Engine::install(m_route);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INIT_PLUGIN(RegexRoutePlugin);
|
||
|
|
||
|
/* vi: set ts=8 sw=4 sts=4 noet: */
|