Приветствую!

Поделюсь еще одним маленьким, но очень полезным костылем к freepbx. Как известно, очень многие любят и пользуют multifon как sip-транк ко всяким астерискам, получая «почти-бесплатный» многоканальный входящий канал связи и вполне интересные цены на исходящий.

Стабильность сервиса, конечно, на уровне его цены. Но многих (в том числе меня) устраивает. При этом можно (и нужно!) одновременно пользоваться сим, например, для исходящих звонков по домашнему региону. Баланс «шевелится», номер не отберут за неиспользование.

Но иногда баланс уходит «в минус». Тогда мультифон отключается, и теряется настройка маршрутизации. При пополнении баланса звонки идут на сим, а не в asterisk.

Тем, у кого много таких транков, особенно на разных PBX (как у меня, я обслуживаю asterisk`и разных клиентов) — довольно проблематично постоянно отслеживать маршрутов «мультифонов» состояние вручную.

Я предлагаю автоматизированное решение для тех, у кого freepbx.
Скрипт запускается по крону (раз в час у меня) и делает следующее:

1) Вытаскивает из базы asterisk регистрационные данные всех транков multifon (по строке регистрации LIKE "%@multifon.ru%");
2) Проверяет на сервисе sm.megafon.ru маршрут, если он неверен — правит на нужный
3) Делает amportal restart для «обновления» транка. Ускоряет процедуру регистрации.

Скрипт запускается по крону, но также есть возможность «дернуть» его ссылкой в любой момент. Можно передать ему параметр «r», который по значениям совпадает с параметром «routing» сервиса sm.megafon.ru.

Вот текст скрипта (файл index.php)
<?php
#включение/отключение мультифона
#автоматическое извлечение из базы FreePBX
#для роутинга на телефон "?r=0", на PBX: "?r=1", на оба: "?r=2"
#vmcl****.ru

#mysql settings
$hostname = "localhost"; 
$username = "mysql_user"; 
$password = "mysql_password"; 
$dbName = "asterisk";

mysql_connect($hostname,$username,$password) or die("NO connect to MySQL: ".mysql_error());
mysql_select_db($dbName) or die("MySQL ERROR:".mysql_error());
mysql_query("set names 'utf8'");

date_default_timezone_set("Europe/Moscow");

if(isset($_GET['r'])) $r = $_GET['r']; else $r = '1'; //если роутинг не задан ?r=X, то включить на PBX

//browser settings
$header = array();
$header[] = 'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
$header[] = 'Cache-Control: max-age=0';
$header[] = 'Connection: keep-alive';
$header[] = 'Keep-Alive: 300';
$header[] = 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7';
$header[] = 'Accept-Language: en-us,en;q=0.5';
$header[] = 'Pragma: ';

//seach multifon trunks
$mf_query = mysql_query('SELECT `data` FROM `sip` WHERE `keyword` = "register" AND `data` LIKE "%@multifon.ru%" ORDER BY `data`') or die("MySQL ERROR:".mysql_error());
while($mf_row = mysql_fetch_array($mf_query, MYSQL_ASSOC)) {
  $pre_data = explode("@", $mf_row['data']);
  $data = explode(":", $pre_data[0]);
  print "Номер {$data[0]}...";
  //читаем
  $ch = curl_init(); 
  curl_setopt($ch, CURLOPT_URL, "https://sm.megafon.ru/sm/client/routing?login={$data[0]}@multifon.ru&password={$data[1]}");
  curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)");
  curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  curl_setopt($ch, CURLOPT_AUTOREFERER, true); 
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_setopt($ch, CURLOPT_ENCODING, '');
  curl_setopt($ch, CURLOPT_TIMEOUT, 20);
  $response = curl_exec($ch);
  curl_close ($ch);
  $routing = json_decode(json_encode(simplexml_load_string($response, "SimpleXMLElement", LIBXML_NOCDATA)), true);
  //проверяем
  if($routing['result']['code'] == 200) { //ответ ok
    if($routing['routing'] == $r) { //не изменился
      print "уже установлен в {$routing['routing']}<br>";
    } else {
      print "был {$routing['routing']}, меняем на $r...";
      $ch = curl_init(); 
      curl_setopt($ch, CURLOPT_URL, "https://sm.megafon.ru/sm/client/routing/set?login={$data[0]}@multifon.ru&password={$data[1]}&routing=$r");
      curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)");
      curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
      curl_setopt($ch, CURLOPT_AUTOREFERER, true); 
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      curl_setopt($ch, CURLOPT_ENCODING, '');
      curl_setopt($ch, CURLOPT_TIMEOUT, 20);
      $response = curl_exec($ch);
      curl_close ($ch);
      $result = json_decode(json_encode(simplexml_load_string($response, "SimpleXMLElement", LIBXML_NOCDATA)), true);
      if($result['result']['code'] == 200) {
          print "{$result['result']['description']}<br>";
      } else {
          print "сервер sm.megafon.ru вернул ошибку {$result['result']['code']} {$result['result']['description']}<br>";
      }
      exec("amportal reload");
    }
  } else {
    print "сервер sm.megafon.ru вернул ошибку {$routing['result']['code']} {$routing['result']['description']}<br>";
  }
}
print "завершено";
?>


Вот sh-файл, который лежит в cron:
#!/bin/sh
#move this file to cron folders

cd /var/www/html/mf && /usr/bin/nohup /usr/bin/php -f index.php >/tmp/mf_php.log &



Скрипт, как видно, находится в каталоге /var/www/html/mf, в области видимости веб-сервера.
Нужно указать только данные для подключения к mysql в секции настроек скрипта.

Удачи!

Комментарии (18)


  1. bougakov
    26.04.2016 21:30

    Спасибо за статью. Посмотрите, пожалуйста, личку — там вопрос про МультиФон.


    1. whoim
      27.04.2016 12:46

      Рад, что пригодилось. Ответил!


  1. vanomel
    27.04.2016 06:08

    А откуда взялась база данных и кто туда эти данные кладет?


    1. doti
      27.04.2016 12:46

      1) Вытаскивает из базы asterisk регистрационные данные всех транков multifon


      1. whoim
        27.04.2016 12:46

        Так точно, спасибо.


    1. Teocraft
      27.04.2016 12:46

      Насколько я знаю, базу создаёт freepbx и, соответственно, он туда и кладёт эти данные.


      1. whoim
        27.04.2016 12:47

        Так точно, при добавлении транка через вебморду данные сохраняются в базе данных.


  1. p00h
    27.04.2016 08:26

    Присоединяюсь к вопросу выше


    1. j3st3r
      27.04.2016 09:16

      С позволения автора отвечу. Так устроен FreePBX: все данные о sip-регистрациях он хранит в MySQL. Если точнее, то в БД asterisk, таблица sip.


      1. whoim
        27.04.2016 12:47

        Спасибо!


  1. xmaster83
    27.04.2016 12:47

    У кого нибудь это мултифон нормальн о работает ??? я два года у же с ним трахаюсь, постоянно оталиваеться пиры виснут и тогдалее.

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

    Такое ощущение, что Мегафон не хочет это направление развивать, а только свою Виртуальную АТС пытаеться втюхать, которая до возмозности астериска даже на 2% не подобралась, в общем хорошобы это читали люди из мегафона


    1. whoim
      27.04.2016 12:48

      Только входящие, для исходящих другой пров с пробросом callerid. Работает 99%, в принципе.


  1. vilgood
    27.04.2016 12:48

    В нас базе данные записаны в таком виде:
    79233333333@multifon.ru: пароль:79233333333@sbc.megafon.ru/79233333333
    Скрипт из запроса берет только номер телефона. Как это поправить?


    1. whoim
      27.04.2016 12:50

      php творит чудеса. Вам нужен explode по ":" -> в массив, далее первый элемент этого массива будет пароль.
      Номер — разбить по @ нулевой элемент массива.

      А зачем такая строка регистрации? Работает и в упрощенном виде же.


  1. barabashek
    27.04.2016 12:50

    Не проще будет использовать bash?
    Делаем запрос curl'ом, парсим вывод, производим действие в зависимости от ответа.


    1. whoim
      27.04.2016 12:51

      Лучший дистрибутив линукс — тот, который ты знаешь, или «гуру» по которому в друзьях :)
      Ну и вопрос в «вытаскивании» данных из транков. На php это чуть проще.


  1. unicsoid
    28.04.2016 09:34

    Хорошая статья, полезная, спасибо.

    Кстати, уже неделю как маршрутизация при переходе через ноль не изменяется. Можно более не отслеживать.
    Такие дела.


    1. whoim
      02.05.2016 17:44

      Очень они вовремя блин :)))