Привет, %username%!
В процессе администрирования Asterisk PBX рано или поздно возникает необходимость маршрутизации звонков по направлениям и чаще всего это: город, МН, внутризоновая связь, МГ. С первыми двумя все ясно. А вот последние два… Ну и что здесь сложного скажете Вы? Уже написан вагон и маленькая тележка статей и скриптов по поводу составления регулярных выражений по DEF и ABC кодам, но периодически приходится обновлять все эти регулярки. И тут возникла мысль, а можно ли это автоматизировать. К сожалению чего-то готового, а главное подходящего найти не удалось. Значит будем изобретать свой велосипед.
Для этого нам необходимо выполнить следующее:
- Настроить соединение asterisk с базой данных
- Создать и заполнить таблицу с DEF и ABC кодами региона
- Описать функции дополнительные функции для asterisk
- Написать контексты для необходимых нам направлений
Шаг 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()
Ну вот вроде бы и все. Вариант далек от идеала, но он работает.