diff --git a/README.md b/README.md index 261a04b..bd7a491 100644 --- a/README.md +++ b/README.md @@ -35,20 +35,14 @@ Make sure you have the following installed on your system: - gui: - freepbx >= 13.0.192 - a working version of [chan-sccp](https://github.com/chan-sccp/chan-sccp) -- PHPx.x-zip has to be installed (where x.x is the installed version of PHP). - For example, on Debian, using PHP7.3 -``` -apt-get install PHP7.3-zip -``` ### Requirements -- chan-sccp module 4.3.4 (or later) channel driver for Asterisk: [See our WIKI](https://github.com/chan-sccp/chan-sccp/wiki/Building-and-Installation-Guide) +- Chan_SCCP module 4.3.4 (or later) channel driver for Asterisk: [See our WIKI](https://github.com/chan-sccp/chan-sccp/wiki/Building-and-Installation-Guide) - sccp_manager expects these configure flags to be set during compilation: ```./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate --enable-video``` - Creating mysql DB from sorce ```mysql -u root asterisk < mysql-v5_enum.sql``` - - TFTP Server running under (recommended) /tftpboot/ [See our WIKI] (https://github.com/chan-sccp/chan-sccp/wiki/setup-tftp-service) - You will need the phone settings templates. You can use the templates taken from the distribution "chan-sccp" ```cp /usr/src/chan-sccp/conf/tftp/\*.xml\* /tftpboot/templates/``` @@ -65,41 +59,30 @@ apt-get install PHP7.3-zip ## Installation -How to install sccp_manager ------ - -1. Creating mysql DB from source using -``` -mysql -p asterisk < /usr/src/chan-sccp/conf/mysql-v5_enum.sql -``` -2. Create a new tab and log in to FreePBX -3. Go to Admin -> Module Admin -4. Click Upload Modules. -5. Enter one of the following urls: - -Stable -``` -https://github.com/chan-sccp/sccp_manager/tarball/develop/chan-sccp-sccp_manager-legacy-1-g9ef59f0.tar -``` -Develop. _This module can be updated through module admin as modifications are made, but may still have issues_ -``` -https://github.com/chan-sccp/sccp_manager/archive/refs/heads/develop.zip -``` -6. Click Download From Web. -7. Click Manage Local Modules. -8. Find and click SCCP Manager. Check Install. Click Process button. -9. Confirm installation. -10. Close Status window. -11. Apply Config to FreePBX. -12. Continue to [Using-SCCP_Manager-to-Manage-chan-sccp](https://github.com/chan-sccp/chan-sccp/wiki/Using-SCCP_Manager-to-Manage-chan-sccp) +1. Download module into your local system. (/var/www/html/admin/modules/) +2. Goto FreePBX Admin -> Module Admin. +3. Click Upload Modules. +4. Browse to the location of the module on your computer and select Upload. +5. Click Manage Local Modules. +6. Find and click SCCP Manager. Check Install. Click Process button. +7. Confirm installation. +8. Close Status window. +9. Apply Config to FreePBX. ### Module update to latest state -If you installed the Develop branch, the module can be updated to the latest version via FreePBX. FreePBX -> Admin -> Module Admin. +If you installed sccp_manager using git clone instead of installing a zip +file / tarball then you can do easily keep up with the latest develop by +doing this: +1. Goto to module into your local system. (/var/www/html/admin/modules/sccp_manager/) + +> cd /var/www/html/admin/modules/sccp_manager/ +> git pull +> git checkout develop ### IMPORTANT NOTES: -- If something stops working, use the Stable branch as described in [Installation](https://github.com/chan-sccp/sccp_manager#installation) +- !!! If something stops working, use the develop branch [develop](https://github.com/chan-sccp/sccp_manager/tree/develop) - This system assumes/requires that you are using the Asterisk realtime database. If you are not yet using the realtime database, you will have to set it up for this module to work ([See](https://github.com/chan-sccp/chan-sccp/wiki/Realtime-Configuration)). - For the cisco phones to work correctly, they should be provisioned with the latest firmware (v8.1 or higher) diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..076d53c --- /dev/null +++ b/README.ru.md @@ -0,0 +1,99 @@ +## Welcome to Develop Chan_SCCP GUI Manager for FreePBX +| [English :gb:/:us:](README.md) | [Russian :ru:](README.ru.md) | [OLD Stable Release](https://github.com/PhantomVl/sccp_manager/tree/master) + +![Gif](https://github.com/PhantomVl/sccp_manager/raw/develop/.dok/image/Demo_1s5.gif) + + * [Installation](https://github.com/PhantomVl/sccp_manager#installation) + * [Prerequisites](https://github.com/PhantomVl/sccp_manager#prerequisites) + * [Links](https://github.com/PhantomVl/sccp_manager#link) + * [Wiki](https://github.com/PhantomVl/sccp_manager/wiki) + +## Link + +[![Download Sccp-Mamager](https://img.shields.io/badge/SccpGUI-build-ff69b4.svg)](https://github.com/PhantomVl/sccp_manager/archive/master.zip)и традиционно добалены новые баги +[![Download Chan-SCCP channel driver for Asterisk](https://img.shields.io/sourceforge/dt/chan-sccp-b.svg)](https://github.com/chan-sccp/chan-sccp/releases/latest) +[![Chan-SCCP Documentation](https://img.shields.io/badge/docs-wiki-blue.svg)](https://github.com/chan-sccp/chan-sccp/wiki) + +### История +Корни идея создания этого проекта лежат в несовершенстве уже существующего и заброшенного проекта. +Для желающих попробовать себя на просторах программирования ссылка на проект (https://github.com/Cynjut/SCCP_Manager). + +### Кому это надо... +Ну в первую очередь для себя, а заодно и для тех у кого есть куча телефонного хлама от компании Cisco. +Если вы планируете использовать Aserisk + FreePBX, то я надеюсь, что данный модуль существенно упростит управление и настройки телефонами от Cisco. +В интернете, существует замечательный проект (IMHO) который интегрирует проприетарный протокол Cisco в Asterisk, конечно он пока далек от идеала, +но все же это замечательная замена серверам CCME, СCM, СUСM ! +Ну я совершенно не представляю себе, сколько времени данный проект будет поддерживаться. + +### Если ты еще с нами ... + +Как я говорил выше, это дополнение к (Aserisk + FreePBX), но нам еще потребуется : + 1. У меня не получилось поставить добиться работы с дисками Aserisk и FreePBX - собираем из исходников + 1.1. Замечательная копания freepbx. Теперь с SNG7-PBX-64bit-1805 все работает ! + 2. Mysql (Maria) + 3. Драйвер протокола SCCP страница (https://github.com/chan-sccp/chan-sccp/) + 4. Ну и этот модуль. + +### Вжно! В этой ветке лежат самые последне нововведения и обновления, и самые последние БАГИ ! + Пользуйся и наслождайся. Так же не забывай писать нам об ошибках, которые ты нашел ! + Это очень нам поможет, Я с радостью исправлю то что ты нашел и добалю новых. + +### Wiki - Основные Инструкции по настройке +Вся документация лежит на Вики [![SCCP Manager Wiki](https://img.shields.io/badge/Wiki-new-blue.svg)](https://github.com/PhantomVl/sccp_manager/wiki) + +### Prerequisites - как говориться все, что хуже этого возможно работать тоже будет .... но только вопрос как ? +Make sure you have the following installed on your system: +- c-compiler: (мне то он не нужен, но как собирать все остальное ?) + - gcc >= 4.4 (note: older not supported, higher advised) + - clang >= 3.6 (note: older not supported, higher advised) +- gnu make +- pbx: + - asterisk >= 1.8 (absolute minimum & not recommended) + - asterisk >= 13.7 or asterisk >= 14.0 or asterisk >= 15.0 (Тестировалось на стендах) +- gui: + - freepbx >= 13.0.192 (http://wiki.freepbx.org/display/FOP/Install+FreePBX) +- standard posix compatible applications like sed, awk, tr + +### Installation Очень короткая инструкция +###### [Полная версия инструкции](https://github.com/PhantomVl/sccp_manager/wiki/step-by-step-instlation) + - Chan_SCCP module 4.3.1 (or later) [See our WIKI](https://github.com/chan-sccp/chan-sccp/wiki/Building-and-Installation-Guide) +> git clone https://github.com/chan-sccp/chan-sccp.git +> git checkout develop + + - Важно ! **_Собираем с флагами и создаем БД для работы:_** +> ./configure ./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate --enable-video +> mysql -u root asterisk < mysql-v5_enum.sql + +- Настраиваем TFTP Server, он нужен для телефонов /tftpboot/ [See our WIKI](https://github.com/chan-sccp/chan-sccp/wiki/setup-tftp-service) +- Настраиваем DHCP serve, как ни странно он тоже нужен [See our WIKI](https://github.com/chan-sccp/chan-sccp/wiki/setup-dhcp-service) + +- Установка модуля +> cd /var/www/html/admin/modules/ +> git clone https://github.com/PhantomVl/sccp_manager.git +> cd /var/www/html/admin/modules/sccp_manager/ +> git checkout develop +> amportal chown +> amportal a ma install sccp_manager + +- Настройка модуля + 1. Открываем "SCCP Connectivity" -> "Server Config" и делаем все, что вам нужно. + 2. Жмем "Сохранить" ..... И Все ! Дальше настройки в рамках концепции Freepbx. + +- Обновление модуля +> cd /var/www/html/admin/modules/sccp_manager/ +> git fetch +> git pull +> git checkout extension_mobility +> or +> git checkout develop + + +### Важно: + - !!! Если это это проект не заработал на твоей системе - переключись на ветку мастер [master](https://github.com/PhantomVl/sccp_manager/tree/master) + !!! Но есть ограничение - ветка master не поддерживает изменения в chan-sccp сделаные после октября 2018 г. + - Желательно иметь Firmware телефонов Cisco, языковые пакеты ну всякое разное. + - Возможно, ты найдешь, то что ищешь, в проекте (https://github.com/dkgroot/provision_sccp) + - Если что-то не так [Wiki GUI](https://github.com/PhantomVl/sccp_manager), [Wiki chan-sccp](https://github.com/chan-sccp/chan-sccp/wiki), +[Wiki FreePbx](https://wiki.freepbx.org/display/FOP/Install+FreePBX) + + diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 00fcc80..7e6381e 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -86,13 +86,23 @@ namespace FreePBX\modules; class Sccp_manager extends \FreePBX_Helpers implements \BMO { /* Field Values for type seq */ + +// const General - sccp.conf = '0'; +// const General - sccp.conf[general] = '0'; +// const General - sccp.conf[%keyset%] = '5'; NAME space +// const General - sccp.conf[%keyset%] = '6'; data +// const General - default.xml = '10'; +// const General - template.xml = '20'; +// const General - system_path = '2'; +// const General - don't store = '99'; +// private $SCCP_LANG_DICTIONARY = 'SCCP-dictionary.xml'; // CISCO LANG file search in /tftp-path private $SCCP_LANG_DICTIONARY = 'be-sccp.jar'; // CISCO LANG file search in /tftp-path private $pagedata = null; private $sccp_driver_ver = '11.4'; // Ver fore SCCP.CLASS.PHP - public $sccp_manager_ver = '14.1.0.0'; + public $sccp_manager_ver = '14.0.0.2'; public $sccp_branch = 'm'; // Ver fore SCCP.CLASS.PHP private $tftpLang = array(); - +// private $hint_context = '@ext-local'; /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Get it from Config !!! private $hint_context = array('default' => '@ext-local'); /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Get it from Config !!! private $val_null = 'NONE'; /// REPLACE to null Field public $sccp_model_list = array(); @@ -105,11 +115,6 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { public $class_error; //error construct public $info_warning; - // Move all non sccp_manager specific functions to traits - use \FreePBX\modules\Sccp_Manager\sccpManTraits\helperFunctions; - use \FreePBX\modules\Sccp_Manager\sccpManTraits\ajaxHelper; // TODO should migrate this to child class - use \FreePBX\modules\Sccp_Manager\sccpManTraits\bmoFunctions; - public function __construct($freepbx = null) { if ($freepbx == null) { throw new Exception("Not given a FreePBX Object"); @@ -119,9 +124,10 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->db = $freepbx->Database; $this->cnf_wr = \FreePBX::WriteConfig(); $this->cnf_read = \FreePBX::LoadConfig(); +// $this->v = new \Respect\Validation\Validator(); $driverNamespace = "\\FreePBX\\Modules\\Sccp_manager"; if (class_exists($driverNamespace, false)) { - foreach (glob(__DIR__ . "/sccpManClasses/*.class.php") as $driver) { + foreach (glob(__DIR__ . "/Sccp_manager.inc/*.class.php") as $driver) { if (preg_match("/\/([a-z1-9]*)\.class\.php$/i", $driver, $matches)) { $name = $matches[1]; $class = $driverNamespace . "\\" . $name; @@ -139,7 +145,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return; } - $this->sccpvalues = $this->dbinterface->get_db_SccpSetting(); // Overwrite Exist + $this->getSccpSettingFromDB(); // Overwrite Exist // $this->getSccpSetingINI(false); // get from sccep.ini $this->initializeSccpPath(); $this->initVarfromDefs(); @@ -184,7 +190,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $htmlret .= load_view(__DIR__ . '/views/formShow.php', array( 'itm' => $item, 'h_show' => $heder_show, 'form_prefix' => $form_prefix, 'fvalues' => $form_values, - 'tftp_lang' => $this->tftpLang, 'metainfo' => $this->sccp_metainfo)); + 'tftp_lang' => $this->getTftpLang(), 'metainfo' => $this->sccp_metainfo)); } } else { $htmlret .= load_view(__DIR__ . '/views/formShowError.php'); @@ -259,49 +265,186 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } } + /* unused but FPBX API requires it */ + + public function doConfigPageInit($page) { + $this->doGeneralPost(); + } + + /* unused but FPBX API requires it */ + + public function install() { + + } + + /* unused but FPBX API requires it */ + + public function uninstall() { + + } + + /* unused but FPBX API requires it */ + + public function backup() { + + } + + /* unused but FPBX API requires it */ + + public function restore($backup) { + + } + + public function getActionBar($request) { + $buttons = array(); + switch ($request['display']) { + case 'sccp_adv': + if (empty($request['tech_hardware'])) { + break; + } + $buttons = array( + 'submit' => array( + 'name' => 'ajaxsubmit', + 'id' => 'ajaxsubmit', + 'value' => _("Save") + ), + 'Save' => array( + 'name' => 'ajaxsubmit2', + 'id' => 'ajaxsubmit2', + 'stayonpage' => 'yes', + 'value' => _("Save + Continue") + ), + 'cancel' => array( + 'name' => 'cancel', + 'id' => 'ajaxcancel', + 'data-search' => '?display=sccp_adv', + 'data-hash' => 'sccpdialplan', + 'value' => _("Cancel") + ), + ); + break; + case 'sccp_phone': + if (empty($request['tech_hardware'])) { + break; + } + $buttons = array( + 'submit' => array( + 'name' => 'ajaxsubmit', + 'id' => 'ajaxsubmit', + 'value' => _("Save") + ), + 'Save' => array( + 'name' => 'ajaxsubmit2', + 'id' => 'ajaxsubmit2', + 'stayonpage' => 'yes', + 'value' => _("Save + Continue") + ), + 'cancel' => array( + 'name' => 'cancel', + 'id' => 'ajaxcancel', + 'data-search' => '?display=sccp_phone', + 'data-hash' => 'sccpdevice', + 'value' => _("Cancel") + ), + ); + + break; + case 'sccpsettings': + $buttons = array( + 'submit' => array( + 'name' => 'ajaxsubmit', + 'id' => 'ajaxsubmit', + 'value' => _("Submit") + ), + 'reset' => array( + 'name' => 'reset', + 'id' => 'ajaxcancel', + 'data-reload' => 'reload', + 'value' => _("Reset") + ), + ); + + break; + } + return $buttons; + } + /* * Show form information - General */ - public function settingsShowPage() { + public function myShowPage() { $request = $_REQUEST; $action = !empty($request['action']) ? $request['action'] : ''; - - $this->pagedata = array( - "general" => array( - "name" => _("General SCCP Settings"), - "page" => 'views/server.setting.php' - ), - "sccpdevice" => array( - "name" => _("SCCP Device"), - "page" => 'views/server.device.php' - ), - "sccpurl" => array( - "name" => _("SCCP Device URL"), - "page" => 'views/server.url.php' - ), - "sccpntp" => array( - "name" => _("SCCP Time"), - "page" => 'views/server.datetime.php' - ), - "sccpcodec" => array( - "name" => _("SCCP Codec"), - "page" => 'views/server.codec.php' - ), - "sccpadv" => array( - "name" => _("Advanced SCCP Settings"), - "page" => 'views/server.advanced.php' - ), - "sccpinfo" => array( - "name" => _("SCCP info"), - "page" => 'views/server.info.php' - ) - ); - // If view is set to simple, remove the ntp, codec and advanced tabs - if (isset($this->sccpvalues['displayconfig']['data']) && ($this->sccpvalues['displayconfig']['data'] == 'sccpsimple')) { - unset($this->pagedata['sccpntp'], $this->pagedata['sccpcodec'], $this->pagedata['sccpadv'] ); + /* + if ($this->sccpvalues['sccp_compatible']['data'] >= '433') { + $this->sccp_metainfo = $this->srvinterface->getGlobalsFromMetaData('general'); + } + */ + if (!empty($this->sccpvalues['displayconfig'])) { + if (!empty($this->sccpvalues['displayconfig']['data']) && ($this->sccpvalues['displayconfig']['data'] == 'sccpsimple')) { + $this->pagedata = array( + "general" => array( + "name" => _("General SCCP Settings"), + "page" => 'views/server.setting.php' + ), + "sccpdevice" => array( + "name" => _("SCCP Device"), + "page" => 'views/server.device.php' + ), + "sccpurl" => array( + "name" => _("SCCP Device URL"), + "page" => 'views/server.url.php' + ), + "sccpinfo" => array( + "name" => _("SCCP info"), + "page" => 'views/server.info.php' + ), + ); + } + } + + if (empty($this->pagedata)) { + //$driver = $this->FreePBX->Config->get_conf_setting('ASTSIPDRIVER'); + $this->pagedata = array( + "general" => array( + "name" => _("General SCCP Settings"), + "page" => 'views/server.setting.php' + ), + "sccpdevice" => array( + "name" => _("SCCP Device"), + "page" => 'views/server.device.php' + ), + "sccpurl" => array( + "name" => _("SCCP Device URL"), + "page" => 'views/server.url.php' + ), + "sccpntp" => array( + "name" => _("SCCP Time"), + "page" => 'views/server.datetime.php' + ), + "sccpcodec" => array( + "name" => _("SCCP Codec"), + "page" => 'views/server.codec.php' + ), + "sccpadv" => array( + "name" => _("Advanced SCCP Settings"), + "page" => 'views/server.advanced.php' + ), + "sccpinfo" => array( + "name" => _("SCCP info"), + "page" => 'views/server.info.php' + ), + ); + } + if (!empty($this->pagedata)) { + foreach ($this->pagedata as &$page) { + ob_start(); + include($page['page']); + $page['content'] = ob_get_contents(); + ob_end_clean(); + } } - $this->processPageData(); return $this->pagedata; } @@ -314,7 +457,14 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { "page" => 'views/server.info.php' ), ); - $this->processPageData(); + + foreach ($this->pagedata as &$page) { + ob_start(); + include($page['page']); + $page['content'] = ob_get_contents(); + ob_end_clean(); + } + return $this->pagedata; } @@ -322,36 +472,44 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $request = $_REQUEST; $action = !empty($request['action']) ? $request['action'] : ''; $inputform = !empty($request['tech_hardware']) ? $request['tech_hardware'] : ''; - switch ($inputform) { - case 'dialplan': - $this->pagedata = array( - "general" => array( - "name" => _("SCCP Dial Plan information"), - "page" => 'views/form.dptemplate.php' - ) - ); - break; - default: - $this->pagedata = array( - "general" => array( - "name" => _("SCCP Model information"), - "page" => 'views/advserver.model.php' - ), - "sccpkeyset" => array( - "name" => _("SCCP Device Keyset"), - "page" => 'views/advserver.keyset.php' - ) - ); - if ($this->sccpvalues['siptftp']['data'] == 'on') { - $this->pagedata["sccpdialplan"] = array( - "name" => _("SIP Dial Plan information"), - "page" => 'views/advserver.dialtemplate.php' + + if (empty($this->pagedata)) { + switch ($inputform) { + case 'dialplan': + $this->pagedata = array( + "general" => array( + "name" => _("SCCP Dial Plan information"), + "page" => 'views/form.dptemplate.php' + ) ); - } - break; + break; + default: + $this->pagedata = array( + "general" => array( + "name" => _("SCCP Model information"), + "page" => 'views/advserver.model.php' + ), + "sccpkeyset" => array( + "name" => _("SCCP Device Keyset"), + "page" => 'views/advserver.keyset.php' + ) + ); + if ($this->sccpvalues['siptftp']['data'] == 'on') { + $this->pagedata["sccpdialplan"] = array( + "name" => _("SIP Dial Plan information"), + "page" => 'views/advserver.dialtemplate.php' + ); + } + break; + } + foreach ($this->pagedata as &$page) { + ob_start(); + include($page['page']); + $page['content'] = ob_get_contents(); + ob_end_clean(); + } } - $this->processPageData(); return $this->pagedata; } @@ -359,78 +517,525 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $request = $_REQUEST; $action = !empty($request['action']) ? $request['action'] : ''; $inputform = !empty($request['tech_hardware']) ? $request['tech_hardware'] : ''; - switch ($inputform) { - case "cisco": - $this->pagedata = array( - "general" => array( - "name" => _("Device configuration"), - "page" => 'views/form.adddevice.php' - ), - "buttons" => array( - "name" => _("Device Buttons"), - "page" => 'views/form.buttons.php' - ), - "advanced" => array( - "name" => _("Device SCCP Advanced"), - "page" => 'views/form.devadvanced.php' - ) - ); - break; - case "cisco-sip": - $this->pagedata = array( - "general" => array( - "name" => _("Sip device configuration"), - "page" => 'views/form.addsdevice.php' - ), - "buttons" => array( - "name" => _("Sip device Buttons"), - "page" => 'views/form.sbuttons.php' - ) - ); - break; + /* + if ($this->sccpvalues['sccp_compatible']['data'] >= '433') { + $this->sccp_metainfo = $this->srvinterface->getGlobalsFromMetaData('device'); + } + */ + if (empty($this->pagedata)) { + switch ($inputform) { + case "cisco": + $this->pagedata = array( + "general" => array( + "name" => _("Device configuration"), + "page" => 'views/form.adddevice.php' + ), + "buttons" => array( + "name" => _("Device Buttons"), + "page" => 'views/form.buttons.php' + )); + if ($this->sccpvalues['sccp_compatible']['data'] < '433') { + $this->pagedata["sccpcodec"] = array( + "name" => _("Device SCCP Codec"), + "page" => 'views/server.codec.php' + ); + } + if ($this->sccpvalues['sccp_compatible']['data'] >= '433') { + $this->pagedata["advanced"] = array( + "name" => _("Device SCCP Advanced"), + "page" => 'views/form.devadvanced.php' + ); + } + break; + case "cisco-sip": + $this->pagedata = array( + "general" => array( + "name" => _("Sip device configuration"), + "page" => 'views/form.addsdevice.php' + ), + "buttons" => array( + "name" => _("Sip device Buttons"), + "page" => 'views/form.sbuttons.php' + )); + /* + if ($this->sccpvalues['sccp_compatible']['data'] < '433') { + $this->pagedata["sccpcodec"] = array( + "name" => _("Device SCCP Codec"), + "page" => 'views/server.codec.php' + ); + } + */ + break; - case "r_user": - $this->pagedata = array( - "general" => array( - "name" => _("Roaming User configuration"), - "page" => 'views/form.addruser.php' - ), - "buttons" => array( - "name" => _("Device Buttons"), - "page" => 'views/form.buttons.php' - ), - ); - break; - - default: - $this->pagedata = array( - "general" => array( - "name" => _("SCCP Extension"), - "page" => 'views/hardware.extension.php' - ), - "sccpdevice" => array( - "name" => _("SCCP Phone"), - "page" => 'views/hardware.phone.php' - ) - ); - if ($this->sccpvalues['siptftp']['data'] == 'on') { - $this->pagedata["sipdevice"] = array( - "name" => _("SIP CISCO Phone"), - "page" => 'views/hardware.sphone.php' + case "r_user": + $this->pagedata = array( + "general" => array( + "name" => _("Roaming User configuration"), + "page" => 'views/form.addruser.php' + ), + "buttons" => array( + "name" => _("Device Buttons"), + "page" => 'views/form.buttons.php' + ), ); - } - break; + + break; + + default: + $this->pagedata = array( + "general" => array( + "name" => _("SCCP Extension"), + "page" => 'views/hardware.extension.php' + ), + "sccpdevice" => array( + "name" => _("SCCP Phone"), + "page" => 'views/hardware.phone.php' + ) + ); + if ($this->sccpvalues['siptftp']['data'] == 'on') { + $this->pagedata["sipdevice"] = array( + "name" => _("SIP CISCO Phone"), + "page" => 'views/hardware.sphone.php' + ); + } + break; + } + foreach ($this->pagedata as &$page) { + ob_start(); + include($page['page']); + $page['content'] = ob_get_contents(); + ob_end_clean(); + } } - $this->processPageData(); + return $this->pagedata; } - public function processPageData() { - foreach ($this->pagedata as &$page) { - ob_start(); - include($page['page']); - $page['content'] = ob_get_contents(); - ob_end_clean(); + public function formShowPage() { + $request = $_REQUEST; + $action = !empty($request['action']) ? $request['action'] : ''; + + if (empty($this->pagedata)) { + //$driver = $this->FreePBX->Config->get_conf_setting('ASTSIPDRIVER'); + $this->pagedata = array( + "general" => array( + "name" => _("SCCP Extension"), + "page" => 'views/extension.page.php' + ) + ); + + $this->pagedata['sccpdevice'] = array( + "name" => _("SCCP Phone"), + "page" => 'views/phone.page.php' + ); + + foreach ($this->pagedata as &$page) { + ob_start(); + include($page['page']); + $page['content'] = ob_get_contents(); + ob_end_clean(); + } + } + + return $this->pagedata; + } + + public function getRightNav($request) { + if (isset($request['tech_hardware']) && ($request['tech_hardware'] == 'cisco')) { + return load_view(__DIR__ . "/views/hardware.rnav.php", array('request' => $request)); + } + } + + public function ajaxRequest($req, &$setting) { + // Called first by BMO. Must return true or request will be aborted. + // See https://wiki.freepbx.org/display/FOP/BMO+Ajax+Calls + switch ($req) { + case 'backupsettings': + case 'savesettings': + case 'save_hardware': + case 'save_sip_hardware': + case 'save_ruser': + case 'save_dialplan_template': + case 'delete_hardware': + case 'getPhoneGrid': + case 'getExtensionGrid': + case 'getDeviceModel': + case 'getUserGrid': + case 'getSoftKey': + case 'getDialTemplate': + case 'create_hw_tftp': + case 'reset_dev': + case 'reset_token': + case 'model_enabled': + case 'model_disabled': + case 'model_update': + case 'model_add': + case 'model_delete': + case 'update_button_label': + case 'updateSoftKey': + case 'deleteSoftKey': + case 'delete_dialplan': + return true; + break; + default: + return false; + } + } + + // !TODO!: this should go into it's only ajax.html.php file (see: dahdiconfig) + // ajaxHandler is called after ajaxRequest returns true + public function ajaxHandler() { + $request = $_REQUEST; + $msg = array(); + $cmd_id = $request['command']; + switch ($cmd_id) { + case 'savesettings': + $action = isset($request['sccp_createlangdir']) ? $request['sccp_createlangdir'] : ''; + if ($action == 'yes') { + $this->initializeTFtpLanguagePath(); + } + $this->handleSubmit($request); + // $this->saveSccpSettings(); + //$this->createDefaultSccpConfig(); + $this->createDefaultSccpXml(); + + $res = $this->srvinterface->sccp_reload(); + $msg [] = 'Config Saved: ' . $res['Response']; + $msg [] = 'Info :' . $res['data']; + // !TODO!: It is necessary in the future to check, and replace all server responses on correct messages. Use _(msg) + return array('status' => true, 'message' => $msg, 'reload' => true); + break; + case 'save_sip_hardware': + case 'save_hardware': + $this->saveSccpDevice($request); + return array('status' => true, 'search' => '?display=sccp_phone', 'hash' => 'sccpdevice'); + + break; + case 'save_ruser': + //$res = $request; + $res = $this->handleRoamingUsers($request); + return array('status' => true, 'search' => '?display=sccp_phone', 'hash' => 'general'); + break; + case 'save_dialplan_template': + /* !TODO!: -TODO-: dialplan templates should be removed (only required for very old devices (like ATA) */ + // ------------------------------- Old + Sip device support - In the development--- + $res = $this->saveDialPlan($request); + //public + if (empty($res)) { + return array('status' => true, 'search' => '?display=sccp_adv', 'hash' => 'sccpdialplan'); + } else { + return array('status' => false, 'message' => print_r($res)); + } + break; + case 'delete_dialplan': + if (!empty($request['dialplan'])) { + $get_file = $request['dialplan']; + $res = $this->deleteDialPlan($get_file); + return array('status' => true, 'message' => 'Dial Template has been deleted ! ', 'table_reload' => true); + } else { + return array('status' => false, 'message' => print_r($res)); + } + break; + // ------------------------------- Old device support - In the development--- + case 'delete_hardware': + if (!empty($request['idn'])) { + foreach ($request['idn'] as $idv) { + if ($this->strpos_array($idv, array('SEP', 'ATA', 'VG')) !== false) { + $this->dbinterface->write('sccpdevice', array('name' => $idv), 'delete', "name"); + $this->dbinterface->write('sccpbuttons', array(), 'delete', '', $idv); + $this->deleteSccpDeviceXML($idv); // Концы в вводу !! + $this->srvinterface->sccpDeviceReset($idv); + } + } + return array('status' => true, 'table_reload' => true, 'message' => 'Hardware device has been deleted! '); + } + break; + case 'create_hw_tftp': + $ver_id = ' Test !'; + if (!empty($request['idn'])) { + $models = array(); + foreach ($request['idn'] as $idv) { + $this->deleteSccpDeviceXML($idv); + $models [] = array('name' => $idv); + } + } else { + $this->deleteSccpDeviceXML('all'); + $models = $this->dbinterface->HWextension_db_SccpTableData("SccpDevice"); + } + + $this->createDefaultSccpXml(); // Default XML + $ver_id = ' on found active model !'; + foreach ($models as $data) { + $ver_id = $this->createSccpDeviceXML($data['name']); + if ($ver_id == -1) { + return array('status' => false, 'message' => 'Error Create Configuration Divice :' . $data['name']); + } + }; + + if ($this->sccpvalues['siptftp']['data'] == 'on') { // Check SIP Support Enabled + $this->createSccpXmlSoftkey(); // Create Softkey Sets for SIP + } + // !TODO!: -TODO-: Do these returned message strings work with i18n ? + return array('status' => true, 'message' => 'Create new config files (version:' . $ver_id . ')'); + + break; + case 'reset_token': + case 'reset_dev': + $msg = ''; + $msgr = array(); + $msgr[] = 'Reset command send'; + if (!empty($request['name'])) { + foreach ($request['name'] as $idv) { + $msg = strpos($idv, 'SEP-'); + if (!(strpos($idv, 'SEP') === false)) { + if ($cmd_id == 'reset_token') { + $res = $this->srvinterface->sccp_reset_token($idv); + + $msgr[] = $msg . ' ' . $res['Response'] . ' ' . $res['data']; + } else { + $res = $this->srvinterface->sccpDeviceReset($idv); + $msgr[] = $msg . ' ' . $res['Response'] . ' ' . $res['data']; + } + } + if ($idv == 'all') { + $dev_list = $this->srvinterface->sccp_get_active_device(); + foreach ($dev_list as $key => $data) { + if ($cmd_id == 'reset_token') { + if (($data['token'] == 'Rej') || ($data['status'] == 'Token ')) { + $res = $this->srvinterface->sccp_reset_token($idv); + $msgr[] = 'Send Token reset to :' . $key; + } + } else { + $res = $this->srvinterface->sccpDeviceReset($idv); + $msgr[] = $res['Response'] . ' ' . $res['data']; + } + } + } + } + } + return array('status' => true, 'message' => $msgr, 'reload' => true); + break; + case 'update_button_label': + $msg = ''; + $hw_list = array(); + if (!empty($request['name'])) { + foreach ($request['name'] as $idv) { + if (!(strpos($idv, 'SEP') === false)) { + $hw_list[] = array('name' => $idv); + } + if ($idv == 'all') { + + } + } + } + $res = $this->updateSccpButtons($hw_list); + $msg .= $res['Response'] . ' raw: ' . $res['data'] . ' '; + return array('status' => true, 'message' => 'Update Butons Labels Complite ' . $msg, 'reload' => true); + case 'model_add': + $save_settings = array(); + $key_name = array('model', 'vendor', 'dns', 'buttons', 'loadimage', 'loadinformationid', 'nametemplate'); + $upd_mode = 'replace'; + case 'model_update': + if ($request['command'] == 'model_update') { + $key_name = array('model', 'loadimage', 'nametemplate'); + $upd_mode = 'update'; + } + if (!empty($request['model'])) { + foreach ($key_name as $key => $value) { + if (!empty($request[$value])) { + $save_settings[$value] = $request[$value]; + } else { + $save_settings[$value] = $this->val_null; // null + } + } + $this->dbinterface->write('sccpdevmodel', $save_settings, $upd_mode, "model"); + return array('status' => true, 'table_reload' => true); + } + return $save_settings; + break; + case 'model_enabled': + $model_set = '1'; // fall through intentionally + case 'model_disabled': + if ($request['command'] == 'model_disabled') { + $model_set = '0'; + } + $msg = ''; + $save_settings = array(); + if (!empty($request['model'])) { + foreach ($request['model'] as $idv) { + $this->dbinterface->write('sccpdevmodel', array('model' => $idv, 'enabled' => $model_set), 'update', "model"); + } + } + return array('status' => true, 'table_reload' => true); + break; + case 'model_delete': + if (!empty($request['model'])) { + $this->dbinterface->write('sccpdevmodel', array('model' => $request['model']), 'delete', "model"); + return array('status' => true, 'table_reload' => true); + } + break; + case 'getDeviceModel': + switch ($request['type']) { + case 'all': + case 'extension': + case 'enabled': + $devices = $this->getSccpModelInformation($request['type'], $validate = true); + break; + } + if (empty($devices)) { + return array(); + } + return $devices; + break; + + case 'deleteSoftKey': + if (!empty($request['softkey'])) { + $id_name = $request['softkey']; + unset($this->sccp_conf_init[$id_name]); + $this->createDefaultSccpConfig(); + $msg = print_r($this->srvinterface->sccp_reload(), 1); + return array('status' => true, 'table_reload' => true); + } + break; + case 'updateSoftKey': + if (!empty($request['id'])) { + $id_name = preg_replace('/[^A-Za-z0-9]/', '', $request['id']); + $this->sccp_conf_init[$id_name]['type'] = "softkeyset"; + foreach ($this->extconfigs->getextConfig('keyset') as $keyl => $vall) { + if (!empty($request[$keyl])) { + $this->sccp_conf_init[$id_name][$keyl] = $request[$keyl]; + } + } + $this->createDefaultSccpConfig(); + + // !TODO!: -TODO-: Check SIP Support Enabled + $this->createSccpXmlSoftkey(); + $msg = print_r($this->srvinterface->sccp_reload(), 1); + return array('status' => true, 'table_reload' => true); + } + break; + case 'getSoftKey': + $result = array(); + $i = 0; + $keyl = 'default'; + foreach ($this->srvinterface->sccp_list_keysets() as $keyl => $vall) { + $result[$i]['softkeys'] = $keyl; + if ($keyl == 'default') { + foreach ($this->extconfigs->getextConfig('keyset') as $key => $value) { + $result[$i][$key] = str_replace(',', '
', $value); + } + } else { + foreach ($this->getMyConfig('softkeyset', $keyl) as $key => $value) { + $result[$i][$key] = str_replace(',', '
', $value); + } + } + + $i++; + } + return $result; + break; + case 'getExtensionGrid': + $result = $this->dbinterface->HWextension_db_SccpTableData('SccpExtension'); + if (empty($result)) { + return array(); + } + /* + $res_info = $this->aminterface->core_list_all_exten('exten'); + if (!empty($res_info)) { + foreach ($result as $key => $value) { + $tpm_info = $res_info[$value['name']]; + if (!empty($tpm_info)) { + $result[$key]['line_status'] = $tpm_info['status']; + $result[$key]['line_statustext'] = $tpm_info['statustext']; + } else { + $result[$key]['line_status'] = ''; + $result[$key]['line_statustext'] = ''; + } + } + } + * + */ + return $result; + break; + case 'getPhoneGrid': + $cmd_type = !empty($request['type']) ? $request['type'] : ''; + + $result = $this->dbinterface->HWextension_db_SccpTableData('SccpDevice', array('type' => $cmd_type)); + if ($cmd_type == 'cisco-sip') { + return $result; + } + $staus = $this->srvinterface->sccp_get_active_device(); + if (empty($result)) { + $result = array(); + } else { + foreach ($result as &$dev_id) { + $id_name = $dev_id['name']; + if (!empty($staus[$id_name])) { + $dev_id['description'] = $staus[$id_name]['descr']; + $dev_id['status'] = $staus[$id_name]['status']; + $dev_id['address'] = $staus[$id_name]['address']; + $dev_id['new_hw'] = 'N'; + $staus[$id_name]['news'] = 'N'; + } else { + $dev_id['description'] = '- -'; + $dev_id['status'] = 'not connected'; + $dev_id['address'] = '- -'; + } + } + } + if (!empty($staus)) { + foreach ($staus as $dev_ids) { + $id_name = $dev_ids['name']; + if (empty($dev_ids['news'])) { + $dev_data = $this->srvinterface->sccp_getdevice_info($id_name); + if (!empty($dev_data['SCCP_Vendor']['model_id'])) { + $dev_addon = $dev_data['SCCP_Vendor']['model_addon']; + if (empty($dev_addon)) { + $dev_addon = null; + } + $dev_schema = $this->getSccpModelInformation('byciscoid', false, "all", array('model' => $dev_data['SCCP_Vendor']['model_id'])); + if (empty($dev_schema)) { + $dev_schema[0]['model'] = "ERROR in Model Schema"; + } + $result[] = array('name' => $id_name, 'mac' => $id_name, 'button' => '---', 'type' => $dev_schema[0]['model'], 'new_hw' => 'Y', + 'description' => '*NEW* ' . $dev_ids['descr'], 'status' => '*NEW* ' . $dev_ids['status'], 'address' => $dev_ids['address'], + 'addon' => $dev_addon); + } + } + } + } + return $result; + break; + case 'getDialTemplate': + // ------------------------------- Old device support - In the development--- + $result = $this->getDialPlanList(); + if (empty($result)) { + $result = array(); + } + return $result; + break; + case 'backupsettings': + // ------------------------------- Old device support - In the development--- + $filename = $this->createSccpBackup(); + $file_name = basename($filename); + + header("Content-Type: application/zip"); + header("Content-Disposition: attachment; filename=$file_name"); + header("Content-Length: " . filesize($filename)); + + readfile($filename); + unlink($filename); + + // return array('status' => false, 'message' => $result); + return $result; + break; + } + } + + public function doGeneralPost() { + // $this->FreePBX->WriteConfig($config); + if (!isset($_REQUEST['Submit'])) { + return; } } @@ -626,6 +1231,13 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $value = $get_settings[$hdr_prefix . 'netlang'] . ':' . $get_settings[$hdr_prefix . 'devlang']; } break; + /* + case '_json': + foreach ($get_settings[$hdr_arprefix . $key.'_sip'] as $vkey => $vval) { + } + break; + + */ default: if (!empty($get_settings[$hdr_prefix . $key])) { $value = $get_settings[$hdr_prefix . $key]; @@ -682,9 +1294,9 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->dbinterface->write('sccpbuttons', $save_buttons, $update_hw, '', $name_dev); $this->createSccpDeviceXML($name_dev); if ($hw_id == 'new') { - $this->aminterface->sccpDeviceReset($name_dev, 'reset'); + $this->srvinterface->sccpDeviceReset($name_dev); } else { - $this->aminterface->sccpDeviceReset($name_dev, 'restart'); + $this->srvinterface->sccpDeviceRestart($name_dev); } return $save_settings; @@ -777,7 +1389,8 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { if (!empty($save_settings)) { $this->saveSccpSettings($save_settings); - $this->sccpvalues = $this->dbinterface->get_db_SccpSetting(); + $this->getSccpSettingFromDB(); + // $this->createDefaultSccpConfig(); } $this->createDefaultSccpConfig(); // Rewrite Config. $save_settings[] = array('status' => true); @@ -790,8 +1403,16 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $save_buttons = array(); $save_settings = array(); + /* + $def_feature = array('parkinglot' => array('name' => 'P.slot', 'value' => 'default'), + 'devstate' => array('name' => 'Coffee', 'value' => 'coffee'), + 'monitor' => array('name' => 'Record Calls', 'value' => '') + ); + */ $name_dev = ''; $db_field = $this->dbinterface->HWextension_db_SccpTableData("get_columns_sccpuser"); + // $hw_id = (empty($get_settings['sccp_deviceid'])) ? 'new' : $get_settings['sccp_deviceid']; + // $update_hw = ($hw_id == 'new') ? 'update' : 'clear'; $hw_prefix = 'SEP'; $name_dev = $get_settings[$hdr_prefix . 'id']; $save_buttons = $this->getPhoneButtons($get_settings, $name_dev, 'sccpline'); @@ -868,6 +1489,11 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return $save_settings; } + public function getSccpSettingFromDB() { + $this->sccpvalues = $this->dbinterface->get_db_SccpSetting(); + return; + } + public function getMyConfig($var = null, $id = "noid") { switch ($var) { case "voicecodecs": @@ -997,10 +1623,41 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return true; } + function Sccp_manager_hookGet_config($engine) { + $this->debugdata($engine); + } + + function Sccp_manager_get_config($engine) { + $this->debugdata($engine); + } + + /* + function soundlang_hookGet_config($engine) { + + global $core_conf; + $this->debugdata($engine); + + switch ($engine) { + case "asterisk": + if (isset($core_conf) && is_a($core_conf, "core_conf")) { + $language = FreePBX::Soundlang()->getLanguage(); + if ($language != "") { + $core_conf->addSipGeneral('language', $language); + $core_conf->addIaxGeneral('language', $language); + } + } + break; + } + } + */ + /** * Retrieve Active Codecs * return fiends Lag pack */ + public function getTftpLang() { + return $this->tftpLang; + } private function initTftpLang() { $result = array(); @@ -1063,7 +1720,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->sccppath["asterisk"] = $confDir; } } - $ver_id = $this->aminterface->get_compatible_sccp(); + $ver_id = $this->srvinterface->get_compatible_sccp(); if (!empty($this->sccpvalues['SccpDBmodel'])) { $ver_id = $this->sccpvalues['SccpDBmodel']['data']; } @@ -1096,7 +1753,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } } - $hint = $this->aminterface->core_list_hints(); + $hint = $this->srvinterface->sccp_list_hints(); foreach ($hint as $key => $value) { if ($this->hint_context['default'] != $value) { $this->hint_context[$key] = $value; @@ -1109,7 +1766,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { */ function createSccpXmlSoftkey() { - foreach ($this->aminterface->sccp_list_keysets() as $keyl => $vall) { + foreach ($this->srvinterface->sccp_list_keysets() as $keyl => $vall) { $this->xmlinterface->create_xmlSoftkeyset($this->sccp_conf_init, $this->sccppath, $keyl); } } @@ -1356,8 +2013,9 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $dir_info['asterisk'] = $this->findAllFiles($amp_conf['ASTETCDIR']); $dir_info['tftpdir'] = $this->findAllFiles($this->sccppath["tftp_path"]); $dir_info['driver'] = $this->FreePBX->Core->getAllDriversInfo(); - $dir_info['core'] = $this->aminterface->getSCCPVersion(); - $dir_info['realtime'] = $this->aminterface->getRealTimeStatus(); + $dir_info['core'] = $this->srvinterface->getSCCPVersion(); + $dir_info['realtime'] = $this->srvinterface->sccp_realtime_status(); + $dir_info['srvinterface'] = $this->srvinterface->info(); $dir_info['extconfigs'] = $this->extconfigs->info(); $dir_info['dbinterface'] = $this->dbinterface->info(); $dir_info['XML'] = $this->xmlinterface->info(); @@ -1525,9 +2183,12 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $res = array(); $default_hint = '@ext-local'; + // get all extension + // $res = $this->srvinterface->core_list_all_exten('hint', $filter); + if (empty($res)) { // Old Req get all hints - $tmp_data = $this->aminterface->core_list_all_hints(); + $tmp_data = $this->srvinterface->sccp_list_all_hints(); foreach ($tmp_data as $value) { $res[$value] = array('key' => $value, 'exten' => $this->before('@', $value), 'label' => $value); } @@ -1561,5 +2222,154 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { /* !TODO!: Update Hint info from sip DB ??? */ return $res_sort; } + + function getIpInformation($type = '') { + $interfaces = array(); + switch ($type) { + case 'ip4': + exec("/sbin/ip -4 -o addr", $result, $ret); + break; + case 'ip6': + exec("/sbin/ip -6 -o addr", $result, $ret); + break; + + default: + exec("/sbin/ip -o addr", $result, $ret); + break; + } + foreach ($result as $line) { + $vals = preg_split("/\s+/", $line); + if ($vals[3] == "mtu") { + continue; + } + if ($vals[2] != "inet" && $vals[2] != "inet6") { + continue; + } + if (preg_match("/(.+?)(?:@.+)?:$/", $vals[1], $res)) { + continue; + } + $ret = preg_match("/(\d*+.\d*+.\d*+.\d*+)[\/(\d*+)]*/", $vals[3], $ip); + + $interfaces[$vals[1] . ':' . $vals[2]] = array('name' => $vals[1], 'type' => $vals[2], 'ip' => ((empty($ip[1]) ? '' : $ip[1]))); + } + return $interfaces; + } + + function getIpInformationOld() { + $interfaces['auto'] = array('0.0.0.0', 'All', '0'); + + exec("/sbin/ip -4 -o addr", $result, $ret); + foreach ($result as $line) { + $vals = preg_split("/\s+/", $line); + + // We only care about ipv4 (inet) lines, or definition lines + if ($vals[2] != "inet" && $vals[3] != "mtu") { + continue; + } + + if (preg_match("/(.+?)(?:@.+)?:$/", $vals[1], $res)) { // Matches vlans, which are eth0.100@eth0 + // It's a network definition. + // This won't clobber an exsiting one, as it always comes + // before the IP addresses. + $interfaces[$res[1]] = array(); + continue; + } + if ($vals[4] == "scope" && $vals[5] == "host") { + $int = 6; + } else { + $int = 8; + } + + // Strip netmask off the end of the IP address + $ret = preg_match("/(\d*+.\d*+.\d*+.\d*+)[\/(\d*+)]*/", $vals[3], $ip); + $interfaces[$vals[$int]] = array($ip[1], $vals[$int], ((empty($ip[2]) ? '' : $ip[2]))); + } + return $interfaces; + } + + private function before($thing, $inthat) { + return substr($inthat, 0, strpos($inthat, $thing)); + } + + private function array_key_exists_recursive($key, $arr) { + if (array_key_exists($key, $arr)) { + return true; + } + foreach ($arr as $currentKey => $value) { + if (is_array($value)) { + return $this->array_key_exists_recursive($key, $value); + } + } + return false; + } + + private function strpos_array($haystack, $needles) { + if (is_array($needles)) { + foreach ($needles as $str) { + if (is_array($str)) { + $pos = $this->strpos_array($haystack, $str); + } else { + $pos = strpos($haystack, $str); + } + if ($pos !== FALSE) { + return $pos; + } + } + } else { + return strpos($haystack, $needles); + } + return FALSE; + } + + private function findAllFiles($dir, $file_mask = null, $mode = 'full') { + $result = null; + if (empty($dir) || (!file_exists($dir))) { + return $result; + } + + $root = scandir($dir); + foreach ($root as $value) { + if ($value === '.' || $value === '..') { + continue; + } + if (is_file("$dir/$value")) { + $filter = false; + if (!empty($file_mask)) { + if (is_array($file_mask)) { + foreach ($file_mask as $k) { + if (strpos(strtolower($value), strtolower($k)) !== false) { + $filter = true; + } + } + } else { + if (strpos(strtolower($value), strtolower($file_mask)) !== false) { + $filter = true; + } + } + } else { + $filter = true; + } + if ($filter) { + if ($mode == 'fileonly') { + $result[] = "$value"; + } else { + $result[] = "$dir/$value"; + } + } else { + $result[] = null; + } + continue; + } + $sub_fiend = $this->findAllFiles("$dir/$value", $file_mask, $mode); + if (!empty($sub_fiend)) { + foreach ($sub_fiend as $sub_value) { + if (!empty($sub_value)) { + $result[] = $sub_value; + } + } + } + } + return $result; + } + } -?> diff --git a/Sccp_manager.inc/aminterface/Event.class.php b/Sccp_manager.inc/aminterface/Event.class.php new file mode 100644 index 0000000..a08c50f --- /dev/null +++ b/Sccp_manager.inc/aminterface/Event.class.php @@ -0,0 +1,206 @@ +getKey('Event'); + } + + public function __construct($rawContent) + { + parent::__construct($rawContent); + $this->_events = array(); + $this->_completed = false; + } +} + +class UnknownEvent extends Event +{ + public function __construct($rawContent = '') + { + } +} + +class TableStart_Event extends Event +{ + + public function getTableName() + { + return $this->getKey('TableName'); + } +} + +class TableEnd_Event extends Event +{ + + public function getTableName() + { + return $this->getKey('TableName'); + } +} + +class SCCPSoftKeySetEntry_Event extends Event +{ + // This is a list of tables, each table is an entry + protected $_data; +} + +class ExtensionStatus_Event extends Event +{ + // this is a list of tables, each table is an entry + public function getPrivilege() + { + return $this->getKey('Privilege'); + } + + public function getExtension() + { + return $this->getKey('Exten'); + } + + public function getContext() + { + return $this->getKey('Context'); + } + + public function getHint() + { + return $this->getKey('Hint'); + } + + public function getStatus() + { + return $this->getKey('Status'); + } +} + +class SCCPDeviceEntry_Event extends Event +{ + // This is a list of tables, each table is an entry +} + +class SCCPShowDevice_Event extends Event +{ + // This is a list of tables + public function getCapabilities() + { + $ret = array(); + $codecs = explode(", ", substr($this->getKey('Capabilities'), 1, -1)); + foreach ($codecs as $codec) { + $codec_parts = explode(" ", $codec); + $ret[] = array("name" => $codec_parts[0], "value" => substr($codec_parts[1], 1, -1)); + } + return $ret; + } + + public function getCodecsPreference() + { + $ret = array(); + $codecs = explode(", ", substr($this->getKey('CodecsPreference'), 1, -1)); + foreach ($codecs as $codec) { + $codec_parts = explode(" ", $codec); + $ret[] = array("name" => $codec_parts[0], "value" => substr($codec_parts[1], 1, -1)); + } + return $ret; + } +} +class SCCPDeviceButtonEntry_Event extends Event +{ +} +class SCCPDeviceFeatureEntry_Event extends Event +{ +// Returned by SCCPShowDevice +} +class SCCPVariableEntry_Event extends Event +{ +// Returned by SCCPShowDevice +} +class SCCPDeviceLineEntry_Event extends Event +{ +} +class SCCPDeviceStatisticsEntry_Event extends Event +{ +} +class SCCPDeviceSpeeddialEntry_Event extends Event +{ +} +abstract class ClosingEvent extends Event +{ + public function __construct($message) { + parent::__construct($message); + $this->_completed = true; + } + public function getListItems() { + return intval($this->getKey('ListItems')); + } + +} +class ResponseComplete_Event extends ClosingEvent +{ + // dummy event to avoid unnecessary testing + public function listCorrectlyReceived($_message, $_eventCount){ + return true; + } +} + +class SCCPShowDeviceComplete_Event extends ClosingEvent +{ + public function listCorrectlyReceived($_message, $_eventCount){ + // Have end of list event. Check with number of lines received and send true if match. + // Remove 9 for the start and end events, and then 4. + if ($this->getKey('listitems') === substr_count( $_message, "\n") -13) { + return true; + } + return false; + } +} +class SCCPShowDevicesComplete_Event extends ClosingEvent +{ + public function listCorrectlyReceived($_message, $_eventCount) { + // Have end of list event. Check with number of events received and send true if match. + // Remove 9 for the lines in the list start and end, and the 2 blank lines. + if ($this->getKey('listitems') === substr_count( $_message, "\n") -11) { + return true; + } + return false; + } +} +class ExtensionStateListComplete_Event extends ClosingEvent +{ + public function listCorrectlyReceived($_message, $_eventCount){ + // Have end of list event. Check with number of events received and send true if match. + // Remove 1 as the closing event is included in the count. + if ($this->getKey('listitems') === $_eventCount -1) { + return true; + } + return false; + } +} + +class SCCPShowSoftKeySetsComplete_Event extends ClosingEvent +{ + public function listCorrectlyReceived($_message, $_eventCount){ + // Have the end of list event. Check the number of lines received and + // return true if match. Remove 8 for the complete event. + if ($this->getKey('listitems') === substr_count( $_message, "\n") -11) { + return true; + } + return false; + } +} diff --git a/Sccp_manager.inc/aminterface/Message.class.php b/Sccp_manager.inc/aminterface/Message.class.php new file mode 100644 index 0000000..f28f53d --- /dev/null +++ b/Sccp_manager.inc/aminterface/Message.class.php @@ -0,0 +1,428 @@ +lines = array(); + $this->variables = array(); + $this->keys = array(); + $this->createdDate = time(); + } + + public function _ToDebug($level, $msg) + { + } + + public function getResponseHandler() + { + if (strlen($this->_responseHandler) > 0) { +// throw new AMIException('Hier:' . $this->_responseHandler); + return (string) $this->_responseHandler; + } else { + return ""; + } + } + + public function setResponseHandler($responseHandler) + { + if (0 == strlen($responseHandler)) { + return; + } + $className = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\' . $responseHandler . '_Response'; + if (class_exists($className, true)) { + $this->_responseHandler = $responseHandler; + } else { + return; + } + } + + public function setVariable($key, $value) + { + $key = strtolower($key); + $this->variables[$key] = $value; + /* print_r('
----Set Value -------
'); + print_r($key); + print_r($value); + */ + } + + public function getVariable($key) + { + $key = strtolower($key); + + if (!isset($this->variables[$key])) { + return null; + } + return $this->variables[$key]; + } + + protected function setKey($key, $value) + { + $key = strtolower((string) $key); + $this->keys[$key] = (string) $value; + /* + print_r('
----Set Key -------
'); + print_r($key); + print_r($value); + * + */ + } + + public function getKey($key) + { + $key = strtolower($key); + if (!isset($this->keys[$key])) { + return null; + } + //return (string)$this->keys[$key]; + return $this->keys[$key]; + } + + public function getVariables() + { + return $this->variables; + } + + public function getActionID() + { + return $this->getKey('ActionID'); + } + + public function getKeys() + { + return $this->keys; + } + + private function serializeVariable($key, $value) + { + return "Variable: $key=$value"; + } + + protected function setSanitizedKey($key, $value) + { + $key = strtolower((string) $key); + $_string_key = array('actionid', 'descr'); + if (array_search($key, $_string_key) !== false) { + $this->keys[$key] = (string) $this->sanitizeInput($value, 'string'); + } else { + $this->keys[$key] = $this->sanitizeInput($value); + } + } + + protected function sanitizeInput($value, $prefered_type = '') + { + if ($prefered_type == '') { + if (!isset($value) || $value === null || strlen($value) == 0) { + return null; + } elseif (is_numeric($value)) { + $prefered_type = 'numeric'; + } elseif (is_string($value)) { + $prefered_type = 'string'; + } else { + throw new AMIException("Don't know how to convert: '" . $value . "'\n"); + } + } + if ($prefered_type !== '') { + switch ($prefered_type) { + case 'string': + if (!isset($value) || $value === null || strlen($value) == 0) { + return ''; + } + if (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { + return (boolean) $value; + } elseif (filter_var($value, FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE)) { + return (string) $value; + } elseif (filter_var($value, FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE)) { + return (string) htmlspecialchars($value, ENT_QUOTES); + } else { + throw new AMIException("Incoming String is not sanitary. Skipping: '" . $value . "'\n"); + } + break; + case 'numeric': + if (!isset($value) || $value === null || strlen($value) == 0) { + return 0; + } + if (filter_var($value, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX | FILTER_FLAG_ALLOW_OCTAL)) { + return intval($value, 0); + } elseif (filter_var($value, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND | FILTER_FLAG_ALLOW_SCIENTIFIC)) { + return (float) $value; + } else { + return (double) $value; + } + default: + throw new AMIException("Don't know how to convert: '" . $value . "'\n"); + break; + } + } + } + + protected function finishMessage($message) + { + return $message . self::EOL . self::EOL; + } + + public function serialize() + { + $result = array(); + foreach ($this->getKeys() as $k => $v) { + $result[] = $k . ': ' . $v; + } + foreach ($this->getVariables() as $k => $v) { + if (is_array($v)) { + foreach ($v as $singleValue) { + $result[] = $this->serializeVariable($k, $singleValue); + } + } else { + $result[] = $this->serializeVariable($k, $v); + } + } + $mStr = $this->finishMessage(implode(self::EOL, $result)); + return $mStr; + } + + public function setActionID($actionID) + { + if (0 == strlen($actionID)) { + throw new AMIException('ActionID cannot be empty.'); + return; + } + + if (strlen($actionID) > 69) { + throw new AMIException('ActionID can be at most 69 characters long.'); + return; + } + + $this->setKey('ActionID', $actionID); + } + + public function __sleep() + { + return array('lines', 'variables', 'keys', 'createdDate'); + } +} + +abstract class IncomingMessage extends Message +{ + + protected $rawContent; + + public function getEventList() + { + return $this->getKey('EventList'); + } + + public function getRawContent() + { + return $this->rawContent; + } + + public function isComplete() + { + return $this->_completed; + } + + public function __sleep() + { + $ret = parent::__sleep(); + $ret[] = 'rawContent'; + return $ret; + } + + public function __construct($rawContent) + { + parent::__construct(); + $this->rawContent = $rawContent; + $lines = explode(Message::EOL, $rawContent); + foreach ($lines as $line) { + $content = explode(':', $line); + $name = strtolower(trim($content[0])); + unset($content[0]); + $value = isset($content[1]) ? trim(implode(':', $content)) : ''; + try { + $this->setSanitizedKey($name, $value); + } catch (AMIException $e) { + throw new AMIException("Error: '" . $e . "'\n Dump RawContent:\n" . $this->rawContent . "\n"); + } + } + } +} + +// namespace FreePBX\modules\Sccp_manager\aminterface\Message; +class LoginAction extends ActionMessage +{ + + /** + * Constructor. + * + * @param string $user AMI username. + * @param string $password AMI password. + * + * @return void + */ + public function __construct($user, $password) + { + parent::__construct('Login'); + $this->setKey('Username', $user); + $this->setKey('Secret', $password); + $this->setKey('Events', 'off'); // &---- + $this->setResponseHandler('Login'); + } +} + +abstract class ActionMessage extends Message +{ + + public function __construct($what) + { + parent::__construct(); + $this->setKey('Action', $what); + $this->setKey('ActionID', microtime(true)); + } +} + +class CommandAction extends ActionMessage +{ + public function __construct($command) + { + parent::__construct('Command'); + $this->setKey('Command', $command); + $this->setResponseHandler("Command"); + } +} + +class ReloadAction extends ActionMessage +{ + + public function __construct($module = false) + { + parent::__construct('Reload'); + if ($module !== false) { + $this->setKey('Module', $module); + $this->setResponseHandler("Generic"); + } + } +} + +class ExtensionStateListAction extends ActionMessage +{ + + public function __construct() + { + parent::__construct('ExtensionStateList'); + $this->setKey('Segment', 'general'); + $this->setKey('ResultFormat', 'command'); + $this->setResponseHandler("ExtensionStateList"); + } +} +class SCCPShowGlobalsAction extends ActionMessage +{ + public function __construct() + { + parent::__construct('SCCPShowGlobals'); + } +} + +class SCCPShowSoftkeySetsAction extends ActionMessage +{ + + public function __construct() + { + parent::__construct('SCCPShowSoftkeySets'); + $this->setKey('Segment', 'general'); + $this->setKey('ResultFormat', 'command'); + $this->setResponseHandler("SCCPShowSoftkeySets"); + } +} + +class SCCPShowDeviceAction extends ActionMessage +{ + + public function __construct($devicename) + { + parent::__construct('SCCPShowDevice'); + $this->setKey('Segment', 'general'); + $this->setKey('ResultFormat', 'command'); + $this->setKey('DeviceName', $devicename); + $this->setResponseHandler("SCCPShowDevice"); + } +} + +class SCCPShowDevicesAction extends ActionMessage +{ + + public function __construct() + { + parent::__construct('SCCPShowDevices'); + $this->setKey('Segment', 'general'); + $this->setKey('ResultFormat', 'command'); + $this->setResponseHandler("SCCPShowDevices"); + } +} + +class SCCPTokenAckAction extends ActionMessage +{ + + public function __construct($DeviceName) + { + parent::__construct('SCCPTokenAck'); + $this->setKey('DeviceId', $DeviceName); + $this->setResponseHandler("SCCPGeneric"); + } +} + +class SCCPDeviceRestartAction extends ActionMessage +{ + + public function __construct($DeviceName, $Type = "restart") + { + parent::__construct('SCCPDeviceRestart'); + $this->setResponseHandler("Generic"); + if (empty($Type)) { + $Type = "restart"; + } + $this->setKey('DeviceName', $DeviceName); + if (in_array(strtolower($Type), array('restart', 'full', 'reset'))) { + $this->setKey('Type', $Type); + } else { + throw new Exception('Param2 has to be one of \'restart\', \'full\', \'reset\'.'); + } + } +} + +class SCCPConfigMetaDataAction extends ActionMessage +{ + public function __construct($segment = false) + { + parent::__construct('SCCPConfigMetaData'); + if ($segment != false) { + $this->setKey('Segment', $segment); + } + $this->setResponseHandler("SCCPJSON"); + } +} diff --git a/Sccp_manager.inc/aminterface/Response.class.php b/Sccp_manager.inc/aminterface/Response.class.php new file mode 100644 index 0000000..60be7bd --- /dev/null +++ b/Sccp_manager.inc/aminterface/Response.class.php @@ -0,0 +1,429 @@ +_events = array(); +// this logic is false - even if we have an error, we will not get anymore data, so is completed. + $this->_completed = $this->isSuccess(); + } + + public function __sleep() + { + $ret = parent::__sleep(); + $ret[] = '_completed'; + $ret[] = '_events'; + return $ret; + } + + public function getEvents() + { + return $this->_events; + } + public function getClosingEvent() { + return $this->_events['ClosingEvent']; + } + public function removeClosingEvent() { + unset($this->_events['ClosingEvent']); + } + public function getCountOfEvents() { + return count($this->_events); + } + + public function isSuccess() + { + // returns true if response message does not contain error + return stristr($this->getKey('Response'), 'Error') === false; + } + + public function isList() + { + if ($this->getKey('EventList') === 'start' ) { + return true; + } + } + + public function getMessage() + { + return $this->getKey('Message'); + } + + public function setActionId($actionId) + { + $this->setKey('ActionId', $actionId); + } + + public function getVariable($_rawContent, $_fields = '') + { + $lines = explode(Message::EOL, $_rawContent); + foreach ($_fields as $key => $value) { + foreach ($lines as $data) { + $_pst = strpos($data, $value); + if ($_pst !== false) { + $this->setKey($key, substr($data, $_pst + strlen($value))); + } + } + } + } +} +class GenericResponse extends Response +{ +} + +//**************************************************************************** +// There are two types of Response messages returned by AMI +// Self contained responses which include any data requested; +// List Responses which contain the data in event messages that follow +// the response message.Response and Event +// Following are the self contained Response classes. +//**************************************************************************** + +class Generic_Response extends Response +{ + public function __construct($rawContent) + { + // Only used for self contained responses. + parent::__construct($rawContent); + // add dummy closing event + $this->_events['ClosingEvent'] = new ResponseComplete_Event($rawContent); + $this->_completed = true; + $this->eventListIsCompleted = true; + + } +} + +class Login_Response extends Generic_Response +{ +} + +class Command_Response extends Generic_Response +{ + private $_temptable; + public function __construct($rawContent) + { + $this->_temptable = array(); + parent::__construct($rawContent); + $lines = explode(Message::EOL, $rawContent); + foreach ($lines as $line) { + $content = explode(':', $line); + if (is_array($content)) { + switch (strtolower($content[0])) { + case 'actionid': + $this->_temptable['ActionID'] = trim($content[1]); + break; + case 'response': + $this->_temptable['Response'] = trim($content[1]); + break; + case 'privilege': + $this->_temptable['Privilege'] = trim($content[1]); + break; + case 'output': + // included for backward compatibility with earlier versions of chan_sccp_b. AMI api does not precede command output with Output + $this->_temptable['Output'] = explode(PHP_EOL,str_replace(PHP_EOL.'--END COMMAND--', '',trim($content[1]))); + break; + default: + $this->_temptable['Output'] = explode(PHP_EOL,str_replace(PHP_EOL.'--END COMMAND--', '', trim($line))); + break; + } + } + } + } + public function getResult() + { + return $this->_temptable; + } +} + +class SCCPJSON_Response extends Generic_Response +{ + public function __construct($rawContent) + { + parent::__construct($rawContent); + $this->getVariable($rawContent, array("DataType" => "DataType:", "JSONRAW" => "JSON:")); + if (null !== $this->getKey('JSONRAW')) { + $this->setKey('Response', 'Success'); + } + } + public function getResult() + { + if (($json = json_decode($this->getKey('JSON'), true)) != false) { + return $json; + } + } +} + +//***************************************************************************// +// Following are the Response classes where the data is contained in a series. +// of event messages. + +class SCCPGeneric_Response extends Response +{ + protected $_tables; + private $_temptable; + + public function __construct($rawContent) + { + parent::__construct($rawContent); + // Confirm that there is a list following. This overrides any setting + // made in one of the parent constructs. + $this->_completed = !$this->isList(); + } + + public function addEvent($event) + { + // Start of list is handled by the isList function in the Constructor + // which also defines the list end event + + if ( empty($thisSetEventEntryType)) { + // This is empty as soon as we have received a TableStart. + // The next message is the first of the data sets + // We use this variable in the switch to add set entries + if (strpos($event->getName(), 'Entry')) { + $thisSetEventEntryType = $event->getName(); + } else { + $thisSetEventEntryType = 'undefinedAsThisIsNotASet'; + } + } + // Unknown events will cause an exception. + // All event classes must be defined within Event.class. + if (get_class($event) === 'FreePBX\modules\Sccp_manager\aminterface\UnknownEvent') { + $this->_events[] = $event; + return; + } + switch ( $event->getName()) { + case $thisSetEventEntryType : + $this->_temptable['Entries'][] = $event; + break; + case 'TableStart': + //initialise + $this->_temptable = array(); + $this->_temptable['Name'] = $event->getTableName(); + $this->_temptable['Entries'] = array(); + $thisSetEventEntryType = ''; + break; + case 'TableEnd': + //Close + if (!is_array($this->_tables)) { + $this->_tables = array(); + } + $this->_tables[$event->getTableName()] = $this->_temptable; + $this->_temptable = array(); + $thisSetEventEntryType = 'undefinedAsThisIsNotASet'; + + // Finished the table. Now check to see if everything was received + // If counts do not match return false and table will not be + //loaded + if ($event->getKey('TableEntries') != count($this->_tables[$event->getTableName()]['Entries'])) { + return false; + } + break; + //case $eventListEndEvent; + case $this->getKey('eventListEndEvent'); + // Have the list end event. The correct number of entries is verified in the event constructor + $this->_events['ClosingEvent'] = $event; + $this->eventListEndEvent = null; + //return $this->_completed = true; + break; + default: + // add regular list event + $this->_events[] = $event; + } + } + + protected function ConvertTableData( $_tablename, array $_fkey, array $_fields) + { + $result = array(); + $_rawtable = $this->Table2Array($_tablename); + // Check that there is actually data to be converted + if (empty($_rawtable)) { return $result;} + foreach ($_rawtable as $_row) { + $all_key_ok = true; + // No need to test if $_fkey is array as array required + foreach ($_fkey as $_fid) { + if (empty($_row[$_fid])) { + $all_key_ok = false; + } else { + $set_name[$_fid] = $_row[$_fid]; + } + } + $Data = &$result; + + if ($all_key_ok) { + foreach ($set_name as $value_id) { + $Data = &$Data[$value_id]; + } + // Label converter in case labels and keys are different + foreach ($_fields as $value_key => $value_id) { + $Data[$value_id] = $_row[$value_key]; + } + } + } + return $result; + } + + protected function ConvertEventData(array $_fkey, array $_fields) + { + $result = array(); + + foreach ($this->_events as $_row) { + $all_key_ok = true; + $tmp_result = $_row->getKeys(); + $set_name = array(); + // No need to test if $_fkey is arrray as array required + foreach ($_fkey as $_fid) { + if (empty($tmp_result[$_fid])) { + $all_key_ok = false; + } else { + $set_name[$_fid] = $tmp_result[$_fid]; + } + } + $Data = &$result; + if ($all_key_ok) { + foreach ($set_name as $value_id) { + $Data = &$Data[$value_id]; + } + // Label converter in case labels and keys are different - not actually required. + foreach ($_fields as $value_id) { + $Data[$value_id] = $tmp_result[$value_id]; + } + } + } + return $result; + } + + public function Table2Array( $tablename ) + { + $result =array(); + if (empty($tablename) || !is_array($this->_tables)) { + return $result; + } + foreach ($this->_tables[$tablename]['Entries'] as $trow) { + $result[]= $trow->getKeys(); + } + return $result; + } + + public function getResult() + { + return $this->getMessage(); + } +} + + + +class SCCPShowSoftkeySets_Response extends SCCPGeneric_Response +{ + public function __construct($rawContent) + { + parent::__construct($rawContent); + $this->setKey('eventlistendevent', 'SCCPShowSoftKeySetsComplete'); + } + public function getResult() + { + return $this->ConvertTableData( + 'SoftKeySets', + array('set','mode'), + array('description'=>'description','label'=>'label','lblid'=>'lblid') + ); + } +} + +class SCCPShowDevices_Response extends SCCPGeneric_Response +{ + public function __construct($rawContent) + { + parent::__construct($rawContent); + $this->setKey('eventlistendevent', 'SCCPShowDevicesComplete'); + } + public function getResult() + { + return $this->ConvertTableData( + 'Devices', + array('mac'), + array('mac'=>'name','address'=>'address','descr'=>'descr','regstate'=>'status', + 'token'=>'token','act'=>'act', 'lines'=>'lines','nat'=>'nat','regtime'=>'regtime') + ); + } +} + +class SCCPShowDevice_Response extends SCCPGeneric_Response +{ + public function __construct($rawContent) + { + parent::__construct($rawContent); + $this->setKey('eventlistendevent', 'SCCPShowDeviceComplete'); + } + public function getResult() + { + // This object has a list of events _events, and a list of tables _tables. + $result = array(); + + foreach ($this->_events as $trow) { + $result = array_merge($result, $trow->getKeys()); + } + // Now handle label changes so that keys from AMI correspond to db keys in _tables + $result['Buttons'] = $this->ConvertTableData( + 'Buttons', + array('id'), + array('id'=>'id','channelobjecttype'=>'channelobjecttype','inst'=>'inst', + 'typestr'=>'typestr', 'type'=>'type', 'pendupdt'=>'pendupdt', 'penddel'=>'penddel', 'default'=>'default' + ) + ); + $result['SpeeddialButtons'] = $this->ConvertTableData( + 'SpeeddialButtons', + array('id'), + array('id'=>'id','channelobjecttype'=>'channelobjecttype','name'=>'name','number'=>'number','hint'=>'hint') + ); + $result['CallStatistics'] = $this->ConvertTableData( + 'CallStatistics', + array('type'), + array('type'=>'type','channelobjecttype'=>'channelobjecttype','calls'=>'calls','pcktsnt'=>'pcktsnt','pcktrcvd'=>'pcktrcvd', + 'lost'=>'lost','jitter'=>'jitter','latency'=>'latency', 'quality'=>'quality','avgqual'=>'avgqual','meanqual'=>'meanqual', + 'maxqual'=>'maxqual', 'rconceal'=>'rconceal', 'sconceal'=>'sconceal' + ) + ); + $result['SCCP_Vendor'] = array('vendor' => strtok($result['skinnyphonetype'], ' '), 'model' => strtok('('), + 'model_id' => strtok(')'), 'vendor_addon' => strtok($result['configphonetype'], ' '), + 'model_addon' => strtok(' ')); + if (empty($result['SCCP_Vendor']['vendor']) || $result['SCCP_Vendor']['vendor'] == 'Undefined') { + $result['SCCP_Vendor'] = array('vendor' => 'Undefined', 'model' => $result['configphonetype'], + 'model_id' => '', 'vendor_addon' => $result['SCCP_Vendor']['vendor_addon'], + 'model_addon' => $result['SCCP_Vendor']['model_addon'] + ); + } + $result['MAC_Address'] =$result['macaddress']; + return $result; + } +} + +class ExtensionStateList_Response extends SCCPGeneric_Response +{ + public function __construct($rawContent) + { + parent::__construct($rawContent); + $this->setKey('eventlistendevent', 'ExtensionStateListComplete'); + } + public function getResult() + { + $result = $this->ConvertEventData(array('exten','context'), array('exten','context','hint','status','statustext')); + return $result; + } +} diff --git a/Sccp_manager.inc/aminterface/aminterface.class.php b/Sccp_manager.inc/aminterface/aminterface.class.php new file mode 100644 index 0000000..0389914 --- /dev/null +++ b/Sccp_manager.inc/aminterface/aminterface.class.php @@ -0,0 +1,518 @@ + 'Message.class.php', 'Response' => 'Response.class.php', 'Event' => 'Event.class.php'); + foreach ($drivers as $key => $value) { + $class = $driverNamespace . "\\" . $key; + $driver = __DIR__ . "/" . $value; + if (!class_exists($class, false)) { + if (file_exists($driver)) { + include(__DIR__ . "/" . $value); + } else { + throw new \Exception("Class required but file not found " . $driver); + } + } + } + } + + public function __construct($parent_class = null) + { + global $amp_conf; + $this->paren_class = $parent_class; + $this->_socket = false; + $this->_connect_state = false; + $this->_error = array(); + $this->_config = array('host' => 'localhost', 'user' => '', 'pass' => '', 'port' => '5038', 'tsoket' => 'tcp://', 'timeout' => 30, 'enabled' => true); + $this->_eventListeners = array(); + $this->_incomingMsgObjectList = array(); + $this->_lastActionId = false; + $this->_incomingRawMessage = array(); + $this->eventListEndEvent = ''; + + $fld_conf = array('user' => 'AMPMGRUSER', 'pass' => 'AMPMGRPASS'); + if (isset($amp_conf['AMPMGRUSER'])) { + foreach ($fld_conf as $key => $value) { + if (isset($amp_conf[$value])) { + $this->_config[$key] = $amp_conf[$value]; + } + } + } + if ($this->_config['enabled']) { + $this->load_subspace(); + } + } + + public function status() + { + if ($this->_config['enabled']) { + return true; + } else { + return false; + } + } + + public function info() + { + $Ver = '13.0.4'; + if ($this->_config['enabled']){ + return array('Version' => $Ver, + 'about' => 'AMI data ver: ' . $Ver, 'test' => get_declared_classes()); + } else { + return array('Version' => $Ver, + 'about' => 'Disabled AMI ver: ' . $Ver); + } + } + + /* + * Opens a socket connection to ami. + */ + public function open() + { + $cString = $this->_config['tsoket'] . $this->_config['host'] . ':' . $this->_config['port']; + $this->_context = stream_context_create(); + $errno = 0; + $errstr = ''; + $this->_ProcessingMessage = ''; + $this->_socket = @stream_socket_client( + $cString, + $errno, + $errstr, + $this->_config['timeout'], + STREAM_CLIENT_CONNECT, + $this->_context + ); + if ($this->_socket === false) { + $this->_errorException('Error connecting to ami: ' . $errstr . $cString); + return false; + } + $msg = new aminterface\LoginAction($this->_config['user'], $this->_config['pass']); + $response = $this->send($msg); + + if ($response != false) { + if (!$response->isSuccess()) { + $this->_errorException('Could not connect: ' . $response->getMessage()); + return false; + } else { + @stream_set_blocking($this->_socket, 0); + $this->_connect_state = true; + $this->_ProcessingMessage = ''; + } + } + return true; + } + + /* + * Closes the connection to ami. + */ + public function close() + { + $this->_connect_state = false; + $this->_ProcessingMessage = ''; + @stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR); + } + /* + * Send action message to ami, and wait for Response + */ + public function send($message) + { + $_incomingRawMessage = array(); + $messageToSend = $message->serialize(); + $length = strlen($messageToSend); + $this->_DumpMessage = ''; + $this->_lastActionId = $message->getActionID(); + $this->_lastRequestedResponseHandler = $message->getResponseHandler(); + $this->_lastActionClass = $message; + $this->_incomingRawMessage[$this->_lastActionId] = ''; + $this->eventListIsCompleted = array(); + if (@fwrite($this->_socket, $messageToSend) < $length) { + $this->_errorException('Could not send message'); + return false; + } + // Have sent a message and now have to wait for and read the reply + // The below infinite loop waits for $this->completed to be true. + // The loop calls readBuffer, which calls GetMessages, which calls Process + // This loop then continues until we have _thisComplete as an object variable + $this->eventListIsCompleted[$this->_lastActionId] = false; + while (true) { + stream_set_timeout($this->_socket, 1); + $this->readBuffer(); + $info = stream_get_meta_data($this->_socket); + if ($info['timed_out'] == true) { + $this->_errorException("Read waittime: " . ($this->socket_param['timeout']) . " exceeded (timeout).\n"); + return false; + } + if ($this->eventListIsCompleted[$this->_lastActionId]) { + $response = $this->_incomingMsgObjectList[$this->_lastActionId]; + // need to test that the list was successfully completed here + $allReceived = $response->getClosingEvent() + ->listCorrectlyReceived($this->_incomingRawMessage[$this->_lastActionId], + $response->getCountOfEvents()); + // now tidy up removing any temp variables or objects + $response->removeClosingEvent(); + unset($_incomingRawMessage[$this->_lastActionId]); + unset($this->_incomingMsgObjectList[$this->_lastActionId]); + unset($this->_lastActionId); + if ($allReceived) { + return $response; + } + // Something is missing from the events list received via AMI, or + // the control parameter at the end of the list has changed. + // This will cause an exception as returning a boolean instead of a Response + // Maybe should handle better, but + // need to break out of the loop as nothing more coming. + try { + throw new \invalidArgumentException("Counts do not match on returned AMI Result"); + } catch ( \invalidArgumentException $e) { + echo substr(strrchr(get_class($response), '\\'), 1), " ", $e->getMessage(), "\n"; + } + return $response; + } + } + } + + protected function readBuffer () + { + $read = @fread($this->_socket, 65535); + // AMI never returns EOF + if ($read === false ) { + $this->_errorException('Error reading'); + } + // Do not return empty Messages + while ($read == "" ) { + $read = @fread($this->_socket, 65535); + } + // Add read to the rest of buffer from previous read + $this->_ProcessingMessage .= $read; + $this->getMessages(); + } + + protected function getMessages() + { + $msgs = array(); + // Extract any complete messages and leave remainder for next read + while (($marker = strpos($this->_ProcessingMessage, aminterface\Message::EOM))) { + $msg = substr($this->_ProcessingMessage, 0, $marker); + $this->_ProcessingMessage = substr( + $this->_ProcessingMessage, + $marker + strlen(aminterface\Message::EOM) + ); + $msgs[] = $msg; + } + $this->process($msgs); + } + + public function process(array $msgs) + { + foreach ($msgs as $aMsg) { + // 2 types of message; Response or Event. Response only incudes data + // for JSON response and Command response. All other responses expect + // data in an event list - these events need to be attached to the response. + $resPos = strpos($aMsg, 'Response: '); // Have a Response message. This may not be 0. + $evePos = strpos($aMsg, 'Event: '); // Have an Event Message. This should always be 0. + // Add the incoming message to a string that can be checked + // against the completed message event when it is received. + $this->_incomingRawMessage[$this->_lastActionId] .= "\r\n\r\n" . $aMsg; + if (($resPos !== false) && (($resPos < $evePos) || $evePos === false)) { + $response = $this->_responseObjFromMsg($aMsg); // resp Ok + $this->eventListEndEvent = $response->getKey('eventlistendevent'); + $this->_incomingMsgObjectList[$this->_lastActionId] = $response; + $this->eventListIsCompleted[$this->_lastActionId] = $response->isComplete(); + } elseif ($evePos === 0) { // Event must be at the start of the msg. + $event = $this->_eventObjFromMsg($aMsg); // Event Ok + $this->eventListIsCompleted[$this->_lastActionId] = $event->isComplete(); + $this->_incomingMsgObjectList[$this->_lastActionId]->addEvent($event); + } else { + // broken ami most probably through changes in chan_sccp_b. + // AMI is sending a message which is neither a response nor an event. + $this->_msgToDebug(1, 'resp broken ami'); + $bMsg = 'Event: ResponseEvent' . "\r\n"; + $bMsg .= 'ActionId: ' . $this->_lastActionId . "\r\n" . $aMsg; + $event = $this->_eventObjFromMsg($bMsg); + $this->_incomingMsgObjectList[$this->_lastActionId]->addEvent($event); + } + } + } + + private function _msgToDebug($level, $msg) + { + if ($level > $this->debug_level) { + return; + } + print_r('
level: '.$level.' '); + print_r($msg); + print_r('
'); + } + + private function _responseObjFromMsg($message) + { + $_className = false; + + $responseClass = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\Generic_Response'; + if ($this->_lastRequestedResponseHandler != false) { + $_className = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\' . $this->_lastRequestedResponseHandler . '_Response'; + } + if ($_className) { + if (class_exists($_className, true)) { + $responseClass = $_className; + } elseif ($responseHandler != false) { + $this->_errorException('Response Class ' . $_className . ' requested via responseHandler, could not be found'); + } + } + $response = new $responseClass($message); + $actionId = $response->getActionID(); + if ($actionId === null) { + $response->setActionId($this->_lastActionId); + } + return $response; + } + public function _eventObjFromMsg($message) + { + $eventType = explode(aminterface\Message::EOL,$message,2); + $name = trim(explode(':',$eventType[0],2)[1]); + $className = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\' . $name . '_Event'; + if (class_exists($className, true) === false) { + $className = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\UnknownEvent'; + } + return new $className($message); + } + + protected function dispatch($message) + { + print_r("
------------dispatch----------
"); + print_r($message); + return false; + die(); + foreach ($this->_eventListeners as $data) { + $listener = $data[0]; + $predicate = $data[1]; + print_r($data); + + if (is_callable($predicate) && !call_user_func($predicate, $message)) { + continue; + } + if ($listener instanceof \Closure) { + $listener($message); + } elseif (is_array($listener)) { + $listener[0]->$listener[1]($message); + } else { + $listener->handle($message); + } + } + print_r("
------------E dispatch----------
"); + } + +//------------------------------------------------------------------------------- + function core_list_all_exten($keyfld = '', $filter = array()) + { + $result = array(); + return $result; + } + +//-------------------Adaptive Function ------------------------------------------------------------ + + function core_list_hints() + { + $result = array(); + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\ExtensionStateListAction(); + $_response = $this->send($_action); + $_res = $_response->getResult(); + foreach ($_res as $key => $value) { + foreach ($value as $key2 => $value2) { + $result[$key2] = '@' . $key2; + } + } + } + return $result; + } + + function core_list_all_hints() + { + $result = array(); + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\ExtensionStateListAction(); + $_res = $this->send($_action)->getResult(); + foreach ($_res as $key => $value) { + foreach ($value as $key2 => $value2) { + $result[$key.'@'.$key2] = $key.'@'.$key2; + } + } + } + return $result; + } +// --------------------- SCCP Comands + function sccp_list_keysets() + { + $result = array(); + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPShowSoftkeySetsAction(); + $_res = $this->send($_action)->getResult(); + foreach ($_res as $key => $value) { + $result[$key] = $key; + } + } + return $result; + } + function sccp_get_active_device() + { + $result = array(); + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPShowDevicesAction(); + $result = $this->send($_action)->getResult(); + } + return $result; + } + function sccp_getdevice_info($devicename) + { + $result = array(); + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPShowDeviceAction($devicename); + $result = $this->send($_action)->getResult(); + $result['MAC_Address'] = $result['macaddress']; + } + return $result; + } + function sccpDeviceReset($devicename, $action = '') + { + if ($this->_connect_state) { + if ($action == 'tokenack') { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPTokenAckAction($devicename); + } else { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPDeviceRestartAction($devicename, $action); + } + $_response = $this->send($_action); + $result['data'] = 'Device :'.$devicename.' Result: '.$_response->getMessage(); + $result['Response']=$_response->getKey('Response'); + } + return $result; + } + +//------------------- Core Comands ---- + function core_sccp_reload() + { + $result = array(); + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\ReloadAction('chan_sccp'); + $result = ['Response' => $this->send($_action)->getMessage(), 'data' => '']; + } + return $result; + } + function getSCCPVersion() + { + $result = array(); + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPConfigMetaDataAction(); + $metadata = $this->send($_action)->getResult(); + } + //return $result; + if (isset($metadata['Version'])) { + $result['Version'] = $metadata['Version']; + $version_parts = explode('.', $metadata['Version']); + $result['vCode'] = 0; + if ($version_parts[0] === 4) { + switch ($version_parts[1]) { + case 1: + $result['vCode'] = 410; + break; + case 2: + $result['vCode'] = 420; + break; + case 3. . .5: + if($version_parts[2] == 3){ + $result['vCode'] = 433; + } else { + $result['vCode'] = 430; + } + break; + default: + $result['vCode'] = 400; + break; + } + } + /* Revision got replaced by RevisionHash in 10404 (using the hash does not work) */ + if (array_key_exists("Revision", $metadata)) { + if (base_convert($metadata["Revision"], 16, 10) == base_convert('702487a', 16, 10)) { + $result['vCode'] = 431; + } + if (base_convert($metadata["Revision"], 16, 10) >= "10403") { + $result['vCode'] = 431; + } + } + if (array_key_exists("RevisionHash", $metadata)) { + $result['RevisionHash'] = $metadata["RevisionHash"]; + } else { + $result['RevisionHash'] = ''; + } + if (isset($metadata['RevisionNum'])) { + $result['RevisionNum'] = $metadata['RevisionNum']; + if ($metadata['RevisionNum'] >= 10403) { // new method, RevisionNum is incremental + $result['vCode'] = 432; + } + if ($metadata['RevisionNum'] >= 10491) { // new method, RevisionNum is incremental + $result['vCode'] = 433; + } + } + if (isset($metadata['ConfigureEnabled'])) { + $result['futures'] = implode(';', $metadata['ConfigureEnabled']); + } + } + return $result; + } + + function getRealTimeStatus() + { + // Initialise array with default values to eliminate testing later + $result = array(); + $cmd_res = array(); + $cmd_res = ['sccp' => ['message' => 'default value', 'realm' => '', 'status' => 'ERROR']]; + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\CommandAction('realtime mysql status'); + $result = $this->send($_action)->getResult(); + } + if (is_array($result['Output'])) { + foreach ($result['Output'] as $aline) { + if (strlen($aline) > 3) { + $temp_strings = explode(' ', $aline); + $cmd_res_key = $temp_strings[0]; + foreach ($temp_strings as $test_string) { + if (strpos($test_string, '@')) { + $this_realm = $test_string; + break; + } + } + $cmd_res[$cmd_res_key] = array('message' => $aline, 'realm' => $this_realm, 'status' => strpos($aline, 'connected') ? 'OK' : 'ERROR'); + } + } + } + return $cmd_res; + } +} diff --git a/Sccp_manager.inc/aminterface/oldinterface.class.php b/Sccp_manager.inc/aminterface/oldinterface.class.php new file mode 100644 index 0000000..a8d8c86 --- /dev/null +++ b/Sccp_manager.inc/aminterface/oldinterface.class.php @@ -0,0 +1,525 @@ +paren_class = $parent_class; + $this->error = ""; + } + + public function info() + { + $Ver = '13.0.4'; + return array('Version' => $Ver, + 'about' => 'Old interface data ver: ' . $Ver); + } + + /* + Core Access Function + */ + + + /* + * Replace or dublicate to AMI interface + */ + + public function sccp_core_commands($params = array()) + { + global $astman; + $cmd_list = array('get_softkey' => array('cmd' => "sccp show softkeyssets", 'param' => ''), + 'get_version' => array('cmd' => "sccp show version", 'param' => ''), + 'get_device' => array('cmd' => "sccp show devices", 'param' => ''), + 'get_dev_info' => array('cmd' => "sccp show device", 'param' => 'name'), + 'get_hints' => array('cmd' => "core show hints", 'param' => ''), + 'sccp_reload' => array('cmd' => "sccp reload force", 'param' => ''), + 'reset_phone' => array('cmd' => "sccp reset ", 'param' => 'name'), // Жесткая перезагрузка + 'restart_phone' => array('cmd' => "sccp restart ", 'param' => 'name'), + 'reload_phone' => array('cmd' => "sccp reload device ", 'param' => 'name'), + 'reload_line' => array('cmd' => "sccp reload line ", 'param' => 'name'), + 'reset_token' => array('cmd' => "sccp tokenack ", 'param' => 'name'), + 'get_realtime_status' => array('cmd' => "realtime mysql status", 'param' => ''), + ); + $result = true; + if (!empty($params['cmd'])) { + $id_cmd = $params['cmd']; + if (!empty($cmd_list[$id_cmd])) { + $id_param = $cmd_list[$id_cmd]['param']; + if (!empty($id_param)) { + if (!empty($params[$id_param])) { + $result = $astman->Command($cmd_list[$id_cmd]['cmd'] . ' ' . $params[$id_param]); + } + } else { + $result = $astman->Command($cmd_list[$id_cmd]['cmd']); + } + } else { + switch ($params['cmd']) { + case 'phone_call': + if (!empty($params['name'])) { + $result = $astman->Command('sccp call ' . $params['name'] . ' ' . $params['call']); + } + break; + case 'phone_message': + if (!empty($params['msg'])) { + $msg = $params['msg']; + } else { + $msg = $this->sccpvalues['servername']['data']; + } + if (!empty($params['name'])) { + $astman->Command('sccp device ' . $params['name'] . ' ' . $msg); + } else { + } + break; + default: + $result = false; + break; + } + } + } + return $result; + } + + public function sccp_getdevice_info($dev_id) + { + if (empty($dev_id)) { + return array(); + } + $res = $this->sccp_core_commands(array('cmd' => 'get_dev_info', 'name' => $dev_id)); + $res1 = str_replace(array("\r\n", "\r", "\n"), ';', strip_tags((string) $res['data'])); + if (strpos($res1, 'MAC-Address')) { + $res2 = substr($res1, 0, strpos($res1, '+--- Buttons ')); + $res1 = explode(';', substr($res2, strpos($res2, 'MAC-Address'))); + foreach ($res1 as $data) { + if (!empty($data)) { + $tmp = explode(':', $data); + $data_key = str_replace(array(" ", "-", "\t"), '_', trim($tmp[0])); + $res3[$data_key] = $tmp[1]; + } + } + + $res1 = $res3['Skinny_Phone_Type']; + $res4 = $res3['Config_Phone_Type']; + if (!empty($res3['Addons'])) { + $res2 = $res3['Addons']; + } else { + $res2 = ''; + } + $res3['SCCP_Vendor'] = array('vendor' => strtok($res1, ' '), 'model' => strtok('('), 'model_id' => strtok(')'), 'vendor_addon' => strtok($res2, ' '), 'model_addon' => strtok(' ')); + if (empty($res3['SCCP_Vendor']['vendor']) || $res3['SCCP_Vendor']['vendor'] == 'Undefined') { + $res3['SCCP_Vendor'] = array('vendor' => 'Undefined', 'model' => $res4, 'model_id' => '', 'vendor_addon' => $res3['SCCP_Vendor']['vendor_addon'], 'model_addon' => $res3['SCCP_Vendor']['model_addon']); +// return $res4; +// return array(); + } + return $res3; + } else { + return array(); + } + } + + /* Current not use */ + /* + * A function should be used in the form of buttons for getting all hint. Not working. I don't know how to use properly. + */ + + public function sccp_list_hints() + { + $hint_key = array(); + $hint_all = $this->sccp_list_all_hints(); + foreach ($hint_all as $value) { + $res = $this->loc_after('@', $value); +// array_search($res, $hint_key)) != NULL) + if (!isset($hint_key[$res])) { + $hint_key[$res] = '@' . $res; + } + } + return $hint_key; + } + + public function sccp_list_all_hints() + { + $ast_out = $this->sccp_core_commands(array('cmd' => 'get_hints')); + $ast_out = preg_split("/[\n]/", $ast_out['data']); + $ast_key = array(); + for ($i = 0; $i < 3; $i++) { + $ast_out[$i] = ""; + } + $i = count($ast_out) - 1; + $ast_out[--$i] = ""; + $ast_out[--$i] = ""; + foreach ($ast_out as $line) { + if (strlen($line) > 3) { + list ($line, $junk) = explode(' ', $line); + if (!is_bool(strpos($line, ':'))) { + $line = trim(substr($line, 0, strpos($line, ':'))); + } + if (isset($ast_key[$line])) { + if (strlen($ast_key[$line]) < 1) { + $ast_key[$line] = $line; + } + } else { + $ast_key[$line] = $line; + } + } + } + return $ast_key; + } + + public function sccp_realtime_status() + { + $ast_res = array(); + // Below added for compatibility with AMI result and modified server.info + $ast_res = ['sccp' => ['message' => 'default value', 'realm' => '', 'status' => 'ERROR']]; + $ast_out = $this->sccp_core_commands(array('cmd' => 'get_realtime_status')); + $ast_out = preg_split("/[\n]/", $ast_out['data']); + if (strpos($ast_out[0], 'Privilege') !== false) { + $ast_out[0] = ""; + } + foreach ($ast_out as $line) { + if (strlen($line) > 3) { + $ast_key = strstr(trim($line), ' ', true); + $ast_res[$ast_key] = array('message' => $line, 'status' => strpos($line, 'connected') ? 'OK' : 'ERROR'); + } + } + return $ast_res; + } + +// !TODO!: -TODO-: install.php is still using the other version number. This is actually where I use another method ? + + + public function get_compatible_sccp() + { + $res = $this->getSCCPVersion(); + if (empty($res)) { + return 0; + } + switch ($res["vCode"]) { + case 0: + return 0; + case 433: + return 433; + + case 432: + case 431: + return 431; + default: + return 430; + } + /* if ($res["vCode"] >= 433) { + + } + if ($res["vCode"] >= 431) { + return 431; + } else { + return 430; + } + * + */ +// return $res["vCode"]; + } + + public function getSCCPVersion() + { + $res = $this->getChanSCCPVersion(); + if (empty($res)) { + $res = $this->getCoreSCCPVersion(); + } + return $res; + } + + function getCoreSCCPVersion() + { + $result = array(); + $ast_out = $this->sccp_version(); + $result["Version"] = $ast_out[0]; + if ($ast_out[0] == '-1') { + $result["vCode"] = 0; + return $result; + } + $version_parts = explode(".", $ast_out[0]); + $result["vCode"] = implode('', $version_parts); + if (!empty($ast_out[1]) && $ast_out[1] == 'develop') { + $result["develop"] = $ast_out[1]; + $res = 10; +// !TODO!: This does not work as you might expect + if (base_convert($ast_out[3], 16, 10) == base_convert('702487a', 16, 10)) { + $result["vCode"] = 431; + } + if (base_convert($ast_out[3], 16, 10) >= "10403") { // new method, RevisionNum is incremental + $result["vCode"] = 432; + } + } + return $result; + } + + private function sccp_version() + { + $ast_out = $this->sccp_core_commands(array('cmd' => 'get_version')); + if (($ast_out['Response'] == 'Error') || (strpos($ast_out['data'], 'No such command') != false)) { + return array('-1'); + } + if (preg_match("/Release.*\(/", $ast_out['data'], $matches)) { + $ast_out = substr($matches[0], 9, -1); + return explode(' ', $ast_out); + } else { + return array('unknown'); + } + } + + function getChanSCCPVersion() + { + global $astman; + $result = array(); + if (!$astman) { + return $result; + } + $metadata = $this->astman_retrieveJSFromMetaData(""); +// return $metadata; + if ($metadata && array_key_exists("Version", $metadata)) { + $result["Version"] = $metadata["Version"]; + $version_parts = explode(".", $metadata["Version"]); + $result["vCode"] = 0; + + # not sure about this sccp_ver numbering. Might be better to just check "Version" and Revision + # $result["vCode"] = implode('', $version_parts); + $result["vCode"] = 0; + if ($version_parts[0] == "4") { + $result["vCode"] = 400; + if ($version_parts[1] == "1") { + $result["vCode"] = 410; + } elseif ($version_parts[1] == "2") { + $result["vCode"] = 420; + } elseif ($version_parts[1] >= "3") { + if ($version_parts[2] == "3"){ + $result["vCode"] = 433; + } else { + $result["vCode"] = 430; + } + } + } + + /* + if (array_key_exists("Branch",$metadata)) { + if ($metadata["Branch"] == "master") { + + } else + if ($metadata["Branch"] == "develop") { + + } + } + */ + + /* Revision got replaced by RevisionHash in 10404 (using the hash does not work) */ + if (array_key_exists("Revision", $metadata)) { + if (base_convert($metadata["Revision"], 16, 10) == base_convert('702487a', 16, 10)) { + $result["vCode"] = 431; + } + if (base_convert($metadata["Revision"], 16, 10) >= "10403") { + $result["vCode"] = 431; + } + } + if (array_key_exists("RevisionHash", $metadata)) { + $result["RevisionHash"] = $metadata["RevisionHash"]; + } else { + $result["RevisionHash"] = ''; + } + if (array_key_exists("RevisionNum", $metadata)) { + $result["RevisionNum"] = $metadata["RevisionNum"]; + if ($metadata["RevisionNum"] >= "10403") { // new method, RevisionNum is incremental + $result["vCode"] = 432; + } + if ($metadata["RevisionNum"] >= "10491") { // new method, RevisionNum is incremental + $result["vCode"] = 433; + } + } + if (array_key_exists("ConfigureEnabled", $metadata)) { + $result["futures"] = implode(';', $metadata["ConfigureEnabled"]); + } + } else { + return null; + die_freepbx("Version information could not be retrieved from chan-sccp, via astman::SCCPConfigMetaData"); + } + return $result; + } + + public function sccp_list_keysets() + { + $ast_out = $this->sccp_core_commands(array('cmd' => 'get_softkey')); + + $ast_out = preg_split("/[\n]/", $ast_out['data']); + $ast_key = array(); + for ($i = 0; $i < 5; $i++) { + $ast_out[$i] = ""; + } + $i = count($ast_out) - 1; + $ast_out[--$i] = ""; + foreach ($ast_out as $line) { + if (strlen($line) > 3) { + $line = substr($line, 2); + list ($line, $junk) = explode(' ', $line); + if (isset($ast_key[$line])) { + if (strlen($ast_key[$line]) < 1) { + $ast_key[$line] = $line; + } + } else { + $ast_key[$line] = $line; + } + } + } + return $ast_key; + } + + public function sccp_get_active_device() + { + $ast_out = $this->sccp_core_commands(array('cmd' => 'get_device')); + + $ast_out = preg_split("/[\n]/", $ast_out['data']); + + $ast_key = array(); + for ($i = 0; $i < 5; $i++) { + $ast_out[$i] = ""; + } + $i = count($ast_out) - 1; + $ast_out[--$i] = ""; + foreach ($ast_out as $line) { + if (strlen($line) > 3) { + $line = substr($line, 2); + $line = preg_replace("/\s{2,}/", " ", $line); + $line_arr = explode(' ', $line); + $it = 1; + do { + if ($this->strpos_array($line_arr[$it + 1], array('SEP', 'ATA', 'VG')) === false) { +// if (strpos($line_arr[$it + 1], 'SEP') === false) { + $line_arr[0] .= ' ' . $line_arr[$it]; + unset($line_arr[$it]); + } else { + break; + } + $it++; + } while ((count($line_arr) > 3) and ( $it < count($line_arr))); + explode(";|", implode(";|", $line_arr)); + list ($descr, $address, $devname, $status, $token, $junk) = explode(";|", implode(";|", $line_arr)); + +// list ($descr, $address, $devname, $status, $junk) = $line_arr; +// if (strlen($ast_key[$devname]) < 1) { + if (strlen($devname) > 1) { + $ast_key[$devname] = array('name' => $devname, 'status' => $status, 'address' => $address, 'descr' => $descr, 'token' => $token); + } + /* + if (isset($ast_key[$devname])) { + if (strlen($ast_key[$devname]) < 1) { + $ast_key[$devname] = Array('name' => $devname, 'status' => $status, 'address' => $address, 'descr' => $descr, 'token' => $descr); + } + } else { + $ast_key[$devname] = Array('name' => $devname, 'status' => $status, 'address' => $address, 'descr' => $descr, 'token' => $token); + } + * + */ + } + } + return $ast_key; + } + + /* + * Replace sccp_core_commands($params = array()) { + */ + + private function astman_retrieveJSFromMetaData($segment = "") + { + global $astman; + $params = array(); + if ($segment != "") { + $params["Segment"] = $segment; + } + $response = $astman->send_request('SCCPConfigMetaData', $params); + if ($response["Response"] == "Success") { + //outn(_("JSON-content:").$response["JSON"]); + $decode = json_decode($response["JSON"], true); + return $decode; + } else { + return false; + } + } + + private function strpos_array($haystack, $needles) + { + if (is_array($needles)) { + foreach ($needles as $str) { + if (is_array($str)) { + $pos = $this->strpos_array($haystack, $str); + } else { + $pos = strpos($haystack, $str); + } + if ($pos !== false) { + return $pos; + } + } + } else { + return strpos($haystack, $needles); + } + return false; + } + + private function loc_after($value, $inthat) + { + if (!is_bool(strpos($inthat, $value))) { + return substr($inthat, strpos($inthat, $value) + strlen($value)); + } + } + + function getеtestChanSCC() + { + global $astman; +// $action = Array('SCCPShowGlobals',); + $params = array(); + $action = 'SCCPShowSoftkeySets'; + $params = array('Segment' => 'device', 'ResultFormat'=>'command' ); +// $params = array('Segment' => 'device'); +// $params = array(); + $metadata = $astman->send_request($action, $params); + return $metadata; + } + + /* + * [Segments] => ( [0] => general [1] => device [2] => line [3] => softkey ) + */ + function getGlobalsFromMetaData($Segment = '') + { + global $astman; + $params = array(); + + $action = 'SCCPConfigMetaData'; + if (empty($Segment)) { + $Segment = 'general'; + } + $params = array('Segment' => $Segment, 'ResultFormat' => 'command'); + $metadata = $astman->send_request($action, $params); + if (!empty($metadata['data'])) { + $tmp_data = $metadata['data']; + if (strpos($tmp_data, 'JSON:') !== false) { + $decode = json_decode(substr($tmp_data, strpos($tmp_data, 'JSON:') + 5), true); + $result = array(); + if (!empty($decode['Options'])) { + foreach ($decode['Options'] as $value) { + $result[$value['Name']] = $value; + } + return $result; + } + return $decode; + } + } + return $metadata; + } +} diff --git a/Sccp_manager.inc/dbinterface.class.php b/Sccp_manager.inc/dbinterface.class.php new file mode 100644 index 0000000..7e55e71 --- /dev/null +++ b/Sccp_manager.inc/dbinterface.class.php @@ -0,0 +1,409 @@ +paren_class = $parent_class; + } + + public function info() + { + $Ver = '13.0.2'; // This should be updated + return array('Version' => $Ver, + 'about' => 'Data access interface ver: ' . $Ver); + } + + /* + * Core Access Function + */ + public function get_db_SccpTableByID($dataid, $data = array(), $indexField = '') + { + $result = array(); + $raw = $this->HWextension_db_SccpTableData($dataid, $data); + if (empty($raw) || empty($indexField)) { + return $raw; + } + foreach ($raw as $value) { + $id = $value[$indexField]; + $result[$id] = $value; + } + return $result; + } + + public function HWextension_db_SccpTableData($dataid, $data = array()) + { + // $stmt is a single row fetch, $stmts is a fetchAll. + $dbh = \FreePBX::Database(); + $stmt = ''; + $stmts = ''; + if ($dataid == '') { + return false; + } + switch ($dataid) { + case 'SccpExtension': + if (empty($data['name'])) { + $stmts = $dbh->prepare('SELECT * FROM sccpline ORDER BY name'); + } else { + $stmts = $dbh->prepare('SELECT * FROM sccpline WHERE name = :name'); + $stmts->bindParam(':name', $data['name'],\PDO::PARAM_STR); + } + break; + case 'SccpDevice': + if (empty($data['fields'])) { + $fld = 'name, name as mac, type, button, addon, _description as description'; + } else { + switch ($data['fields']) { + case "all": + $fld ='*'; + break; + case "sip_ext": + $fld ='button as sip_lines, description as description, addon'; + break; + default: + $fld = $data['fields']; + break; + } + } + if (!empty($data['name'])) { //either filter by name or by type + $stmt = $dbh->prepare('SELECT ' . $fld . ' FROM sccpdeviceconfig WHERE name = :name ORDER BY name'); + $stmt->bindParam(':name', $data['name'],\PDO::PARAM_STR); + } elseif (!empty($data['type'])) { + switch ($data['type']) { + case "cisco-sip": + $stmts = $dbh->prepare('SELECT ' . $fld . ' FROM sccpdeviceconfig WHERE TYPE LIKE \'%-sip\' ORDER BY name'); + break; + case "cisco": // Fall through to default intentionally + default: + $stmts = $dbh->prepare('SELECT ' . $fld . ' FROM sccpdeviceconfig WHERE TYPE not LIKE \'%-sip\' ORDER BY name'); + break; + } + } else { //no filter and no name provided - return all + $stmts = $dbh->prepare("SELECT {$fld} FROM sccpdeviceconfig ORDER BY name"); + } + break; + case 'HWSipDevice': + $raw_settings = $this->getDb_model_info($get = "sipphones", $format_list = "model"); + break; + case 'HWDevice': + $raw_settings = $this->getDb_model_info($get = "ciscophones", $format_list = "model"); + break; + case 'HWextension': + $raw_settings = $this->getDb_model_info($get = "extension", $format_list = "model"); + break; + case 'get_columns_sccpdevice': + $stmts = $dbh->prepare('DESCRIBE sccpdevice'); + break; + case 'get_columns_sccpuser': + $stmts = $dbh->prepare('DESCRIBE sccpuser'); + break; + case 'get_sccpdevice_byid': + $stmt = $dbh->prepare('SELECT t1.*, types.dns, types.buttons, types.loadimage, types.nametemplate as nametemplate, + addon.buttons as addon_buttons FROM sccpdevice AS t1 + LEFT JOIN sccpdevmodel as types ON t1.type=types.model + LEFT JOIN sccpdevmodel as addon ON t1.addon=addon.model WHERE name = :name'); + $stmt->bindParam(':name', $data['id'],\PDO::PARAM_STR); + break; + case 'get_sccpuser': + $stmt = $dbh->prepare('SELECT * FROM sccpuser WHERE name = :name'); + $stmt->bindParam(':name', $data['id'],\PDO::PARAM_STR); + break; + case 'get_sccpdevice_buttons': + $sql = ''; + if (!empty($data['buttontype'])) { + $sql .= 'buttontype = :buttontype'; + } + if (!empty($data['id'])) { + $sql .= (empty($sql)) ? 'ref = :ref' : ' and ref = :ref'; + } + if (!empty($sql)) { + $stmts = $dbh->prepare("SELECT * FROM sccpbuttonconfig WHERE {$sql} ORDER BY instance"); + // Now bind labels - only bind label if it exists or bind will create exception. + // can only bind once have prepared, so need to test again. + if (!empty($data['buttontype'])) { + $stmts->bindParam(':buttontype', $data['buttontype'],\PDO::PARAM_STR); + } + if (!empty($data['id'])) { + $stmts->bindParam(':ref', $data['id'],\PDO::PARAM_STR); + } + } else { + $raw_settings = array(); + } + break; + } + if (!empty($stmt)) { + $stmt->execute(); + $raw_settings = $stmt->fetch(\PDO::FETCH_ASSOC); + } elseif (!empty($stmts)) { + $stmts->execute(); + $raw_settings = $stmts->fetchAll(\PDO::FETCH_ASSOC); + } + return $raw_settings; + } + + public function get_db_SccpSetting() + { + $dbh = \FreePBX::Database(); + try { + $stmt = $dbh->prepare('SELECT keyword, data, type, seq FROM sccpsettings ORDER BY type, seq'); + $stmt->execute(); + foreach ($stmt->fetchAll() as $var) { + $mysccpvalues[$var['keyword']] = array('keyword' => $var['keyword'], 'data' => $var['data'], 'seq' => $var['seq'], 'type' => $var['type']); + } + return $mysccpvalues; + } catch(\PDOException $e) { + // sccpsettings table does not yet exist. FreePBX is instantiating + // a SCCP_Manager object from the Installer before the installer can + // create the table so will create here. + $stmt = $dbh-> prepare('CREATE TABLE IF NOT EXISTS sccpsettings ( + keyword VARCHAR (50) NOT NULL, + data VARCHAR (255) NOT NULL, + seq TINYINT (1), + type TINYINT (1) NOT NULL default 0, + PRIMARY KEY (keyword, seq, type ) + );'); + $stmt->execute(); + //if ($dbh::IsError($check)) { + // die_freepbx("Can not create sccpsettings table, error: $check\n"); + //} + return array(); + } + } + + public function get_db_sysvalues() + { + $dbh = \FreePBX::Database(); + $stmt = $dbh->prepare('SHOW VARIABLES LIKE \'%group_concat%\''); + $stmt->execute(); + return $stmt->fetch(\PDO::FETCH_ASSOC); + } + + /* + * Get Sccp Device Model information + */ + + function getDb_model_info($get = 'all', $format_list = 'all', $filter = array()) + { + $dbh = \FreePBX::Database(); + $sel_inf = '*, 0 as validate'; + if ($format_list === 'model') { + $sel_inf = 'model, vendor, dns, buttons, 0 as validate'; + } + switch ($get) { + case 'byciscoid': + if (!empty($filter)) { + if (!empty($filter['model'])) { + if (!strpos($filter['model'], 'loadInformation')) { + $filter['model'] = 'loadInformation' . $filter['model']; + } + $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (loadinformationid = :model ) ORDER BY model"); + $stmt->bindParam(':model', $filter['model'], \PDO::PARAM_STR); + } else { + $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel ORDER BY model"); + } + break; + } + break; + case 'byid': + if (!empty($filter)) { + if (!empty($filter['model'])) { + $stmt = $dbh->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel WHERE model = :model ORDER BY model'); + $stmt->bindParam(':model', $filter['model'],\PDO::PARAM_STR); + } else { + $stmt = $dbh->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel ORDER BY model'); + } + break; + } + break; + case 'extension': + $stmt = $dbh->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel WHERE (dns = 0) and (enabled = 1) ORDER BY model'); + break; + case 'enabled': + //$stmt = $db->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel WHERE enabled = 1 ORDER BY model'); //previously this fell through to phones. + //break; // above includes expansion modules but was not original behaviour so commented out. Falls through to phones. + case 'phones': + $stmt = $dbh->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) ORDER BY model '); + break; + case 'ciscophones': + $stmt = $dbh->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) AND vendor NOT LIKE \'%-sip\' ORDER BY model'); + break; + case 'sipphones': + $stmt = $dbh->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) AND `vendor` LIKE \'%-sip\' ORDER BY model'); + break; + case 'all': // Fall through to default + default: + $stmt = $dbh->prepare('SELECT ' . $sel_inf . ' FROM sccpdevmodel ORDER BY model'); + break; + } + $stmt->execute(); + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } + + function write($table_name = "", $save_value = array(), $mode = 'update', $key_fld = "", $hwid = "") + { + // mode clear - Empty table before update + // mode update - update / replace record + $dbh = \FreePBX::Database(); + $result = false; + $delete_value = array(); + switch ($table_name) { + case 'sccpsettings': + if ($mode == 'replace') { // Change mode name to be more transparent + $dbh->prepare('TRUNCATE sccpsettings')->execute(); + $stmt = $dbh->prepare('INSERT INTO sccpsettings (keyword, data, seq, type) VALUES (:keyword,:data,:seq,:type)'); + } else { + $stmt = $dbh->prepare('REPLACE INTO sccpsettings (keyword, data, seq, type) VALUES (:keyword,:data,:seq,:type)'); + } + foreach ($save_value as $key => $dataArr) { + if (!empty($dataArr) && isset($dataArr['data'])) { + if ($dataArr['data'] == $this->val_null) { + $delete_value[] = $save_value[$key]['keyword']; + break; + } + } + $stmt->bindParam(':keyword',$dataArr['keyword'],\PDO::PARAM_STR); + $stmt->bindParam(':data',$dataArr['data'],\PDO::PARAM_STR); + $stmt->bindParam(':seq',$dataArr['seq'],\PDO::PARAM_INT); + $stmt->bindParam(':type',$dataArr['type'],\PDO::PARAM_INT); + $result = $stmt->execute(); + } + if (!empty($delete_value)) { + $stmt = $dbh->prepare('DELETE FROM sccpsettings WHERE keyword = :keyword'); + foreach ($delete_value as $del_key) { + $stmt->bindParam(':keyword',$del_key,\PDO::PARAM_STR); + $result = $stmt->execute(); + } + } + break; + case 'sccpdevmodel': // Fall through to next intentionally + case 'sccpdevice': // Fall through to next intentionally + case 'sccpuser': + $sql_key = ""; + $sql_var = ""; + foreach ($save_value as $key_v => $data) { + if (!empty($sql_var)) { + $sql_var .= ', '; + } + if ($data === $this->val_null) { + $sql_var .= $key_v . '= NULL'; + } else { + $sql_var .= $key_v . ' = \'' . $data . '\''; //quote data as normally is string + } + if ($key_v === $key_fld) { + $sql_key = $key_v . ' = \'' . $data . '\''; //quote data as normally is string + } + } + if (!empty($sql_var)) { + switch ($mode) { + case 'delete': + $stmt = $dbh->prepare('DELETE FROM '. $table_name . ' WHERE ' . $sql_key); + break; + case 'update': + $stmt = $dbh->prepare('UPDATE ' . $table_name . ' SET ' . $sql_var . ' WHERE ' . $sql_key); + break; + case 'replace': + $stmt = $dbh->prepare('REPLACE INTO ' . $table_name . ' SET ' . $sql_var); + break; + // no default mode - must be explicit. + } + } + $result = $stmt->execute(); + break; + case 'sccpbuttons': + switch ($mode) { + case 'delete': + $sql = 'DELETE FROM sccpbuttonconfig WHERE ref = :hwid'; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':hwid', $hwid,\PDO::PARAM_STR); + $result = $stmt->execute(); + break; + case 'replace': + foreach ($save_value as $button_array) { + $stmt = $dbh->prepare('UPDATE sccpbuttonconfig SET name =:name WHERE ref = :ref AND reftype =:reftype AND instance = :instance AND buttontype = :buttontype'); + $stmt->bindParam(':ref', $button_array['ref'],\PDO::PARAM_STR); + $stmt->bindParam(':reftype', $button_array['reftype'],\PDO::PARAM_STR); + $stmt->bindParam(':instance', $button_array['instance'],\PDO::PARAM_INT); + $stmt->bindParam(':buttontype', $button_array['type'],\PDO::PARAM_STR); + $stmt->bindParam(':name', $button_array['name'],\PDO::PARAM_STR); + $result= $dbh->execute(); + } + break; + case 'add': + foreach ($save_value as $button_array) { + $stmt = $dbh->prepare('INSERT INTO sccpbuttonconfig (ref, reftype, instance, buttontype, name, options) VALUES (:ref, :reftype, :instance, :buttontype, :name, :options)'); + $stmt->bindParam(':ref', $button_array['ref'],\PDO::PARAM_STR); + $stmt->bindParam(':reftype', $button_array['reftype'],\PDO::PARAM_STR); + $stmt->bindParam(':instance', $button_array['instance'],\PDO::PARAM_INT); + $stmt->bindParam(':buttontype', $button_array['type'],\PDO::PARAM_STR); + $stmt->bindParam(':name', $button_array['name'],\PDO::PARAM_STR); + $stmt->bindParam(':options', $button_array['options'],\PDO::PARAM_STR); + $result = $stmt->execute(); + } + break; + case 'clear'; + // Clear is equivalent of delete + insert. + $this->write('sccpbuttons', '', $mode = 'delete','', $hwid); + $this->write('sccpbuttons', $save_value, $mode = 'add','', $hwid); + break; + // No default case - must be specific in request. + } + } + return $result; + } + + /* + * Maybe Replace by SccpTables ??! + * + */ + public function dump_sccp_tables($data_path, $database, $user, $pass) + { + $filename = $data_path.'/sccp_backup_'.date('G_a_m_d_y').'.sql'; + $result = exec('mysqldump '.$database.' --password='.$pass.' --user='.$user.' --single-transaction >'.$filename, $output); + return $filename; + } + +/* + * Check Table structure + */ + public function validate() + { + $dbh = \FreePBX::Database(); + $result = 0; + $check_fields = [ + '430' => ['_hwlang' => "varchar(12)"], + '431' => ['private'=> "enum('on','off')"], + '433' => ['directed_pickup'=>''] + ]; + $stmt = $dbh->prepare('DESCRIBE sccpdevice'); + $stmt->execute(); + foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $value) { + $id_result[$value['Field']] = $value['Type']; + } + foreach ($check_fields as $key => $value) { + if (!empty(array_intersect_assoc($value, $id_result))) { + $result = $key; + } else { + // no match but maybe checking against an empty string so just need to check key does not exist + foreach ($value as $skey => $svalue) { + if (empty($svalue) && (!isset($id_result[$skey]))) { + $result = $key; + } + } + } + } + + return $result; + } +} diff --git a/Sccp_manager.inc/extconfigs.class.php b/Sccp_manager.inc/extconfigs.class.php new file mode 100644 index 0000000..08ffad2 --- /dev/null +++ b/Sccp_manager.inc/extconfigs.class.php @@ -0,0 +1,506 @@ +paren_class = $parent_class; + } + + public function info() + { + $Ver = '13.0.3'; + return array('Version' => $Ver, + 'about' => 'Default Setings and Enums ver: ' . $Ver); + } + + public function getextConfig($id = '', $index = '') + { + switch ($id) { + case 'keyset': + $result = $this->keysetdefault; + break; + case 'sccp_lang': + $result = $this->cisco_language; + break; + case 'sccpDefaults': + $result = $this->sccpDefaults; + break; + case 'sccp_timezone_offset': // Sccp manafer: 1400 (+ Id) :2007 (+ Id) + if (empty($index)) { + return 0; + } + if (array_key_exists($index, $this->cisco_timezone)) { + $tmp_time = $this->get_cisco_time_zone($index); + return $tmp_time['offset']; + } + + $tmp_dt = new \DateTime(null, new \DateTimeZone($index)); + $tmp_ofset = $tmp_dt->getOffset(); + return $tmp_ofset / 60; + + break; + case 'sccp_timezone': // Sccp manafer: 1400 (+ Id) :2007 (+ Id) + $result = array(); + + if (empty($index)) { + return array('offset' => '00', 'daylight' => '', 'cisco_code' => 'Greenwich'); + } + if (array_key_exists($index, $this->cisco_timezone)) { + return $this->get_cisco_time_zone($index); + } else { + $timezone_abbreviations = \DateTimeZone::listAbbreviations(); + + $tz_tmp = array(); + foreach ($timezone_abbreviations as $subArray) { + $tf_idt = array_search($index, array_column($subArray, 'timezone_id')); + if (!empty($tf_idt)) { + $tz_tmp[] = $subArray[$tf_idt]; + } + } + if (empty($tz_tmp)) { + return array('offset' => '00', 'daylight' => '', 'cisco_code' => 'Greenwich'); + } + + if (count($tz_tmp)==1) { + $time_set = $tz_tmp[0]; + } else { + $tmp_dt = new \DateTime(null, new \DateTimeZone($index)); + $tmp_ofset = $tmp_dt->getOffset(); + foreach ($tz_tmp as $subArray) { + if ($subArray['offset'] == $tmp_ofset) { + $time_set = $subArray; + break; + } + } + } + $tmp_ofset = $time_set['offset'] / 60; + $tmp_dli = (empty($time_set['dst']) ? '' : 'Daylight' ); + foreach ($this->cisco_timezone as $key => $value) { + if (($value['offset'] == $tmp_ofset) and ( $value['daylight'] == $tmp_dli )) { + return $this->get_cisco_time_zone($key); + break; + } + } + return array('offset' => '00', 'daylight' => '', 'cisco_code' => 'Greenwich'); + } + break; + default: + return array('noId'); + break; + } + if (empty($index)) { + return $result; + } else { + if (isset($result[$index])) { + return $result[$index]; + } else { + return array(); + } + } + } + + private function get_cisco_time_zone($tzc) + { + + if ((empty($tzc)) or (!array_key_exists($tzc, $this->cisco_timezone))) { +// return array('offset' => '00', 'daylight' => '', 'cisco_code' => 'Greenwich'); + return array(); + } + $tzdata = $this->cisco_timezone[$tzc]; + $cisco_code = $tzc . ' Standard' . ((empty($tzdata['daylight'])) ? '' : '/' . $tzdata['daylight']) . ' Time'; + if (isset($tzdata['cisco_code'])) { + $cisco_code = (empty($tzdata['cisco_code'])) ? $cisco_code : $tzdata['cisco_code']; + } + return array('offset' => $tzdata['offset'], 'daylight' => $tzdata['daylight'], 'cisco_code' => $cisco_code); + } + + private $sccpDefaults = array( + "servername" => 'VPBXSCCP', + "bindaddr" => '0.0.0.0', "port" => '2000', # chan_sccp also supports ipv6 + # bindaddr = "::" will support ipv6 and ipv4 at the same time + "deny" => '0.0.0.0/0.0.0.0', + "permit" => '0.0.0.0/0.0.0.0', # !TODO!: please change this to 'internal' which would mean: + # permit:127.0.0.0/255.0.0.0,permit:10.0.0.0/255.0.0.0,permit:172.0.0.0/255.224.0.0,permit:192.168.0.0/255.255.0.0" + "dateformat" => 'D.M.Y', # This is the german default format. Should be "D/M/Y" or "D/M/YA" instead + "disallow" => 'all', "allow" => 'alaw;ulaw', + "hotline_enabled" => 'off', + "hotline_context" => 'default', # !TODO!: Should this not be from-internal on FreePBX ? + "hotline_extension" => '*60', # !TODO!: Is this a good default extension to dial for hotline ? + "hotline_label" => 'hotline', + "devicetable" => 'sccpdevice', + "linetable" => 'sccpline', + "tftp_path" => '/tftpboot' + ); + private $keysetdefault = array('onhook' => 'redial,newcall,cfwdall,cfwdbusy,cfwdnoanswer,pickup,gpickup,dnd,private', + 'connected' => 'hold,endcall,park,vidmode,select,cfwdall,cfwdbusy,idivert,monitor', + 'onhold' => 'resume,newcall,endcall,transfer,conflist,select,dirtrfr,idivert,meetme', + 'ringin' => 'answer,endcall,transvm,idivert', + 'offhook' => 'redial,endcall,private,cfwdall,cfwdbusy,cfwdnoanswer,pickup,gpickup,meetme,barg', + 'conntrans' => 'hold,endcall,transfer,conf,park,select,dirtrfr,monitor,vidmode,meetme,cfwdal', + 'digitsfoll' => 'back,endcall,dial', + 'connconf' => 'conflist,newcall,endcall,hold,vidmode,monitor', + 'ringout' => 'empty,endcall,transfer', + 'offhookfeat' => 'resume,newcall,endcall', + 'onhint' => 'redial,newcall,pickup,gpickup', + 'onstealable' => 'redial,newcall,barge,intrcpt,cfwdall,pickup,gpickup,dnd', + 'holdconf' => 'resume,newcall,endcall,join', + 'uriaction' => 'default'); +// Cisco Language Code / Directory +// + private $cisco_language = array('ar_SA' => array('code' => 'ar', 'language' => 'Arabic', 'locale' => 'Arabic_Saudi_Arabia', 'codepage' => 'ISO8859-1'), + 'bg_BG' => array('code' => 'bg', 'language' => 'Bulgarian', 'locale' => 'Bulgarian_Bulgaria', 'codepage' => 'ISO8859-1'), + 'cz_CZ' => array('code' => 'cz', 'language' => 'Czech', 'locale' => 'Czech_Czech_Republic', 'codepage' => 'ISO8859-1'), + 'da_DK' => array('code' => 'da', 'language' => 'Danish', 'locale' => 'Danish_Denmark', 'codepage' => 'ISO8859-1'), + 'de_DE' => array('code' => 'de', 'language' => 'German', 'locale' => 'German_Germany', 'codepage' => 'ISO8859-1'), + 'el_GR' => array('code' => 'el', 'language' => 'Greek', 'locale' => 'Greek_Greece', 'codepage' => 'ISO8859-1'), + 'en_AU' => array('code' => 'en', 'language' => 'English', 'locale' => 'AU_English_United_States', 'codepage' => 'ISO8859-1'), + 'en_GB' => array('code' => 'en', 'language' => 'English', 'locale' => 'English_United_Kingdom', 'codepage' => 'ISO8859-1'), + 'en_US' => array('code' => 'en', 'language' => 'English', 'locale' => 'English_United_States', 'codepage' => 'ISO8859-1'), + 'es_ES' => array('code' => 'es', 'language' => 'Spanish', 'locale' => 'Spanish_Spain', 'codepage' => 'ISO8859-1'), + 'et_EE' => array('code' => 'et', 'language' => 'Estonian', 'locale' => 'Estonian_Estonia', 'codepage' => 'ISO8859-1'), + 'fi_FI' => array('code' => 'fi', 'language' => 'Finnish', 'locale' => 'Finnish_Finland', 'codepage' => 'ISO8859-1'), + 'fr_CA' => array('code' => 'fr', 'language' => 'French', 'locale' => 'French_Canada', 'codepage' => 'ISO8859-1'), + 'fr_FR' => array('code' => 'fr', 'language' => 'French', 'locale' => 'French_France', 'codepage' => 'ISO8859-1'), + 'he_IL' => array('code' => 'he', 'language' => 'Hebrew', 'locale' => 'Hebrew_Israel', 'codepage' => 'ISO8859-1'), + 'hr_HR' => array('code' => 'hr', 'language' => 'Croatian', 'locale' => 'Croatian_Croatia', 'codepage' => 'ISO8859-1'), + 'hu_HU' => array('code' => 'hu', 'language' => 'Hungarian', 'locale' => 'Hungarian_Hungary', 'codepage' => 'ISO8859-1'), + 'it_IT' => array('code' => 'it', 'language' => 'Italian', 'locale' => 'Italian_Italy', 'codepage' => 'ISO8859-1'), + 'ja_JP' => array('code' => 'ja', 'language' => 'Japanese', 'locale' => 'Japanese_Japan', 'codepage' => 'ISO8859-1'), + 'ko_KO' => array('code' => 'ko', 'language' => 'Korean', 'locale' => 'Korean_Korea_Republic', 'codepage' => 'ISO8859-1'), + 'lt_LT' => array('code' => 'lt', 'language' => 'Lithuanian', 'locale' => 'Lithuanian_Lithuania', 'codepage' => 'ISO8859-1'), + 'lv_LV' => array('code' => 'lv', 'language' => 'Latvian', 'locale' => 'Latvian_Latvia', 'codepage' => 'ISO8859-1'), + 'nl_NL' => array('code' => 'nl', 'language' => 'Dutch', 'locale' => 'Dutch_Netherlands', 'codepage' => 'ISO8859-1'), + 'no_NO' => array('code' => 'no', 'language' => 'Norwegian', 'locale' => 'Norwegian_Norway', 'codepage' => 'ISO8859-1'), + 'pl_PL' => array('code' => 'pl', 'language' => 'Polish', 'locale' => 'Polish_Poland', 'codepage' => 'ISO8859-1'), + 'pt_BR' => array('code' => 'pt', 'language' => 'Portuguese', 'locale' => 'Portuguese_Brazil', 'codepage' => 'ISO8859-1'), + 'pt_PT' => array('code' => 'pt', 'language' => 'Portuguese', 'locale' => 'Portuguese_Portugal', 'codepage' => 'ISO8859-1'), + 'ro_RO' => array('code' => 'ro', 'language' => 'Romanian', 'locale' => 'Romanian_Romania', 'codepage' => 'ISO8859-1'), + 'ru_RU' => array('code' => 'ru', 'language' => 'Russian', 'locale' => 'Russian_Russian_Federation', 'codepage' => 'CP1251'), + 'sk_SK' => array('code' => 'sk', 'language' => 'Slovakian', 'locale' => 'Slovak_Slovakia', 'codepage' => 'ISO8859-1'), + 'sl_SL' => array('code' => 'sl', 'language' => 'Slovenian', 'locale' => 'Slovenian_Slovenia', 'codepage' => 'ISO8859-1'), + 'sr_ME' => array('code' => 'sr', 'language' => 'Serbian', 'locale' => 'Serbian_Republic_of_Montenegro', 'codepage' => 'ISO8859-1'), + 'sr_RS' => array('code' => 'rs', 'language' => 'Serbian', 'locale' => 'Serbian_Republic_of_Serbia', 'codepage' => 'ISO8859-1'), + 'sv_SE' => array('code' => 'sv', 'language' => 'Swedish', 'locale' => 'Swedish_Sweden', 'codepage' => 'ISO8859-1'), + 'th_TH' => array('code' => 'th', 'language' => 'Thailand', 'locale' => 'Thai_Thailand', 'codepage' => 'ISO8859-1'), + 'tr_TR' => array('code' => 'tr', 'language' => 'Turkish', 'locale' => 'Turkish_Turkey', 'codepage' => 'ISO8859-1'), + 'zh_CN' => array('code' => 'cn', 'language' => 'Chinese', 'locale' => 'Chinese_China', 'codepage' => 'ISO8859-1'), + 'zh_TW' => array('code' => 'zh', 'language' => 'Chinese', 'locale' => 'Chinese_Taiwan', 'codepage' => 'ISO8859-1') + ); + private $cisco_timezone = array( + 'Dateline' => array('offset' => '-720', 'daylight' => ''), + 'Samoa' => array('offset' => '-660', 'daylight' => ''), + 'Hawaiian' => array('offset' => '-600', 'daylight' => ''), + 'Alaskan' => array('offset' => '-540', 'daylight' => 'Daylight'), + 'Pacific' => array('offset' => '-480', 'daylight' => 'Daylight'), + 'Mountain' => array('offset' => '-420', 'daylight' => 'Daylight'), + 'US Mountain' => array('offset' => '-420', 'daylight' => ''), + 'Central' => array('offset' => '-360', 'daylight' => 'Daylight'), + 'Mexico' => array('offset' => '-360', 'daylight' => 'Daylight'), + 'Canada Central' => array('offset' => '-360', 'daylight' => ''), + 'SA Pacific' => array('offset' => '-300', 'daylight' => ''), + 'Eastern' => array('offset' => '-300', 'daylight' => 'Daylight'), + 'US Eastern' => array('offset' => '-300', 'daylight' => ''), + 'Atlantic' => array('offset' => '-240', 'daylight' => 'Daylight'), + 'SA Western' => array('offset' => '-240', 'daylight' => ''), + 'Pacific SA' => array('offset' => '-240', 'daylight' => ''), + 'Newfoundland' => array('offset' => '-210', 'daylight' => 'Daylight'), + 'E. South America' => array('offset' => '-180', 'daylight' => 'Daylight'), + 'SA Eastern' => array('offset' => '-180', 'daylight' => ''), + 'Pacific SA' => array('offset' => '-180', 'daylight' => 'Daylight'), + 'Mid-Atlantic' => array('offset' => '-120', 'daylight' => 'Daylight'), + 'Azores' => array('offset' => '-060', 'daylight' => 'Daylight'), + 'GMT' => array('offset' => '00', 'daylight' => 'Daylight'), + 'Greenwich' => array('offset' => '00', 'daylight' => ''), + 'W. Europe' => array('offset' => '60', 'daylight' => 'Daylight'), + 'GTB' => array('offset' => '60', 'daylight' => 'Daylight'), + 'Egypt' => array('offset' => '60', 'daylight' => 'Daylight'), + 'E. Europe' => array('offset' => '60', 'daylight' => 'Daylight'), + 'Romance' => array('offset' => '120', 'daylight' => 'Daylight'), + 'Central Europe' => array('offset' => '120', 'daylight' => 'Daylight'), + 'South Africa' => array('offset' => '120', 'daylight' => ''), + 'Jerusalem' => array('offset' => '120', 'daylight' => 'Daylight'), + 'Saudi Arabia' => array('offset' => '180', 'daylight' => ''), + /* Russian Regions */ + 'Russian/Kaliningrad' => array('offset' => '120', 'daylight' => '', 'cisco_code' => 'South Africa Standard Time'), + 'Russian/Moscow' => array('offset' => '180', 'daylight' => '', 'cisco_code' => 'Russian Standard Time'), + 'Russian/St.Peterburg' => array('offset' => '180', 'daylight' => '', 'cisco_code' => 'Russian Standard Time'), + 'Russian/Samara' => array('offset' => '240', 'daylight' => '', 'cisco_code' => 'Arabian Standard Time'), + 'Russian/Novosibirsk' => array('offset' => '300', 'daylight' => '', 'cisco_code' => 'Ekaterinburg Standard Time'), + 'Russian/Ekaterinburg' => array('offset' => '300', 'daylight' => '', 'cisco_code' => 'Ekaterinburg Standard Time'), + 'Russian/Irkutsk' => array('offset' => '480', 'daylight' => '', 'cisco_code' => 'China Standard Time'), + 'Russian/Yakutsk' => array('offset' => '540', 'daylight' => '', 'cisco_code' => 'Tokyo Standard Time'), + 'Russian/Khabarovsk' => array('offset' => '600', 'daylight' => '', 'cisco_code' => 'West Pacific Standard Time'), + 'Russian/Vladivostok' => array('offset' => '600', 'daylight' => '', 'cisco_code' => 'West Pacific Standard Time'), + 'Russian/Sakhalin' => array('offset' => '660', 'daylight' => '', 'cisco_code' => 'Central Pacific Standard Time'), + 'Russian/Magadan' => array('offset' => '660', 'daylight' => '', 'cisco_code' => 'Central Pacific Standard Time'), + 'Russian/Kamchatka' => array('offset' => '720', 'daylight' => '', 'cisco_code' => 'Fiji Standard Time'), + /* EnD - Russian Regions */ + 'Iran' => array('offset' => '210', 'daylight' => 'Daylight'), + 'Caucasus' => array('offset' => '240', 'daylight' => 'Daylight'), + 'Arabian' => array('offset' => '240', 'daylight' => ''), + 'Afghanistan' => array('offset' => '270', 'daylight' => ''), + 'West Asia' => array('offset' => '300', 'daylight' => ''), + 'India' => array('offset' => '330', 'daylight' => ''), + 'Central Asia' => array('offset' => '360', 'daylight' => ''), + 'SE Asia' => array('offset' => '420', 'daylight' => ''), + 'China' => array('offset' => '480', 'daylight' => ''), + 'Taipei' => array('offset' => '480', 'daylight' => ''), + 'Tokyo' => array('offset' => '540', 'daylight' => ''), + 'Cen. Australia' => array('offset' => '570', 'daylight' => 'Daylight'), + 'AUS Central' => array('offset' => '570', 'daylight' => ''), + 'E. Australia' => array('offset' => '600', 'daylight' => ''), + 'AUS Eastern' => array('offset' => '600', 'daylight' => 'Daylight'), + 'West Pacific' => array('offset' => '600', 'daylight' => ''), + 'Tasmania' => array('offset' => '600', 'daylight' => 'Daylight'), + 'Central Pacific' => array('offset' => '660', 'daylight' => ''), + 'Fiji' => array('offset' => '720', 'daylight' => ''), + 'New Zealand' => array('offset' => '720', 'daylight' => 'Daylight') + ); + + public function validate_init_path($confDir = '', $db_vars, $sccp_driver_replace = '') + { +// global $db; +// global $amp_conf; +// *** Setings for Provision Sccp + $adv_config = array('tftproot' => '', 'firmware' => 'firmware', 'settings' => 'settings', + 'locales' => 'locales', 'languages' => 'languages', 'templates' => 'templates', 'dialplan' => 'dialplan', 'softkey' => 'softkey'); +// 'pro' /tftpboot - root dir +// /tftpboot/locales/locales/%Languge_name% +// /tftpboot/settings/XMLdefault.cnf.xml +// /tftpboot/settings/SEP[MAC].cnf.xml +// /tftpboot/firmware/79xx/SCCPxxxx.loads + $adv_tree['pro'] = array('templates' => 'tftproot', 'settings' => 'tftproot', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'locales', 'dialplan' => 'tftproot', 'softkey' => 'tftproot'); + +// 'def' /tftpboot - root dir +// /tftpboot/languages/%Languge_name% +// /tftpboot/XMLdefault.cnf.xml +// /tftpboot/SEP[MAC].cnf.xml +// /tftpboot/SCCPxxxx.loads + $adv_tree['def'] = array('templates' => 'tftproot', 'settings' => '', 'locales' => '', 'firmware' => '', 'languages' => 'tftproot', 'dialplan' => '', 'softkey' => ''); +// $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => ''); +// $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'tftproot'); +//* **************------ **** + $base_tree = array('tftp_templates' => 'templates', 'tftp_path_store' => 'settings', 'tftp_lang_path' => 'languages', 'tftp_firmware_path' => 'firmware', 'tftp_dialplan' => 'dialplan', 'tftp_softkey' => 'softkey'); + + if (empty($confDir)) { + return array('error' => 'empty СonfDir'); + } + + $base_config = array('asterisk' => $confDir, 'sccp_conf' => $confDir . '/sccp.conf', 'tftp_path' => ''); + +// Test Base dir (/tftproot) + if (!empty($db_vars["tftp_path"])) { + if (file_exists($db_vars["tftp_path"]["data"])) { + $base_config["tftp_path"] = $db_vars["tftp_path"]["data"]; + } + } + if (empty($base_config["tftp_path"])) { + if (file_exists($this->getextConfig('sccpDefaults', "tftp_path"))) { + $base_config["tftp_path"] = $this->getextConfig('sccpDefaults', "tftp_path"); + } + } + if (empty($base_config["tftp_path"])) { + if (!empty($this->paren_class)) { + $this->paren_class->class_error['tftp_path'] = 'Tftp path not exist or not defined'; + } + return array('error' => 'empty tftp_path'); + } + if (!is_writeable($base_config["tftp_path"])) { + if (!empty($this->paren_class)) { + $this->paren_class->class_error['tftp_path'] = 'No write permission on tftp DIR'; + } + return array('error' => 'No write permission on tftp DIR'); + } +// END Test Base dir (/tftproot) + + if (!empty($db_vars['tftp_rewrite_path'])) { + $adv_ini = $db_vars['tftp_rewrite_path']["data"]; + } + + $adv_tree_mode = 'def'; + if (empty($db_vars["tftp_rewrite"])) { + $db_vars["tftp_rewrite"]["data"] = "off"; + } + + $adv_config['tftproot'] = $base_config["tftp_path"]; + if ($db_vars["tftp_rewrite"]["data"] == 'pro') { + $adv_tree_mode = 'pro'; + if (!empty($adv_ini)) { // something found in external conflicts + $adv_ini .= '/index.cnf'; + if (file_exists($adv_ini)) { + $adv_ini_array = parse_ini_file($adv_ini); + $adv_config = array_merge($adv_config, $adv_ini_array); + } + } + } + if ($db_vars["tftp_rewrite"]["data"] == 'on') { + $adv_tree_mode = 'def'; + } + foreach ($adv_tree[$adv_tree_mode] as $key => $value) { + if (!empty($adv_config[$key])) { + if (!empty($value)) { + if (substr($adv_config[$key], 0, 1) != "/") { + $adv_config[$key] = $adv_config[$value] . '/' . $adv_config[$key]; + } + } else { + $adv_config[$key] = $adv_config['tftproot']; + } + } + } + foreach ($base_tree as $key => $value) { + $base_config[$key] = $adv_config[$value]; + if (!file_exists($base_config[$key])) { + if (!mkdir($base_config[$key], 0777, true)) { + die('Error creating dir : ' . $base_config[$key]); + } + } + } + print_r($base_config, 1); +// die(print_r($base_config,1)); +// $base_config['External_ini'] = $adv_config; +// $base_config['External_mode'] = $adv_tree_mode; + + /* + if (!empty($this->sccppath["tftp_path"])) { + $this->sccppath["tftp_DP"] = $this->sccppath["tftp_path"] . '/Dialplan'; + if (!file_exists($this->sccppath["tftp_DP"])) { + if (!mkdir($this->sccppath["tftp_DP"], 0777, true)) { + die('Error creating DialPlan template dir'); + } + } + } + */ + // TFTP -REWrite double model + if (empty($_SERVER['DOCUMENT_ROOT'])) { + if (!empty($this->paren_class)) { + $this->paren_class->class_error['DOCUMENT_ROOT'] = 'Empty DOCUMENT_ROOT'; + } + $base_config['error'] = 'Empty DOCUMENT_ROOT'; + return $base_config; + } + + if (!file_exists($base_config["tftp_templates"] . '/XMLDefault.cnf.xml_template')) { + $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/'; + $dst_path = $base_config["tftp_templates"] . '/'; + foreach (glob($src_path . '*.*_template') as $filename) { + copy($filename, $dst_path . basename($filename)); + } + } + + + $dst = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/core/functions.inc/drivers/Sccp.class.php'; + if (!file_exists($dst) || $sccp_driver_replace == 'yes') { + $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/' . basename($dst) . '.v' . $db_vars['sccp_compatible']['data']; + if (file_exists($src_path)) { + copy($src_path, $dst); + } else { + $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/' . basename($dst); + copy($src_path, $dst); + } + } + + if (!file_exists($base_config["sccp_conf"])) { // System re Config + $sccpfile = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/sccp.conf'); + file_put_contents($base_config["sccp_conf"], $sccpfile); + } + + return $base_config; + } + // Type declaration in below function is incompatible with PHP 5 + public function validate_RealTime( $connector ) + { + // This method only checks that asterisk is correctly configured for Realtime + // It is preventative and does not change anything for Sccp_manager + global $amp_conf; + $res = array(); +/* if (empty($connector)) { + $connector = 'sccp'; + } + $cnf_int = \FreePBX::Config(); + $cnf_wr = \FreePBX::WriteConfig(); +*/ + $cnf_read = \FreePBX::LoadConfig(); + + // We are running inside FreePBX so must use the same database + $def_config = array('sccpdevice' => 'mysql,' . $amp_conf['AMPDBNAME'] . ',sccpdeviceconfig', 'sccpline' => 'mysql,' . $amp_conf['AMPDBNAME'] . ',sccpline'); + $backup_ext = array('_custom.conf', '.conf', '_additional.conf'); + $def_bd_config = array('dbhost' => $amp_conf['AMPDBHOST'], 'dbname' => $amp_conf['AMPDBNAME'], + 'dbuser' => $amp_conf['AMPDBUSER'], 'dbpass' => $amp_conf['AMPDBPASS'], + 'dbport' => '3306', 'dbsock' => '/var/lib/mysql/mysql.sock' + ); + $dir = $amp_conf['ASTETCDIR']; + $res_conf_sql = ini_get('pdo_mysql.default_socket'); + $res_conf = ''; + $ext_conf = ''; + + foreach ($backup_ext as $fext) { + if (file_exists($dir . '/extconfig' . $fext)) { + $ext_conf = $cnf_read->getConfig('extconfig' . $fext); + if (!empty($ext_conf['settings']['sccpdevice'])) { + if ($ext_conf['settings']['sccpdevice'] === $def_config['sccpdevice']) { + $res['sccpdevice'] = 'OK'; + $res['extconfigfile'] = 'extconfig' . $fext; + } else { + $res['sccpdevice'] .= ' Error in line sccpdevice '; + } + } + if (!empty($ext_conf['settings']['sccpline'])) { + if ($ext_conf['settings']['sccpline'] === $def_config['sccpline']) { + $res['sccpline'] = 'OK'; + } else { + $res['sccpline'] .= ' Error in line sccpline '; + } + } + } + } + + $res['extconfig'] = 'OK'; + + if (empty($res['sccpdevice'])) { + $res['extconfig'] = ' Option "Sccpdevice" is not configured '; + } + if (empty($res['sccpline'])) { + $res['extconfig'] = ' Option "Sccpline" is not configured '; + } + + if (empty($res['extconfigfile'])) { + $res['extconfig'] = 'File extconfig.conf does not exist'; + } + + if (!empty($res_conf_sql)) { + if (file_exists($res_conf_sql)) { + $def_bd_config['dbsock'] = $res_conf_sql; + } + } + // Check for mysql config files - should only be one depending on version + $mySqlConfigFiles = [ 'res_mysql.conf', 'res_config_mysql.conf' ]; + foreach ($mySqlConfigFiles as $sqlConfigFile) { + if (file_exists( $dir . '/' . $sqlConfigFile )) { + $res_conf = $cnf_read->getConfig($sqlConfigFile); + if (empty($res_conf[$connector])) { + $res['mysqlconfig'] = 'Config not found in file: ' . $sqlConfigFile; + } else { + if ($res_conf[$connector]['dbsock'] != $def_bd_config['dbsock']) { + $res['mysqlconfig'] = 'Mysql Socket Error in file: ' . $sqlConfigFile; + } + } + if (empty($res['mysqlconfig'])) { + $res['mysqlconfig'] = 'OK'; + } + } + } + + if (empty($res['mysqlconfig'])) { + $res['mysqlconfig'] = 'Realtime Error: neither res_config_mysql.conf nor res_mysql.conf found in the path : ' . $dir; + } + return $res; + } +} diff --git a/Sccp_manager.inc/sipconfigs.class.php b/Sccp_manager.inc/sipconfigs.class.php new file mode 100644 index 0000000..5704981 --- /dev/null +++ b/Sccp_manager.inc/sipconfigs.class.php @@ -0,0 +1,163 @@ +paren_class = $parent_class; +// $freepbx +// $this->database = $freepbx->Database; + } + + public function info() + { + $Ver = '13.0.4'; + return array('Version' => $Ver, + 'about' => 'Sip Setings ver: ' . $Ver); + } + + public function get_db_sip_TableData($dataid, $data = array()) + { + global $db; + if ($dataid == '') { + return false; + } + switch ($dataid) { + case "Device": + $sql = "SELECT * FROM sip ORDER BY `id`"; + $tech = array(); + try { + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + foreach ($raw_settings as $value) { + if (empty($tech[$value['id']]['id'])) { + $tech[$value['id']]['id']= $value['id']; + } + $tech[$value['id']][$value['keyword']]=$value['data']; + } + } catch (\Exception $e) { + } + return $tech; + case "DeviceById": + $sql = "SELECT keyword,data FROM sip WHERE id = ?"; + $sth = $db->prepare($sql); + $tech = array(); + try { + $id = $data['id']; + $sth->execute(array($id)); + $tech = $sth->fetchAll(\PDO::FETCH_COLUMN | \PDO::FETCH_GROUP); + foreach ($tech as &$value) { + $value = $value[0]; + } + } catch (\Exception $e) { + } + return $tech; + } + } + + public function getSipConfig() + { + $result = array(); +// $def_sip_proto = 'sip'; +// $def_proto = 'tcp'; +// $supp_proto = ''; + +// $result['sipport'] = \FreePBX::Sipsettings()->getConfig('bindport'); +// $result['tlsport'] = \FreePBX::Sipsettings()->getConfig('tlsbindport'); +// $tmp_sipsetigs = \FreePBX::Sipsettings()->getChanSipSettings(); + $tmp_binds = \FreePBX::Sipsettings()->getBinds(); + $if_list = $this->paren_class ->getIpInformation('ip4'); + +/* + $tmp_bind_ip = !empty($tmp_sipsetigs['externhost_val']) ? $tmp_sipsetigs['externhost_val'] : ''; + $tmp_bind_ip = !empty($tmp_sipsetigs['externip_val']) ? $tmp_sipsetigs['externip_val'] : $tmp_bind_ip; + $tmp_bind_ip = !empty($tmp_sipsetigs['bindaddr']) ? $tmp_sipsetigs['bindaddr'] : $tmp_bind_ip; + */ + $tmp_binds = is_array($tmp_binds) ? $tmp_binds: array(); + $result = array(); + foreach ($tmp_binds as $f_protocol => $f_bind) { + foreach ($f_bind as $f_ip => $f_port) { + if (($f_ip == '0.0.0.0') || ($f_ip == '[::]')) { + foreach ($if_list as $f_if => $f_data) { + if ($f_data['ip'] == "127.0.0.1") { + continue; + } + if (empty($result[$f_protocol][$f_data['ip']])) { + $result[$f_protocol][$f_data['ip']]= $f_port; + } else { + $result[$f_protocol][$f_data['ip']]= array_merge($result[$f_protocol][$f_data['ip']],$f_port); + } + $result[$f_protocol][$f_data['ip']]['ip']=$f_data['ip']; + } + } else { + $result[$f_protocol][$f_ip]=$f_port; + $result[$f_protocol][$f_ip]['ip']=$f_ip; + } + } + } + return $result; +/* +// $result['sipbind'] = $tmp_bind_ip; + if (empty($tmp_sip_binds[$def_sip_proto])){ + $def_proto = 'pjsip'; + } + return $result; + + foreach ($tmp_sip_binds[$def_sip_proto] as $key => $value) { + if (empty($value[$def_proto])) { + $def_proto = 'udp'; + $supp_proto = 'udp'; + } else { + $supp_proto = !empty($value['udp']) ? 'tcp;udp' : 'tcp'; + } + if (empty($def_key)) { + $def_key = $key; + } + if ($key != '0.0.0.0') { + $tmp_bind_ip = $key; + } + $result['sipbindport'] = $value[$def_proto]; + } + $result['sipbind'] = $tmp_bind_ip; + $result['sipsuportproto'] = $supp_proto; + + $binds= array(); + $driver = \FreePBX::Config()->get_conf_setting('ASTSIPDRIVER'); + if ($driver == "both" || $driver == "chan_pjsip") { + $b = \FreePBX::Sipsettings()->getConfig("binds"); + $b = is_array($b) ? $b : array(); + foreach($b as $protocol => $bind) { + foreach($bind as $ip => $state) { + if($state != "on") { + continue; + } + $p = \FreePBX::Sipsettings()->getConfig($protocol."port-".$ip); + $result['nb3'.$protocol] = $p; + if ($flatten) { + $binds['pjsip']['[::]'][$protocol] = $p; + } else { + $binds['pjsip'][$ip][$protocol] = $p; + } + } + } + } else { + $binds['pjsip'] = array("0.0.0.0" => array()); + } + + $result['nd'] = $driver; + + $result['nb'] = $binds; + $result['nb2'] = $b; + return $result; + * + */ + } +} diff --git a/Sccp_manager.inc/srvinterface.class.php b/Sccp_manager.inc/srvinterface.class.php new file mode 100644 index 0000000..982ecb1 --- /dev/null +++ b/Sccp_manager.inc/srvinterface.class.php @@ -0,0 +1,350 @@ +paren_class = $parent_class; + if ($this->paren_class == null) { + $this->paren_class = $this; + } + $this->error = ""; + $driverNamespace = "\\FreePBX\\Modules\\Sccp_manager"; + $drivers = array('aminterface' => 'aminterface.class.php', 'oldinterface' => 'oldinterface.class.php'); + $ami_mode = false; + foreach ($drivers as $key => $value) { + $class = $driverNamespace . "\\" . $key; + $driver = __DIR__ . "/aminterface/" . $value; + if (!class_exists($class, false)) { + if (file_exists($driver)) { + include($driver); + } else { + throw new \Exception("Class required but file not found " . $driver); + } + if (class_exists($class, false)) { + $this->$key = new $class($this->paren_class); + $parent_class->$key = $this->$key; + $this->_info [] = $this->$key->info(); + } else { + throw new \Exception("Invalid Class inside in the include folder" . $freepbx); + } + } else { + if (is_null($this->$key)) { + if (class_exists($class, false)) { + $this->$key = new $class($this->paren_class); + $this->_info [] = $this->$key->info(); + } + } + } + } + if ($this->aminterface->status()) { + // Ami is not hard disabled in Amiinterface __construct line 54. + if ($this->aminterface->open()) { + // Can open a connection. Now check compatibility with chan-sccp. + // will return true if compatible. + if (!$this->get_compatible_sccp(true)[1]) { + // Close the open socket as will not use + $this->aminterface->close(); + } else { + // is compatible so enable AMI mode + $this->ami_mode = true; + } + } + } + } + + public function info() { + $Ver = '14.0.1'; + $info = ''; + foreach ($this->_info as $key => $value) { + $info .= $value['about'] . "\n "; + } + return array('Version' => $Ver, + 'about' => 'Server interface data ver: ' . $Ver . "\n " . $info); + } + + public function sccpDeviceReset($id = '') { + if ($this->ami_mode) { + return $this->aminterface->sccpDeviceReset($id, 'reset'); + } else { + return $this->oldinterface->sccp_core_commands(array('cmd' => 'reset_phone', 'name' => $id)); + } + } + + public function sccpDeviceRestart($id = '') { + if ($this->ami_mode) { + return $this->aminterface->sccpDeviceReset($id, 'restart'); + } else { + return $this->oldinterface->sccp_core_commands(array('cmd' => 'reset_phone', 'name' => $id)); + } + } + + public function sccp_device_reload($id = '') { + if ($this->ami_mode) { + return $this->aminterface->sccpDeviceReset($id, 'full'); + } else { + return $this->oldinterface->sccp_core_commands(array('cmd' => 'reload_phone', 'name' => $id)); + } + } + + public function sccp_reset_token($id = '') { + if ($this->ami_mode) { + return $this->aminterface->sccpDeviceReset($id, 'tokenack'); + } else { + return $this->oldinterface->sccp_core_commands(array('cmd' => 'reset_token', 'name' => $id)); + } + } + + public function sccp_reload() { + if ($this->ami_mode) { + return $this->aminterface->core_sccp_reload(); +// return $this->oldinterface->sccp_core_commands(array('cmd' => 'sccp_reload')); // !!!!!!!!!!!!!!!!!!!!!!!!!--------------------------- Remove + } else { + return $this->oldinterface->sccp_core_commands(array('cmd' => 'sccp_reload')); + } + } + + public function sccp_line_reload($id = '') { + if ($this->ami_mode) { + return $this->oldinterface->sccp_core_commands(array('cmd' => 'reload_line', 'name' => $id)); + } else { + return $this->oldinterface->sccp_core_commands(array('cmd' => 'reload_line', 'name' => $id)); + } + } + + private function sccp_core_commands($params = array()) { + + if (!$this->ami_mode) { + return $this->oldinterface->sccp_core_commands($params); + } + + if (!empty($params['cmd'])) { + switch ($params['cmd']) { + case 'reset_phone': + return $this->aminterface->sccpDeviceReset($params['name'], 'reset'); + break; + case 'restart_phone': + return $this->aminterface->sccpDeviceReset($params['name'], 'restart'); + break; + case 'reload_phone': + return $this->aminterface->sccpDeviceReset($params['name'], 'full'); + break; + case 'reset_token': + return $this->aminterface->sccpDeviceReset($params['name'], 'tokenack'); + break; + case 'reload_line': +// return $this->aminterface->sccpDeviceReset($params['name'], 'full'); + break; +// case 'get_version': +// case 'sccp_reload': +// break; +// case 'get_realtime_status': +// break; +// case 'phone_call': +// case 'phone_message': + + case 'get_softkey': + case 'get_device': + case 'get_hints': + case 'get_dev_info': + print_r($params); + throw new \Exception("Invalid Class inside in the include folder" . $params['cmd']); + die(); + break; + default: + return $this->oldinterface->sccp_core_commands($params); + break; + } + } + + } + + public function sccp_getdevice_info($dev_id) { + if (empty($dev_id)) { + return array(); + } + if ($this->ami_mode) { + return $this->aminterface->sccp_getdevice_info($dev_id); + } else { + return $this->oldinterface->sccp_getdevice_info($dev_id); + } + } + + public function sccp_list_hints() { + if ($this->ami_mode) { + return $this->aminterface->core_list_hints(); + } else { + return $this->oldinterface->sccp_list_hints(); + } + } + + public function sccp_list_all_hints() { + + if ($this->ami_mode) { + return $this->aminterface->core_list_all_hints(); + } else { + return $this->oldinterface->sccp_list_all_hints(); + } + } + + public function sccp_realtime_status() { + if ($this->ami_mode) { + return $this->aminterface->getRealTimeStatus(); + } else { + return $this->oldinterface->sccp_realtime_status(); + } + } + + public function get_compatible_sccp($revNumComp=false) { + // only called with args from installer to get revision and compatibility + $res = $this->getSCCPVersion(); + if (empty($res)) { + return 0; + } + switch ($res["vCode"]) { + case 0: + $retval = 0; + break; + case 433: + $retval = 433; + break; + case 432: + $retval = 430; + break; + case 431: + $retval = 431; + break; + default: + $retval = 430; + } + if ($res['RevisionNum'] < 11063) { + $this->useAmiInterface = false; + } + if ($revNumComp) { + return array($retval, $this->useAmiInterface); + } + return $retval; + } + + public function getSCCPVersion() { + $res = $this->getChanSCCPVersion(); + if (empty($res)) { + $res = $this->oldinterface->getCoreSCCPVersion(); + } + return $res; + } + + public function sccp_list_keysets() { + if ($this->ami_mode) { + return $this->aminterface->sccp_list_keysets(); + } else { + return $this->oldinterface->sccp_list_keysets(); + } + + } + + public function sccp_get_active_device() { + if ($this->ami_mode) { + return $this->aminterface->sccp_get_active_device(); + } else { + return $this->oldinterface->sccp_get_active_device(); + } + } + + function getChanSCCPVersion() { + if ($this->ami_mode) { + return $this->aminterface->getSCCPVersion(); + } else { + return $this->oldinterface->getChanSCCPVersion(); + } + } + + // ---------------------------- Debug Data ------------------------------------------- + function t_get_ami_data() { + global $amp_conf; + $fp = fsockopen("127.0.0.1", "5038", $errno, $errstr, 10); + if (!$fp) { + echo "$errstr ($errno)
\n"; + } else { + $time_connect = microtime_float(); + fputs($fp, "Action: login\r\n"); + fputs($fp, "Username: " . $amp_conf[AMPMGRUSER] . "\r\n"); +// fputs ($fp,"Secret: secret\r\n"); + fputs($fp, "Secret: " . $amp_conf[AMPMGRPASS] . "\r\n"); + fputs($fp, "Events: on\r\n\r\n"); + +// fputs($fp, "Action: SCCPShowDevice\r\n"); +// fputs($fp,"Segment: general\r\n"); +// fputs($fp,"DeviceName: SEP00070E36555C\r\n"); +// fputs ($fp,"Action: DeviceStateList\r\n"); + fputs($fp, "Action: SCCPShowDevices\r\n"); + fputs($fp, "Segment: general\r\n"); + +// fputs ($fp,"Action: SCCPShowDevice\r\n"); +// fputs ($fp,"DeviceName: SEP00070E36555C\r\n"); +// +// fputs($fp, "Action: ExtensionStateList\r\n"); +// fputs($fp, "Action: ExtensionStateList\r\n"); +// fputs($fp, "Command: sccp show version\r\n"); +// fputs($fp, "Command: core show hints\r\n"); +// fputs ($fp,"Segment: general\r\n"); +// fputs ($fp,"Segment: general\r\n"); +// "Segments":["general","device","line","softkey"]} +// fputs ($fp,"Segment: device\r\n"); +// fputs ($fp,"ResultFormat: command\r\n"); + fputs($fp, "\r\n"); + $time_send = microtime_float(); + /* + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"\r\n"); + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: general\r\n"); + fputs ($fp,"\r\n"); + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: general\r\n"); + fputs ($fp,"ListResult: yes\r\n"); + fputs ($fp,"Option: fallback\r\n"); + fputs ($fp,"\r\n"); + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: device\r\n"); + fputs ($fp,"ListResult: freepbx\r\n"); + fputs ($fp,"\r\n"); + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: device\r\n"); + fputs ($fp,"Option: dtmfmode\r\n"); + fputs ($fp,"ListResult: yes\r\n"); + fputs ($fp,"\r\n"); + */ + fputs($fp, "Action: logoff\r\n\r\n"); + $time_logoff = microtime_float(); + +// print_r(fgets($fp)); + $resp = ''; + while (!feof($fp)) { + $resp .= fgets($fp); + } + $time_resp = microtime_float(); + $resp .= "\r\n\r\n Connect :" . ($time_send - $time_connect) . " Logoff :" . ($time_logoff - $time_send) . " Response :" . ($time_resp - $time_logoff) . "\r\n\r\n "; +// print_r(fgets($fp)); +// print_r('
'); +// echo fgets($fp, 128); + } + fclose($fp); + return $resp; + } + +} diff --git a/Sccp_manager.inc/xmlinterface.class.php b/Sccp_manager.inc/xmlinterface.class.php new file mode 100644 index 0000000..d6d6b16 --- /dev/null +++ b/Sccp_manager.inc/xmlinterface.class.php @@ -0,0 +1,940 @@ +paren_class = $parent_class; + } + + public function info() + { + $Ver = '13.0.4'; + return array('Version' => $Ver, + 'about' => 'Create XML data interface ver: ' . $Ver); + } + + function create_default_XML($store_path = '', $data_values = array(), $model_information = array(), $lang_info = array()) + { + $data_path = $data_values['tftp_path']; + if (empty($store_path) || empty($data_path) || empty($data_values)) { + return; + } + $def_xml_fields = array('authenticationURL', 'informationURL', 'messagesURL', 'servicesURL', 'directoryURL', + 'secureauthenticationURL', 'secureinformationURL', 'securemessagesURL', 'secureservicesURL', 'securedirectoryURL', 'secureidleURL', + 'proxyServerURL', 'idleTimeout', 'idleURL'); + $def_xml_locale = array('userLocale', 'networkLocaleInfo', 'networkLocale'); + $xml_name = $store_path . '/XMLDefault.cnf.xml'; + $xml_template = $data_values['tftp_path'] . '/templates/XMLDefault.cnf.xml_template'; + + if (file_exists($xml_template)) { + $xml_work = simplexml_load_file($xml_template); + $xnode = &$xml_work->callManagerGroup->members; + $bind_tmp = $this->get_server_sccp_bind($data_values); + //error_log("bind_tmp:".print_r($bind_tmp, true), 0); + $ifc = 0; + foreach ($bind_tmp as $bind_value) { + $xnode_obj = clone $xnode->member; + $xnode_obj['priority'] = $ifc; + $xnode_obj->callManager->name = $data_values['servername']; + $xnode_obj->callManager->ports->ethernetPhonePort = $bind_value['port']; + $xnode_obj->callManager->processNodeName = $bind_value['ip']; + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); + } + $ifc++; + } + + $this->replaceSimpleXmlNode($xml_work->callManagerGroup->members, $xnode); + + foreach ($def_xml_fields as $value) { + if (!empty($data_values['dev_' . $value])) { + $xml_work->$value = trim($data_values['dev_' . $value]); + } else { + $node = $xml_work->$value; + if (!empty($node)) { + unset($node[0][0]); + } + } + } + foreach ($def_xml_locale as $key) { + if (!empty($xml_work->$key)) { + $xnode = &$xml_work->$key; + switch ($key) { + case 'userLocale': + case 'networkLocaleInfo': + if ($key == 'networkLocaleInfo') { + $lang = $data_values['netlang']; + } else { + $lang = $data_values['devlang']; + } +// configs->getConfig('sccp_lang') + if (isset($lang_info[$lang])) { + $xnode->name = $lang_info[$lang]['locale']; + $xnode->langCode = $lang_info[$lang]['code']; + } else { + $xnode->name = ''; + $xnode->langCode = ''; + } +// $this -> replaceSimpleXmlNode($xml_work->$key,$xnode); + break; + case 'networkLocale': + $lang = $data_values['netlang']; + if (isset($lang_info[$lang])) { + $xnode = $lang_info[$lang]['language']; + } else { + $xnode = ''; + } + break; + } + //$this-> replaceSimpleXmlNode($xml_work->$value, $xnode ); + } + } + + foreach ($model_information as $var) { + if (!empty($var['loadinformationid'])) { + $node = $xml_work->addChild($var['loadinformationid'], $var['loadimage']); + $node->addAttribute('model', $var['vendor'] . ' ' . $var['model']); + } + } + $xml_work->asXml($xml_name); // Save XMLDefault1.cnf.xml + } + } + + function create_SEP_XML($store_path = '', $data_values = array(), $dev_config = array(), $dev_id = '', $lang_info = array()) + { + $var_xml_general_fields = array('authenticationurl' => 'dev_authenticationURL', 'informationurl' => 'dev_informationURL', 'messagesurl' => 'dev_messagesURL', + 'servicesurl' => 'dev_servicesURL', 'directoryurl' => 'dev_directoryURL', 'idleurl' => 'dev_idleURL', + 'secureauthenticationurl' => 'dev_secureauthenticationURL', + 'secureinformationurl' => 'dev_secureinformationURL', 'securemessagesurl'=>'dev_securemessagesURL', + 'secureservicesurl'=>'dev_secureservicesURL', 'securedirectoryurl'=>'dev_securedirectoryURL', 'secureidleurl' => 'dev_secureidleURL', + 'proxyserverurl' => 'dev_proxyServerURL', 'idletimeout' => 'dev_idleTimeout', + 'sshuserid' => 'dev_sshUserId', 'sshpassword' => 'dev_sshPassword', 'deviceprotocol' => 'dev_deviceProtocol', + 'phonepersonalization' => 'phonePersonalization' + ); + $var_xml_general_vars = array('capfAuthMode' => 'null', 'capfList' => 'null', 'mobility' => 'null', + 'phoneServices' => 'null', 'certHash' => 'null', + 'deviceSecurityMode' => '1'); + +// $var_hw_config = $this->dbinterface->HWextension_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); + + if (empty($dev_config)) { + return false; + } + $data_path = $dev_config['tftp_path']; + + if (empty($store_path) || empty($data_path) || empty($data_values) || empty($dev_id)) { + return; + } + + if (!empty($dev_config['nametemplate'])) { + $xml_template = $data_path . '/templates/' . $dev_config['nametemplate']; + } else { + $xml_template = $data_path . '/templates/SEP0000000000.cnf.xml_79df_template'; + } + $xml_name = $store_path . '/' . $dev_id . '.cnf.xml'; + if (file_exists($xml_template)) { + $xml_work = simplexml_load_file($xml_template); + + foreach ($var_xml_general_vars as $key => $data) { + if (isset($xml_work->$key)) { + if ($data != 'null') { + $xml_work->$key = $data; + } else { + $node = $xml_work->$key; + unset($node[0][0]); + } + } + } + + foreach ($xml_work as $key => $data) { +// Set System global Values + $key_l = strtolower($key); + if (!empty($var_xml_general_fields[$key_l])) { + $xml_work->$key = $data_values[$var_xml_general_fields[$key_l]]; + } +// Set section Values + $xml_node = $xml_work->$key; + switch ($key_l) { + case 'devicepool': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + switch (strtolower($dkey)) { + case 'datetimesetting': + $xnode = &$xml_node->$dkey; + $tz_id = $data_values['ntp_timezone']; + $TZdata = $data_values['ntp_timezone_id']; + if (empty($TZdata)) { + $TZdata = array('offset' => '0', 'daylight' => '', 'cisco_code' => 'Greenwich Standard Time'); + } + $xnode->name = $tz_id; + $xnode->dateTemplate = $data_values['dateformat']; + $xnode->timeZone = $TZdata['cisco_code']; +// $xnode->timeZone = $tz_id.' Standard'.((empty($TZdata['daylight']))? '': '/'.$TZdata['daylight']).' Time'; + + if ($data_values['ntp_config_enabled'] == 'on') { + $xnode->ntps->ntp->name = $data_values['ntp_server']; + $xnode->ntps->ntp->ntpMode = $data_values['ntp_server_mode']; + } else { + $xnode->ntps = null; + } + // Ntp Config + break; + case 'srstinfo': + if ($data_values['srst_Option'] == 'user') { + break; + } + $xnode = &$xml_node->$dkey; + $xnode->name = $data_values['srst_Name']; + $xnode->srstOption = $data_values['srst_Option']; + $xnode->userModifiable = $data_values['srst_userModifiable']; + $xnode->isSecure = $data_values['srst_isSecure']; + + $srst_fld = array('srst_ip' => array('ipAddr', 'port')); +// $srst_fld = array('srst_ip' => array('ipAddr','port') , 'srst_sip' => array('sipIpAddr','sipPort') ); + foreach ($srst_fld as $srst_pro => $srs_put) { + if (empty($data_values[$srst_pro]) || ($data_values['srst_Option'] == 'disable') ) { + $srst_data =array(); + } else { + $srst_data = explode(';', $data_values[$srst_pro]); + } + $si = 1; +// $xnode['test'] = $srst_data[0]; + foreach ($srst_data as $value) { + $srs_val = explode('/', $value); + $nod = $srs_put[0] . $si; + $xnode->$nod = $srs_val[0]; + $nod = $srs_put[1] . $si; + $xnode->$nod = ((empty($srs_val[1])) ? "2000": $srs_val[1]); +// $xnode->$nod = $srs_val[1]; + $si++; + } + while ($si < 4) { + $nod = $srs_put[0] . $si; + $xnode->$nod = ''; + $nod = $srs_put[1] . $si; + $xnode->$nod = ''; + $si++; + } + } + break; + case 'connectionmonitorduration': + $xml_node->$dkey = strval(intval(intval($data_values['keepalive']) * 0.75)); + break; + case 'callmanagergroup': + $xnode = &$xml_node->$dkey->members; + $bind_tmp = $this->get_server_sccp_bind($data_values); + $ifc = 0; + foreach ($bind_tmp as $bind_value) { + $xnode_obj = clone $xnode->member; + $xnode_obj['priority'] = $ifc; + $xnode_obj->callManager->name = $data_values['servername']; + if (!is_null($xnode_obj->callManager->description)) { + $xnode_obj->callManager->description = $data_values['servername']; + } + $xnode_obj->callManager->ports->ethernetPhonePort = $bind_value['port']; + $xnode_obj->callManager->processNodeName = $bind_value['ip']; + if (!empty($xnode_obj->callManager->ports->mgcpPorts)) { + unset($xnode_obj->callManager->ports->mgcpPorts); + } + + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); + } + $ifc++; + } + /* if ($data_values['bindaddr'] == '0.0.0.0') { + $ifc = 0; + foreach ($data_values['server_if_list'] as $value) { + + if (!empty($value['ip'])) { + $ip_valid = true; + if (!empty($data_values['ccm_address'])) { + if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false ) { + // Skip + } else { + if (strpos($data_values['ccm_address'], $value['ip']) === false) { + $ip_valid = false; + } + } + } + if (!in_array($value['ip'], array('0.0.0.0', '127.0.0.1'), true) && ($ip_valid)) { + + $xnode_obj = clone $xnode->member; + // $xnode_obj = $xnode -> member; + // $xnode_obj = $xnode -> addChild($xnode->member); + $xnode_obj['priority'] = $ifc; + //$xnode_obj = &$xnode -> member -> callManager; + $xnode_obj->callManager->name = $data_values['servername']; + $xnode_obj->callManager->ports->ethernetPhonePort = $data_values['port']; + $xnode_obj->callManager->processNodeName = $value['ip']; + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); + } + $ifc ++; + } + } + } + } else { + $xnode->member['priority'] = '0'; + $xnode_obj = &$xnode->member->callManager; + $xnode_obj->name = $data_values['servername']; + $xnode_obj->ports->ethernetPhonePort = $data_values['port']; + $xnode_obj->processNodeName = $data_values['bindaddr']; + } + break; + * + */ + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + case 'vendorconfig': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + $dkey_l = strtolower($dkey); + $vtmp_key = $key_l.'_'.$dkey_l; + if (isset($data_values[$vtmp_key])) { + $vtmp_data = $data_values[$vtmp_key]; + if ((!empty($vtmp_data)) || ($vtmp_data == "0")) { + $xml_node->$dkey = $vtmp_data; + } + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + + case 'versionstamp': + $xml_work->$key = time(); + break; + case 'loadinformation': +// Set Path Image ???? + if (isset($dev_config["tftp_firmware"])) { + $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["tftp_firmware"] . $dev_config["loadimage"] : ''; + } else { + $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["loadimage"] : ''; + } +// $xml_work->$key = $dev_config["loadimage"]; + if (!empty($dev_config['addon'])) { + $xnode = $xml_work->addChild('addOnModules'); + $ti = 1; + $hw_addon = explode(',', $dev_config['addon']); + foreach ($hw_addon as $add_key) { +// foreach ($dev_config['addon_info'] as $add_key => $add_val) { + if (!empty($dev_config['addon_info'][$add_key])) { + $add_val = $dev_config['addon_info'][$add_key]; + $xnode_obj = $xnode->addChild('addOnModule'); + $xnode_obj->addAttribute('idx', $ti); + $xnode_obj->addChild('loadInformation', $add_val); + $ti++; + } + } +// $this->appendSimpleXmlNode($xml_work , $xnode_obj); + } + break; + case 'commonprofile': + $xml_node->phonePassword = $data_values['dev_sshPassword']; + $xml_node->backgroundImageAccess = (($data_values['backgroundImageAccess'] == 'on') || ($data_values['backgroundImageAccess'] == 'true') ) ? 'true' : 'false'; + $xml_node->callLogBlfEnabled = $data_values['callLogBlfEnabled']; + break; + + case 'userlocale': + case 'networklocaleinfo': + case 'networklocale': + $hwlang = ''; + $lang = ''; + if (!empty($dev_config["_hwlang"])) { + $hwlang = explode(':', $dev_config["_hwlang"]); + } + if (($key_l == 'networklocaleinfo') || ($key_l == 'networklocale')) { + $lang = (empty($hwlang[0])) ? $data_values['netlang'] : $hwlang[0]; + } else { + $lang = (empty($hwlang[1])) ? $data_values['devlang'] : $hwlang[1]; + } + if (($lang != 'null') && (!empty($lang))) { + if ($key_l == 'networklocale') { + $xml_work->$key = $lang; + } else { + if (isset($lang_info[$lang])) { + $xml_node->name = $lang_info[$lang]['locale']; + $xml_node->langCode = $lang_info[$lang]['code']; + if ($key_l == 'userlocale') { + $xml_node->winCharSet = $lang_info[$lang]['codepage']; + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + } + } + } else { + $xml_work->$key = ''; + } + break; +// Move all set to $var_xml_general_vars +// case 'mobility': +// case 'capfList': +// break; +// case 'phoneServices': +// break; +// $xml_work->$key = ''; + default: + break; + } + } + +// print_r($xml_work); + $xml_work->asXml($xml_name); // Save + } else { + die('Error Hardware template :' . $xml_template . ' not found'); + } + return time(); + } + + private function get_server_sccp_bind($data_values = array()) + { + $res = array(); + if ($data_values['bindaddr'] !== '0.0.0.0') { + $rkey = $data_values['bindaddr']; + $res[$rkey] = array('ip' => $data_values['bindaddr'], 'port' => $data_values['port']); + return $res; + } + $ip_fill = true; + if (!empty($data_values['ccm_address'])) { + $ccm_address = $data_values['ccm_address']; + if (strpos($ccm_address, 'internal') === false && strpos($ccm_address, '0.0.0.0') === false) { + $tmp_data = explode(';', $ccm_address); + $ip_fill = false; + foreach ($tmp_data as $tmp_row) { + if (strpos($tmp_row, '/') !== false) { + $ttmp_r = explode('/', $tmp_row); // IPv6 - ???? + $rkey = $ttmp_r[0]; + $res[$rkey] = array('ip' => $rkey, 'port' => $ttmp_r[1]); + } else { + $rkey = $tmp_row; + $res[$rkey] = array('ip' => $rkey, 'port' => $data_values['port']); + } + } + } + } + if ($ip_fill) { + foreach ($data_values['server_if_list'] as $value) { + if (!empty($value['ip'])) { + if (!in_array($value['ip'], array('0.0.0.0', '127.0.0.1'), true)) { + $rkey = $value['ip']; + $res[$rkey] = array('ip' => $rkey, 'port' => $data_values['port']); + } + } + } + } + if (!empty($data_values['externhost'])) { + $rkey = $data_values['externhost']; + if (!in_array($rkey, array('0.0.0.0', '127.0.0.1', 'localhost'), true)) { + $res[$rkey] = array('ip' => $rkey, 'port' => $data_values['port']); + } + } else { + if (!empty($data_values['externip'])) { + $rkey = $data_values['externip']; + if (!in_array($rkey, array('0.0.0.0', '127.0.0.1'), true)) { + $res[$rkey] = array('ip' => $rkey, 'port' => $data_values['port']); + } + } + } + + return $res; + } + + /* + private function get_server_sip_bind($data_values = array()) { + $res = array(); + + if (!empty($data_values['sipbind']) and ( $data_values['sipbind'] != '0.0.0.0')) { + $res[0] = array('ip' => $data_values['sipbind'], 'port' => $data_values['sipbindport'], 'tlsport' => $data_values['tlsport'], 'proto' => $data_values['sipsuportproto']); + } + + $ifc = 0; + foreach ($data_values['server_if_list'] as $value) { + if (!empty($value['ip'])) { + $ip_valid = true; + if (!empty($data_values['ccm_address'])) { + if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false) { + // Skip + } else { + if (strpos($data_values['ccm_address'], $value['ip']) === false) { + $ip_valid = false; + } + } + } + if (!in_array($value['ip'], array('0.0.0.0', '127.0.0.1', $data_values['sipbind']), true) && ($ip_valid)) { + $res[] = array('ip' => $value['ip'], 'port' => $data_values['sipbindport'], 'tlsport' => $data_values['tlsport'], 'proto' => $data_values['sipsuportproto']); + } + } + } + return $res; + } + * + */ + + function create_SEP_SIP_XML($store_path = '', $data_values = array(), $dev_config = array(), $dev_id = '', $lang_info = array()) + { + + $var_xml_general_fields = array('authenticationURL' => 'dev_authenticationURL', 'informationURL' => 'dev_informationURL', 'messagesURL' => 'dev_messagesURL', + 'servicesURL' => 'dev_servicesURL', 'directoryURL' => 'dev_directoryURL', 'proxyServerURL' => 'dev_proxyServerURL', 'idleTimeout' => 'dev_idleTimeout', + 'idleURL' => 'dev_idleURL', 'sshUserId' => 'dev_sshUserId', 'sshPassword' => 'dev_sshPassword', + 'phonePersonalization' => 'phonePersonalization' + ); + $var_xml_sipProfile = array('phoneLabel' => 'description', + 'transferOnhookEnabled' => 'transferOnhookEnabled', 'enableVad' => 'enableVad', 'voipControlPort' => 'sipport' + ); + $var_xml_sipline = array('name' => 'account', 'featureLabel' => 'account', 'displayName' => 'callerid', 'contact' => 'account', + 'authName' => 'account', 'authPassword' => 'secret'); + $var_xml_general_vars = array('capfAuthMode' => 'null', 'capfList' => 'null', 'mobility' => 'null', + 'phoneServices' => 'null', 'certHash' => 'null', 'deviceProtocol' => 'SIP', + 'deviceSecurityMode' => '1'); + +// $var_hw_config = $this->dbinterface->HWextension_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); + + if (empty($dev_config)) { + return false; + } + $data_path = $dev_config['tftp_path']; + + if (empty($store_path) || empty($data_path) || empty($data_values) || empty($dev_id)) { + return; + } + + if (!empty($dev_config['nametemplate'])) { + $xml_template = $data_path . '/templates/' . $dev_config['nametemplate']; + if (!file_exists($xml_template)) { + $xml_template = $data_path . '/templates/SEP0000000000.cnf.xml_79df_sip_template'; + } + } else { + $xml_template = $data_path . '/templates/SEP0000000000.cnf.xml_79df_sip_template'; + } + $xml_name = $store_path . '/' . $dev_id . '.cnf.xml'; + //$sip_bind = $this->get_server_sip_bind($data_values); + $sip_bind = $data_values['sbind']; + $bind_proto = 'tcp'; + $bind_ip_def = ''; + foreach ($sip_bind as $key => $value) { + if (empty($bind_ip_def)) { + $bind_ip_def = $key; + $bind_proto = (isset($value['tcp'])) ? 'tcp' : 'udp'; + } + } + if (file_exists($xml_template)) { + $xml_work = simplexml_load_file($xml_template); + + foreach ($var_xml_general_vars as $key => $data) { + if (isset($xml_work->$key)) { + if ($data != 'null') { + $xml_work->$key = $data; + } else { + $node = $xml_work->$key; + unset($node[0][0]); + } + } + } + + foreach ($xml_work as $key => $data) { +// Set System global Values + if (!empty($var_xml_general_fields[$key])) { + $xml_work->$key = $data_values[$var_xml_general_fields[$key]]; + } +// Set section Values + $xml_node = $xml_work->$key; + switch ($key) { + case 'devicePool': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + switch ($dkey) { + case 'dateTimeSetting': + $xnode = &$xml_node->$dkey; + $tz_id = $data_values['ntp_timezone']; + $TZdata = $data_values['ntp_timezone_id']; + if (empty($TZdata)) { + $TZdata = array('offset' => '0', 'daylight' => '', 'cisco_code' => 'Greenwich Standard Time'); + } +// $xnode->name = $tz_id; + $xnode->dateTemplate = $data_values['dateformat']; + $xnode->timeZone = $TZdata['cisco_code']; +// $xnode->timeZone = $tz_id.' Standard'.((empty($TZdata['daylight']))? '': '/'.$TZdata['daylight']).' Time'; + + if ($data_values['ntp_config_enabled'] == 'on') { + $xnode->ntps->ntp->name = $data_values['ntp_server']; + $xnode->ntps->ntp->ntpMode = $data_values['ntp_server_mode']; + } else { + $xnode->ntps = null; + } + // Ntp Config + break; + /* case 'srstInfo': + if ($data_values['srst_Option'] == 'user') { + break; + } + $xnode = &$xml_node->$dkey; + $xnode->name = $data_values['srst_Name']; + $xnode->srstOption = $data_values['srst_Option']; + $xnode->userModifiable = $data_values['srst_userModifiable']; + $xnode->isSecure = $data_values['srst_isSecure']; + + $srst_fld = array('srst_ip' => array('ipAddr', 'port')); + // $srst_fld = array('srst_ip' => array('ipAddr','port') , 'srst_sip' => array('sipIpAddr','sipPort') ); + foreach ($srst_fld as $srst_pro => $srs_put) { + $srst_data = explode(';', $data_values[$srst_pro]); + $si = 1; + // $xnode['test'] = $srst_data[0]; + foreach ($srst_data as $value) { + $srs_val = explode('/', $value); + $nod = $srs_put[0] . $si; + $xnode->$nod = $srs_val[0]; + $nod = $srs_put[1] . $si; + $xnode->$nod = $srs_val[1]; + $si ++; + } + while ($si < 4) { + $nod = $srs_put[0] . $si; + $xnode->$nod = ''; + $nod = $srs_put[1] . $si; + $xnode->$nod = ''; + $si ++; + } + } + break; + case 'connectionMonitorDuration': + $xml_node->$dkey = strval(intval(intval($data_values['keepalive']) * 0.75)); + break; + */ + case 'callManagerGroup': + $xnode = &$xml_node->$dkey->members; + $ifc = 0; + foreach ($sip_bind as $bind_ip => $bind_value) { + $xnode_obj = clone $xnode->member; + $xnode_obj['priority'] = $ifc; + $xnode_obj->callManager->name = $data_values['servername']; + $xnode_obj->callManager->ports->sipPort = $bind_value[$bind_proto]; +// $xnode_obj->callManager->ports->securedSipPort = $bind_value['tlsport']; + $xnode_obj->callManager->processNodeName = $bind_ip; + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); + } + $ifc++; + } + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + case 'sipProfile': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + if (!empty($var_xml_sipProfile[$dkey])) { + if (!empty($data_values[$var_xml_sipProfile[$dkey]])) { + $xml_node->$dkey = $data_values[$var_xml_sipProfile[$dkey]]; + } else { + $xml_node->$dkey = null; + } + } + switch ($dkey) { + case 'sipProxies': + $xnode = &$xml_node->$dkey; + $xnode->backupProxy = $bind_ip_def; + $xnode->backupProxyPort = $sip_bind[$bind_ip_def][$bind_proto]; + $xnode->emergencyProxy = $bind_proto; + $xnode->emergencyProxyPort = $sip_bind[$bind_ip_def][$bind_proto]; + $xnode->outboundProxy = $bind_proto; + $xnode->outboundProxyPort = $sip_bind[$bind_ip_def][$bind_proto]; + $xnode->registerWithProxy = "true"; + + break; + case 'sipLines': + $xnode = &$xml_node->$dkey; + $ifc = 0; + if (!empty($data_values['siplines'])) { + foreach ($data_values['siplines'] as $spkey => $spvalue) { +// if $spvalue[] + $xnode_obj = clone $xnode->line; + $xnode_obj['button'] = $ifc + 1; + $xnode_obj['lineIndex'] = $ifc + 1; + //$xnode_obj->proxy = $data_values['bindaddr']; + $xnode_obj->featureID = "9"; + if ($xnode_obj->proxy != 'USECALLMANAGER') { + $xnode_obj->proxy = $bind_proto; + $xnode_obj->port = $sip_bind[$bind_ip_def][$bind_proto]; + } + + foreach ($var_xml_sipline as $line_key => $line_val) { + $xnode_obj->$line_key = $spvalue[$line_val]; + } + + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->line, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->line, $xnode_obj); + } + $ifc++; + } + } + if (!empty($data_values['speeddial'])) { + foreach ($data_values['speeddial'] as $spkey => $spvalue) { + $xmlstr = ' 22' + . '' . $spvalue["name"] . '' + . '' . $spvalue["dial"] . '' + . '' . $spvalue["dial"] . ' '; + $xnode_obj = simplexml_load_string($xmlstr); + $this->appendSimpleXmlNode($xnode->line, $xnode_obj); + $ifc++; + } + } +// $xnode = &$xml_node->$dkey->members; + //$xnode = null; + break; + case 'softKeyFile': + case 'dialTemplate': // Доработать ! + $xml_ext_file = ''; + $templet_path = (($dkey == 'softKeyFile') ? $dev_config['tftp_softkey'] : $dev_config['tftp_dialplan']); + $tmp_key = ($dkey == 'softKeyFile') ? 'softkeyset' : '_dialrules'; + if (!empty($dev_config[$tmp_key])) { + $xml_ext_file = (($dkey == 'softKeyFile') ? 'softkey' . $dev_config[$tmp_key] . '.xml' : $dev_config[$tmp_key] . '.xml'); + } +// $xml_node->$dkey = $templet_path . '/' . $xml_ext_file.'---'.$dev_config[$tmp_key]; +// break; + if (empty($xml_ext_file) || !file_exists($templet_path . '/' . $xml_ext_file)) { + $xml_ext_file = (($dkey == 'softKeyFile') ? 'softkeydefault.xml' : 'dialplan.xml'); + } + if (file_exists($templet_path . '/' . $xml_ext_file)) { + $xml_node->$dkey = $xml_ext_file; + } else { + $xml_node->$dkey = null; + } + break; + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + + case 'versionStamp': + $xml_work->$key = time(); + break; + case 'loadInformation': +// Set Path Image ???? + if (isset($dev_config["tftp_firmware"])) { + $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["tftp_firmware"] . $dev_config["loadimage"] : ''; + } else { + $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["loadimage"] : ''; + } +// $xml_work->$key = $dev_config["loadimage"]; + if (!empty($dev_config['addon'])) { + $xnode = $xml_work->addChild('addOnModules'); + $ti = 1; + foreach ($dev_config['addon_info'] as $add_key => $add_val) { + $xnode_obj = $xnode->addChild('addOnModule'); + $xnode_obj->addAttribute('idx', $ti); + $xnode_obj->addChild('loadInformation', $add_val); + $ti++; + } +// $this->appendSimpleXmlNode($xml_work , $xnode_obj); + } + break; + case 'commonProfile': + $xml_node->phonePassword = $data_values['dev_sshPassword']; + $xml_node->backgroundImageAccess = (($data_values['backgroundImageAccess'] == 'on') || ($data_values['backgroundImageAccess'] == 'true') ) ? 'true' : 'false'; + $xml_node->callLogBlfEnabled = $data_values['callLogBlfEnabled']; + break; + + case 'userLocale': + case 'networkLocaleInfo': + case 'networkLocale': + $hwlang = ''; + $lang = ''; + if (!empty($dev_config["_hwlang"])) { + $hwlang = explode(':', $dev_config["_hwlang"]); + } + if (($key == 'networkLocaleInfo') || ($key == 'networkLocale')) { + $lang = (empty($hwlang[0])) ? $data_values['netlang'] : $hwlang[0]; + } else { + $lang = (empty($hwlang[1])) ? $data_values['devlang'] : $hwlang[1]; + } + if (($lang != 'null') && (!empty($lang))) { + if ($key == 'networkLocale') { + $xml_work->$key = $lang; + } else { + if (isset($lang_info[$lang])) { + $xml_node->name = $lang_info[$lang]['locale']; + $xml_node->langCode = $lang_info[$lang]['code']; + if ($key == 'userLocale') { + $xml_node->winCharSet = $lang_info[$lang]['codepage']; + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + } + } + } else { + $xml_work->$key = ''; + } + break; +// Move all set to $var_xml_general_vars +// case 'mobility': +// case 'capfList': +// break; +// case 'phoneServices': +// break; +// $xml_work->$key = ''; + default: + break; + } + } + +// print_r($xml_work); + $xml_work->asXml($xml_name); // Save + } else { + die('Error Hardware template :' . $xml_template . ' not found'); + } + return time(); + } + + function saveDialPlan($confDir, $get_settings) + { + $xmlstr = "\n"; + $xmlstr .= "" . time() . "\n"; + $dialFelds = array('match', 'timeout', 'rewrite', 'tone'); //str -to lo ! + + $hdr_prefix = 'sccp_dial_'; + $hdr_arprefix = 'sccp_dial-ar_'; + $save_data = array(); + $integer_msg = _("%s must be a non-negative integer"); + $errors = array(); + foreach ($get_settings[$hdr_arprefix . 'dialtemplate'] as $key => $value) { + $xmlstr .= ' 'Access error' . $name); + } + } + return array(); + } else { + return array('error' => 'Invalid softkey Name' . $name); + } + } + $errors = array(); + $xmlstr = "\n"; + $xmlstr .= "" . time() . "\n"; +// $xmlstr .= "\n"; + $typeSoft = $confDir["tftp_templates"] . '/SIPTypeSoftKey.xml_template'; + $read_soft = ""; + if (file_exists($typeSoft)) { + $f_read = fopen($typeSoft, 'r'); + while (!feof($f_read)) { + $read_soft .= fread($f_read, 8192); + } + fclose($f_read); + } + $xmlstr .= $read_soft; +// $xmlstr .= $read_soft."\n\n"; + $xmlstr .= " \n"; + foreach ($config[$name] as $key => $value) { + $xmlstr .= ' ' . "\n"; + foreach (explode(",", $value) as $keyvalue) { + $xmlstr .= ' ' . "\n"; + } + $xmlstr .= " \n"; + } + $xmlstr .= " \n"; + + $xmlstr .= ''; + if (empty($errors)) { +// $put_file = str_replace(array("\n", "\r", "\t", "/", "\\", ".", ","), '', $put_file); + $file = $confDir["tftp_softkey"] . '/softkey' . $name . '.xml'; + file_put_contents($file, $xmlstr); + } + + return $errors; + } + + private function replaceSimpleXmlNode($xml, $element = SimpleXMLElement) + { + $dom = dom_import_simplexml($xml); + $import = $dom->ownerDocument->importNode( + dom_import_simplexml($element), + true + ); + $dom->parentNode->replaceChild($import, $dom); + } + + private function appendSimpleXmlNode($xml, $element = SimpleXMLElement) + { + + $dom = dom_import_simplexml($xml); + $import = $dom->ownerDocument->importNode( + dom_import_simplexml($element), + true + ); +// $dom->parentNode->appendChild($import, $dom); + $dom->parentNode->appendChild($import->cloneNode(true)); + } +} diff --git a/Technical.note/ATA.txt b/Technical.note/ATA.txt new file mode 100644 index 0000000..d561556 --- /dev/null +++ b/Technical.note/ATA.txt @@ -0,0 +1,64 @@ +https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cata/186_188/2_15_ms/english/administration/guide/sccp/sccp/sccpaape.html + + Cisco ATA-186, 188 + +--- linux +/sata186us.linux -any -d3 ATA030204SCCP090202A.zup + + Cisco ATA-186, 188 atadefault.cfg +---------- Config +cfgfmt.linux atadefault.txt atadefault.cfg + + +----------------------begin atadefault.txt --------------------- +#txt +UIPassword:0 +UseTftp:1 +TftpURL:0 +cfgInterval:3600 +EncryptKey:0 +ToConfig:0 +upgradecode:0,0x301,0x0400,0x0200,0.0.0.0,69,0,none +upgradelang:0,0x301,0x0400,0x0200,0.0.0.0,69,0,none +Dhcp:1 +StaticIp:0 +StaticRoute:0 +StaticNetMask:0 +CA0orCM0:172.30.122.41:2000 +CA1orCM1:0 +CA0UID:0 +CA1UID:0 +EPID0orSID0:. +EPID1orSID1:. +PrfCodec:1 +LBRCodec:3 +AudioMode:0x00350035 +NumTxFrames:2 +CallerIdMethod:0x00019e60 +ConnectMode:0x90000400 +DNS1IP:0.0.0.0 +DNS2IP:0.0.0.0 +UDPTOS:0xA0 +RingCadence:2,4,25 +DialTone:2,31538,30831,1380,1740,1,0,0,0 +BusyTone:2,30467,28959,1191,1513,0,4000,4000,0 +ReorderTone:2,30467,28959,1191,1513,0,2000,2000,0 +RingBackTone:2,30831,30467,1943,2111,0,16000,32000,0 +CallWaitTone:1,30831,0,5493,0,0,2400,2400,4800 +ConfirmTone:1,30467,0,5970,0,0,480,480,1920 +MediaPort:16384 +UseMGCP:0 +MGCPPort:2427 +RetxIntvl:500 +RetxLim:7 +MGCPVer:MGCP1.0 +NPrintf:0 +TraceFlags:0x00000000 +SigTimer:0x00000064 +CodecName:PCMU,PCMA,G723,G729 +OpFlags:0x2 +VLANSetting:0x0000002b +-----------------------end atadefault.txt ------------------ + + + diff --git a/Technical.note/Conferencing.txt b/Technical.note/Conferencing.txt new file mode 100644 index 0000000..d3cfee8 --- /dev/null +++ b/Technical.note/Conferencing.txt @@ -0,0 +1,49 @@ +Conference - NOT CONFERENCE BRIDGE !!!!! ( Sccp Conference) + +Conference Introduction + +The integrated conference solution build in chan-sccp-b is based on asterisk's ConfBridge functionality. In stead of having to memorize the confbridge voice menu and having to press DTMF keys to control your conference we have opted to include a visual Cisco-XML menu, which give you (the Moderator) the ability to Kick, Mute and Promote another user to become an additional Moderator. + +Note: You need to './configure --enable-conference ...' when you built the chan_sccp.so module. Note: A conference always requires at least one moderator. +Conference Settings + +The standard conference settings are setup per device and contain: +param default description +conf_allow yes Allow the use of conference +conf_play_general_announce yes Playback General Announcements (like: 'You are Entering/Leaving the conference') +conf_play_part_announce yes Playback Personal/Participant Announcements, (like: 'You have been muted / You have been kicked') +conf_mute_on_entry no Mute new participants from the start, when they enter the conference (Preventing them to talk amongst one another). The Moderator will have to UnMute a participant manually to allow them to speak. Useful in a classroom setting. +conf_music_on_hold_class 'default' Play music on hold of this class when no moderator is listening on the conference. If set to an empty string, no music on hold will be played. +conf_show_conflist yes Automatically show conference list to the moderator +Creating a New Conference (Conf Softkey) + +Using the Conference Button makes it possible to set up a Simple Conference between 3 or more participant. (The actual minimum to start a conference is 2, but that doesn't make a lot of sense now does it.) + +You already have 2 or more lines connected (One is active and the other(s) is/are on Hold), which you would like to put in a Conference; Simply Press the Conf Softkey Button. + +If you do not already have these lines connected, that call some people first and then start the conference. It does not make sense to be conferencing on your own. +Conference List (ConfList Softkey) + +When conf_show_conflist=yes or you press the ConfList Softkey, you will be presented with a Cisco-XML Menu, showing you all currently connected Participant. Something like this: + +7970_Conference.png + +You can use the Softkeys underneath the menu, for example: +Softkey Description +EndConf Hangup all participants and end the current conference +Kick Through a specific participant out of the conference (Call is hungup) +Mute Do not allow a specific participant to speak (The hear a voiceprompt stating that they have been muted (if conf_play_part_announce = yes), and the mute status is displayed on their display (if they have an sccp device)) +Unmute Allow a specific participant to speak (The hear a voiceprompt stating that they have been unmuted (if conf_play_part_announce = yes), and the mute status is displayed on their display (if they have an sccp device)). +Promote Make a specific participant a moderator as well (giving them control over the conference as well). You can leave the conference by hanging up, without the conference being terminated. +Exit Leave the ConfList Menu, but remain connected to the conference. This makes it possible to put the conference onhold and invite someone new for examples. You need to press the ConfList Softkey to get back into the ConfList Menu. +Adding another Participant after the conference has already started (Join Softkey) + +If you do need to add a person after having started the conference, then you need to exit the conflist menu, put the conference on hold and dial the new "future" participant, once that person has picked up, you press the join button on that new call and this new participant will be added to the conference and you will automatically resume the conference you where in before. + +Once the conference is started you will be presented with the conflist menu which will allow you to control the conference directly from your phone (kick / mute participant and even promote one of the participant to become a secondary moderator, so that they can take over control of the conference and you are free to leave). +Q & A: +The Conference Softkey just created a two person conference + +Question: Creating a conference call on my 7961 does not seem to work. Once I hit the Conference softbutton, it will create a conference but put me and the other person directly into the conference without giving me any way to call a third party. + +Solution: Just put the first person on hold, dial the second person (and a third, fourth etc) and then press the conference button. All of the calls connected to your phone will automatically be put into the conference. \ No newline at end of file diff --git a/Technical.note/RedialMenu.txt b/Technical.note/RedialMenu.txt new file mode 100644 index 0000000..66c8b50 --- /dev/null +++ b/Technical.note/RedialMenu.txt @@ -0,0 +1,24 @@ + + +You can specifying 'useRedialMenu = yes' in the sccp.conf device section and the redial softkey will cause the "placed calls" list instead of immediately calling the last dialed number. +CallListStateUpdate (java phones) + +If you add/enable the 'callLogBlfEnabled' xml entry in SEPXXX.cnf.xml under commonProfile, like so: + + + 3 + + +and you have added hints for your local extension in your dialplan, like: + +exten => _XX.,hint,SCCP/${EXTEN} + +Then the placed calls list will include the status of the remote extension, like this: + +PlacedCalls + +Which does show numbers you can redial, but also include their current device state, so you know when they are currently busy. Note that the other phonebook entries will now also monitor the remove device state and show the current device state. + +Note: the hints for the extension need to be in the same context as the device/global context, for callLogBlfEnabled to work + +# This does not apply to phones 7940. Be careful with these keys the phone may not boot !!! diff --git a/Technical.note/SEP0000000000.cnf.xml_annotated b/Technical.note/SEP0000000000.cnf.xml_annotated new file mode 100644 index 0000000..fa5a73f --- /dev/null +++ b/Technical.note/SEP0000000000.cnf.xml_annotated @@ -0,0 +1,554 @@ + + + true + SCCP + cisco + cisco + + + 0 + Default + + Netherlands + D/M/YA + W. Europe Standard/Daylight Time + + + pool.ntp.org + Unicast + + + + + Default + true + + + + Asterisk + Primary Asterisk Server + + 2000 + + + x.x.x.x + + + + + Asterisk 1 + Secundary Asterisk Server + + 2000 + + + x.x.x.x + + + + + + + Enable + Enable + true + x.x.x.x + 2000 + + 2000 + + 2000 + 192.168.5.101 + 5060 + + 5060 + + 5060 + false + + -1 + Default + Default + 120 + + + + true + 2 + + + 1 + + + false + + + false + + + 0 + + + 1 + + + 0 + + + 0 + + + 1 + + + 0 + + + 0 + + + 1,7 + 08:00 + 12:00 + 00:10 + 1 + + 1 + + 1 + + + + + + + + + + + + + + 1 + + + 2 + + + 1 + 1 + 1 + 1 + 1 + + 1 + + + 0 + 22 + + + + + + + + 0 + + 0 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + 0 + + + {Jan 01 2003 00:00:00} + P00308010100 + + + Dutch_Netherlands + nl + iso-8859-1 + + + Netherlands + + Dutch_Netherlands + nl + 64 + 4.0(1) + + + + http://x.x.x.x/cisco_menu/authentication.php + + http://x.x.x.x/cisco_menu/help/help.php + + + http://x.x.x.x/cisco_menu/menu.php + http://x.x.x.x/cisco_menu/directory/menu.php + + http://x.x.x.x/cisco_menu/idle.php + + 3600 + + 1 + 1 + 1 + 1 + false + 1 + 1 + 1 + + + + + + *81 + *82 + *83 + *84 + *85 + + + 104 + 0 + 184 + 4 + 0 + + + 3804 + + + + false + + 0 + + + + + Corporate Directory + Application:Cisco/CorporateDirectory + + + + + Missed Calls + Application:Cisco/MissedCalls + + + + + Received Calls + Application:Cisco/ReceivedCalls + + + + + Placed Calls + Application:Cisco/PlacedCalls + + + + + Personal Directory + Application:Cisco/PersonalDirectory + + + + + Voicemail + Application:Cisco/Voicemail + + + + + diff --git a/Technical.note/SEPXML.txt b/Technical.note/SEPXML.txt new file mode 100644 index 0000000..79cd723 --- /dev/null +++ b/Technical.note/SEPXML.txt @@ -0,0 +1,8 @@ +http://usecallmanager.nz/sepmac-cnf-xml.html +http://usecallmanager.nz/line-keys-xml.html +http://usecallmanager.nz/user-locale.html +https://www.voip-info.org/wiki/view/Asterisk+phone+cisco+79x1+xml+configuration+files+for+SIP +https://www.voip-info.org/wiki/view/Asterisk+phone+cisco+7970+SIP +https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cuipph/all_models/xsi/8_5_1/xsi_dev_guide/xmlobjects.html +https://habrahabr.ru/post/176019/ +https://learningnetwork.cisco.com/thread/14585 \ No newline at end of file diff --git a/Technical.note/backgroundImage.txt b/Technical.note/backgroundImage.txt new file mode 100644 index 0000000..bfa2b31 --- /dev/null +++ b/Technical.note/backgroundImage.txt @@ -0,0 +1,57 @@ +https://github.com/chan-sccp/chan-sccp/wiki/Adding-custom-background-images +http://www.voicecerts.com/2011/08/changing-cisco-ip-phone-background.html +https://silver-golem.livejournal.com/432591.html + +> Real Time ! +http://silver-golem.livejournal.com/431942.html + +General Information + +Cisco IP Phones support either colored or monochrom background images in various resolutions (depending on model). The background can either be set up in sccp.conf server side or the user can be enabled to select a background image from a defined list of backgrounds. The image has to be a graphic file with .PNG extension. Other requirements apply, depending on phone model (see below). +Set background image server side + +Background images can be set up server side in sccp.conf for most modern Cisco IP Phones by using a parameter in the device section. This image is pushed to the phone upon every restart. + +[SEPXXXXXXXXX] +... +backgroundImage=http://PATH-TO-BACKGROUND-IMAGE/filename.png + +!!!> Phone personalization needs to be set to allow the server to push background or ringtones to the phone in the SEPXXXXXXXXXX.cnf.xml of each phone: + +------------------------------------ +1 +------------------------------------ +Enable user to pick a custom background image + +When a user is allowed to pick his own background image in the user settings (true in device section of the SEPXXXX.xml config file), the phone searches for the List.xml (case-sensitive) file in the following directories. Depending on the phone model, the required file properties are as follows: +Phone Model Image Size Thumbnail Size Directory +7906 / 7911 95x34 23x8 /Desktops/95x34x1 +7941 / 7961 320x196 80x49 /Desktops/320x196x4 +7942 / 7962 320x196 80x49 /Desktops/320x196x4 +7945 / 7965 320x212 80x53 /Desktops/320x212x16 +7970 / 7971 320x212 80x53 /Desktops/320x212x12 +7975 320x216 80x53 /Desktops/320x216x16 +7985 800x600 not supported /Desktops/800x600x16 +8941 / 8945 640x480 123x111 /Desktops/640x480x24 + +The Image file is used for the background of the phone display. An additional thumbnail is used as a preview image on the phone settings menu (on 7985 only the filename). The List.xml has to be in the above model-depending directory. The file has a Cisco IPPhoneImage syntax, example: + + + + + + +While the resolution is fix, the phones are able to reduce the color depth if the original image uses too many colors. + +Note: This can also be done using the SEP....cnf.xml file + +... + + TFTP/HTTP/HTTPS URL + true/false + +1 +... + diff --git a/Technical.note/dialplan.txt b/Technical.note/dialplan.txt new file mode 100644 index 0000000..11574bf --- /dev/null +++ b/Technical.note/dialplan.txt @@ -0,0 +1,11 @@ +Убрать коменты +в sccpgeneral.xml + - + + + + +в Sccp_manager.class.php +// "sccpdialplan" => array( +// "name" => _("SCCP Dial Plan information"), +// "page" => 'views/server.dialtemplate.php' +// ) diff --git a/Technical.note/freepbx.txt b/Technical.note/freepbx.txt new file mode 100644 index 0000000..f5a405c --- /dev/null +++ b/Technical.note/freepbx.txt @@ -0,0 +1 @@ +https://github.com/chan-sccp/chan-sccp/wiki/Monitor-and-Pickup-Incoming-Calls-via-Speeddial-Using-Custom-Devstate diff --git a/Technical.note/help.tftprewrite b/Technical.note/help.tftprewrite new file mode 100644 index 0000000..bcc089a --- /dev/null +++ b/Technical.note/help.tftprewrite @@ -0,0 +1,58 @@ +diff --git a/src/sccp_config.c b/src/sccp_config.c +index e15d19db..c78bcbf2 100644 +--- a/src/sccp_config.c ++++ b/src/sccp_config.c +@@ -3062,6 +3062,7 @@ int sccp_manager_config_metadata(struct mansession *s, const struct message *m) + uint i; + const char *id = astman_get_header(m, "ActionID"); + const char *req_segment = astman_get_header(m, "Segment"); ++ const char *req_listresult = astman_get_header(m, "ListResult"); + uint comma = 0; + + if (sccp_strlen_zero(req_segment)) { // return all segments +@@ -3180,11 +3181,22 @@ int sccp_manager_config_metadata(struct mansession *s, const struct message *m) + sccpConfigSegment = &sccpConfigSegments[i]; + const SCCPConfigOption *config = sccpConfigSegment->config; + +- astman_append(s, "Response: Success\r\n"); +- if (!ast_strlen_zero(id)) { +- astman_append(s, "ActionID: %s\r\n", id); ++ if (sccp_strcaseequals(req_listresult, "yes")) { ++ //astman_append(s, "Response: Follows\r\n\r\n"); ++ //astman_append(s, "EventList: Start\r\n"); ++ astman_send_listack(s, m, "SCCPConfigMetaData Follows", "Start"); ++ astman_append(s, "Event: SCCPConfigMetaData\r\n"); ++ if (!ast_strlen_zero(id)) { ++ astman_append(s, "ActionID: %s\r\n", id); ++ } ++ } else if (sccp_strcaseequals(req_listresult, "freepbx")) { ++ astman_append(s, "Response: Follows\r\n"); ++ } else { ++ astman_append(s, "Response: Success\r\n"); ++ if (!ast_strlen_zero(id)) { ++ astman_append(s, "ActionID: %s\r\n", id); ++ } + } +- + astman_append(s, "JSON: {"); + astman_append(s, "\"Segment\":\"%s\",", sccpConfigSegment->name); + astman_append(s, "\"Options\":["); +@@ -3296,8 +3308,17 @@ int sccp_manager_config_metadata(struct mansession *s, const struct message *m) + comma = 1; + } + } +- astman_append(s, "]}\r\n\r\n"); ++ astman_append(s, "]}\r\n"); + total++; ++ if (sccp_strcaseequals(req_listresult, "yes")) { ++ astman_append(s, ++ "\r\nEvent: SCCPConfigMetaDataComplete\r\n" ++ "EventList: Complete\r\n" ++ "ListItems: %d\r\n\r\n", total); ++ } else if (sccp_strcaseequals(req_listresult, "freepbx")) { ++ astman_append(s, "--END COMMAND--\r\n"); ++ } ++ astman_append(s, "\r\n"); + } + } + } diff --git a/Technical.note/make_sccp.txt b/Technical.note/make_sccp.txt new file mode 100644 index 0000000..8747f29 --- /dev/null +++ b/Technical.note/make_sccp.txt @@ -0,0 +1,15 @@ +git clone https://github.com/chan-sccp/chan-sccp chan-sccp_develop + +./configure --enable-indications --enable-conference --enable-advanced-functions --enable-distributed-devicestate +make +make install + +load = chan_sccp.so +noload = chan_skinny.so + +preload = func_db.so +preload = res_odbc.so +preload = res_config_odbc.so +preload = cdr_adaptive_odbc.so +preload = app_voicemail.so + diff --git a/Technical.note/sccp.conf.annotated b/Technical.note/sccp.conf.annotated new file mode 100644 index 0000000..5c1cdcb --- /dev/null +++ b/Technical.note/sccp.conf.annotated @@ -0,0 +1,280 @@ +;! +;! Automatically generated configuration file +;! Filename: sccp.conf.annotated (/usr/local/asterisk-13-branch/etc/asterisk/sccp.conf.annotated) +;! Generator: sccp config generate +;! Creation Date: Sun Nov 1 01:27:41 2015 +;! + + +; +; general section +; +[general] +;servername = Asterisk ; (REQUIRED) show this name on the device registration +;keepalive = 60 ; (REQUIRED) Phone keep alive message every 60 secs. Used to check the voicemail and keep an open connection between server and phone (nat). + ; Don't set any lower than 60 seconds. +;debug = core ; (MULTI-ENTRY) console debug level or categories + ; examples: debug = 11 | debug = mwi,event,core | debug = all | debug = none or 0 + ; possible categories: + ; core, sccp, hint, rtp, device, line, action, channel, cli, config, feature, feature_button, softkey, indicate, pbx + ; socket, mwi, event, adv_feature, conference, buttontemplate, speeddial, codec, realtime, lock, newcode, high, all, none +;context = default ; (REQUIRED) pbx dialplan context +;dateformat = M/D/Y ; (SIZE: 7) M-D-Y in any order. Use M/D/YA (for 12h format) +;bindaddr = 0.0.0.0 ; (REQUIRED) replace with the ip address of the asterisk server (RTP important param) +;port = 2000 ; listen on port 2000 (Skinny, default) +deny = 0.0.0.0/0.0.0.0 +permit = internal ; (REQUIRED) (MULTI-ENTRY) Deny every address except for the only one allowed. example: '0.0.0.0/0.0.0.0' + ; Accept class C 192.168.1.0 example '192.168.1.0/255.255.255.0' + ; You may have multiple rules for masking traffic. + ; Rules are processed from the first to the last. + ; This General rule is valid for all incoming connections. It's the 1st filter. + ; using 'internal' will allow the 10.0.0.0, 172.16.0.0 and 192.168.0.0 networks +;localnet = internal ; (MULTI-ENTRY) All RFC 1918 addresses are local networks, example '192.168.1.0/255.255.255.0' +;externip = 0.0.0.0 ; External IP Address of the firewall, required in case the PBX is running on a separate host behind it. IP Address that we're going to notify in RTP media stream as the pbx source address. +;firstdigittimeout = 16 ; Dialing timeout for the 1st digit +;digittimeout = 8 ; More digits +;digittimeoutchar = # ; You can force the channel to dial with this char in the dialing state +;recorddigittimeoutchar = no ; You can force the channel to dial with this char in the dialing state +;simulate_enbloc = yes ; Use simulated enbloc dialing to speedup connection when dialing while onhook (older phones) +;ringtype = outside ; Ringtype for incoming calls (default='outside') +;autoanswer_ring_time = 1 ; Ringing time in seconds for the autoanswer. +;autoanswer_tone = 0x32 ; Autoanswer confirmation tone. For a complete list of tones: grep SKINNY_TONE sccp_protocol.h + ; not all the tones can be played in a connected state, so you have to try. +;remotehangup_tone = 0x32 ; Passive hangup notification. 0 for none +;transfer_tone = 0 ; Confirmation tone on transfer. Works only between SCCP devices +;transfer_on_hangup = no ; Complete transfer on hangup, without pressing transfer a second time. + ; Will complete transfer, when the transferer puts the receiver on hook, after the destination has been reached. + ; To cancel the transfer, either press resume on the transferred channel, press the 'endcall' softkey, or have the receiving party hangup first. +;dnd_tone = 0x0 ; Use 0x2D, 0x31, 0x32, 0x33 to activate dnd incoming call indication when dnd silent is active +;callwaiting_tone = 0x2d ; Sets to 0 to disable the callwaiting tone +;callwaiting_interval = 0 ; Callwaiting ring interval in seconds. Set to 0 to disable the callwaiting ringing interval. +;musicclass = default ; Sets the default music on hold class +;language = en ; Default language setting +;callevents = yes ; Generate manager events when phone + ; Performs events (e.g. hold) +;accountcode = skinny ; Accountcode to ease billing +;sccp_tos = 0x68 ; Sets the default sccp signaling packets Type of Service (TOS) (defaults to 0x68 = 01101000 = 104 = DSCP:011010 = AF31) + ; Others possible values : [CS?, AF??, EF], [0x??], [lowdelay, throughput, reliability, mincost(solaris)], none +;sccp_cos = 4 ; sets the default sccp signaling packets Class of Service (COS). +;audio_tos = 0xB8 ; sets the default audio/rtp packets Type of Service (TOS) (defaults to 0xb8 = 10111000 = 184 = DSCP:101110 = EF) +;audio_cos = 6 ; sets the default audio/rtp packets Class of Service (COS). +;video_tos = 0x88 ; sets the default video/rtp packets Type of Service (TOS) (defaults to 0x88 = 10001000 = 136 = DSCP:100010 = AF41) +;video_cos = 5 ; sets the default video/rtp packets Class of Service (COS). +;echocancel = yes ; sets the phone echocancel for all devices +;silencesuppression = no ; sets the silence suppression for all devices + ; we don't have to trust the phone ip address, but the ip address of the connection +;earlyrtp = progress ; valid options: none, offhook, immediate, dial, ringout and progress. + ; The audio stream will be open in the progress and connected state by default. Immediate forces overlap dialing. + ; (POSSIBLE VALUES: ["Immediate","OffHook","Dialing","Ringout","Progress","None"]) +;dndFeature = on ; Turn on the dnd softkey for all devices. Valid values are 'off', 'on'. +;private = yes ; permit the private function softkey +;mwilamp = on ; Set the MWI lamp style when MWI active to on, off, wink, flash or blink + ; (POSSIBLE VALUES: ["Off","On","Wink","Flash","Blink"]) +;mwioncall = no ; Set the MWI on call. +;blindtransferindication = ring ; moh or ring. the blind transfer should ring the caller or just play music on hold + ; (POSSIBLE VALUES: ["RING","MOH"]) +;cfwdall = yes ; activate the callforward ALL stuff and softkeys +;cfwdbusy = yes ; activate the callforward BUSY stuff and softkeys +;cfwdnoanswer = yes ; activate the callforward NOANSWER stuff and softkeys +;nat = auto ; Global NAT support. + ; (POSSIBLE VALUES: ["Auto","Off","(Auto)Off","On","(Auto)On"]) +;directrtp = no ; This option allow devices to do direct RTP sessions. +;allowoverlap = no ; Enable overlap dialing support. If enabled, starts dialing immediately and sends remaining digits as DTMF/inband. + ; Use with extreme caution as it is very dialplan and provider dependent. +callgroup = "" ; We are in caller groups 1,3,4. Valid for all lines +pickupgroup = "" ; We can do call pick-p for call group 1,3,4,5. Valid for all lines +;directed_pickup_modeanswer = yes ; Automatically Answer when using Directed Pickup. +;amaflags = default ; Sets the default AMA flag code stored in the CDR record +;callanswerorder = oldestfirst ; oldestfirst or lastestfirst + ; (POSSIBLE VALUES: ["OldestFirst","LastFirst"]) +regcontext = "" ; SCCP Lines will we added to this context in asterisk for Dundi lookup purposes. + ; Do not set to an already created/used context. The context will be autocreated. You can share the sip/iax regcontext if you like. +;devicetable = sccpdevice ; datebasetable for devices +;linetable = sccpline ; datebasetable for lines +;meetme = yes ; enable/disable conferencing via meetme (on/off), make sure you have one of the meetme apps mentioned below activated in module.conf + ; when switching meetme=on it will search for the first of these three possible meetme applications and set these defaults + ; - {'MeetMe', 'qd'}, + ; - {'ConfBridge', 'Mac'}, + ; - {'Konference', 'MTV'} +;meetmeopts = qxd ; options to send the meetme application, defaults are dependent on meetme app see the list above + ; Other options (app_meetme: A,a,b,c,C,d,D,E,e,F,i,I,l,L,m,M,o,p,P,q,r,s,S,t,T,w,x,X,1) see meetme specific documentation +;jbenable = no ; Enables the use of a jitterbuffer on the receiving side of a sccp channel. + ; An enabled jitterbuffer will be used only if the sending side can create and the receiving side can not accept jitter. + ; The sccp channel can accept jitter, thus a jitterbuffer on the receive sccp side will beused only if it is forced and enabled. +;jbforce = no ; Forces the use of a jitterbuffer on the receive side of a sccp channel. +;jblog = no ; Enables jitterbuffer frame logging. +;jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds. +;jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is + ; resynchronized. Useful to improve the quality of the voice, with + ; big jumps in/broken timestamps, usually sent from exotic devices + ; and programs. +;jbimpl = fixed ; (SIZE: 11) Jitterbuffer implementation, used on the receiving side of a + ; sccp channel. Two implementations are currently available + ; - 'fixed' (with size always equals to jbmaxsize) + ; - 'adaptive' (with variable size, actually the new jb of IAX2). +;hotline_enabled = yes ; Setting the hotline Feature on a device, will make it connect to a predefined extension as soon as the Receiver + ; is picked up or the 'New Call' Button is pressed. No number has to be given. This works even on devices which + ; have no entry in the config file or realtime database. + ; The hotline function can be used in different circumstances, for example at a door, where you want people to be + ; able to only call one number, or for unprovisioned phones to only be able to call the helpdesk to get their phone + ; set up. If hotline_enabled = yes, any device which is not included in the configuration explicitly will be allowed + ; to registered as a guest device. All such devices will register on a single shared line called 'hotline'. +;hotline_context = sccp ; +;hotline_extension = 111 ; +;hotline_label = hotline ; +;fallback = no ; Immediately fallback to primairy/master server when it becomes available (master/slave asterisk cluster) (TokenRequest) + ; Possible values are: true/false/odd/even/script. + ; active/passive cluster: true on active/false on passive + ; active/active cluster: even on active1/off on active2 + ; more complex cluster: use script. It will be called with three arguments, namely mac-address, ip-address, devicetype. + ; and it should return 'ACK' (without the quotes) to acknowledge the token, or a value for the number of seconds to backoff and try again. + ; Value can be changed online via CLI/AMI command 'sccp set fallback true/false/odd/even/script' +;backoff_time = 60 ; Time to wait before re-asking to fallback to primairy server (Token Reject Backoff Time) +;server_priority = 1 ; Server Priority for fallback: 1=Primairy, 2=Secundary, 3=Tertiary etc + ; For active-active (fallback=odd/even) use 1 for both + +; +; device section +; +[default_device](!) +device = "" ; (SIZE: 15) device type +devicetype = "" ; (SIZE: 15) device type +description = "" ; device description +keepalive = "" ; set keepalive to 60 +;tzoffset = 0 ; time zone offset +;disallow = all +;allow = ulaw ; (MULTI-ENTRY) Same as entry in [general] section +;allow = alaw +;transfer = yes ; enable or disable the transfer capability. It does remove the transfer softkey +;park = yes ; take a look to the compile how-to. Park stuff is not compiled by default. +;cfwdall = no ; activate the call forward stuff and soft keys +;cfwdbusy = no ; allow call forward when line is busy +;cfwdnoanswer = no ; allow call forward when line if not being answered +;dndFeature = yes ; allow usage do not disturb button +dnd = "" ; allow setting dnd action for this device. Valid values are 'off', 'reject' (busy signal), 'silent' (ringer = silent) or 'user' (not used at the moment). . The value 'on' has been made obsolete in favor of 'reject' + ; (POSSIBLE VALUES: ["Off","Reject","Silent","UserDefined"]) +;force_dtmfmode = auto ; auto, skinny or rfc2833. Some phone models with bad firmware do send dtmf in a messed up order and need to be forced to skinny mode. + ; (POSSIBLE VALUES: ["AUTO","RFC2833","SKINNY"]) +deny = "" +permit = "" ; (MULTI-ENTRY) Same as entry in [general] section + ; This device can register only using this ip address +audio_tos = "" ; sets the audio/rtp packets Type of Service (TOS) (defaults to 0xb8 = 10111000 = 184 = DSCP:101110 = EF). + ; Others possible values : 0x??, lowdelay, throughput, reliability, mincost(solaris), none. +audio_cos = "" ; sets the audio/rtp packets Class of Service (COS) +video_tos = "" ; sets the video/rtp packets Type of Service (TOS) (defaults to 0x88 = 10001000 = 136 = DSCP:100010 = AF41). +video_cos = "" ; sets the video/rtp packets Class of Service (COS). +nat = "" ; Device NAT support. Currently nat is automatically detected in most cases. + ; (POSSIBLE VALUES: ["Auto","Off","(Auto)Off","On","(Auto)On"]) +directrtp = "" ; This option allow devices to do direct RTP sessions. +earlyrtp = "" ; valid options: none, offhook, immediate, dial, ringout and progress. + ; The audio stream will be open in the progress and connected state by default. Immediate forces overlap dialing. + ; (POSSIBLE VALUES: ["Immediate","OffHook","Dialing","Ringout","Progress","None"]) +private = "" ; permit the private function softkey for this device +privacy = "" ; permit the private function softkey for this device +mwilamp = "" ; Set the MWI lamp style when MWI active to on, off, wink, flash or blink + ; (POSSIBLE VALUES: ["Off","On","Wink","Flash","Blink"]) +mwioncall = "" ; Set the MWI on call. +meetme = "" ; enable/disable conferencing via app_meetme (on/off) +meetmeopts = "" ; options to send the app_meetme application (default 'qd' = quiet,dynamic pin) + ; Other options (A,a,b,c,C,d,D,E,e,F,i,I,l,L,m,M,o,p,P,q,r,s,S,t,T,w,x,X,1) see app_meetme documentation +;softkeyset = default ; use specified softkeyset with name 'default' +;useRedialMenu = no ; show redial phone book list instead of dialing the last number (adv_feature). Requires a Phone Service block in SEP....cnf.xml to work correct on Java phones (See conf/tftp/SEP example files) +;directed_pickup = yes ; enable/disable Pickup button to do directed pickup from a specific extension. +directed_pickup_context = "" ; context where direct pickup search for extensions. if not set current contect will be use. +;directed_pickup_modeanswer = yes ; on = asterisk way, the call has been answered when picked up. +monitor = "" ; +allowoverlap = "" ; Allow for Overlap dialing (Continue dialing after the first part of the number has already been send to the pstn) +setvar = "" ; (MULTI-ENTRY) extra variables to be set on line initialization multiple entries possible (for example the sip number to use when dialing outside) + ; format setvar=param=value, for example setvar=sipno=12345678 +permithost = "" ; (MULTI-ENTRY) permit/deny but by resolved hostname +addon = "" ; One of 7914, 7915, 7916 +button = "" ; (MULTI-ENTRY) Buttons come in the following flavours (empty, line, speeddial, service, feature). + ; Examples (read the documentation for more examples/combinations): + ; - button = line,1234 + ; - button = line,1234,default + ; - button = empty + ; - button = line,98099@11:Phone1 + ; - button = line,98099@12:Phone2#ButtonLabel!silent ; append cidnum:'12' and cidname:'Phone2' to line-ci with label 'ButtonLabel', don't ring when dialed directly + ; - button = line,98099@+12:Phone2@ButtonLabel!silent ; same as the previous line + ; - button = line,98099@=12:Phone2!silent ; overwrite line-cid instead of appending + ; - button = speeddial,Phone 2 Line 1, 98021, 98021@hints + ; - button = feature,cfwdall,1234 + ; - button = feature,PDefault,ParkingLot,default ; feature, name, feature_type, parkinglotContext [,RetrieveSingle] + ; - button = feature,PDefault,ParkingLot,default,RetrieveSingle ; feature, name, feature_type, parkinglotContext [,RetrieveSingle] +;allowRinginNotification = no ; allow ringin notification for hinted extensions. experimental configuration param that may be removed in further version +;conf_allow = yes ; Allow the use of conference +;conf_play_general_announce = yes ; Playback General Announcements (like: 'You are Entering/Leaving the conference') +;conf_play_part_announce = yes ; Playback Personal/Participant Announcements, (like: 'You have been muted / You have been kicked') +;conf_mute_on_entry = no ; Mute new participants from the start +;conf_music_on_hold_class = default ; Play music on hold of this class when no moderator is listening on the conference. If set to an empty string, no music on hold will be played. +;conf_show_conflist = yes ; Automatically show conference list to the moderator +backgroundImage = "" ; Set the Background Image after device registered. Image must be set as URI to a http served file. +ringtone = "" ; Set the Ring Tone after device registered. Ring Tone must be set as URI to a http served file. +imageversion = "" ; (SIZE: 31) ImageVersion to be loaded on the device. + +; +; line section +; +[default_line](!) +id = "" ; (SIZE: 7) id +pin = "" ; (SIZE: 7) pin +description = "" ; description +context = "" ; pbx dialing context +defaultSubscriptionId_name = "" ; (SIZE: 79) Name used on a shared line when no name is specified on the line button for the device +defaultSubscriptionId_number = "" ; (SIZE: 79) Number used on a shared line when no name is specified on the line button for the device +mailbox = "" ; Mailbox to store messages in. Format 'mailbox@context' or 'mailbox' when you use 'default' context +vmnum = "" ; Number to dial to get to the users Mailbox +adhocNumber = "" ; Adhoc Number or Private-line automatic ring down (PLAR): + ; Adhoc/PLAR circuits have statically configured endpoints and do not require the user dialing to connect calls. + ; - The adhocNumber is dialed as soon as the Phone is taken off-hook or when the new-call button is pressed. + ; - The number will not be dialed when choosing a line; so when you choose a line you can enter a number manually. +meetme = "" ; enable/disable conferencing via meetme, make sure you have one of the meetme apps mentioned below activated in module.conf. + ; When switching meetme=on it will search for the first of these three possible meetme applications and set these defaults. + ; Meetme=>'qd', ConfBridge=>'Mac', Konference=>'MTV' +meetmenum = "" ; This extension will receive meetme requests, SCCP_MEETME_ROOM channel variable will + ; contain the room number dialed into simpleswitch (this parameter is going to be removed). +meetmeopts = "" ; options to send the meetme application, defaults are dependent on meetme app see the list above. + ; Other options (app_meetme: A,a,b,c,C,d,D,E,e,F,i,I,l,L,m,M,o,p,P,q,r,s,S,t,T,w,x,X,1) see conferencing app for specific documentation +transfer = "" ; per line transfer capability +;incominglimit = 6 ; allow x number of incoming calls (call waiting) +echocancel = "" ; sets the phone echocancel for this line +silencesuppression = "" ; sets the silence suppression for this line +language = "" ; sets the language setting per line +musicclass = "" ; sets the music on hold class per line +accountcode = "" ; accountcode for this line to make billing per call possible +amaflags = "" ; sets the AMA flags stored in the CDR record for this line +callgroup = "" ; sets the caller groups this line is a member of +pickupgroup = "" ; sets the pickup groups this line is a member of (this phone can pickup calls from remote phones which are in this caller group +namedcallgroup = "" ; sets the named caller groups this line is a member of (ast111) +namedpickupgroup = "" ; sets the named pickup groups this line is a member of (this phone can pickup calls from remote phones which are in this caller group (ast111) +parkinglot = "" ; parkinglot assigned to this line +trnsfvm = "" ; extension to redirect the caller to for voice mail +secondary_dialtone_digits = "" ; digits to indicate an external line to user (secondary dialtone) (max 9 digits) +;secondary_dialtone_tone = 0x22 ; outside dialtone frequency +setvar = "" ; (MULTI-ENTRY) extra variables to be set on line initialization multiple entries possible (for example the sip number to use when dialing outside) + ; format setvar=param=value, for example setvar=sipno=12345678 +dnd = "" ; allow setting dnd action for this line. Valid values are 'off', 'reject' (busy signal), 'silent' (ringer = silent) or 'user' (not used at the moment). . The value 'on' has been made obsolete in favor of 'reject' + ; (POSSIBLE VALUES: ["Off","Reject","Silent","UserDefined"]) +regexten = "" ; SCCP Lines will we added to the regcontext with this number for Dundi look up purpose + ; If regexten is not filled in the line name (categoryname between []) will be used + +; +; softkey section +; +;[mysoftkeyset] +;type = softkeyset ; (SIZE: -1) This should be set to softkeyset +;onhook = redial,newcall,cfwdall,dnd,pickup,gpickup,private ; (SIZE: 15) displayed when we are on hook +;connected = hold,endcall,park,vidmode,select,cfwdall,cfwdbusy,idivert ; (SIZE: 15) displayed when we have a connected call +;onhold = resume,newcall,endcall,transfer,conflist,select,dirtrfr,idivert,meetme ; (SIZE: 15) displayed when we have a call on hold +;ringin = answer,endcall,transvm,idivert ; (SIZE: 15) displayed when we have an incoming call +;offhook = redial,endcall,private,cfwdall,cfwdbusy,pickup,gpickup,meetme,barge ; (SIZE: 15) displayed when the phone is taken off hook +;conntrans = hold,endcall,transfer,conf,park,select,dirtrfr,vidmode,meetme,cfwdall,cfwdbusy ; (SIZE: 15) displayed when we are connected and could transfer a call +;digitsfoll = back,endcall,dial ; (SIZE: 15) displayed when one or more digits have been entered, more are expected +;connconf = conflist,newcall,endcall,hold,vidmode ; (SIZE: 15) displayed when we are in a conference +;ringout = empty,endcall,transfer,cfwdall,idivert ; (SIZE: 15) displayed when We are calling someone +;offhookfeat = redial,endcall ; (SIZE: 15) displayed wenn we went offhook using a feature +;onhint = redial,newcall,pickup,gpickup,barge ; (SIZE: 15) displayed when a hint is activated +;onstealable = redial,newcall,cfwdall,pickup,gpickup,dnd,intrcpt ; (SIZE: 15) displayed when there is a call we could steal on one of the neighboring phones +;holdconf = resume,newcall,endcall,join ; (SIZE: 15) displayed when we are a conference moderator, have the conference on hold and have another active call +uriaction = "" ; (MULTI-ENTRY) (SIZE: 7) softkey uri action to replace default handling. Format: uriaction = softkeyname, uri[,uri...] + ; . URI can be an embedded cisco action (like Key:Service, Play:1041.raw) or a URLIf uri is a url the following parameters will be added to it: devicename, linename, channelname, callid, linkedid, uniqueid, appid, transactionid diff --git a/conf/Sccp.class.php.v431 b/conf/Sccp.class.php.v431 new file mode 100644 index 0000000..7f34dbe --- /dev/null +++ b/conf/Sccp.class.php.v431 @@ -0,0 +1,421 @@ + key Settings + private $data_fld = array("pin"=>'pin', "label" => 'label', "accountcode" => 'account', + "context" =>'lcontext',"incominglimit"=>'incominglimit', +// "callgroup"=>'callgroup',"pickupgroup"=>'pickupgroup', + 'namedcallgroup'=>'namedcallgroup', 'namedpickupgroup' => 'namedpickupgroup', + "transfer" => 'transfer', "echocancel" => 'echocancel', + "language" => 'language', "description" => 'callerid', + "cid_num" => 'cid_num', "cid_name" => 'label', "mailbox" => 'mailbox', + "musicclass" => 'musicclass', + "dnd" => 'dnd', "silencesuppression" => 'silencesuppression', + "secondary_dialtone_digits" => 'secondary_dialtone_digits', "secondary_dialtone_tone" => 'secondary_dialtone_tone' + ); + + public function __construct($freepbx) { + parent::__construct($freepbx); +// $this->version = $freepbx->Config->get('ASTVERSION'); + } + + public function getInfo() { + return array( + "rawName" => "sccp", + "hardware" => "sccp_custom", + "prettyName" => _("Sccp Custom Driver"), + "shortName" => "SCCP", + "description" => _("Sccp Device"), + "Version" => "11.3.v432", + "about" => "Sccp mysql class Base ver: 11.3, Sccp ver: 431" + ); + } +/* + public function addDevice1($id, $settings) { + $sql = 'INSERT INTO sccp (id, keyword, data, flags) values (?,?,?,?)'; + $sth = $this->database->prepare($sql); + $settings = is_array($settings)?$settings:array(); + foreach($settings as $key => $setting) { + $sth->execute(array($id,$key,$setting['value'],$setting['flag'])); + } + return true; + } +*/ + public function addDevice($id, $settings) { + $add_fld = array ("name"=>'label',"outboundcid"=>'cid_num',"langcode"=>'language',"extdisplay"=>'description','devinfo_mailbox'=>'mailbox'); +// print_r($_REQUEST); +// echo '

'; +// die(print_r($settings)); + $settings['cid_num']['value']=''; + $settings['mailbox']['value']= ''; + if (isset($_REQUEST)){ + foreach($add_fld as $key => $val) { + if (!empty($_REQUEST[$key])){ + $settings[$val]['value'] = $_REQUEST[$key]; + } + } + } + if (empty($settings['cid_num']['value'])) { + $settings['cid_num']['value']= $id; + } + + if (!empty($_REQUEST['vm']) && ($_REQUEST['vm'] =='enabled')){ // mailbox + if (empty($settings['mailbox']['value'])) { + $settings['mailbox']['value']= $id; + } + } + +// die(print_r($settings)); + + $sql = 'REPLACE INTO sccpline (name'; + $sqlv = 'values ("'.$id.'"'; + foreach($this->data_fld as $key => $val) { + switch ($key) { + case 'incominglimit': + $sql .= ', '.$key; + if (!empty($settings[$val]['value'])){ + $sqlv .= ", '".$settings[$val]['value']."' "; + } else { + $sqlv .= ", DEFAULT(`".$key."`)"; + } + break; + case 'secondary_dialtone_digits': + case 'secondary_dialtone_tone': + case 'dnd': + $sql .= ', '.$key; + if (!$this->is_my_blank($settings[$val]['value'])){ + $sqlv .= ", '".$settings[$val]['value']."' "; + } else { + $sqlv .= ", NULL "; +// $sqlv .= ", DEFAULT(`".$key."`)"; + } + break; + default: + if (!empty($settings[$val]) ) { + if (!empty($settings[$val]['value'])){ + $sql .= ', '.$key; + $sqlv .= ", '".$settings[$val]['value']."' "; + } + } + break; + } + } + $sql .= ") ".$sqlv.");"; +// die(print_r($sql)); + $sth = $this->database->prepare($sql); + $sth->execute(); + return true; + } + + public function delDevice($id) { +// $sql = "DELETE FROM sccpline WHERE id = ?"; + $sql = "DELETE FROM sccpline WHERE name = ?"; + $sth = $this->database->prepare($sql); + $sth->execute(array($id)); + return true; + } + + + public function getDevice($id) { + $sccp_line = array(); + $sql = "SELECT name as id, name as name "; + foreach($this->data_fld as $key => $val) { + $sql .= ',`'. $key .'` as '.$val; + } +// $sql .= " FROM sccpline WHERE id = ?"; + $sql .= " FROM sccpline WHERE name = ?"; + $sth = $this->database->prepare($sql); + $result = array(); + $tech = array(); + try { + $sth->execute(array($id)); + $result = $sth->fetch(\PDO::FETCH_ASSOC); + $tech = $result; + $tech['dial']='SCCP/'.$id; + } catch(\Exception $e) {} + +// print_r($tech); +// echo '

'; +// print_r($sql); +// die(print_r($id)); +// echo '

'; + + return $tech; + } + + public function getNamedGroup() { + $sql = "select namedcallgroup from sccpline group by namedcallgroup"; + $sth = $this->database->prepare($sql); + $result = array(); + $tech = array(); +// $tech['namedcallgroup'] = ''; +// $tech['namedpickupgroup'] = ''; + try { + $sth->execute(); + $result = $sth->fetchAll(); + foreach($result as $val) { + $tech['namedcallgroup'][] = $val[0]; + } + } catch(\Exception $e) {} + $sql = "select namedpickupgroup from sccpline group by namedpickupgroup"; + $sth = $this->database->prepare($sql); + try { + $sth->execute(); + $result = $sth->fetchAll(); + foreach($result as $val) { + $tech['namedpickupgroup'][] = $val[0]; + } + } catch(\Exception $e) {} + + return $tech; + } + + public function getDefaultDeviceSettings($id, $displayname, &$flag) { + $dial = 'SCCP'; + $settings = array( + "mailbox" => array( + "value" => "", + "flag" => $flag++ + ), + "incominglimit" => array( + "value" => "2", + "flag" => $flag++ + ), + "lcontext" => array( + "value" => "from-internal", + "flag" => $flag++ + ), +// "callgroup" => array( +// "value" => "from-internal", +// "flag" => $flag++ +// ), + "namedcallgroup" => array( + "value" => "", + "flag" => $flag++ + ), +// "pickupgroup" => array( +// "value" => "", +// "flag" => $flag++ +// ), + "namedpickupgroup" => array( + "value" => "", + "flag" => $flag++ + ), + "secondary_dialtone_digits" => array( + "value" => "9", + "flag" => $flag++ + ), + "secondary_dialtone_tone" => array( + "value" => "0x22", + "flag" => $flag++ + ), + "transfer" => array( + "value" => "on", + "flag" => $flag++ + ), + "echocancel" => array( + "value" => "on", + "flag" => $flag++ + ), + "dnd" => array( + "value" => "", + "flag" => $flag++ + ), + "silencesuppression" => array( + "value" => "off", + "flag" => $flag++ + ), + "musicclass" => array( + "value" => "default", + "flag" => $flag++ + ), + "pin" => array( + "value" => "", + "flag" => $flag++ + ), + "musicclass" => array( + "value" => "default", + "flag" => $flag++ + ), + ); + return array( + "dial" => $dial, + "settings" => $settings + ); + } + + public function getDeviceDisplay($display, $deviceInfo, $currentcomponent, $primarySection) { + $section = _("SCCP Extension Details"); +// $category = "general"; +// Assigned DID/CID + $named_group = $this->getNamedGroup(); + $tmparr = array(); + $tt = _("Name or id of lincked maibox"); + $tmparr['mailbox'] = array('prompttext' => _('Mailbox'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tt = _("The SCCP channel number for this port. If you plaining to use this line as 'Shared' or use on several devices - leave this field blank or set limit to 10 calls."); +// $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '2', 'tt' => $tt, 'level' => 0, 'jsvalidation' => 'isEmpty()', 'failvalidationmsg' => $msgInvalidChannel); +// $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section, 'category' => 'general'); + + $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + + $tt = _("Asterisk context this device will send calls to. Only change this is you know what you are doing."); + $tmparr['lcontext'] = array('prompttext' => _('Line context'), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1, 'section' => $section); + +// $tt = _("Phone call group callgroup=1,3-4"); +// $tmparr['callgroup'] = array('prompttext' => _('Call group id'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + + $tt = _("Sets the named caller groups this line is a member of (ast111) : "); + if (!empty($named_group['namedcallgroup'])) { + foreach ($named_group['namedcallgroup'] as $val) { + $tt .= $val. ', '; + } + $tt .= '... '; + } + $tmparr['namedcallgroup'] = array('prompttext' => _('Named Call Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); +// $tmparr['namedcallgroup'] = array('prompttext' => _('Named Call Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section, 'category' => 'general'); +// $tt = _("Phone pickup group pickupgroup=1,3-4"); +// $tmparr['pickupgroup'] = array('prompttext' => _('Pickup group id'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tt = _("Named PickupGroup : "); + if (!empty($named_group['namedpickupgroup'])) { + foreach ($named_group['namedpickupgroup'] as $val) { + $tt .= $val. ', '; + } + $tt .= '... '; + } + $tmparr['namedpickupgroup'] = array('prompttext' => _('Named Pickup Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); +// $tmparr['namedpickupgroup'] = array('prompttext' => _('Named Pickup Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section, 'category' => 'general'); + $tt = _("Digits to indicate an external line to user (secondary dialtone) Sample 9 or 8 (max 9 digits)"); + $tmparr['secondary_dialtone_digits'] = array('prompttext' => _('Secondary dialtone digits'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + + unset($select); + $select[] = array( 'value' => '0x21', 'text' => 'Inside Dial Tone'); + $select[] = array( 'value' => '0x22', 'text' => 'Outside Dial Tone'); + $select[] = array( 'value' => '0x23', 'text' => 'Line Busy Tone'); + $select[] = array( 'value' => '0x24', 'text' => 'Alerting Tone'); + $select[] = array( 'value' => '0x25', 'text' => 'Reorder Tone'); + $select[] = array( 'value' => '0x26', 'text' => 'Recorder Warning Tone'); + $select[] = array( 'value' => '0x27', 'text' => 'Recorder Detected Tone'); + $select[] = array( 'value' => '0x28', 'text' => 'Reverting Tone'); + $select[] = array( 'value' => '0x29', 'text' => 'Receiver OffHook Tone'); + $select[] = array( 'value' => '0x2A', 'text' => 'Partial Dial Tone'); + $select[] = array( 'value' => '0x2B', 'text' => 'No Such Number Tone'); + $select[] = array( 'value' => '0x2C', 'text' => 'Busy Verification Tone'); + $select[] = array( 'value' => '0x2D', 'text' => 'Call Waiting Tone'); + $select[] = array( 'value' => '0x2E', 'text' => 'Confirmation Tone'); + $select[] = array( 'value' => '0x2F', 'text' => 'Camp On Indication Tone'); + $select[] = array( 'value' => '0x30', 'text' => 'Recall Dial Tone'); + $select[] = array( 'value' => '0x31', 'text' => 'Zip Zip'); + $select[] = array( 'value' => '0x32', 'text' => 'Zip'); + $select[] = array( 'value' => '0x33', 'text' => 'Beep Bonk'); + $select[] = array( 'value' => '0x34', 'text' => 'Music Tone'); + $select[] = array( 'value' => '0x35', 'text' => 'Hold Tone'); + $select[] = array( 'value' => '0x36', 'text' => 'Test Tone'); + $select[] = array( 'value' => '0x37', 'text' => 'DT Monitor Warning Tone'); + $select[] = array( 'value' => '0x40', 'text' => 'Add Call Waiting'); + $select[] = array( 'value' => '0x41', 'text' => 'Priority Call Wait'); + $select[] = array( 'value' => '0x42', 'text' => 'Recall Dial'); + $select[] = array( 'value' => '0x43', 'text' => 'Barg In'); + $select[] = array( 'value' => '0x44', 'text' => 'Distinct Alert'); + $select[] = array( 'value' => '0x45', 'text' => 'Priority Alert'); + $select[] = array( 'value' => '0x46', 'text' => 'Reminder Ring'); + $select[] = array( 'value' => '0x47', 'text' => 'Precedence RingBank'); + $select[] = array( 'value' => '0x48', 'text' => 'Pre-EmptionTone'); + $select[] = array( 'value' => '0x67', 'text' => '2105 HZ'); + $select[] = array( 'value' => '0x68', 'text' => '2600 HZ'); + $select[] = array( 'value' => '0x69', 'text' => '440 HZ'); + $select[] = array( 'value' => '0x6A', 'text' => '300 HZ'); + $select[] = array( 'value' => '0x77', 'text' => 'MLPP Pala'); + $select[] = array( 'value' => '0x78', 'text' => 'MLPP Ica'); + $select[] = array( 'value' => '0x79', 'text' => 'MLPP Vca'); + $select[] = array( 'value' => '0x7A', 'text' => 'MLPP Bpa'); + $select[] = array( 'value' => '0x7B', 'text' => 'MLPP Bnea'); + $select[] = array( 'value' => '0x7C', 'text' => 'MLPP Upa'); +/* !TODO!: I would remove the values below this line, except for 'No Tone' */ +// $select[] = array( 'value' => '0x7F', 'text' => 'No Tone'); + $select[] = array( 'value' => '0x80', 'text' => 'Meetme Greeting Tone'); + $select[] = array( 'value' => '0x81', 'text' => 'Meetme Number Invalid Tone'); + $select[] = array( 'value' => '0x82', 'text' => 'Meetme Number Failed Tone'); + $select[] = array( 'value' => '0x83', 'text' => 'Meetme Enter Pin Tone'); + $select[] = array( 'value' => '0x84', 'text' => 'Meetme Invalid Pin Tone'); + $select[] = array( 'value' => '0x85', 'text' => 'Meetme Failed Pin Tone'); + $select[] = array( 'value' => '0x86', 'text' => 'Meetme CFB Failed Tone'); + $select[] = array( 'value' => '0x87', 'text' => 'Meetme Enter Access Code Tone'); + $select[] = array( 'value' => '0x88', 'text' => 'Meetme Access Code Invalid Tone'); + $select[] = array( 'value' => '0x89', 'text' => 'Meetme Access Code Failed Tone'); + $select[] = array('value' => 'yes', 'text' => 'Yes'); + $select[] = array('value' => 'no', 'text' => 'No'); + + $tt = _("Outside dialtone frequency (defaul 0x22)"); + $tmparr['secondary_dialtone_tone'] = array('prompttext' => _('Secondary dialtone'), 'value' => '0x22', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'select', 'section' => $section); + + + + unset($select); + $select[] = array('value' => 'on', 'text' => 'Yes'); + $select[] = array('value' => 'off', 'text' => 'No'); + $tt = _("Allow call transfer."); +// $tmparr['transfer'] = array('prompttext' => _('Call Transfer'), 'value' => 'yes', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section, 'category' => 'general'); + $tmparr['transfer'] = array('prompttext' => _('Call Transfer'), 'value' => 'on', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + + unset($select); + $select[] = array('value' => 'on', 'text' => 'Yes'); + $select[] = array('value' => 'off', 'text' => 'No'); + $tt = _("Echo cancel"); + $tmparr['echocancel'] = array('prompttext' => _('Echo cancel'), 'value' => 'on', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + + unset($select); + $select[] = array('value' => 'off', 'text' => 'Off'); + $select[] = array('value' => 'reject', 'text' => 'Reject'); + $select[] = array('value' => 'silent', 'text' => 'Silent'); + $select[] = array('value' => 'user', 'text' => 'Cycle'); + $tt = _("DND: Means how will dnd react when it is set on the device level dnd can have three states: off / busy(reject) / silent / Cycle").'
'. + _("Cycle - dnd that cycles through all three states off -> reject -> silent -> off (this is the normal behaviour)").'
'. + _("Reject - Usesr can only switch off and on (in reject/busy mode)").'
'. + _("Silent - Usesr can only switch off and on (in silent mode)"); + $tmparr['dnd'] = array('prompttext' => _('DND'), 'value' => 'reject', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + + unset($select); + $select[] = array('value' => 'on', 'text' => 'Yes'); + $select[] = array('value' => 'off', 'text' => 'No'); + $tt = _("Silence Suppression. Asterisk Not supported"); + $tmparr['silencesuppression'] = array('prompttext' => _('Silence Suppression'), 'value' => 'off', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + + unset($select); + $select[] = array('value' => 'default', 'text' => _('default')); + if (function_exists('music_list')){ + $moh_list = music_list(); + } else { + $moh_list = array('default'); + } + foreach ($moh_list as $value) { + $select[] = array('value' => $value, 'text' => _($value)); + } + + $tt = _("Music on hold"); + $tmparr['musicclass'] = array('prompttext' => _('Music on hold'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'section' => $section); + + $tt = _("Sets the named pickup groups this line is a member of (this phone can pickup calls from remote phones which are in this caller group (ast111)"); + $tmparr['pin'] = array('value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + + + $devopts = $tmparr; + return $devopts; + } + public function getDeviceHeaders() { + return array( + 'secret' => array('identifier' => _('Secret'), 'description' => sprintf(_('Secret [Enter "%s" to regenerate]'),"REGEN")), + ); + } + public function is_my_blank($value) { + return empty($value) && !is_numeric($value); +} + +} diff --git a/conf/Sccp.class.php.v433 b/conf/Sccp.class.php.v433 index 46fbbda..6eac413 100644 --- a/conf/Sccp.class.php.v433 +++ b/conf/Sccp.class.php.v433 @@ -6,30 +6,31 @@ // namespace FreePBX\modules\Core\Drivers; class Sccp extends \FreePBX\modules\Core\Driver { - private $data_fld = array("pin"=>'pin', "label" => 'label', "accountcode" => 'account', - "context" =>'lcontext',"incominglimit"=>'incominglimit', - "callgroup"=>'callgroup',"pickupgroup"=>'pickupgroup', - "transfer" => 'transfer', "echocancel" => 'echocancel', - "language" => 'language', "description" => 'callerid', - "cid_num" => 'cid_num', "cid_name" => 'cid_name', "mailbox" => 'mailbox', - "musicclass" => 'musicclass',"allow" => 'allow',"disallow" => 'disallow', - "videomode" => 'videomode', - "dnd" => 'dnd', "silencesuppression" => 'silencesuppression', - "secondary_dialtone_digits" => 'secondary_dialtone_digits', "secondary_dialtone_tone" => 'secondary_dialtone_tone', - 'namedcallgroup'=>'namedcallgroup', 'namedpickupgroup' => 'namedpickupgroup' - ); + private $data_fld = array("pin"=>'pin', "label" => 'label', "accountcode" => 'account', + "context" =>'lcontext',"incominglimit"=>'incominglimit', + "callgroup"=>'callgroup',"pickupgroup"=>'pickupgroup', + "transfer" => 'transfer', "echocancel" => 'echocancel', + "language" => 'language', "description" => 'callerid', + "cid_num" => 'cid_num', "cid_name" => 'cid_name', "mailbox" => 'mailbox', + "musicclass" => 'musicclass',"allow" => 'allow',"disallow" => 'disallow', + "videomode" => 'videomode', + "dnd" => 'dnd', "silencesuppression" => 'silencesuppression', + "secondary_dialtone_digits" => 'secondary_dialtone_digits', "secondary_dialtone_tone" => 'secondary_dialtone_tone', + 'namedcallgroup'=>'namedcallgroup', 'namedpickupgroup' => 'namedpickupgroup' + ); - public function getInfo() { - return array( - "rawName" => "sccp", - "hardware" => "sccp_custom", - "prettyName" => _("Sccp Custom Driver"), - "shortName" => "SCCP", - "description" => _("Sccp Device"), - "Version" => "11.4", - "about" => "Sccp mysql class Base ver: 11.3, Sccp ver: default" - ); - } + public function getInfo() { + return array( + "rawName" => "sccp", + "hardware" => "sccp_custom", + "prettyName" => _("Sccp Custom Driver"), + "shortName" => "SCCP", + "description" => _("Sccp Device"), + "Version" => "11.4", + "about" => "Sccp mysql class Base ver: 11.3, Sccp ver: default" + + ); + } /* public function addDevice1($id, $settings) { $sql = 'INSERT INTO sccp (id, keyword, data, flags) values (?,?,?,?)'; @@ -41,311 +42,315 @@ class Sccp extends \FreePBX\modules\Core\Driver { return true; } */ - public function addDevice($id, $settings) { - $add_fld = array ("name"=>'label',"outboundcid"=>'cid_num',"langcode"=>'language',"extdisplay"=>'description'); - // print_r($_REQUEST); - // echo '

'; - // die(print_r($settings)); - $settings['cid_num']['value'] = ''; - $settings['cid_name']['value'] = $label; - $settings['mailbox']['value']= ''; + public function addDevice($id, $settings) { + $add_fld = array ("name"=>'label',"outboundcid"=>'cid_num',"langcode"=>'language',"extdisplay"=>'description'); +// print_r($_REQUEST); +// echo '

'; +// die(print_r($settings)); + $settings['cid_num']['value'] = ''; + $settings['cid_name']['value'] = $label; + $settings['mailbox']['value']= ''; - if (isset($_REQUEST)){ - foreach($add_fld as $key => $val) { - if (!empty($_REQUEST[$key])){ - $settings[$val]['value'] = $_REQUEST[$key]; + if (isset($_REQUEST)){ + foreach($add_fld as $key => $val) { + if (!empty($_REQUEST[$key])){ + $settings[$val]['value'] = $_REQUEST[$key]; + } + } } - } - } - $allow_codec = array(); - foreach($settings as $key => $val) { - if (strpos($key,'codec_') !== false ) { - $allow_codec[] =substr($key,6); - } - } - $settings['allow']['value'] = implode(",", $allow_codec); + $allow_codec = array(); + foreach($settings as $key => $val) { + if (strpos($key,'codec_') !== false ) { + $allow_codec[] =substr($key,6); + } + } + $settings['allow']['value'] = implode(",", $allow_codec); - // parse outboundcid content into cid_num and cid_name sccpline fields - if (empty($settings['cid_num']['value'])) { - $settings['cid_num']['value'] = $id; - } else { - $outboundcid = $settings['cid_num']['value']; - if (preg_match('/"(.*)"\s?<(.*)>/', $outboundcid, $matches)) { - $settings['cid_num']['value'] = $matches[2]; - $settings['cid_name']['value'] = $matches[1]; - } else if (is_integer($outboundcid)) { - $settings['cid_num']['value'] = $outboundcid; - } + // parse outboundcid content into cid_num and cid_name sccpline fields + if (empty($settings['cid_num']['value'])) { + $settings['cid_num']['value'] = $id; + } else { + $outboundcid = $settings['cid_num']['value']; + if (preg_match('/"(.*)"\s?<(.*)>/', $outboundcid, $matches)) { + $settings['cid_num']['value'] = $matches[2]; + $settings['cid_name']['value'] = $matches[1]; + } else if (is_integer($outboundcid)) { + $settings['cid_num']['value'] = $outboundcid; + } + } + + if (!empty($_REQUEST['vm']) && ($_REQUEST['vm'] =='enabled')){ // mailbox + if (empty($settings['mailbox']['value'])) { + $settings['mailbox']['value']= $id; + } + } + +// die(print_r($settings)); + $tech = Array(); + $sql = "DESCRIBE `sccpline`"; + foreach ($this->database->query($sql) as $row) { + $tech[$row["Field"]]=$row["Field"]; + } + +// die(print_r($tech)); + + $sql = 'REPLACE INTO sccpline (name'; + $sqlv = 'values ("'.$id.'"'; + foreach($this->data_fld as $key => $val) { + if (!empty($settings[$val]) ) { + if (!empty($settings[$val]['value'])){ + $sql .= ', '.$key; + $sqlv .= ", '".$settings[$val]['value']."' "; + } + } + } + $sql .= ") ".$sqlv.");"; + $sth = $this->database->prepare($sql); + $sth->execute(); + return true; } - if (!empty($_REQUEST['vm']) && ($_REQUEST['vm'] =='enabled')){ // mailbox - if (empty($settings['mailbox']['value'])) { - $settings['mailbox']['value']= $id; - } - } - - // die(print_r($settings)); - $tech = Array(); - $sql = "DESCRIBE sccpline"; - foreach ($this->database->query($sql) as $row) { - $tech[$row["Field"]]=$row["Field"]; - } - $sqlCol = 'name'; - $sqlVal = "'{$id}'"; - foreach($this->data_fld as $key => $val) { - if (isset($settings[$val]['value'])){ - $sqlCol .= ", {$key}"; - $sqlVal .= ", '{$settings[$val]['value']}'"; - } - } - $sql = "REPLACE INTO sccpline ( {$sqlCol} ) VALUES ( {$sqlVal} );"; - - $sth = $this->database->prepare($sql); - $sth->execute(); - return true; - } - - public function delDevice($id) { - $sql = "DELETE FROM sccpline WHERE name = ?"; - $sth = $this->database->prepare($sql); - $sth->execute(array($id)); - return true; - } + public function delDevice($id) { + $sql = "DELETE FROM sccpline WHERE name = ?"; + $sth = $this->database->prepare($sql); + $sth->execute(array($id)); + return true; + } - public function getDevice($id) { - $sccp_line = array(); - // $sql = "SELECT name as id, name as name"; - $sql = "SELECT name as id, name as name "; - foreach($this->data_fld as $key => $val) { - $sql .= ',`'. $key .'` as '.$val; - } - $sql .= " FROM sccpline WHERE name = ?"; - $sth = $this->database->prepare($sql); - $result = array(); - $tech = array(); - try { - $sth->execute(array($id)); - $result = $sth->fetch(\PDO::FETCH_ASSOC); - $tech = $result; - $tech['dial']='SCCP/'.$id; - } catch(\Exception $e) {} + public function getDevice($id) { + $sccp_line = array(); +// $sql = "SELECT name as id, name as name"; + $sql = "SELECT name as id, name as name "; + foreach($this->data_fld as $key => $val) { + $sql .= ',`'. $key .'` as '.$val; + } + $sql .= " FROM sccpline WHERE name = ?"; + $sth = $this->database->prepare($sql); + $result = array(); + $tech = array(); + try { + $sth->execute(array($id)); + $result = $sth->fetch(\PDO::FETCH_ASSOC); + $tech = $result; + $tech['dial']='SCCP/'.$id; + } catch(\Exception $e) {} - return $tech; - } + return $tech; + } - public function getDefaultDeviceSettings($id, $displayname, &$flag) { - $dial = 'SCCP'; - $settings = array( - "pin" => array( - "value" => "", - "flag" => $flag++ - ), - "incominglimit" => array( - "value" => "", - "flag" => $flag++ - ), - "lcontext" => array( - "value" => "from-internal", - "flag" => $flag++ - ), - "callgroup" => array( - "value" => "", - "flag" => $flag++ - ), - "namedcallgroup" => array( - "value" => "", - "flag" => $flag++ - ), - "pickupgroup" => array( - "value" => "", - "flag" => $flag++ - ), - "namedpickupgroup" => array( - "value" => "", - "flag" => $flag++ - ), - "transfer" => array( - "value" => "on", - "flag" => $flag++ - ), - "adhocNumber" => array( - "value" => "", - "flag" => $flag++ - ), - "echocancel" => array( - "value" => "no", - "flag" => $flag++ - ), - "dnd" => array( - "value" => "UserDefined", - "flag" => $flag++ - ), - "silencesuppression" => array( - "value" => "no", - "flag" => $flag++ - ), - "secondary_dialtone_digits" => array( - "value" => "9", - "flag" => $flag++ - ), - "secondary_dialtone_tone" => array( - "value" => "0x22", - "flag" => $flag++ - ), - "musicclass" => array( - "value" => "default", - "flag" => $flag++ - ) - ); - return array( - "dial" => $dial, - "settings" => $settings - ); - } + public function getDefaultDeviceSettings($id, $displayname, &$flag) { + $dial = 'SCCP'; + $settings = array( + "pin" => array( + "value" => "", + "flag" => $flag++ + ), + "incominglimit" => array( + "value" => "", + "flag" => $flag++ + ), + "lcontext" => array( + "value" => "from-internal", + "flag" => $flag++ + ), + "callgroup" => array( + "value" => "", + "flag" => $flag++ + ), + "namedcallgroup" => array( + "value" => "", + "flag" => $flag++ + ), + "pickupgroup" => array( + "value" => "", + "flag" => $flag++ + ), + "namedpickupgroup" => array( + "value" => "", + "flag" => $flag++ + ), + "transfer" => array( + "value" => "yes", + "flag" => $flag++ + ), + "adhocNumber" => array( + "value" => "", + "flag" => $flag++ + ), + "echocancel" => array( + "value" => "no", + "flag" => $flag++ + ), + "dnd" => array( + "value" => "UserDefined", + "flag" => $flag++ + ), + "silencesuppression" => array( + "value" => "no", + "flag" => $flag++ + ), + "secondary_dialtone_digits" => array( + "value" => "9", + "flag" => $flag++ + ), + "secondary_dialtone_tone" => array( + "value" => "0x22", + "flag" => $flag++ + ), + "musicclass" => array( + "value" => "default", + "flag" => $flag++ + ), + ); + return array( + "dial" => $dial, + "settings" => $settings + ); + } # !TODO!: -TODO-: Would it not be better to put this part in the view directory (MVC) ? No, This is a template for Freepbx. - public function getDeviceDisplay($display, $deviceInfo, $currentcomponent, $primarySection) { - $section = _("Settings"); - $category = "general"; - $tmparr = array(); - $tt = _("The maximum number of incoming calls on this line."); - // $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '2', 'tt' => $tt, 'level' => 0, 'jsvalidation' => 'isEmpty()', 'failvalidationmsg' => $msgInvalidChannel); - // !TODO!: Please change the default value for incominglimit to '6' or higher - $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '2', 'tt' => $tt, 'level' => 1); + public function getDeviceDisplay($display, $deviceInfo, $currentcomponent, $primarySection) { + $section = _("Settings"); + $category = "general"; + $tmparr = array(); + $tt = _("The maximum number of incoming calls on this line."); +// $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '2', 'tt' => $tt, 'level' => 0, 'jsvalidation' => 'isEmpty()', 'failvalidationmsg' => $msgInvalidChannel); +// !TODO!: Please change the default value for incominglimit to '6' or higher + $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '2', 'tt' => $tt, 'level' => 1); - $tt = _("Asterisk context which this line will use to send and receive calls (Note: Only change this is you know what you are doing)."); - $tmparr['lcontext'] = array('prompttext' => _('Line context'), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1); + $tt = _("Asterisk context which this line will use to send and receive calls (Note: Only change this is you know what you are doing)."); + $tmparr['lcontext'] = array('prompttext' => _('Line context'), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1); - // !TODO!: -TODO-: Maybe completely remove support for old numberic callgroup/pickupgroup in favor of the named version ? See Sccp.class.php.v431 - $tt = _("Phone call group (numeric only, example:1,3-4)"); - $tmparr['callgroup'] = array('prompttext' => _('Call group id'),'value' => '', 'tt' => $tt, 'level' => 1); +// !TODO!: -TODO-: Maybe completely remove support for old numberic callgroup/pickupgroup in favor of the named version ? See Sccp.class.php.v431 + $tt = _("Phone call group (numeric only, example:1,3-4)"); + $tmparr['callgroup'] = array('prompttext' => _('Call group id'),'value' => '', 'tt' => $tt, 'level' => 1); - // !TODO!: -TODO-: multiple allowed (not sure if that is implemented here). See Sccp.class.php.v431 - $tt = _("Phone named call group (>asterisk-11)"); - $tmparr['namedcallgroup'] = array('prompttext' => _('Named Call Group'),'value' => '', 'tt' => $tt, 'level' => 1); +// !TODO!: -TODO-: multiple allowed (not sure if that is implemented here). See Sccp.class.php.v431 + $tt = _("Phone named call group (>asterisk-11)"); + $tmparr['namedcallgroup'] = array('prompttext' => _('Named Call Group'),'value' => '', 'tt' => $tt, 'level' => 1); - $tt = _("Sets the pickup group (numeric only, example:1,3-4) this line is a member of. Allows this line to pickup calls from remote phones which are in this callhroup."); - $tmparr['pickupgroup'] = array('prompttext' => _('Pickup group id'),'value' => '', 'tt' => $tt, 'level' => 1); + $tt = _("Sets the pickup group (numeric only, example:1,3-4) this line is a member of. Allows this line to pickup calls from remote phones which are in this callhroup."); + $tmparr['pickupgroup'] = array('prompttext' => _('Pickup group id'),'value' => '', 'tt' => $tt, 'level' => 1); - // !TODO!: -TODO-: multiple allowed (not sure if that is implemented here). See Sccp.class.php.v431 - $tt = _("Sets the named pickup name group this line is a member of. Allows this line to pickup calls from remote phones which are in this name callgroup (>asterisk-11)."); - $tmparr['namedpickupgroup'] = array('prompttext' => _('Named Pickup Group'),'value' => '', 'tt' => $tt, 'level' => 1); +// !TODO!: -TODO-: multiple allowed (not sure if that is implemented here). See Sccp.class.php.v431 + $tt = _("Sets the named pickup name group this line is a member of. Allows this line to pickup calls from remote phones which are in this name callgroup (>asterisk-11)."); + $tmparr['namedpickupgroup'] = array('prompttext' => _('Named Pickup Group'),'value' => '', 'tt' => $tt, 'level' => 1); - $tt = _("Phone pincode (Note used)"); - $tmparr['pin'] = array('value' => '', 'tt' => $tt, 'level' => 1); + $tt = _("Phone pincode (Note used)"); + $tmparr['pin'] = array('value' => '', 'tt' => $tt, 'level' => 1); - $tt = _("Digits to indicate an external line to user (secondary dialtone) Sample 9 or 8 (max 9 digits)"); - $tmparr['secondary_dialtone_digits'] = array('prompttext' => _('Secondary dialtone digits'), 'value' => '', 'tt' => $tt, 'level' => 1); + $tt = _("Digits to indicate an external line to user (secondary dialtone) Sample 9 or 8 (max 9 digits)"); + $tmparr['secondary_dialtone_digits'] = array('prompttext' => _('Secondary dialtone digits'), 'value' => '', 'tt' => $tt, 'level' => 1); - unset($select); - $select[] = array( 'value' => '0x21', 'text' => 'Inside Dial Tone'); - $select[] = array( 'value' => '0x22', 'text' => 'Outside Dial Tone'); - $select[] = array( 'value' => '0x23', 'text' => 'Line Busy Tone'); - $select[] = array( 'value' => '0x24', 'text' => 'Alerting Tone'); - $select[] = array( 'value' => '0x25', 'text' => 'Reorder Tone'); - $select[] = array( 'value' => '0x26', 'text' => 'Recorder Warning Tone'); - $select[] = array( 'value' => '0x27', 'text' => 'Recorder Detected Tone'); - $select[] = array( 'value' => '0x28', 'text' => 'Reverting Tone'); - $select[] = array( 'value' => '0x29', 'text' => 'Receiver OffHook Tone'); - $select[] = array( 'value' => '0x2A', 'text' => 'Partial Dial Tone'); - $select[] = array( 'value' => '0x2B', 'text' => 'No Such Number Tone'); - $select[] = array( 'value' => '0x2C', 'text' => 'Busy Verification Tone'); - $select[] = array( 'value' => '0x2D', 'text' => 'Call Waiting Tone'); - $select[] = array( 'value' => '0x2E', 'text' => 'Confirmation Tone'); - $select[] = array( 'value' => '0x2F', 'text' => 'Camp On Indication Tone'); - $select[] = array( 'value' => '0x30', 'text' => 'Recall Dial Tone'); - $select[] = array( 'value' => '0x31', 'text' => 'Zip Zip'); - $select[] = array( 'value' => '0x32', 'text' => 'Zip'); - $select[] = array( 'value' => '0x33', 'text' => 'Beep Bonk'); - $select[] = array( 'value' => '0x34', 'text' => 'Music Tone'); - $select[] = array( 'value' => '0x35', 'text' => 'Hold Tone'); - $select[] = array( 'value' => '0x36', 'text' => 'Test Tone'); - $select[] = array( 'value' => '0x37', 'text' => 'DT Monitor Warning Tone'); - $select[] = array( 'value' => '0x40', 'text' => 'Add Call Waiting'); - $select[] = array( 'value' => '0x41', 'text' => 'Priority Call Wait'); - $select[] = array( 'value' => '0x42', 'text' => 'Recall Dial'); - $select[] = array( 'value' => '0x43', 'text' => 'Barg In'); - $select[] = array( 'value' => '0x44', 'text' => 'Distinct Alert'); - $select[] = array( 'value' => '0x45', 'text' => 'Priority Alert'); - $select[] = array( 'value' => '0x46', 'text' => 'Reminder Ring'); - $select[] = array( 'value' => '0x47', 'text' => 'Precedence RingBank'); - $select[] = array( 'value' => '0x48', 'text' => 'Pre-EmptionTone'); - $select[] = array( 'value' => '0x67', 'text' => '2105 HZ'); - $select[] = array( 'value' => '0x68', 'text' => '2600 HZ'); - $select[] = array( 'value' => '0x69', 'text' => '440 HZ'); - $select[] = array( 'value' => '0x6A', 'text' => '300 HZ'); - $select[] = array( 'value' => '0x77', 'text' => 'MLPP Pala'); - $select[] = array( 'value' => '0x78', 'text' => 'MLPP Ica'); - $select[] = array( 'value' => '0x79', 'text' => 'MLPP Vca'); - $select[] = array( 'value' => '0x7A', 'text' => 'MLPP Bpa'); - $select[] = array( 'value' => '0x7B', 'text' => 'MLPP Bnea'); - $select[] = array( 'value' => '0x7C', 'text' => 'MLPP Upa'); - /* !TODO!: +TODO+: I would remove the values below this line, except for 'No Tone' */ - // $select[] = array( 'value' => '0x7F', 'text' => 'No Tone'); - $select[] = array( 'value' => '0x80', 'text' => 'Meetme Greeting Tone'); - $select[] = array( 'value' => '0x81', 'text' => 'Meetme Number Invalid Tone'); - $select[] = array( 'value' => '0x82', 'text' => 'Meetme Number Failed Tone'); - $select[] = array( 'value' => '0x83', 'text' => 'Meetme Enter Pin Tone'); - $select[] = array( 'value' => '0x84', 'text' => 'Meetme Invalid Pin Tone'); - $select[] = array( 'value' => '0x85', 'text' => 'Meetme Failed Pin Tone'); - $select[] = array( 'value' => '0x86', 'text' => 'Meetme CFB Failed Tone'); - $select[] = array( 'value' => '0x87', 'text' => 'Meetme Enter Access Code Tone'); - $select[] = array( 'value' => '0x88', 'text' => 'Meetme Access Code Invalid Tone'); - $select[] = array( 'value' => '0x89', 'text' => 'Meetme Access Code Failed Tone'); - $select[] = array('value' => 'yes', 'text' => 'Yes'); - $select[] = array('value' => 'no', 'text' => 'No'); + unset($select); + $select[] = array( 'value' => '0x21', 'text' => 'Inside Dial Tone'); + $select[] = array( 'value' => '0x22', 'text' => 'Outside Dial Tone'); + $select[] = array( 'value' => '0x23', 'text' => 'Line Busy Tone'); + $select[] = array( 'value' => '0x24', 'text' => 'Alerting Tone'); + $select[] = array( 'value' => '0x25', 'text' => 'Reorder Tone'); + $select[] = array( 'value' => '0x26', 'text' => 'Recorder Warning Tone'); + $select[] = array( 'value' => '0x27', 'text' => 'Recorder Detected Tone'); + $select[] = array( 'value' => '0x28', 'text' => 'Reverting Tone'); + $select[] = array( 'value' => '0x29', 'text' => 'Receiver OffHook Tone'); + $select[] = array( 'value' => '0x2A', 'text' => 'Partial Dial Tone'); + $select[] = array( 'value' => '0x2B', 'text' => 'No Such Number Tone'); + $select[] = array( 'value' => '0x2C', 'text' => 'Busy Verification Tone'); + $select[] = array( 'value' => '0x2D', 'text' => 'Call Waiting Tone'); + $select[] = array( 'value' => '0x2E', 'text' => 'Confirmation Tone'); + $select[] = array( 'value' => '0x2F', 'text' => 'Camp On Indication Tone'); + $select[] = array( 'value' => '0x30', 'text' => 'Recall Dial Tone'); + $select[] = array( 'value' => '0x31', 'text' => 'Zip Zip'); + $select[] = array( 'value' => '0x32', 'text' => 'Zip'); + $select[] = array( 'value' => '0x33', 'text' => 'Beep Bonk'); + $select[] = array( 'value' => '0x34', 'text' => 'Music Tone'); + $select[] = array( 'value' => '0x35', 'text' => 'Hold Tone'); + $select[] = array( 'value' => '0x36', 'text' => 'Test Tone'); + $select[] = array( 'value' => '0x37', 'text' => 'DT Monitor Warning Tone'); + $select[] = array( 'value' => '0x40', 'text' => 'Add Call Waiting'); + $select[] = array( 'value' => '0x41', 'text' => 'Priority Call Wait'); + $select[] = array( 'value' => '0x42', 'text' => 'Recall Dial'); + $select[] = array( 'value' => '0x43', 'text' => 'Barg In'); + $select[] = array( 'value' => '0x44', 'text' => 'Distinct Alert'); + $select[] = array( 'value' => '0x45', 'text' => 'Priority Alert'); + $select[] = array( 'value' => '0x46', 'text' => 'Reminder Ring'); + $select[] = array( 'value' => '0x47', 'text' => 'Precedence RingBank'); + $select[] = array( 'value' => '0x48', 'text' => 'Pre-EmptionTone'); + $select[] = array( 'value' => '0x67', 'text' => '2105 HZ'); + $select[] = array( 'value' => '0x68', 'text' => '2600 HZ'); + $select[] = array( 'value' => '0x69', 'text' => '440 HZ'); + $select[] = array( 'value' => '0x6A', 'text' => '300 HZ'); + $select[] = array( 'value' => '0x77', 'text' => 'MLPP Pala'); + $select[] = array( 'value' => '0x78', 'text' => 'MLPP Ica'); + $select[] = array( 'value' => '0x79', 'text' => 'MLPP Vca'); + $select[] = array( 'value' => '0x7A', 'text' => 'MLPP Bpa'); + $select[] = array( 'value' => '0x7B', 'text' => 'MLPP Bnea'); + $select[] = array( 'value' => '0x7C', 'text' => 'MLPP Upa'); +/* !TODO!: +TODO+: I would remove the values below this line, except for 'No Tone' */ +// $select[] = array( 'value' => '0x7F', 'text' => 'No Tone'); + $select[] = array( 'value' => '0x80', 'text' => 'Meetme Greeting Tone'); + $select[] = array( 'value' => '0x81', 'text' => 'Meetme Number Invalid Tone'); + $select[] = array( 'value' => '0x82', 'text' => 'Meetme Number Failed Tone'); + $select[] = array( 'value' => '0x83', 'text' => 'Meetme Enter Pin Tone'); + $select[] = array( 'value' => '0x84', 'text' => 'Meetme Invalid Pin Tone'); + $select[] = array( 'value' => '0x85', 'text' => 'Meetme Failed Pin Tone'); + $select[] = array( 'value' => '0x86', 'text' => 'Meetme CFB Failed Tone'); + $select[] = array( 'value' => '0x87', 'text' => 'Meetme Enter Access Code Tone'); + $select[] = array( 'value' => '0x88', 'text' => 'Meetme Access Code Invalid Tone'); + $select[] = array( 'value' => '0x89', 'text' => 'Meetme Access Code Failed Tone'); + $select[] = array('value' => 'yes', 'text' => 'Yes'); + $select[] = array('value' => 'no', 'text' => 'No'); - $tt = _("Outside dialtone frequency (defaul 0x22)"); - $tmparr['secondary_dialtone_tone'] = array('prompttext' => _('Secondary dialtone'), 'value' => '0x22', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'select'); + $tt = _("Outside dialtone frequency (defaul 0x22)"); + $tmparr['secondary_dialtone_tone'] = array('prompttext' => _('Secondary dialtone'), 'value' => '0x22', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'select'); - # !TODO!: -TODO-: is there no easier way to specify a boolean radio group ? No. - unset($select); - $select[] = array('value' => 'on', 'text' => 'On'); - $select[] = array('value' => 'off', 'text' => 'Off'); - $tt = _("Allow call transfer."); - $tmparr['transfer'] = array('prompttext' => _('Call Transfer'), 'value' => 'on', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); +# !TODO!: -TODO-: is there no easier way to specify a boolean radio group ? No. + unset($select); + $select[] = array('value' => 'yes', 'text' => 'Yes'); + $select[] = array('value' => 'no', 'text' => 'No'); + $tt = _("Allow call transfer."); + $tmparr['transfer'] = array('prompttext' => _('Call Transfer'), 'value' => 'yes', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); - unset($select); - $select[] = array('value' => 'on', 'text' => 'On'); - $select[] = array('value' => 'off', 'text' => 'Off'); - $tt = _("Echo cancel"); - $tmparr['echocancel'] = array('prompttext' => _('Echo cancel'), 'value' => 'off', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); + unset($select); + $select[] = array('value' => 'yes', 'text' => 'Yes'); + $select[] = array('value' => 'no', 'text' => 'No'); + $tt = _("Echo cancel"); + $tmparr['echocancel'] = array('prompttext' => _('Echo cancel'), 'value' => 'yes', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); - unset($select); - $select[] = array('value' => 'off', 'text' => 'Off'); - $select[] = array('value' => 'reject', 'text' => 'Reject'); - $select[] = array('value' => 'silent', 'text' => 'Silent'); - $select[] = array('value' => 'UserDefined', 'text' => 'UserDefined'); - # !TODO!: -TODO-: The next entry should be "null/empty" (not UserDefined) -> to indicate the trie-state behaviour - # !TODO!: -TODO-: Userdefined is also a possible state, but it is not used or implemented (and it should not be implemented here, i think). See Sccp.class.php.v431, See Sccp.class.php - Old Style - $tt = _("DND: How will dnd react when it is set on the device level dnd can have three states: off / busy(reject) / silent / UserDefined").'
'. - _("UserDefined - dnd that cycles through all three states off -> reject -> silent -> off (this is the normal behaviour)").'
'. - _("Reject - Usesr can only switch off and on (in reject/busy mode)").'
'. - _("Silent - Usesr can only switch off and on (in silent mode)"); - $tmparr['dnd'] = array('prompttext' => _('DND'), 'value' => 'UserDefined', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); + unset($select); + $select[] = array('value' => 'off', 'text' => 'Off'); + $select[] = array('value' => 'reject', 'text' => 'Reject'); + $select[] = array('value' => 'silent', 'text' => 'Silent'); + $select[] = array('value' => 'UserDefined', 'text' => 'UserDefined'); +# !TODO!: -TODO-: The next entry should be "null/empty" (not UserDefined) -> to indicate the trie-state behaviour +# !TODO!: -TODO-: Userdefined is also a possible state, but it is not used or implemented (and it should not be implemented here, i think). See Sccp.class.php.v431, See Sccp.class.php - Old Style + $tt = _("DND: How will dnd react when it is set on the device level dnd can have three states: off / busy(reject) / silent / UserDefined").'
'. + _("UserDefined - dnd that cycles through all three states off -> reject -> silent -> off (this is the normal behaviour)").'
'. + _("Reject - Usesr can only switch off and on (in reject/busy mode)").'
'. + _("Silent - Usesr can only switch off and on (in silent mode)"); + $tmparr['dnd'] = array('prompttext' => _('DND'), 'value' => 'UserDefined', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); - unset($select); - $select[] = array('value' => 'on', 'text' => 'On'); - $select[] = array('value' => 'off', 'text' => 'Off'); - $tt = _("Silence Suppression. Asterisk Not supported"); - $tmparr['silencesuppression'] = array('prompttext' => _('Silence Suppression'), 'value' => 'off', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); + unset($select); + $select[] = array('value' => 'yes', 'text' => 'Yes'); + $select[] = array('value' => 'no', 'text' => 'No'); + $tt = _("Silence Suppression. Asterisk Not supported"); + $tmparr['silencesuppression'] = array('prompttext' => _('Silence Suppression'), 'value' => 'no', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio'); - unset($select); - $select[] = array('value' => 'default', 'text' => _('default')); - if (function_exists('music_list')){ - $moh_list = music_list(); - } else { - $moh_list = array('default'); - } - foreach ($moh_list as $value) { - $select[] = array('value' => $value, 'text' => _($value)); - } + unset($select); + $select[] = array('value' => 'default', 'text' => _('default')); + if (function_exists('music_list')){ + $moh_list = music_list(); + } else { + $moh_list = array('default'); + } + foreach ($moh_list as $value) { + $select[] = array('value' => $value, 'text' => _($value)); + } - $tt = _("Music on hold"); - $tmparr['musicclass'] = array('prompttext' => _('Music on hold'), 'value' => 'no', 'tt' => $tt, 'select' => $select, 'level' => 1); + $tt = _("Music on hold"); + $tmparr['musicclass'] = array('prompttext' => _('Music on hold'), 'value' => 'no', 'tt' => $tt, 'select' => $select, 'level' => 1); - $devopts = $tmparr; - return $devopts; - } + $devopts = $tmparr; + return $devopts; + } } diff --git a/conf/sccpgeneral.xml.v431 b/conf/sccpgeneral.xml.v431 new file mode 100644 index 0000000..226a670 --- /dev/null +++ b/conf/sccpgeneral.xml.v431 @@ -0,0 +1,1520 @@ + + + + + + XML_info + + NONE + + + + + + + + + + + + dev_sshUserId + cisco + + Help. + + + + + dev_sshPassword + cisco + + Help. + + + + + dev_deviceProtocol + SCCP + + Help. + + + + + sccp_xml_about + XML Base ver: 11.2, Sccp ver: 431 + + Help. + + + + + + + + + + + servername + Vt + + Servername: This is the type of server - usually, it will be Asterisk. + + + + + bindaddr + 0.0.0.0 + sccp-custom + + + port + 2000 + sccp-custom + + Bind Address: The address to bind to for SCCP. In general, it should be set to '0.0.0.0'. If you find problems with one-way audio, you can set this to a specific address in the server. Note that '127.0.0.1' is always wrong here. Also note that placing in your external IP address will cause the chan_sccp module to not load. A manual edit of the /etc/asterisk/sccp.conf file will be needed to fix and reload the module. + : + + + + + externip + + sccp-custom + + + External IP Address of the firewall, required in case the PBX is running on a separate host behind it. IP Address that we're going to notify in RTP media stream as the pbx source address. + / + + + + + keepalive + 60 + sccp-custom + number + + + Time between Keep Alive checks. Valid range is 60-300 seconds. After much trial-and-error, the minimum (60) seems to work just fine. + + + nat + + auto + + + + Global NAT support (default Auto) + + + debug + + NONE + + + + + + Debug: Enable debugging level in SCCP module. + + + displayconfig + + sccpgeneral + + + Help! + + + + + + + permit + Internal + 0.0.0.0/0.0.0.0 + + + + + + + + + Add Allow Range + Allow network settings. Blank fields will be ignored used Network 0.0.0.0/0.0.0.0 to resolve any existing connections. You can use the 'internal' connections only from the networks connected to the server. + + + + + + localnet + Internal + 0.0.0.0/0.0.0.0 + + + + + + + + + + + Add Internal Range + Local network settings. Blank fields will be ignored used Network 0.0.0.0. + + + + deny + 0.0.0.0/0.0.0.0 + + + + + + + + + + + Add Deny network + All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. + + + + + + + + + language + English + + SCCP Language: This is the language for your hints and other features of the phone. If you don't have any languages installed or are using a single language, you can leave this blank. + + + + netlang + English_United_States + + The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. + + + + devlang + English_United_States + + The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. + + + + + + + + + firstdigittimeout + 16 + sccp-custom + number + + + First Digit Timeout: The amount of time after your first digit to start dialing automatically. This can be over-ridden with settings in your dialplan.xml or by using the 'immediate dial' button. + + + + + digittimeout + 8 + sccp-custom + number + + + Digit Timeout: The amount of time to wait after the second (or subsequent) dialed digit. Override rules are the same as for firstdigittimeout. + + + + + autoanswer_ring_time + 0 + sccp-custom + number + + + Autoanswer Ring Time: The amount of time the phones will ring when being called as Intercom or Paging mode. + + + + + autoanswer_tone + 0x32 + sccp-custom + + Autoanswer Tone: The tone the phone plays back when it picks up the phone in autoanswer mode. Default is '0x32'. Silence is '0x00'. There are lots of tones, all expressed as '0XNN' where 'NN' is a hexadecimal number. + + + + + remotehangup_tone + 0x32 + sccp-custom + + Remote Hangup Tone: The tone played by the phone when it received a remote hang-up signal. Use '0' to disable the tone. + + + + + transfer_tone + 0x32 + sccp-custom + + Transfer Tone: The tone played when a call is transferred. Use '0' to disable the tone. + + + + + callwaiting_tone + 0x2D + sccp-custom + + Call Waiting Tone: The tone played when a call is waiting. If you set this one to '0', you will not get a tone in your current call if a new call comes in, so you might want to disable call waiting for this line instead. + + + + + directed_pickup_context + + + sccp-custom + + Context where direct pickup search for extensions. if not set current contect will be use. + + + echocancel + + off + + + Echo Cancel: Echo Cancellation (On or Off). + + + silencesuppression + + off + + + Silence Suppression: Slience Suppression on the phone. + + + private + + on + + + Private Calling Enabled: Place a call with privacy Options (no Caller ID) turned on. Needs to be supported in Asterisk to work through SIP and DAHDI trunks. + + + directed_pickup_modeanswer + + off + + + Directed Pickup Mode (Answer): If a call is sent with the "directed pickup" flag, the phone will answer when set to "Yes". + + + transfer_on_hangup + + off + + + Complete transfer on hangup, without pressing transfer a second time. Will complete transfer, when the transferer puts the receiver on hook, after the destination has been reached. To cancel the transfer, either press resume on the transferred channel, press the 'endcall' softkey, or have the receiving party hangup first. + + + callanswerorder + + oldestfirst + + + Call Answer Order: Which call should be answered first? The most common choice is "oldestfirst", but other orders are supported. + + + callhistory_answered_elsewhere + + Missed Calls + + + + + + + + mwilamp + + On + + + + + + Set the MWI lamp style when MWI active to on, off, wink, flash or blink + + + mwioncall + + off + + + Set the MWI on call. + + + + + + directrtp + + off + + + This option set global allow devices to do direct RTP sessions (default Off) + + + earlyrtp + + none + Immediate + + + + + + The audio strem will be open in the progress and connected state. Valid options: NONE, progress, offhook, dial, ringout. Default may be Progress. + + + simulate_enbloc + + on + + + Use simulated enbloc dialing to speedup connection when dialing while onhook (older phones) + + + + + + cfwdall + + off + + + Activate the callforward softkeys. Default is On + + + cfwdbusy + + off + + + Activate the callforward busy softkeys. Default is On + + + dndFeature + + on + + + Do Not Disturb. Default is Off + + + + + + + ntp_config_enabled + + off + + + Enabling NTP settings in device configuration. + + + + + ntp_server + pool.ntp.org + pool.ntp.org + + NTP Server name or IP + + + ntp_server_mode + + unicast + + + + + Configure NTP Server protocol time synchronization + + + + + + + + dateformat + + Date Format: The date format for the on-screen display. Can be one of the following: (D-M-YA, M.D.Y, Y/M/D) where 'D' is Day, 'M' is Month, 'Y' is Year, 'A' is 24-hour, 'a' is 12-hour, and the separators can be '.','-','/' + + + + ntp_timezone + sccp-custom + + Date Format: Time zone + + + + + + + + Help_srst + You can also configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. This proves especially useful in a remote site configuration where the phones and Asterisk are connected over a WAN network. SRST provides users with fallback support for the IP phones that cannot access the primary, secondary, or tertiary Asterisk Node in the CallManager List because of an Asterisk Node failure or loss of connectivity across the WAN. For the remote sites attached to multiple-service routers across the WAN, SRST ensures that your remote users receive continuous (although minimal) service by providing call handling support directly from the SRST router. + When IP phones lose contact with primary, secondary, and tertiary Asterisk Nodes (CM's), they must establish a connection to a local SRST router to sustain the call-processing capability necessary to place and receive calls. The IP phone retains the IP address of the local SRST router as a default router in the Network Configuration area of the Settings menu. The Settings menu supports a maximum of five default router entries; however, the cnf.xml accommodates a maximum of three entries. When a secondary Asterisk Node is not available on the network, the local SRST Router's IP address is retained as the standby connection for Asterisk Node during normal operation. + + + + srst_Option + + disable + + + + You enabled/configured a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. + + + srst_userModifiable + + false + + + The user can change the personal SRST configuration on the device + + + srst_isSecure + + false + + + The user can change the personal SRST configuration on the device + + + + + + srst_Name + Enable + + You enabled configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. + + + + + srst_ip + 3 + / + + + + + + + + + Add Server + Help. + + + + srst_sip + 3 + / + + + + + + + + + Add Server + Help. + + + + + + + + + dev_servicesURL + + + + + + + + + + + dev_authenticationURL + + + + + The above is simply a dummy authentication page. It literally contains one word: AUTHORIZED (it receives UserId, Password, and devicename in the url - if you truly wish to implement special auth) + + + + + dev_idleURL + + + + + URL of CiscoIPPhoneImage. Requires a non-zero setting in idleTimeout. + + + + + dev_informationURL + + + + + + + + + dev_messagesURL + + + + + + + + + dev_directoryURL + + + + This is the URL for a CiscoIPPhoneMenu which gets appended to the end of the Missed/Received/Placed calls. I don't use it (I find it makes more sense to put my phone book under services) + + + + + dev_proxyServerURL + + + + + + + + + + + dev_idleTimeout + 60 + sccp-custom + number + + + + + + + + + + + + sccp_tos + 0x68 + sccp-custom + + + sccp_cos + 0x4 + sccp-custom + + SCCP Type Of Service / Class Of Service: SCCP Type or Class of Service - this is modifiable, but don't. + + + + + audio_tos + 0xB8 + sccp-custom + + + audio_cos + 0x6 + sccp-custom + + Audio Type Of Service / Class Of Service: Audio Type or Class of Service - this is modifiable, but don't. + + + + + video_tos + 0x88 + sccp-custom + + + video_cos + 0x5 + sccp-custom + + Video Type Of Service / Class Of Service: Video Type or Class of Service - this is modifiable, but don't. + + + + + + Help_id2 + + Setting the hotline Feature on a device, will make it connect to a predefined extension as soon as the Receiver is picked up or the "New Call" Button is pressed. No number has to be given. This works even on devices which have no entry in the config file or realtime database. + The hotline function can be used in : + + + First time configuration + This will make it easier to register new devices and assign numbers + + + At a door + Where you want people to be able to only call one number + + + For unprovisioned phones + To only be able to call the helpdesk to get their phone set up + + + + Be careful with this function. Especially not to the internet. So i would restring the deny/permit to 'internal' by default in that case. + + + Allow = + Specify a list of your networks, for example: 192.168.1.0 + + + deny = + 0.0.0.0/0.0.0.0 + + + permit = + internal + + + hotline_context = + sccp + + + hotline_label = + hotline + + + + + + + hotline_enabled + + off + + + Hotline Enabled: This allows unregistered extensions to connect to the system and dial the number listed below. + + + + + hotline_extension + *111 + sccp-custom + + Hotline Extension: The number that gets called when a hotline is picked up. hint + + + + + hotline_label + Hot Line + sccp-custom + + Hotline Label: The label on the device + + + + + hotline_context + default + sccp-custom + + Hotline Context: This is the context through which the phone will connect. It should probably match your other contest. The default is "from-internal" but "from-internal-xfer" would also make sense by limiting the options for the person using the phone. + + + + + context + from-internal + sccp-custom + + Context: This is the context in which your phones will operate. It should match the context you are using for the rest of your phones (if you have any). The FreePBX default is 'from-internal' + + + + + regcontext + sccpregistration + sccp-custom + + If regcontext is specified in sccp.conf chan-sccp-b will dynamically create and destroy a NoOp priority 1 extension for a given peer/line which registers with the server. If the context is not specified in extension.conf, then it will be dynamically created when an chan-sccp-b agent registers + + + + musicclass + NONE + + form-control + Music Class: Available MOH Classes. These are the MOH classes listed in your current server. + + + + dial_template + NONE + + sccp-custom + Help. + + + autoselectline_enabled + + off + + + Enables and Disables auto line selection. + + + meetme + + off + + + Enable/Disable conferencing via meetme (on/off), make sure you have one of the meetme apps mentioned below activated in module.conf + + + + + meetmeopts + qxd + sccp-custom + + Other options (app_meetme: A,a,b,c,C,d,D,E,e,F,i,I,l,L,m,M,o,p,P,q,r,s,S,t,T,w,x,X,1) see meetme specific documentation + + + + autocall_select + + off + + + + + + backgroundImageAccess + + true + + + I'm guessing on this one, but on some devices, the background image on the display can be modified at the device. I think this is the thing that allows that to take. + + + phonePersonalization + + 0 + + + Phone personalization needs to be set to allow the server to push background or ringtones to the phone in the SEPXXXXXXXXXX.cnf.xml of each phone: + + + callLogBlfEnabled + + 2 + + + Which does show numbers you can redial, but also include their current device state, so you know when they are currently busy. Note that the other phonebook entries will now also monitor the remove device state and show the current device state + + + + + + + Help_tftp_rewrite + This section is responsible for the modes of operation of external services: tftp http. + * off - Flat model cisco. All data is in the directory /tftproot + * Custom - The directory structure is strictly defined in the manager (for internal use). Requires tftpd rewrite support. + * Provision - Directory structure data is read from an external file. This project supports phones that can work on tftp and http. Support rewrite. + + + + + provision_hide + + tftp_path + /tftpboot + sccp-custom + + Path to tftp home directory + + + + provision_show + + tftp_rewrite_path + /tftpboot + sccp-custom + + Use path from provision index.cnf file. You must first make sure that you have properly configured the "Provision" + + + + tftp_rewrite + + off + pro + pro + + Internal + + + Support the use of regular-expression-based filename remapping + + + + + devicetable + sccpdevice + + + sccp-custom + Device Table: This is the devicetable for your realtime configuration. Don't change this unless you know what you are doing and have made all the appropriate changes in the rest of your Asterisk config files. There are two reasonable settings for this - the sccpdevice table or the sccpdeviceconfig view. If you do not want to use the realtime database anymore, you can set this to blank. NOT RECOMMENDED. + + + + + + linetable + sccpline + sccp-custom + + Line Table: This is the linetable for your realtime configuration. Don't change this unless you know what you are doing and have made all the appropriate changes in the rest of your Asterisk config files. If you do not want to use the realtime database anymore, you can set this to blank. NOT RECOMMENDED. + + + + createlangdir + + no + + + Say 'yes' if you need to create cisco default language directory in tftp path. + + + + + + + + + + mac + 000000000 + sccp-custom + + The MAC address of the phone. You must specify 12 characters in the format XXXX.XXXX.XXXX or XX-XX-XX-XX-XX-XX or XXXXXXXXXXXX + + + + + type + 7911 + + hw_select sccp-custom + The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. + + + + addon + NONE + + hw_select sccp-custom + Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. + + + + + + + + + mac + 000000000 + sccp-custom + + + The MAC address of the phone + + + + type + 7911 + + + hw_select sccp-custom + The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. + + + + + + type + 79XX + sccp-custom + + + The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. + + + + + addon + NONE + sccp-custom + + + Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. + + + + + + + + + + description + 000000000 + sccp-custom + + + The information in the upper right corner of the device screen. Only English letters and digits ! + + + + softkeyset + default + + System Default Softkey + + + + tzoffset + 00 + + Time Zone offset + + + + netlang + English_United_States + + The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. + + + + devlang + Russian_Russia + + The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. + + + + + backgroundImage + + sccp-custom + + For phones that can display background images - display this one. Default is [empty] + + + + + ringtone + + sccp-custom + + The ringtone that the phone will default to. Can be overridden in the phone. The files RINGLIST.XML provice the basic phone ring tones, while DISTINCTIVERINGLIST.XML defines the list of possible ring tones for your other line types. They, along with the actual 'raw' ringtones, are stored in the /tftpboot/ringtones directory with the rest of the config files. + + + + + + + + + mac + 000000000 + sccp-custom + + + + + + + + + transfer + + off + + + Transfer allowed + + + cfwdall + + NONE + + + + Activate the callforward softkeys. Default is On + + + cfwdbusy + + NONE + + + + Activate the callforward busy softkeys. Default is On + + + dndFeature + + NONE + + + + Do Not Disturb. Default is Off + + + directed_pickup + + on + off + + + Enable Pickup function to direct pickup an extension. Default is On + + + conf_allow + + on + off + + + Allow the use of conference + + + + + + pickup_hide + + + + directed_pickup_context + + sccp-custom + + Context where direct pickup search for extensions. if not set current contact will be use. + + + directed_pickup_modeanswer + + on + + + On (Default)= the call has been answered when picked up. Off = call manager way, the phone who picked up the call rings the call + Options: 'Immediate Answer' or 'Show CallerID' ?????? + + + + + + + useRedialMenu + + off + + + You can specifying 'useRedialMenu = yes' in the sccp.conf device section and the redial softkey will cause the "placed calls" list instead of immediately calling the last dialed number. + + + force_dtmfmode + + auto + + + + Some phone models with bad firmware do send dtmf in a messed up order and need to be forced to skinny mode. + + + mwioncall + + NONE + + + + Set the MWI on call. + + + + mwilamp + + NONE + + + + + + + Set the MWI lamp style when MWI active to on, off, wink, flash or blink + + + + + conf_hide + + + conf_play_general_announce + + on + + + Playback General Announcements (like: 'You are Entering/Leaving the conference') + + + conf_play_part_announce + + on + + + Playback Personal/Participant Announcements, (like: 'You have been muted / You have been kicked') + + + conf_mute_on_entry + + off + + + Mute new participants from the start + + + conf_show_conflist + + on + + + Automatically show conference list to the moderator + + + + conf_music_on_hold_class + default + + form-control + Play music on hold of this class when no moderator is listening on the conference. If set to an empty string, no music on hold will be played. + + + + + + custom_network_acc + + permit + + + + Help. + + + custom_network_type + + ipv4 + + + Help. + + + + + custom_network_v + + + sccp-custom + + + custom_network_m + + sccp-custom + + + Help. + + + + + + + + + deny + / + sccp_hw_net_inherit + + + + + + + + + Add Deny network + All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. + + + + + + permit + NONE + Inherit + false + + sccp_hw-ar_permit-grinternal + + sccp_hw_net_inherit + + + + + + + + + Add Allow network + Allow network settings. Blank fields will be ignored used Network 0.0.0.0. + + + + nat + + NONE + + + + + Device NAT support (default Auto) + + + + directrtp + + NONE + Auto + + + + This option allow devices to do direct RTP sessions (default Off) + + + earlyrtp + + NONE + + Immediate + + + + + + The audio stream will be open in the progress and connected state. Valid options: none, progress, offhook, dial, ringout. Default may be Progress. + + + + + + + dialtemplate_name + + form-control + + Help. + + + + + + + + Help_id1 + Specifies a pattern to match dialed digits against. Note: TEMPLATE must be in uppercase. + Rules: + + + match: + Pattern to match, consists of one or more elements + + + 0 1 2 3 4 5 6 7 8 9 + Match digit + + + . + Match one digit, # or * + + + * + Match zero or more digits, # or * + + + \* + Match a literal * + + + , + Play secondary dial-tone specified by tone + + + timeout: + Number of seconds to wait for more digits if this pattern matches + + + line: + Only apply template to the specified line (optional) + + + rewrite: + Rewrite the matched digits before dialing, consists of one or more elements (optional) + + + 0 1 2 3 4 5 6 7 8 9 + Replace with digit + + + %0 + The entire match + + + %1 %2 %3 %4 %5 + Replace with group of digits matched, grouping is done by consecutive literal digit or . elements + + + %% + A literal % + + + . + Each . is replaced by the digit that was matched by the corresponding . in the pattern + + + tone: + Secondary dial-tone to play when a , is matched, up to 3 can be specified (optional) + + + + + + dialtemplate + */10/* + + title + + + + + + + + text1 + + + + + + empty + Bellcore-Alerting + Bellcore-Inside + Bellcore-Outside + Bellcore-Busy + Bellcore-BusyVerify + Bellcore-Reorder + Bellcore-CallWaiting + Bellcore-Hold + Bellcore-Reminder + Bellcore-Confirmation + Bellcore-Stutter + Bellcore-Permanent + Bellcore-None + Cisco-Zip + Cisco-ZipZip + Cisco-BeepBonk + Bellcore-dr1 + Bellcore-dr2 + Bellcore-dr3 + Bellcore-dr4 + Bellcore-dr5 + Bellcore-dr6 + CallWaiting-2 + CallWaiting-3 + CallWaiting-4 + + Allow network settings. Blank fields will be ignored used Network 0.0.0.0. + + + + + diff --git a/conf/sccpgeneral.xml.v433 b/conf/sccpgeneral.xml.v433 index 698f0d6..f734102 100644 --- a/conf/sccpgeneral.xml.v433 +++ b/conf/sccpgeneral.xml.v433 @@ -3,34 +3,34 @@ To change this license header, choose License Headers in Project Properties. To change this template file, choose Tools | Templates and open the template in the editor. Base Version before all crash :-) - * IE - Text Input + * IE - Text Input * IED - Text Input Dynamic * ITED- Input Dynamic Table * IS - Radio box - * SL - Select element + * SL - Select element * SLA - Select element (from - data ) - * Input element Select SLD - Date format - * SLZ - Time Zone + * Input element Select SLD - Date format + * SLZ - Time Zone * SLTZN - Time Zone List * SLT - TFTP Lang - * SLM - Music on hold + * SLM - Music on hold * SLK - System KeySet - * * Input element Select SLS - System Language - * Input element Select SDM - Model List + * * Input element Select SLS - System Language + * Input element Select SDM - Model List * SDE - Extension List tftp_rewrite * Help elemen HLP - Help Element - + --> - XML_info + XML_info NONE - + @@ -67,7 +67,7 @@ and open the template in the editor. Base Version before all crash :-) Help.
- + @@ -76,36 +76,36 @@ and open the template in the editor. Base Version before all crash :-) - servername + servername Vt Servername: This is the type of server - usually, it will be Asterisk. - + - bindaddr + bindaddr 0.0.0.0 sccp-custom - port + port 2000 sccp-custom Bind Address: The address to bind to for SCCP. In general, it should be set to '0.0.0.0'. If you find problems with one-way audio, you can set this to a specific address in the server. Note that '127.0.0.1' is always wrong here. Also note that placing in your external IP address will cause the chan_sccp module to not load. A manual edit of the /etc/asterisk/sccp.conf file will be needed to fix and reload the module. : - + - externip + externip 0.0.0.0 sccp-custom - externhost + externhost sccp-custom @@ -116,7 +116,7 @@ and open the template in the editor. Base Version before all crash :-) / externhost - + @@ -129,16 +129,16 @@ and open the template in the editor. Base Version before all crash :-) Time between Keep Alive checks. Valid range is 60-300 seconds. After much trial-and-error, the minimum (60) seems to work just fine. - nat + nat auto Global NAT support (default Auto) - + - debug + debug NONE @@ -150,7 +150,7 @@ and open the template in the editor. Base Version before all crash :-) Debug: Enable debugging level in SCCP module. - displayconfig + displayconfig sccpgeneral @@ -158,7 +158,7 @@ and open the template in the editor. Base Version before all crash :-) Help! - siptftp + siptftp off @@ -177,7 +177,7 @@ and open the template in the editor. Base Version before all crash :-) - + + Add Allow Range @@ -195,7 +195,7 @@ and open the template in the editor. Base Version before all crash :-) - + + @@ -243,30 +243,30 @@ and open the template in the editor. Base Version before all crash :-) - language + language English SCCP Language: This is the language for your hints and other features of the phone. If you don't have any languages installed or are using a single language, you can leave this blank. - netlang + netlang English_United_States The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. - devlang + devlang English_United_States The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. - - + + - + firstdigittimeout @@ -277,10 +277,10 @@ and open the template in the editor. Base Version before all crash :-) First Digit Timeout: The amount of time after your first digit to start dialing automatically. This can be over-ridden with settings in your dialplan.xml or by using the 'immediate dial' button. - + - digittimeout + digittimeout 8 sccp-custom number @@ -291,7 +291,7 @@ and open the template in the editor. Base Version before all crash :-) - cfwdnoanswer_timeout + cfwdnoanswer_timeout 30 sccp-custom number @@ -302,7 +302,7 @@ and open the template in the editor. Base Version before all crash :-) - autoanswer_ring_time + autoanswer_ring_time 0 sccp-custom number @@ -313,7 +313,7 @@ and open the template in the editor. Base Version before all crash :-) - autoanswer_tone + autoanswer_tone 0x32 sccp-custom @@ -322,7 +322,7 @@ and open the template in the editor. Base Version before all crash :-) - remotehangup_tone + remotehangup_tone 0x32 sccp-custom @@ -331,7 +331,7 @@ and open the template in the editor. Base Version before all crash :-) - transfer_tone + transfer_tone 0x32 sccp-custom @@ -340,14 +340,14 @@ and open the template in the editor. Base Version before all crash :-) - callwaiting_tone + callwaiting_tone 0x2D sccp-custom Call Waiting Tone: The tone played when a call is waiting. If you set this one to '0', you will not get a tone in your current call if a new call comes in, so you might want to disable call waiting for this line instead. - echocancel + echocancel off @@ -355,15 +355,15 @@ and open the template in the editor. Base Version before all crash :-) Echo Cancel: Echo Cancellation (On or Off). - silencesuppression - + silencesuppression + off Silence Suppression: Slience Suppression on the phone. - private + private on @@ -371,7 +371,7 @@ and open the template in the editor. Base Version before all crash :-) Private Calling Enabled: Place a call with privacy Options (no Caller ID) turned on. Needs to be supported in Asterisk to work through SIP and DAHDI trunks. - callanswerorder + callanswerorder oldestfirst @@ -379,7 +379,7 @@ and open the template in the editor. Base Version before all crash :-) Call Answer Order: Which call should be answered first? The most common choice is "oldestfirst", but other orders are supported. - callhistory_answered_elsewhere + callhistory_answered_elsewhere Missed Calls @@ -389,7 +389,7 @@ and open the template in the editor. Base Version before all crash :-) - mwilamp + mwilamp On @@ -400,19 +400,19 @@ and open the template in the editor. Base Version before all crash :-) Set the MWI lamp style when MWI active to on, off, wink, flash or blink - mwioncall + mwioncall off Set the MWI on call. - - + + - directrtp + directrtp off @@ -420,7 +420,7 @@ and open the template in the editor. Base Version before all crash :-) This option set global allow devices to do direct RTP sessions (default Off) - earlyrtp + earlyrtp none Immediate @@ -432,18 +432,18 @@ and open the template in the editor. Base Version before all crash :-) The audio strem will be open in the progress and connected state. Valid options: NONE, progress, offhook, dial, ringout. Default may be Progress. - simulate_enbloc + simulate_enbloc on Use simulated enbloc dialing to speedup connection when dialing while onhook (older phones) - + - cfwdall + cfwdall off @@ -451,7 +451,7 @@ and open the template in the editor. Base Version before all crash :-) Activate the callforward softkeys. Default is On - cfwdbusy + cfwdbusy off Call Forward @@ -459,7 +459,7 @@ and open the template in the editor. Base Version before all crash :-) Activate the callforward busy softkeys. Default is On - cfwdnoanswer + cfwdnoanswer off @@ -467,7 +467,7 @@ and open the template in the editor. Base Version before all crash :-) Activate the callforward NOANSWER stuff and softkeys. Default is On - dndFeature + dndFeature on @@ -475,19 +475,19 @@ and open the template in the editor. Base Version before all crash :-) Do Not Disturb. Default is Off - transfer + transfer on Allow the use of the transfer feature - - +
+ - ntp_config_enabled + ntp_config_enabled off @@ -497,14 +497,14 @@ and open the template in the editor. Base Version before all crash :-) - ntp_server + ntp_server pool.ntp.org pool.ntp.org NTP Server name or IP - ntp_server_mode + ntp_server_mode unicast @@ -514,12 +514,12 @@ and open the template in the editor. Base Version before all crash :-) Configure NTP Server protocol time synchronization - + - dateformat + dateformat @@ -527,61 +527,61 @@ and open the template in the editor. Base Version before all crash :-) - ntp_timezone + ntp_timezone sccp-custom Date Format: Time zone - - + + - + - vendorconfig_logserver + vendorconfig_logserver sccp-custom Log server Address: x.x.x.x:9001 - + - vendorconfig_daysdisplaynotactive + vendorconfig_daysdisplaynotactive sccp-custom Comma separated list of days that the phone's display is not active and will be automatically turned off after the time specified by "displayIdleTimeout" has elapsed (1 - Sunday, 7 - Saturday) - + - vendorconfig_displayontime + vendorconfig_displayontime sccp-custom Time in HH:MM format to automatically turn on the phone display. - + - vendorconfig_displayonduration + vendorconfig_displayonduration sccp-custom Time duration in HH:MM format to automatically turn off the phone display after it was turned on. - + - vendorconfig_displayidletimeout + vendorconfig_displayidletimeout sccp-custom @@ -590,7 +590,7 @@ and open the template in the editor. Base Version before all crash :-) - vendorconfig_settingsaccess + vendorconfig_settingsaccess @@ -599,7 +599,7 @@ and open the template in the editor. Base Version before all crash :-) Whether a user can access the phone settings. - vendorconfig_videocapability + vendorconfig_videocapability @@ -608,7 +608,7 @@ and open the template in the editor. Base Version before all crash :-) - vendorconfig_webaccess + vendorconfig_webaccess @@ -617,7 +617,7 @@ and open the template in the editor. Base Version before all crash :-) Enable the phone's HTTP server. - vendorconfig_webadmin + vendorconfig_webadmin @@ -626,7 +626,7 @@ and open the template in the editor. Base Version before all crash :-) Enable remote administration using the phone's HTTP server. 8821 model only. - vendorconfig_pcport + vendorconfig_pcport @@ -635,7 +635,7 @@ and open the template in the editor. Base Version before all crash :-) Disable the PC (computer) port - vendorconfig_spantopcport + vendorconfig_spantopcport @@ -644,7 +644,7 @@ and open the template in the editor. Base Version before all crash :-) Forward packets sent and received on the SW (network) port to the PC (computer) port. - vendorconfig_voicevlanaccess + vendorconfig_voicevlanaccess @@ -653,7 +653,7 @@ and open the template in the editor. Base Version before all crash :-) Allow devices connected to the PC (computer) port to access the voice VLAN. - vendorconfig_enablecdpswport + vendorconfig_enablecdpswport @@ -662,7 +662,7 @@ and open the template in the editor. Base Version before all crash :-) Enable Cisco Discovery Protocol on the SW (network) port. - vendorconfig_enablecdppcport + vendorconfig_enablecdppcport @@ -671,7 +671,7 @@ and open the template in the editor. Base Version before all crash :-) Enable Cisco Discovery Protocol on the PC (computer) port. - vendorconfig_enablelldpswport + vendorconfig_enablelldpswport @@ -680,7 +680,7 @@ and open the template in the editor. Base Version before all crash :-) Enable Link Layer Discovery Protocol on the SW (network) port. - vendorconfig_enablelldppcport + vendorconfig_enablelldppcport @@ -688,21 +688,21 @@ and open the template in the editor. Base Version before all crash :-) Enable Link Layer Discovery Protocol on the PC (computer) port. - - - - + + + + - + Help_srst You can also configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. This proves especially useful in a remote site configuration where the phones and Asterisk are connected over a WAN network. SRST provides users with fallback support for the IP phones that cannot access the primary, secondary, or tertiary Asterisk Node in the CallManager List because of an Asterisk Node failure or loss of connectivity across the WAN. For the remote sites attached to multiple-service routers across the WAN, SRST ensures that your remote users receive continuous (although minimal) service by providing call handling support directly from the SRST router. When IP phones lose contact with primary, secondary, and tertiary Asterisk Nodes (CM's), they must establish a connection to a local SRST router to sustain the call-processing capability necessary to place and receive calls. The IP phone retains the IP address of the local SRST router as a default router in the Network Configuration area of the Settings menu. The Settings menu supports a maximum of five default router entries; however, the cnf.xml accommodates a maximum of three entries. When a secondary Asterisk Node is not available on the network, the local SRST Router's IP address is retained as the standby connection for Asterisk Node during normal operation. - srst_Option + srst_Option disable @@ -711,7 +711,7 @@ and open the template in the editor. Base Version before all crash :-) You enabled/configured a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. - srst_userModifiable + srst_userModifiable false @@ -719,7 +719,7 @@ and open the template in the editor. Base Version before all crash :-) The user can change the personal SRST configuration on the device - srst_isSecure + srst_isSecure false @@ -730,7 +730,7 @@ and open the template in the editor. Base Version before all crash :-) - srst_Name + srst_Name Enable You enabled configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. @@ -746,7 +746,7 @@ and open the template in the editor. Base Version before all crash :-) - + Add Server @@ -762,40 +762,40 @@ and open the template in the editor. Base Version before all crash :-) - + Add Server Help. - + - dev_servicesURL + dev_servicesURL - + - dev_secureservicesURL + dev_secureservicesURL - + - dev_authenticationURL + dev_authenticationURL @@ -805,7 +805,7 @@ and open the template in the editor. Base Version before all crash :-) - dev_secureauthenticationURL + dev_secureauthenticationURL @@ -886,7 +886,7 @@ and open the template in the editor. Base Version before all crash :-) - + @@ -897,7 +897,7 @@ and open the template in the editor. Base Version before all crash :-) - + @@ -909,58 +909,58 @@ and open the template in the editor. Base Version before all crash :-) - - - + + + - + - sccp_tos + sccp_tos 0x68 sccp-custom - sccp_cos + sccp_cos 0x4 sccp-custom SCCP Type Of Service / Class Of Service: SCCP Type or Class of Service - this is modifiable, but don't. - + - audio_tos + audio_tos 0xB8 sccp-custom - audio_cos + audio_cos 0x6 sccp-custom Audio Type Of Service / Class Of Service: Audio Type or Class of Service - this is modifiable, but don't. - + - video_tos + video_tos 0x88 sccp-custom - video_cos + video_cos 0x5 sccp-custom Video Type Of Service / Class Of Service: Video Type or Class of Service - this is modifiable, but don't. - + Help_id2 - + Setting the hotline Feature on a device, will make it connect to a predefined extension as soon as the Receiver is picked up or the "New Call" Button is pressed. No number has to be given. This works even on devices which have no entry in the config file or realtime database. The hotline function can be used in : @@ -1001,11 +1001,11 @@ and open the template in the editor. Base Version before all crash :-) hotline - + - + - hotline_enabled + hotline_enabled off @@ -1015,7 +1015,7 @@ and open the template in the editor. Base Version before all crash :-) - hotline_extension + hotline_extension *111 sccp-custom @@ -1024,7 +1024,7 @@ and open the template in the editor. Base Version before all crash :-) - hotline_label + hotline_label Hot Line sccp-custom @@ -1033,20 +1033,20 @@ and open the template in the editor. Base Version before all crash :-) - hotline_context + hotline_context default sccp-custom Hotline Context: This is the context through which the phone will connect. It should probably match your other contest. The default is "from-internal" but "from-internal-xfer" would also make sense by limiting the options for the person using the phone. - + - context + context from-internal sccp-custom @@ -1055,7 +1055,7 @@ and open the template in the editor. Base Version before all crash :-) - regcontext + regcontext sccpregistration sccp-custom @@ -1064,7 +1064,7 @@ and open the template in the editor. Base Version before all crash :-) - directed_pickup_context + directed_pickup_context sccp-custom @@ -1074,16 +1074,16 @@ and open the template in the editor. Base Version before all crash :-) - pickupgroup + pickupgroup sccp-custom Context where direct pickup search for extensions. if not set current contect will be use. - + - pickup_modeanswer + pickup_modeanswer off @@ -1091,7 +1091,7 @@ and open the template in the editor. Base Version before all crash :-) Directed Pickup Mode (Answer): If a call is sent with the "directed pickup" flag, the phone will answer when set to "Yes". - transfer_on_hangup + transfer_on_hangup off @@ -1101,14 +1101,14 @@ and open the template in the editor. Base Version before all crash :-) - dial_template + dial_template NONE sccp-custom Help. - autoselectline_enabled + autoselectline_enabled off @@ -1116,7 +1116,7 @@ and open the template in the editor. Base Version before all crash :-) Enables and Disables auto line selection. - meetme + meetme off @@ -1126,7 +1126,7 @@ and open the template in the editor. Base Version before all crash :-) - meetmeopts + meetmeopts qxd sccp-custom @@ -1134,7 +1134,7 @@ and open the template in the editor. Base Version before all crash :-) - autocall_select + autocall_select off @@ -1142,7 +1142,7 @@ and open the template in the editor. Base Version before all crash :-) - backgroundImageAccess + backgroundImageAccess true @@ -1150,7 +1150,7 @@ and open the template in the editor. Base Version before all crash :-) I'm guessing on this one, but on some devices, the background image on the display can be modified at the device. I think this is the thing that allows that to take. - phonePersonalization + phonePersonalization 0 @@ -1158,7 +1158,7 @@ and open the template in the editor. Base Version before all crash :-) Phone personalization needs to be set to allow the server to push background or ringtones to the phone in the SEPXXXXXXXXXX.cnf.xml of each phone: - callLogBlfEnabled + callLogBlfEnabled 2 @@ -1167,7 +1167,7 @@ and open the template in the editor. Base Version before all crash :-) - musicclass + musicclass NONE form-control @@ -1178,7 +1178,7 @@ and open the template in the editor. Base Version before all crash :-) - + Help_tftp_rewrite This section is responsible for the modes of operation of external services: tftp http. * off - Flat model cisco. All data is in the directory /tftproot @@ -1190,7 +1190,7 @@ and open the template in the editor. Base Version before all crash :-) provision_hide - tftp_path + tftp_path /tftpboot sccp-custom @@ -1200,7 +1200,7 @@ and open the template in the editor. Base Version before all crash :-) provision_show - tftp_rewrite_path + tftp_rewrite_path /tftpboot sccp-custom @@ -1208,7 +1208,7 @@ and open the template in the editor. Base Version before all crash :-) - tftp_rewrite + tftp_rewrite off pro @@ -1222,7 +1222,7 @@ and open the template in the editor. Base Version before all crash :-) - devicetable + devicetable sccpdevice @@ -1233,7 +1233,7 @@ and open the template in the editor. Base Version before all crash :-) - linetable + linetable sccpline sccp-custom @@ -1241,7 +1241,7 @@ and open the template in the editor. Base Version before all crash :-) - createlangdir + createlangdir no @@ -1250,28 +1250,28 @@ and open the template in the editor. Base Version before all crash :-) - system_rouminguser + system_rouminguser no Experemental Function Roaming Users - + - + - mac + mac 000000000 sccp-custom The MAC address of the phone. You must specify 12 characters in the format XXXX.XXXX.XXXX or XX-XX-XX-XX-XX-XX or XXXXXXXXXXXX - + type @@ -1282,7 +1282,7 @@ and open the template in the editor. Base Version before all crash :-) - addon + addon NONE hw_select sccp-custom @@ -1295,13 +1295,13 @@ and open the template in the editor. Base Version before all crash :-) - mac + mac 000000000 sccp-custom The MAC address of the phone - + type @@ -1315,7 +1315,7 @@ and open the template in the editor. Base Version before all crash :-) - type + type 79XX sccp-custom @@ -1325,7 +1325,7 @@ and open the template in the editor. Base Version before all crash :-) - addon + addon NONE sccp-custom @@ -1336,11 +1336,11 @@ and open the template in the editor. Base Version before all crash :-) - + - _description + _description 000000000 sccp-custom @@ -1349,28 +1349,28 @@ and open the template in the editor. Base Version before all crash :-) - softkeyset + softkeyset default System Default Softkey - tzoffset + tzoffset 00 Time Zone offset - netlang + netlang English_United_States The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. - devlang + devlang Russian_Russia The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. @@ -1378,7 +1378,7 @@ and open the template in the editor. Base Version before all crash :-) - backgroundImage + backgroundImage sccp-custom @@ -1387,40 +1387,40 @@ and open the template in the editor. Base Version before all crash :-) - ringtone + ringtone sccp-custom The ringtone that the phone will default to. Can be overridden in the phone. The files RINGLIST.XML provice the basic phone ring tones, while DISTINCTIVERINGLIST.XML defines the list of possible ring tones for your other line types. They, along with the actual 'raw' ringtones, are stored in the /tftpboot/ringtones directory with the rest of the config files. - + - mac + mac 000000000 sccp-custom - + - transfer + transfer - off - + NONE + Transfer allowed - park + park on Inherit @@ -1429,58 +1429,58 @@ and open the template in the editor. Base Version before all crash :-) Take a look to the compile how-to. Park stuff is not compiled by default. - cfwdall + cfwdall - off - + NONE + Activate the callforward softkeys. Default is On - cfwdbusy + cfwdbusy - off - + NONE + Activate the callforward busy softkeys. Default is On - cfwdnoanswer + cfwdnoanswer - on - + NONE + Activate the callforward NOANSWER stuff and softkeys. Default is On - dndFeature + dndFeature - off - + NONE + Do Not Disturb. Default is Off - conf_allow + conf_allow on off Allow the use of conference - + - - + + - + - useRedialMenu + useRedialMenu off @@ -1488,7 +1488,7 @@ and open the template in the editor. Base Version before all crash :-) You can specifying 'useRedialMenu = yes' in the sccp.conf device section and the redial softkey will cause the "placed calls" list instead of immediately calling the last dialed number. - force_dtmfmode + force_dtmfmode auto @@ -1497,29 +1497,29 @@ and open the template in the editor. Base Version before all crash :-) Some phone models with bad firmware do send dtmf in a messed up order and need to be forced to skinny mode. - mwioncall + mwioncall - on - + NONE + Set the MWI on call. - - - mwilamp + + + mwilamp - on - + NONE + Set the MWI lamp style when MWI active to on, off, wink, flash or blink - + - callhistory_answered_elsewhere + callhistory_answered_elsewhere Missed Calls @@ -1528,14 +1528,14 @@ and open the template in the editor. Base Version before all crash :-) - + - + conf_hide - conf_play_general_announce + conf_play_general_announce on @@ -1543,7 +1543,7 @@ and open the template in the editor. Base Version before all crash :-) Playback General Announcements (like: 'You are Entering/Leaving the conference') - conf_play_part_announce + conf_play_part_announce on @@ -1551,7 +1551,7 @@ and open the template in the editor. Base Version before all crash :-) Playback Personal/Participant Announcements, (like: 'You have been muted / You have been kicked') - conf_mute_on_entry + conf_mute_on_entry off @@ -1559,7 +1559,7 @@ and open the template in the editor. Base Version before all crash :-) Mute new participants from the start - conf_show_conflist + conf_show_conflist on @@ -1568,7 +1568,7 @@ and open the template in the editor. Base Version before all crash :-) - conf_music_on_hold_class + conf_music_on_hold_class default form-control @@ -1578,41 +1578,41 @@ and open the template in the editor. Base Version before all crash :-) - custom_network_acc + custom_network_acc permit Help. - + - custom_network_type + custom_network_type ipv4 Help. - + - custom_network_v + custom_network_v sccp-custom - custom_network_m + custom_network_m sccp-custom Help. - + - + @@ -1629,7 +1629,7 @@ and open the template in the editor. Base Version before all crash :-) + Add Deny network All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. - + @@ -1646,18 +1646,18 @@ and open the template in the editor. Base Version before all crash :-) - - + + + Add Allow network Allow network settings. Blank fields will be ignored used Network 0.0.0.0. - nat + nat - auto - + NONE + @@ -1665,17 +1665,17 @@ and open the template in the editor. Base Version before all crash :-) - directrtp + directrtp - off - Auto - + NONE + Auto + This option allow devices to do direct RTP sessions (default Off) - earlyrtp + earlyrtp NONE @@ -1692,18 +1692,18 @@ and open the template in the editor. Base Version before all crash :-) - dialtemplate_name + dialtemplate_name name_ruls form-control Help. - + - + Help_id1 Specifies a pattern to match dialed digits against. Note: TEMPLATE must be in uppercase. Rules: @@ -1788,7 +1788,7 @@ and open the template in the editor. Base Version before all crash :-) - + empty Bellcore-Alerting Bellcore-Inside @@ -1817,11 +1817,11 @@ and open the template in the editor. Base Version before all crash :-) CallWaiting-4 Allow network settings. Blank fields will be ignored used Network 0.0.0.0. - + - + - @@ -1829,18 +1829,18 @@ and open the template in the editor. Base Version before all crash :-) - id + id 000000000 sccp-custom Help! - + - description + description Help! @@ -1848,7 +1848,7 @@ and open the template in the editor. Base Version before all crash :-) - pin + pin Help! @@ -1856,13 +1856,13 @@ and open the template in the editor. Base Version before all crash :-) - password + password Help! - roaminglogin + roaminglogin off @@ -1871,7 +1871,7 @@ and open the template in the editor. Base Version before all crash :-) - auto_logout + auto_logout off @@ -1881,20 +1881,20 @@ and open the template in the editor. Base Version before all crash :-) - homedevice + homedevice NONE sccp-custom Help! - - work_time + work_time off @@ -1905,7 +1905,7 @@ and open the template in the editor. Base Version before all crash :-) - work_group + work_group Help! @@ -1913,25 +1913,25 @@ and open the template in the editor. Base Version before all crash :-) - time_extend + time_extend 30 Help! - + - mac + mac 000000000 sccp-custom The MAC address of the phone. You must specify 12 characters in the format XXXX.XXXX.XXXX or XX-XX-XX-XX-XX-XX or XXXXXXXXXXXX - + type @@ -1942,7 +1942,7 @@ and open the template in the editor. Base Version before all crash :-) - addon + addon NONE hw_select sccp-custom @@ -1951,19 +1951,19 @@ and open the template in the editor. Base Version before all crash :-) - + - _dialrules + _dialrules dialplan Dial templates control what number patterns are valid and how many seconds to wait for extra digits before dialing. - + - + setvar @@ -1974,7 +1974,7 @@ and open the template in the editor. Base Version before all crash :-) + - + - + diff --git a/conf/sccpsimple.xml.v431 b/conf/sccpsimple.xml.v431 new file mode 100644 index 0000000..d4eee57 --- /dev/null +++ b/conf/sccpsimple.xml.v431 @@ -0,0 +1,1523 @@ + + + + + + XML_info + + NONE + + + + + + + + + + + + dev_sshUserId + cisco + + Help. + + + + + dev_sshPassword + cisco + + Help. + + + + + dev_deviceProtocol + SCCP + + Help. + + + + + sccp_xml_about + XML Base ver: 11.2, Sccp ver: 431 + + Help. + + + + + autoanswer_tone + 0x32 + sccp-custom + + Autoanswer Tone: The tone the phone plays back when it picks up the phone in autoanswer mode. Default is '0x32'. Silence is '0x00'. There are lots of tones, all expressed as '0XNN' where 'NN' is a hexadecimal number. + + + + + remotehangup_tone + 0x32 + sccp-custom + + Remote Hangup Tone: The tone played by the phone when it received a remote hang-up signal. Use '0' to disable the tone. + + + + + transfer_tone + 0x32 + sccp-custom + + Transfer Tone: The tone played when a call is transferred. Use '0' to disable the tone. + + + + + callwaiting_tone + 0x2D + sccp-custom + + Call Waiting Tone: The tone played when a call is waiting. If you set this one to '0', you will not get a tone in your current call if a new call comes in, so you might want to disable call waiting for this line instead. + + + + + + + sccp_tos + 0x68 + sccp-custom + + + sccp_cos + 0x4 + sccp-custom + + SCCP Type Of Service / Class Of Service: SCCP Type or Class of Service - this is modifiable, but don't. + + + + + audio_tos + 0xB8 + sccp-custom + + + audio_cos + 0x6 + sccp-custom + + Audio Type Of Service / Class Of Service: Audio Type or Class of Service - this is modifiable, but don't. + + + + + video_tos + 0x88 + sccp-custom + + + video_cos + 0x5 + sccp-custom + + Video Type Of Service / Class Of Service: Video Type or Class of Service - this is modifiable, but don't. + + + + + + linetable + sccpline + sccp-custom + + Line Table: This is the linetable for your realtime configuration. Don't change this unless you know what you are doing and have made all the appropriate changes in the rest of your Asterisk config files. If you do not want to use the realtime database anymore, you can set this to blank. NOT RECOMMENDED. + + + + devicetable + sccpdevice + + + sccp-custom + Device Table: This is the devicetable for your realtime configuration. Don't change this unless you know what you are doing and have made all the appropriate changes in the rest of your Asterisk config files. There are two reasonable settings for this - the sccpdevice table or the sccpdeviceconfig view. If you do not want to use the realtime database anymore, you can set this to blank. NOT RECOMMENDED. + + + callhistory_answered_elsewhere + + Missed Calls + + + + + + + + + + + + + + + + + + + + + + + + + servername + Vt + + Servername: This is the type of server - usually, it will be Asterisk. + + + + + bindaddr + 0.0.0.0 + sccp-custom + + + port + 2000 + sccp-custom + + Bind Address: The address to bind to for SCCP. In general, it should be set to '0.0.0.0'. If you find problems with one-way audio, you can set this to a specific address in the server. Note that '127.0.0.1' is always wrong here. Also note that placing in your external IP address will cause the chan_sccp module to not load. A manual edit of the /etc/asterisk/sccp.conf file will be needed to fix and reload the module. + : + + + + + externip + + sccp-custom + + + External IP Address of the firewall, required in case the PBX is running on a separate host behind it. IP Address that we're going to notify in RTP media stream as the pbx source address. + / + + + + + keepalive + 60 + sccp-custom + number + + + Time between Keep Alive checks. Valid range is 60-300 seconds. After much trial-and-error, the minimum (60) seems to work just fine. + + + nat + + auto + + + + Global NAT support (default Auto) + + + debug + + NONE + + + + + + Debug: Enable debugging level in SCCP module. + + + displayconfig + + sccpgeneral + + + Help! + + + + + + + permit + Internal + 0.0.0.0/0.0.0.0 + + + + + + + + + Add Allow Range + Allow network settings. Blank fields will be ignored used Network 0.0.0.0/0.0.0.0 to resolve any existing connections. You can use the 'internal' connections only from the networks connected to the server. + + + + + + localnet + Internal + 0.0.0.0/0.0.0.0 + + + + + + + + + + + Add Internal Range + Local network settings. Blank fields will be ignored used Network 0.0.0.0. + + + + deny + 0.0.0.0/0.0.0.0 + + + + + + + + + + + Add Deny network + All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. + + + + + + + + + language + English + + SCCP Language: This is the language for your hints and other features of the phone. If you don't have any languages installed or are using a single language, you can leave this blank. + + + + netlang + English_United_States + + The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. + + + + devlang + English_United_States + + The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. + + + + + + + + + firstdigittimeout + 16 + sccp-custom + number + + + First Digit Timeout: The amount of time after your first digit to start dialing automatically. This can be over-ridden with settings in your dialplan.xml or by using the 'immediate dial' button. + + + + + digittimeout + 8 + sccp-custom + number + + + Digit Timeout: The amount of time to wait after the second (or subsequent) dialed digit. Override rules are the same as for firstdigittimeout. + + + + + autoanswer_ring_time + 0 + sccp-custom + number + + + Autoanswer Ring Time: The amount of time the phones will ring when being called as Intercom or Paging mode. + + + + + directed_pickup_context + + + sccp-custom + + Context where direct pickup search for extensions. if not set current contect will be use. + + + echocancel + + off + + + Echo Cancel: Echo Cancellation (On or Off). + + + silencesuppression + + off + + + Silence Suppression: Slience Suppression on the phone. + + + private + + on + + + Private Calling Enabled: Place a call with privacy Options (no Caller ID) turned on. Needs to be supported in Asterisk to work through SIP and DAHDI trunks. + + + directed_pickup_modeanswer + + off + + + Directed Pickup Mode (Answer): If a call is sent with the "directed pickup" flag, the phone will answer when set to "Yes". + + + transfer_on_hangup + + off + + + Complete transfer on hangup, without pressing transfer a second time. Will complete transfer, when the transferer puts the receiver on hook, after the destination has been reached. To cancel the transfer, either press resume on the transferred channel, press the 'endcall' softkey, or have the receiving party hangup first. + + + callanswerorder + + oldestfirst + + + Call Answer Order: Which call should be answered first? The most common choice is "oldestfirst", but other orders are supported. + + + mwilamp + + On + + + + + + Set the MWI lamp style when MWI active to on, off, wink, flash or blink + + + mwioncall + + off + + + Set the MWI on call. + + + + + + + directrtp + + off + + + This option set global allow devices to do direct RTP sessions (default Off) + + + earlyrtp + + none + Immediate + + + + + + The audio strem will be open in the progress and connected state. Valid options: NONE, progress, offhook, dial, ringout. Default may be Progress. + + + simulate_enbloc + + on + + + Use simulated enbloc dialing to speedup connection when dialing while onhook (older phones) + + + + + + cfwdall + + off + + + Activate the callforward softkeys. Default is On + + + cfwdbusy + + off + + + Activate the callforward busy softkeys. Default is On + + + dndFeature + + on + + + Do Not Disturb. Default is Off + + + + + + + ntp_config_enabled + + off + + + Enabling NTP settings in device configuration. + + + + + ntp_server + pool.ntp.org + pool.ntp.org + + NTP Server name or IP + + + ntp_server_mode + + unicast + + + + + Configure NTP Server protocol time synchronization + + + + + + + + dateformat + + Date Format: The date format for the on-screen display. Can be one of the following: (D-M-YA, M.D.Y, Y/M/D) where 'D' is Day, 'M' is Month, 'Y' is Year, 'A' is 24-hour, 'a' is 12-hour, and the separators can be '.','-','/' + + + + ntp_timezone + sccp-custom + + Date Format: Time zone + + + + + + + + Help_srst + You can also configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. This proves especially useful in a remote site configuration where the phones and Asterisk are connected over a WAN network. SRST provides users with fallback support for the IP phones that cannot access the primary, secondary, or tertiary Asterisk Node in the CallManager List because of an Asterisk Node failure or loss of connectivity across the WAN. For the remote sites attached to multiple-service routers across the WAN, SRST ensures that your remote users receive continuous (although minimal) service by providing call handling support directly from the SRST router. + When IP phones lose contact with primary, secondary, and tertiary Asterisk Nodes (CM's), they must establish a connection to a local SRST router to sustain the call-processing capability necessary to place and receive calls. The IP phone retains the IP address of the local SRST router as a default router in the Network Configuration area of the Settings menu. The Settings menu supports a maximum of five default router entries; however, the cnf.xml accommodates a maximum of three entries. When a secondary Asterisk Node is not available on the network, the local SRST Router's IP address is retained as the standby connection for Asterisk Node during normal operation. + + + + srst_Option + + disable + + + + You enabled/configured a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. + + + srst_userModifiable + + false + + + The user can change the personal SRST configuration on the device + + + srst_isSecure + + false + + + The user can change the personal SRST configuration on the device + + + + + + srst_Name + Enable + + You enabled configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. + + + + + srst_ip + 3 + / + + + + + + + + + Add Server + Help. + + + + srst_sip + 3 + / + + + + + + + + + Add Server + Help. + + + + + + + + + dev_servicesURL + + + + + + + + + + + dev_authenticationURL + + + + + The above is simply a dummy authentication page. It literally contains one word: AUTHORIZED (it receives UserId, Password, and devicename in the url - if you truly wish to implement special auth) + + + + + dev_idleURL + + + + + URL of CiscoIPPhoneImage. Requires a non-zero setting in idleTimeout. + + + + + dev_informationURL + + + + + + + + + dev_messagesURL + + + + + + + + + dev_directoryURL + + + + This is the URL for a CiscoIPPhoneMenu which gets appended to the end of the Missed/Received/Placed calls. I don't use it (I find it makes more sense to put my phone book under services) + + + + + dev_proxyServerURL + + + + + + + + + + + dev_idleTimeout + 60 + sccp-custom + number + + + + + + + + + + + Help_id2 + + Setting the hotline Feature on a device, will make it connect to a predefined extension as soon as the Receiver is picked up or the "New Call" Button is pressed. No number has to be given. This works even on devices which have no entry in the config file or realtime database. + The hotline function can be used in : + + + First time configuration + This will make it easier to register new devices and assign numbers + + + At a door + Where you want people to be able to only call one number + + + For unprovisioned phones + To only be able to call the helpdesk to get their phone set up + + + + Be careful with this function. Especially not to the internet. So i would restring the deny/permit to 'internal' by default in that case. + + + Allow = + Specify a list of your networks, for example: 192.168.1.0 + + + deny = + 0.0.0.0/0.0.0.0 + + + permit = + internal + + + hotline_context = + sccp + + + hotline_label = + hotline + + + + + + + hotline_enabled + + off + + + Hotline Enabled: This allows unregistered extensions to connect to the system and dial the number listed below. + + + + + hotline_extension + *111 + sccp-custom + + Hotline Extension: The number that gets called when a hotline is picked up. hint + + + + + hotline_label + Hot Line + sccp-custom + + Hotline Label: The label on the device + + + + + hotline_context + default + sccp-custom + + Hotline Context: This is the context through which the phone will connect. It should probably match your other contest. The default is "from-internal" but "from-internal-xfer" would also make sense by limiting the options for the person using the phone. + + + + + context + from-internal + sccp-custom + + Context: This is the context in which your phones will operate. It should match the context you are using for the rest of your phones (if you have any). The FreePBX default is 'from-internal' + + + + + regcontext + sccpregistration + sccp-custom + + If regcontext is specified in sccp.conf chan-sccp-b will dynamically create and destroy a NoOp priority 1 extension for a given peer/line which registers with the server. If the context is not specified in extension.conf, then it will be dynamically created when an chan-sccp-b agent registers + + + + musicclass + NONE + + form-control + Music Class: Available MOH Classes. These are the MOH classes listed in your current server. + + + + dial_template + NONE + + sccp-custom + Help. + + + autoselectline_enabled + + off + + + Enables and Disables auto line selection. + + + meetme + + off + + + Enable/Disable conferencing via meetme (on/off), make sure you have one of the meetme apps mentioned below activated in module.conf + + + + + meetmeopts + qxd + sccp-custom + + Other options (app_meetme: A,a,b,c,C,d,D,E,e,F,i,I,l,L,m,M,o,p,P,q,r,s,S,t,T,w,x,X,1) see meetme specific documentation + + + + autocall_select + + off + + + + + + backgroundImageAccess + + true + + + I'm guessing on this one, but on some devices, the background image on the display can be modified at the device. I think this is the thing that allows that to take. + + + phonePersonalization + + 0 + + + Phone personalization needs to be set to allow the server to push background or ringtones to the phone in the SEPXXXXXXXXXX.cnf.xml of each phone: + + + callLogBlfEnabled + + 2 + + + Which does show numbers you can redial, but also include their current device state, so you know when they are currently busy. Note that the other phonebook entries will now also monitor the remove device state and show the current device state + + + + + + + + provision_hide + + tftp_path + /tftpboot + sccp-custom + + Path to tftp home directory + + + + provision_show + + tftp_rewrite_path + /tftpboot + sccp-custom + + Use path from provision index.cnf file. You must first make sure that you have properly configured the "Provision" + + + + tftp_rewrite + + off + pro + pro + + Internal + + + Support the use of regular-expression-based filename remapping + + + + + createlangdir + + no + + + Say 'yes' if you need to create cisco default language directory in tftp path. + + + + + + + + + + mac + 000000000 + sccp-custom + + The MAC address of the phone. You must specify 12 characters in the format XXXX.XXXX.XXXX or XX-XX-XX-XX-XX-XX or XXXXXXXXXXXX + + + + + type + 7911 + + hw_select sccp-custom + The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. + + + + addon + NONE + + hw_select sccp-custom + Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. + + + + + + + + + mac + 000000000 + sccp-custom + + + The MAC address of the phone + + + + type + 7911 + + + hw_select sccp-custom + The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. + + + + + + type + 79XX + sccp-custom + + + The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. + + + + + addon + NONE + sccp-custom + + + Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. + + + + + + + + + + description + 000000000 + sccp-custom + + + The information in the upper right corner of the device screen. Only English letters and digits ! + + + + softkeyset + default + + System Default Softkey + + + + tzoffset + 00 + + Time Zone offset + + + + netlang + English_United_States + + The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. + + + + devlang + Russian_Russia + + The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. + + + + + backgroundImage + + sccp-custom + + For phones that can display background images - display this one. Default is [empty] + + + + + ringtone + + sccp-custom + + The ringtone that the phone will default to. Can be overridden in the phone. The files RINGLIST.XML provice the basic phone ring tones, while DISTINCTIVERINGLIST.XML defines the list of possible ring tones for your other line types. They, along with the actual 'raw' ringtones, are stored in the /tftpboot/ringtones directory with the rest of the config files. + + + + + + + + + mac + 000000000 + sccp-custom + + + + + + + + + transfer + + off + + + Transfer allowed + + + cfwdall + + NONE + + + + Activate the callforward softkeys. Default is On + + + cfwdbusy + + NONE + + + + Activate the callforward busy softkeys. Default is On + + + dndFeature + + NONE + + + + Do Not Disturb. Default is Off + + + directed_pickup + + on + off + + + Enable Pickup function to direct pickup an extension. Default is On + + + conf_allow + + on + off + + + Allow the use of conference + + + + + + pickup_hide + + + + directed_pickup_context + + sccp-custom + + Context where direct pickup search for extensions. if not set current contact will be use. + + + directed_pickup_modeanswer + + on + + + On (Default)= the call has been answered when picked up. Off = call manager way, the phone who picked up the call rings the call + Options: 'Immediate Answer' or 'Show CallerID' ?????? + + + + + + + useRedialMenu + + off + + + You can specifying 'useRedialMenu = yes' in the sccp.conf device section and the redial softkey will cause the "placed calls" list instead of immediately calling the last dialed number. + + + + force_dtmfmode + + auto + + + + Some phone models with bad firmware do send dtmf in a messed up order and need to be forced to skinny mode. + + + mwioncall + + NONE + + + + Set the MWI on call. + + + + mwilamp + + NONE + + + + + + + Set the MWI lamp style when MWI active to on, off, wink, flash or blink + + + + + conf_hide + + + conf_play_general_announce + + on + + + Playback General Announcements (like: 'You are Entering/Leaving the conference') + + + conf_play_part_announce + + on + + + Playback Personal/Participant Announcements, (like: 'You have been muted / You have been kicked') + + + conf_mute_on_entry + + off + + + Mute new participants from the start + + + conf_show_conflist + + on + + + Automatically show conference list to the moderator + + + + conf_music_on_hold_class + default + + form-control + Play music on hold of this class when no moderator is listening on the conference. If set to an empty string, no music on hold will be played. + + + + + + custom_network_acc + + permit + + + + Help. + + + custom_network_type + + ipv4 + + + Help. + + + + + custom_network_v + + + sccp-custom + + + custom_network_m + + sccp-custom + + + Help. + + + + + + + + + deny + / + sccp_hw_net_inherit + + + + + + + + + Add Deny network + All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. + + + + + + permit + NONE + Inherit + false + + sccp_hw-ar_permit-grinternal + + sccp_hw_net_inherit + + + + + + + + + Add Allow network + Allow network settings. Blank fields will be ignored used Network 0.0.0.0. + + + + nat + + NONE + + + + + Device NAT support (default Auto) + + + + directrtp + + NONE + Auto + + + + This option allow devices to do direct RTP sessions (default Off) + + + earlyrtp + + NONE + + Immediate + + + + + + The audio stream will be open in the progress and connected state. Valid options: none, progress, offhook, dial, ringout. Default may be Progress. + + + + + + + dialtemplate_name + + form-control + + Help. + + + + + + + + Help_id1 + Specifies a pattern to match dialed digits against. Note: TEMPLATE must be in uppercase. + Rules: + + + match: + Pattern to match, consists of one or more elements + + + 0 1 2 3 4 5 6 7 8 9 + Match digit + + + . + Match one digit, # or * + + + * + Match zero or more digits, # or * + + + \* + Match a literal * + + + , + Play secondary dial-tone specified by tone + + + timeout: + Number of seconds to wait for more digits if this pattern matches + + + line: + Only apply template to the specified line (optional) + + + rewrite: + Rewrite the matched digits before dialing, consists of one or more elements (optional) + + + 0 1 2 3 4 5 6 7 8 9 + Replace with digit + + + %0 + The entire match + + + %1 %2 %3 %4 %5 + Replace with group of digits matched, grouping is done by consecutive literal digit or . elements + + + %% + A literal % + + + . + Each . is replaced by the digit that was matched by the corresponding . in the pattern + + + tone: + Secondary dial-tone to play when a , is matched, up to 3 can be specified (optional) + + + + + + dialtemplate + */10/* + + title + + + + + + + + text1 + + + + + + empty + Bellcore-Alerting + Bellcore-Inside + Bellcore-Outside + Bellcore-Busy + Bellcore-BusyVerify + Bellcore-Reorder + Bellcore-CallWaiting + Bellcore-Hold + Bellcore-Reminder + Bellcore-Confirmation + Bellcore-Stutter + Bellcore-Permanent + Bellcore-None + Cisco-Zip + Cisco-ZipZip + Cisco-BeepBonk + Bellcore-dr1 + Bellcore-dr2 + Bellcore-dr3 + Bellcore-dr4 + Bellcore-dr5 + Bellcore-dr6 + CallWaiting-2 + CallWaiting-3 + CallWaiting-4 + + Allow network settings. Blank fields will be ignored used Network 0.0.0.0. + + + + + diff --git a/functions.inc.php b/functions.inc.php new file mode 100644 index 0000000..8271339 --- /dev/null +++ b/functions.inc.php @@ -0,0 +1,88 @@ +parentNode->removeChild($dom); + } + + function replaceSimpleXmlNode($xml, SimpleXMLElement $element) { + $dom = dom_import_simplexml($xml); + $import = $dom->ownerDocument->importNode( + dom_import_simplexml($element),TRUE + ); + $dom->parentNode->replaceChild($import, $dom); + } + + */ +/* +function after($thing, $inthat) +{ + if (!is_bool(strpos($inthat, $thing))) { + return substr($inthat, strpos($inthat, $thing) + strlen($thing)); + } +} + +function after_last($thing, $inthat) +{ + if (!is_bool(strrevpos($inthat, $thing))) { + return substr($inthat, strrevpos($inthat, $thing) + strlen($thing)); + } +} +function before($thing, $inthat) +{ + return substr($inthat, 0, strpos($inthat, $thing)); +} + +function before_last($thing, $inthat) +{ + return substr($inthat, 0, strrevpos($inthat, $thing)); +} + +function between($thing, $that, $inthat) +{ + return before($that, after($thing, $inthat)); +} + +function between_last($thing, $that, $inthat) +{ + return after_last($thing, before_last($that, $inthat)); +} + +function strrevpos($instr, $needle) +{ + $rev_pos = strpos(strrev($instr), strrev($needle)); + if ($rev_pos === false) { + return false; + } else { + return strlen($instr) - $rev_pos - strlen($needle); + } +} + +function strpos_array($haystack, $needles) +{ + if (is_array($needles)) { + foreach ($needles as $str) { + if (is_array($str)) { + $pos = strpos_array($haystack, $str); + } else { + $pos = strpos($haystack, $str); + } + if ($pos !== false) { + return $pos; + } + } + } else { + return strpos($haystack, $needles); + } + return false; +} + * + * +*/ diff --git a/install.php b/install.php index 9aa2329..b21ada7 100644 --- a/install.php +++ b/install.php @@ -1,4 +1,11 @@ Sccp_manager; - -$class = "\\FreePBX\\Modules\\Sccp_manager\\aminterface"; +$class = "\\FreePBX\\Modules\\Sccp_manager\\srvinterface"; if (!class_exists($class, false)) { - include(__DIR__ . "/sccpManClasses/aminterface.class.php"); + include(__DIR__ . "/Sccp_manager.inc/srvinterface.class.php"); } if (class_exists($class, false)) { - $aminterface = new $class(); + $srvinterface = new $class(); } - -$sccp_version = CheckChanSCCPCompatible(); -$sccp_compatible = $sccp_version[0]; -$chanSCCPWarning = $sccp_version[1] ^= 1; -outn("
  • " . _("Sccp model Compatible code : ") . $resultReturned[0] . "
  • "); -if ($sccp_compatible == 0) { - outn("
    "); - outn("Chan Sccp not Found. Install it before continuing !"); - die(); -} -$db_config = Get_DB_config($sccp_compatible); -$sccp_db_ver = CheckSCCPManagerDBVersion(); - -// BackUp Old config -CreateBackUpConfig(); -RenameConfig(); - -InstallDB_updateSchema($db_config); -$stmt = $db->prepare('SELECT CASE WHEN EXISTS(SELECT 1 FROM sccpdevmodel) THEN 0 ELSE 1 END AS IsEmpty;'); -$stmt->execute(); -$result = $stmt->fetchAll(\PDO::FETCH_ASSOC); -if ($result[0]['IsEmpty']) { - outn("Populating sccpdevmodel..."); - InstallDB_fillsccpdevmodel(); -} -if (!$sccp_db_ver) { - InstallDB_updateSccpDevice(); -} else { - outn("Skip update Device model"); -} - -InstallDB_createButtonConfigTrigger(); -InstallDB_CreateSccpDeviceConfigView($sccp_compatible); -InstallDB_updateDBVer($sccp_compatible); -if ($chanSCCPWarning) { - outn("
    "); - outn("Error: installed version of chan-sccp is not compatible. Please upgrade chan-sccp"); -} -if (!$sccp_db_ver) { - Setup_RealTime(); - outn("
    "); - outn("Install Complete !"); -} else { - outn("
    "); - outn("Update Complete !"); -} -outn("
    "); - -// Functions follow - function Get_DB_config($sccp_compatible) { global $mobile_hw; + $db_config_v0 = array( + 'sccpdevmodel' => array( + 'enabled' => array('create' => "INT(2) NULL DEFAULT '0'"), + 'nametemplate' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL'), + 'loadinformationid' => array('create' => "VARCHAR(30) NULL DEFAULT NULL") + ), + 'sccpdevice' => array( + '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), + //'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_hwlang`"), + //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), + 'deny' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), + 'permit' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), + 'backgroundImage' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), + 'ringtone' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), +// 'force_dtmfmode' => array('create' => "VARCHAR(10) default 'auto'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'auto'), + 'transfer' => array('def_modify' => "on"), + 'cfwdall' => array('def_modify' => "on"), + 'cfwdbusy' => array('def_modify' => "on"), + 'directrtp' => array('def_modify' => "off"), + 'dndFeature' => array('def_modify' => "on"), + 'earlyrtp' => array('def_modify' => "on"), + 'audio_tos' => array('def_modify' => "0xB8"), + 'audio_cos' => array('def_modify' => "6"), + 'video_tos' => array('def_modify' => "0x88"), + 'video_cos' => array('def_modify' => "5"), + 'mwilamp' => array('def_modify' => "on"), + 'mwioncall' => array('def_modify' => "on"), + 'private' => array('def_modify' => "on"), + 'privacy' => array('def_modify' => "off"), + 'nat' => array('def_modify' => "auto"), + 'softkeyset' => array('def_modify' => "softkeyset") + ), + 'sccpline' => array( + 'namedcallgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `setvar`", 'modify' => "VARCHAR(100)"), + 'namedpickupgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `namedcallgroup`", 'modify' => "VARCHAR(100)"), + 'adhocNumber' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `namedpickupgroup`"), + 'meetme' => array('create' => "VARCHAR(5) NULL DEFAULT NULL AFTER `adhocNumber`"), + 'meetmenum' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetme`"), + 'meetmeopts' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmenum`"), + 'regexten' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmeopts`"), + 'incominglimit' => array('def_modify' => "2"), + 'transfer' => array('def_modify' => "on"), + 'vmnum' => array('def_modify' => "*97"), + 'musicclass' => array('def_modify' => "default"), + 'echocancel' => array('def_modify' => "on"), + 'silencesuppression' => array('def_modify' => "off"), + 'id' => array('create' => 'VARCHAR( 20 ) NULL DEFAULT NULL', 'modify' => "VARCHAR(20)", 'def_modify' => "NULL"), + 'dnd' => array('create' => 'VARCHAR( 12 ) DEFAULT "reject" AFTER `amaflags`', 'modify' => "VARCHAR(12)", 'def_modify' => "reject") + ) + ); + /* Old */ + $db_config_v_test = array( + 'sccpdevmodel' => array( + 'enabled' => array('create' => "INT(2) NULL DEFAULT '0'"), + 'nametemplate' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL'), + 'loadinformationid' => array('create' => "VARCHAR(30) NULL DEFAULT NULL") + ), + 'sccpdevice' => array( + 'pickupexten' => array('rename' => "directed_pickup"), + 'directed_pickup' => array('create' => "VARCHAR(5) NULL DEFAULT 'yes'"), + 'pickupcontext' => array('rename' => "directed_pickup_context"), + 'directed_pickup_context' => array('create' => "VARCHAR(100) NULL DEFAULT NULL"), + 'pickupmodeanswer' => array('rename' => "directed_pickup_modeanswer"), + 'directed_pickup_modeanswer' => array('create' => "VARCHAR(5) NULL DEFAULT 'yes'"), + 'hwlang' => array('rename' => "_hwlang"), + '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), + 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_hwlang`"), + //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), + 'dtmfmode' => array('drop' => "yes"), +// 'force_dtmfmode' => array('create' => "ENUM('auto','rfc2833','skinny') NOT NULL default 'auto'", 'modify' => "ENUM('auto','rfc2833','skinny')", 'def_modify'=> 'auto'), + 'deny' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), + 'permit' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), + 'backgroundImage' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), + 'ringtone' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), + 'transfer' => array('create' => 'VARCHAR(5) DEFAULT "on"', 'modify' => "VARCHAR(5)", 'def_modify' => "on"), + 'cfwdall' => array('create' => 'VARCHAR(5) NULL DEFAULT "on"', 'modify' => "VARCHAR(5)", 'def_modify' => "on"), + 'cfwdbusy' => array('create' => 'VARCHAR(5) NULL DEFAULT "on"', 'modify' => "VARCHAR(5)", 'def_modify' => "on"), + 'directrtp' => array('create' => 'VARCHAR(3) NULL DEFAULT "off"', 'modify' => "VARCHAR(3)", 'def_modify' => "off"), + 'dndFeature' => array('create' => 'VARCHAR(5) NULL DEFAULT "on"', 'modify' => "VARCHAR(5)", 'def_modify' => "on"), + 'earlyrtp' => array('create' => 'VARCHAR(10) NULL DEFAULT "progress"', 'modify' => "VARCHAR(10)", 'def_modify' => "progress"), + 'audio_tos' => array('def_modify' => "0xB8"), + 'audio_cos' => array('def_modify' => "6"), + 'video_tos' => array('def_modify' => "0x88"), + 'video_cos' => array('def_modify' => "5"), + 'trustphoneip' => array('drop' => "yes"), + 'mwilamp' => array('create' => 'VARCHAR(5) DEFAULT "on"', 'modify' => "VARCHAR(5)", 'def_modify' => "on"), + 'mwioncall' => array('create' => 'VARCHAR(5) DEFAULT "off"', 'modify' => "VARCHAR(5)", 'def_modify' => "off"), + 'private' => array('create' => 'VARCHAR(5) DEFAULT "on"', 'modify' => "VARCHAR(5)", 'def_modify' => "on"), + 'privacy' => array('create' => 'VARCHAR(100) DEFAULT "full"', 'modify' => "VARCHAR(5)", 'def_modify' => "full"), + 'nat' => array('create' => 'VARCHAR(7) DEFAULT "auto"', 'modify' => "VARCHAR(7)", 'def_modify' => "auto"), + 'softkeyset' => array('def_modify' => "softkeyset") + ), + 'sccpline' => array( + 'namedcallgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `setvar`", 'modify' => "VARCHAR(100)"), + 'namedpickupgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `namedcallgroup`", 'modify' => "VARCHAR(100)"), + 'adhocNumber' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `namedpickupgroup`"), + 'meetme' => array('create' => "VARCHAR(5) NULL DEFAULT NULL AFTER `adhocNumber`"), + 'meetmenum' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetme`"), + 'meetmeopts' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmenum`"), + 'regexten' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmeopts`"), + 'rtptos' => array('drop' => "yes"), + 'audio_tos' => array('drop' => "yes"), + 'audio_cos' => array('drop' => "yes"), + 'video_tos' => array('drop' => "yes"), + 'video_cos' => array('drop' => "yes"), + 'incominglimit' => array('def_modify' => "2"), + 'transfer' => array('def_modify' => "on"), + 'vmnum' => array('def_modify' => "*97"), + 'musicclass' => array('def_modify' => "default"), + 'echocancel' => array('def_modify' => "on"), + 'silencesuppression' => array('def_modify' => "off"), + 'dnd' => array('create' => 'VARCHAR( 12 ) DEFAULT "reject" AFTER `amaflags`', 'modify' => "VARCHAR(12)", 'def_modify' => "reject") + ) + ); + + $db_config_v3 = array( + 'sccpdevmodel' => array( + 'enabled' => array('create' => "INT(2) NULL DEFAULT '0'"), + 'nametemplate' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL'), + 'loadinformationid' => array('create' => "VARCHAR(30) NULL DEFAULT NULL") + ), + 'sccpdevice' => array( + 'pickupexten' => array('rename' => "directed_pickup"), + 'directed_pickup' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'pickupcontext' => array('rename' => "directed_pickup_context"), + 'directed_pickup_context' => array('create' => "VARCHAR(100) NULL DEFAULT NULL"), + 'pickupmodeanswer' => array('rename' => "directed_pickup_modeanswer"), + 'directed_pickup_modeanswer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'description' => array('rename' => "_description"), + 'hwlang' => array('rename' => "_hwlang"), + '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), + '_loginname' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_hwlang`'), + '_profileid' => array('create' => "INT(11) NOT NULL DEFAULT '0' AFTER `_loginname`"), + + 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_profileid`"), + //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), + 'dtmfmode' => array('drop' => "yes"), +// 'force_dtmfmode' => array('create' => "VARCHAR(10) default 'auto'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'auto'), + 'force_dtmfmode' => array('create' => "ENUM('auto','rfc2833','skinny') NOT NULL default 'auto'", 'modify' => "ENUM('auto','rfc2833','skinny')", 'def_modify'=> 'auto'), + 'deny' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), + 'permit' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), + 'backgroundImage' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), + 'ringtone' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), + 'transfer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'cfwdall' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'cfwdbusy' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'directrtp' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), + 'dndFeature' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), + 'earlyrtp' => array('create' => "ENUM('immediate','offHook','dialing','ringout','progress','none') NULL default NULL", 'modify' => "ENUM('immediate','offHook','dialing','ringout','progress','none')"), + 'audio_tos' => array('def_modify' => "0xB8"), + 'audio_cos' => array('def_modify' => "6"), + 'video_tos' => array('def_modify' => "0x88"), + 'video_cos' => array('def_modify' => "5"), + 'trustphoneip' => array('drop' => "yes"), + 'mwilamp' => array('create' => "enum('on','off','wink','flash','blink') NULL default 'on'", 'modify' => "enum('on','off','wink','flash','blink')"), + 'mwioncall' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'private' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), // Что-то лишенне + 'privacy' => array('create' => "enum('full','on','off') NOT NULL default 'full'", 'modify' => "enum('full','on','off')"), // Что-то лишенне + 'nat' => array('create' => "enum('on','off','auto') NULL default NULL", 'modify' => "enum('on','off','auto')"), + 'conf_allow' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'conf_play_part_announce' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'conf_mute_on_entry' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'conf_show_conflist' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'type' => array('create' => 'VARCHAR(15) NULL DEFAULT NULL', 'modify' => "VARCHAR(15)"), + 'imageversion' => array('create' => 'VARCHAR(31) NULL DEFAULT NULL', 'modify' => "VARCHAR(31)"), + 'softkeyset' => array('def_modify' => "softkeyset") + ), + 'sccpline' => array( + 'namedcallgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `setvar`", 'modify' => "VARCHAR(100)"), + 'namedpickupgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `namedcallgroup`", 'modify' => "VARCHAR(100)"), + 'adhocNumber' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `namedpickupgroup`"), + 'meetme' => array('create' => "VARCHAR(5) NULL DEFAULT NULL AFTER `adhocNumber`"), + 'meetmenum' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetme`"), + 'meetmeopts' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmenum`"), + 'regexten' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmeopts`"), + 'rtptos' => array('drop' => "yes"), + 'audio_tos' => array('drop' => "yes"), + 'audio_cos' => array('drop' => "yes"), + 'video_tos' => array('drop' => "yes"), + 'video_cos' => array('drop' => "yes"), + 'phonecodepage' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL', 'modify' => "VARCHAR(50)"), + 'incominglimit' => array('create' => "INT(11) DEFAULT '6'", 'modify' => 'INT(11)', 'def_modify' => "6"), + 'transfer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'vmnum' => array('def_modify' => "*97"), + 'musicclass' => array('def_modify' => "default"), + 'id' => array('create' => 'MEDIUMINT(9) NOT NULL AUTO_INCREMENT, ADD UNIQUE(id);', 'modify' => "MEDIUMINT(9)", 'index' => 'id'), +// 'id' =>array('create' => 'VARCHAR( 20 ) NULL DEFAULT NULL', 'modify' => "VARCHAR(20)", 'def_modify' =>"NULL"), + 'echocancel' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'silencesuppression' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'dnd' => array('create' => "enum('off','reject','silent','user') NOT NULL default 'reject'", 'modify' => "enum('off','reject','silent','user')", 'def_modify' => "reject") + ) + ); + // Software mobile $db_config_v4 = array( 'sccpdevmodel' => array( @@ -100,8 +239,7 @@ function Get_DB_config($sccp_compatible) 'pickupmodeanswer' => array('drop' => "yes"), 'disallow' => array('drop' => "yes"), 'disallow' => array('drop' => "yes"), - 'callhistory_answered_elsewhere' => array('create' => "enum('Ignore','Missed Calls','Received Calls', 'Placed Calls') NOT NULL default 'Ignore'", - 'modify' => "enum('Ignore','Missed Calls','Received Calls','Placed Calls')"), + 'callhistory_answered_elsewhere' => array('create' => "enum('Ignore','Missed Calls','Received Calls', 'Placed Calls') NULL default NULL", 'modify' => "enum('Ignore','Missed Calls','Received Calls','Placed Calls')"), 'description' => array('rename' => "_description"), 'hwlang' => array('rename' => "_hwlang"), @@ -111,38 +249,35 @@ function Get_DB_config($sccp_compatible) '_dialrules' => array('create' => "VARCHAR(255) NULL DEFAULT NULL AFTER `_profileid`"), 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_dialrules`"), + //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), 'dtmfmode' => array('drop' => "yes"), - 'force_dtmfmode' => array('create' => "ENUM('auto','rfc2833','skinny') NOT NULL default 'auto'", - 'modify' => "ENUM('auto','rfc2833','skinny')", 'def_modify'=> 'auto'), +// 'force_dtmfmode' => array('create' => "VARCHAR(10) default 'auto'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'auto'), + 'force_dtmfmode' => array('create' => "ENUM('auto','rfc2833','skinny') NOT NULL default 'auto'", 'modify' => "ENUM('auto','rfc2833','skinny')", 'def_modify'=> 'auto'), 'deny' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), 'permit' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), 'backgroundImage' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), 'ringtone' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), - 'transfer' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), - 'cfwdall' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), - 'cfwdbusy' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), - 'cfwdnoanswer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), - 'park' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), - 'directrtp' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), - 'dndFeature' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), - 'earlyrtp' => array('create' => "ENUM('immediate','offHook','dialing','ringout','progress','none') NOT NULL default 'none'", - 'modify' => "ENUM('immediate','offHook','dialing','ringout','progress','none')", - 'def_modify' => 'none'), - 'monitor' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'transfer' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), + 'cfwdall' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'cfwdbusy' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'cfwdnoanswer' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'park' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'directrtp' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), + 'dndFeature' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), + 'earlyrtp' => array('create' => "ENUM('immediate','offHook','dialing','ringout','progress','none') NULL default NULL", 'modify' => "ENUM('immediate','offHook','dialing','ringout','progress','none')"), + 'monitor' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), 'audio_tos' => array('def_modify' => "0xB8"), 'audio_cos' => array('def_modify' => "6"), 'video_tos' => array('def_modify' => "0x88"), 'video_cos' => array('def_modify' => "5"), 'trustphoneip' => array('drop' => "yes"), - 'transfer_on_hangup' => array('create' => "enum('on','off') NOT NULL DEFAULT 'off'", 'modify' => "enum('on','off')"), + 'transfer_on_hangup' => array('create' => "enum('on','off') NULL DEFAULT NULL", 'modify' => "enum('on','off')"), 'phonecodepage' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL', 'modify' => "VARCHAR(50)"), - 'mwilamp' => array('create' => "enum('on','off','wink','flash','blink') NOT NULL default 'on'", - 'modify' => "enum('on','off','wink','flash','blink')"), - 'mwioncall' => array('create' => "enum('on','off') NOT NULL default 'on'", - 'modify' => "enum('on','off')"), + 'mwilamp' => array('create' => "enum('on','off','wink','flash','blink') NULL default 'on'", 'modify' => "enum('on','off','wink','flash','blink')"), + 'mwioncall' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), 'private' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), // Что-то лишенне 'privacy' => array('create' => "enum('full','on','off') NOT NULL default 'full'", 'modify' => "enum('full','on','off')"), // Что-то лишенне - 'nat' => array('create' => "enum('on','off','auto') NOT NULL default 'off'", 'modify' => "enum('on','off','auto')"), + 'nat' => array('create' => "enum('on','off','auto') NULL default NULL", 'modify' => "enum('on','off','auto')"), 'conf_allow' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), 'conf_play_part_announce' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), 'conf_mute_on_entry' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), @@ -152,9 +287,9 @@ function Get_DB_config($sccp_compatible) 'softkeyset' => array('def_modify' => "softkeyset") ), 'sccpline' => array( - 'directed_pickup' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'directed_pickup' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), 'directed_pickup_context' => array('create' => "VARCHAR(100) NULL DEFAULT NULL"), - 'pickup_modeanswer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'pickup_modeanswer' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), 'namedcallgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `setvar`", 'modify' => "VARCHAR(100)"), 'namedpickupgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `namedcallgroup`", 'modify' => "VARCHAR(100)"), 'adhocNumber' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `namedpickupgroup`"), @@ -167,14 +302,15 @@ function Get_DB_config($sccp_compatible) 'audio_cos' => array('drop' => "yes"), 'video_tos' => array('drop' => "yes"), 'video_cos' => array('drop' => "yes"), - 'videomode' => array('create' => "enum('user','auto','off') NOT NULL default 'auto'", 'modify' => "enum('user','auto','off')"), + 'videomode' => array('create' => "enum('user','auto','off') NULL default 'auto'", 'modify' => "enum('user','auto','off')"), 'incominglimit' => array('create' => "INT(11) DEFAULT '6'", 'modify' => 'INT(11)', 'def_modify' => "6"), - 'transfer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'transfer' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), 'vmnum' => array('def_modify' => "*97"), 'musicclass' => array('def_modify' => "default"), 'disallow' => array('create' => "VARCHAR(255) NULL DEFAULT NULL"), 'allow' => array('create' => "VARCHAR(255) NULL DEFAULT NULL"), 'id' => array('create' => 'MEDIUMINT(9) NOT NULL AUTO_INCREMENT, ADD UNIQUE(id);', 'modify' => "MEDIUMINT(9)", 'index' => 'id'), +// 'id' =>array('create' => 'VARCHAR( 20 ) NULL DEFAULT NULL', 'modify' => "VARCHAR(20)", 'def_modify' =>"NULL"), 'echocancel' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), 'silencesuppression' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), 'dnd' => array('create' => "enum('off','reject','silent','user') NOT NULL default 'reject'", 'modify' => "enum('off','reject','silent','user')", 'def_modify' => "reject") @@ -184,14 +320,13 @@ function Get_DB_config($sccp_compatible) 'pin' => array('create' => "varchar(7) NOT NULL", 'modify' => "VARCHAR(7)" ), 'password' => array('create' => "varchar(7) NOT NULL", 'modify' => "VARCHAR(7)" ), 'description' => array('create' => "varchar(45) NOT NULL", 'modify' => "VARCHAR(45)" ), - 'roaminglogin' => array('create' => "ENUM('on','off','multi') NOT NULL DEFAULT 'off'", 'modify' => "ENUM('on','off','multi')" ), - 'auto_logout' => array('create' => "ENUM('on','off') NOT NULL DEFAULT 'off'", 'modify' => "ENUM('on','off')" ), + 'roaminglogin' => array('create' => "ENUM('on','off','multi') NULL DEFAULT 'off'", 'modify' => "ENUM('on','off','multi')" ), + 'auto_logout' => array('create' => "ENUM('on','off') NULL DEFAULT 'off'", 'modify' => "ENUM('on','off')" ), 'homedevice' => array('create' => "varchar(20) NOT NULL", 'modify' => "VARCHAR(20)" ), 'devicegroup' => array('create' => "varchar(7) NOT NULL", 'modify' => "VARCHAR(7)" ), ), 'sccpbuttonconfig' => array( - 'reftype' => array('create' => "enum('sccpdevice', 'sipdevice', 'sccpuser') NOT NULL default 'sccpdevice'", - 'modify' => "enum('sccpdevice', 'sipdevice', 'sccpuser')" ), + 'reftype' => array('create' => "enum('sccpdevice', 'sipdevice', 'sccpuser') NOT NULL default 'sccpdevice'", 'modify' => "enum('sccpdevice', 'sipdevice', 'sccpuser')" ), ) ); // Hardware Mobile. Can switch Softwate to Hardware @@ -227,17 +362,33 @@ function Get_DB_config($sccp_compatible) } return $db_config_v4; } + if ($sccp_compatible >= 430) { + return $db_config_v3; + } else { + return $db_config_v0; + } } +$autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT" : "AUTO_INCREMENT"; + +$table_req = array('sccpdevice', 'sccpline'); +$ss = FreePBX::create()->Sccp_manager; +$astman = FreePBX::create()->astman; +$sccp_compatible = 0; +$chanSCCPWarning = true; +//$db_config = $db_config_v0; +$db_config = ''; + function CheckSCCPManagerDBTables($table_req) { - // These tables should already exist having been created by FreePBX through module.xml global $amp_conf; + global $astman; global $db; - outn("
  • " . _("Checking for required Sccp_manager database tables..") . "
  • "); + outn("
  • " . _("Checking for Sccp_manager database tables..") . "
  • "); foreach ($table_req as $value) { $check = $db->getRow("SELECT 1 FROM `$value` LIMIT 0", DB_FETCHMODE_ASSOC); if (DB::IsError($check)) { + //print_r("none, creating table :". $value); outn(_("Can't find table: " . $value)); outn(_("Please goto the chan-sccp/conf directory and create the DB schema manually (See wiki)")); die_freepbx("!!!! Installation error: Can not find required " . $value . " table !!!!!!\n"); @@ -296,9 +447,100 @@ function CheckAsteriskVersion() function CheckChanSCCPCompatible() { global $chanSCCPWarning; - global $aminterface; + global $srvinterface, $astman; + if (!$astman) { + ie_freepbx('No asterisk manager connection provided!. Installation Failed'); + } // calling with true returns array with compatibility and RevisionNumber - return $aminterface->get_compatible_sccp(true); + return $srvinterface->get_compatible_sccp(true); +} + +function InstallDB_Buttons() +{ + global $db; + outn("
  • " . _("Creating buttons table...") . "
  • "); +// $check = $db->getRow("SELECT 1 FROM buttonconfig LIMIT 0", DB_FETCHMODE_ASSOC); +// if (DB::IsError($check)) { + $sql = "DROP TABLE IF EXISTS `buttonconfig`; + CREATE TABLE IF NOT EXISTS `sccpbuttonconfig` ( + `ref` varchar(15) NOT NULL default '', + `reftype` enum('sccpdevice', 'sipdevice', 'sccpuser') NOT NULL default 'sccpdevice', + `instance` tinyint(4) NOT NULL default 0, + `buttontype` enum('line','speeddial','service','feature','empty') NOT NULL default 'line', + `name` varchar(36) default NULL, + `options` varchar(100) default NULL, + PRIMARY KEY (`ref`,`reftype`,`instance`,`buttontype`), + KEY `ref` (`ref`,`reftype`) + ) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not create sccpbuttonconfig table, error:$check\n"); + } + return true; +} + +function InstallDB_sccpsettings() +{ + global $db; + outn("
  • " . _("Creating sccpsettings table...") . "
  • "); + $stmt = $db-> prepare('CREATE TABLE IF NOT EXISTS sccpsettings ( + keyword VARCHAR (50) NOT NULL, + data VARCHAR (255) NOT NULL, + seq TINYINT (1), + type TINYINT (1) NOT NULL, + PRIMARY KEY (keyword, seq, type ) + );'); + $check = $stmt->execute(); + if (DB::IsError($check)) { + die_freepbx("Can not create sccpsettings table, error: $check\n"); + } + return true; +} + +function InstallDB_sccpdevmodel() +{ + global $db; + outn("
  • " . _("Creating sccpdevmodel table...") . "
  • "); + $sql = "CREATE TABLE IF NOT EXISTS `sccpdevmodel` ( + `model` varchar(20) NOT NULL DEFAULT '', + `vendor` varchar(40) DEFAULT '', + `dns` int(2) DEFAULT '1', + `buttons` int(2) DEFAULT '0', + `loadimage` varchar(40) DEFAULT '', + `loadinformationid` VARCHAR(30) NULL DEFAULT NULL, + `enabled` INT(2) NULL DEFAULT '0', + `nametemplate` VARCHAR(50) NULL DEFAULT NULL, + PRIMARY KEY (`model`), + KEY `model` (`model`) + ) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not create sccpdevmodel table, error:$check\n"); + } + return true; +} + +function InstallDB_sccpuser() +{ + global $db; + outn("
  • " . _("Creating sccpuser table...") . "
  • "); + $sql = "CREATE TABLE IF NOT EXISTS `sccpuser` ( + `name` VARCHAR(20) NULL DEFAULT NULL, + `pin` VARCHAR(7) NULL DEFAULT NULL, + `password` VARCHAR(7) NULL DEFAULT NULL, + `description` VARCHAR(45) NULL DEFAULT NULL, + `roaminglogin` ENUM('on','off','multi') NULL DEFAULT 'off', + `devicegroup` VARCHAR(20) NULL DEFAULT 'all', + `auto_logout` ENUM('on','off') NULL DEFAULT 'off', + `homedevice` VARCHAR(20) NULL DEFAULT NULL, + UNIQUE INDEX (`name`), + PRIMARY KEY (`name`) + ) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not create sccpdevmodel table, error:$check\n"); + } + return true; } function InstallDB_updateSchema($db_config) @@ -309,34 +551,30 @@ function InstallDB_updateSchema($db_config) } $count_modify = 0; outn("
  • " . _("Modify Database schema") . "
  • "); - foreach ($db_config as $tabl_name => &$tab_modif) { + foreach ($db_config as $tabl_name => &$tab_modify) { // 0 - name 1-type 4- default - $sql = "DESCRIBE {$tabl_name};"; - $stmt = $db->prepare("DESCRIBE {$tabl_name}"); - $stmt->execute(); - $db_result = $stmt->fetchAll(); + $sql = "DESCRIBE " . $tabl_name . ""; + $db_result = $db->getAll($sql); if (DB::IsError($db_result)) { - die_freepbx("Can not get information from " . $tabl_name . " table\n"); + die_freepbx("Can not add get information from " . $tabl_name . " table\n"); } foreach ($db_result as $tabl_data) { $fld_id = $tabl_data[0]; - // Filter commands to avoid applying unnecessary - if (!empty($tab_modif[$fld_id])) { - // Potentially have something to modify in schema - $db_config[$tabl_name][$fld_id]['fieldExists'] = 'yes'; - if (!empty($tab_modif[$fld_id]['def_modify'])) { - if (strtoupper($tab_modif[$fld_id]['def_modify']) == strtoupper($tabl_data[4])) { - unset($db_config[$tabl_name][$fld_id]['def_modify']); + if (!empty($tab_modify[$fld_id])) { + $db_config[$tabl_name][$fld_id]['status'] = 'yes'; + if (!empty($tab_modify[$fld_id]['def_modify'])) { + if (strtoupper($tab_modify[$fld_id]['def_modify']) == strtoupper($tabl_data[4])) { + $db_config[$tabl_name][$fld_id]['def_mod_stat'] = 'no'; } } - if (!empty($tab_modif[$fld_id]['modify'])) { - if (strtoupper($tab_modif[$fld_id]['modify']) == strtoupper($tabl_data[1])) { - unset($db_config[$tabl_name][$fld_id]['modify']); + if (!empty($tab_modify[$fld_id]['modify'])) { + if (strtoupper($tab_modify[$fld_id]['modify']) == strtoupper($tabl_data[1])) { + $db_config[$tabl_name][$fld_id]['mod_stat'] = 'no'; } } - if (!empty($tab_modif[$fld_id]['rename'])) { - $fld_id_source = $tab_modif[$fld_id]['rename']; - $db_config[$tabl_name][$fld_id_source]['fieldExists'] = 'yes'; + if (!empty($tab_modify[$fld_id]['rename'])) { + $fld_id_source = $tab_modify[$fld_id]['rename']; + $db_config[$tabl_name][$fld_id_source]['status'] = 'yes'; if (!empty($db_config[$tabl_name][$fld_id_source]['create'])) { $db_config[$tabl_name][$fld_id]['create'] = $db_config[$tabl_name][$fld_id_source]['create']; } else { @@ -350,23 +588,25 @@ function InstallDB_updateSchema($db_config) $sql_modify = ''; $sql_update = ''; - foreach ($tab_modif as $row_fld => $row_data) { - if (empty($row_data['fieldExists'])) { + foreach ($tab_modify as $row_fld => $row_data) { + if (empty($row_data['status'])) { if (!empty($row_data['create'])) { - $sql_create .= "ADD COLUMN {$row_fld} {$row_data['create']}, "; + $sql_create .= 'ADD COLUMN `' . $row_fld . '` ' . $row_data['create'] . ', '; $count_modify ++; } } else { if (!empty($row_data['rename'])) { - $sql_modify .= "CHANGE COLUMN {$row_fld} {$row_data['rename']} {$row_data['create']}, "; + $sql_modify .= 'CHANGE COLUMN `' . $row_fld . '` `' . $row_data['rename'] . '` ' . $row_data['create'] . ', '; $count_modify ++; } if (!empty($row_data['modify'])) { if (empty($row_data['mod_stat'])) { if (!empty($row_data['create'])) { - $sql_modify .= "MODIFY COLUMN {$row_fld} {$row_data['create']}, "; +// $sql_modify .= "CHANGE COLUMN `".$row_fld."` `".$row_fld."` ".$row_data['create'].", "; + $sql_modify .= "MODIFY COLUMN `" . $row_fld . "` " . $row_data['create'] . ", "; } else { - $sql_modify .= "MODIFY COLUMN {$row_fld} {$row_data['modify']} DEFAULT {$row_data['def_modify']}, "; +// $sql_modify .= "CHANGE COLUMN `".$row_fld."` `".$row_fld."` ".$row_data['modify']." DEFAULT '".$row_data['def_modify']."', "; + $sql_modify .= "MODIFY COLUMN `" . $row_fld . "` " . $row_data['modify'] . " DEFAULT '" . $row_data['def_modify'] . "', "; } if (strpos($row_data['modify'], 'enum') !== false) { $sql_update .= "UPDATE " . $tabl_name . " set `" . $row_fld . "`=case when lower(`" . $row_fld . "`) in ('yes','true','1') then 'on' when lower(`" . $row_fld . "`) in ('no', 'false', '0') then 'off' else `" . $row_fld . "` end; "; @@ -377,25 +617,35 @@ function InstallDB_updateSchema($db_config) } if (!empty($row_data['def_modify'])) { if (empty($row_data['def_mod_stat'])) { - $sql_modify .= "ALTER COLUMN {$row_fld} SET DEFAULT {$row_data['def_modify']}, "; + $sql_modify .= "ALTER COLUMN `" . $row_fld . "` SET DEFAULT '" . $row_data['def_modify'] . "', "; $count_modify ++; } } if (!empty($row_data['drop'])) { - $sql_create .= "DROP COLUMN {$row_fld}, "; + $sql_create .= 'DROP COLUMN `' . $row_fld . '`, '; $count_modify ++; } } } +// out("
  • " . print_r($sql_update, 1) . "
  • "); +// out("
  • " . print_r($sql_modify, 1) . "
  • "); +// die("Can not modify Е" . $tabl_name . " table sql: " . $sql_modify . "n"); + if (!empty($sql_update)) { $sql_update = 'BEGIN; ' . $sql_update . ' COMMIT;'; sql($sql_update); $affected_rows = $db->affectedRows(); - outn("
  • " . _("Updated table rows :") . $affected_rows . "
  • "); +// $check = $db->query($sql_update); +// $db->closeCursor(); + outn("
  • " . _("Update table row :") . $affected_rows . "
  • "); +// if (db::IsError($check)) { +// die_freepbx("Can not update ".$tabl_name." table sql: ".$sql_update."n"); +// die_freepbx("Can not update ".$tabl_name." table\n"); +// } } if (!empty($sql_create)) { - outn("
  • " . _("Adding new FILTER_VALIDATE_INT") . "
  • "); + outn("
  • " . _("Create New table") . "
  • "); $sql_create = "ALTER TABLE `" . $tabl_name . "` " . substr($sql_create, 0, -2); $check = $db->query($sql_create); if (DB::IsError($check)) { @@ -403,7 +653,7 @@ function InstallDB_updateSchema($db_config) } } if (!empty($sql_modify)) { - outn("
  • " . _("Modifying table ") . $tabl_name ."
  • "); + outn("
  • " . _("Modify table") . "
  • "); $sql_modify = "ALTER TABLE `" . $tabl_name . "` " . substr($sql_modify, 0, -2) . ';'; $check = $db->query($sql_modify); @@ -422,134 +672,20 @@ function InstallDB_fillsccpdevmodel() { global $db; outn("
  • " . _("Fill sccpdevmodel") . "
  • "); - $sql = "REPLACE INTO sccpdevmodel (model, vendor, dns, buttons, loadimage, loadinformationid, enabled, nametemplate) VALUES - ('12 SP', 'CISCO', 1, 1, '', 'loadInformation3', 0, NULL), - ('12 SP+', 'CISCO', 1, 1, '', 'loadInformation2', 0, NULL), - ('30 SP+', 'CISCO', 1, 1, '', 'loadInformation1', 0, NULL), - ('30 VIP', 'CISCO', 1, 1, '', 'loadInformation5', 0, NULL), - ('3911', 'CISCO', 1, 1, '', 'loadInformation446', 0, NULL), - ('3951', 'CISCO', 1, 1, '', 'loadInformation412', 0, ''), - ('6901', 'CISCO', 1, 1, 'SCCP6901.9-2-1-a', 'loadInformation547', 0, NULL), - ('6911', 'CISCO', 1, 1, 'SCCP6911.9-2-1-a', 'loadInformation548', 0, NULL), - ('6921', 'CISCO', 1, 1, 'SCCP69xx.9-4-1-3SR3', 'loadInformation496', 0, NULL), - ('6941', 'CISCO', 1, 1, 'SCCP69xx.9-3-1-3', 'loadInformation495', 0, NULL), - ('6945', 'CISCO', 1, 1, 'SCCP6945.9-3-1-3', 'loadInformation564', 0, NULL), - ('6961', 'CISCO', 1, 1, 'SCCP69xx.9-2-1-0', 'loadInformation497', 0, NULL), - ('7902', 'CISCO', 1, 1, 'CP7902080002SCCP060817A', 'loadInformation30008', 0, NULL), - ('7905', 'CISCO', 1, 1, 'CP7905080003SCCP070409A', 'loadInformation20000', 0, NULL), - ('7906', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation369', 1, 'SEP0000000000.cnf.xml_791x_template'), - ('7910', 'CISCO', 1, 1, 'P00405000700', 'loadInformation6', 1, 'SEP0000000000.cnf.xml_791x_template'), - ('7911', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_template'), - ('7912', 'CISCO', 1, 1, 'CP7912080004SCCP080108A', 'loadInformation30007', 0, NULL), - ('7914', 'CISCO', 0, 14, 'S00105000400', 'loadInformation124', 1, NULL), - ('7914;7914', 'CISCO', 0, 28, 'S00105000400', 'loadInformation124', 1, NULL), - ('7915', 'CISCO', 0, 24, 'B015-1-0-4-2', 'loadInformation227', 1, NULL), - ('7915;7915', 'CISCO', 0, 48, 'B015-1-0-4-2', 'loadInformation228', 1, NULL), - ('7916', 'CISCO', 0, 24, 'B016-1-0-4-2', 'loadInformation229', 1, NULL), - ('7916;7916', 'CISCO', 0, 48, 'B016-1-0-4-2', 'loadInformation230', 1, NULL), - ('7920', 'CISCO', 1, 1, 'cmterm_7920.4.0-03-02', 'loadInformation30002', 0, NULL), - ('7921', 'CISCO', 1, 1, 'CP7921G-1.4.6.3', 'loadInformation365', 0, NULL), - ('7925', 'CISCO', 1, 6, 'CP7925G-1.4.1SR1', 'loadInformation484', 0, 'SEP0000000000.cnf.xml_7925_template'), - ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.1SR1', 'loadInformation557', 0, NULL), - ('7931', 'CISCO', 1, 34, 'SCCP31.9-2-1S', 'loadInformation348', 0, NULL), - ('7935', 'CISCO', 1, 2, 'P00503021900', 'loadInformation9', 0, NULL), - ('7936', 'CISCO', 1, 1, 'cmterm_7936.3-3-21-0', 'loadInformation30019', 0, NULL), - ('7937', 'CISCO', 1, 1, 'apps37sccp.1-4-5-7', 'loadInformation431', 0, 'SEP0000000000.cnf.xml_7937_template'), - ('7940', 'CISCO', 1, 2, 'P0030801SR02', 'loadInformation8', 1, 'SEP0000000000.cnf.xml_7940_template'), - ('7941', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation115', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7941G-GE', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation309', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7942', 'CISCO', 1, 2, 'SCCP42.9-4-2SR3-1S', 'loadInformation434', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7945', 'CISCO', 1, 2, 'SCCP45.9-3-1SR1-1S', 'loadInformation435', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7960', 'CISCO', 3, 6, 'P0030801SR02', 'loadInformation7', 1, 'SEP0000000000.cnf.xml_7940_template'), - ('7961', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation30018', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7961G-GE', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation308', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7962', 'CISCO', 3, 6, 'SCCP42.9-4-2SR3-1S', 'loadInformation404', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7965', 'CISCO', 3, 6, 'SCCP45.9-3-1SR1-1S', 'loadInformation436', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7970', 'CISCO', 3, 8, 'SCCP70.9-4-2SR3-1S', 'loadInformation30006', 0, 'SEP0000000000.cnf.xml_797x_template'), - ('7971', 'CISCO', 1, 2, 'SCCP70.9-4-2SR3-1S', 'loadInformation119', 0, 'SEP0000000000.cnf.xml_797x_template'), - ('7975', 'CISCO', 3, 8, 'SCCP75.9-4-2SR3-1S', 'loadInformation437', 0, 'SEP0000000000.cnf.xml_7975_template'), - ('7985', 'CISCO', 3, 8, 'cmterm_7985.4-1-7-0', 'loadInformation302', 0, NULL), - ('8941', 'CISCO', 1, 1, 'SCCP894x.9-2-2-0', 'loadInformation586', 0, NULL), - ('8945', 'CISCO', 1, 1, 'SCCP894x.9-2-2-0', 'loadInformation585', 0, NULL), - ('ATA 186', 'CISCO', 1, 1, 'ATA030204SCCP090202A', 'loadInformation12', 0, 'SEP0000000000.cnf.xml_ATA_template'), - ('ATA 187', 'CISCO', 1, 1, 'ATA187.9-2-3-1', 'loadInformation550', 0, 'SEP0000000000.cnf.xml_ATA_template'), - ('CN622', 'MOTOROLA', 1, 1, '', 'loadInformation335', 0, NULL), - ('Digital Access', 'CISCO', 1, 1, 'D001M022', 'loadInformation40', 0, NULL), - ('Digital Access+', 'CISCO', 1, 1, 'D00303010033', 'loadInformation42', 0, NULL), - ('E-Series', 'NOKIA', 1, 1, '', '', 0, NULL), - ('ICC', 'NOKIA', 1, 1, '', '', 0, NULL), - ('Analog Access', 'CISCO', 1, 1, 'A001C030', 'loadInformation30', 0, ''),('WS-X6608', 'CISCO', 1, 1, 'D00404000032', 'loadInformation43', 0, ''), - ('WS-X6624', 'CISCO', 1, 1, 'A00204000013', 'loadInformation43', 0, ''), - ('WS-X6608', 'CISCO', 1, 1, 'C00104000003', 'loadInformation51', 0, ''), - ('H.323 Phone', 'CISCO', 1, 1, '', 'loadInformation61', 0, ''), - ('Simulator', 'CISCO', 1, 1, '', 'loadInformation100', 0, ''), - ('MTP', 'CISCO', 1, 1, '', 'loadInformation111', 0, ''), - ('MGCP Station', 'CISCO', 1, 1, '', 'loadInformation120', 0, ''), - ('MGCP Trunk', 'CISCO', 1, 1, '', 'loadInformation121', 0, ''), - ('UPC', 'CISCO', 1, 1, '', 'loadInformation358', 0, ''), - ('TelePresence', 'TELEPRESENCE', 1, 1, '', 'loadInformation375', 0, ''), - ('1000', 'TELEPRESENCE', 1, 1, '', 'loadInformation478', 0, ''), - ('3000', 'TELEPRESENCE', 1, 1, '', 'loadInformation479', 0, ''), - ('3200', 'TELEPRESENCE', 1, 1, '', 'loadInformation480', 0, ''), - ('500-37', 'TELEPRESENCE', 1, 1, '', 'loadInformation481', 0, ''), - ('1300-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation505', 0, ''), - ('1100', 'TELEPRESENCE', 1, 1, '', 'loadInformation520', 0, ''), - ('200', 'TELEPRESENCE', 1, 1, '', 'loadInformation557', 0, ''), - ('400', 'TELEPRESENCE', 1, 1, '', 'loadInformation558', 0, ''), - ('EX90', 'TELEPRESENCE', 1, 1, '', 'loadInformation584', 0, ''), - ('500-32', 'TELEPRESENCE', 1, 1, '', 'loadInformation590', 0, ''), - ('1300-47', 'TELEPRESENCE', 1, 1, '', 'loadInformation591', 0, ''), - ('TX1310-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation596', 0, ''), - ('EX60', 'TELEPRESENCE', 1, 1, '', 'loadInformation604', 0, ''), - ('C90', 'TELEPRESENCE', 1, 1, '', 'loadInformation606', 0, ''), - ('C60', 'TELEPRESENCE', 1, 1, '', 'loadInformation607', 0, ''), - ('C40', 'TELEPRESENCE', 1, 1, '', 'loadInformation608', 0, ''), - ('C20', 'TELEPRESENCE', 1, 1, '', 'loadInformation609', 0, ''), - ('C20-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation610', 0, ''), - ('C60-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation611', 0, ''), - ('C40-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation612', 0, ''), - ('C60-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation613', 0, ''), - ('C60-52D', 'TELEPRESENCE', 1, 1, '', 'loadInformation614', 0, ''), - ('C60-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation615', 0, ''), - ('C90-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation616', 0, ''), - ('MX200', 'TELEPRESENCE', 1, 1, '', 'loadInformation617', 0, ''), - ('TX9000', 'TELEPRESENCE', 1, 1, '', 'loadInformation619', 0, ''), - ('TX9200', 'TELEPRESENCE', 1, 1, '', 'loadInformation620', 0, ''), - ('SX20', 'TELEPRESENCE', 1, 1, '', 'loadInformation626', 0, ''), - ('MX300', 'TELEPRESENCE', 1, 1, '', 'loadInformation627', 0, ''), - ('C40-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation633', 0, ''), - ('Jabber', 'CISCO', 1, 1, '', 'loadInformation652', 0, ''), - ('S60', 'NOKIA', 0, 1, '', 'loadInformation376', 0, ''), - ('9971', 'CISCO', 1, 1, '', 'loadInformation493', 0, ''), - ('9951', 'CISCO', 1, 1, '', 'loadInformation537', 0, ''), - ('8961', 'CISCO', 1, 1, '', 'loadInformation540', 0, ''), - ('Iphone', 'APPLE', 0, 1, '', 'loadInformation562', 0, ''), - ('Android', 'ANDROID', 0, 1, '', 'loadInformation575', 0, ''), - ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.5.3', 'loadInformation577', 0, ''), - ('7821', 'CISCO', 1, 1, '', 'loadInformation621', 0, ''), - ('7841', 'CISCO', 1, 1, '', 'loadInformation622', 0, ''), - ('7861', 'CISCO', 1, 1, '', 'loadInformation623', 0, ''), - ('VXC 6215', 'CISCO', 1, 1, '', 'loadInformation634', 0, ''), - ('8831', 'CISCO', 1, 1, '', 'loadInformation659', 0, ''), - ('8841', 'CISCO', 1, 1, '', 'loadInformation683', 0, ''), - ('8851', 'CISCO', 1, 1, '', 'loadInformation684', 0, ''), - ('8861', 'CISCO', 1, 1, '', 'loadInformation685', 0, ''), - ('Analog', 'CISCO', 1, 1, '', 'loadInformation30027', 0, ''), - ('ISDN', 'CISCO', 1, 1, '', 'loadInformation30028', 0, ''), - ('SCCP GW', 'CISCO', 1, 1, '', 'loadInformation30032', 0, ''), - ('IP-STE', 'CISCO', 1, 1, '', 'loadInformation30035', 0, ''), - ('SPA 521S', 'CISCO', 1, 1, '', 'loadInformation80000', 0, ''), - ('SPA 502G', 'CISCO', 1, 1, '', 'loadInformation80003', 0, ''), - ('SPA 504G', 'CISCO', 1, 1, '', 'loadInformation80004', 0, ''), - ('SPA 525G', 'CISCO', 1, 1, '', 'loadInformation80005', 0, ''), - ('SPA 525G2', 'CISCO', 1, 1, '', 'loadInformation80009', 0, ''), - ('SPA 303G', 'CISCO', 1, 1, '', 'loadInformation80011', 0, ''), - ('IP Communicator', 'CISCO', 1, 1, '', 'loadInformation30016', 0, NULL), - ('Nokia E', 'Nokia', 1, 28, '', 'loadInformation275', 0, NULL), - ('VGC Phone', 'CISCO', 1, 1, '', 'loadInformation10', 0, NULL), - ('7911-sip', 'CISCO-SIP', 1, 1, 'SIP11.9-2-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_sip_template'), - ('9951-sip', 'CISCO-SIP', 1, 1, 'sip9951.9-2-2SR1-9', 'loadinformation537', 1, 'SEP0000000000.cnf.xml_99xx_sip_template'), - ('VGC Virtual', 'CISCO', 1, 1, '', 'loadInformation11', 0, NULL);"; + $sql = "REPLACE INTO `sccpdevmodel` (`model`, `vendor`, `dns`, `buttons`, `loadimage`, `loadinformationid`, `enabled`, `nametemplate`) VALUES ('12 SP', 'CISCO', 1, 1, '', 'loadInformation3', 0, NULL)," . + "('12 SP+', 'CISCO', 1, 1, '', 'loadInformation2', 0, NULL), ('30 SP+', 'CISCO', 1, 1, '', 'loadInformation1', 0, NULL), ('30 VIP', 'CISCO', 1, 1, '', 'loadInformation5', 0, NULL), ('3911', 'CISCO', 1, 1, '', 'loadInformation446', 0, NULL), ('3951', 'CISCO', 1, 1, '', 'loadInformation412', 0, ''), ('6901', 'CISCO', 1, 0, 'SCCP6901.9-2-1-a', 'loadInformation547', 0, NULL), ('6911', 'CISCO', 1, 0, 'SCCP6911.9-2-1-a', 'loadInformation548', 0, NULL), ('6921', 'CISCO', 1, 0, 'SCCP69xx.9-4-1-3SR3', 'loadInformation496', 0, NULL), ('6941', 'CISCO', 1, 1, 'SCCP69xx.9-3-1-3', 'loadInformation495', 0, NULL), ('6945', 'CISCO', 1, 0, 'SCCP6945.9-3-1-3', 'loadInformation564', 0, NULL), ('6961', 'CISCO', 1, 0, 'SCCP69xx.9-2-1-0', 'loadInformation497', 0, NULL), ('7902', 'CISCO', 1, 1, 'CP7902080002SCCP060817A', 'loadInformation30008', 0, NULL), " . + "('7905', 'CISCO', 1, 1, 'CP7905080003SCCP070409A', 'loadInformation20000', 0, NULL), ('7906', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation369', 1, 'SEP0000000000.cnf.xml_791x_template'), ('7910', 'CISCO', 1, 1, 'P00405000700', 'loadInformation6', 1, 'SEP0000000000.cnf.xml_791x_template'), ('7911', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_template'), ('7912', 'CISCO', 1, 1, 'CP7912080004SCCP080108A', 'loadInformation30007', 0, NULL), ('7914', 'CISCO', 0, 14, 'S00105000400', 'loadInformation124', 1, NULL),('7914;7914', 'CISCO', 0, 28, 'S00105000400', 'loadInformation124', 1, NULL), ('7915', 'CISCO', 0, 24, 'B015-1-0-4-2', 'loadInformation227', 1, NULL), ('7915;7915', 'CISCO', 0, 48, 'B015-1-0-4-2', 'loadInformation228', 1, NULL), ('7916', 'CISCO', 0, 24, 'B016-1-0-4-2', 'loadInformation229', 1, NULL), " . + "('7916;7916', 'CISCO', 0, 48, 'B016-1-0-4-2', 'loadInformation230', 1, NULL), ('7920', 'CISCO', 1, 1, 'cmterm_7920.4.0-03-02', 'loadInformation30002', 0, NULL), ('7921', 'CISCO', 1, 1, 'CP7921G-1.4.6.3', 'loadInformation365', 0, NULL),('7925', 'CISCO', 1, 6, 'CP7925G-1.4.1SR1', 'loadInformation484', 0, 'SEP0000000000.cnf.xml_7925_template'), ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.1SR1', 'loadInformation557', 0, NULL), ('7931', 'CISCO', 1, 34, 'SCCP31.9-2-1S', 'loadInformation348', 0, NULL), ('7935', 'CISCO', 1, 2, 'P00503021900', 'loadInformation9', 0, NULL), ('7936', 'CISCO', 1, 1, 'cmterm_7936.3-3-21-0', 'loadInformation30019', 0, NULL), ('7937', 'CISCO', 1, 1, 'apps37sccp.1-4-5-7', 'loadInformation431', 0, 'SEP0000000000.cnf.xml_7937_template'), ('7940', 'CISCO', 1, 2, 'P0030801SR02', 'loadInformation8', 1, 'SEP0000000000.cnf.xml_7940_template'), " . + "('7941', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation115', 0, 'SEP0000000000.cnf.xml_796x_template'),('7941G-GE', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation309', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7942', 'CISCO', 1, 2, 'SCCP42.9-4-2SR3-1S', 'loadInformation434', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7945', 'CISCO', 1, 2, 'SCCP45.9-3-1SR1-1S', 'loadInformation435', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7960', 'CISCO', 3, 6, 'P0030801SR02', 'loadInformation7', 1, 'SEP0000000000.cnf.xml_7940_template'), ('7961', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation30018', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7961G-GE', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation308', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7962', 'CISCO', 3, 6, 'SCCP42.9-4-2SR3-1S', 'loadInformation404', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7965', 'CISCO', 3, 6, 'SCCP45.9-3-1SR1-1S', 'loadInformation436', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7970', 'CISCO', 3, 8, 'SCCP70.9-4-2SR3-1S', 'loadInformation30006', 0, 'SEP0000000000.cnf.xml_797x_template'), ('7971', 'CISCO', 1, 2, 'SCCP70.9-4-2SR3-1S', 'loadInformation119', 0, 'SEP0000000000.cnf.xml_797x_template'), ('7975', 'CISCO', 3, 8, 'SCCP75.9-4-2SR3-1S', 'loadInformation437', 0, 'SEP0000000000.cnf.xml_7975_template'), ('7985', 'CISCO', 3, 8, 'cmterm_7985.4-1-7-0', 'loadInformation302', 0, NULL), ('8941', 'CISCO', 1, 0, 'SCCP894x.9-2-2-0', 'loadInformation586', 0, NULL), ('8945', 'CISCO', 1, 0, 'SCCP894x.9-2-2-0', 'loadInformation585', 0, NULL), ('ATA 186', 'CISCO', 1, 1, 'ATA030204SCCP090202A', 'loadInformation12', 0, 'SEP0000000000.cnf.xml_ATA_template'), ('ATA 187', 'CISCO', 1, 1, 'ATA187.9-2-3-1', 'loadInformation550', 0, 'SEP0000000000.cnf.xml_ATA_template'), ('CN622', 'MOTOROLA', 1, 1, '', 'loadInformation335', 0, NULL), ('Digital Access', 'CISCO', 1, 1, 'D001M022', 'loadInformation40', 0, NULL), ('Digital Access+', 'CISCO', 1, 1, 'D00303010033', 'loadInformation42', 0, NULL), ('E-Series', 'NOKIA', 1, 1, '', '', 0, NULL), ('ICC', 'NOKIA', 1, 1, '', '', 0, NULL), " . + "('Analog Access', 'CISCO', 1, 1, 'A001C030', 'loadInformation30', 0, ''),('WS-X6608', 'CISCO', 1, 1, 'D00404000032', 'loadInformation43', 0, ''), ('WS-X6624', 'CISCO', 1, 1, 'A00204000013', 'loadInformation43', 0, ''), ('WS-X6608', 'CISCO', 1, 1, 'C00104000003', 'loadInformation51', 0, ''), ('H.323 Phone', 'CISCO', 1, 1, '', 'loadInformation61', 0, ''), ('Simulator', 'CISCO', 1, 1, '', 'loadInformation100', 0, ''), ('MTP', 'CISCO', 1, 1, '', 'loadInformation111', 0, ''), ('MGCP Station', 'CISCO', 1, 1, '', 'loadInformation120', 0, ''), ('MGCP Trunk', 'CISCO', 1, 1, '', 'loadInformation121', 0, ''), ('UPC', 'CISCO', 1, 1, '', 'loadInformation358', 0, ''), ". + "('TelePresence', 'TELEPRESENCE', 1, 1, '', 'loadInformation375', 0, ''), ('1000', 'TELEPRESENCE', 1, 1, '', 'loadInformation478', 0, ''), ('3000', 'TELEPRESENCE', 1, 1, '', 'loadInformation479', 0, ''), ('3200', 'TELEPRESENCE', 1, 1, '', 'loadInformation480', 0, ''), ('500-37', 'TELEPRESENCE', 1, 1, '', 'loadInformation481', 0, ''), ('1300-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation505', 0, ''), ('1100', 'TELEPRESENCE', 1, 1, '', 'loadInformation520', 0, ''), ('200', 'TELEPRESENCE', 1, 1, '', 'loadInformation557', 0, ''), ('400', 'TELEPRESENCE', 1, 1, '', 'loadInformation558', 0, ''), ('EX90', 'TELEPRESENCE', 1, 1, '', 'loadInformation584', 0, ''), ('500-32', 'TELEPRESENCE', 1, 1, '', 'loadInformation590', 0, ''), ('1300-47', 'TELEPRESENCE', 1, 1, '', 'loadInformation591', 0, ''), ('TX1310-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation596', 0, ''), ('EX60', 'TELEPRESENCE', 1, 1, '', 'loadInformation604', 0, ''), ('C90', 'TELEPRESENCE', 1, 1, '', 'loadInformation606', 0, ''), ('C60', 'TELEPRESENCE', 1, 1, '', 'loadInformation607', 0, ''), ('C40', 'TELEPRESENCE', 1, 1, '', 'loadInformation608', 0, ''), ('C20', 'TELEPRESENCE', 1, 1, '', 'loadInformation609', 0, ''), ('C20-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation610', 0, ''), ('C60-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation611', 0, ''), ('C40-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation612', 0, ''), ('C60-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation613', 0, ''), ('C60-52D', 'TELEPRESENCE', 1, 1, '', 'loadInformation614', 0, ''),('C60-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation615', 0, ''), ('C90-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation616', 0, ''), ('MX200', 'TELEPRESENCE', 1, 1, '', 'loadInformation617', 0, ''), ('TX9000', 'TELEPRESENCE', 1, 1, '', 'loadInformation619', 0, ''), ('TX9200', 'TELEPRESENCE', 1, 1, '', 'loadInformation620', 0, ''), ('SX20', 'TELEPRESENCE', 1, 1, '', 'loadInformation626', 0, ''), ('MX300', 'TELEPRESENCE', 1, 1, '', 'loadInformation627', 0, ''), ('C40-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation633', 0, ''), ('Jabber', 'CISCO', 1, 1, '', 'loadInformation652', 0, ''), ". + "('S60', 'NOKIA', 0, 1, '', 'loadInformation376', 0, ''), ('9971', 'CISCO', 1, 1, '', 'loadInformation493', 0, ''), ('9951', 'CISCO', 1, 1, '', 'loadInformation537', 0, ''), ('8961', 'CISCO', 1, 1, '', 'loadInformation540', 0, ''), ('Iphone', 'APPLE', 0, 1, '', 'loadInformation562', 0, ''), ('Android', 'ANDROID', 0, 1, '', 'loadInformation575', 0, ''), ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.5.3', 'loadInformation577', 0, ''), ('7821', 'CISCO', 1, 1, '', 'loadInformation621', 0, ''), ('7841', 'CISCO', 1, 1, '', 'loadInformation622', 0, ''), ('7861', 'CISCO', 1, 1, '', 'loadInformation623', 0, ''), ('VXC 6215', 'CISCO', 1, 1, '', 'loadInformation634', 0, ''), ('8831', 'CISCO', 1, 1, '', 'loadInformation659', 0, ''), ('8841', 'CISCO', 1, 1, '', 'loadInformation683', 0, ''), ('8851', 'CISCO', 1, 1, '', 'loadInformation684', 0, ''), ('8861', 'CISCO', 1, 1, '', 'loadInformation685', 0, ''), ". + "('Analog', 'CISCO', 1, 1, '', 'loadInformation30027', 0, ''), ('ISDN', 'CISCO', 1, 1, '', 'loadInformation30028', 0, ''), ('SCCP GW', 'CISCO', 1, 1, '', 'loadInformation30032', 0, ''), ('IP-STE', 'CISCO', 1, 1, '', 'loadInformation30035', 0, ''), ". + "('SPA 521S', 'CISCO', 1, 1, '', 'loadInformation80000', 0, ''), ('SPA 502G', 'CISCO', 1, 1, '', 'loadInformation80003', 0, ''), ('SPA 504G', 'CISCO', 1, 1, '', 'loadInformation80004', 0, ''), ('SPA 525G', 'CISCO', 1, 1, '', 'loadInformation80005', 0, ''), ('SPA 525G2', 'CISCO', 1, 1, '', 'loadInformation80009', 0, ''), ('SPA 303G', 'CISCO', 1, 1, '', 'loadInformation80011', 0, ''),". + "('IP Communicator', 'CISCO', 1, 1, '', 'loadInformation30016', 0, NULL), ('Nokia E', 'Nokia', 1, 28, '', 'loadInformation275', 0, NULL), ('VGC Phone', 'CISCO', 1, 1, '', 'loadInformation10', 0, NULL),". + "('7911-sip', 'CISCO-SIP', 1, 1, 'SIP11.9-2-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_sip_template'),". + "('9951-sip', 'CISCO-SIP', 1, 1, 'sip9951.9-2-2SR1-9', 'loadinformation537', 1, 'SEP0000000000.cnf.xml_99xx_sip_template'),". + "('VGC Virtual', 'CISCO', 1, 1, '', 'loadInformation11', 0, NULL);"; $check = $db->query($sql); if (DB::IsError($check)) { die_freepbx("Can not create sccpdevmodel table, error:$check\n"); @@ -621,85 +757,73 @@ function InstallDB_CreateSccpDeviceConfigView($sccp_compatible) outn("
  • " . _("(Re)Create sccpdeviceconfig view") . "
  • "); $sql = ""; if ($sccp_compatible < 431) { - $sql = "CREATE OR REPLACE + $sql = " + CREATE OR REPLACE ALGORITHM = MERGE VIEW sccpdeviceconfig AS - SELECT GROUP_CONCAT( CONCAT_WS( ',', buttonconfig.type, buttonconfig.name, buttonconfig.options ) - ORDER BY instance ASC - SEPARATOR ';' ) AS button, - sccpdevice.type AS type, - sccpdevice.addon AS addon, - sccpdevice.description AS description, - sccpdevice.tzoffset AS tzoffset, - sccpdevice.transfer AS transfer, - sccpdevice.cfwdall AS cfwdall, - sccpdevice.cfwdbusy AS cfwdbusy, - sccpdevice.imageversion AS imageversion, - sccpdevice.deny AS deny, - sccpdevice.permit AS permit, - sccpdevice.dndFeature AS dndFeature, - sccpdevice.directrtp AS directrtp, - sccpdevice.earlyrtp AS earlyrtp, - sccpdevice.mwilamp AS mwilamp, - sccpdevice.mwioncall AS mwioncall, - sccpdevice.pickupexten AS pickupexten, - sccpdevice.pickupcontext AS pickupcontext, - sccpdevice.pickupmodeanswer AS pickupmodeanswer, - sccpdevice.private AS private, - sccpdevice.privacy AS privacy, - sccpdevice.nat AS nat, - sccpdevice.softkeyset AS softkeyset, - sccpdevice.audio_tos AS audio_tos, - sccpdevice.audio_cos AS audio_cos, - sccpdevice.video_tos AS video_tos, - sccpdevice.video_cos AS video_cos, - sccpdevice.conf_allow AS conf_allow, - sccpdevice.conf_play_general_announce AS conf_play_general_announce, - sccpdevice.conf_play_part_announce AS conf_play_part_announce, - sccpdevice.conf_mute_on_entry AS conf_mute_on_entry, - sccpdevice.conf_music_on_hold_class AS conf_music_on_hold_class, - sccpdevice.conf_show_conflist AS conf_show_conflist, - sccpdevice.setvar AS setvar, - sccpdevice.disallow AS disallow, - sccpdevice.allow AS allow, - sccpdevice.backgroundImage AS backgroundImage, - sccpdevice.ringtone AS ringtone, - sccpdevice.name AS name - FROM sccpdevice - LEFT JOIN sccpbuttonconfig buttonconfig ON ( buttonconfig.device = sccpdevice.name ) - GROUP BY sccpdevice.name;"; + + SELECT GROUP_CONCAT( CONCAT_WS( ',', buttonconfig.type, buttonconfig.name, buttonconfig.options ) + ORDER BY instance ASC + SEPARATOR ';' ) AS button, + `sccpdevice`.`type` AS `type`,`sccpdevice`.`addon` AS `addon`,`sccpdevice`.`description` AS `description`,`sccpdevice`.`tzoffset` AS `tzoffset`, + `sccpdevice`.`transfer` AS `transfer`,`sccpdevice`.`cfwdall` AS `cfwdall`,`sccpdevice`.`cfwdbusy` AS `cfwdbusy`,`sccpdevice`.`imageversion` AS `imageversion`, + `sccpdevice`.`deny` AS `deny`,`sccpdevice`.`permit` AS `permit`,`sccpdevice`.`dndFeature` AS `dndFeature`,`sccpdevice`.`directrtp` AS `directrtp`, + `sccpdevice`.`earlyrtp` AS `earlyrtp`,`sccpdevice`.`mwilamp` AS `mwilamp`,`sccpdevice`.`mwioncall` AS `mwioncall`,`sccpdevice`.`pickupexten` AS `pickupexten`, + `sccpdevice`.`pickupcontext` AS `pickupcontext`,`sccpdevice`.`pickupmodeanswer` AS `pickupmodeanswer`,`sccpdevice`.`private` AS `private`, + `sccpdevice`.`privacy` AS `privacy`,`sccpdevice`.`nat` AS `nat`,`sccpdevice`.`softkeyset` AS `softkeyset`,`sccpdevice`.`audio_tos` AS `audio_tos`, + `sccpdevice`.`audio_cos` AS `audio_cos`,`sccpdevice`.`video_tos` AS `video_tos`,`sccpdevice`.`video_cos` AS `video_cos`,`sccpdevice`.`conf_allow` AS `conf_allow`, + `sccpdevice`.`conf_play_general_announce` AS `conf_play_general_announce`,`sccpdevice`.`conf_play_part_announce` AS `conf_play_part_announce`, + `sccpdevice`.`conf_mute_on_entry` AS `conf_mute_on_entry`,`sccpdevice`.`conf_music_on_hold_class` AS `conf_music_on_hold_class`, + `sccpdevice`.`conf_show_conflist` AS `conf_show_conflist`,`sccpdevice`.`setvar` AS `setvar`,`sccpdevice`.`disallow` AS `disallow`, + `sccpdevice`.`allow` AS `allow`,`sccpdevice`.`backgroundImage` AS `backgroundImage`,`sccpdevice`.`ringtone` AS `ringtone`,`sccpdevice`.`name` AS `name` + FROM sccpdevice + LEFT JOIN sccpbuttonconfig buttonconfig ON ( buttonconfig.device = sccpdevice.name ) + GROUP BY sccpdevice.name;"; } else { - $sql = "DROP VIEW IF EXISTS sccpdeviceconfig; - DROP VIEW IF EXISTS sccpuserconfig;"; + /* $sql = " + CREATE OR REPLACE + ALGORITHM = MERGE + VIEW sccpdeviceconfig AS + SELECT IF(sccpdevice._profileid = 0, + GROUP_CONCAT(CONCAT_WS( ',', defbutton.buttontype, defbutton.name, defbutton.options ) ORDER BY defbutton.instance ASC SEPARATOR ';' ), + GROUP_CONCAT( CONCAT_WS( ',', userbutton.buttontype, userbutton.name, userbutton.options ) ORDER BY userbutton.instance ASC SEPARATOR ';' ) + ) AS button, + sccpdevice.* + FROM sccpdevice + LEFT JOIN sccpbuttonconfig defbutton ON ( defbutton.ref = sccpdevice.name ) + LEFT JOIN sccpbuttonconfig userbutton ON ( userbutton.ref = sccpdevice._loginname ) + LEFT JOIN sccpline ON ( sccpline.name = sccpdevice._loginname) + GROUP BY sccpdevice.name;"; +*/ + $sql = "DROP VIEW IF EXISTS `sccpdeviceconfig`; + DROP VIEW IF EXISTS `sccpuserconfig`;"; /// global $hw_mobil; global $mobile_hw; if ($mobile_hw == '1') { - $sql .= "CREATE OR REPLACE - ALGORITHM = MERGE - VIEW sccpdeviceconfig AS - SELECT GROUP_CONCAT( CONCAT_WS( ',', sccpbuttonconfig.buttontype, sccpbuttonconfig.name, sccpbuttonconfig.options ) - ORDER BY instance ASC SEPARATOR ';' ) AS sccpbutton, sccpdevice.* - FROM sccpdevice - LEFT JOIN sccpbuttonconfig ON (sccpbuttonconfig.reftype = 'sccpdevice' AND sccpbuttonconfig.ref = sccpdevice.name ) - GROUP BY sccpdevice.name; "; - $sql .= "CREATE OR REPLACE ALGORITHM = MERGE VIEW sccpuserconfig AS - SELECT GROUP_CONCAT( CONCAT_WS( ',', sccpbuttonconfig.buttontype, sccpbuttonconfig.name, sccpbuttonconfig.options ) - ORDER BY instance ASC SEPARATOR ';' ) AS button, sccpuser.* - FROM sccpuser - LEFT JOIN sccpbuttonconfig ON ( sccpbuttonconfig.reftype = 'sccpuser' AND sccpbuttonconfig.ref = sccpuser.id) - GROUP BY sccpuser.name; "; + $sql .= "CREATE OR REPLACE ALGORITHM = MERGE VIEW sccpdeviceconfig AS + SELECT GROUP_CONCAT( CONCAT_WS( ',', sccpbuttonconfig.buttontype, sccpbuttonconfig.name, sccpbuttonconfig.options ) + ORDER BY instance ASC SEPARATOR ';' ) AS sccpbutton, sccpdevice.* + FROM sccpdevice + LEFT JOIN sccpbuttonconfig ON (sccpbuttonconfig.reftype = 'sccpdevice' AND sccpbuttonconfig.ref = sccpdevice.name ) + GROUP BY sccpdevice.name; "; + $sql .= "CREATE OR REPLACE ALGORITHM = MERGE VIEW sccpuserconfig AS + SELECT GROUP_CONCAT( CONCAT_WS( ',', sccpbuttonconfig.buttontype, sccpbuttonconfig.name, sccpbuttonconfig.options ) + ORDER BY instance ASC SEPARATOR ';' ) AS button, sccpuser.* + FROM sccpuser + LEFT JOIN sccpbuttonconfig ON ( sccpbuttonconfig.reftype = 'sccpuser' AND sccpbuttonconfig.ref = sccpuser.id) + GROUP BY sccpuser.name; "; } else { $sql .= "CREATE OR REPLACE ALGORITHM = MERGE VIEW sccpdeviceconfig AS SELECT case sccpdevice._profileid when 0 then - (select GROUP_CONCAT(CONCAT_WS( ',', defbutton.buttontype, defbutton.name, defbutton.options ) SEPARATOR ';') from sccpbuttonconfig as defbutton where defbutton.ref = sccpdevice.name ORDER BY defbutton.instance ) + (select GROUP_CONCAT(CONCAT_WS( ',', defbutton.buttontype, defbutton.name, defbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as defbutton where defbutton.ref = sccpdevice.name ORDER BY defbutton.instance ) when 1 then - (select GROUP_CONCAT(CONCAT_WS( ',', userbutton.buttontype, userbutton.name, userbutton.options ) SEPARATOR ';') from sccpbuttonconfig as userbutton where userbutton.ref = sccpdevice._loginname ORDER BY userbutton.instance ) + (select GROUP_CONCAT(CONCAT_WS( ',', userbutton.buttontype, userbutton.name, userbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as userbutton where userbutton.ref = sccpdevice._loginname ORDER BY userbutton.instance ) when 2 then - (select GROUP_CONCAT(CONCAT_WS( ',', homebutton.buttontype, homebutton.name, homebutton.options ) SEPARATOR ';') from sccpbuttonconfig as homebutton where homebutton.ref = sccpuser.homedevice ORDER BY homebutton.instance ) + (select GROUP_CONCAT(CONCAT_WS( ',', homebutton.buttontype, homebutton.name, homebutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as homebutton where homebutton.ref = sccpuser.homedevice ORDER BY homebutton.instance ) end as button, if(sccpdevice._profileid = 0, sccpdevice._description, sccpuser.description) as description, sccpdevice.* FROM sccpdevice LEFT JOIN sccpuser sccpuser ON ( sccpuser.name = sccpdevice._loginname ) @@ -715,7 +839,7 @@ function InstallDB_CreateSccpDeviceConfigView($sccp_compatible) function CreateBackUpConfig() { global $amp_conf; - outn("
  • " . _("Creating Config BackUp") . "
  • "); + outn("
  • " . _("Create Config BackUp") . "
  • "); $cnf_int = \FreePBX::Config(); $backup_files = array('extensions','extconfig','res_mysql', 'res_config_mysql','sccp','sccp_hardware','sccp_extensions'); $backup_ext = array('_custom.conf', '_additional.conf','.conf'); @@ -724,14 +848,8 @@ function CreateBackUpConfig() $fsql = $dir.'/sccp_backup_'.date("Ymd").'.sql'; $result = exec('mysqldump '.$amp_conf['AMPDBNAME'].' --password='.$amp_conf['AMPDBPASS'].' --user='.$amp_conf['AMPDBUSER'].' --single-transaction >'.$fsql, $output); - try { - $zip = new \ZipArchive(); - } catch (\Exception $e) { - outn("
    "); - outn("PHPx.x-zip not installed where x.x is the installed PHP version. Install it before continuing !"); - die_freepbx(); - } - $filename = $dir . "/sccp_install_backup" . date("Ymd"). ".zip"; + $zip = new \ZipArchive(); + $filename = $dir . "/sccp_instal_backup" . date("Ymd"). ".zip"; if ($zip->open($filename, \ZIPARCHIVE::CREATE)) { foreach ($backup_files as $file) { foreach ($backup_ext as $b_ext) { @@ -745,7 +863,7 @@ function CreateBackUpConfig() } $zip->close(); } else { - outn("
  • " . _("Error Creating BackUp: ") . $filename ."
  • "); + outn("
  • " . _("Error Create BackUp: ") . $filename ."
  • "); } unlink($fsql); outn("
  • " . _("Create Config BackUp: ") . $filename ."
  • "); @@ -777,11 +895,11 @@ function Setup_RealTime() $cnf_read = \FreePBX::LoadConfig(); $backup_ext = array('_custom.conf', '_additional.conf','.conf'); - $def_config = array('sccpdevice' => 'mysql,asterisk,sccpdeviceconfig', 'sccpline' => ' mysql,asterisk,sccpline'); + $def_config = array('sccpdevice' => 'mysql,sccp,sccpdeviceconfig', 'sccpline' => ' mysql,sccp,sccpline'); $def_bd_config = array('dbhost' => $amp_conf['AMPDBHOST'], 'dbname' => $amp_conf['AMPDBNAME'], 'dbuser' => $amp_conf['AMPDBUSER'], 'dbpass' => $amp_conf['AMPDBPASS'], 'dbport' => '3306', 'dbsock' => '/var/lib/mysql/mysql.sock','dbcharset'=>'utf8'); - $def_bd_sec = 'asterisk'; + $def_bd_sec = 'sccp'; $dir = $cnf_int->get('ASTETCDIR'); $res_conf_sql = ini_get('pdo_mysql.default_socket'); @@ -844,4 +962,66 @@ function Setup_RealTime() $cnf_wr->writeConfig($ext_conf_file, $ext_conf, false); } -?> +CheckSCCPManagerDBTables($table_req); +#CheckPermissions(); +CheckAsteriskVersion(); +$sccp_version = array(); +$sccp_version = CheckChanSCCPCompatible(); +$sccp_compatible = $sccp_version[0]; +$chanSCCPWarning = $sccp_version[1] ^= 1; +outn("
  • " . _("Sccp model Compatible code : ") . $resultReturned[0] . "
  • "); +if ($sccp_compatible == 0) { +// die_freepbx('Chan Sccp not Found. Install it before continuing'); + outn("
    "); + outn("Chan Sccp not Found. Install it before continuing !"); + die(); +} +$db_config = Get_DB_config($sccp_compatible); +$sccp_db_ver = CheckSCCPManagerDBVersion(); + +// BackUp Old config +CreateBackUpConfig(); +RenameConfig(); +if ($sccp_compatible > 431) { + InstallDB_sccpuser(); + InstallDB_Buttons(); +} + +InstallDB_sccpsettings(); +InstallDB_sccpdevmodel(); +InstallDB_updateSchema($db_config); +$stmt = $db->prepare('SELECT CASE WHEN EXISTS(SELECT 1 FROM sccpdevmodel) THEN 0 ELSE 1 END AS IsEmpty;'); +$stmt->execute(); +$result = $stmt->fetchAll(\PDO::FETCH_ASSOC); +if ($result[0]['IsEmpty']) { + outn("Populating sccpdevmodel..."); + InstallDB_fillsccpdevmodel(); +} +if (!$sccp_db_ver) { + InstallDB_updateSccpDevice(); +} else { + outn("Skip update Device model"); +} + +InstallDB_createButtonConfigTrigger(); +InstallDB_CreateSccpDeviceConfigView($sccp_compatible); +InstallDB_updateDBVer($sccp_compatible); +if ($chanSCCPWarning) { + outn("
    "); + outn("Warning: Upgrade chan_sccp_b to use full ami functionality"); +} +if (!$sccp_db_ver) { + Setup_RealTime(); + outn("
    "); + outn("Install Complete !"); +} else { + outn("
    "); + outn("Update Complete !"); +} +outn("
    "); + +// $ss->handleSubmit($request); +// $ss->createDefaultSccpConfig(); +// $ss->saveSccpSettings(); +// +//} diff --git a/module.xml b/module.xml index c0e6020..1eaaae5 100644 --- a/module.xml +++ b/module.xml @@ -1,168 +1,28 @@ sccp_manager SCCP Manager - 14.2.0.1 + 14.0.0.2M setup SCCP Connectivity - Steve Lad, Alex GP - extended + Steve Lad + Alex GP + extended SCCP Phone and Extension Manager - Server Config - System Parameters - Phones Manager + Server Config + System Parameters + Phones Manager - * Version 13.0.0.1 * - Alfa Release tested on freepbx v.13.0.192.16, v.14.0.1.5 - * Version 13.0.0.2 * - Release tested - * Version 14.0.0.1 * - Alfa Release new DB structure Add User mobility - * Version 14.1.0.1 * - Migrated to chan-sccp repo - * Version 14.2.0.1 * - Retired old interface - min chan-sccp v433 + * Version 13.0.0.1 * - Alfa Release tested on freepbx v.13.0.192.16, v.14.0.1.5 + * Version 13.0.0.2 * - Release tested + * Version 14.0.0.1 * - Alfa Release new DB structure Add User mobility - https://github.com/chan-sccp/sccp_manager + 13.0.0.2M - https://github.com/chan-sccp/sccp_manager - https://raw.githubusercontent.com/chan-sccp/sccp_manager/develop/sccpManagerUpdater.json - GPL + https://github.com/chan-sccp/sccp_manager + GPL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    - - - - - - - - - - - - -
    - - - - - - - - - - - - -
    - - - - - -
    -
    diff --git a/page.html.php b/page.html.php index f2ac6cc..5ede85b 100644 --- a/page.html.php +++ b/page.html.php @@ -21,7 +21,7 @@ - + diff --git a/page.sccpsettings.php b/page.sccpsettings.php index 363254b..deb8315 100644 --- a/page.sccpsettings.php +++ b/page.sccpsettings.php @@ -11,7 +11,7 @@ if (!defined('FREEPBX_IS_AUTH')) { // // Initialise page before to avoid double calls and improve performance -$display_page = FreePBX::create()->Sccp_manager->settingsShowPage(); +$display_page = FreePBX::create()->Sccp_manager->myShowPage(); $display_info = _("SCCP Server Settings"); // standardise code to reduce base include('page.html.php'); diff --git a/uninstall.php b/uninstall.php index e3b2651..6974b3b 100644 --- a/uninstall.php +++ b/uninstall.php @@ -34,11 +34,11 @@ if (!defined('FREEPBX_IS_AUTH')) { die('No direct script access allowed'); } -global $db; -$version = FreePBX::Config()->get('ASTVERSION'); + global $db; + $version = FreePBX::Config()->get('ASTVERSION'); -out('Removing all Sccp_manager tables'); -$tables = array('sccpdevmodel', 'sccpsettings'); + out('Removing all Sccp_manager tables'); + $tables = array('sccpdevmodel', 'sccpsettings'); foreach ($tables as $table) { $sql = "DROP TABLE IF EXISTS {$table}"; $result = $db->query($sql); @@ -63,6 +63,7 @@ if (!empty($version)) { if (DB::IsError($result)) { die_freepbx($result->getDebugInfo()); } + unset($result); /* Comment: Maybe save in sccpsettings, if the chan_sccp tables already existed in the database or if they were created by install.php */ /* So that you know if it is safe to drop/delete them */ @@ -77,5 +78,5 @@ if (!empty($version)) { * */ } + echo "done
    \n"; -?>