Предыстория
На днях мне досталась задача: продиагностировать и по возможности отремонтировать несколько десятков IP-телефонов производства фирмы Cisco. Телефоны эти у клиента предназначены для работы по протоколу SCCP, поэтому — никаких перепрошивок под другие протоколы. Попытка получить симулятор CCM (распространяется бесплатно в составе SDK) с официального сайта не увенчалась успехом: в Cisco я не был зарегистрирован, базовая регистрация не даёт права на скачивание, а менеджер пользовательского профиля показывает только Error 500. Вот и пришлось вникать в вопрос и искать альтернативы, не требующие долгих «плясок с бубном».
Первое, что пришло в голову — Asterisk. И действительно, в стандартной поставке для моего дистрибутива ОС оказался канальный модуль chan_skinny. Однако в процессе поиска я наткнулся на другой вариант реализации протокола SCCP в Asterisk: chan_sccp. От chan_skinny, насколько я понял, он отличается набором функционала и производительностью. В частности, на сайте разработчиков об этом сказано следующее:
It delivers better performance, scalability, interoperability and functionality than either chan_skinny or chan_sip on a SCCP capable phone.
Перевод:
Он (модуль — прим. пер.) обеспечивает лучшую производительность, масштабируемость, совместимость и набор функционала с телефонами, поддерживающими протокол SCCP, нежели chan_skinny и chan_sip.
Заявление смелое, но, как выяснилось, вполне обоснованное, по крайней мере в вопросе функциональности. На этом варианте я и остановился, несмотря на то, что этот модуль отсутствовал в пакетах репозитория.
Все описанные действия проводились на машине с openSuSE Linux 11.4 x86_64 с IP-адресом 10.0.0.250.
Установка ПО и сборка chan_sccp
Я подключил репозиторий Asterisk 1.8 и поставил следующие пакеты (в других дистрибутивах названия пакетов могут отличаться):
- asterisk
- asterisk-devel
- gcc
- m4
- make
- dhcp-server
- tftp
Зависимости подтянулись автоматически.
Так как версия 3.x модуля chan_sccp, по умолчанию предлагаемая на официальном сайте, не поддерживает asterisk 1.8, я взял версию 4 — она тоже вполне стабильная.
Сборка модуля тривиальна:
configure --prefix=/usr --sysconfdir=/etc
make && make install
После этого в /usr/lib64/asterisk/modules
среди прочих оказался файл chan_sccp.so
.
Конфигурация
Первым делом следует обнулить конфигурацию телефона. Например, в Cisco 7940G это делается так: кнопка меню — «Network configuration» — * * # — «Erase configuration» — «Yes».
«Голый» телефон сначала хочет узнать, кто он, где он и зачем он. Делает он это в несколько этапов:
- Получает IP-адрес и узнаёт местоположение TFTP-сервера через DHCP
- Получает с TFTP-сервера общую и персональную конфигурацию (исходя из собственного MAC-адреса), где указан адрес (или несколько адресов) Call Manager-а.
- Соединяется с Call Manager-ом по протоколу SCCP, регистрируется и узнаёт всё остальное, необходимое для работы.
DHCP
Адрес TFTP-сервера телефону надо передавать через нестандартную DHCP-опцию с номером 150. Для этого в конфигурации ISC DHCP Server (/etc/dhcpd.conf
) я среди прочего написал:
...
option cisco-tftp code 150 = ip-address;
...
subnet 10.0.0.0 netmask 255.0.0.0 {
...
option cisco-tftp 10.0.0.250;
...
}
Сервер настроил на автозапуск (chkconfig dhcpd on
) и запустил (service dhcpd start
).
TFTP
В корне TFTP-сервера я создал файл с именем SEPDefault.cnf.xml
(это файл общей конфигурации для всех телефонов) и следующим содержимым:
<device>
<devicePool>
<callManagerGroup>
<members>
<member priority="0">
<callManager>
<ports>
<ethernetPhonePort>2000</ethernetPhonePort>
</ports>
<processNodeName>10.0.0.250</processNodeName>
</callManager>
</member>
</members>
</callManagerGroup>
</devicePool>
</device>
Так как TFTP-сервер обслуживается запущенным по умолчанию «супервервером» xinetd, больше ничего делать не потребовалось.
Asterisk
Больше всего настроек относится к Asterisk и канальному модулю SCCP.
/etc/asterisk/sccp.conf
:
[general]
servername = Asterisk
keepalive = 60
debug = 1
context = default
dateformat = D.M.Y
bindaddr = 0.0.0.0
port = 2000
disallow=all
allow=alaw
allow=ulaw
allow=g729
firstdigittimeout = 16
digittimeout = 8
autoanswer_ring_time = 1
autoanswer_tone = 0x32
remotehangup_tone = 0x32
transfer_tone = 0
callwaiting_tone = 0x2d
musicclass=default
language=ru
deny=0.0.0.0/0.0.0.0
permit=10.0.0.0/255.0.0.0
sccp_tos = 0x68
sccp_cos = 4
audio_tos = 0xB8
audio_cos = 6
video_tos = 0x88
video_cos = 5
echocancel = on
silencesuppression = off
private = on
callanswerorder=oldestfirst
[SEP0123456789ABCDEF]
description = Phone 1
devicetype = 7940
park = off
button = line, 102
cfwdall = off
type = device
keepalive = 60
tzoffset = +5
transfer = on
park = on
cfwdall = off
cfwdbusy = off
cfwdnoanswer = off
pickupexten = off
pickupmodeanswer = on
dtmfmode = inband
deny=0.0.0.0/0.0.0.0
permit=10.0.0.0/255.0.0.0
nat=off
directrtp=on
earlyrtp = none
private = on
mwilamp = on
mwioncall = off
meetme = on
meetmeopts = qd
setvar=testvar=value
cfwdall = on
[102]
id = 1000
type = line
pin = 1234
label = Line 102
description = Line 102
mailbox = 10102
cid_name = Line 102
cid_num = 102
accountcode=79102
callgroup=1,3-4
pickupgroup=1,3-5
context = default
incominglimit = 2
transfer = on
vmnum = 600
meetmenum = 700
trnsfvm = 1000
secondary_dialtone_digits = 9
secondary_dialtone_tone = 0x22
musicclass=default
language=ru
audio_tos = 0xB8
audio_cos = 6
video_tos = 0x88
video_cos = 5
echocancel = on
meetme = on
meetme = qxd
regexten = 102
silencesuppression = off
Первая секция — настройки по умолчанию.
Вторая — настройки регистрации телефонного аппарата, имя секции совпадает с ID аппарата. Фактически этот ID является строкой из букв SEP и MAC-адреса телефона.
Третья секция — описание линии.
Вот тут, насколько я понял, и есть главное отличие chan_sccp от chan_skinny. Один аппарат может работать с несколькими линиями, несколько аппаратов могут разделять одну и ту же линию. Настройка получается намного более гибкой и использует все возможности протокола SCCP.
Так как блок питания для телефонов у меня был только один (и тот переделанный на скорую руку из PoE-инжектора), в качестве «второго конца» я использовал SIP-софтфон Ekiga. На всякий случай приведу фрагмент /etc/asterisk/sip.conf
:
[test]
type=friend
secret=topsecret
host=dynamic
Также я создал правила дозвона в /etc/asterisk/extensions.ael
:
context default {
102 => Dial(SCCP/102);
199 => Dial(SIP/test);
}
Затем — очевидные действия: chkconfig asterisk on
и service asterisk start
.
Брандмауэр
Для правильной работы всех подсистем следует открыть нужные порты в брандмауэре. В моём случае это были:
- DHCP: 67/udp
- TFTP: 69/udp
- SCCP: 2000/tcp
- SIP: 5060/udp
- RTP: 10000:20000/udp
Результат и выводы
Всё это «взлетело» практически сразу. Телефоны ругались на отсутствие файлов локали (скачать их с официального сайта просто так тоже не удалось), но при этом отлично работали.
Этот простой и минималистичный опыт показывает, что во многих случаях от применения дорогостоящего ПО можно отказаться. Несмотря на то, что описаны только файловые конфигурации Asterisk, ничто не мешает организовать хранение соответствующей информации в базе данных (модули res_config_*) и интегрировать графический интерфейс (например, FreePBX). И, конечно же, описанный вариант прекрасно подходит для диагностики, тестирования и различного рода экспериментов с оборудованием и ПО для IP-телефонии при минимальных затратах.
Автор: m0Ray