Pull to refresh

Настройка телефона Cisco серии 79XX для работы с Asterisk

Development of communication systems *


В статье будут описаны нюансы настройки IP-телефона Cisco на примере цискофона 7942G.
Итак, если вы присматриваетесь к VoIP-устройствам Cisco серии 79XX, то добро пожаловать под кат.


Используется:


Cisco VoIP Phone 7942G
Asterisk 1.4.39
TFTP-server-0.49
Внимание! Инструкция подходит не для всех телефонов Cisco 79XX. См. здесь

Настройка



Комбинации клавиш в Cisco

**#** — перезагрузка телефона (через меню)
**# — разблокировка настроек (также через меню). Разблокировка нужна, например, для того чтобы поставить настройки DHCP-клиента

TFTP

Первое что нам понадобиться сделать — это настроить tftpserver. Я использовал стандартный линуксовый. Рекомендую сразу настроить, чтобы tftp-запросы записывались в лог-файл (по умолчанию /var/log/messages).
cat /etc/xinetd.d/tftp:
...
server_args = -s /tftpboot -v
...

Смена прошивки

Итак, сначала нужно разыскать нужную прошивку для работы по SIP, т.к. по умолчанию используется версия с SCCP. Для этого есть гугл или торренты.

Далее заходим на известный всем сайт voip-info.org. По ссылке выложена информация о прошивке. Т.к. у меня версия астериска 1.4 (которая не умеет работать по tcp), то советуют брать версию 8.5.4. По этой ссылке есть много и другой полезной информации.
Таким образом, нам нужен файл cmterm-7942_7962-sip.8-5-4.zip. Все файлы которые там есть нужно вывалить в корень тфтп-сервера.

Русская локаль

Еще бы нам не помешала русская локаль. Ну т.е. чтобы все надписи на экране были на русском языке.
Я её брал из файла po-locale-ru_RU-8.4.3.1000-1.exe (тоже можно найти в интернете). Тут есть одна хитрость — при запуске программы она вываливает ошибку и потом закрывается. Но нам ведь всего лишь нужны файлы локали, установить мы их можем и сами.
Поэтому после запуска идем в папку %TEMP% (советую предварительно её очистить) и смотрим что там программа вывалит.
Там в числе прочего будет папка Russian_Russian_Federation. Вот её нам и нужно будет поместить в корень tftp-сервера.
Версия локали будет как раз 8.4.3.1000-1.

Файл кофигурации цискофона

Теперь перейдем непосредственно к файлу конфигурации. Цискофон загружает его исключительно с tftp-сервера. Сначала кажется неудобно, с другой стороны, нужно настроить всего один раз, а затем можно эти телефоны хоть штабелями закупать — настройка их будет аналогичной и займет минимум времени. Кроме того, этим Cisco обезопасил телефон от «шаловливых ручек» пользователей. Через меню сделать практически ничего нельзя.
Файл должен называться SEP<MAC-адрес Cisco-телефона>.cnf.xml.
Мак-адрес записан на тыльной стороне устройства.
Определим некоторые значения:
$ASTERISK — ай-пи нашего астериска
$SERVICESURL — полный путь до скрипта, который генерирует адресную книгу (например, 192.168.0.22/asterisk/directory.php)
$ACCOUNT — пользователь/номер нашего аккаунта на астериске. Если у вас нет соответствия номер<=>пользователь, то конфиг нужно будет соответствующим образом поменять.
$ACCOUNT_PASS — пароль от SIP-аккаунта
<device>
    <fullConfig>true</fullConfig>
    <deviceProtocol>SIP</deviceProtocol>
    <devicePool>
        <dateTimeSetting>
            <dateTemplate>D.M.Y</dateTemplate>
            <timeZone>Ekaterinburg Standard Time</timeZone>
            <ntps>
                <ntp>
                    <name>$ASTERISK</name>
                    <ntpMode>Unicast</ntpMode>
                </ntp>
            </ntps>
        </dateTimeSetting>
        <callManagerGroup>
            <tftpDefault>true</tftpDefault>
                <members>
                <member priority="0">
                <callManager>
                <name>$ASTERISK</name>
                <description>CallManager 5.0</description>
                <ports>
                  <ethernetPhonePort>2000</ethernetPhonePort>
                  <sipPort>5060</sipPort>
                  <securedSipPort>5061</securedSipPort>
                </ports>
                <processNodeName>$ASTERISK</processNodeName>
                </callManager>
                </member>
                </members>
             </callManagerGroup>
    </devicePool>
    <commonProfile>
        <phonePassword></phonePassword>
        <backgroundImageAccess>true</backgroundImageAccess>
        <callLogBlfEnabled>0</callLogBlfEnabled>
    </commonProfile>
    <loadInformation>SIP42.8-5-4S</loadInformation>
    <loadInformation434  model="Cisco 7942">SIP42.8-5-4S</loadInformation434>
    <vendorConfig>
        <disableSpeaker>false</disableSpeaker>
        <disableSpeakerAndHeadset>false</disableSpeakerAndHeadset>
        <pcPort>0</pcPort>
        <settingsAccess>1</settingsAccess>
        <garp>0</garp>
        <voiceVlanAccess>0</voiceVlanAccess>
        <videoCapability>0</videoCapability>
        <autoSelectLineEnable>0</autoSelectLineEnable>
        <daysDisplayNotActive>1,7</daysDisplayNotActive>
        <displayOnTime>10:30</displayOnTime>
        <displayOnDuration>06:05</displayOnDuration>
        <displayIdleTimeout>00:05</displayIdleTimeout>
        <webAccess>1</webAccess>
        <spanToPCPort>1</spanToPCPort>
        <loggingDisplay>1</loggingDisplay>
        <loadServer></loadServer>
    </vendorConfig>

<userLocale> 
  <name>Russian_Russian_Federation</name> 
  <uid></uid> 
  <langCode>ru_RU</langCode> 
  <version>8.4.3.1000-1</version> 
  <winCharSet>utf-8</winCharSet> 
</userLocale>


<networkLocale>Russian_Federation</networkLocale> 
<networkLocaleInfo> 
  <name>Russian_Federation</name> 
  <uid></uid> 
  <version>8.4.3.1000-1</version> 
</networkLocaleInfo>
    
    <deviceSecurityMode>1</deviceSecurityMode>
    <idleTimeout>0</idleTimeout>
    <directoryURL></directoryURL> 
    <servicesURL>$SERVICESURL</servicesURL> 
    <idleURL></idleURL>
    <messagesURL></messagesURL>
    <proxyServerURL></proxyServerURL>
    <dscpForSCCPPhoneConfig>96</dscpForSCCPPhoneConfig>
    <dscpForSCCPPhoneServices>0</dscpForSCCPPhoneServices>
    <dscpForCm2Dvce>96</dscpForCm2Dvce>
    <transportLayerProtocol>2</transportLayerProtocol>
    <capfAuthMode>0</capfAuthMode>
    <capfList>
        <capf>
            <phonePort>3804</phonePort>
        </capf>
    </capfList>
    <certHash></certHash>
    <encrConfig>false</encrConfig>
    <sipProfile>
        <sipProxies>
            <backupProxy>$ASTERISK</backupProxy>
            <backupProxyPort>5060</backupProxyPort>
            <emergencyProxy>$ASTERISK</emergencyProxy>
            <emergencyProxyPort>5060</emergencyProxyPort>
            <outboundProxy>$ASTERISK</outboundProxy>
            <outboundProxyPort>5060</outboundProxyPort>
            <registerWithProxy>true</registerWithProxy>
        </sipProxies>
     <sipCallFeatures>
        <cnfJoinEnabled>true</cnfJoinEnabled>
        <callForwardURI>x--serviceuri-cfwdall</callForwardURI>
        <callPickupURI>x-cisco-serviceuri-pickup</callPickupURI>
        <callPickupListURI>x-cisco-serviceuri-opickup</callPickupListURI>
        <callPickupGroupURI>x-cisco-serviceuri-gpickup</callPickupGroupURI>
        <meetMeServiceURI>x-cisco-serviceuri-meetme</meetMeServiceURI>
        <abbreviatedDialURI>x-cisco-serviceuri-abbrdial</abbreviatedDialURI>
        <rfc2543Hold>false</rfc2543Hold>
        <callHoldRingback>2</callHoldRingback>
        <localCfwdEnable>true</localCfwdEnable>
        <semiAttendedTransfer>true</semiAttendedTransfer>
        <anonymousCallBlock>2</anonymousCallBlock>
        <callerIdBlocking>2</callerIdBlocking>
        <dndControl>0</dndControl>
        <remoteCcEnable>true</remoteCcEnable>
     </sipCallFeatures> 
     <sipStack>
        <sipInviteRetx>6</sipInviteRetx>
        <sipRetx>10</sipRetx>
        <timerInviteExpires>180</timerInviteExpires>
        <timerRegisterExpires>3600</timerRegisterExpires>
        <timerRegisterDelta>5</timerRegisterDelta>
        <timerKeepAliveExpires>120</timerKeepAliveExpires>
        <timerSubscribeExpires>120</timerSubscribeExpires>
        <timerSubscribeDelta>5</timerSubscribeDelta>
        <timerT1>500</timerT1>
        <timerT2>4000</timerT2>
        <maxRedirects>70</maxRedirects>
        <remotePartyID>false</remotePartyID>
        <userInfo>None</userInfo>
     </sipStack>
     <autoAnswerTimer>1</autoAnswerTimer>
     <autoAnswerAltBehavior>false</autoAnswerAltBehavior>
     <autoAnswerOverride>true</autoAnswerOverride>
     <transferOnhookEnabled>false</transferOnhookEnabled>
     <enableVad>false</enableVad> 
        <preferredCodec>g711alaw</preferredCodec>
       <dtmfAvtPayload>101</dtmfAvtPayload>
       <dtmfDbLevel>3</dtmfDbLevel>
       <dtmfOutofBand>avt</dtmfOutofBand>
        <alwaysUsePrimeLine>false</alwaysUsePrimeLine>
        <alwaysUsePrimeLineVoiceMail>false</alwaysUsePrimeLineVoiceMail>
        <kpml>3</kpml>
        <stutterMsgWaiting>1</stutterMsgWaiting>
        <callStats>true</callStats>
        <silentPeriodBetweenCallWaitingBursts>10</silentPeriodBetweenCallWaitingBursts>
        <disableLocalSpeedDialConfig>true</disableLocalSpeedDialConfig>
        <startMediaPort>10100</startMediaPort>
        <stopMediaPort>10300</stopMediaPort>
        <voipControlPort>5060</voipControlPort>
        <dscpForAudio>184</dscpForAudio>
        <ringSettingBusyStationPolicy>0</ringSettingBusyStationPolicy>
        <dialTemplate>dialplan.xml</dialTemplate> 
        <phoneLabel>Cisco</phoneLabel>
          <natReceivedProcessing>false</natReceivedProcessing>
          <natEnabled>false</natEnabled>
          <natAddress></natAddress>
        <sipLines>
          <line button="1">
            <featureID>9</featureID>
            <featureLabel>$ACCOUNT</featureLabel>
            <proxy>$ASTERISK</proxy>
            <port>5060</port>
            <name>$ACCOUNT</name>
            <displayName>$ACCOUNT</displayName>
            <autoAnswer>
              <autoAnswerEnabled>2</autoAnswerEnabled>
            </autoAnswer>
            <callWaiting>3</callWaiting>
            <authName>$ACCOUNT</authName>
            <authPassword>$ACCOUNT_PASS</authPassword>
            <sharedLine>false</sharedLine>
            <messageWaitingLampPolicy>3</messageWaitingLampPolicy>
            <messagesNumber></messagesNumber>
            <ringSettingIdle>4</ringSettingIdle>
            <ringSettingActive>5</ringSettingActive>
            <contact>$ACCOUNT</contact>
            <forwardCallInfoDisplay>
              <callerName>true</callerName>
              <callerNumber>false</callerNumber>
              <redirectedNumber>false</redirectedNumber>
              <dialedNumber>true</dialedNumber>
            </forwardCallInfoDisplay>
          </line>
          <line button="2">
          <featureID></featureID>
          <featureLabel></featureLabel>
          <speedDialNumber></speedDialNumber>
          </line>
        </sipLines>
    </sipProfile>
</device>


Теперь будем комментировать.

<timeZone>Ekaterinburg Standard Time</timeZone> - настройки часового пояса, которые будут использовать при получении информации от NTP-сервере (в конфиге это наш астериск). 

Все часовые пояса можно найти, например, здесь.

<loadInformation>SIP42.8-5-4S</loadInformation> - имя прошивки, которая будет загружена


Следующие настройки нужны для настройки локали:
<userLocale> 
  <name>Russian_Russian_Federation</name> 
  <uid></uid> 
  <langCode>ru_RU</langCode> 
  <version>8.4.3.1000-1</version> 
  <winCharSet>utf-8</winCharSet> 
</userLocale>
<networkLocale>Russian_Federation</networkLocale> 
<networkLocaleInfo> 
  <name>Russian_Federation</name> 
  <uid></uid> 
  <version>8.4.3.1000-1</version> 
</networkLocaleInfo>


<servicesURL>$SERVICESURL</servicesURL> - указываем откуда загружать XML для сервисов (в нашем случае там будет передаваться список абонентов).


<dialTemplate>dialplan.xml</dialTemplate>  - это очень важная строчка, о ней будет ниже.


<line button="2"> - у нас пустой, т.к. используем один SIP-аккаунт.


<preferredCodec>g711alaw</preferredCodec> - кодек G711 alaw у нас будет предпочтительным.


Конфигурация sip.conf астериска

...
[$ACCOUNT]
deny=0.0.0.0/0.0.0.0
permit=192.168.0.0/255.255.255.0
type=friend
host=dynamic
context=НАШ_КОНТЕКСТ
dtmfmode=rfc2833
disallow=all
allow=alaw
allow=ulaw
allow=gsm
username=$ACCOUNT
secret=$ACCOUNT_PASS
call-limit=2
...

Самое интересное здесь — call-limit=2. Суть в том, что можно будет получать 1 или 2 звонка (3 звонок уже на циску не пойдет — зачем её напрягать?), их можно обрабатывать на телефоне, переключаясь между ними. Больше чем 2 звонка в этом аппарате не поддерживается (возможно будет поддерживаться в новых прошивках), хотя обрабатывать 3 звонка уже достаточно накладно.

Настройка диалплана цискофона

Циско настолько умная, что может использовать свой собственный диалплан. Но тут есть обратная сторона медали. Если этот диалплан не указать, то исходящие звонки вообще ходить не будут. Точней будут, но только на номера от 0 до 9 =).
<DIALTEMPLATE>
  <TEMPLATE MATCH="*" Timeout="3"/> <!-- Anything else -->
</DIALTEMPLATE>

В этом конфиге мы по сути передаем всю ответственность на астериск — т.е. просто после 3-х секунд передаем номер. Более изящные номерные планы можно найти на voip-info.org.

Адресная книга абонентов

У нас есть LDAP (в связке с samba), в нем есть информация о телефонах пользователей. Так почему бы этим не воспользоваться?
Сервер LDAP, filter поиска нужно будет поменять на свои настройки.
directory.php:
<?
   header("Content-type: text/xml");
   header("Connection: close");
   header("Expires: -1");

  $page=1;
  if(isset($_GET['page']))
  {
    $page = $_GET['page'];
    if(settype($page,"integer") == false)
      die("<b>BAD REQUEST (invalid type)</b>");
  }

  echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";

  $ldapconfig['host'] = '192.168.0.8';
  $ldapconfig['port'] = NULL;
  $ldapconfig['basedn'] = 'ou=users,dc=MyCompany,dc=ru';
  $ldapconfig['filter'] = "(&(uid=*)(objectClass=sambaSamAccount)(objectClass=inetOrgPerson))";

   print("<CiscoIPPhoneDirectory>\n");
   print("\t<Title> </Title>\n");
   print("\t<Prompt> </Prompt>\n");

  $DS = @ldap_connect($ldapconfig['host'], $ldapconfig['port']);

  if ( $DS === false )
    exit("ldap_connect problem: ".ldap_error($DS));

  $SRes = @ldap_search($DS, $ldapconfig['basedn'], $ldapconfig['filter']);

  if ( $SRes === false )
    exit("ldap_search problem: ".ldap_error($DS));

  $res = @ldap_get_entries($DS, $SRes);
  if ( $res === false )
    exit("ldap_get_entries problem: ".ldap_error($DS));


  $results = array();

  for ($i = 0; $i < $res["count"]; $i++)
  {

    if (!isset($res[$i]["telephonenumber"]))
      continue;
    if (!isset($res[$i]["displayname"]))
      continue;

    $r_ar = array();

    $r_ar['displayname']=$res[$i]["displayname"][0];
    $r_ar['telephonenumber']=$res[$i]["telephonenumber"][0];
    array_push($results, $r_ar);

  }

  for ($i = 0; $i < (count($results)-1); $i++)
    for ($k = $i+1; $k < count($results); $k++)
    {
      if (strcmp($results[$i]['displayname'],$results[$k]['displayname']) > 0)
      {
        $r_tmp = array();
        $r_tmp = $results[$i];
        $results[$i] = $results[$k];
        $results[$k] = $r_tmp;
      }

    }



  for ($i = (32*($page-1)); $i < (32*$page); $i++)
  {

    if ($i == count($results))
      break;

    print("\t<DirectoryEntry>\n");

    print("\t\t<Name>");
    print($results[$i]['displayname']);
    print("</Name>\n");


    print("\t\t<Telephone>");
    print($results[$i]['telephonenumber']);
    print("</Telephone>\n");

    print("\t</DirectoryEntry>\n");
  }

  print("<SoftKeyItem>");
  print("<Name>Dial</Name>");
  print("<URL>SoftKey:Dial</URL>");
  print("<Position>1</Position>");
  print("</SoftKeyItem>");

  if ($page > 1)
  {
    print("<SoftKeyItem>");
    print("<Name>Prev</Name>");
    print("<URL>http://".$_SERVER['SERVER_NAME']."/asterisk/directory.php?page=".($page-1)."</URL>");
    print("<Position>2</Position>");
    print("</SoftKeyItem>");
  }

  $count_pages = (int) (count($results) / 32);

  if ((count($results) % 32) !=0)
    $count_pages++;

  if ($page < $count_pages)
  {
    print("<SoftKeyItem>");
    print("<Name>Next</Name>");
    print("<URL>http://".$_SERVER['SERVER_NAME']."/asterisk/directory.php?page=".($page+1)."</URL>");
    print("<Position>3</Position>");
    print("</SoftKeyItem>");
  }

  print("<SoftKeyItem>");
  print("<Name>Exit</Name>");
  print("<URL>SoftKey:Exit</URL>");
  print("<Position>4</Position>");
  print("</SoftKeyItem>");

  print("</CiscoIPPhoneDirectory>\n");

?>


Обновление. Заметьте, что на странице только 32 контакта. Почему так? Не знаю, чем это объяснить, но так реализовано в прошивке — больше чем 32 контакта не поддерживается. Впрочем, это не беда, т.к. можно реализовать при помощи софткеев механизм отображения пред. и след. страниц.

Делаем настройки для логотипа

Для начала по логам tftp смотрим куда cisco обращается за картинкой. Происходит это в момент выбора фонового изображения
через меню телефона (как разблокировать меню написано выше).
изображения из меню
/tftpboot/Desktops/320x196x4/List.xml:
<CiscoIPPhoneImageList>
  <ImageItem Image="TFTP:Desktops/320x196x4/Logo-TN.png" URL="TFTP:Desktops/320x196x4/Logo.png"/>
</CiscoIPPhoneImageList>

Нам нужно создать одну картинку 320x196 и одну картинку в 4 раза меньше (80x49).
Logo-TN.png — эскиз.
Logo.png — полноценная картинка.
Изменять логотип нужно через меню телефона.

Что не вошло в статью


— Настройка сигналов вызовов. Да, это тоже можно делать. Другое дело — зачем? Если для вас оно имеет смысл — то дерзайте.
— Настройка directories. Есть возможность, например, читать RSS с телефона и вообще добавлять различные контент-каталоги.

Проблемы, возникшие в процессе настройки


1. Нужна была прошивка для SIP (по умолч. SCCP)
2. Не регистрировался телефон (поставил прошивку 9.0.3, которая работает только по TCP)
3. Не шли исходящие звонки (см. dialplan.xml)
4. Отображаются только 32 контакта в адресной книге (ограничение прошивки)

Ссылки


www.voip-info.org/wiki/view/Asterisk+phone+cisco+79x1+xml+configuration+files+for+SIP
www.voip-info.org/wiki/view/Asterisk+phone+cisco+7970+SIP
www.asteriskguru.com/tutorials/cisco_7960_ip_phone_configuration.html
Опыт настройки:
3090607.ru/note/27-cisco-ip-phone-locale
forum.sysadmins.su/index.php?showtopic=20489
www.voipstore.com/configuring-cisco-7975-ip-phones-for-sip
asteriskpbx.ru/display/Asterisk/CISCO+7911
www.gho.no/2009/05/cisco-ip-phone-configuration-with-asterisk
Офиц. руководство:
www.cisco.com/en/US/docs/voice_ip_comm/cuipph/7960g_7940g/sip/2_0/english/administration/guide/admin2.pdf
www.cisco.com/en/US/docs/voice_ip_comm/cuipph/7962g_7942g/6_0/english/administration/guide/7962G-Admin-Book-Wrapper.html
XML objects:
www.cisco.com/univercd/cc/td/doc/product/voice/vpdd/cdd/5_0/5_0_1/ipphsv/ip503ch2.htm#wp1033491
www.ibm.com/developerworks/wireless/library/wi-voip
webmaxtor.blogspot.com/2009/04/cisco-ipphonedirectory-exit-softkey.html
www.cisco.com/univercd/cc/td/doc/product/voice/vpdd/cdd/5_0/5_0_1/ipphsv/ip503ch2.htm
docstore.mik.ua/univercd/cc/td/doc/product/voice/vpdd/cdd/5_0/ipphsv/ip502apa.htm#wp1007090
my.safaribooksonline.com/book/telephony/1587050609/using-cisco-ip-phone-xml-objects-and-tags/ch04#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTEtNTg3MDUtMDYwLTkvNjE=
Tags:
Hubs:
Total votes 38: ↑35 and ↓3 +32
Views 189K
Comments Comments 30