­
Новости
Обзоры и тесты
Техно
Советы
Разное
Главная » Техно

Сравниваем конфигурации Freeswitch и Asterisk для одной задачи

Добавлено на 27.02.2019 – 09:45

Для чемпионата мира в России, который прошёл в 2018 году, нужно было решить задачу авторизации пользователей для услуги Wi-Fi при помощи звонка на телефонный номер как один из способов авторизации. Для решения использованы аналогичные конфигурации Freeswtich и Asterisk.

Смысл в том, что пользователь вводит номер телефона своего смартфона\планшета\компьютера через веб-форму авторизации в Wi-Fi сети, далее, пользователь выбирает каким способом он подтвердит, что это действительно его мобильный номер: при помощи отправки SMS-сообщения или звонком на номер телефона, где ему должна проиграться голосовая подсказка о успешности\неуспешности авторизации, в зависимости от языка интерфейса(русский, английский, французский, немецкий или испанский). Голосовая платформа Asterisk\Freeswith передаёт номер позвонившего серверу авторизации, сервер сверяет телефонный номер полученный через веб-форму с номером, который передала голосовая платформа, в ответ возвращается успешный или неуспешный код. Сообщение должно проигрываться в предответном состоянии до начала тарификации, чтобы абонент не платил деньги за звонок. Так как Asterisk и Freeswitch в этой схеме выполняют функции медиасерверов, будем называть далее их именно так.
Терминация из телефонных сетей на медасерверы работала через два транковых шлюза Eltex SMG1016M, голосовых платформ тоже две: первая Asterisk 15.3.0 установленный на ОС Linux Debian 9.4, вторая FreeSWITCH Version 1.6.20 установленная на ОС Linux Debian 8.10. В июне 2018 FreeSWITCH ещё не поддерживал ОС Linux Debian 9 для «продакшен» режима.
Asterisk и Freeswitch запущены на виртуальных машинах, основные пики нагрузки приходились, когда начинались футбольные матчи.
Главный минус схемы с такой авторизацией – иногда из телефонной сети общего пользования может приходить искажённый номер вызывающего абонента(А-номер), в таком случае пользователь не будет авторизован, хотя правильно указал свои данные. Данная ситуация была замечена у одного сотового оператора для парных номеров: федеральный номер плюс местный городской номер в которых равны последние 7 цифр номера.

Техническая реализация

Создан пул телефонных номеров равный количеству языков – 5, звонки на любой из 5 телефонных номеров по очереди попадает на шлюзы SMG1016: 192.168.25.8 и 192.168.25.9, на каждом из шлюзов созданы транковые направления терминации состоящие из двух транковых групп, по одной на медиасервер (Asterisk и Freeswitch), алгоритм работы направлений для терминации: последовательно вперёд.

Транковое направление SMG

Заметку по маршрутизации на шлюзах Элекс SMG можно найти по данной ссылке.
Оба шлюза подключены к городской АТС, где также создана группа терминации с алгоритмом работы по очереди. Такая схема даёт равномерное распределение нагрузки по шлюзам и медиасерверам.
Когда медиасервер получает вызов, он делает запрос по http на сервер авторизации куда в фомате JSON передаёт номер телефонный позвонившего и телефонный номер для авторизации куда позвонил пользователь:

1
data={'user_phone': user_phone,'gw_phone': gw_phone}

В ответ сервер передаёт код ответа и результат в формате:

1
resultCode=1&resultMessage=accepted

Если,

  • resultCode = 1 – проиграть подсказку об успешно авторизации
  • Любой другой код – проиграть сообщение об ошибке

В статье я не буду касаться вопросов инсталляции Asterisk и Freeswtich, рассмотрю только необходимую конфигурации внешнего канала SIP и дайлплана, также скриптов которые делают запрос по http и возвращают результат.

Медиасервер Astersik

IP-адрес=192.168.25.32

Здесь из дайлплана при помощи AGI вызываем внешний скрипт, который сделает запрос на сервер и вернёт результат.

Настройка внешних каналов SIP для приёма трафика от шлюзов, файл /etc/asterisk/sip.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[FIFA-1]
type=peer
context=FIFA-IN
host=192.168.25.8 ;Шлюз 1 SMG1016M
insecure=port,invite
disallow=all
allow=ulaw
nat=no
canreinvite=no
use_q850_reason = yes
 
 
[FIFA-2]
type=peer
context=FIFA-IN
host=192.168.25.9 ;Шлюз 2 SMG1016M
insecure=port,invite
disallow=all
allow=ulaw
nat=no
canreinvite=no
use_q850_reason = yes

Здесь вызовы с любого из двух шлюзов отправляются в контекст FIFA-IN.
Дайплан Asterisk, файл /etc/asterisk/extensions.ael
Приведу только первые два номера, напомню, что всего языков подсказок 5 и номеров столько же, соответственно.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
context FIFA-IN
{
78120002915 => {
        AGI(get-res.py,${CALLERID(num)},${EXTEN:1});
Set(CDR(userfield)=${ANSWER});
NoOp(RES => ${RES});
        switch (${RES}) {
                    case 1:
                    Progress();
                    Playback(/var/lib/asterisk/sounds/fifa/success_readyRUS1,noanswer);
                    Busy(10);
                    Hangup(16);
                  default:
                    Progress();
                    Playback(/var/lib/asterisk/sounds/fifa/Fail_RUS1,noanswer);
                    //Playback(/var/lib/asterisk/sounds/ru/agent-alreadyon,noanswer);
                    Busy(10);
                    Hangup(16);
 
                };
        };
 
78120002916 => {                                                                //English
        AGI(get-res.py,${CALLERID(num)},${EXTEN:1});
Set(CDR(userfield)=${ANSWER});
NoOp(RES => ${RES});
        switch (${RES}) {
                    case 1:
                    Progress();
                    Playback(/var/lib/asterisk/sounds/fifa/Success_readyEN1,noanswer);
                    Busy(10);
                    Hangup(16);
                  default:
                    Progress();
                    Playback(/var/lib/asterisk/sounds/fifa/Fail_EN1,noanswer);
                    //Playback(/var/lib/asterisk/sounds/ru/agent-alreadyon,noanswer);
                    Busy(10);
                    Hangup(16);
 
                };
        };
 
 
};

Любой вызов, пришедший со шлюзов 192.168.25.8 и 192.168.25.9 попадает в контекст FIFA-IN дайлплана Asterisk, здесь, в зависимости от одного из пяти набранных номеров, вызов попадает на нужный экстеншен, например, 78120002916, при помощи приложения AGI вызывается внешний скрипт из директории по умолчанию /var/lib/asterisk/agi-bin. Результат работы скрипта передаётся оператору выбора case, далее, приложение Progress() указывает Asterisk что не нужно посылать SIP 200OK, что равно соединению и началу тарификации, а проиграть голосовое сообщение в режиме предответа(early media) с помощью приложения Playback, затем послать сигнал занято — Busy(10) и повесить трубку Hangup. Аудиофайлы, которые нужно проиграть загружаются в /var/lib/asterisk/sounds/ru/.
Для контроля содержимого ответа в CDR Asterisk добавим содержимое переменой ANSWER при помощи приложения Set,
Set(CDR(userfield)=${ANSWER});
Далее, в примере CDR содержимое полученного значения переменной будет продемонстрировано.
Ниже два примера скрипта написанные на bash и Python3, скрипты передают номера и возвращают в дайлплан результат.
#cat /var/lib/asterisk/agi-bin/get-res.sh

1
2
3
4
5
6
7
8
#!/bin/bash
 
res=`curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d"user_phone=$1&gw_phone=$2" http://wfff-loginpage:8008/ivr_auth| sed -n 's/^.*resultCode=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
 
echo $res
echo -e "SET VARIABLE RES $res";
sleep 0
exit 0

Здесь я использовал консольную утилиту curl для http запроса на сервер авторизации. Кстати, последняя строчка exit 0, иначе в консоли Asterisk будут появляться ошибки результаты работы AGI-скрипта.
Ниже аналогичный скрипт на языке Python3, который я использовал в «боевой» конфигурации.

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
 
import requests
from sys import argv
user_phone,gw_phone = argv[1:]
answer = requests.post('http://wfff-loginpage:8008/ivr_auth',headers={'Content-Type': 'application/x-www-form-urlencoded'},data={'user_phone': user_phone,'gw_phone': gw_phone})
#res='resultCode=0&resultMessage=rejected'
answer=str(answer.content)
print("SET VARIABLE RES %s" % answer[13] +"\n"+"SET VARIABLE ANSWER %s" % answer)

Здесь я использовал отличный модуль для http запросов requests. На этом настройка Asterisk закончена.

В CDR вызовы будут выглядеть так:

1
2
3
"","+00000637658","sw_5_0","FIFA-IN",""""" <+00000637658>","SIP/FIFA-1-000034c0","","Busy","10","2018-07-15 18:54:34",,"2018-07-15 18:54:41",7,0,"BUSY","DOCUMENTATION","1531670074.27007","b'resultCode=0&amp;amp;resultMessage=rejected'"
 
"","79060003159","sw_4_1","FIFA-IN",""""" <79060003159>","SIP/FIFA-2-000034c1","","Busy","10","2018-07-15 18:55:22",,"2018-07-15 18:55:31",8,0,"BUSY","DOCUMENTATION","1531670122.27010","b'resultCode=1&amp;amp;resultMessage=accepted'"

По мониторингу Asterisk использую следующие основные параметры, ниже пример конфигурации для Zabbix файл /etc/zabbix/zabbix_agentd.conf в UserParameter:

1
2
3
4
5
6
7
### Option: UserParameter
#Текущие вызовы
UserParameter=asterisk.core.show.calls,/usr/bin/sudo /usr/sbin/asterisk -rx 'core show calls' | grep active| awk '{print $1}'
#Текущие каналы SIP
UserParameter=asterisk.sip.show.channels,/usr/bin/sudo /usr/sbin/asterisk -rx 'sip show channels' | grep "active SIP dialog" | awk '{print $1}'
#Обработанные звонки, накопительный счётчик
UserParameter=asterisk.sip.show.calls.processed,/usr/bin/sudo /usr/sbin/asterisk -rx 'core show calls' | grep processed | awk '{print $1}'

Медиасервер Freeswitch

IP-адрес=192.168.25.32
У Freeswitch есть встроенный модуль curl.
Нам надо добавить модуль mod_curl поэтому, при компиляции снимаем комментарий с требуемых модулей в
/usr/src/freeswitch/modules.conf

1
2
languages/mod_python
applications/mod_curl

Сохраняем. Запускаем конфигурацию сбоку и инсталляцию ещё раз:

1
2
3
./configure
make
make install

Теперь в конфигурационных файлах Freeswtich /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml, удаляем комментарии:

1
2
<load module="mod_curl"/>
<load module="mod_python"/>

Проверим что модуль есть:

1
2
3
4
5
6
#fs_cli
$fs_cli
freeswitch@FS1.6> module_exists mod_python
true
freeswitch@FS1.6> module_exists mod_curl
true

В файле можно /freeswitch/conf/autoload_configs/switch.conf.xml можно увеличить данные параметры:

1
2
3
4
5
<param name="max-sessions" value="1000"/>
    <!--Most channels to create per second -->
    <param name="sessions-per-second" value="30"/>
    <!-- Default Global Log Level - value is one of debug,info,notice,warning,err,crit,alert -->
    <param name="loglevel" value="debug"/>

Внешние каналы SIP, добавим новый профиль:

1
#touch /freeswitch/conf/sip_profiles/fifa.xml

Добавим в файл следующие строки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<settings>
    <param name="debug" value="0"/>
    <param name="sip-trace" value="no"/>
    <param name="sip-capture" value="no"/>
    <param name="rfc2833-pt" value="101"/>
    <param name="sip-port" value="$${external_sip_port}"/>
    <param name="dialplan" value="XML"/>
    <param name="context" value="fifa"/>
    <param name="dtmf-duration" value="2000"/>
    <param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
    <param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/>
    <param name="hold-music" value="$${hold_music}"/>
    <param name="rtp-timer-name" value="soft"/>
    <param name="local-network-acl" value="localnet.auto"/>
    <param name="manage-presence" value="false"/>
  <param name="rtp-ip" value="192.168.25.32"/>
    <param name="sip-ip" value="192.168.25.32"/>
  </settings>

Значение $${external_sip_port} это глобальный параметр, его значение указано в /freeswitch/conf/vars.xml, и выглядит так: external_sip_port=5080.

Запустим наш новый профиль:

1
2
3
freeswitch@wfff-media2> sofia profile fifa start
Reload XML [Success]
fifa started successfully

В консоли Linux, проверим, что IP и порт прослушивает Freeswitch:

1
2
3
root@wfff-media2:/freeswitch/conf/sip_profiles# netstat -anp | grep 5080
tcp        0      0 192.168.25.32:5080      0.0.0.0:*               LISTEN      5499/freeswitch
udp        0      0 192.168.25.32:5080      0.0.0.0:*                           5499/freeswitch

Теперь переходим к настройке дайлплана, файл /freeswitch/conf/dialplan/fifa.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<include>
  <context name="fifa">
<extension name="FIFA_NUM_POOL" continue="true">
    <condition field="destination_number" expression="^(.*)$">
            <action application="curl" data="http://wfff-loginpage:8008/ivr_auth content-type 'application/x-www-form-urlencoded' post user_phone=${caller_id_number}&amp;amp;gw_phone=${destination_number:1}" inline="true"/>
            <!--action application="set" data="answer=resultCode=0&amp;amp;resultMessage=rejected"/-->
            <!--action application="set" data="respdata=${curl_response_data}"/-->
            <action application="set" data="result=${curl_response_data:11:1}" inline="true"/>
            <action application="log" data="INFO result is ${result}" inline="true"/>
    </condition>
    <condition field="destination_number" expression="^78120002915$" break="on-true">   <!-- Russian -->
        <action application="log" data="ANI NUMBER IS ${ani} "/>
        <action application="log" data="78120002915 WARNING RESULT IS ${result} "/>
        <action application="pre_answer"/>
        <action application="playback" data="${cond(${result} == 1 ? /usr/local/freeswitch/sounds/fifa/success_readyRUS1.wav : /usr/local/freeswitch/sounds/fifa/Fail_RUS1.wav)}"/>
        <action application="sleep" data="3000"/>
        <action application="hangup" data="USER_BUSY"/>
    </condition>
        <condition field="destination_number" expression="^78120002916$" break="on-true"> <!-- English -->
        <action application="log" data="RESULT IS ${result} "/>
        <action application="pre_answer"/>
        <action application="playback" data="${cond(${result} == 1 ? /usr/local/freeswitch/sounds/fifa/Success_readyEN1.wav : /usr/local/freeswitch/sounds/fifa/Fail_EN1.wav"/>
        <action application="hangup" data="USER_BUSY"/>
    </condition>
 </context>
 </include>

Затем перезагружаем дайлплан:

1
2
3
4
5
freeswitch@wfff-media2> reloadxml
+OK [Success]
 
2019-02-22 13:32:23.277861 [INFO] mod_enum.c:879 ENUM Reloaded
2019-02-22 13:32:23.277861 [INFO] switch_time.c:1423 Timezone reloaded 1750 definitions

Всё, на этом настройка закончена.

Что происходит в дайлплан?

В модуль SIP медиасервера Freeswitch (использует Sofia) приходит вызов, в соответствии с созданным sip профилем FIFA вызов направляется в контекст fifa для обработки.
Контекст fifa содержит единственный эктеншен с именем FIFA_NUM_POOL. В первое условие(condition) содержит правило

1
<condition field="destination_number" expression="^(.*)$">

Поэтому туда попадает любой позвонивший пользователь. Начинается первая фаза ROUTING – формирования найденного по совпавшим в условиям списка действий(actions) TODO. Значение break в первом условии (condition) отсутствует, это равно break=”on-false”, то есть
не проверять следующее условие condition, если это условие ложно, но оно всегда в нашем случае истинно. Далее, проверяются остальные условия conditions которые содержат 5 номеров, соответствующих языку, на котором воспроизводятся голосовые подсказки, в примере я показываю только два номера 78120002915 и 78120002916. Когда условие по номеру позвонившего или destination_number совпадает с набранным пользователем номером, срабатывает директива break=»on-true», что значит прервать просмотр условий (condition)и запустить те условия, которые совпали. То есть первое и второе, одно из пяти. Причём условия как бы стекируются и связаны межу собой оператором И(AND).
Список на выполнение или TODO список действии(action) составлен, начинается фаза выполнения State EXECUTE.
Запускается первое приложение curl:

1
<action application="curl" data="http://wfff-loginpage:8008/ivr_auth content-type 'application/x-www-form-urlencoded' post user_phone=${caller_id_number}&amp;amp;gw_phone=${destination_number:1}"/>

Мы отправляем сообщение POST в формате JSON номер звонящего и номер телефона на который позвонили, при этому удаляем первую цифру номера.
В ответ получаем ответ, наподобие

1
resultCode=1&amp;amp;resultMessage=accepted

Приложение curl возвращает результа в стандартную переменную curl_response_data
Так как интересующее нас значение находится в 11 символе, извлечём её при помощи конструкции

1
<action application="set" data="result=${curl_response_data:11:1}" inline="true"/>

и присвоим переменной result.
Здесь запускается приложение curl, которое проверяет телефонный номер и возвращает результат в переменную ${result}. Далее, выполняются действия из второго найденного условия, во-первых

1
<action application="pre_answer"/>

означает что мы будем проигрывать сообщение в предответном состоянии, без начала тарификации.
Следующее действие:

1
<action application="playback" data="${cond(${result} == 1 ? /usr/local/freeswitch/sounds/fifa/success_readyRUS1.wav : /usr/local/freeswitch/sounds/fifa/Fail_RUS1.wav)}"/>

Тут мы воспроизводим файл success_readyRUS1.wav, если значение переменной ${result}=1 или файл Fail_RUS1.wav в противном случае.
Сследующие действия:

1
2
<action application="sleep" data="3000"/>
<action application="hangup" data="USER_BUSY"/>

Ждём 3000 миллисекунд и запускаем приложение «отбой» с кодом USER_BUSY или SIP 486.
Результат в CDR Freeswitch представлен ниже.
Если абонент авторизован:

1
"70002783772","70002783772","78120002915","fifa","2018-07-17 13:40:58","","2018-07-17 13:41:05","7","0","ORIGINATOR_CANCEL","c6337123-7a94-4ba2-96ee-17d00d2e460b","","","PCMA","PCMA","resultCode=1&amp;amp;resultMessage=accepted"

Если абоненту отказано в авторизации:

1
"70002254963","70002254963","78120002918","fifa","2018-07-17 17:13:23","","2018-07-17 17:13:34","11","0","USER_BUSY","854529fc-62c6-479a-8c10-4c639fa624d9","","","PCMA","PCMA","resultCode=0&amp;amp;resultMessage=rejected"

Как видно, в cdr отображается содержимое переменной ${curl_response_data}

Чтобы добавить её в CDR, нужно сделать следующее:

Открыть на редактирование файл /usr/local/freeswitch/conf/autoload_configs/cdr_csv.conf.xml, далее, смотрим какой используется темплейт для CDR:

1
<param name=«default-template» value=«example»/>

Затем, в

1
<template name=«example»>

добавляем в конце по образцу «${curl_response_data}»
Получится:

1
<template name="example">"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}","${curl_response_data}"</template>

Сохраняем.

Затем делаем перезагрузку модуля из fs_cli

1
freeswitch@debian8> reload mod_cdr_csv

Ниже лог примера выполнения дайлплана Freeswitch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
====Вызов пришёл в модуль Sofia SIP====
 
2019-02-22 17:38:40.497865 [NOTICE] switch_channel.c:1104 New Channel sofia/fifa/79500090900@192.168.25.9 [dac48249-f16f-4026-b176-d29d0719b8dc]
2019-02-22 17:38:40.497865 [DEBUG] switch_core_state_machine.c:584 (sofia/fifa/79500090900@192.168.25.9) Running State Change CS_NEW (Cur 1 Tot 13675)
2019-02-22 17:38:40.497865 [DEBUG] sofia.c:9873 sofia/fifa/79500090900@192.168.25.9 receiving invite from 192.168.25.9:5060 version: 1.6.20 git 43a9feb 2018-05-07 18:56:11Z 64bit
2019-02-22 17:38:40.497865 [DEBUG] sofia.c:7084 Channel sofia/fifa/79500090900@192.168.25.9 entering state [received][100]
2019-02-22 17:38:40.497865 [DEBUG] sofia.c:7094 Remote SDP:
v=0
o=- 1060 847210 IN IP4 192.168.25.9
s=SMG SIP session
c=IN IP4 192.168.25.9
t=0 0
m=audio 25862 RTP/AVP 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=ptime:20
 
2019-02-22 17:38:40.497865 [DEBUG] sofia.c:7486 (sofia/fifa/79500090900@192.168.25.9) State Change CS_NEW -> CS_INIT
2019-02-22 17:38:40.497865 [DEBUG] switch_core_state_machine.c:603 (sofia/fifa/79500090900@192.168.25.9) State NEW
2019-02-22 17:38:40.497865 [DEBUG] switch_core_state_machine.c:584 (sofia/fifa/79500090900@192.168.25.9) Running State Change CS_INIT (Cur 1 Tot 13675)
2019-02-22 17:38:40.497865 [DEBUG] switch_core_state_machine.c:627 (sofia/fifa/79500090900@192.168.25.9) State INIT
2019-02-22 17:38:40.497865 [DEBUG] mod_sofia.c:90 sofia/fifa/79500090900@192.168.25.9 SOFIA INIT
2019-02-22 17:38:40.497865 [DEBUG] switch_core_state_machine.c:40 sofia/fifa/79500090900@192.168.25.9 Standard INIT
2019-02-22 17:38:40.497865 [DEBUG] switch_core_state_machine.c:48 (sofia/fifa/79500090900@192.168.25.9) State Change CS_INIT -> CS_ROUTING
2019-02-22 17:38:40.497865 [DEBUG] switch_core_state_machine.c:627 (sofia/fifa/79500090900@192.168.25.9) State INIT going to sleep
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:584 (sofia/fifa/79500090900@192.168.25.9) Running State Change CS_ROUTING (Cur 1 Tot 13675)
2019-02-22 17:38:40.517818 [DEBUG] switch_channel.c:2249 (sofia/fifa/79500090900@192.168.25.9) Callstate Change DOWN -> RINGING
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:643 (sofia/fifa/79500090900@192.168.25.9) State ROUTING
2019-02-22 17:38:40.517818 [DEBUG] mod_sofia.c:143 sofia/fifa/79500090900@192.168.25.9 SOFIA ROUTING
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:236 sofia/fifa/79500090900@192.168.25.9 Standard ROUTING
2019-02-22 17:38:40.517818 [INFO] mod_dialplan_xml.c:637 Processing 79500090900 <79500090900>->78120002915 in context fifa
 
=== Вызов ушёл в контекст fifa =====
 
Dialplan: sofia/fifa/79500090900@192.168.25.9 parsing [fifa->FIFA_NUM_POOL] continue=false
Dialplan: sofia/fifa/79500090900@192.168.25.9 Regex (PASS) [FIFA_NUM_POOL] destination_number(78120002915) =~ /^(.*)$/ break=on-false
 
===Условие сработало, добавить действия в этом условии в TODO список, фаза 1 ===
 
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action curl(http://wfff-loginpage:8008/ivr_auth content-type 'application/x-www-form-urlencoded' post user_phone=${caller_id_number}&amp;amp;gw_phone=${destination_number:1})
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action set(result=${curl_response_data:11:1})
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action log(INFO result is ${result})
Dialplan: sofia/fifa/79500090900@192.168.25.9 Regex (FAIL) [FIFA_NUM_POOL] ani(79500090900) =~ /^71110007780$/ break=on-true
Dialplan: sofia/fifa/79500090900@192.168.25.9 Regex (PASS) [FIFA_NUM_POOL] destination_number(78120002915) =~ /^78120002915$/ break=on-true
 
===Условие destination_number(78120002915)  сработало, добавить действия в этом условии в TODO список, другие условия проверяться не будут так как установлено break=on-true ===
 
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action log(ANI NUMBER IS ${ani} )
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action log(78120002915 WARNING RESULT IS ${result} )
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action pre_answer()
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action playback(${cond(${result} == 1 ?  /usr/local/freeswitch/sounds/fifa/success_readyRUS1.wav : /usr/local/freeswitch/sounds/fifa/Fail_RUS1.wav)})
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action sleep(3000)
Dialplan: sofia/fifa/79500090900@192.168.25.9 Action hangup(USER_BUSY)
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:286 (sofia/fifa/79500090900@192.168.25.9) State Change CS_ROUTING -> CS_EXECUTE
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:643 (sofia/fifa/79500090900@192.168.25.9) State ROUTING going to sleep
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:584 (sofia/fifa/79500090900@192.168.25.9) Running State Change CS_EXECUTE (Cur 1 Tot 13675)
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:650 (sofia/fifa/79500090900@192.168.25.9) State EXECUTE
2019-02-22 17:38:40.517818 [DEBUG] mod_sofia.c:198 sofia/fifa/79500090900@192.168.25.9 SOFIA EXECUTE
2019-02-22 17:38:40.517818 [DEBUG] switch_core_state_machine.c:328 sofia/fifa/79500090900@192.168.25.9 Standard EXECUTE
 
====Начало запуска условии в состоянии EXECUTE, фаза 2. Выполняются действия из совпавших условий.
 
EXECUTE sofia/fifa/79500090900@192.168.25.9 curl(http://wfff-loginpage:8008/ivr_auth content-type 'application/x-www-form-urlencoded' post user_phone=79500090900&amp;amp;gw_phone=8120002915)
2019-02-22 17:38:40.517818 [DEBUG] mod_curl.c:182 method: post, url: http://wfff-loginpage:8008/ivr_auth, content-type: application/x-www-form-urlencoded
2019-02-22 17:38:40.517818 [DEBUG] mod_curl.c:211 Post data: user_phone=79500090900&amp;amp;gw_phone=8120002915
EXECUTE sofia/fifa/79500090900@192.168.25.9 set(result=0)
 
=== От curl получен результат 0 ===
 
2019-02-22 17:38:40.557875 [DEBUG] mod_dptools.c:1548 SET sofia/fifa/79500090900@192.168.25.9 [result]=[0]
EXECUTE sofia/fifa/79500090900@192.168.25.9 log(INFO result is 0)
2019-02-22 17:38:40.557875 [INFO] mod_dptools.c:1742 result is 0
EXECUTE sofia/fifa/79500090900@192.168.25.9 log(ANI NUMBER IS 79500090900 )
2019-02-22 17:38:40.557875 [DEBUG] mod_dptools.c:1742 NUMBER IS 79500090900
EXECUTE sofia/fifa/79500090900@192.168.25.9 log(78120002915 WARNING RESULT IS 0 )
EXECUTE sofia/fifa/79500090900@192.168.25.9 pre_answer()
 
=== Состояние предответа ===
 
2019-02-22 17:38:40.557875 [INFO] mod_dptools.c:1355 Sending early media
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[opus:116:48000:20:0:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[G722:9:8000:20:64000:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMU:0:8000:20:64000:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMA:8:8000:20:64000:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4504 Audio Codec Compare [PCMA:8:8000:20:64000:1] ++++ is saved as a match
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMU:0:8000:20:64000:1]/[opus:116:48000:20:0:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMU:0:8000:20:64000:1]/[G722:9:8000:20:64000:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMU:0:8000:20:64000:1]/[PCMU:0:8000:20:64000:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4504 Audio Codec Compare [PCMU:0:8000:20:64000:1] ++++ is saved as a match
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4449 Audio Codec Compare [PCMU:0:8000:20:64000:1]/[PCMA:8:8000:20:64000:1]
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:3061 Set Codec sofia/fifa/79500090900@192.168.25.9 PCMA/8000 20 ms 160 samples 64000 bits 1 channels
2019-02-22 17:38:40.557875 [DEBUG] switch_core_codec.c:111 sofia/fifa/79500090900@192.168.25.9 Original read codec set to PCMA:8
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4738 No 2833 in SDP. Liberal DTMF mode adding 101 as telephone-event.
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:4767 sofia/fifa/79500090900@192.168.25.9 Set 2833 dtmf send payload to 101 recv payload to 101
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:6878 AUDIO RTP [sofia/fifa/79500090900@192.168.25.9] 192.168.25.32 port 16452 -> 192.168.25.9 port 25862 codec: 8 ms: 20
2019-02-22 17:38:40.557875 [DEBUG] switch_rtp.c:4137 Starting timer [soft] 160 bytes per 20ms
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:7180 sofia/fifa/79500090900@192.168.25.9 Set 2833 dtmf send payload to 101
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:7187 sofia/fifa/79500090900@192.168.25.9 Set 2833 dtmf receive payload to 101
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:7210 sofia/fifa/79500090900@192.168.25.9 Set rtp dtmf delay to 40
2019-02-22 17:38:40.557875 [NOTICE] sofia_media.c:92 Pre-Answer sofia/fifa/79500090900@192.168.25.9!
2019-02-22 17:38:40.557875 [DEBUG] switch_channel.c:3474 (sofia/fifa/79500090900@192.168.25.9) Callstate Change RINGING -> EARLY
2019-02-22 17:38:40.557875 [DEBUG] switch_core_media.c:6861 Audio params are unchanged for sofia/fifa/79500090900@192.168.25.9.
2019-02-22 17:38:40.557875 [DEBUG] mod_sofia.c:2364 Ring SDP:
v=0
o=FreeSWITCH 1550829868 1550829869 IN IP4 192.168.25.32
s=FreeSWITCH
c=IN IP4 192.168.25.32
t=0 0
m=audio 16452 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=sendrecv
 
=== Начало проигрывания звукового файла Fail_RUS1.wav ===
 
EXECUTE sofia/fifa/79500090900@192.168.25.9 playback(/usr/local/freeswitch/sounds/fifa/Fail_RUS1.wav)
2019-02-22 17:38:40.557875 [DEBUG] sofia.c:7084 Channel sofia/fifa/79500090900@192.168.25.9 entering state [early][183]
2019-02-22 17:38:40.557875 [DEBUG] switch_ivr_play_say.c:1498 Codec Activated L16@8000hz 1 channels 20ms
2019-02-22 17:38:40.657867 [DEBUG] switch_rtp.c:7308 Correct audio ip/port confirmed.
2019-02-22 17:38:49.677867 [DEBUG] sofia.c:7084 Channel sofia/fifa/79500090900@192.168.25.9 entering state [terminated][487]
2019-02-22 17:38:49.677867 [NOTICE] sofia.c:8273 Hangup sofia/fifa/79500090900@192.168.25.9 [CS_EXECUTE] [ORIGINATOR_CANCEL]
2019-02-22 17:38:49.677867 [DEBUG] switch_ivr_play_say.c:1942 done playing file /usr/local/freeswitch/sounds/fifa/Fail_RUS1.wav
2019-02-22 17:38:49.677867 [DEBUG] switch_core_session.c:2815 sofia/fifa/79500090900@192.168.25.9 skip receive message [APPLICATION_EXEC_COMPLETE] (channel is hungup already)
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:650 (sofia/fifa/79500090900@192.168.25.9) State EXECUTE going to sleep
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:584 (sofia/fifa/79500090900@192.168.25.9) Running State Change CS_HANGUP (Cur 1 Tot 13675)
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:850 (sofia/fifa/79500090900@192.168.25.9) Callstate Change EARLY -> HANGUP
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:852 (sofia/fifa/79500090900@192.168.25.9) State HANGUP
2019-02-22 17:38:49.677867 [DEBUG] mod_sofia.c:438 Channel sofia/fifa/79500090900@192.168.25.9 hanging up, cause: ORIGINATOR_CANCEL
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:60 sofia/fifa/79500090900@192.168.25.9 Standard HANGUP, cause: ORIGINATOR_CANCEL
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:852 (sofia/fifa/79500090900@192.168.25.9) State HANGUP going to sleep
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:619 (sofia/fifa/79500090900@192.168.25.9) State Change CS_HANGUP -> CS_REPORTING
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:584 (sofia/fifa/79500090900@192.168.25.9) Running State Change CS_REPORTING (Cur 1 Tot 13675)
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:938 (sofia/fifa/79500090900@192.168.25.9) State REPORTING
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:174 sofia/fifa/79500090900@192.168.25.9 Standard REPORTING, cause: ORIGINATOR_CANCEL
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:938 (sofia/fifa/79500090900@192.168.25.9) State REPORTING going to sleep
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:610 (sofia/fifa/79500090900@192.168.25.9) State Change CS_REPORTING -> CS_DESTROY
2019-02-22 17:38:49.677867 [DEBUG] switch_core_session.c:1665 Session 13675 (sofia/fifa/79500090900@192.168.25.9) Locked, Waiting on external entities
2019-02-22 17:38:49.677867 [NOTICE] switch_core_session.c:1683 Session 13675 (sofia/fifa/79500090900@192.168.25.9) Ended
2019-02-22 17:38:49.677867 [NOTICE] switch_core_session.c:1687 Close Channel sofia/fifa/79500090900@192.168.25.9 [CS_DESTROY]
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:741 (sofia/fifa/79500090900@192.168.25.9) Running State Change CS_DESTROY (Cur 0 Tot 13675)
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:751 (sofia/fifa/79500090900@192.168.25.9) State DESTROY
2019-02-22 17:38:49.677867 [DEBUG] mod_sofia.c:343 sofia/fifa/79500090900@192.168.25.9 SOFIA DESTROY
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:181 sofia/fifa/79500090900@192.168.25.9 Standard DESTROY
2019-02-22 17:38:49.677867 [DEBUG] switch_core_state_machine.c:751 (sofia/fifa/79500090900@192.168.25.9) State DESTROY going to sleep

По мониторингу Freeswitch использую следующие основные параметры, ниже пример конфигурации для Zabbix файл /etc/zabbix/zabbix_agentd.conf в UserParameter :

1
2
3
4
5
6
7
8
9
### Option: UserParameter
####Channel count
UserParameter=fs.channels.count.current, /usr/local/freeswitch/bin/fs_cli -x "show channels count" | grep total | awk {'print $1'}
UserParameter=fs.channels.count.max.5.min, /usr/local/freeswitch/bin/fs_cli -x "status" | grep 'session(s) - peak' |  awk '{print $8}'
####CPS count
UserParameter=fs.cps.count.current, /usr/local/freeswitch/bin/fs_cli -x "status" | grep ' session(s) - peak' | awk '{print $1}'
UserParameter=fs.cps.count.max.5.min,/usr/local/freeswitch/bin/fs_cli -x "status" | grep 'session(s) per Sec out of max' | awk '{print $13}'
###Sessions count since startup
UserParameter=fs.sessions.count.since.startup,/usr/local/freeswitch/bin/fs_cli -x "status" | grep "session(s) since startup" | awk {'print $1'}

Итог

Для задачи авторизации в сети Wi-Fi по звонку отлично подойдёт любое из решений, Asterisk проще в конфигурировании, Freeswitch несколько сложнее, зато у него есть модуль curl и не нужно вызывать внешний скрипт, но скрипт написать не сложно. По производительности я не заметил разницы, наверное, потому что нагрузка была не существенная. Вот по качеству воспроизведения подсказок, по моей субъективной оценке, Freeswtich звучал лучше. По отладке и мониторингу, больше нравится Freeswitch, потому что логичнее и понятнее сообщения Freeswitch, также можно мониторить больше переменных, особенно порадовало наличие параметра Call per Second(CPS). В целом, по логической организации Freeswitch тоже больше нравится, но xml конфигурация Freeswtich несколько сложнее для восприятия, чем язык ael дайлплана Astersik, хотя со временем чтение и написание xml не вызывает никаких сложностей.

Автор: Игнат Кудрявцев

Tags: ,

Оставить комментарий

Напишите Ваш комментарий ниже. Также Вы можете подписаться на комментарии к материалу через RSS

Вы можете использовать следующие теги:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

Мы поддерживаем Gravatar.

Контроль спама: *