Pull to refresh

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

Reading time4 min
Views6.1K

Привет, %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()


Ну вот вроде бы и все. Вариант далек от идеала, но он работает.
Tags:
Hubs:
+10
Comments3

Articles

Change theme settings