четверг, 24 декабря 2015 г.

Проверка качества звука в звонках

Есть готовые решения, типа
http://sevana.biz/

"Из коробки", но стоит денег.

PESQ, Perceptual Evaluation of Speech Quality, is a family of standards comprising a test methodology for automated assessment of the speech quality as experienced by a user of a telephony system. It is standardised as ITU-T recommendation P.862 (02/01). Today, PESQ is a worldwide applied industry standard for objective voice quality testing used by phone manufacturers, network equipment vendors and telecom operators. Its usage requires a license.
https://en.wikipedia.org/wiki/PESQ
Требует лицензии, но для тестов есть варианты на гитхабе. Помним, что лицензия всё-равно нужна. Пример
https://github.com/dennisguse/ITU-T_pesq

Также можно почитать
https://txlab.wordpress.com/2015/06/02/quality-assurance-for-voip-calls-2/

Если нужно просто оценинть пригодность каналов - можно взять 2 сервера с этим каналом посередине, заслать некий файл, захватывая rtp пакеты, и потом оценить, сколько потеряно, сколько побито. Метод совсем грубый и не подходит для анализа сервер-клиент, только если на сервере делать эхо, чтобы клиент мог проверить именно свой канал.

Более правильный метод - частотный анализ. Тот же PESQ или своя реализация. Тогда можно проверить уже поставщиков телефонии, даже с учётом перекодирований, E1 по пути и прочего, но это совсем другая сложность. Требуются исходный и конечный файлы.

Отдельно - звонок клиент-АТС-клиент, для частотного анализа тут просто нет 2 точек и если мало джиттера и потерь, снимаемых с rtp, начинается совсем магия, поиск характерных признаков - шипения, шумов, провалов...

Ну и остаётся субъективный анализ - звонок человеком.
Средняя экспертная оценка MOS (Mean Opinion Score) — это субъективное измерение, определенное в рекомендации P.800 МСЭ-Т для оценки качества передачи в телефонных сетях.
http://habrahabr.ru/post/177099/
ну и саму статью почитать стоит.

четверг, 5 ноября 2015 г.

проверяем и синхронизируем даты и время

После ntpdate pool.ntp.org обнаружили неприятную "особенность" - апи стало работать с новым временем, а FS - по прежнему использует старое. Впрочем, правится тоже несложно: из апи или консоли
fsctl sync_clock
или
fsctl sync_clock_when_idle

Для проверки можно использовать такой скрипт:
check-time.py

import freeswitch

import time

def fsapi(session, stream, env, args):

        t = str(int(time.time()*1000))
        print t
        freeswitch.consoleLog('info', 'timestamp: %s\n' % t)

        t = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
        print t
        freeswitch.consoleLog('info', 'sys date: \n%s\n' % t)

класть в скрипты, это может быть /etc/freeswitch/scripts или /usr/share/freeswitch/scripts

Теперь из fs_ctl вызываем:
freeswitch@192.168.10.202@internal> python check-time

и проверяем что даты перед и после sys date совпадают

При необходимости ставим и грузим mod_python

среда, 19 августа 2015 г.

freeswitch arrays

В доке сказано, что можно делать массив так:
Appending to an ARRAY with PUSH
<action application="push" data"myvar,test A"/>
<action application="push" data"myvar,test B"/>
<action application="push" data"myvar,test C"/>

По факту, формат такой
<action application="push" data"myvar=test A"/>

Получить потом можно так
<action application="log" data="INFO ${myvar}"/>
и выглядеть оно будет примерно так
ARRAY::test X|:test Y|:test Z|:test A|:test B|:test C

Можно указать конкретный элемент:
<action application="set" data="myvar[0]=Test A"/>

Вариант добавления в начало, не проверялось, но скорее всего так:
<action application="unshift" data="myvar=test X"/>
(в офдоке снова через запятую, что вероятно неверно)

Есть через regex, тоже не проверялось
<action application="set" data="num=2121231234"/>
<action application="capture" data="myvar|${num}|(\d{3})(\d{3})(\d{4})"/>

Получать через
${myvar}, пример вывода выше
${myvar[2]}

пятница, 14 августа 2015 г.

dtmf - типы передачи

Бывает in-bound и out-of-bound, то есть в голосовом потоке (можно услышать ушами) или прочие методы.
Коротко

  1. in-bound, inbound
  2. out-of-bound
    1. rfc 2833, rtp-nte
    2. sip info
    3. sip notify
Подробнее

среда, 15 июля 2015 г.

zabbix: мониторим freeswitch

Рабочая версия 2.4, под centos 6 x86_64
Считаем, что у нас уже есть сервер, поднимать будем агентов. Тут речь о настройке.
быстрая установка
идём на http://repo.zabbix.com/, выбираем нужный релиз, в моём случае zabbix-release-2.4-1.el6.noarch.rpm, ставим через rpm -Uvh, потом yum -y install zabbix-agent

Введение-предупреждение: selinux у меня выключен, поэтому если требуется его работа - или настраиваем в режиме permissive, выставляя потом права и создавая правила, или при любой проблеме первым делом проверяем, не он ли мешает работе.

2 метода получения данных:
  1. SNMP
  2. скриптами для агента

zabbix + kamailio

Как обычно, 2 варианта: SNMP и zabbix-agent

вторник, 14 июля 2015 г.

Sox

I am looking for command-line utility that monitors the microphone, and if you start to speak, writes the file. Recording period should be adjusted.

Solution is:

   sox -t alsa default recording.wav silence 1 0.1 5% 1 1.0 5%

+
http://www.thegeekstuff.com/2009/05/sound-exchange-sox-15-examples-to-manipulate-audio-files/

понедельник, 22 июня 2015 г.

Freeswitch + debian jessie (8.x)

Если apt-get install freeswitch-meta-vanilla заканчивается с ошибкой, можно поставить
freeswitch-meta-bare и затем freeswitch-init-systemd

Или наоборот, как вариант. Суть в том, что до установки freeswitch-init уже должен стоять хоть какой-то инит пакет.

Ошибка выглядит примерно так
# apt-get install -f
Reading package lists... Done
Building dependency tree    
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
2 not fully installed or removed.
After this operation, 0 B of additional disk space will be used.
Setting up freeswitch-sysvinit (1.4.20~34-1~jessie+1) ...
Job for freeswitch.service failed. See 'systemctl status freeswitch.service' and 'journalctl -xn' for details.
invoke-rc.d: initscript freeswitch, action "start" failed.
dpkg: error processing package freeswitch-sysvinit (--configure):
 subprocess installed post-installation script returned error exit status 1
dpkg: dependency problems prevent configuration of freeswitch-init:
 freeswitch-init depends on freeswitch-sysvinit (= 1.4.20~34-1~jessie+1); however:
  Package freeswitch-sysvinit is not configured yet.

dpkg: error processing package freeswitch-init (--configure):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 freeswitch-sysvinit
 freeswitch-init
E: Sub-process /usr/bin/dpkg returned an error code (1)

среда, 3 июня 2015 г.

freeswitch 1.6 - основные фишки

https://freeswitch.org/confluence/display/FREESWITCH/FreeSWITCH+1.6+Video
Detailed information on how to properly build and test the new FreeSWITCH™ 1.6 with awesome video conferencing support.
Прежде всего, перерабатывают работу с видео. Правда, штука довольно редко нужна, без учета всяких порночатиков.
Плюс изменили систему сборки, но зачем ради этого менять версию?...

По ссылке - инструкция по установке. Пока версия альфа, 1.5.

freeswitch + docker

Представляет определенный интерес такой продукт как Docker, он умеет пускать фрисвич в контейнере, но не требует всей обвязки openvz. Правда, без проброса группы портов он хорош только в небольших внедрениях, но это "пока"...

https://beingasysadmin.wordpress.com/2014/06/16/dockerizing-freeswitch-docker-enters-telephony-world/

I wouldn't recommend using Docker for a VoIP server before Docker supports port ranges. You need to configure it to map UDP port ranges for RTP, and with current version of Dicker you can only list every port explicitly. In the next release, they promise to support port ranges.
http://stackoverflow.com/questions/27830518/sip-408-request-timeout-for-freeswitch

и пример запуска из комментария

I did the following before running the freeswitch server on docker docker run -d -p 0.0.0.0:2223:22 -p 82:80 -p 5060:5060/tcp -p 5060:5060/udp -p 16384:16384/udp -p 16385:16385/udp -p 16386:16386/udp -p 16387:16387/udp -p 16388:16388/udp -p 16389:16389/udp -p 16390:16390/udp -p 16391:16391/udp -p 16392:16392/udp -p 16393:16393/udp -p 5080:5080/tcp -p 5080:5080/udp --name <container_name_goes_here> <repository_name_goes_here>

среда, 13 мая 2015 г.

Управление zrtp

ZRTP ("Z" is a reference to its inventor, Zimmermann; "RTP" stands for Real-time Transport Protocol)[2] is described in the Internet Draft as a "key agreement protocol which performs Diffie–Hellman key exchange during call setup in-band in the Real-time Transport Protocol (RTP) media stream which has been established using some other signaling protocol such as Session Initiation Protocol (SIP). This generates a shared secret which is then used to generate keys and salt for a Secure RTP (SRTP) session." One of ZRTP's features is that it does not rely on SIP signaling for the key management, or on any servers at all. It supports opportunistic encryption by auto-sensing if the other VoIP client supports ZRTP.
http://en.wikipedia.org/wiki/ZRTP

ZRTP is SRTP based, but instead of using SIP to exchange keys, it exchanges keys within the media stream itself making it more secure. It does not require PKI.
https://wiki.freeswitch.org/wiki/ZRTP

Включение: в switch.conf:
<param name="rtp-enable-zrtp" value="true"/>

Есть 3 режима работы:

  1. trusted MITM, когда устанавливается 2 сессии с сервером, с транскодингом, 
  2. простой проброс rtp - media relay, и 
  3. прямой (direct, peer-to-peer) режим, когда rtp через сервер вообще не ходит.

Про первый режим
The PBX can operate as a trusted man-in-the-middle, terminating the media streams for both parties at the PBX. This also terminates the ZRTP encryption for both parties at the PBX. This is mathematically equivalent to a classic man-in-the-middle attack, but it's not really an attack if the clients trust the PBX and consent to this. ZRTP has a mechanism to allow a client to recognize a trusted PBX to act as a "friendly" man-in-the-middle. This allows conference mixing, transcoding, and lawful interception of plaintext media, all within the confines of the trusted PBX.
http://zfoneproject.com/faq.html
ну и в целом дока интересная и полезная.

Включить первый режим:
<action application="set" data="zrtp_enrollment=true"/>

второй режим (проксирование):
<param name="inbound-zrtp-passthru" value="true"/>

плюс
https://wiki.freeswitch.org/wiki/Proxy_Media

И напоследок дока с картинками
http://zfone.com/docs/asterisk/man/html/u_guide.html

четверг, 23 апреля 2015 г.

180, 183, early_media

Early media это информация, которая ходит только в 1 сторону, оно же обычно pre answer. Если медиа нет - телефон сам генерирует гудки, иначе передает то, что прилетает. А это может быть "абонент временно недоступен", просто какая-то информация...

Обычно при установке соединения идут сообщения тип 100 (trying), потом 180 ringing, без медиа, потом 183 session progress, с медиа. Но в рф сотовые и тут выпендрились и медиа у них уже в 180 летит, что несколько ломает поведение фрисвича, хотя по RFC это и допустимо.


Работа с хуками и стартап скриптами

Пример стартап скрипта
con = freeswitch.EventConsumer("CUSTOM","vm::maintenance")
for e in (function() return con:pop(1) end) do
        freeswitch.consoleLog("notice","event\n" .. e:serialize("xml") .. "\n")
        element = nil
        element = e:getHeader("VM-Action")
        if element then
                --
        end
end

Пример хук скрипта
freeswitch.consoleLog("notice","RECORD_STOP\n" .. event:serialize(""))
path = nil
path = event:getHeader("Record-File-Path")
итд.
То есть у нас изначально есть массив event, где лежат все значения ивента. Но при этом недоступны канальные переменные, только глобальные. Можно добавить свои поля в ивент через event:addHeader("API-FileSize", size), и даже сформировать новый ивент (читаем доку), но просто модификация полей не перенесет новые переменные в сессию.

Можно создать привязку к api так:
api = freeswitch.API()
и дальше делать запросы типа
req = urlencode(event:serialize("json"))
data = api:executeString("curl "..  url .. " content-type application/json post " .. req)
Опять же, сессионные переменные будут недоступны, то есть можно сделать eval на строку вида
path =  "$${base_dir}/recordings/archive/${strftime(%Y-%m-%d-%H-%M-%S)}_${caller_id_number}_${destination_number}.wav"
но ${caller_id_number}_${destination_number} будут пустые и на выходе останется только "_". Нужно подобрать подходящие поля в event. Что-то можно заранее в ивент (и сип заголовки) выставить через application=set data="sip_h_X-Caller=12345", появится поле X-Caller.

Есть ещё метод вызова, через lua или luarun, тогда доступны сессионные переменные через массив session, самый простой пример
session:execute("playback", mySound)
в отличии от api:execute, выполняется в контексте текущей сессии, где доступны все переменные.

Также нужно быть предельно аккуратными с freeswitch.EventConsumer -- если такая конструкция появится в хуке на ивент, фрисвич начнёт падать. Точно актуально для 1.4.15, и на момент выхода 1.4.18 никто даже не пытался понять причин. И что самое противное -- падать будет не сразу, а спустя N дней, и при этом КАК БЫ работать. То есть поступает звонок, в логе есть инвайт, есть ответ на него... и всё. ringing уже не будет. Но cancel примет и обработает!

Ну и помним, что стартап скрипты перечитываются ТОЛЬКО при рестарте всего фрисвича целиком! Увы, просто рестартовать модуль lua нельзя. А вот хуки - читаются при каждом обращении к ним, поэтому для повышения скорости их лучше помещать в tmpfs/shm

линки
https://freeswitch.org/confluence/display/FREESWITCH/mod_lua
https://freeswitch.org/confluence/display/FREESWITCH/Lua+API+Reference

среда, 22 апреля 2015 г.

установка таймаутов

Переменные, которые управляют таймаутами:
timeout
leg_timeout
call_timeout (deprecated?)
originate_timeout
progress_timeout

bridge_answer_timeout - таймаут, когда имеется early_media. Имеет баг - в отличии от других таймаутов, через set дропает ногу А с ALLOTTED_TIMEOUT. Ставить или на ногу Б через [], {}, или export

Почти ко всем таймаутам есть предупреждение
WARNING: Beware that if you are not using {ignore_early_media=true} (...) is no longer applicable as soon as early media signal is received.

Ну и несколько специфичных
conference_auto_outcall_timeout
park_timeout
leg_progress_timeout

rtp_hold_timeout_sec
rtp_timeout_sec
SOFIA_SESSION_TIMEOUT

почти вся информация есть тут

про early_media надо сказать отдельно, будет дальше.

генерация тонов

Есть для этого спец модуль tone_stream, общий формат
tone_stream://[L=x;][v=y;]%(<on-duration>, <off-duration>, <freq-1> [, freq-2] [, freq-3] [, freq-n] [;loops=x])

Пример использования
<action application="playback" data="tone_stream://L=100;%(100,100,350,440)" />

Примеры

Непрерывный тон
tone_stream://%(10000,0,350,440)

Звонок формата сша, сам тон в константе
tone_stream://$${us-ring}
оно же
tone_stream://%(2000,4000,440,480)
также интересны ru-ring, uk-ring

опционально ;loops=-1 или {loops=-1}tone...

сложный тон (2 тона)
tone_stream://%(275,10,600);%(275,100,300)

бывает даже так
tone_stream://path=${conf_dir}/tetris.ttml

Более подробное описание и совсем сложные примеры:
https://wiki.freeswitch.org/wiki/TGML

lua json библиотеки

список библиотек
http://lua-users.org/wiki/JsonModules

Также есть pure lua, которая просто копируется в проект
http://regex.info/blog/lua/json
Особенность загрузки - через
JSON = (loadfile "JSON.lua")()
Если будет проблема с загрузкой - тут лучше указать полный путь. Через require не грузится.
Модуль достаточно медленный, но если надо быстро распарсить результат curl - скорости достаточно.

Сравнение производительности
http://www.kyne.com.au/~mark/software/lua-json-performance.html
http://lua-users.org/wiki/JsonModules
наиболее интересным выглядит mp-CJSON / Lua CJSON

понедельник, 20 апреля 2015 г.

lua, execute и curl - получить код ответа

1)
session:execute("curl", some_url)
Код будет в curl_response_code

2)
local response = api:execute("curl", url .. " json timeout 2 get ")
resp = json.decode(response)

if  resp.status_code ~= 200 then ...

среда, 15 апреля 2015 г.

Что за внутренний кодек L16?

В логе можно увидеть такую строку:
[DEBUG] switch_ivr_play_say.c:1314 Codec Activated L16@8000hz 1 channels 20ms

По сути, это чистый WAV, 16 бит на такт, 8кГц, линейное преобразование. Каждые 20 мс сигнала собираются в 1 пакет.
Промежуточный внутренний кодек фрисвича, когда нужно транскодирование, микширование итд.

HD - те же 16 бит, но полоса больше, допустимые значения 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000

пятница, 27 марта 2015 г.

Allow removal of User-Agent header

В версии 1.4.18 теперь можно удалять user-agent

I propose accomplishing this by removing the header when the sofia profile parameter user-agent-string is set to "_undef_".
https://freeswitch.org/jira/browse/FS-7309

понедельник, 23 марта 2015 г.

Отладка freeswitch

1)
сd /usr/src/freeswitch

gdb /usr/bin/freeswitch core.*

2)
service freeswitch stop
gdb
set logging file /tmp/freeswitch-gdb.log
set logging on

handle SIG33 nostop noprint noignore pass
run -u freeswitch -g daemon -nonat -c

set pagination off
info threads
bt
bt full
thread apply all bt
thread apply all bt full

Итог в jira.freeswitch.org, вывод или просто аттачем, или через pastebin.freeswitch.org

Перед этим ставим freeswitch-debuginfo, если ставилось пакетом.

Также полезные опции
sofia global siptrace on
sofia loglevel all 9
sofia tracelevel alert
console loglevel debug
fsctl debug_level 10

https://freeswitch.org/confluence/display/FREESWITCH/Debugging

вторник, 17 марта 2015 г.

Многодоменность

Необходимо УБРАТЬ в настройках

  • force-register-domain
  • force-register-db-domain
  • force-subscription-domain


После этого в экстеншенах будет что-то вроде
         <action application="set" data="domain_name=company-b.com"/>
         <action application="set" data="domain=company-b.com"/>
         <action application="transfer" data="1000 XML default"/>
Также может иметь смысл выставлять sip_invite_domain

Также, если регистрации обрабатываются не на камаилио, а на самом фрисвиче, надо внимательно заполнять directory по юзерам, например
  <user id="1000">
    <params>
      <param name="password" value="$${default_password}"/>
      <param name="vm-password" value="1000"/>
    </params>
    <variables>
      <variable name="toll_allow" value="domestic,international,local"/>
      <variable name="accountcode" value="1000"/>
      <!--<variable name="user_context" value="default"/>-->
      <variable name="effective_caller_id_name" value="Extension 1000"/>
      <variable name="effective_caller_id_number" value="1000"/>
      <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
      <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
      <variable name="callgroup" value="techsupport"/>
    </variables>
  </user>

Линки
https://wiki.freeswitch.org/wiki/Multi-tenant
https://wiki.freeswitch.org/wiki/Multiple_Companies


Установка своих переменных

просто переменные выставляются так:
set
export
export nolocal:
и 3 варианта прямо для bridge - скобки {}, [], <>

The syntax of using { } versus < > versus [] is explained below.
{foo=bar} is only valid at the beginning of the dial string. It will set the same variables on every channel, but does not do so for enterprise bridging/originate.
<foo=bar> is only valid at the beginning of the dial string. It will set the same variables on every channel, including all those in an enterprise bridging/originate.
[foo=bar] goes before each individual dial string and will set the variable values specified for only this channel.


Свои заголовки (в SIP) можно выставить через set|export, выставляя специальные имена
sip_h_

Response header
sip_rh_
Provisional response header
sip_ph_
Bye response header
sip_bye_h_

Помним, что по стандарту свои переменные должны иметь префикс X-
While not required, you should prefix your headers with "X-" to avoid issues with interoperability with other SIP stacks.
All inbound SIP calls will install any X- headers into local variables.
This means you can easily bridge any X- header from one FreeSWITCH instance to another.
To access the header above on a 2nd box, use the channel variable ${sip_h_X-Answer}
It is important to note that the syntax ${sip_h_customer-header} can't be used to retrieve any custom header not starting with X-.
It is because Sofia only reads and puts into variables custom headers starting with X-.

Пример
<action application="set" data="sip_rh_X-Reason=Destination Number Not in Footprint"/>

Иногда нужно выставить не-Х заголовок, это можно сделать так
<action application="set"><![CDATA[sip_h_P-Charge-Info=<sip:${caller_id_number}@${domain_name}>;npi=0;noa=3]]></action>

Убрать переменную например так:
<action application="unset" data="sip_h_X-voipnow-did"/>

Чтобы переменные перекидывались между ногами, можно указать список для перекидывания
<action application="set" data="export_vars=myvar,myvar2,foo,bar"/>
или вообще все
sip_copy_custom_headers=true

Отдельно стоит mod_callcenter, штатно он ничего не пропустит. Нужна примерно такая конструкция:
            <action application="set" data="sip_h_X-DestID=${destination_number}"/>
            <action application="set" data="cc_export_vars=sip_h_X-DestID"/>
 
Линки
http://wiki.freeswitch.org/wiki/Sofia-SIP / https://freeswitch.org/confluence/display/FREESWITCH/Sofia+SIP+Stack
http://wiki.sangoma.com/NSG-advanced-parameters-new

Как отключить транскодинг

<configuration name="sofia.conf" description="sofia Endpoint">
   <profiles>
     <profile name="sip">
       <settings>
         <param name="disable-transcoding" value="true"/>
         <param name="inbound-late-negotiation" value="false"/>

https://freeswitch.org/confluence/display/FREESWITCH/Sofia+SIP+Stack

среда, 4 февраля 2015 г.

freeswitch и прокси

с камаилио
http://kb.asipto.com/freeswitch:kamailio-3.3.x-freeswitch-1.2.x-sbc

с opensips
https://wiki.freeswitch.org/wiki/OpenSIPS_configuration_for_2_or_more_FreeSWITCH_installs
http://wiki.freeswitch.org/wiki/SBC_Setup
https://wiki.freeswitch.org/wiki/Enterprise_deployment_OpenSIPS
http://www.opensips.org/Documentation/Tutorials-OpenSIPSFreeSwitchIntegration
(вики-часть скоро переедет на конфлюенс, надо отслеживать)

Знакомимся с факсами

Передача факсов через VoIP-сети не работает. Иногда у вас получится достичь достаточно высокого процента успешных передач факсов. Может случиться, что вы создадите такую установку, которая будет работать на 100% всё время своего существования. Это редкие, неповторимые установки.
http://asterisk.ru/knowledgebase/foip

И далее по статье.

Сам протокол T.30 - нативный факсовый - создан в 80-х годах прошлого века, и хотя он примерно ровестик IP-протоколу (1974 год), в то время никто не думал над их совмещением и у них совершенно разные принципы работы: у Т.30 ожидается коммутация каналов, а IP - коммутация пакетов, и это создаёт много сложностей. Потом была сделана "обёртка" в виде протокола T.38, подробности есть выше. С ним шанс успешного прохождения сильно выше.

http://en.wikipedia.org/wiki/Fax

FreeSWITCH: свой юзер-агент

В параметрах профиля пишем
<param name="user-agent-string" value="IPPBX"/>
<param name="username" value="IPPBX" />

вторник, 3 февраля 2015 г.

freeswitch install

Введение
https://www.packtpub.com/networking-and-servers/freeswitch-12

Для тестов хорошо ставить в системы виртуализации, поддерживаются KVM, XEN, openvz
https://freeswitch.org/confluence/display/FREESWITCH/Virtualization

openvz

Работаем как с обычной системой, шаблон желательно взять /etc/vz/conf/ve-unlimited.conf-sample 

Для сборки
https://wiki.freeswitch.org/wiki/FreeSWITCH_in_OpenVZ
(информация устарела)
образы для разработчика можно взять тут
http://files.freeswitch.org/openvz/
Почему для разработчика? Потому что там уже подготовлена среда для компиляции, в /usr/src лежит freeswitch.git, правда устаревший и не учитывающий переезд фрисвича на stash, но это правится через cd /usr/src/freeswitch.git/ && git remote set-url origin https://stash.freeswitch.org/scm/fs/freeswitch.git && git pull

сейчас там сборка debian 7. Пример установки
# wget -P /vz/template/cache http://files.freeswitch.org/openvz/debian-7-x86_64-freeswitch-devel.tar.gz
Ставим с тем же именем, но удаляем расширение
# vzctl create 999 --ostemplate debian-7-x86_64-freeswitch-devel
Настроим (настройки ставим свои).
# vzctl set 999 --ipadd 192.168.1.200 --hostname freeswitch-01 --nameserver 192.168.1.1 --save
# vzctl start 999
# vzctl enter 999
Перед нами будет страшная консолька. Обновляем гит (см выше) и делаем свой первый билд!
# cd /usr/src/freeswitch.git
# ./bootstrap.sh -j && ./configure && make && make install
Итог ловим в /usr/local/freeswitch/ . Убедимся, что пациент скорее жив:
# freeswitch
выход ... (три точки)

Не используйте proxmox, есть проблемы с таймерами!

Как создать свой шаблон:
http://www.powerpbx.org/content/rhel-openvz-template-install-guide

xen, kvm

Ставим как обычно.

Далее, ставим сам фрисвич
Из исходников без особой нужды ставить не советую, есть штатные репы.

centos

статус доки "устаревает", там можно скачать файл:
rpm -Uvh http://files.freeswitch.org/freeswitch-release-1-0.noarch.rpm
yum install --nogpgcheck freeswitch-config-vanilla

Для сборки
7 официально пока не поддерживается, да и смысла особо нет.
Можно скомпилировать самим по этой же доке.

debian

Поддерживается только 7 (wheezy)

echo 'deb http://files.freeswitch.org/repo/deb/debian/ wheezy main' >> /etc/apt/sources.list.d/freeswitch.list
curl http://files.freeswitch.org/repo/deb/debian/freeswitch_archive_g0.pub | apt-key add -
apt-get update; apt-get install freeswitch-meta-vanilla

Далее

Есть 4 вида конфигов, минимальный
https://github.com/voxserv/freeswitch_conf_minimal

Посложнее
https://github.com/xlab1/sipfe_freeswitch_common

где есть почти всё нужное
vanilla, идёт в пакетах, freeswitch-meta-vanilla в дебе, freeswitch-config-vanilla в центоси.

SBC
дебиан freeswitch-conf-sbc, в центоси тоже было, но сходу найти не удалось.