Greetings,% username%!
Today I would like to share a solution that allows you to teach your Asterisk to automatically route calls to the appropriate destinations without resorting to cumbersome regular expressions.

')
Practice shows that more and more companies are starting to think about their communication expenses. The lion's share of expenses is calls to mobile numbers. Hence, the task was born to process outgoing calls and send through the line where the call will be made free of charge or at the lowest cost.
In my case, it was necessary to marshutize calls to the home region of the Big Three operators through the corresponding SIM cards inserted into the GSM gateway. Instead of the selected operators, you can use any other directions by analogy with the subject.
OpenVox VoxStack VS-GW1202-4G acted as a gateway, in which SIM cards of operators known to you were inserted in advance and 3 trunks to Asterisk were configured.
Of course, there are a lot of ways to solve the problem, but I would like to dwell on a solution that I found optimal: automatic reconciliation of numbers from the MySQL database and further redirection to the desired line. The implementation is quite simple, although in some places it may seem clumsy.
You can break all the work into several stages:
- Create and populate database
- Prepare Asterisk to work with the database
- Write a dialplan to handle outgoing calls
Base preparation
First you need to create a separate database (optional):
CREATE DATABASE telcodes;
Route access in our situation is better not to give, because there is no need for this, and no one needs a security hole in the form of a root login and password to MySQL in the open form in the configuration file. Therefore, we give access to an arbitrary user only to our database (in my case, the user: “mobile”, password: “heavypass”)
CREATE DATABASE telcodes; GRANT ALL ON telcodes.* TO mobile@localhost IDENTIFIED BY 'mobile'; FLUSH PRIVILEGES; SET PASSWORD FOR 'mobile'@'localhost'=PASSWORD('heavypass');
Create a table:
Hidden text CREATE TABLE telcodes ( code smallint(3) NOT NULL, begin int(11) NOT NULL, end int(11) NOT NULL, ammount int (11) NOT NULL, operator varchar(100) NOT NULL, region varchar(100) NOT NULL) DEFAULT CHARSET=utf8;
And now you can go directly to the filling. Everyone is free to choose for himself the way, I will focus on the following:
wget http://www.rossvyaz.ru/docs/articles/Kody_DEF-9kh.csv cat Kody_DEF-9kh.csv | iconv -f pt154 -t utf8 >> telcodes.csv mysqlimport -umobile -p telcodes /usr/src/telcodes.csv --fields-terminated-by=';' --lines-terminated-by="\r\n"
We download the list of codes of mobile operators from the Rossvyaz website, convert the encoding and fill it in our database. The path to the file is optional.
The base is full, but in order to avoid problems with encodings, we will make small changes: I need to select the numbers of the big three for calls in my home region, then I only change them, I mark the region as
home , and change the names to
beeline ,
mts and
megafon, respectively:
UPDATE telcodes set region = 'home',operator = 'beeline' where operator = '-' and region = ' '; UPDATE telcodes set region = 'home',operator = 'mts' where operator = ' ' and region = ' '; UPDATE telcodes set region = 'home',operator = 'megafon' where operator = '' and region = ' ';
Database is ready to use.
Asterisk preparation
We will connect Asterisk with the database using ODBC, since I think this is a unified solution. First you need to rebuild Asterisk with ODBC support. Ubuntu Server 12.04 acts as an OS in my case.
Install unixodbc, unixodbc-dev and libmyodbc packages
apt-get install unixodbc unixodbc-dev libmyodbc
In the Asterisk source directory we run:
./configure && make menuselect
We check that the
res_odbc module is available and enabled, in the functions we need to check the availability of
func_odbc . Then we save and execute:
make && make install
We look where drivers for ODBC lie
Hidden text /. /usr /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/odbc /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so
We look where there are configuration files for ODBC
Hidden text unixODBC 2.2.14 DRIVERS............: /etc/odbcinst.ini SYSTEM DATA SOURCES: /etc/odbc.ini FILE DATA SOURCES..: /etc/ODBCDataSources USER DATA SOURCES..: /root/.odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8
Edit /etc/odbcinst.ini , add an entry to the file:
Hidden text [MySQL] Description = MySQL driver Driver = /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so
Describe the connection to the database in the
/etc/odbc.ini fileHidden text [telcodes-mysql] Driver = MySQL Description = MySQL telcodes via ODBC Server = localhost
And now Asterisk is directly acquainted with MySQL using ODBC. Making changes to
/etc/asterisk/res_odbc.iniHidden text [telcodes] enabled => yes dsn => telcodes-mysql username => mobile password => heavypass pooling => no limit => 1 pre-connect => yes
and write the module load in
/etc/asterisk/modules.conf preload => res_odbc.so
Now you can restart Asterisk itself, or just load the
res_odbc.so module. Then in the CLI we execute the command:
odbc show all
Hidden textaster * CLI> odbc show all
ODBC DSN Settings
- Name: telcodes
DSN: telcodes-mysql
Last connection attempt: 1970-01-01 03:00:00
Pooled: No
Connected: Yes
At this point, the second stage can be considered complete, we created and populated the database and made friends with Asterisk.
Writing a dialplan
Well, now you can proceed directly to writing a dialplan to handle outgoing calls.
Each dialed number is processed by a macro, as a result of which the line through which the call will be made will be determined. The argument to be passed to the macro will be the number to be dialed. The first character (8) will be cut off before it gets into the macro, then in the SQL query we will select further first 3 characters (123) for comparison with the operator code and the remaining 7 characters (4567890) to determine belonging to one or another numbering capacity.
All work with the database is
written in the configuration file
func_odbc.conf . Here we invent and compose functions for interacting with the database, and then use their result in the dialplan. Each section describes its function, the name of each section is usually filled in upper case.
In my case, it is necessary to determine the belonging of the number to the region and the operator and transfer the result for further processing by the macro.
Add to
/etc/asterisk/func_odbc.conf entry
[MOBILE] dsn=telcodes-mysql read=SELECT operator,region FROM `telcodes` WHERE ${ARG1:3:9} BETWEEN `begin` AND `end` AND `code`=${ARG1:0:3}
It is worth remembering that the result of the query will be 2 values, separated by a comma: the operator serving the number, as well as the service region.
Well, now you can directly write the rules themselves number processing. In the example I will omit the extra rules, I will leave only what is relevant. All changes are made in the file
/etc/asterisk/extensions.confCreate a context for outgoing calls.
Hidden text[from-users]
exten => _8XXXXX., 1, NoOp (Call from $ {CALLERID (num)} to $ {EXTEN})
same => n, Set (TARGETNO = $ {EXTEN})
same => n, Macro (seeknumber-odbc, $ {EXTEN: 1: 10})
same => n, Noop ($ {TRUNK_MOB})
same => n, Goto (to - $ {TRUNK_MOB}, $ {EXTEN}, 1)
same => n, hangup
We create contexts for calls to mobile service providers, as well as for the default provider. In setting up each trunk, I limited the number of simultaneous sessions to one and added call forwarding to the default trunk in case of busy or unavailable lines.
Hidden text[to-prov-trunk]
exten => _8XXXXX., 1, NoOp (Call from $ {CALLERID (num)} to $ {EXTEN} other)
same => n, Dial (SIP / prov-trunk / $ {EXTEN}, 140, Tt)
same => n, hangup ()
[to-beeline]
exten => _8XXXXX., 1, NoOp (Call from $ {CALLERID (num)} to $ {EXTEN} beeline)
same => n, Dial (SIP / beeline / $ {EXTEN}, 140, Tt)
same => n, Goto (status, s - $ {DIALSTATUS}, 1)
[to-megafon]
exten => _8XXXXX., 1, NoOp (Call from $ {CALLERID (num)} to $ {EXTEN} megafon)
same => n, Dial (SIP / megafon / $ {EXTEN}, 140, Tt)
same => n, Goto (status, s - $ {DIALSTATUS}, 1)
[to-mts]
exten => _8XXXXX., 1, NoOp (Call from $ {CALLERID (num)} to $ {EXTEN} mts)
same => n, Dial (SIP / mts / $ {EXTEN}, 140, Tt)
same => n, Goto (status, s - $ {DIALSTATUS}, 1)
[status]
exten => s-ANSWER, 1, Hangup ()
exten => s-CHANUNAVAIL, 1, Goto (to-prov-trunk, $ {TARGETNO}, 1)
exten => s-BUSY, 1, Goto (to-prov-trunk, $ {TARGETNO}, 1)
exten => s -., 1, Hangup ()
Well, now the macro itself:
Hidden text[macro-seeknumber-odbc]
exten => s, 1, NoOp (== tel nomber == $ {ARG1: 0: 3} == $ {ARG1: 3: 9} ==)
same => n, Set (result = $ {ODBC_MOBILE ()})
same => n, Set (operator = $ {CUT (result, \ ,, 1)})
same => n, Set (region = $ {CUT (result, \ ,, 2)})
same => n, NoOp (name of region = $ {region})
same => n, NoOp (name of operator = $ {operator})
same => n, Set (TRUNK_MOB = prov-trunk)
same => n, ExecIf ($ ["$ {operator}" = "beeline" & "$ {region}" = "home"]? Set (TRUNK_MOB = beeline))
same => n, ExecIf ($ ["$ {operator}" = "mts" & "$ {region}" = "home"]? Set (TRUNK_MOB = mts))
same => n, ExecIf ($ ["$ {operator}" = "megafon" & "$ {region}" = "home"]? Set (TRUNK_MOB = megafon))
The result was, in my opinion, a good unified solution for distributing calls to the right directions by phone number. In addition, I can say that it can be automated even more by writing a bash script to download and process fresh databases from the RosSvyaz website and add it to the
crontab for a monthly upgrade, but this will be considered homework;)