Настало время подключить телефоны к астериск по протоколу SIP и сделать «звонок другу» :)
Выбор протокола
Asterisk поддерживает большое количество протоколов для работы. На данный момент, имеет смысл остановится только на двух из них – SIP и IAX2. Какой протокол выбрать для стационарных IP телефонов - решать, разумеется, вам.
В моем случае, для телефонов внутри локальной сети выбран SIP, т.к. это устоявшийся протокол, поддерживается всеми производителями, шустрый и тд. К его недостатком можно отнести его сложность при работе через NAT.
В то же время, для подключения к внешним сетям и «межастерисковой» связи, на мой взгляд, уместнее использовать IAX2. IAX2 расшифровывается как (если не ошибаюсь) Inter Asterisk eXchange, и я не вижу смысла не использовать его для связи с внешними источниками, т.к. он легко проходит NAT, не требует открытия большого количества портов (точнее, требует только один UDP) и как бы специально для этого и предназначен.
Файл sip.conf
В астериск существует два пути подключения пользователей – через файл users.conf, который является общим для всего астериска или через выделенные файлы – sip.conf и iax.conf – соответственно, для протоколов SIP и IAX2.
Лично я выбрал вариант с раздельными файлами, что, как мне кажется, позволит более тонко конфигурировать разные разделы.
Файл sip.conf (как и большинство других конфигурационных файлов asterisk) состоит из секции [general], в которой перечисляются параметры для всех подключенных устройств, и индивидуальных настроек для каждого устройства.
В раздел [general] я решил для начала внести минимум настроек.
context=internal_phones ; Этот контекст будет использоваться
; для звонков с/на внутренние телефоны
allowoverlap=no ; Насколько я понял, это отключение набора
; по мере поступления номера, т.е.
; система будет ждать полного номера
; и лишь затем начнет набирать.
bindport=5060 ; управляющий SIP порт. Это значение по-
; умолчанию
srvlookup=no ; эта функция позволяет набирать номер
; по доменному имени пользователя
; я ее отключил от греха подальше.
qualify=200 ; если ответ от телефона идет более,
; чем 0.2 секунды - считаем его
; неработающим.
Теперь необходимо прописать сам телефон. Для начала, пропишем его максимально просто и, в дальнейшем, будем наращивать функционал.
Обращаю ваше внимание, что в моем случае сервер не имеет открытого IP, поэтому, я могу на данный момент не накладывать ограничений по IP адресам и тд – они будут отброшены нашим файерволом.
В случае открытой системы обязательно наложите ограничение на пул IP, установите пароли посложнее, пропишите правила на фаерволе!
type=friend ; пользователь может и принимать
; звонки, и звонить
host=dynamic ; т.к. телефоны получают IP по
; DHCP, то нужно поставить значение dynamic
username=1260 ; мы решили использовать имя пользователя,
; совпадающее с его номером - так немного проще
secret=**** ; пароль для подключения телефона. На данном
; этапе, все пароли будут одинаковыми.
; потом мы это поменяем.
[1261] ; а это - второй телефон
type=friend
host=dynamic
username=1261
secret=****
В дальнейшем, разумеется, этот файл настроек будет изменяться и, как мне видится, начнет генерироваться автоматически на основании информации из домена.
Перезагружаем конфигурацию SIP и смотрим на результат.
asterisk*CLI> sip show users
Username Secret Accountcode Def.Context ACL ForcerPort
1260 **** internal_phones No No
1261 **** internal_phones No No
Теоретически, настроенные телефоны должны сразу подключиться к астериск.
На практике, в моем случае это не произошло, т.к. после установки CentOS по-умолчанию закрыты все порты.
Необходимо разрешить входящие TCP и UDP на порт 5060, а так же входящие UDP на интервал 10000-20000. Я, на всякий случай, прописал еще и ограничение по исходному IP.
После этих манипуляций, на телефонах загорелась радостная надпись SIP. Проверим – что на эту тему думает сам астериск:
Name/username Host Dyn Forcerport ACL Port Status
1260/1260 10.62.20.240 D 5060 OK (5 ms)
1261/1261 10.62.20.238 D 5060 OK (5 ms)
2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]
Оба телефона, как нетрудно заметить, подключены.
Разумеется, в этот момент крайне хочется на одном из телефонов набрать номер другого, услышать голос коллеги (или свой же) и несколько секунд с идиотской улыбкой на лице «аллекать».
Набираем номер, но не тут-то было – в телефоне короткие гудки. Разумеется, если телефон не подключен, то его реакция объяснима. Но наш-то подключен :)
Проблема кроется в том, что у нас пустой диалплан. Соответственно, звонок уходит в «тупик», и телефон дает отбой.
Это можно увидеть через консоль. Подключаемся, набираем номер и видим:
Простейший диалплан
Создадим самый простой диалплан, просто чтобы увидеть, что звонок все-таки идет. При этом, можно напрямую задать номер телефона абонента, но мы сразу в тестовых целях сделаем обработку всех четырехзначных номеров. В дальнейших статьях мы, разумеется, его значительно усложним.
Итак, нашу текущую задачу можно описать так: При наборе четырехзначного номера – набрать его через SIP.
Создаем файл extensions.conf и в нем прописываем
[general]
[default] ; контекст для звонков без заданного контекста
; обычно это входящие звонки
; Ругнемся в лог
exten => s,1,Verbose(Hey! WTF??? ${EXTEN} dialed from default!)
; и повесим трубку
exten => s,n,Hangup()
[internal_phones]
; все следующие правила будут работать при наборе любого номера из четырех цифр
; вывод сообщения в консоль
exten => _XXXX,1,Verbose(Test call 4 digits)
; выведем номер, который мы набираем
exten => _XXXX,n,Verbose(Dialed number:${EXTEN})
; наберем его через SIP, используя переменную
; EXTEN
exten => _XXXX,n,Dial(SIP/${EXTEN})
; в конце - повесим трубку
exten => _XXXX,n,Hangup()
Перезагрузим диалплан и сделаем звонок.
Dialplan reloaded.
== Using SIP RTP CoS mark 5
-- Executing [1261@internal_phones:1] Verbose("SIP/1260-00000007", "Test call 4 digits") in new stack
Test call 4 digits
-- Executing [1261@internal_phones:2] Verbose("SIP/1260-00000007", "Dialed number:1261") in new stack
Dialed number:1261
-- Executing [1261@internal_phones:3] Dial("SIP/1260-00000007", "SIP/1261") in new stack
== Using SIP RTP CoS mark 5
-- Called 1261
-- SIP/1261-00000008 is ringing
-- SIP/1261-00000008 answered SIP/1260-00000007
-- Remotely bridging SIP/1260-00000007 and SIP/1261-00000008
== Spawn extension (internal_phones, 1261, 3) exited non-zero on 'SIP/1260-00000007'
Другой телефон звонит и можно поговорить.
В следующей статье я планирую описать (и узнать :) – как расширить диалплан, чтобы фиксировать звонки по несуществующим номерам и выдавать какое-нибудь приятное голосовое сообщение.