Статья: Asterisk: автообзвон (auto-dial out) и обратный звонок (callback) с использованием AGI
Проблема
При организации функции callback на Asterisk`е, когда Asterisk перезванивает и ты пытаешься ввести тоном номер, то нажатые тобой цифры начинают задваиваться, а то и затраиваться.
Причем это могло происходить не всегда и не зависело от аппарата, на котором набирали тоном.
Так же после многочисленных тестов стало точно понятно, что когда идет звонок из «города» на Asterisk, то подобных проблем не возникает, только если сам Asterisk звонит в «город».
VoIP соединение идет так:
E1 <—> Cisco AS5350 (c5350-js-mz.124-15.T11.bin) <—> Asterisk (версия 1.4.29_2)
Попробую более менее внятно рассказать о процессе нашего разбора с этой проблемой и последовательности действий, а вдруг кому ещё пригодится кроме меня, если я захочу освежить память по этому вопросу через какое то время.
Начали разбор полетов
Для того что бы выявить проблему стало понятно, что нужно подебажить DTMF на самом Asterisk. Как это сделать ?
Пока опыт работы с Asterisk не такой большой как хотелось бы, посему прибегнули к помощи гугла, через минут пять выяснили:
Открываем файл logger.conf и там ищем строчку:
console => notice,warning,error
В нее дописывем dtmf, получаем:
console => notice,warning,error,dtmf
Сохраняем файл, входим в консоль Asterisk`а:
asterisk -r
И в консоле даем команду:
asterisk*CLI> logger reload
После чего, в той же консоле, задаем уровень дебага, я делал так:
asterisk*CLI> core set debug 3
Далее, для того что бы потестить нажатие кнопок, я внес нехитрые изменения в dialplan:
[dtmf_test]
exten => s,1,Answer()
exten => s,n,Wait(1)
exten => s,n(collect),Read(digito,,11)
exten => s,n,SayDigits(${digito})
exten => s,n,GoTo(collect)
exten => s,n,Hangup
Т.е. поднимаем трубку, ждем ввода 11-ти цифр, а затем проговариваем все что набрали, собственно в этот контекст я перенаправил callback вызовы.
Подготовились, значит можно начинать.
Делаю callback на свою мобилку, начинаю давить цифири на мобиле, в консоле Астериска вижу:
[ДАТА] DTMF[5031]: channel.c:2351 __ast_read: DTMF begin '9' received on SIP/gt-00000015 [ДАТА] DTMF[5031]: channel.c:2355 __ast_read: DTMF begin ignored '9' on SIP/gt-00000015 [ДАТА] DTMF[5031]: channel.c:2283 __ast_read: DTMF end '9' received on SIP/gt-00000015, duration 352 ms [ДАТА] DTMF[5031]: channel.c:2336 __ast_read: DTMF end passthrough '9' on SIP/gt-00000015 [ДАТА] DTMF[5031]: channel.c:2351 __ast_read: DTMF begin '8' received on SIP/gt-00000015 [ДАТА] DTMF[5031]: channel.c:2355 __ast_read: DTMF begin ignored '8' on SIP/gt-00000015 [ДАТА] DTMF[5031]: channel.c:2283 __ast_read: DTMF end '8' received on SIP/gt-00000015, duration 376 ms [ДАТА] DTMF[5031]: channel.c:2336 __ast_read: DTMF end passthrough '8' on SIP/gt-00000015
и т.д. Во, то что надо, дебаг нажатия кнопок есть.
На одно нажатие в дебаге 4-ре строки. Чем дальше я смотрел в дебаг тем больше понимал, что я нажимаю цифирь один раз, а в дебаге она могла появиться и 2 и 3 раза (т.к. после одного нажатия появлялось более 4-х строк).
Смотрим что вообще мы можем «потрогать» в Астериске на тему DTMF.
Открываем файл sip.conf:
relaxdtmf=yes ; Relax dtmf handling
dtmfmode = rfc2833 ; Set default dtmfmode for sending DTMF. Default: rfc2833
; Other options:
; info : SIP INFO messages
; inband : Inband audio (requires 64 kbit codec -alaw, ulaw)
; auto : Use rfc2833 if offered, inband otherwise
Это глобальные настройки, кроме них так же можно указать dtmfmode и для конкретного пира в его контексте.
Меняли режимы, ситуация не изменялась. Как работало через раз, так и продолжало работать.
Раз так, то смотреть нужно с обоих сторон, т.е. в какой то момент привлекли и девайс Cisco.
Смотрим что же у нас указано в dial-peer:
dial-peer voice 23 voip description 4_outgoing_asterisk translation-profile incoming fake_aon answer-address 0010..... session protocol sipv2 voice-class codec 20 dtmf-relay rtp-nte h245-signal h245-alphanumeric no vad
В voice-class перечислены кодеки:
voice class codec 20 codec preference 1 g723r53 codec preference 2 g723ar53 codec preference 3 g723r63 codec preference 4 g723ar63 codec preference 5 g729r8 codec preference 6 g729br8 codec preference 7 gsmfr codec preference 8 g726r16 codec preference 9 g726r24 codec preference 10 g726r32 codec preference 11 g711alaw codec preference 12 g711ulaw
Решили ужать выбор кодеков до alaw и ulaw, т.к. тот же режим inband работет только с этими кодеками.
Тоже самое сделали и на Asterisk, запретив использование всех кодеков кроме этих двух, для этого в sip.conf, в настройках peer`а, который смотрит на Cisco, указали:
disallow=all
allow = alaw
allow = ulaw
Снова стали менять режимы в sip.conf, пробовать звонить, пофиг, все как было так и осталось.
Полезли на Cisco.com -> Configuring SIP DTMF Features, в частности интересовали предлагаемый самой циской debug:
Verifying SIP DTMF Support
To verify SIP DTMF support, perform the following steps as appropriate (commands are listed in alphabetical order).
SUMMARY STEPS
1. show running-config
2. show sip-ua retry
3. show sip-ua statistics
4. show sip-ua status
5. show sip-ua timers
6. show voip rtp connections
7. show sip-ua calls
Благодаря команде show sip-ua calls видно какой режим DTMF выбран в данный момент:
Call 1 SIP Call ID : 12abb76a79d610df282e2b237177bfe5@XX.XXX.XXX.XXX State of the call : STATE_SENT_ALERTING (14) Substate of the call : SUBSTATE_NONE (0) Calling Number : 001000119 Called Number : 8916XXXXXXX Bit Flags : 0xC0001C 0x100 0x404 CC Call ID : 22371 Source IP Address (Sig ): XXX.XXX.XXX.XXX Destn SIP Req Addr:Port : XXX.XXX.XXX.XXX:5060 Destn SIP Resp Addr:Port: XXX.XXX.XXX.XXX:5060 Destination Name : XXX.XXX.XXX.XXX Number of Media Streams : 1 Number of Active Streams: 0 RTP Fork Object : 0x0 Media Mode : flow-through Media Stream 1 State of the stream : STREAM_ADDING Stream Call ID : -1 Stream Type : voice+dtmf (1) Negotiated Codec : g711alaw (160 bytes) Codec Payload Type : 8 Negotiated Dtmf-relay : rtp-nte Dtmf-relay Payload Type : 101 Media Source IP Addr:Port: XXX.XXX.XXX.XXX:18936 Media Dest IP Addr:Port : XXX.XXX.XXX.XXX:14328 Orig Media Dest IP Addr:Port : 0.0.0.0:0
Итак теперь видно что происходит с двух сторон и какой режим выбирается и снова пробовали разнообразные режимы.
В Инете (в частности на www.voip-info.org/wiki/view/Asterisk+DTMF) иногда народ советовал прям в dialplan указывать режим DTMF перед набором чего-либо, сделать это можно командой SIPdtmfmode:
SIPDtmfMode(inband|info|rfc2833)
Но это как то тоже не очень спасало. После многочасовых разборок решили глянуть, а что у Asterisk`а на тему vad есть.
Решение
В файле codecs.conf:
; voice activity detection [true / false]
; reduces bitrate when no voice detected, used only for CBR
; (implicit in VBR/ABR)
vad => true
Таксссс.. опять же народ в Инете, при разборках с DTMF, советует с первую очередь гасить vad к чертям, делаем это:
vad => false
Далее была обнаружена вот эта статья «Changing DTMF tone frequency in Asterisk«:
Changing the DTMF tones
The Asterisk module dsp.c contains the definitions for DTMF tones. Just look for a part of the source code that says:
static float dtmf_row[] =
{
697.0, 770.0, 852.0, 941.0
};
static float dtmf_col[] =
{
1209.0, 1336.0, 1477.0, 1633.0
};
And change that to:
static float dtmf_row[] =
{
732.0, 809.0, 894.0, 988.0
/* 697.0, 770.0, 852.0, 941.0 */
};
static float dtmf_col[] =
{
1270.0, 1404.0, 1551.0, 1715.0
/* 1209.0, 1336.0, 1477.0, 1633.0 */
};
This will raise all detected DTMF codes by some 40Hz, enough for Asterisk to become completely tone-blind to existing DTMF codes.
Once you made the change, you must recompile Asterisk by:
- 1. Stopping Asterisk
- 2. Go to your Asterisk source directory
- 3. Enter make clean
- 4. Enter make
- 5. Enter make install
Note that you still can send Asterisk DTMF codes to transfer the call, start monitoring or what else — as long as you use the new DTMF tone matrix you just input. This is pretty easy to do with most industrial-grade call handling equipment.
«Ну что ж, не грех попробовать» — сказали мы и выполнили как написано.
Диалпир на циске был приведен к виду:
dial-peer voice 23 voip description 4_outgoing_asterisk translation-profile incoming fake_aon answer-address 0010..... session protocol sipv2 codec g711alaw dtmf-relay rtp-nte no vad
Наконец то оно заработало, заработало как надо. По крайней мере, после многочасовых тестов, ни одного сбоя в наборе тоном не было. Надеемся что и далее не будет проблем.
Я решил написать все это для того, что бы если кто-то тоже заморочится с этой темой и не будет знать как к этому подступиться, ну и если я вернусь к этому вопросу позднее, чтобы не вспоминать что уже было сделано :).
З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Пожалуйста, уважайте чужой труд.
Авторы: Панфилов Алексей (lehis (at) subnets.ru), Николаев Дмитрий (virus (at) subnets.ru)
Похожие статьи:
- Не найдено
mh сказал:
Мы тоже сейчас занимаемся IP телефонией на asterisk’e… спасибо за статью!
14.04.2010, 15:03admin сказал:
пжалста, значит был прав, что может пригодится не только мне 🙂
14.04.2010, 18:36xfiles сказал:
Спасибо за подсказки!
Появился еще вопрос, можно ли логгировать дтмф коды которые прожимали в ivr?
Например, в /etc/asterisk/extensions_override_freepbx.conf можно добавить что-то вроде:
[ext-queues]
exten => h,1,DumpChan() — дамп всех переменных, дтмф тут нет
exten => h,1,ExecIf($[«${CDR(dstchannel)}»=»»]?System(/usr/local/bin/send_msg.sh —ext-name ext-queues —ext-type CallInQueue —call-num «${CALLERID(num)}» —queue «${NODEST}» —call-time «${CDR(duration)}» —call-to «${CDR(did)}» )
exten => h,2,Macro(hangupcall,)
в результате скрипт send_msg.sh обрабатывает пропущенные вызовы, но хотелось бы дополнить уведомления информацией о том, какое именно меню клиент выбирал в IVR, или несколько раз нажимал.
03.07.2021, 12:55