Talant Blogs about VOIP
19.11.2019
Asterisk Click2Call API
- Готовый скрипт для вызовов между extension и внешним номером, а также для запуска любого диалплана и передачи ему параметров. Использовалась библиотека https://github.com/chan-sccp/PAMI это форк самой популярной библиотеки от marcelog/PAMI. Используется потому, что в ней исправлена ошибка при использовании CommandAction. в оригинальной библиотеке она будет выдавать read timeout. Скрипт выдает статус оригинации в json формате и unqueid. техническое задание в конце кода.
ini_set('display_errors', 0);
require __DIR__ . '/vendor/autoload.php';
use PAMI\Client\Impl\ClientImpl;
use PAMI\Listener\IEventListener;
use PAMI\Message\Event\EventMessage;
use PAMI\Message\Action\OriginateAction;
use \PAMI\Message\Event\NewchannelEvent;
class A implements IEventListener
{
public $result;
public function handle(EventMessage $event)
{
if ($event instanceof \PAMI\Message\Event\NewchannelEvent) {
$this->result = $event->getUniqueID();
return $this->result;
}
}
}
$agent = $_GET['agent'];
$extension = $_GET['extension'];
$destination = $_GET['destination'];
while ($agent && $extension) {
echo "No agent and extension possible!";
exit;
}
include "config.php";
$a = new ClientImpl($options);
$a->open();
$ClassA = new A();
$a->registerEventListener($ClassA);
while ($agent && $destination) {
echo "Agent && Destination";
$result = makecallagent($a,$agent,$destination);
$arr = array('success' => false, 'errormsg' => $result);
if ($result === true)
$arr = array('success' => $result,'errormsg' => NULL, 'uniqueid' => $ClassA->result);
echo json_encode($arr);
$a->close();
exit;
}
while ($extension && $destination) {
$result = makecall($a,$extension,$destination);
$arr = array('success' => false, 'errormsg' => $result);
if ($result === true)
$arr = array('success' => $result,'errormsg' => NULL, 'uniqueid' => $ClassA->result);
echo json_encode($arr);
$a->close();
exit;
}
echo "No extension\agent and destination correctly passed";
exit;
function makecall($a,$source,$number) {
$originateMsg = new OriginateAction("PJSIP/$source");
$originateMsg->setContext('from-internal');
$originateMsg->setPriority('1');
$originateMsg->setExtension("$number");
$res = $a->send($originateMsg);
if ($res->isSuccess()) return true; //return tru if originating success
return $res->getKeys()['message']; //otherwise return error message
}
function makecallagent($a,$source,$number) {
$originateMsg = new OriginateAction("Local/28@queuemetrics");
$originateMsg->setContext('queuemetrics');
$originateMsg->setPriority('1');
$originateMsg->setVariable('AGENTCODE',$source);
$originateMsg->setVariable('QDIALER_QUEUE','outqueue');
$originateMsg->setVariable('EXTTODIAL',$number);
$originateMsg->setExtension("28");
$res = $a->send($originateMsg);
if ($res->isSuccess()) return true; //return tru if originating success
return $res->getKeys()['message']; //otherwise return error message
}
15.11.2019 Removing plus symbol from CLI (Asterisk)
If CLI coming with +, then remove it, otherwise do nothing.
same = n,Set(CALLERID(num)=${IF($["${CALLERID(num):0:1}"="+"]?${CALLERID(num):1}:${CALLERID(num)})})12.08.2019
Colored Fax with raspberry and hylafax+.
Для работа цветных факсов нужно использовать hylafax+ , не путать с обычным Hylafax. В целом установка проходит по порядку, основные проблемы это как обычно поставить все нужные пакеты аккуратно.
Для работы используются следующие статьи:
Hylafax+ на sourceforge скачать нужно последнюю версию 7+.
hylafax+ installation from svn.
hylafax+ about colored fax – во время ./configure необходимо обратить внимание на то, что нужные библиотеки присутствуют в системе.
для работы понадобится iaxmodem и две библиотеки spandsp и libiax2, которые идут вместе с iaxmodem.
- Скачать hylafax+ и скомпилировать, во время компиляции gs программа была не найдена, но я просто создал symlink на то место где hylfax+ её искала. хотя это не обязательно.
- скачать iaxmodem и скомпилировать две библиотеки идущие с ним в папке Lib. (кстати вероятно этот шаг можно облегчить, если использовать готовые пакеты с iaxmodem )
- Сконнектить iaxmodem с астериском, статьи которые помогут это сделать: статья про обычный hylafax и связке с астериском, у меня в прицнипе получилось всё сделать через web freepbx, единственное, что если Host для iax пользователя установить как 127.0.0.1 то, регистрация не проходила, либо проходила с ошибкой, поэтому я сделал dynamic, но permit выставил для 127.0.0.1/32 . О запуске модема можно также в этой статье почитать, но и описание внутри пакета тоже простое и подробное.
- После того как модем появился в системе, можно запустить faxgetty и позвонить на номер модема в примере он указан как iaxmodem0, но я использовал 2000.
Для тестирования факсов использовал кстати, ventafax – Это программа с очень долгой историей, но удивительно робит и сейчас.
3.07.2019Asterisk as Wholesale. PAMI instead of AGI. Stable AMI connection.
Во время выполнения диалплана необходимо уточнять маршруты для звонка и делать то нужно из базы Mysql. Классический вариант использовать AGI Либо FastAGI, Но здесь я рассмотрю вариант запуска в фоне скрипта который, получая информацию о звонке, будет устанавливать переменную обратно в диалплан.
Asterisk адаптированный для wholesale, кстати, достаточно быстро всё обрабатывает используя минимум модулей и запросы в базу через ODBC. на удивление. Но всё равно с Opensips И Kamailio не сравнится.
Используем: PAMI library при установке пришлось повозиться т.к. не очень знаком с composer, но почитав про него – всё получилось. библиотеки ставятся в текущую директорию agi-bin, тогда будет доступ.
Основная проблема это поддержка коннекта между скриптом и астером, а также отсутствие ошибок между ними. Если вы запустите по умолчанию скрипты с ами, то вы наверняка получите внезапное завершение программы при анализе event от астериска. Есть несколько факторов, которые влияют на стабильность соединения:
- read timeout\read error – возникает на стороне скрипта, нужно обрабатывать такие события, в скрипте для этого будет try { } catch {}.
- Снизить поток событий из Астериска. В manager.conf Использовать eventfilter=Event: Newchannel тогда пользователю будет прилетать только определенный события.
- Не подключаться каждый раз при чтении и записи. В рамках библиотеки PAMI пришлось разбираться с классами в php.
- Астериск должен подождать в диалплане пока AMI скрипт установит переменную в канал, вот тут я не нашел ничего лучше чем просто подвесить его на 1500 циклов присвоения переменной – это ужасно я знаю.
Пример pami.php
Пример extensions.conf
Пример manager.conf
1.05.2019Черный список ip адресов для voip
sh скрипт который
!/bin/bash13.03.2019
BADIPSFILE="badips.list"
BADIPSFILETEMP="$BADIPSFILE".temp
ADDLISTFILE="$BADIPSFILE".load
# get new list
wget https://www.badips.com/get/list/voip/0 -O $BADIPSFILETEMP
# sort new list
sort $BADIPSFILETEMP -o $BADIPSFILETEMP
# touch to be sure that file exist
touch $BADIPSFILE
# diff old ans new file
diff $BADIPSFILE $BADIPSFILETEMP | grep -Po '\d+.\d+.\d+.\d+' > $ADDLISTFILE
# copy new file to old for next ips going fast
cp -f $BADIPSFILETEMP $BADIPSFILE
cp -f drop_temp.xml drop_temp_.xml
BLOCKED_IP=$ADDLISTFILE
IPTABLES="iptables"
if [ -f $BLOCKED_IP ]; then
while read BLOCKED; do
$IPTABLES -A INPUT_direct -i ens192 -s $BLOCKED -p udp -j DROP
done < $BLOCKED_IP
fi
connecting TATA sip trunk
TATA выдает подключает sip-trunkи через локальные сети, т.е. например они дают подсеть 10.0.8.6/32 со шлюзом 10.0.8.5 и только назначив первый ip адрес вы сможете подключиться к их voip сети.
Сразу укажу статью оригинал, которая помогла понять смысл подключения.
В качестве IP SBC\PBX тоже используются локальный адрес, например это может быть 10.0.74.11.
Едем дальше, чтобы получать входящие звонки нужно:
- добавить интерфейс к centos ip address add 10.0.86.6/30 dev eth0:0
- создать статический маршрут route add 10.0.74.11 gateway 10.0.8.5
- регистрироваться на их SBC (пароль по-умолчанию 1234)
register => 66810000:1234:66810000@10.0.74.11/66810000
для совершения исходящих:
- нужно звонить по определенным правилам набора, например для индии это набор номера 10 знаков без 5.
- нужно использовать в поле FROM правильный номер,
- А также необходимо удостовериться что поле contact соответствует 10.0.8.6 (если такое сделать не получится, то у меня звонки проходили и без этого пункта ),
- Обязательно добавьте SIP заголовок к исходящим
P-Preferred-Identity: <sip:66810000@SBC_IP> ,
для FREEPBX добавить sip заголовок к исходящему звонку просто:
- добавить в файл extensions_custom.conf нужный контекст, например такой:
[add-tata1-header]
exten => s,1,SipAddHeader(P-Preferred-Identity: ${ARG1})
exten => s,n,Return
- в настройках транка переопределить DIAL опции на:
B(add-tata1-header^s^1(66810000@10.0.76.11))
Вот так сумбурно, но в целом это все требования.
PS: чтобы freepbx подставлял в поле contact нужные данные, необходимо чтобы был маршрут до SBC. route add sbc_ip gateway gateway_IP. А также сети должны быть прописаны в конфигах Asterisk как localnet
1.03.2019pjsip, pitch_shift, real-time
Необходимо решить такую задачу нужно в режиме реального времени менять тональность каналов на asterisk 13.
Для реализации будем использовать AMI который есть почти во всех астерисках.
- Получаем список активных каналов через команду
- “core show channels concise”
- Отображаем пользователям каналы и кнопки увеличения,уменьшения тональности для конкретных каналов
- Применяем к каналам данные настройки через команду:
Action: SetVar
Channel: 1551426910.36
Variable: PITCH_SHIFT(both)
Value: 3
или как итоге получилось:
dialplan set chanvar $channel PITCH_SHIFT(both) high
sox asterisk wav mp3
Хорошая статья по теме конвертации в mp3 для centos7.
у меня лично возникла проблема со входящими файлами wav почему-то – sox не видел данных в них, пришлось явно указывать.
скрипт для конвертации всех файлов в каталоге в mp3
#!/usr/bin/perl
use strict;
use Proc::PID::File;
if (Proc::PID::File->running()) {
print "Already running, exiting now\n";
exit(0);
}
my @monitor_dirs=("/var/spool/asterisk/monitor");
foreach my $monitor_dir (@monitor_dirs) {
opendir(my $dh,$monitor_dir) or die ("Cannot open dir $monitor_dir");
print "Processing dir $monitor_dir\n";
while (my $file=readdir($dh)) {
next if $file !~m/\.wav$/;
print "Processing file $file\n";
my $newfile=$file;
$newfile=~s/\.wav$/\.mp3/;
system ("/usr/local/bin/sox -t raw -r 8000 -b 16 -e signed-integer $monitor_dir/$file -t mp3 -C32 $monitor_dir/$newfile");
sleep(0.01);
if (-e "$monitor_dir/$newfile") {
print "Coneverted sucessfully $file\n";
unlink "$monitor_dir/$file";
}
}
closedir($dh);
}
6.12.2018 firewalld asterisk fail2ban
На centos 7 по умолчанию используется firewalld и возникла проблема с тем что fail2ban не банит после неуспешных попыток авторизации и звонков
проблемы тут 2:
Первая это сами правила которыми пользуется fail2ban чтобы банить, я их заменил на
actionban = firewall-cmd –direct –add-rule ipv4 raw PREROUTING 0 -s -j DROP && firewall-cmd –change-source= –zone=block && firewall-cmd –change-source= –zone=block –permanent
actionunban = firewall-cmd –direct –remove-rule ipv4 raw PREROUTING 0 -s -j DROP && firewall-cmd –change-source= –zone=block && firewall-cmd –change-source= –zone=block –permanent && firewall-cmd –remove-source= –zone=block && firewall-cmd –remove-source= –zone=block –permanent
Вторая это то, что firewalld разрешает все соединения которые были установлены и остались в таблицах, посмотреть их можно командой iptstate
решается первым правилом
firewall-cmd –direct –add-rule ipv4 raw PREROUTING 0 -s -j DROP
Которое добавляет блокировку пакетов до проверки ESTABLESHED,RELATED
А третья проблема была в фильтре fail2ban который смотрит для регистраций accountID, и по мнению fail2ban он может быть только числовым или <unknown>
решается изменением регулярного выражения accountID = “(.+)” в фильтрах fail2ban.
| Posted in Asterisk, Готовые решения, Проблемы при настройке | No Comments »
| Posted in Asterisk, kamailio, rtpengine, Эксперт | No Comments »