- PVSM.RU - https://www.pvsm.ru -

Макрос для балансировки исходящих звонков на GSM в Asterisk

Привет!

В прошлом топике(уже в черновиках) я обещал предоставить хабрасообществу действующий макрос для балансировки исходящих звонков через N-ное количество сим-карт. Сабж, собственно, найден, усовершенствован и протестирован. Плюс — он гарантирует, что симка с превышенным лимитом использоваться не будет.

Дано: FreeBSD 9, Asterisk 11.4, 2х Addpac GS1002 (используются все 4 сим-карты). Настроено 4 транка на симки: 9001, 9002, 9003, 9004 соответственно. На них полосатый тариф с «безлимитом» 300 минут в месяц на каждой.
Задача: Если на какой-либо симке исчерпан лимит, не использовать ее при наборе. Если же исчерпаны все — слать звонок через провайдера (там чуть дешевле, чем через GSM с тарификацией)

1. Настраиваем сохранение cdr в mysql

Не вижу смысла копипастить сюда мануал [1]. Добавлю лишь, проверьте наличие модуля cdr_mysql.so в своей сборке.

2. Добавляем контекст с макросом в extensions.conf(для работы необходим модуль app_mysql.so — Simple Mysql Interface!)

Сам макрос подробно прокомментирован.

[macro-gsm]

exten => s,1(start),Set(ARG2=$[${ARG2} + 1]) ;инкремент, подробности чуть ниже
same => n,GotoIf($[${ARG2}>=9005]?sip:repeat) ;У нас 4 транка, предлагает 9005 - пускаем через провайдера
same => n(repeat),MYSQL(Connect connid localhost asterisk password asterisk) ; Подключаемся к базе
same => n,MYSQL(Query resultid ${connid} SELECT SUM(`billsec`) FROM `cdr` WHERE `dstchannel` LIKE '%${ARG2}%' AND MONTH(`calldate`)=MONTH(NOW()) AND YEAR(`calldate`)=YEAR(NOW())) ; Собственно запрос. Результат - суммарное количество тарифицируемых секунд на текущем транке за текущий месяц
same => n,MYSQL(Fetch fetchid ${resultid} duration) ; Результат в переменную duration
same => n,MYSQL(Clear ${resultid}) ;Очистка и отключение от базы
same => n,MYSQL(Disconnect ${connid})
same => n,GotoIf($[${duration}<=18000]?call:start) ; Если через транк прошло менее 300 минут, посылаем звонок через него, нет - отправляемся в начало, в следующем круге используется транк с большим номером
same => n(call),Dial(SIP/${ARG2}/${ARG1},,tkr) ;Звоним
same => n,GotoIf($[${DIALSTATUS}=ANSWER]?end:start) ;Разговор состоялся - кладем трубку, транк занят - следующий круг
same => n(sip),Dial(SIP/ctm/${ARG1},,Ttr) ;Звонок через провайдера
same => n(end),Hangup ;Кладем трубку

exten => h,1,MYSQL(Clear ${resultid}) ; Еще команды на отключение от базы, для перестраховки. 
same => n,MYSQL(Disconnect ${connid})


Пример вызова в диалплане: exten => _79XXXXXXXXX,1,Macro(gsm,${EXTEN},9000)
9000: номер транка — 1

Макрос протестирован и работает. Очевидные минусы — неоптимизированный запрос, названия транков только цифровые. Есть желание помочь — предлагайте в комментариях свои варианты. Плюс — он эффективен)

Спасибо pfactum [2], PyroRed [3] и Malamut [4] за вдохновение.

Автор: Sl1mShady

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/linux/44584

Ссылки в тексте:

[1] мануал: http://voip.rus.net/tiki-index.php?page=Asterisk+cdr+mysql

[2] pfactum: http://habrahabr.ru/users/pfactum/

[3] PyroRed: http://habrahabr.ru/users/pyrored/

[4] Malamut: http://habrahabr.ru/users/malamut/

[5] Источник: http://habrahabr.ru/post/195730/