Попытка обойтись без регулярных выражений для номеров телефонов собственного региона

в 15:21, , рубрики: asterisk, def-коды, ip-телефония, Регулярные выражения, телефония, метки: , , ,

Привет, %username%!

В процессе администрирования Asterisk PBX рано или поздно возникает необходимость маршрутизации звонков по направлениям и чаще всего это: город, МГ, внутризоновая связь, МГ. С первыми двумя все ясно. А вот последние два… Ну и что здесь сложного скажете Вы? Уже написан вагон и маленькая тележка статей и скриптов по поводу составления регулярных выражений по DEF и ABC кодам, но периодически приходится обновлять все эти регулярки. И тут возникла мысль, а можно ли это автоматизировать. К сожалению чего-то готового, а главное подходящего найти не удалось. Значит будем изобретать свой велосипед.

Для этого нам необходимо выполнить следующее:

  1. Настроить соединение asterisk с базой данных
  2. Создать и заполнить таблицу с DEF и ABC кодами региона
  3. Описать функции дополнительные функции для asterisk
  4. Написать контексты для необходимых нам направлений

Шаг 1. Настраиваем соединение asterisk с БД

Предполагаю, что у Вас уже установлена и настроена база данных. В связи с тем, что у меня задействован механизм realtime, который использует базу данных postgresql, все описанные дальнейшие действия будут справедливы для postgresql, для иных баз возможно потребуются незначительные изменения.
На сервере с asterisk устанавливаем unixodbc, а также драйвер postgresql для odbc со всеми зависимостями. Для Debian/Ubuntu это делается командой:

apt-get install unixodbc odbc-postgresql

Приводим файл описания odbc драйверов к следующему виду:

cat /etc/odbcini.ini
[PostgreSQL ANSI]
Description  = PostgreSQL ODBC driver (ANSI version)
Driver  = /usr/lib/x86_64-linux-gnu/odbc/psqlodbca.so
Setup  = /usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so
Debug  = 0
CommLog  = 1
UsageCount  = 1

[PostgreSQL Unicode]
Description  = PostgreSQL ODBC driver (Unicode version)
Driver  = /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
Setup  = /usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so
Debug  = 0
CommLog  = 1
UsageCount  = 1

Для 32-битных систем путь к драйверам будет отличаться.
Создаем соединение с предварительной созданной базой:

 cat /etc/odbc.ini
[config]
Description         = PostgreSQL connection to 'asterisk' database
Driver              = PostgreSQL ANSI
Database            = asterisk
Servername          = 192.168.204.167
UserName            = asterisk
Password            = Uidj$5tuYF
Port                = 5432
Protocol            = 9.1
KSQO                = No
ReadOnly            = No
RowVersioning       = No
ShowSystemTables    = No
ShowOidColumn       = No
FakeOidIndex        = No
ConnSettings        =

Проверяем соединение с базой:

isql config

Если видим следующее приглашение:

+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> 

значит у нас соединение работает нормально.
Прописываем данное соединение в /etc/asterisk/res_odbc.conf:

[asterisk]
enabled => yes
dsn => config
username => asterisk
password => Uidj$5tuYF
pre-connect => yes

Шаг 2. Создать и заполнить таблицу с DEF и ABC кодами региона

На сервере баз создаем базу asterisk внутри, которой создаем таблицу примерно такую таблицу (указано минимально необходимое количество колонок):

CREATE TABLE zones ( 
def smallint NOT NULL,
start integer NOT NULL,
finish integer NOT NULL) 
WITHOUT OIDS;

Заполняем созданную таблицу запустив следующий скрипт:

#!/bin/bash
REGION='татарстан'
echo "COPY zones FROM stdin;" > zones.sql

wget -q http://www.rossvyaz.ru/docs/articles/DEF-9x.html -O DEF-9x.html
cat DEF-9x.html|iconv -f cp1251 -t utf8|grep -i $REGION|awk '{print($3"t"$6"t"$9)}' >> zones.sql
rm DEF-9x.html

wget -q http://rossvyaz.ru/docs/articles/ABC-3x.html -O ABC-3x.html
cat ABC-3x.html |iconv -f cp1251 -t utf8|grep -i $REGION|awk '{print($3"t"$6"t"$9)}' >> zones.sql
rm ABC-3x.html

wget -q http://rossvyaz.ru/docs/articles/ABC-4x.html -O ABC-4x.html
cat ABC-4x.html |iconv -f cp1251 -t utf8|grep -i $REGION|awk '{print($3"t"$6"t"$9)}' >> zones.sql
rm ABC-4x.html

wget -q http://rossvyaz.ru/docs/articles/ABC-8x.html -O ABC-8x.html
cat ABC-8x.html |iconv -f cp1251 -t utf8|grep -i $REGION|awk '{print($3"t"$6"t"$9)}' >> zones.sql
rm ABC-8x.html

echo "." >> zones.sql

psql -U asterisk -d asterisk -c 'DELETE FROM zones'
psql -U asterisk -d asterisk  -f zones.sql

rm zones.sql

Шаг 3. Описать функции дополнительные функции для asterisk

Нам понадобится дополнительная функция, которую опишем в /etc/asterisk/func_odbc.conf

[ZONES]
prefix=CHECK
dsn=asterisk
readhandle=asterisk
readsql=SELECT count(*) from zones where def='${ARG1:1:3}' and start<='${ARG1:4}' and finish>='${ARG1:4}'

Шаг 4.Написать контексты для необходимых нам направлений

Ну заключительный шаг: описать контексты.
Первый контекст для абонентов, которым разрешены только внутризоновые звонки:

[zones]
include => template

Второй для тех кому разрешены междугородние звонки:

[meggorod]
include => template

Да, они одинаковые :-)

[template]
exten => _8XXXXXXXXXX,1,GotoIf($["${CHECK_ZONES(${EXTEN})}" = "1"]?4)
 same => 2,GotoIf($["${CONTEXT}" = "meggorod"]?6:error,1)
 same => 3,Hangup()
 same => 4,Dial(SIP/prov1/${EXTEN},30,tTS(3600)gxX)
 same => 5,Hangup()
 same => 6,Dial(SIP/prov2/${EXTEN},30,tTS(3600)gxX)
exten => error,1,Playback(an-error-has-occured)
exten => error,n,Hangup()

Ну вот вроде бы и все. Вариант далек от идеала, но он работает.

Автор: rino906

* - обязательные к заполнению поля