Автоматическая маршрутизация с IP АТС Asterisk для на VoIP GSM-шлюз или SIP-транк
Когда компания получает большие счета за телефонию и анализирует структуру расходов в этих счетах, то обнаруживает, что ощутимая их часть – плата за исходящие вызовы, часто это вызовы на мобильные сети. Операторы фиксированной связи берут за минуту больше, чем сотовые операторы, не говоря уже о том, что у сотовых операторов есть безлимитные тарифы или пакеты минут по очень привлекательным ценам. Поэтому, в недрах многих компаний рождается простая идея как сэкономить на телефонии – направить мобильный трафик через GSM-шлюз и соответствующие SIM-карты мобильных операторов.
Очевидное преимущество: использование GSM-шлюза — это существенное удешевление минуты исходящей связи. В обзоре пойдет речь именно о VoIP GSM-шлюзе, который подключается к IP АТС по протоколу SIP.
Но есть несколько проблем, с которой может столкнуться компания при использовании как обычного GSM-шлюза, так и VoIP GSM-шлюза:
-
При вызовах на мобильные сети через GSM-шлюз качество связи может ухудшится или стать нестабильным. Это нормальная ситуация при работе через радиосети, пусть и GSM – внешние помехи, неправильная установка антенн и как следствие недостаточная мощность сигнала, меняющаяся загрузка на базовые станции и другие факторы, оказывают существенное влияние уровень сигнала. Причём этот эффект может удвоиться, если через GSM-шлюз и АТС, соединяются два мобильных абонента.
-
Если основой номер компании городской, например, в коде 812, да ещё и красивый, как визитная карточка компании, клиенты привыкли видеть его на экранах своих телефонов. Но теперь, когда сотрудник компании звонит своим заказчикам и клиентам, то при исходящем вызове через SIM-карту GSM-шлюза, вызываемый абонент увидит номер этой SIM-карты, вместо городского номера компании.
-
Если вызовов через SIM-карту за определенный период слишком много, оператор может заблокировать SIM-карту. Сотовые операторы считают большую нагрузку на линию фродом, т.е. использование SIM-карты сверх лимитов, которые могут быть указаны в договоре с оператором.
Но, при правильной организации работы схемы с VoIP GSM-шлюзом, перечисленные выше проблемы можно максимально нивелировать или вовсе исключить.
Есть и другая проблема – как определить какие вызовы отправлять на фиксированного оператора, в нашем случае это SIP-транк, а какие вызовы направить на VoIP GSM-шлюз? Причём на GSM-шлюзе наверняка нужно использовать SIM-карты нескольких сотовых операторов, например, Мегафон, МТС, Билайн и Теле2, ведь клиенты пользуются разными сотовыми операторами.
Например, есть SIM-карты с безлимитными тарифами на звонки по всей России, а есть безлимитными тарифами на звонки только по Санкт-Петербургу. Поэтому, для правильной маршрутизации вызовов по наименьшей стоимости, нужно учитывать маски номеров, не просто принадлежащих определенному оператору, но и маски номеров для регионов каждого оператора. Простой пример: код 905, с 2500000 по 2899999 – 400000 номеров в регионе г. Санкт-Петербург и Ленинградская область ОАО «Вымпел-Коммуникации», код 905, с 5000000 по 5999999 – 1000000 номеров г. Москва и Московская область ОАО «Вымпел-Коммуникации», тарифы на звонки между регионами могут быть разными.
В зависимости от задачи, для каждого вызова, необходимо автоматически решать посылать его в SIP-транк или на VoIP GSM-шлюз. На GSM-шлюзе решать на какую SIM-карту сотового оператора терминировать вызов.
Можно пойти простым путём – расписать все маски прямо в плане набора АТС, но если учитывать все направления, которые есть на сегодняшний день (список по ссылке rossvyaz.ru), то получается порядка нескольких сотен разрозненных масок. Причём маски номеров или по-другому DEF-коды периодически меняются, редактировать конфигурационные файлы, например, extensions.conf в Asterisk, крайне неудобно. Кроме того, с декабря 2013 абоненты могут переводить свои мобильные номера от оператору к оператору и появилась ещё одна БД перенесенных номеров, я писал о ней в одной из заметок.
Рис. Пример выписки из реестра Российской системы и плана нумерации DEF-9xx
Поэтому, логичным выглядит создание базы данных, где будет храниться информация о обо всех направлениях на мобильные сети, которые нас интересуют.
Информация об изменениях в маршрутах будет заноситься автоматически, условного из некого внешнего приложения. Например, скрипта, который раз в сутки будет скачивать всю выписку из реестра и обновляет базу данных (БД).
Когда абонент IP АТС будет набирать мобильный номер, он будет автоматически проанализирован IP АТС путём его сравнения с имеющимся в БД маскам мобильных кодов и если маска найдена, направлен на VoIP GSM-шлюз, если нет, то на фиксированный SIP-транк. На VoIP GSM-шлюзе SIM-карты одного оператора объединены в группу, по более общим маскам на GSM-шлюзе, вызов направляется на определенную группу SIM-карт. Если требуется направлять вызов на определенную SIM-карту или на группу SIM-карт, то нужно вводить уникальный префикс, который будет подставлять IP АТС, например, в Б-номер, затем на GSM-шлюзе по этому префиксу вызов будет направлен через нужную SIM-карту или группу SIM-карт. В нашем примере маршрутизация на конкретную SIM-карту не рассматривается.
Если все линии на VoIP GSM-шлюзе заняты или шлюз недоступен, например, отключено питание или он завис, нужно перемаршрутизировать вызовы на фиксированный SIP-транк.
Итак, VoIP GSM-шлюз выступает в качестве альтернативного маршрута SIP-транку на котором стоимость исходящей минуты на мобильного оператора дороже чем через SIM-карты .
Рис. Схема автоматической маршрутизации вызова на GSM-шлюз или SIP-транк
Для примера в статье используется IP АТС на базе Asterisk и VoIP GSM-шлюз Dinstar DWG2000D-32G GSM/VoIP на 32 SIM карты. Модель Dinstar DWG2000D-32G GSM конфигурируется аналогично более новой модели Dinstar DWG2000G-32G.
Рис. Dinstar DWG2000G-32G
В статье представлен способ маршрутизации вызовов через IP АТС Asterisk с использованием внешней базы данных MySQL. Его можно расширить для маршрутизации исходящих вызовов по наименьшей стоимости или LCR (Least Cost Routing), добавив в БД условную стоимость каждого маршрута и имя SIP-транка, который должен использовать Asterisk для его терминации если Б-номер совпал по маске из БД.
Небольшое техническое задание:
-
Количество SIM-карт в шлюзе по операторам: Мегафон – 10шт, МТС – 10шт, 6шт –Билайн, 6шт – Теле2;
-
Исходящие вызовы на сотовые телефоны в кодах 905,906,909,960-967,921,931,911,981, 950,951,952,953 должны уходить через SIM-карты соответствующих операторов.
-
Остальные вызовы должны уходить через SIP-транк фиксированного оператора
-
В случае, если количество исходящих вызовов превысило кол-во SIM-карт для данного оператора, звонок должен уходить через SIP-транк
-
В случае недоступности GSM-шлюза вызовы должны направляться через SIP-транк.
Сначала сконфигурируем GSM-шлюз, затем IP АТС Asterisk.
Настройка VoIP GSM-шлюза Dinstar DWG2000D-32G
GSM шлюз Dinstar DWG2000D-32G GSM/VoIP конфигурируется при помощи встроенного веб-интерфейса. Приступим.
1) Подключаемся к GSM-шлюз, авторизуемся в веб-интерфейсе шлюза, назначим ему IP, в нашем примере это 192.168.0.1.
Вставляем SIM-карты и запоминаем какие SIM-карты в какие порты вставлены.
2) В меню «Port Group Configuration» группируем слоты, куда вставлены SIM-карты операторов, путём создания четырёх Port Group для операторов Теле 2, МТС, Билайн, Мегафон. Выбор портов в группе, устанавливаем, например, циклический.
Индекс | Оператор | Порт | Режим |
0 | Все | 20 | |
28 | Tele 2 | 26-31 | Циклический возрастающий |
29 | MTS | 10-19 | Циклический возрастающий |
30 | Beeline | 20-25 | Циклический возрастающий |
31 | Megafon | 0-9 | Циклический возрастающий |
3) В меню IP Trunk Configuration создаём IP-Trunk нашей IP АТС Asterisk, в примере он имеет IP=192.168.0.100. Исходящие и входящие вызовы будем совершать без регистрации. Далее, в меню IP trunk configuraton создаём IP Trunk Group куда включаем наш единственный SIP-транк на IP АТС Asterisk. В группе может быть до 32 SIP-транков.
В System Configuration -> Service Parameter настраиваем следующие параметры:
IP to GSM One Stage Dialing=yes
Play IVR for GSM Incoming Calls=no
Ringback Tone= GSM Ringback
Разрешить исходящие и входящие вызов без регистрации, тк на Asterisk будет использоваться статический SIP-транк:
Allow Call from GSM to IP without Registration=yes
Allow Call from IP to GSM without Registration=yes
Разрешить анонимные вызовы из GSM сети:
Reject Anonymous Call from IP to GSM=no
Также советую обратить внимание на таймеры No Answer Timeout и Interdigit Timeout.
Теперь в меню System Configuration -> Media Parameter настроим используемые аудиокодеки.
4) Настраиваем маршрутизацию вызовов с Asterisk на GSM-шлюз.
Переходим в меню Routing Configuration раздел IP->Tel Routing и настраиваем общие маски Destination Prefix операторов в зависимости от которых вызов будет направлен на определенную группу портов Destination представляющую сотового оператора.
Index | Description | Source IP | Source Prefix | Destination Prefix | Destination |
9 | Tele2 | IP Group 31 | any | 8900 | Port Group 28 |
10 | Beeline | IP Group 31 | any | 8969 | Port Group 30 |
11 | Megafon | IP Group 31 | any | 8999 | Port Group 31 |
12 | Beeline | IP Group 31 | any | 8968 | Port Group 30 |
13 | Beeline | IP Group 31 | any | 8967 | Port Group 30 |
14 | Beeline | IP Group 31 | any | 8966 | Port Group 30 |
15 | Beeline | IP Group 31 | any | 8965 | Port Group 30 |
16 | Beeline | IP Group 31 | any | 8964 | Port Group 30 |
17 | Beeline | IP Group 31 | any | 8962 | Port Group 30 |
18 | Beeline | IP Group 31 | any | 8961 | Port Group 30 |
19 | Beeline | IP Group 31 | any | 8960 | Port Group 30 |
20 | Beeline | IP Group 31 | any | 8909 | Port Group 30 |
21 | Beeline | IP Group 31 | any | 8905 | Port Group 30 |
22 | Beeline | IP Group 31 | any | 8906 | Port Group 30 |
23 | Megafon | IP Group 31 | any | 8921 | Port Group 31 |
24 | Tele2 | IP Group 31 | any | 8952 | Port Group 28 |
25 | Tele2 | IP Group 31 | any | 8953 | Port Group 28 |
26 | Tele2 | IP Group 31 | any | 8951 | Port Group 28 |
27 | Tele2 | IP Group 31 | any | 8950 | Port Group 28 |
28 | MTS | IP Group 31 | any | 8981 | Port Group 29 |
29 | MTS | IP Group 31 | any | 8911 | Port Group 29 |
30 | Beeline | IP Group 31 | any | 8963 | Port Group 30 |
31 | Megafon | IP Group 31 | any | 8931 | Port Group 31 |
5) Настраиваем маршрутизацию вызовов с GSM-шлюза на Asterisk.
Для этого, откроем в том же меню Routing Configuration пункт Tel->IP Routing.
Здесь зададим правило – отправлять все вызовы с GSM-шлюза на Asterisk используя IP Trunk 0 под названием aster:
Все вызовы с GSM-шлюза будут направляться на IP АТС Asterisk, если точнее, то на группу в которой у нас настроен единственный Asterisk.
Теперь, направим все вызовы на указанный номер в Asteisk, пусть это будет 78123004321
Откроем меню System Configuration -> Port Parameter, нажимаем кнопку Detail, в строке To VOIP Hotline указываем 78123004321 и нажимаем Save.
6) Последняя настройка – разрешим вызовы c части GSM на VoIP (SIP).
Открываем меню Operation -> Tel-> IP Operation и добавляем правило разрешить вызовы с любого порта с любым префиксом.
На этом настройка GSM-шлюза закончена. Если необходимо отправлять определённые вызовы на определенные SIM-карты, то для каждой SIM-карты нужно прописать префикс по которому вызов будет направлен на конкретную SIM-карту.
Настройка IP АТС Asterisk
Предполагается что:
-
Asterisk собран с поддержкой ODBC
-
Выполнена базовая настройка Asterisk – мы будем добавлять код в некоторые конфигурационные файлы Asterisk.
-
Установлен и настроен сервер MySQL с поддержкой ODBC
Вместо приведённого примера с функциями ODBC, в дайлплане Asterisk, можно использовать приложение AGI с вызовом внешнего скрипта или на худой конец использовать аналогично приложение System, но в рамках данной задачи проще всего, как мне кажется, именно ODBC.
Сначала подготовим БД MySQL для использования. Создадим БД astcdrdb и таблицу gsmroute куда будем помещать информацию о маршрутах на GSM-шлюз:
asterisk# mysql –uroot -p mysql> CREATE DATABASE astcdrdb; mysql> GRANT ALL ON astcdrdb.* TO asterisk_user@localhost -> IDENTIFIED BY ' asterisk_user'; mysql> FLUSH PRIVILEGES; mysql> SET PASSWORD FOR -> 'asterisk_user'@'localhost'=PASSWORD('some_password'); CREATE TABLE `gsmroutess` ( `id` int(15) NOT NULL AUTO_INCREMENT, `begin` bigint(15) NOT NULL, `end` bigint(15) NOT NULL, `enabled` char(1) NOT NULL DEFAULT '1', `notes` longtext NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET= utf8;
Опишем созданные столбцы:
Поле id пустое – оно заполниться автоматически это просто порядковый номер диапазона;
begin — начало диапазона;
end — конец диапазона;
enable =1 разрешить маршрут на шлюз;
enable =0 запретить маршрут на шлюз;
notes – текстовая пометка к маршруту;
Теперь добавим пару записей в таблицу gsmroute:
mysql> INSERT INTO `gsmroute` (`begin`, `end`, `enabled`, `notes`) -> VALUES -> (79991503000, 79991547999, '1', 'Megafon'), -> (79991803000, 79991837999, '1', 'Megafon');
Если нужно выключить маршрут:
mysql> update gsmroutess set enabled=0 where -> begin=79991503000 and end=79991547999;
После заполнения всех необходимых маршрутов, БД готова к использованию.
Тем, кому не удобно пользоваться консолью mysql, может понравится альтернативная графическая оболочка phpmyadmin, тогда для обновления маршрутов знания синтаксиса mysql не понадобится.
Для обновления таблицы gsmroute можно использовать, например, скрипт, который будет автоматически добавлять обновлять необходимые машруты.
Теперь подключим БД к Asterisk через драйвер ODBC.
Вообще ODBC (Open Database Connectivity) – универсальный программный интерфейс для доступа к БД, в нашем случае это серве MySQL.
Предполагается, что пакеты unixodbc unixodbc-dev libmyodbc уже установлены и известно где находятся конфигурационные файлы odbc, посмотреть где лежат драйверы можно командой
dpkg -L libmyodbc /. /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 /usr/share /usr/share/libmyodbc /usr/share/libmyodbc/odbcinst.ini /usr/share/doc /usr/share/doc/libmyodbc /usr/share/doc/libmyodbc/copyright /usr/share/doc/libmyodbc/changelog.Debian.gz /usr/share/doc/libmyodbc/README.Debian /usr/share/doc/libmyodbc/changelog.gz /usr/share/doc/libmyodbc/examples /usr/share/doc/libmyodbc/examples/odbc.ini
где конфигурационные файлы ODBC командой:
#odbcinst –j 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
Добавим описание драйвера MySQL коннектора к в файле /etc/odbc.ini:
[MySQL] Description = MySQL driver Driver = /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so Setup = /usr/lib/x86_64-linux-gnu/odbc/libodbcmyS.so CPTimeout = CPReuse =
[DBasterisk] Driver = /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so Description = MySQL Asterisk database ;Trace = Off TraceFile = /var/log/odbc.log Trace = Yes ForceTrace = Yes ;TraceFile = stderr Driver = MySQL Server = localhost User = asterisk_user Password = some_password
Теперь необходимо подключить Asterisk к MySQL через только что созданное подключение ODBC.
В файле Asterisk /etc/asterisk/res_odbc.ini добавляем объект:
[asterisk] enabled => yes dsn => DBasterisk username => asterisk_user password => some_password pre-connect => yes
В файле /etc/asterisk/modules.conf
проверяем что включена автозагрузка модулей директивой:
autoload=yes
или явно указываем загрузку модуля res_odbc.so
preload => res_odbc.so
Проверяем загружен ли модуль в консоли Asterisk :
#asterisk*CLI> odbc show all ODBC DSN Settings ----------------- Name: asterisk DSN: DBasterisk Last connection attempt: 1970-01-01 03:00:00 Pooled: No Connected: Yes Если модуль не загружен, то загрузим его: #asterisk*CLI> module load res_odbc.so
Таким образом, БД с масками машрутов на мобильные сети подключена к IP АТС Asterisk.
Теперь нужно добавить функцию ODBC в файле /etc/asterisk/func_odbc.conf, которая будет вызываться из дайплана Asterisk, передавать в неё будем значение ${ARG1}’, соответствующее коду мобильного оператора в набраном номере, функция вернет нам значение 1 — маршрут разрешён на GSM-шлюз в нашей таблице gsmroute, 0 или пусто – маршрут запрещен.
[CHECK_GSM_ROUTE] dsn=asterisk readsql=SELECT enabled FROM gsmroute WHERE '${ARG1}' BETWEEN begin AND end and enabled=1
после сохранения файла, из консоли Asterisk даём команду:
#asterisk*CLI> module reload func_odbc.so
Увидим:
== Registered custom function 'ODBC_ CHECK_GSM_ROUTE '
Проверим, что функция работает:
asterisk*CLI> odbc read ODBC_CHECK_GSM_ROUTE 9627277780 SELECT enabled FROM gsmroute WHERE '9627277780' BETWEEN begin AND end and enabled=1
Когда абонент набрал мобильный номер, в дайлплане Asterisk будет каждый раз вызываться данная функция для выбора точки терминации вызова или SIP-транк или GSM-шлюз.
Теперь приступим к настройки SIP-транка на GSM-шлюз. В конфигурационный файл /etc/asterisk/sip.conf добавляем параметры подключения:
[GSM-gate] type=peer context=GSM-IN host=192.168.0.100 port=5060 insecure=port,invite disallow=all allow=alaw allow=gsm allow=ulaw nat=no ;canreinvite=yes canreinvite=no use_q850_reason = yes
В качестве примера, SIP-транк на фиксированного оператора, который будет использоваться для вызовов на все номера, кроме мобильных.
[FIXED-operator] type=peer context=FIX-IN host=192.168.0.1 port=5060 insecure=port,invite disallow=all allow=alaw allow=ulaw nat=no canreinvite=yes use_q850_reason = yes
Теперь настроим маршрутизацию. Приведу пример простого контекста [mobile-out] отвечающего за обработку вызовов на мобильные сети из файла дайлплана Asterisk /etc/asterisk/extensions.conf.
[mobile-out] exten => _ [78]9XXXXXXXXX,1,NoOp(Check call ) same => n,GotoIf($["${ODBC_CHECK_GSM_ROUTE(7${EXTEN:1})}" = "1" ]?gsmroute:fixed) ; same => n(gsmroute),Dial(SIP/GSM-gate/7${EXTEN:1},,tTM(startrec)) same => n,NoOp(${DIALSTATUS}) same => n,Gotoif( $["${DIALSTATUS}" = ""]?fixed) same => n,Gotoif( $["${DIALSTATUS}" = "BUSY"]?stop) same => n,Gotoif( $["${DIALSTATUS}" = "NOANSWER"]?stop) same => n,Gotoif( $["${DIALSTATUS}" != "ANSWER"]?fixed:stop) same => n(fixed),Dial(SIP/FIXED-operator/7${EXTEN:1},,tTM(startrec)) same => n(stop),Hangup
Из встроенной в Asterisk переменной EXTEN извлекается Б номер, выражение (7${EXTEN:1} – отрезать 1 цифру от номера и подставить цифру 7. Затем, при помощи заранее подготовленной функции ODBC_CHECK_GSM_ROUTE, в БД проверяется существует ли и разрешена маршрутизация данного Б-номера на GSM-шлюз, если да, вызов направляется на SIP-транк под названием GSM-gate, если нет, то на SIP-транк фиксированного SIP-оператора FIXED-operator, причём, в случае если вызовы был отправлен на GSM-gate, по окончании вызова проверяется статус его завершения из встроенный в Asterisk переменной DIALSTATUS, если он приял значение BUSY, ANSWER или NOANSWER – завершить вызов, в остальных случаях попробовать позвонить через фиксированный SIP-транк с именем FIXED-operator. Также в опции переменной Dial командой M(startrec) запускается макрос для записи вызова.
На основе этого примера, легко можно сделать LCR маршрутизацию, например, в несколько SIP-транков по нужным критериям, например, в таблицу gsmroute добавить столбец cost – стоимость
маршрута и столбец direction – имя SIP-транка или имя точки терминации вызова, затем немного изменить запрос ODBC_ CHECK_GSM_ROUTE, чтобы он возвращал не 1 или 0, те разрешено или запрещено звонить на GSM-шлюз, а значение строки столбца direction, с наименьшей стоимостью cost, которое подставляться в приложение Dial, SIP-транки описать в файле /etc/asterisk/sip.conf.
Похожие материалы: