VoIP

Для IP-телефонии критичны задержки пакетов в сети, хотя технология обладает некоей толерантностью (устойчивостью) к потерям отдельных пакетов. Так, потеря до 5 % пакетов не приводит к ухудшению разборчивости речи. Максимальное отклонение между последовательной передачей пакетов в сети Интернет не должны превышать 50 мс. Максимальный процент потерь при передачи пакетов в сети Интернет – не более 3%.

Причины задержек в передаче голосовых данных по сети IP в большой степени связаны с особенностями транспорта пакетов. Протокол TCP обеспечивает контроль доставки пакетов, однако достаточно медленный и потому не используется для передачи голоса. UDP быстро отправляет пакеты, однако восстановление потерянных данных не гарантируется, что приводит к потерянным частям разговора при восстановлении (обратном преобразовании) звука. Немалые проблемы приносит джиттер (отклонения в периоде поступления-приёмки пакетов), появляющийся при передаче через большое число узлов в нагруженной IP-сети. Недостаточно высокая пропускная способность сети (например при одновременной нагрузке несколькими пользователями), серьёзно влияет не только на задержки (то есть рост джиттера), но и приводит к большим потерям пакетов.

Между конечными точками пользователей и серверами IP-телефонии, а также между серверами IP-телефонии и оборудованием оператора связи (поставщика VoIP) программных или аппаратных устройств, канал должен отвечать описанным выше требованиям.

Проверить пропускную способность каналов можно с помощью простой утилиты iperf-2.0.5. Предположим, что мы хотим гарантировать 10 одновременных разговоров с использованием G.711 кодека. Рекомендуемое требование к каналу составляет 1 Мбит/с.

На сервере запускаем iperf с параметрами (ожидать на стандартном порте 5001 входящие UDP запросы):
iperf -u -s

На клиенте запускаем тестирование UDP c длиной 160 байт со скоростью 1 Мбит/с в течение 180 секунд на сервер 10.10.10.119:
iperf -u -c 10.10.10.119 -l 160 -b 1M -t 180

Получаем результат:

Канал пригоден для 10 одновременных соединений.

Icons_39x39_RoutingВ разделе [Маршрутизация] мы можем указать префикс для набранного направления либо несколько префиксов через разделитель «|». К примеру, что бы указать выбор направлений на оператора Life, можем задать: 063|093. Но, что делать, если наши пользователи не придерживаются стандарта? А могут набрать номер того же Life в несколько способов: +38063 , 38063, 8063 или 063.

«Можно создать сразу 4 маршрута», — скажите Вы.
«Достаточно создать только 1 маршрут», — отвечу я 🙂

Для этого воспользуемся регулярными выражениями. В системных настройках Terrasoft, активируйте ключ «WebitelConfigExpertMode»:

WebitelConfigExpertMode

Перезапустите Terrasoft. Теперь в настройках Маршрутизации мы можем использовать регулярные выражения. Все наши 4 варианта можно прописать одной строкой:

Life_RegExp

Обратите внимание! Теперь в направлениях у Вас будет открыт доступ к управлению того, что надо отдавать на шлюз. Здесь достаточно указать сколько последних цифр из выражения отправлять. Если нам не нужны с Life «+38», тогда поставим просто 10 — десять последних знаков в строке. Выглядит это так:

Dialplan

В переменной ${destination_number} храниться то, что набрал пользователь. Из этой переменной я вырезаю 10 последних цифр: (\d{10})$ и результат возвращаю в первую переменную канала (то, что пойдет к оператору): %1

FreeSWITCHИнтересной функцией для офисной АТС может стать отправка SMS сотруднику о пропущенном звонке. Я опишу, как реализовать этот функционал на FreeSWITCH.

1. Формат SMS
Мой SMS провайдер принимает сообщения через HTTP XML API. Мне необходимо будет сформировать XML файл и передать его методом POST на URL шлюза. Использовать будем модуль mod_curl. Здесь проблем нет. Только нужна будет функция для преобразования XML в urlencode…

2. Когда и куда отправлять
Что бы ответить на вопрос куда отправить, в directory я к регистрации каждого сотрудника добавил переменную cell с мобильным. Теперь из скрипта можно будет получить эту информацию. А когда отправлять? Здесь 2 проверки:
1. причина разрыва коммутации «ORIGINATOR_CANCEL»
2. возможно абонент Вам оставил голосовое сообщение?

3. Как вызвать скрипт?
Из dialplana 🙂 Просто добавьте вот такой action в extension с локальными пользователями:

4. А теперь сам скрипт на Lua

local send = false
local cell = env:getHeader("cell")
local hangup_cause = env:getHeader("hangup_cause")
local bridge_channel = env:getHeader("bridge_channel")
local CallerName = env:getHeader("Caller-Caller-ID-Name")
local CallerNumber = env:getHeader("Caller-Caller-ID-Number")

function urlencode (s)
 return (string.gsub (s, "%W",
        function (str)
                return string.format ("%%%02X", string.byte (str) )
        end ))
end

local SMS = ' \
 \
'

if (hangup_cause == "ORIGINATOR_CANCEL" and cell) then
        SMS = SMS.. "Вам звонили: " ..CallerName.. " " .. CallerNumber
        send = true
end

if (bridge_channel == "loopback/voicemail-a" and cell) then
        SMS = SMS.. "Новое сообщение от " ..CallerName.. " " .. CallerNumber
        send = true
end

if (send) then
        SMS = SMS.. ""
        api = freeswitch.API();
        local response = api:execute("curl", "http://sms.it-sfera.com/websend/ post " ..urlencode(SMS) )
        freeswitch.consoleLog("DEBUG","Here's response:\n" .. response .. "\n")
end

5. О, sms-ка пришла!

У Вас пропущенный звонок!
У Вас пропущенный звонок!

Недавно мне задали вопрос: «Как можно с помощью FreeSWITCH сделать рассылку факсов по списку номеров?» Я набросаю ключевые пункты, как это сделать.

Во-первых, у Вас должна быть какая-то SQL база со списком номеров. К примеру, берем MySQL с одной табличкой fax, где находиться колонка distination.

Во-вторых, файл, который будем отправлять. Что бы привести его в пригодный нам формат, воспользуемся утилитой convert:

convert -density 204x98 -units PixelsPerInch -resize 1728x1186\! -monochrome -compress Fax my-fax-file.pdf /opt/freeswitch/storage/fax_out/01.tif

В-третьих, напишем LUA-скрипт scripts/send_fax.lua, который будет лезть в базу, выбирать номер и отправлять наш файлик:

local fax_file = "/opt/freeswitch/storage/fax_out/01.tif"

local dbh = freeswitch.Dbh("dsn", "user", "password")
if dbh:connected() then
        freeswitch.consoleLog("NOTICE", "database connected\n")
else
        freeswitch.consoleLog("ERR", "database error\n")
    return
end

local my_query = "select distination from fax "

assert(dbh:query(my_query, function(row)
        freeswitch.consoleLog("NOTICE", "\nSending FAX to " ..row.distination.. "\n")
        send_fax = "originate sofia/gateway/farlep/" ..row.distination.. " &txfax(" ..fax_file.. ")"
        api = freeswitch.API()
        reply = api:executeString(send_fax)
        freeswitch.consoleLog("DEBUG", "\nSending " ..reply.. "\n")
end))

Теперь можем просто из консоли FreeSWITCH выполнить скрипт:

luarun send_fax.lua

Дальше, приправляем на свой вкус: записать результат отправки в базу или еще чего….

Говорим мы сегодня о конференциях: ClueCon, ElastixWorld и AstriCon. Что новое мы увидим в Asterisk 11.0. А так же, много слов о вебе и телефонии: Websocket и WebRTC — будущие веб-телефонии!

Начиная с 4 выпуска у нас будут подарки за лучший вопрос в podcast! Детали в этом выпуске.

Прочитал статью на habrahabr.ru и решил проверить у себя. Вот запись аудио: message.mp3, а вот что пришло на мыло:

добрый день александр трофименко игра 1000 для работы я не могу дойти до 120 инуяша телефону номер
для девчонок которая 3 3 3 он метро смоленская

Прочитав такое, я все равно буду слушать запись 🙂

Все знают о возможности «подслушивать» телефонные разговоры. А как Вам вариант слушать разговор в любимом медиаплеере, как обычное аудио вещание в сети? Оказывается, во FreeSWITCH это возможно! Все, что Вам нужно — включить модуль Mod_shout (о котором я уже писал). С модулем становиться доступная функция telecast . Через webAPI (по адресу http://<Ваш_Сервер>:8080/webapi/telecast/index) Вы сможете увидеть список текущих разговоров:

И открыть выбранный разговор в плеере: