26.12.2015

Asterisk. Annoucement. Dialplan. ChannelRedirect. Elastix.

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

Задача: Записать заранее приветствие в нескольких вариантах, и затем воспроизводить его абонентку по нажатию на кнопки быстрого набора.

Проблема: Быстрый набор – это просто очередной INVITE с заранее запрограммированным кодом, поэтому, для астериска это выглядит как поступление нового звонка.

Решение: Я решил эту задачу как для DTMF так и для использования speed-dial.

Ключ к решению: Основная проблема это заставить астериск воспроизводить заранее записанное приветствие нужному абоненту, если просто внести в dialplan запись вида ##1, где номер приветствия то астериск его проиграет тому кто прислал вызов, а нам нужно воспроизвести его абоненту, да еще и в терминологии Asterisk в другой канал.

Коротенько: Записывать приветствия мы будем формата XXXX_N.wav , XXXX- номер эксентшина который записывает приветствие, а N – это номер самого приветствия, таким образом мы можем записывать несколько приветствий для одного экстеншина.

[custom-record] ; Context for recording voice messages
exten => _#*00X,1,Noop(${EXTEN})
same => n,Set(CHANNEL(language)=ru)
same => “”n,Set(MONITOR_FILENAME=${DIR}${CALLERID(num)}_${EXTEN:4})
same”” => n,Playback(beep)
same => n,Answer
same => n,Record(${MONITOR_FILENAME}:wav)
same => n,Playback(vm-msgsaved)
same => n,Playback(${MONITOR_FILENAME})
same => n,Playback(vm-goodbye)

Воспроизведение:  При звонке мы сохраняем данные кто звонил и имя канала куда позвонили   : ${CALLEDRID(num)} – ${CHANNEL}, Делать это нужно в время команды Dial поэтому используется pre_dial_handler, для Эластикс это просто Опции в разделе General Setting. Tt – дает возмоножсть пользоваться DTMF, а ^M(testsub) выполняет макрос testsub.

[macro-testsub]
exten => s,1,NoOp(${CHANNEL})
exten => s,n,NoOp(${MYVAR})
exten => s,n,Set(DB(br/${MYVAR})=${CHANNEL})
exten => s,n,NoOp(${DB(br/${MYVAR})})

Чтобы запомнить переменную кто звонил мы добавляем строчку “exten => s,n,Set(__MYVAR=${CALLERID(number)})”  в macro-user-callerid и отправляем этот макрос в файл extensions_override_elastix Это означает, что Эластикс будет читать его их этого файла, чтобы не случилось в конфигурации. __ – означает что эта переменная будем передана вновь создаваемому каналу командой Dial.

И теперь при получении кода ##N от пользователя мы просто смотрим есть такая переменная в DB Астериска, если есть, то переводим сохраненный ранее канал в место где начинается воспроизведение.

[transfer-context]
exten => “”_##X,1,NoOp(${DB(br/${CALLERID(num)})})
exten”” => “”_##X,2,ChannelRedirect(${DB(br/${CALLERID(num)})},transfer-context,${EXTEN},3)
exten”” => _##X,3,Playback(${DIR}${MYVAR}_${EXTEN:-1}) ;
exten => _##X,4,Hangup()

Таким образом никаких скриптов, все гибко, красиво, изящно.

Бай.

 

PS: http://asteriskfaqs.org/2010/09/09/asterisk-users/set-channel-variable-from-within-other-channel.html

PS: https://wiki.asterisk.org/wiki/display/AST/Function_DB

 

 

 

 

16.08.2015

SOX. WAV. ASTERISK. BATCH. Конвертнуть файлы для астериска.

Привет!

Дали wavки для заливки на астериск, если честно понятия не имею что там и как устроено в астере, но Астериск сам предлоагает сервис для конвертации WAV файлов во все нужные ему форматы. при помощи CLI “file convert”.

1. WAV нужно преобразовать в 8000 Khz и 1 канал, делается это командой: “sox input.wav -c 1 -b 8000 outout.wav”

лично я не смог потратить время с делать одной командой конвертацию файлов в каталоге поэтому поступил тупейшим образом: ls -a *.wav

скопировал результат в файлик, там произвел замену при помощи регулярных выражений например из строчки: 1.wav я получил

sox  1.wav -r 8000 -c 1 new/1.wav

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

2.далее я создаю файлик с командами типа ” asterisk -x “file convert    transfering.wav           res/transfering.g729”

и все, в каталоге res получаются файлики с нужными кодеками. Астериск сам понимает в какой кодек надо перекинуть файл, если вы указывается расширение. В моем случае это g729.

Кодеки должны присутствовать и быть активными конечно.

Бай.

14.06.2015

ACK. OPENSIPS. SEMS. ROUTE

Столкнулся с проблемой при использовании SEMS. При звонке ACK отправлялся на тот же IP что и сервер. И не доходил до абонента. проблема решается удалением IP адреса из списка локальных доменов. решение было найдено в архиве за 2009 год.

Приятного Opensips всем.

4.06.2015

Opensips Ростелеком chel.media.usi.ru

Чтобы подключить услугу НЕОФОН от Ростелекома на Опенсипсе – необхоидмо выполнить несколько условий.

 

1. Ростелеком трЕбует:

FROM: sip: 7337788@chel.media.usi.ru

2. Исходящий звонок должен происходить обязательно с железки с которой была регистрация, вот рабочая версия для модуля registrant:

modparam(“uac_registrant”,”uac”, “sip:chel.media.usi.ru,,sip:7298171@chel.media.usi.ru,,7337788,PASSWORD,sip:7298171@123.123.123.123:5060,,,”)

3. при получении пакета 407 необходимо отсылать логин и пароль:

route[AUTHCHECK] {
if (t_check_status(“(401)|(407)”)) {

xlog(“got auth request from”);

if ( uri=~”sip:.+@chel.media.usi.ru” ) {
$avp(authrealm) = “Realm”;
$avp(authuser) = “7337788”;
$avp(authpass) = “PASSWORD”;
}

}

failure_route[2] {
xlog(“second failure route”);
uac_auth();
route(AUTHCHECK);

}

10.04.2015

Тестирование максимальной пропускной способности A2Billing.

1. Абонента А – Opensips – Media2 – Абонент B (600)

Тестирование проводится командой sipp. Необходимо поправит скрипт, для того, чтобы sipp работал c opensips. Заставить работать ту версию, что поставке – никак не смог.

/sipp   -default_behaviors abortunexp -s 600 -sf uac_pcap.xml sip.fiberpipe.in -r 10 -trace_err

 

Первая Проблема была традиционной: ограничение на кол-во открытых файлов в системе.

Вторая проблема касалась того, что Mysql для таких систем должен стоять либо в памяти либо на SSD.

Третья проблема касалась ограничения кол-ва поключений к Mysql.

Вытекающие проблемы: надо делать для Mysql репликацию из памяти на HDD.

После решения первых трех проблем кол-во вызовов в системе возразло , критическую нагрузку нет возможность поверить не позволили возможности абонента А. Дошли до 300.

 

Сценарий для sipp:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?>
<!DOCTYPE scenario SYSTEM “sipp.dtd”>

<!– This program is free software; you can redistribute it and/or –>
<!– modify it under the terms of the GNU General Public License as –>
<!– published by the Free Software Foundation; either version 2 of the –>
<!– License, or (at your option) any later version. –>
<!– –>
<!– This program is distributed in the hope that it will be useful, –>
<!– but WITHOUT ANY WARRANTY; without even the implied warranty of –>
<!– MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the –>
<!– GNU General Public License for more details. –>
<!– –>
<!– You should have received a copy of the GNU General Public License –>
<!– along with this program; if not, write to the –>
<!– Free Software Foundation, Inc., –>
<!– 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA –>
<!– –>
<!– Sipp ‘uac’ scenario with pcap (rtp) play –>
<!– –>

<scenario name=”UAC with media”>
<!– In client mode (sipp placing calls), the Call-ID MUST be –>
<!– generated by sipp. To do so, use [call_id] keyword. –>
<send retrans=”500″ >
<![CDATA[

INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: 9415601662 <sip:9415601662@[local_ip]:[local_port]>;tag=[call_number]
To: sut <sip:[service]@[remote_ip]:[remote_port]>
Call-ID: [call_id]
CSeq: 1 INVITE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length: [len]

v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[local_ip_type] [local_ip]
t=0 0
m=audio [auto_media_port] RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16

]]>
</send>

<recv response=”100″ optional=”true”>
</recv>

<recv response=”180″ optional=”true”>
</recv>

<!– By adding rrs=”true” (Record Route Sets), the route sets –>
<!– are saved and used for following messages sent. Useful to test –>
<!– against stateful SIP proxies/B2BUAs. –>
<recv response=”200″ rrs=”true” rtd=”true” crlf=”true”>
</recv>

<!– Packet lost can be simulated in any send/recv message by –>
<!– by adding the ‘lost = “10”‘. Value can be [1-100] percent. –>
<send>
<![CDATA[

ACK [next_url] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: 9415601662 <sip:9415601662@[local_ip]:[local_port]>;tag=[call_number]
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 1 ACK
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0

]]>
</send>

<!– Play a pre-recorded PCAP file (RTP stream) –>
<nop>
<action>
<exec play_pcap_audio=”pcap/g711a.pcap”/>
</action>
</nop>

<!– Pause 8 seconds, which is approximately the duration of the –>
<!– PCAP file –>
<pause milliseconds=”12000″/>

<!– The ‘crlf’ option inserts a blank line in the statistics report. –>
<send retrans=”500″>
<![CDATA[

BYE [next_url] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
[routes]
From: 9415601662 <sip:9415601662@[local_ip]:[local_port]>;tag=[call_number]
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 2 BYE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0

]]>
</send>

<recv response=”200″ crlf=”true”>
</recv>

<!– definition of the response time repartition table (unit is ms) –>
<ResponseTimeRepartition value=”10, 20, 30, 40, 50, 100, 150, 200″/>

<!– definition of the call length repartition table (unit is ms) –>
<CallLengthRepartition value=”10, 50, 100, 500, 1000, 5000, 10000″/>

</scenario>

7.04.2015

Проблемы с виртуальной машиной. Opensips. KVM.

http://opensips-open-sip-server.1449251.n2.nabble.com/fr-timer-not-working-properly-td7588092.html

Вот здесь описывается случай с процессором AMD Opteron(tm) Processor 6344 (on KVM).

 

1.04.2015

Opensips. NAT. Port. Asterisk.

Почти день потратил на то чтобы понять почему при исходящем звонке нет звука.

Система такая:

Client A ( local IP) —> Router(TP-Link) —-> Opensips (NAT_HELPER) —-> Asterisk (1.8) (A2Billing) —–> Carrier

По SIP trace все гладко, порты, IP адреса, все подменяется просто отлично но аудио нет. Не слышно абонента.

Оказывается при выходе с TP-link media отправлялось не с 8000 порта, а с 1024. Чертов роутер меняет его по свему усмотрению, при это в SIP сообщение он не залезает, потому, что я отключил все “умные” функции связанные с SIP сообщениями на роутере, для чего? Для того, чтобы быть уверенным в том, что SIP сообщение отправленное мной, не претерпевает изменений.

Так вот, а Астериск получая медиа-трафик с порта 1024 слал его на 8000, т.к. в сообщении указан именно он. TP-Link разводил руками, че это мне на 8000 порт приходит трафик, я шлю только с 1024.  В общем, в астериске есть настройка nat в sip.conf значение comedia означает, что астериск будет слать трафик на фактический адрес, с которого приходит медиа. Это решает такие проблемы.

 

 

9.02.2015

Перенос базы данных A2Billing

при переносе базы данных с одного сервера на дргуой.

Астериск берет часть информации с новой базы данных а вот за списком транков и историей звонков  бегает в старую, почему так себя ведет – не понятно…

Разбираемся.

На астериске оставлся не измененным файл a2billing.conf AGI скрипты брали оттуда информацию… Чтож банально.

Для A2Billing AGI необходимы пакеты с libphp-adodb. иначе будет выдать ошибку

<SIP/myip-0000004c>AGI Tx >> 200 result=1
<SIP/myip-0000004c>AGI Rx << Connection failed
<SIP/myip-0000004c>AGI Tx >> 510 Invalid or unknown command
[Dec 30 07:59:16] ERROR[28331]: utils.c:1343 ast_carefulwrite: write() returned error: Broken pipe


Потратил несколько часов... удивительно как бездарно можно провести время.