mehanik.me

IP Телефония

Знакомим Panasonic KX-HDV100(130,230,330,430) с телефонной книгой FreePBX(Asterisk)

Знакомим Panasonic KX-HDV100(130,230,330,430) с телефонной книгой FreePBX(Asterisk)

В процессе перехода на IP телефонию приобрели телефоны компании Panasonic KX-HDV130 и KX-HDV230. Формат телефонной книги в данном аппарате мягко говоря ужасен и заливать её на каждый аппарат совсем не хотелось, а значит придётся знакомить аппараты с FreePBX. Готовых решений из коробки не нашлось, пришлось клепать самому. Делюсь подробностями.

В телефонных аппаратах серии KX-HDV используется собственный формат телефонной книги основанный на базе CSV, который можно загружать/выгружать, но его использование усложняется тем, что данную операцию необходимо проделывать вручную. Выполнить подобную операцию для 2-3 телефонов, не самая большая проблема, но когда подобных аппаратов сотни, это становиться огромной проблемой.

Тем более что, для настройки аппаратов использовали провиженинг. Изучая его доступные опции была найдена XMLAPP_LDAP_URL, что позволяет состыковать аппарат с Active Directory и использовать его телефонную книгу..

В процессе изучения вопроса натыкаемся на документацию от компании Panasonic: XML Application Developer’s Guide для Panasonic SIP Phone TGP600, HDV100/130/230/330/430. И в ней мы находим формат, в котором необходимо предоставить аппарату ответ на поисковый запрос:

<?xml version="1.0" encoding="utf-8"?>
<ppxml
 xmlns="http://panasonic/sip_phone"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://panasonic/sip_phone_directorysip_phone_phonebook.xsd">
  <Screen version="2.0”>
    <PhoneBook version="2.0”>
      <Personnel id="1">
        <Name>Test User01</Name>
        <Ruby>Test01</Ruby>
        <PhoneNums>
          <PhoneNum type="ext">6789</PhoneNum>
          <PhoneNum type="company">382719</PhoneNum>
          <PhoneNum type="mobile">928378</PhoneNum>
          <PhoneNum type="home">6789</PhoneNum>
          <PhoneNum type="etc">382719</PhoneNum>
        </PhoneNums>
      </Personnel>
      <Personnel id="2">
        <Name>Test User02</Name>
        <Ruby>Test02</Ruby>
        <PhoneNums>
          <PhoneNum type="ext">6058</PhoneNum>
          <PhoneNum type="company">777058</PhoneNum>
          <PhoneNum type="mobile">888012</PhoneNum>
          <PhoneNum type="home">6058</PhoneNum>
          <PhoneNum type="etc">777058</PhoneNum>
        </PhoneNums>
      </Personnel>
      <Personnel id="3">
        <Name>Test User03</Name>
        <Ruby>Test03</Ruby>
        <PhoneNums>
          <PhoneNum type="ext">6001</PhoneNum>
          <PhoneNum type="company">777001</PhoneNum>
          <PhoneNum type="mobile">888001</PhoneNum>
          <PhoneNum type="home">6001</PhoneNum>
          <PhoneNum type="etc">777001</PhoneNum>
        </PhoneNums>
      </Personnel>
      <Personnel id="4">
        <Name>Test user04</Name>
        <Ruby>Test04</Ruby>
        <PhoneNums>
          <PhoneNum type="ext">6053</PhoneNum>
          <PhoneNum type="company">777053</PhoneNum>
          <PhoneNum type="mobile">888053</PhoneNum>
          <PhoneNum type="home">6053</PhoneNum>
          <PhoneNum type="etc">777053</PhoneNum>
        </PhoneNums>
      </Personnel>
      <Personnel id="5">
        <Name>Test user05</Name>
        <Ruby>Test05</Ruby>
          <PhoneNums>
          <PhoneNum type="ext">6002</PhoneNum>
          <PhoneNum type="company">777002</PhoneNum>
          <PhoneNum type="mobile">888002</PhoneNum>
          <PhoneNum type="home">6002</PhoneNum>
          <PhoneNum type="etc">777002</PhoneNum>
        </PhoneNums>
      </Personnel>
    </PhoneBook>
  </Screen>
</ppxml>

Итак теперь мы знаем как предоставить телефону кусок книги. Путем минимального разбора запроса телефона мы узнаём, что сам поисковый запрос передаётся на сервер через параметр name передаваемый методом GET. Также посредством GET передаётся ещё приличный набор параметров, но для нашей задачи он уже избыточен. Пишем небольшой кусок кода, который мы расположим на сервере FreePBX на PHP.

Готовый скрипт необходимо расположить по пути /var/www/html/ например с названием phonebook.php.

<?php
// Весь код ниже адаптирован для просмотра на сайте, если вас смущает такой способ
// объединения строк, вы всегда можете оформить это приятным для вас образом.

$mysql_conn = mysql_connect('localhost','root',''); // Логин и пароль для подключения к MySQL
mysql_select_db('asterisk', $mysql_conn); // База данных
$query = 'SELECT description AS Name, user AS Telephone FROM devices WHERE';
$query .= ' tech="sip" and description like binary "%'.$_GET["name"].'%" order by user';

$result = mysql_query($query, $mysql_conn);
if (!$result){
    echo mysql_error();
}

$Output .= '<?xml version="1.0" encoding="utf-8"?>'."\r\n";
$Output .= '<ppxml xmlns="http://panasonic/sip_phone"';
$Output .= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
$Output .= ' xsi:schemalocation="http://panasonic/sip_phone_directory/sip_phone_phonebook.xsd">';
$Output .= '<screen version="2.0"><phonebook version="2.0">';

$i = 1;
while($row=mysql_fetch_assoc($result))
{
    $Output .= '<personnel id="'.$i.'">';
    $Output .= '<name>'.$row[Name].'</name>';
    $Output .= '<ruby>'.$row[Name].'</ruby>';
    $Output .= '<phonenums>';
    $Output .= '<phonenum type="ext">'.$row[Telephone].'</phonenum>';
    $Output .= '</phonenums>';
    $Output .= '</personnel>';
    $i++;
}
$Output .= '</phonebook></screen></ppxml>';
echo $Output;
?>

Для того, чтобы телефон начал использовать данную телефонную книгу - необходимо в web-интерфейсе телефона в разделе Telephone - Application Settings заполнить параметр Network Phonebook URL - http://[freepbx_address]/phonebook.php, а также заполнить поля имени пользователя и пароля любыми данными(в скрипте отсутсвует их проверка), т.к. без них телефон не включает функционал телефонной книги.

P.S.: Конечно данный скрипт - это простейшая заплатка решающая задачу доступа к телефонной книге FreePBX(Asterisk), и нету никаких ограничений прав, интергации с Active Directory, контроля доступа пользователей и прочих потенциально возможных прелестей жизни. Но данного функционала вполне достаточно для понимания того, как это работает и если кому-то потребуется - он может доработать данный функционал под себя.