commit 972b213b680556e971b4f72f20da30ce60f81e76 Author: PhantomVl Date: Tue Sep 12 17:08:52 2017 +0300 Пререлиз 12.09.2017 Замена функции чтения sccp.conf diff --git a/!Readme.txt/Conferencing.txt b/!Readme.txt/Conferencing.txt new file mode 100644 index 0000000..ced8269 --- /dev/null +++ b/!Readme.txt/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. Usefull 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/!Readme.txt/RedialMenu.txt b/!Readme.txt/RedialMenu.txt new file mode 100644 index 0000000..75cf3d1 --- /dev/null +++ b/!Readme.txt/RedialMenu.txt @@ -0,0 +1,20 @@ + + +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. diff --git a/!Readme.txt/SEPXML.txt b/!Readme.txt/SEPXML.txt new file mode 100644 index 0000000..b8780db --- /dev/null +++ b/!Readme.txt/SEPXML.txt @@ -0,0 +1,5 @@ +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 \ No newline at end of file diff --git a/!Readme.txt/bacgroundImage.txt b/!Readme.txt/bacgroundImage.txt new file mode 100644 index 0000000..48b877e --- /dev/null +++ b/!Readme.txt/bacgroundImage.txt @@ -0,0 +1,42 @@ +https://github.com/chan-sccp/chan-sccp/wiki/Adding-custom-background-images + +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. \ No newline at end of file diff --git a/!Readme.txt/make_sccp.txt b/!Readme.txt/make_sccp.txt new file mode 100644 index 0000000..8747f29 --- /dev/null +++ b/!Readme.txt/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/README.md b/README.md new file mode 100644 index 0000000..c69c6aa --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +## Welcome to Chan_SCCP GUI Manager + +``` + ______ _____ ______ __ +| ____| | __ \| _ \ \ / / +| |__ _ __ ___ ___| |__) | |_) \ V / +| __| '__/ _ \/ _ \ ___/| _ < > < +| | | | | __/ __/ | | |_) / . \ +|_| |_| \___|\___|_| |____/_/ \_\ +Your Open Source Asterisk PBX GUI Solution +``` +SCCP Manager is free software. Please see the file COPYING for details. +For documentation, please see the files in the doc subdirectory. +For building and installation instructions please see the INSTALL file. + +[![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) +[![Documentation](https://img.shields.io/badge/docs-wiki-blue.svg)](https://github.com/chan-sccp/chan-sccp/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.6.2 (absolute minimum) + - asterisk >= 13.7 or asterisk >= 14.0 recommended +- gui: + - freepbx >= 13.0.192 +- Chan_SCCP module: + - configure flags ./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate + - creating mysql DB from sorce (mysql -u root asterisk < mysql-v5.sql) + - cofigure TFTP server + - cofigure DHCP server +- standard posix compatible applications like sed, awk, tr + +### Setting up a FreePBX system +[See our WIKI](http://wiki.freepbx.org/display/FOP/Install+FreePBX) + +### Setting up a Sccp manager +[See our WIKI] https://github.com/chan-sccp/chan-sccp/wiki/How-to-setup-the-chan_sccp-Module + +### Module requred +SCCP channel driver Compiling: + +./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate +or +./configure --enable-indications --enable-conference --enable-advanced-functions --enable-distributed-devicestate + +copy all from sorce/conf/tftp to /tftpboot-directory + +create mysql-db +cd sorce/conf +mysql -u root asterisk < mysql-v5.sql + + + + diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php new file mode 100644 index 0000000..a9db677 --- /dev/null +++ b/Sccp_manager.class.php @@ -0,0 +1,1980 @@ + 'VPBXSCCP', + "bindaddr" => '0.0.0.0', "port" => '2000', + "deny" => '0.0.0.0/0.0.0.0', + "permit" => '0.0.0.0/0.0.0.0', + "dateformat" => 'D.M.Y', + "disallow" => 'all', "allow" => 'alaw;ulaw', + "devicetable" => 'sccpdevice', + "linetable" => 'sccpline', + "tftp_path" => '/tftpboot' + ); + public $xml_data; + public $keysetdefault = array('onhook' => 'redial,newcall,cfwdall,dnd,pickup,gpickup,private', + 'connected' => 'hold,endcall,park,vidmode,select,cfwdall,cfwdbusy,idivert', + 'onhold' => 'resume,newcall,endcall,transfer,conflist,select,dirtrfr,idivert,meetme', + 'ringin' => 'answer,endcall,transvm,idivert', + 'offhook' => 'redial,endcall,private,cfwdall,cfwdbusy,pickup,gpickup,meetme,barge', + 'conntrans' => 'hold,endcall,transfer,conf,park,select,dirtrfr,vidmode,meetme,cfwdall,cfwdbusy', + 'digitsfoll' => 'back,endcall,dial', + 'connconf' => 'conflist,newcall,endcall,hold,vidmode', + 'ringout' => 'empty,endcall,transfer,cfwdall,idivert', + 'offhookfeat' => 'redial,endcall', + 'onhint' => 'redial,newcall,pickup,gpickup,barge', + 'onstealable' => 'redial,newcall,cfwdall,pickup,gpickup,dnd,intrcpt', + 'holdconf' => 'resume,newcall,endcall,join', + 'uriaction' => 'default'); +// Cisco Language Code / Directory + public $sccp_lang = array('ar_SA' => array('code' => 'ar', 'language' => 'Arabic', 'locale' => 'Arabic_Saudi_Arabia'), + 'bg_BG' => array('code' => 'bg', 'language' => 'Bulgarian', 'locale' => 'Bulgarian_Bulgaria'), + 'cz_CZ' => array('code' => 'cz', 'language' => 'Czech', 'locale' => 'Czech_Czech_Republic'), + 'da_DK' => array('code' => 'da', 'language' => 'Danish', 'locale' => 'Danish_Denmark'), + 'de_DE' => array('code' => 'de', 'language' => 'German', 'locale' => 'German_Germany'), + 'el_GR' => array('code' => 'el', 'language' => 'Greek', 'locale' => 'Greek_Greece'), + 'en_AU' => array('code' => 'en', 'language' => 'English', 'locale' => 'AU_English_United_States'), + 'en_GB' => array('code' => 'en', 'language' => 'English', 'locale' => 'English_United_Kingdom'), + 'en_US' => array('code' => 'en', 'language' => 'English', 'locale' => 'English_United_States'), + 'es_ES' => array('code' => 'es', 'language' => 'Spanish', 'locale' => 'Spanish_Spain'), + 'et_EE' => array('code' => 'et', 'language' => 'Estonian', 'locale' => 'Estonian_Estonia'), + 'fi_FI' => array('code' => 'fi', 'language' => 'Finnish', 'locale' => 'Finnish_Finland'), + 'fr_CA' => array('code' => 'fr', 'language' => 'French', 'locale' => 'French_Canada'), + 'fr_FR' => array('code' => 'fr', 'language' => 'French', 'locale' => 'French_France'), + 'he_IL' => array('code' => 'he', 'language' => 'Hebrew', 'locale' => 'Hebrew_Israel'), + 'hr_HR' => array('code' => 'hr', 'language' => 'Croatian', 'locale' => 'Croatian_Croatia'), + 'hu_HU' => array('code' => 'hu', 'language' => 'Hungarian', 'locale' => 'Hungarian_Hungary'), + 'it_IT' => array('code' => 'it', 'language' => 'Italian', 'locale' => 'Italian_Italy'), + 'ja_JP' => array('code' => 'ja', 'language' => 'Japanese', 'locale' => 'Japanese_Japan'), + 'ko_KO' => array('code' => 'ko', 'language' => 'Korean', 'locale' => 'Korean_Korea_Republic'), + 'lt_LT' => array('code' => 'lt', 'language' => 'Lithuanian', 'locale' => 'Lithuanian_Lithuania'), + 'lv_LV' => array('code' => 'lv', 'language' => 'Latvian', 'locale' => 'Latvian_Latvia'), + 'nl_NL' => array('code' => 'nl', 'language' => 'Dutch', 'locale' => 'Dutch_Netherlands'), + 'no_NO' => array('code' => 'no', 'language' => 'Norwegian', 'locale' => 'Norwegian_Norway'), + 'pl_PL' => array('code' => 'pl', 'language' => 'Polish', 'locale' => 'Polish_Poland'), + 'pt_BR' => array('code' => 'pt', 'language' => 'Portuguese', 'locale' => 'Portuguese_Brazil'), + 'pt_PT' => array('code' => 'pt', 'language' => 'Portuguese', 'locale' => 'Portuguese_Portugal'), + 'ro_RO' => array('code' => 'ro', 'language' => 'Romanian', 'locale' => 'Romanian_Romania'), + 'ru_RU' => array('code' => 'ru', 'language' => 'Russian', 'locale' => 'Russian_Russian_Federation'), + 'sk_SK' => array('code' => 'sk', 'language' => 'Slovakian', 'locale' => 'Slovak_Slovakia'), + 'sl_SL' => array('code' => 'sl', 'language' => 'Slovenian', 'locale' => 'Slovenian_Slovenia'), + 'sr_ME' => array('code' => 'sr', 'language' => 'Serbian', 'locale' => 'Serbian_Republic_of_Montenegro'), + 'sr_RS' => array('code' => 'rs', 'language' => 'Serbian', 'locale' => 'Serbian_Republic_of_Serbia'), + 'sv_SE' => array('code' => 'sv', 'language' => 'Swedish', 'locale' => 'Swedish_Sweden'), + 'th_TH' => array('code' => 'th', 'language' => 'Thailand', 'locale' => 'Thai_Thailand'), + 'tr_TR' => array('code' => 'tr', 'language' => 'Turkish', 'locale' => 'Turkish_Turkey'), + 'zh_CN' => array('code' => 'cn', 'language' => 'Chinese', 'locale' => 'Chinese_China'), + 'zh_TW' => array('code' => 'zh', 'language' => 'Chinese', 'locale' => 'Chinese_Taiwan') + ); + + public function __construct($freepbx = null) { + if ($freepbx == null) { + throw new Exception("Not given a FreePBX Object"); + } + $this->errors = array(); + $this->FreePBX = $freepbx; + $this->db = $freepbx->Database; + $this->cnf_wr = \FreePBX::WriteConfig(); + $this->cnf_read =\FreePBX::LoadConfig(); + + + $this->v = new \Respect\Validation\Validator(); + + $this->getSccpSettingsDB(false); // Overwrite Exist +// $this->getSccpSetingINI(false); // get from sccep.ini + $this->init_sccp_path(); + $this->initVarfromDefs(); + $this->initTftpLang(); + + + // Load Advanced Form Constuctor Data + if (file_exists(__DIR__ . '/views/sccpgeneral.xml')) { + $this->xml_data = simplexml_load_file(__DIR__ . '/views/sccpgeneral.xml'); + $this->initVarfromXml(); // Overwrite Exist + } + } + + /* + * Generate Input elements in Html Code from sccpgeneral.xml + */ + + public function ShowGroup($grup_name, $heder_show, $form_prefix = 'sccp', $form_values = null) { + $htmlret = ""; + if (empty($form_values)) { + $form_values = $this->sccpvalues; + } + if ((array) $this->xml_data) { + foreach ($this->xml_data->xpath('//page_group[@name="' . $grup_name . '"]') as $item) { +// $htmlret .= print_r($item,1); + $htmlret .= load_view(__DIR__ . '/views/formShow.php', array( + 'itm' => $item, 'h_show' => $heder_show, + 'form_prefix' => $form_prefix, 'fvalues' => $form_values, + 'tftp_lang' => $this->getTftpLang()) + ); + } + } else { + $htmlret .= load_view(__DIR__ . '/views/formShowError.php'); + } + return $htmlret; + } + + /* + * Load config vars from base array + */ + + public function initVarfromDefs() { + foreach ($this->sccpDefaults as $key => $value) { + if (empty($this->sccpvalues[$key])) { + $this->sccpvalues[$key] = array('keyword' => $key, 'data' => $value, 'type' => '0', 'seq' => '0'); + } + } + } + + /* + * Load config vars from xml + */ + + public function initVarfromXml() { + if ((array) $this->xml_data) { + foreach ($this->xml_data->xpath('//page_group') as $item) { + foreach ($item->children() as $child) { + $seq = 0; + if (!empty($child['seq'])) { + $seq = (string) $child['seq']; + } + if ($seq < 99) { + + if ($child['type'] == 'IE') { + foreach ($child->xpath('input') as $value) { + $tp = 0; + if (empty($value->value)) { + $datav = (string) $value->default; + } else { + $datav = (string) $value->value; + } + if (strtolower($value->type) == 'number') + $tp = 1; + if (empty($this->sccpvalues[(string) $value->name])) { + $this->sccpvalues[(string) $value->name] = array('keyword' => (string) $value->name, 'data' => $datav, 'type' => $tp, 'seq' => $seq); +// $this->sccpvalues[] = array('keyword' => (string)$value->name, 'data' =>(string)$value->default, 'type'=> '0'); + } + } + } + if ($child['type'] == 'IS' || $child['type'] == 'IED' ) { + if (empty($child->value)) { + $datav = (string) $child->default; + } else { + $datav = (string) $child->value; + } + if (empty($this->sccpvalues[(string) $child->name])) { + $this->sccpvalues[(string) $child->name] = array('keyword' => (string) $child->name, 'data' => $datav, 'type' => '2', 'seq' => $seq); +// $this->sccpvalues[] = array('keyword' => (string)$child->name, 'data' =>(string)$child-> default,'type'=>'0'); + } + } + if ($child['type'] == 'SLD' || $child['type'] == 'SLS' || $child['type'] == 'SLT' || $child['type'] == 'SL' || $child['type'] == 'SLM' || $child['type'] == 'SLZ' || $child['type'] == 'SLZN') { + if (empty($child->value)) { + $datav = (string) $child->default; + } else { + $datav = (string) $child->value; + } + if (empty($this->sccpvalues[(string) $child->name])) { + $this->sccpvalues[(string) $child->name] = array('keyword' => (string) $child->name, 'data' => $datav, 'type' => '2', 'seq' => $seq); + } + } + } + } + } + } + } + + public function doConfigPageInit($page) { + $this->doGeneralPost(); + } + + public function install() { + + } + + public function uninstall() { + + } + + public function backup() { + + } + + public function restore($backup) { + + } + + public function getActionBar($request) { + $buttons = array(); + switch ($request['display']) { + case 'sccp_phone': + if (empty($request['tech_hardware'])) { + break; + } + $buttons = array( + 'submit' => array( + 'name' => 'ajaxsubmit', + 'id' => 'ajaxsubmit', + 'value' => _("Submit") + ), + '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 myShowPage() { + $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" => _("General SCCP Settings"), + "page" => 'views/server.setting.php' + ), + "sccpdevice" => array( + "name" => _("SCCP Device"), + "page" => 'views/server.device.php' + ), + "sccpntp" => array( + "name" => _("SCCP Time"), + "page" => 'views/server.datetime.php' + ), + "sccpcodec" => array( + "name" => _("SCCP Codec"), + "page" => 'views/server.codec.php' + ), + "sccpkeyset" => array( + "name" => _("SCCP Device Keyset"), + "page" => 'views/server.keyset.php' + ), + "sccpmodels" => array( + "name" => _("SCCP Model information"), + "page" => 'views/server.model.php' + ) + ); + + foreach ($this->pagedata as &$page) { + ob_start(); + include($page['page']); + $page['content'] = ob_get_contents(); + ob_end_clean(); + } + } + + return $this->pagedata; + } + + public function PhoneShowPage() { + $request = $_REQUEST; + $action = !empty($request['action']) ? $request['action'] : ''; + $inputform = !empty($request['tech_hardware']) ? $request['tech_hardware'] : ''; + +// print_r($inputform); + 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' + ), + "sccpcodec" => array( + "name" => _("Device SCCP Codec"), + "page" => 'views/server.codec.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' + ) + ); + break; + } + foreach ($this->pagedata as &$page) { + ob_start(); + include($page['page']); + $page['content'] = ob_get_contents(); + ob_end_clean(); + } + } + + return $this->pagedata; + } + + 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 ajaxRequest($req, &$setting) { + switch ($req) { + case 'savesettings': + case "save_hardware": + case "delete_hardware": + case "getPhoneGrid": + case "getExtensionGrid": + case "getDeviceModel": + case "getUserGrid": + case "getSoftKey": + case "create_hw_tftp": + case "reset_dev": + case "model_enabled": + case "model_disabled": + case "model_update": + case "model_add": + case "model_delete": + case "updateSoftKey": + case "deleteSoftKey": + return true; + break; + } + return false; + } + + public function ajaxHandler() { + $request = $_REQUEST; + $msg = ''; + switch ($request['command']) { + case 'savesettings': + $action = isset($request['sccp_createlangdir']) ? $request['sccp_createlangdir'] : ''; + if ($action == 'yes') { + $this->init_tftp_lang_path(); + } + $this->save_submit($request); + $this->sccp_db_save_setting(); + $res = $this->sccp_core_comands(array('cmd' => 'sccp_reload')); + $msg = 'Config Saved: ' . $res['Response'] . '. Info :' . $res['data']; +// needreload(); + return array('status' => true, 'message' => $msg, 'reload' => true); + break; + case 'save_hardware': + $this->save_hw_phone($request); +// return array('status' => true, 'href' => 'config.php?display=sccp_phone', 'reload' => true); + return array('status' => true, 'search' => '?display=sccp_phone', 'hash' => 'sccpdevice'); + + return $this->save_hw_phone($request); + + break; + case 'delete_hardware': + if (!empty($request['idn'])) { + foreach ($request['idn'] as $idv) { + $msg = strpos($idv, 'SEP-'); + if (!(strpos($idv, 'SEP') === false)) { + $this->sccp_save_db('sccpdevice', array('name' => $idv), 'delete', "name"); + $this->sccp_save_db("sccpbuttons", array(), 'delete', '', $idv); + } + } + return array('status' => true, 'table_reload' => true, 'message' => 'HW is Delete ! '); + } + break; + case 'create_hw_tftp': + $this->sccp_create_tftp_XML(); + $models = $this->get_db_SccpTableData("SccpDevice"); + foreach ($models as $data) { + $ver_id = $this->sccp_create_device_XML($data['name']); + }; + return array('status' => true, 'message' => 'Create new CNF files Ver :' . $ver_id); + + break; + case 'reset_dev': + $msg = ''; + if (!empty($request['name'])) { + foreach ($request['name'] as $idv) { + $msg = strpos($idv, 'SEP-'); + if (!(strpos($idv, 'SEP') === false)) { + $res = $this->sccp_core_comands(array('cmd' => 'reset_phone', 'name' => $idv)); +// $msg = print_r($this->sccp_core_comands(array('cmd' => 'reset_phone', 'name' => $idv)), 1); + $msg = $res['Response'] . ' ' . $res['data']; + } + if ($idv == 'all') { + $dev_list = $this->sccp_get_active_devise(); + foreach ($dev_list as $key => $data) { + $res = $this->sccp_core_comands(array('cmd' => 'reset_phone', 'name' => $key)); + $msg .= $res['Response'] . '' . $res['data'] . ' '; +// $msg = print_r($this->sccp_core_comands(array('cmd' => 'reset_phone', 'name' => $key)), 1); + } + } + } + } + return array('status' => true, 'message' => 'Reset comand send ' . $msg, 'reload' => true); +// } + break; + case 'model_add': + $save_settings = array(); + $key_name = array('model', 'vendor', 'dns', 'buttons', 'loadimage', 'loadinformationid', 'nametemplet'); + $upd_mode = 'replace'; + case 'model_update': + if ($request['command'] == 'model_update') { + $key_name = array('model', 'loadimage', 'nametemplet'); + $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] = 'none'; + } + } + $this->sccp_save_db('sccpdevmodel', $save_settings, $upd_mode, "model"); + return array('status' => true, 'table_reload' => true); + } + return $save_settings; + break; + case 'model_enabled': + $model_set = '1'; + 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->sccp_save_db('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->sccp_save_db('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->getSccp_model_information($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->sccp_create_sccp_init(); + $msg = print_r($this->sccp_core_comands(array('cmd' => 'sccp_reload')), 1); + return array('status' => true, 'table_reload' => true); + } + break; + case "updateSoftKey": + if (!empty($request['id'])) { + $id_name = $request['id']; + $this->sccp_conf_init[$id_name]['type'] = "softkeyset"; + foreach ($this->keysetdefault as $keyl => $vall) { + if (!empty($request[$keyl])) { + $this->sccp_conf_init[$id_name][$keyl] = $request[$keyl]; + } + } + $this->sccp_create_sccp_init(); + $msg = print_r($this->sccp_core_comands(array('cmd' => 'sccp_reload')), 1); + + return array('status' => true, 'table_reload' => true); +// return $this->sccp_conf_init[$id_name]; + } + +// sccp_conf_init + break; + case 'getSoftKey': + $result = array(); + $i = 0; + $keyl = 'default'; + foreach ($this->sccp_list_keysets() as $keyl => $vall) { + $result[$i]['softkeys'] = $keyl; + if ($keyl == 'default') { + foreach ($this->keysetdefault 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->get_db_SccpTableData('SccpExtension'); + if (empty($result)) { + $result = array(); + } + return $result; + break; + case "getPhoneGrid": + $result = $this->get_db_SccpTableData('SccpDevice'); + if (empty($result)) { + $result = array(); + } else { + $staus = $this->sccp_get_active_devise(); + 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']; + } else { + $dev_id['description'] = '- -'; + $dev_id['status'] = 'no connect'; + $dev_id['address'] = '- -'; + } + } + } + return $result; + break; + } + } + + public function doGeneralPost() { +// $this->FreePBX->WriteConfig($config); + if (!isset($_REQUEST['Submit'])) + return; + } + + /* + * + * * Save Hardware Device Information to Db + ???? Create / update XML Profile + * + */ + + function save_hw_phone($get_settings, $validateonly = false) { + $hdr_prefix = 'sccp_hw_'; + $save_buttons = array(); + $save_settings = array(); + $save_codec = 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->get_db_SccpTableData("get_colums_sccpdevice"); + $hw_id = (empty($get_settings['sccp_deviceid'])) ? 'new' : $get_settings['sccp_deviceid']; + $update_hw = ($hw_id == 'new') ? 'update' : 'clear'; + foreach ($db_field as $data) { + $key = (string) $data['Field']; + $value = ""; + switch ($key) { + case 'permit': + case 'deny': + $value = $get_settings[$hdr_prefix . $key . '_net'] . '/' . $get_settings[$hdr_prefix . $key . '_mask']; + break; + case 'name': + if (!empty($get_settings[$hdr_prefix . 'mac'])) { + $value = 'SEP' . $get_settings[$hdr_prefix . 'mac']; + $name_dev = $value; + } + break; + case 'disallow': + $value = $get_settings['sccp_disallow']; + break; + + case 'allow': + $i = 0; + foreach ($get_settings['voicecodecs'] as $keycodeс => $valcodeс) { + $save_codec[$i] = $keycodeс; + $i++; + }; + $value = implode(";", $save_codec); + break; + case 'hwlang': + if (empty($get_settings[$hdr_prefix . 'netlang']) || empty($get_settings[$hdr_prefix . 'devlang'])) { + $value = 'null'; + } else { + $value = $get_settings[$hdr_prefix . 'netlang'] . ':' . $get_settings[$hdr_prefix . 'devlang']; + } + break; + default : + if (!empty($get_settings[$hdr_prefix . $key])) { + $value = $get_settings[$hdr_prefix . $key]; + } + } + if (!empty($value)) { + $save_settings[$key] = $value; + } + } +// Save / Updade Base + $this->sccp_save_db("sccpdevice", $save_settings, 'replace'); +// return print_r($save_settings,1); +// Get Model Butons info + $lines_list = $this->get_db_SccpTableData('SccpExtension'); + $max_btn = ((!empty($get_settings['butonscount']) ? $get_settings['butonscount'] : 100)); + for ($it = 0; $it < $max_btn; $it++) { + if (!empty($get_settings['button' . $it . '_type'])) { + $btn_t = $get_settings['button' . $it . '_type']; + + $btn_n = ''; + $btn_opt = ''; + if ($it == 0) { + $btn_opt = 'default'; + } + switch ($btn_t) { + case 'feature': + $btn_f = $get_settings['button' . $it . '_feature']; +// $btn_opt = (empty($get_settings['button' . $it . '_fvalue'])) ? '' : $get_settings['button' . $it . '_fvalue']; + $btn_n = (empty($get_settings['button' . $it . '_flabel'])) ? $def_feature[$btn_f]['name'] : $get_settings['button' . $it . '_flabel']; + $btn_opt = $btn_f; + if (!empty($def_feature[$btn_f]['value'])) { + if (empty($get_settings['button' . $it . '_fvalue'])) { + $btn_opt .= ','.$def_feature[$btn_f]['value']; + } else { + $btn_opt .= ','.$get_settings['button' . $it . '_fvalue']; + } + } + break; + case 'monitor': + $btn_t = 'speeddial'; + $btn_opt = (string) $get_settings['button' . $it . '_line']; + $db_res = $this->get_db_SccpTableData('SccpExtension',array('id'=>$btn_opt)); + $btn_n = $db_res[0]['label']; + $btn_opt .= ',' . $btn_opt. $this->hint_context; + break; + case 'speeddial': + if (!empty($get_settings['button' . $it . '_input'])) { + $btn_n = $get_settings['button' . $it . '_input']; + } + if (!empty($get_settings['button' . $it . '_phone'])) { + $btn_opt = $get_settings['button' . $it . '_phone']; + if (empty($btn_n)) { + $btn_n = $btn_opt; + } + } + + if (!empty($get_settings['button' . $it . '_hint'])) { + if ($get_settings['button' . $it . '_hint'] == "hint") { + if (empty($btn_n)) { + $btn_t = 'line'; + $btn_n = $get_settings['button' . $it . '_hline'] . '!silent'; + $btn_opt = ''; + } else { + $btn_opt .= ',' . $get_settings['button' . $it . '_hline'] . $this->hint_context; + } + } + } + break; + case 'line': + case 'silent': + $btn_n = (string) $get_settings['button' . $it . '_line']; + if ($it > 0) { + if ($btn_t == 'silent') { + $btn_n .= '!silent'; + $btn_t = 'line'; + } + } + break; + case 'empty': + $btn_t = ''; + break; + } + if (!empty($btn_t)) { + $save_buttons[] = array('device' => $name_dev, 'instance' => (string) ($it + 1), 'type' => $btn_t, 'name' => $btn_n, 'options' => $btn_opt); + } + } + } +// Sace Buttons config + $this->sccp_save_db("sccpbuttons", $save_buttons, $update_hw, '', $name_dev); +// Create Device XML + $this->sccp_create_device_XML($name_dev); +// sccp restart +// $this->sccp_core_comands(array('cmd'=>'reset_phone', 'name' => $name_dev)); + $this->sccp_core_comands(array('cmd'=>'reload_phone', 'name' => $name_dev)); +// die(); + return $save_settings; + } + + function save_submit($get_settings, $validateonly = false) { + $hdr_prefix = 'sccp_'; + $hdr_arprefix = 'sccp-ar_'; + $save_settings = array(); + $save_codec = array(); + $integer_msg = _("%s must be a non-negative integer"); + $errors = array(); + $i = 0; + foreach ($get_settings as $key => $value) { + $pos = strpos($key, $hdr_prefix); + if ($pos !== false) { + $key1 = substr_replace($key, '', 0, strlen($hdr_prefix)); + if (!empty($this->sccpvalues[$key1])) { + if (!($this->sccpvalues[$key1]['data'] == $value)) { + $save_settings[] = array('keyword' => $this->sccpvalues[$key1]['keyword'], 'data' => $value, + 'seq' => $this->sccpvalues[$key1]['seq'], 'type' => $this->sccpvalues[$key1]['type']); + } + } + } + $pos = strpos($key, $hdr_arprefix); + if ($pos !== false) { + $key1 = substr_replace($key, '', 0, strlen($hdr_arprefix)); + $arr_data = ''; + if (!empty($this->sccpvalues[$key1])) { + foreach ($value as $vkey => $vval) { + $tmp_data =''; + foreach ($vval as $vkey => $vval) { + $tmp_data .= $vval. '/'; + } + if (strlen($tmp_data)>2){ + $arr_data .= substr($tmp_data,0,-1).';'; + } + } + $arr_data = substr($arr_data,0,-1); + if (!($this->sccpvalues[$key1]['data'] == $arr_data)) { + $save_settings[] = array('keyword' => $this->sccpvalues[$key1]['keyword'], 'data' => $arr_data, + 'seq' => $this->sccpvalues[$key1]['seq'], 'type' => $this->sccpvalues[$key1]['type']); + } + } + + } + switch ($key) { + case 'voicecodecs': + foreach ($value as $keycodeс => $valcodeс) { + $save_codec[$i] = $keycodeс; + $i++; + }; + $tmpv = implode(";", $save_codec); + if ($tmpv !== $this->sccpvalues['allow']['data']) { + $save_settings[] = array('keyword' => 'allow', 'data' => $tmpv, + 'seq' => $this->sccpvalues['allow']['seq'], + 'type' => $this->sccpvalues['allow']['type']); + } + break; + } + } + if (!empty($save_settings)) { + $this->sccp_db_save_setting($save_settings); + $this->getSccpSettingsDB(); // Overwrite Exist + $this->sccp_create_sccp_init(); + } + $save_settings[] = array('status' => true); + return $save_settings; + } + + /** + * + * Core Comsnd Interface + * + * + */ + public function sccp_core_comands($params = array()) { + global $astman; + $cmd_list = array('get_softkey' => array('cmd' => "sccp show softkeyssets", 'param' => ''), + 'get_device' => array('cmd' => "sccp show devices", 'param' => ''), + 'get_hints' => array('cmd' => "core show hints", 'param' => ''), + 'sccp_reload' => array('cmd' => "sccp reload force", 'param' => ''), + 'reset_phone' => array('cmd' => "sccp reset ", 'param' => 'name'), // Жесткая перезагрузка + 'reload_phone' => array('cmd' => "sccp reload device ", 'param' => 'name'), + ); + $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; + } + + /** + * + * return Html_ Input control code---------------------------------------------------------------------------------------temp + * + * + */ + public function sccp_list_hints() { + $ast_out = $this->sccp_core_comands(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 (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_list_keysets() { + $ast_out = $this->sccp_core_comands(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_devise() { + $ast_out = $this->sccp_core_comands(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 (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 $devname, 'status' => $status, 'address' => $adress, 'descr' => $descr); + } + } else { + $ast_key[$devname] = Array('name' => $devname, 'status' => $status, 'address' => $adress, 'descr' => $descr); + } + } + } + return $ast_key; + } + + function sccp_get_keysetdata($name) { + + if ($name == 'default') { + $keysetData = sccp_get_confData('softkeyset'); + $keysetData['name'] = 'default'; + } else { + $keysetData = sccp_get_confData($name); + } + $keysetData['name'] = ($keysetData['name'] ? $keysetData['name'] : $name); + return $keysetData; + } + + function sccp_edit_keyset($keysetData) { + global $amp_conf; + $key_name = array('onhook', 'connected', 'onhold', 'ringin', 'offhook', 'conntrans', 'digitsfoll', 'connconf', 'ringout', 'offhookfeat', 'onhint', 'onstealable'); + + $keysetImplode['name'] = $keysetData['name']; + $keysetImplode['type'] = $keysetData['type']; + $keysetImplode['file_context'] = $keysetData['file_context']; + foreach ($key_name as $i) { + if (isset($keysetData[$i])) { + $keysetImplode[$i] = implode(',', $keysetData[$i]); + } + } +// +// Write config file context section. +// + $file_context = $keysetData['name']; + if ($file_context != 'default') { + $confDir = $amp_conf["ASTETCDIR"]; + if (strlen($confDir) < 1) { + $confDir = "/etc/asterisk"; + } + $inputfile = "$confDir/sccp.conf"; + if (!file_exists($inputfile)) { + $sccpfile = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/sccp.conf'); + file_put_contents($inputfile, $sccpfile); + } + $handle = fopen($inputfile, "r"); + $file_context = "[$file_context]"; + $sccpfile = ''; + + $conext_data = "$file_context ; Managed by sccp_manager\n"; + $conext_data .= "type=softkeyset\n"; + foreach ($keysetImplode as $field => $value) { + echo($field); + if ($field != 'type' && $field != 'name' && $field != 'file_context') { + echo($value); + if (strlen($value) > 1) { + $conext_data .= $field . "=" . $value . "\n"; + } + } + } + $conext_data .= "\n"; + + + $new_context = "1"; + echo($file_context); + if ($handle) { + while (($input = fgets($handle)) != false) { + if (trim($input) != $file_context) { +// echo($input); + $sccpfile .= $input; + } else { + $new_context = "0"; + $sccpfile .= $conext_data; +// +// We don't include the 'name=' directive in sccp.conf contexts. +// $sccpfile .= "name=".$keysetImplode['name']."\n"; +// + $trimmer = true; + while ($trimmer) { + $trimmer = ($input = fgets($handle)); + if (substr($input, 0, 1) == '[') { + $trimmer = false; + $sccpfile .= $input; + } + } + } + } + if ($new_context != "0") { + $sccpfile .= $conext_data; + } + } + } + file_put_contents($inputfile, $sccpfile); + return $sccpfile; + } + + function sccp_display_keyset($keysetData, $softkey, $option) { + if ($keysetData['name'] == 'default') { + $output = ""; + if (strpos(' ' . $keysetData[$softkey], $option)) { + $output .= '☑'; + } else { + $output .= '☐'; + } + $output .= " $option
"; + } else { + $output = "sccpvalues['allow']['data']); + $final = array(); + $i = 1; + foreach ($val as $value) { + $final[$value] = $i; + $i++; + } + break; + case "softkeyset": + $final = array(); + $i = 0; + if ($id == "noid") { + foreach ($this->sccp_conf_init as $key => $value) { + if ($this->sccp_conf_init[$key]['type'] == 'softkeyset') { + $final[$i] = $value; + $i++; + } + } + } else { + if (!empty($this->sccp_conf_init[$id])) { + if ($this->sccp_conf_init[$id]['type'] == 'softkeyset') { + $final = $this->sccp_conf_init[$id]; + } + } + } + + break; + } + return $final; + } + + public function getCodecs($type, $showDefaults = false) { + + switch ($type) { + case 'audio': + $codecs = $this->getMyConfig('voicecodecs'); + break; + case 'video': + $codecs = $this->getConfig('videocodecs'); + break; + case 'text': + $codecs = $this->getConfig('textcodecs'); + break; + case 'image': + $codecs = $this->getConfig('imagecodecs'); + break; + default: + throw new Exception(_('Unknown Type')); + break; + } + + if (empty($codecs) || !is_array($codecs)) { + switch ($type) { + case 'audio': + $codecs = $this->FreePBX->Codecs->getAudio(true); + break; + case 'video': + $codecs = $this->FreePBX->Codecs->getVideo(true); + break; + case 'text': + $codecs = $this->FreePBX->Codecs->getText(true); + break; + case 'image': + $codecs = $this->FreePBX->Codecs->getImage(true); + break; + } + } + + if ($showDefaults) { + switch ($type) { + case 'audio': + $allCodecs = $this->FreePBX->Codecs->getAudio(); + break; + case 'video': + $allCodecs = $this->FreePBX->Codecs->getVideo(); + break; + case 'text': + $allCodecs = $this->FreePBX->Codecs->getText(); + break; + case 'image': + $allCodecs = $this->FreePBX->Codecs->getImage(); + break; + } + // Update the $codecs array by adding un-selected codecs to the end of it. + + foreach ($allCodecs as $c => $v) { + if (!isset($codecs[$c])) { + $codecs[$c] = false; + } + } + + return $codecs; + } else { + //Remove all non digits + $final = array(); + foreach ($codecs as $codec => $order) { + $order = trim($order); + if (ctype_digit($order)) { + $final[$codec] = $order; + } + } + asort($final); + return $final; + } + } + + /** + * Update or Set Codecs + * @param {string} $type Codec Type + * @param {array} $codecs=array() The codecs with order, if blank set defaults + */ + public function setCodecs($type, $codecs = array()) { + $default = empty($codecs) ? true : false; + switch ($type) { + case 'audio': + $codecs = $default ? $this->FreePBX->Codecs->getAudio(true) : $codecs; + $this->setConfig("voicecodecs", $codecs); + break; + case 'video': + $codecs = $default ? $this->FreePBX->Codecs->getVideo(true) : $codecs; + $this->setConfig("videocodecs", $codecs); + break; + case 'text': + $codecs = $default ? $this->FreePBX->Codecs->getText(true) : $codecs; + $this->setConfig("textcodecs", $codecs); + break; + case 'image': + $codecs = $default ? $this->FreePBX->Codecs->getImage(true) : $codecs; + $this->setConfig("imagecodecs", $codecs); + break; + default: + throw new Exception(_('Unknown Type')); + break; + } + 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(); + $dir = $this->sccppath["tftp_path"]; + $cdir = scandir($dir); + foreach ($cdir as $key => $value) { + if (!in_array($value, array(".", ".."))) { + if (is_dir($dir . DIRECTORY_SEPARATOR . $value)) { + $filename = $dir . DIRECTORY_SEPARATOR . $value . DIRECTORY_SEPARATOR . $this->SCCP_LANG_DICTIONARY; + if (file_exists($filename)) { + foreach ($this->sccp_lang as $lang_key => $lang_value) { + if ($lang_value['locale'] == $value) { + $result[$lang_key] = $value; + } + } +// $result[] = $value; + } + } + } + } + $this->tftpLang = $result; + } + + /* + * Chek file enverovments ( xml) + */ + + private function init_tftp_lang_path() { + $dir = $this->sccppath["tftp_path"]; + foreach ($this->sccp_lang as $lang_key => $lang_value) { + $filename = $dir . DIRECTORY_SEPARATOR . $lang_value['locale']; + if (!file_exists($filename)) { + if (!mkdir($filename, 0777, true)) { + die('Error create lang dir'); + } + } + } + } + + /* + * Chek file enverovments ( xml) + */ + + function init_sccp_path() { + global $db; + global $amp_conf; + $confDir = $amp_conf["ASTETCDIR"]; + if (empty($this->sccppath["asterisk"])) { + if (strlen($confDir) < 1) { + $this->sccppath["asterisk"] = "/etc/asterisk"; + } else { + $this->sccppath["asterisk"] = $confDir; + } + } + + if (empty($this->sccppath["sccp_conf"])) { + $this->sccppath["sccp_conf"] = $this->sccppath["asterisk"] . "/sccp.conf"; + } + + if (empty($this->sccppath["tftp_path"])) { + if (!empty($sccpvalues["tftp_path"])) { + if (file_exists($this->$sccpvalues["tftp_path"]["data"])) { + $this->sccppath["tftp_path"] = $this->$sccpvalues["tftp_path"]["data"]; + } + } + if (empty($this->sccppath["tftp_path"])) { + if (file_exists($this->sccpDefaults["tftp_path"])) { + $this->sccppath["tftp_path"] = $this->sccpDefaults["tftp_path"]; + } + } + } + if (!empty($this->sccppath["tftp_path"])) { + $this->sccppath["tftp_templets"] = $this->sccppath["tftp_path"] . '/templets'; + if (!file_exists($this->sccppath["tftp_templets"])) { + if (!mkdir($this->sccppath["tftp_templets"], 0777, true)) { + die('Error create templet dir'); + } + } + } + if (empty($_SERVER['DOCUMENT_ROOT'])) { + return; + } + + if (!file_exists($this->sccppath["tftp_templets"] . '/XMLDefault.cnf.xml_template')) { + $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/'; + $dst_path = $this->sccppath["tftp_templets"] . '/'; + 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)) { + $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/' . basename($dst); + copy($src_path, $dst); + } + + if (!file_exists($this->sccppath["sccp_conf"])) { // System re Config + $sccpfile = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/sccp.conf'); + file_put_contents($this->sccppath["sccp_conf"], $sccpfile); + } + + $this->sccp_conf_init = $this->cnf_read->getConfig('sccp.conf'); + +// $this->sccp_conf_init = @parse_ini_file($this->sccppath["sccp_conf"], true); + } + + /* + * Save Config Value to mysql DB + * sccp_db_save_setting(empty) - Save All settings from $sccpvalues + */ + + private function sccp_save_db($db_name = "", $save_value = array(), $mode = 'update', $key_fld = "", $hwid = "") { + // mode clear - Empty tabele before update + // mode update - update / replace record + global $db; +// global $amp_conf; + $result = "Error"; + + switch ($db_name) { + case 'sccpsettings': + if ($mode == 'clear') { + $sql = 'truncate `sccpsettings`'; + $stmt = $db->prepare($sql); + $stmt->execute(); + $stmt = $db->prepare('INSERT INTO `sccpsettings` (`keyword`, `data`, `seq`, `type`) VALUES (?,?,?,?)'); + $result = $db->executeMultiple($stmt, $save_value); + } else { + $stmt = $db->prepare('REPLACE INTO `sccpsettings` (`keyword`, `data`, `seq`, `type`) VALUES (?,?,?,?)'); + $result = $db->executeMultiple($stmt, $save_value); + } + break; + case 'sccpdevmodel': + case 'sccpdevice': + $sql_db = $db_name; + $sql_key = ""; + $sql_var = ""; + foreach ($save_value as $key_v => $data) { + if (!empty($sql_var)) { + $sql_var .= ', '; + } + if ($data === 'none') { + $sql_var .= '`' . $key_v . '`=NULL'; + } else { + $sql_var .= '`' . $key_v . '`="' . $data . '"'; + } + if ($key_fld == $key_v) { + $sql_key = '`' . $key_v . '`="' . $data . '"'; + } + } + if (!empty($sql_var)) { + if ($mode == 'delete') { + $req = 'DELETE FROM `' . $sql_db . '` WHERE ' . $sql_key . ';'; + } else { + if ($mode == 'update') { + $req = 'UPDATE `' . $sql_db . '` SET ' . $sql_var . ' WHERE ' . $sql_key . ';'; + } else { + $req = 'REPLACE INTO `' . $sql_db . '` SET ' . $sql_var . ';'; + } + } + } + $stmt = $db->prepare($req); + $result = $stmt->execute(); + break; + case 'sccpbuttons': + if (($mode == 'clear') || ($mode == 'delete')) { + $sql = 'DELETE FROM `buttonconfig` WHERE device="' . $hwid . '";'; + $stmt = $db->prepare($sql); + $stmt->execute(); + } + if ($mode == 'delete') { + break; + } + if (!empty($save_value)) { + $sql = 'INSERT INTO `buttonconfig` (`device`, `instance`, `type`, `name`, `options`) VALUES (?,?,?,?,?);'; + $stmt = $db->prepare($sql); + $res = $db->executeMultiple($stmt, $save_value); + } + + break; + } + return $result; + } + + private function sccp_db_save_setting($save_value = array()) { + global $db; + global $amp_conf; + + $save_settings = array(); + + if (empty($save_value)) { + foreach ($this->sccpvalues as $key => $val) { + if (!trim($val['data']) == '') { + $save_settings[] = array($key, $db->escapeSimple($val['data']), $val['seq'], $val['type']); + } + } + $this->sccp_save_db('sccpsettings', $save_settings, 'clear'); + } else { + $this->sccp_save_db('sccpsettings', $save_value, 'update'); + return true; + } + return true; + } + + /* + * Create XMLDefault.cnf.xml + */ + + function sccp_create_tftp_XML() { + $def_xml_fields = array('authenticationURL', 'informationURL', 'messagesURL', 'servicesURL', 'directoryURL', 'proxyServerURL', 'idleTimeout', 'idleURL'); + $def_xml_locale = array('userLocale', 'networkLocaleInfo', 'networkLocale'); + $xml_name = $this->sccppath["tftp_path"] . '/XMLDefault.cnf.xml'; + $xml_templet = $this->sccppath["tftp_templets"] . '/XMLDefault.cnf.xml_template'; + + if (file_exists($xml_templet)) { + $xml_work = simplexml_load_file($xml_templet); + + + $xnode = &$xml_work->callManagerGroup->members; + if ($this->sccpvalues['bindaddr']['data'] == '0.0.0.0') { + $ifc = 0; + foreach ($this->getIP_information() as $value) { + if (!empty($value[0])) { + if (!in_array($value[0], array('0.0.0.0', '127.0.0.1'), true)) { + $xnode_obj = clone $xnode->member; + + $xnode_obj['priority'] = $ifc; + //$xnode_obj = &$xnode -> member -> callManager; + $xnode_obj->callManager->name = $this->sccpvalues['servername']['data']; + $xnode_obj->callManager->ports->ethernetPhonePort = $this->sccpvalues['port']['data']; + $xnode_obj->callManager->processNodeName = $value[0]; + 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 = $this->sccpvalues['servername']['data']; + $xnode_obj->ports->ethernetPhonePort = $this->sccpvalues['port']['data']; + $xnode_obj->processNodeName = $this->sccpvalues['bindaddr']['data']; + } + $this->replaceSimpleXmlNode($xml_work->callManagerGroup->members, $xnode); + + foreach ($def_xml_fields as $value) { + if (!empty($this->sccpvalues['dev_' . $value])) { + $xml_work->$value = trim($this->sccpvalues['dev_' . $value]['data']); + } + } + 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 = $this->sccpvalues['netlang']['data']; + } else { + $lang = $this->sccpvalues['devlang']['data']; + } + $xnode->name = $this->sccp_lang[$lang]['locale']; + $xnode->langCode = $this->sccp_lang[$lang]['code']; +// $this -> replaceSimpleXmlNode($xml_work->$key,$xnode); + break; + case 'networkLocale': + $xnode = $this->sccp_lang[$this->sccpvalues['netlang']['data']]['language']; + break; + } + //$this-> replaceSimpleXmlNode($xml_work->$value, $xnode ); + } + } + + $msro = $this->getSccp_model_information($get = "enabled", $validate = false); // Get Active + if (empty($msro)) + $msro = $this->getSccp_model_information($get = "all", $validate = false); // Get All + foreach ($msro 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 + // + // + // +// die(print_r($xml_work)); + } + } + + /* + * Create (SEP) dev_ID.cnf.xml + */ + + function sccp_create_device_XML($dev_id = '') { + $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', 'deviceProtocol' => 'dev_deviceProtocol'); + if (empty($dev_id)) { + return false; + } + $var_hw_config = $this->get_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); + + if (empty($var_hw_config)) { + return false; + } + + if (!(empty($var_hw_config['nametemplet']))) { + $xml_templet = $this->sccppath["tftp_templets"] . '/' . $var_hw_config['nametemplet']; + } else { + $xml_templet = $this->sccppath["tftp_templets"] . '/SEP0000000000.cnf.xml_791x_template'; + } + $xml_name = $this->sccppath["tftp_path"] . '/' . $dev_id . '.cnf.xml'; + if (file_exists($xml_templet)) { + $xml_work = simplexml_load_file($xml_templet); + /* + $node = $xml_work -> certHash; + if ( !empty($node)) {F + unset($node[0][0]); + } + * + */ + foreach ($xml_work as $key => $data) { +// Set System global Values + if (!empty($var_xml_general_fields[$key])) { + $xml_work->$key = $this->sccpvalues[$var_xml_general_fields[$key]]['data']; + } +// 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; + $xnode->name = $this->sccpvalues['ntp_timezone']['data']; + $xnode->dateTemplate = $this->sccpvalues['dateformat']['data']; + $xnode->timeZone = $this->sccpvalues['ntp_timezone']['data']; + if ($this->sccpvalues['ntp_config_enabled']['data'] == 'yes') { + $xnode->ntps->ntp->name = $this->sccpvalues['ntp_server']['data']; + $xnode->ntps->ntp->ntpMode = $this->sccpvalues['ntp_server_mode']['data']; + } else { + $xnode->ntps = ''; + } + // Ntp Config + break; + case 'srstInfo': + $xml_node->$dkey = ''; + break; + case 'callManagerGroup': + $xnode = &$xml_node->$dkey->members; + if ($this->sccpvalues['bindaddr']['data'] == '0.0.0.0') { + $ifc = 0; + foreach ($this->getIP_information() as $value) { + if (!empty($value[0])) { + if (!in_array($value[0], array('0.0.0.0', '127.0.0.1'), true)) { + $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 = $this->sccpvalues['servername']['data']; + $xnode_obj->callManager->ports->ethernetPhonePort = $this->sccpvalues['port']['data']; + $xnode_obj->callManager->processNodeName = $value[0]; + 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 = $this->sccpvalues['servername']['data']; + $xnode_obj->ports->ethernetPhonePort = $this->sccpvalues['port']['data']; + $xnode_obj->processNodeName = $this->sccpvalues['bindaddr']['data']; + } + break; + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + case 'versionStamp': + $xml_work->$key = time(); + break; + case 'loadInformation': + $xml_work->$key = $var_hw_config["loadimage"]; + if (!empty($var_hw_config['addon'])) { + $hw_addon = explode(',', $var_hw_config['addon']); + $xnode = $xml_work -> addChild('addOnModules'); + $ti = 1; + foreach ($hw_addon as $key ) { + $hw_inf = $this-> getSccp_model_information('byid',false, "all",array('model'=>$key )); + $xnode_obj = $xnode -> addChild('addOnModule'); +// if $hw_inf['loadimage'] + $xnode_obj -> addAttribute('idx', $ti); + $xnode_obj -> addChild('loadInformation',$hw_inf[0]['loadimage']); + $ti ++; + } +// $this->appendSimpleXmlNode($xml_work , $xnode_obj); + } + break; + case 'userLocale': + case 'networkLocaleInfo': + case 'networkLocale': + $hwlang = ''; + if (!empty($var_hw_config["hwlang"])) { + $hwlang = explode(':', $var_hw_config["hwlang"]); + } + if (($key == 'networkLocaleInfo') || ($key == 'networkLocale') ){ +// $lang=$this->sccpvalues['netlang']['data']; + $lang = (empty($hwlang[0])) ? $this->sccpvalues['netlang']['data'] : $hwlang[0]; + } else { + $lang = (empty($hwlang[1])) ? $this->sccpvalues['devlang']['data'] : $hwlang[1]; +// $lang=$this->sccpvalues['devlang']['data']; + } + if ($key == 'networkLocale'){ + $xml_work->$key = $lang; + } else { + $xml_node->name = $this->sccp_lang[$lang]['locale']; + $xml_node->langCode = $this->sccp_lang[$lang]['code']; + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + } + break; +// case 'networkLocale': +// $xml_work->$key = $this->sccp_lang[$this->sccpvalues['netlang']['data']]['language']; +// $xml_work->$key = $this->sccp_lang[$this->sccpvalues['netlang']['data']]['language']; +// break; + case 'mobility': +// break; + case 'phoneServices': +// break; + $xml_work->$key = ''; + default: + break; + } + } + +// print_r($xml_work); + $xml_work->asXml($xml_name); // Save + } else { + die('Error Hardware templete :' . $xml_templet . ' not found'); + } + return time(); + } + + function sccp_create_sccp_init() { +// Make sccp.conf data +// [general] + foreach ($this->sccpvalues as $key => $value) { + if ($value['seq'] == 0) { + switch ($key) { + case "allow": + case "disallow": + case "deny": + case "localnet": + case "permit": + $this->sccp_conf_init['general'][$key] = explode(';', $value['data']); + break; + case "netlang": // Remove Key + case "devlang": + case "tftp_path": + break; + default: + $this->sccp_conf_init['general'][$key] = $value['data']; + } + } + } +// [Namesoftkeyset] +// type=softkeyset + + $this->cnf_wr->writeConfig('sccp.conf', $this->sccp_conf_init); +// return $this-> sccp_conf_init; + } + + /* + * Load Config Value from mysql DB + * sccp_db_save_setting(empty) - Save All settings from $sccpvalues + */ + + public function get_db_SccpTableData($dataid, $data = array()) { + if ($dataid == '') { + return False; + } + switch ($dataid) { + case "SccpExtension": + if (empty($data['id'])) { + $sql = "SELECT * FROM `sccpline` ORDER BY `id`"; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + } else { + $sql = "SELECT * FROM `sccpline` WHERE `id`=".$data['id']; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + } + break; + case "SccpDevice": +// $sql = "SELECT * FROM `sccpdeviceconfig` ORDER BY `name`"; + $sql = "select `name`,`name` as `mac`, `type`, `button` from `sccpdeviceconfig` ORDER BY `name`"; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + break; + case "HWDevice": + $raw_settings = $this->getSccp_model_information($get = "phones", $validate = false, $format_list = "model"); + break; + case "HWextension": + $raw_settings = $this->getSccp_model_information($get = "extension", $validate = false, $format_list = "model"); + break; + case "get_colums_sccpdevice": + $sql = "DESCRIBE sccpdevice"; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + break; + case "get_sccpdevice_byid": + $sql = 'SELECT t1.*, types.dns, types.buttons, types.loadimage, types.nametemplet as nametemplet, ' + . '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="' . $data['id'] . '";'; + $raw_settings = sql($sql, "getRow", DB_FETCHMODE_ASSOC); + break; + case "get_sccpdevice_buttons": + $sql = 'SELECT * FROM buttonconfig WHERE device="' . $data['id'] . '";'; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + break; + } + + return $raw_settings; + } + + public function getSccpSettingsDB($returnraw = false) { + $sql = "SELECT `keyword`, `data`, `type`, `seq` FROM `sccpsettings` ORDER BY `type`, `seq`"; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + + if ($returnraw === true) { + return $raw_settings; + } + + + foreach ($raw_settings as $var) { + $this->sccpvalues[$var['keyword']] = array('keyword' => $var['keyword'], 'data' => $var['data'], 'seq' => $var['seq'], 'type' => $var['type']); + } + return; + } + + /* + * Get Sccp Device Model information + * + */ + + function getSccp_model_information($get = "all", $validate = false, $format_list = "all", $filter = array()) { + global $db; + $file_ext = array('.loads','.sbn','.SBN'); + + $dir = $this->sccppath["tftp_path"]; + switch ($format_list) { + case "model": + $sel_inf = "model, vendor, dns, buttons"; + break; + case "all": + default: + $sel_inf = "*"; + break; + } + + if ($validate) { + $sel_inf .= ", '0' as 'validate'"; + } + switch ($get) { + case "byid": + if (!empty($filter)) { + if (!empty($filter['model'])) { + $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (`model` =".$filter['model'].") ORDER BY model "; + } else { +// $sql = "SELECT ".$filter['model']; + $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel ORDER BY model "; + } + break; + } + break; + case "extension": + $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (dns = 0)ORDER BY model "; + break; + case "enabled": + case "phones": + $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (dns > 0) and (enabled > 0) ORDER BY model "; +// $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (enabled > 0) ORDER BY model "; + break; + case "all": + default: + $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel ORDER BY model "; + break; + } + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + $i = 0; + if ($validate) { + for ($i = 0; $i < count($raw_settings); $i++) { + $file = $dir . '/' . $raw_settings[$i]['loadimage']; + $raw_settings[$i]['validate'] = 'no'; + if (strtolower($raw_settings[$i]['vendor']) == 'cisco') { + foreach ($file_ext as $value) { + if (file_exists($file.$value)) { + $raw_settings[$i]['validate'] = 'yes'; + break; + } + } + } else { + if (file_exists($file)) { + $raw_settings[$i]['validate'] = 'yes'; + } + } + } + } + return $raw_settings; + } + + function getIP_information() { + $interfaces['auto'] = array('0.0.0.0', 'All', '0'); + + exec("/sbin/ip -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]))); + } +// $int = 0; +// foreach ($interfaces as $value) { +// $this->sccpvalues['interfaces_'.$int] = array('keyword' => 'interfaces_'.$value[1], 'data' => $value[0], 'type' => '1', 'seq' => '99'); +// $int ++; +// } + return $interfaces; + } + + 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)); + } + +// private function removeSimpleXmlNode($node) { +// $dom = dom_import_simplexml($node); +// $dom->parentNode->removeChild($dom); +// } +} diff --git a/assets/css/sccp_manager.css b/assets/css/sccp_manager.css new file mode 100644 index 0000000..4e9eb12 --- /dev/null +++ b/assets/css/sccp_manager.css @@ -0,0 +1,19 @@ +/* +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. +*/ +/* + Created on : 03.05.2017, 16:13:49 + Author : Alex +*/ +.sccpmultiselect { + min-height: 100px; + padding: 1px 1px; + +} +.sccpbtn { + min-height: 10px; + padding: 1px 1px; +} + diff --git a/assets/images/arrow_up_down.png b/assets/images/arrow_up_down.png new file mode 100644 index 0000000..6850245 Binary files /dev/null and b/assets/images/arrow_up_down.png differ diff --git a/assets/js/jquery.selectlistactions.js b/assets/js/jquery.selectlistactions.js new file mode 100644 index 0000000..afbfe2f --- /dev/null +++ b/assets/js/jquery.selectlistactions.js @@ -0,0 +1,76 @@ +/** + * jQuery.SelectListActions + * https://github.com/esausilva/jquery.selectlistactions.js + * + * (c) http://esausilva.com + */ + +(function ($) { + //Moves selected item(s) from sourceList to destinationList + $.fn.moveToList = function (sourceList, destinationList) { + var opts = $(sourceList + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(destinationList).append($(opts).clone()); + }; + + //Moves all items from sourceList to destinationList + $.fn.moveAllToList = function (sourceList, destinationList) { + var opts = $(sourceList + ' option'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(destinationList).append($(opts).clone()); + }; + + //Moves selected item(s) from sourceList to destinationList and deleting the + // selected item(s) from the source list + $.fn.moveToListAndDelete = function (sourceList, destinationList) { + var opts = $(sourceList + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(opts).remove(); + $(destinationList).append($(opts).clone()); + }; + + //Moves all items from sourceList to destinationList and deleting + // all items from the source list + $.fn.moveAllToListAndDelete = function (sourceList, destinationList) { + var opts = $(sourceList + ' option'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(opts).remove(); + $(destinationList).append($(opts).clone()); + }; + + //Removes selected item(s) from list + $.fn.removeSelected = function (list) { + var opts = $(list + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to remove"); + } + + $(opts).remove(); + }; + + //Moves selected item(s) up or down in a list + $.fn.moveUpDown = function (list, btnUp, btnDown) { + var opts = $(list + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + if (btnUp) { + opts.first().prev().before(opts); + } else if (btnDown) { + opts.last().next().after(opts); + } + }; +})(jQuery); diff --git a/assets/js/sccp_manager.js b/assets/js/sccp_manager.js new file mode 100644 index 0000000..bfac029 --- /dev/null +++ b/assets/js/sccp_manager.js @@ -0,0 +1,660 @@ +$(document).ready(function () { + $('.sortable').sortable({ + update: function (event, ui) { + // console.log(ui.item.find('input').val(), ui.item.index()) + ui.item.find('input').val(ui.item.index()); + }, + }); + $('#ajaxcancel').on('click', function (e) { +// console.log('Calncel'); + if ($(this).data('hash') != null) { + location.hash = $(this).data('hash'); + } + if ($(this).data('href') != null) { + location.href = $(this).data('href'); + } + if ($(this).data('path') != null) { + location.path = $(this).data('path'); + } + if ($(this).data('search') != null) { + location.search = $(this).data('search'); + } + if ($(this).data('reload') != null) { + location.reload(); + } + }); + + $('#ajaxsubmit').on('click', function (e) { + var vdata = ''; + var snd_command = 'savesettings'; + $('.fpbx-submit').each(function () { + vdata = vdata + $(this).serialize() + '&'; + }); + if ($('.fpbx-submit').data('id') == "hw_edit") { + snd_command = 'save_hardware'; + } + $.ajax({ + type: 'POST', + url: 'ajax.php?module=sccp_manager&command=' + snd_command, + data: vdata, + success: function (data) { + if (data.status === true) { + if (data.message) { + alert(data.message); + } + if (data.table_reload === true) { + $('table').bootstrapTable('refresh'); + } + if (data.hash != null) { + location.hash = data.hash; + } + if (data.href != null) { + location.href = data.href; + } + if (data.path != null) { + location.path = data.path; + } + if (data.search != null) { + location.search = data.search; + } + if (data.reload === true) { + location.reload(); + } + + } else { + if (Array.isArray(data.message)) { + data.message.forEach(function (entry) { + fpbxToast(entry, 'error', 'error'); + }); + } + } + } + }); + }); + + $(".input-js-add").click(function(){ + add_dynamic_input($(this),$(this).data('for'),"",""); + }); + +// ----------------------- Server.model.Button.Select---------------- + + $('.dropdown-menu a.dropitem').on("click", function (e) { + + $(this).parents('div.btn-group').find('.dropdown_capture').text($(this).text()); +// console.log($(this).data('id')); + ref_url = "ajax.php?module=sccp_manager&command=getDeviceModel&type=" + $(this).data('id'); + $('#table-models').bootstrapTable('refresh', {url: ref_url}); + }); +// --------------------------------------- + + $('.btnMultiselect').click(function (e) { + var kid = $(this).data('id'); + if ($(this).data('key') === 'Right') { + $('select').moveToListAndDelete('#source_' + kid, '#destination_' + kid); + } + if ($(this).data('key') === 'AllRight') { + $('select').moveAllToListAndDelete('#source_' + kid, '#destination_' + kid); + } + if ($(this).data('key') === 'Left') { + $('select').moveToListAndDelete('#destination_' + kid, '#source_' + kid); + } + if ($(this).data('key') === 'AllLeft') { + $('select').moveAllToListAndDelete('#destination_' + kid, '#source_' + kid); + } + e.preventDefault(); + }); +// Form.buttons - Form.adddevice + + $('.lineselect').change(function (e) { + var kid = $(this).data('id'); + var kval = $(this).val(); + $('.lineselect_' + kid).each(function () { + switch (kval) { + case 'silent': + case 'monitor': + case 'line': + $(this).removeClass('hidden'); + break; + case 'service': + case 'feature': + case 'speeddial': + case 'empty': + $(this).addClass('hidden'); + break; + } + }); + $('.linevalue_' + kid).each(function () { + switch (kval) { + case 'service': + case 'speeddial': + $(this).removeClass('hidden'); + break; + case 'feature': + case 'silent': + case 'monitor': + case 'empty': + case 'line': + $(this).addClass('hidden'); + break; + } + }); + $('.linefeature_' + kid).each(function () { + switch (kval) { + case 'feature': + $(this).removeClass('hidden'); + break; + case 'service': + case 'speeddial': + case 'silent': + case 'monitor': + case 'empty': + case 'line': + $(this).addClass('hidden'); + break; + } + }); + $('.linespeed_' + kid).each(function () { + if (kval == 'speeddial') { + $(this).removeClass('hidden'); + } else { + $(this).addClass('hidden'); + } + }); + }); +// Form.adddevice + $('.hw_select').change(function (e) { +// console.log('HwSelect'); + var type_id = $('#sccp_hw_type').find(':selected').data('id'); + var btn_dev = $('#sccp_hw_type').find(':selected').data('val'); +// var btn_add=$('#sccp_hw_addon').find(':selected').data('val'); + + if (type_id === 1) { + if ($('#sccp_hw_addon').val() !== 'none') { + $('#sccp_hw_addon').val('none').change(); + } + $('#sccp_hw_addon').attr("disabled", "disabled"); + + } else { + $('#sccp_hw_addon').removeAttr('disabled'); + } + + var btn_add = $('#sccp_hw_addon').find(':selected').data('val'); + $('.line_button').each(function () { + if ($(this).data('id') < btn_dev + btn_add) { + $(this).removeClass('hidden'); + $(this).removeAttr('hidden') + } else { + $(this).addClass('hidden'); + } + }); + + }); +// ----------------------- TEST Validate ---------------- + $('.need-validate').on('change', function (e) { + var dev_class = $(this).attr('class'); + var dev_id = $(this).val(); + if (dev_class.includes('validate-netmask')) { + confirm(dev_id); + } +// confirm(dev_id); + }); + +// $('.sccp_test').on('click', function (e) { +// var dev_id = []; +// $('table').bootstrapTable('getSelections').forEach(function (entry) { +// dev_id.push(entry['name']); +// }); +// dv = dev_id; +// confirm(dv); +// }); +// ----------------------- TEST ---------------- + + + $('.test').on('click', function (e) { + var dev_fld = ['onhook', 'connected', 'onhold', 'ringin', 'offhook', 'conntrans', 'digitsfoll', 'connconf', 'ringout', 'offhookfeat', + 'onhint', 'onstealable', 'holdconf', 'uriaction']; +// var x=document.getElementById("source_onhook"); +// var x=$("#source_onhook")[0]; +// console.log(x.length); + var datas = ''; + var tmp_val = ''; + var dev_opt = ''; + for (var i = 0; i < dev_fld.length; i++) { + dev_opt = $('#destination_' + dev_fld[i])[0]; + tmp_val = ''; + for (var n = 0; n < dev_opt.length; n++) { + if (n > 0) { + tmp_val += ','; + } + tmp_val += dev_opt.options[n].value; + } + datas += dev_fld[i] + '=' + tmp_val + '&'; + } + ; +// console.log(datas); + }); + + + + $('.sccp_update').on('click', function (e) { +// console.log($(this).data('id')); + +// ----------------------- Server.keyset form ---------------- +// + if ($(this).data('id') === 'keyset_add') { + var dev_cmd = 'updateSoftKey'; + if ($(this).data('mode') === 'new') { + dev_cmd = 'updateSoftKey'; + } + var dev_fld = ['onhook', 'connected', 'onhold', 'ringin', 'offhook', 'conntrans', 'digitsfoll', 'connconf', 'ringout', 'offhookfeat', + 'onhint', 'onstealable', 'holdconf']; + var datas = 'id=' + $('#new_keySetname').val() + '&'; + var tmp_val = ''; + var dev_opt = ''; + + for (var i = 0; i < dev_fld.length; i++) { + tmp_val = ''; + dev_opt = $('#destination_' + dev_fld[i])[0]; + for (var n = 0; n < dev_opt.length; n++) { + if (n > 0) { + tmp_val += ','; + } + tmp_val += dev_opt.options[n].value; + } + datas += dev_fld[i] + '=' + tmp_val + '&'; + } + ; + } + +// ----------------------- Server.model form ---------------- + + if ($(this).data('id') === 'model_add') { + var dev_cmd = 'model_add'; +// var dev_fld = ["model","vendor","dns","buttons","loadimage","loadinformationid","validate","enabled"]; + var dev_fld = ["model", "vendor", "dns", "buttons", "loadimage", "loadinformationid", "nametemplet"]; + datas = 'enabled=0' + '&'; + + for (var i = 0; i < dev_fld.length; i++) { + datas = datas + dev_fld[i] + '=' + $('#new_' + dev_fld[i]).val() + '&'; + } + ; + +// $("#add_new_model").modal('hide'); + } + if ($(this).data('id') === 'model_applay') { + var dev_cmd = 'model_update'; + var dev_fld = ["model", "loadimage", "nametemplet"]; + datas = ''; + for (var i = 0; i < dev_fld.length; i++) { + datas = datas + dev_fld[i] + '=' + $('#editd_' + dev_fld[i]).val() + '&'; + } + ; +// $("#edit_model").modal('hide'); + } + if (($(this).data('id') === 'model_enabled') || ($(this).data('id') === 'model_disabled')) { + var dev_cmd = $(this).data('id'); + var datas = ''; + var i = 0; + $('table').bootstrapTable('getSelections').forEach(function (entry) { + datas = datas + 'model[' + i + ']=' + entry['model'] + '&'; + i++; + }); + } +// ----------------------- form ---------------- + if ($(this).data('id') === 'create-cnf') { + var dev_cmd = 'create_hw_tftp'; + } + if ($(this).data('id') === 'delete_hardware') { + var dev_cmd = $(this).data('id'); + var datas = ''; + var i = 0; + $('table').bootstrapTable('getSelections').forEach(function (entry) { + datas = datas + 'idn[' + i + ']=' + entry['name'] + '&'; + i++; + }); + if (!confirm(_('Are you sure you wish to delete selected device ?'))) { + dev_cmd = ''; + } + + } + if ($(this).data('id') === 'reset_dev') { + var dev_cmd = $(this).data('id'); + var datas = ''; + var i = 0; + $('table').bootstrapTable('getSelections').forEach(function (entry) { + datas = datas + 'name[' + i + ']=' + entry['name'] + '&'; + i++; + }); + if (datas === '') { + if (confirm('Resaet All device')) { + datas = 'name[0]=all'; + } else { + dev_cmd = ''; + } + + } + } + if (dev_cmd !== '') { + $.ajax({ + type: 'POST', + url: 'ajax.php?module=sccp_manager&command=' + dev_cmd, + data: datas, + success: function (data) { +// console.log(data); + if (data.status === true) { + if (data.message) { + alert(data.message); + } + if (data.table_reload === true) { + $('table').bootstrapTable('refresh'); + } + if (data.reload === true) { + location.reload(); + } + } else { + if (Array.isArray(data.message)) { + data.message.forEach(function (entry) { + fpbxToast(entry, 'error', 'error'); + }); + } + } + } + + }); + } + + }); + $('#cr_sccp_phone_xml').on('click', function (e) { +// console.log("asasdasdasdasd"); +// console.log($('#update-sccp-phone').find(':selected').data('val')); + + }); +}); + + + +//$("table").on('click-cell.bs.table', function (field, value, row, $element) { +// var id_fld=$element['model']; Работает ! +// console.log('Table test: '+ id_fld); +// $('#bt'+id_fld).removeAttr('hidden'); +//}); + + +// Bootstrap table Enabled / Disabled butons ( class="btn-tab-select") +$("table").on('check-all.bs.table', function (rows) { + var id_fld = $(this).data('id'); + $(".btn-tab-select").each(function () { + $(this).removeAttr('disabled'); + }); +// console.log('Table unselect all' + id_fld); +}); +$("table").on('check.bs.table', function (e, row) { + var id_fld = $(this).data('id'); + $(".btn-tab-select").each(function () { + $(this).removeAttr('disabled'); + }); +// console.log('Table select ' + id_fld); +}); +$("table").on('uncheck.bs.table', function (e, row) { + var id_fld = $(this).data('id'); + var id_count = $("table").bootstrapTable('getAllSelections').length; + if (id_count < 1) { + $(".btn-tab-select").each(function () { + $(this).attr('disabled', true); + }); + } +// console.log('Table unselect ' + id_count); +}); +$("table").on('uncheck-all.bs.table', function (rows) { + var id_fld = $(this).data('id'); + var id_count = $("table").bootstrapTable('getAllSelections').length; + if (id_count < 1) { + $(".btn-tab-select").each(function () { + $(this).attr('disabled', true); + }); + } +// console.log('Table unselect all' + id_fld); +}); + +// +$("table").on("post-body.bs.table", function () { +// console.log('Table '); + $(this).find(".clickable.delete").click(function () { + var id = $(this).data("id"); +// console.log(id); + if (confirm(_("Are you sure you wish to delete this extension?"))) { + $.post("ajax.php", {command: "delete", module: "core", extensions: [id], type: "extensions"}, function (data) { + if (data.status) { + delete(extmap[id]); + $(".ext-list-sccp").bootstrapTable('remove', { + field: "name", + values: [id.toString()] + }); + toggle_reload_button("show"); + } else { + alert(data.message); + } + }); + } + }); +}); +function load_oncliсk(e, data) { + +// console.log('load_oncliсk'); + var add_softkey = false; + var add_btn = false; + + if (typeof e.href === 'undefined') { + add_softkey = false; + if (data == '*new*') { + add_softkey = true; + add_btn = true; + } + } else { + if (e.href.indexOf('#edit_softkeys')) { + add_softkey = true; + } + } + + if (add_softkey) { + var dev_fld = ['onhook', 'connected', 'onhold', 'ringin', 'offhook', 'conntrans', 'digitsfoll', 'connconf', 'ringout', 'offhookfeat', + 'onhint', 'onstealable', 'holdconf']; + if (add_btn) { + document.getElementById("new_keySetname").disabled = false; + data = 'SoftKeyset'; + } else { + var datas = $('#softkey-all').bootstrapTable('getRowByUniqueId', data); + } + document.getElementById("new_keySetname").value = data; + document.getElementById("new_keySetname").disabled = !add_btn; + var opts = ''; + var opts_idx = -1; + for (var i = 0; i < dev_fld.length; i++) { + opts = $('#destination_' + dev_fld[i] + ' option'); + if (opts.length > 0) { // Remove all + $(opts).remove(); + $('#source_' + dev_fld[i]).append($(opts).clone()); + } + if (!add_btn) { + sv_data = datas[dev_fld[i]].split("
"); + opts = $('#source_' + dev_fld[i] + ' option'); + for (var n = 0; n < sv_data.length; n++) { + opts_idx = -1; + for (var j = 0; j < opts.length; j++) { + if (opts[j].value === sv_data[n]) { + opts_idx = j; + } + } + if (opts_idx => 0) { + $('#destination_' + dev_fld[i]).append($(opts[opts_idx]).clone()); + $(opts[opts_idx]).remove(); + } + } + } + } + } +} + +function delete_oncliсk(e, data) { + var dev_cmd = ''; + var datas = ''; + if (e.href.indexOf('#delete_softkeys') > 0) { + dev_cmd = 'deleteSoftKey'; + datas = "softkey=" + data; + } + if (e.href.indexOf('#delete_model') > 0) { + dev_cmd = 'model_delete'; + datas = "model=" + data; + } + if (e.href.indexOf('#delete_hardware') > 0) { + dev_cmd = 'delete_hardware'; + datas = "idn[0]=" + data; + } +// console.log("delete : " + data); + if (confirm(_('Are you sure you wish to delete "' + data.toUpperCase() + '" inormation ?'))) { + $.ajax({ + type: 'POST', + url: 'ajax.php?module=sccp_manager&command=' + dev_cmd, + data: datas, + success: function (data) { +// console.log(data); + if (data.status === true) { + if (data.message) { + alert(data.message); + } + if (data.table_reload === true) { + $('table').bootstrapTable('refresh'); + } + if (data.reload === true) { + location.reload(); + } + } else { + if (Array.isArray(data.message)) { + data.message.forEach(function (entry) { + fpbxToast(entry, 'error', 'error'); + }); + } + } + } + }); + } + +} +function add_dynamic_input(pe, pclass, vdefault) { + // We'd like a new one, please. + pcls = pe.data('for'); + pname = pe.data('id'); + jdata = JSON.parse(hex2bin(pe.data('json'))); + + var last = $("."+pcls+":last"), + ourid = last.data('nextid'), + nextid = ourid + 1; + var html = "
"; + for (var key in jdata) { + html_opt = ''; + html_calss = jdata[key]['class']; + for (var skey in jdata[key]['options']) { + html_opt += ' ' + skey+'="' + jdata[key]['options'][skey] +'"'; + } + html += " "+ jdata[key]['nameseparator'] + " "; + } + html += "
\n"; + + last.after(html); +} + +var theForm = document.editIax; +/* Insert a iax_setting/iax_value pair of text boxes */ +(function ($) { + //Moves selected item(s) from sourceList to destinationList + $.fn.moveToList = function (sourceList, destinationList) { + var opts = $(sourceList + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(destinationList).append($(opts).clone()); + }; + + //Moves all items from sourceList to destinationList + $.fn.moveAllToList = function (sourceList, destinationList) { + var opts = $(sourceList + ' option'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(destinationList).append($(opts).clone()); + }; + + //Moves selected item(s) from sourceList to destinationList and deleting the + // selected item(s) from the source list + $.fn.moveToListAndDelete = function (sourceList, destinationList) { + var opts = $(sourceList + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(opts).remove(); + $(destinationList).append($(opts).clone()); + }; + + //Moves all items from sourceList to destinationList and deleting + // all items from the source list + $.fn.moveAllToListAndDelete = function (sourceList, destinationList) { + var opts = $(sourceList + ' option'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + $(opts).remove(); + $(destinationList).append($(opts).clone()); + }; + + //Removes selected item(s) from list + $.fn.removeSelected = function (list) { + var opts = $(list + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to remove"); + } + + $(opts).remove(); + }; + + //Moves selected item(s) up or down in a list + $.fn.moveUpDown = function (list, btnUp, btnDown) { + var opts = $(list + ' option:selected'); + if (opts.length == 0) { + alert("Nothing to move"); + } + + if (btnUp) { + opts.first().prev().before(opts); + } else if (btnDown) { + opts.last().next().after(opts); + } + }; +})(jQuery); + +/* +String.prototype.hex2bin = function() +{ + var i = 0, len = this.length, result = ""; + + //Converting the hex string into an escaped string, so if the hex string is "a2b320", it will become "%a2%b3%20" + for(; i < len; i+=2) + result += '%' + this.substr(i, 2); + + return unescape(result); +} +*/ + +function hex2bin(hex) +{ + var bytes = [], str; + + for(var i=0; i< hex.length-1; i+=2) + bytes.push(parseInt(hex.substr(i, 2), 16)); + + return String.fromCharCode.apply(String, bytes); +} + diff --git a/conf/Sccp.class.php b/conf/Sccp.class.php new file mode 100644 index 0000000..18bb044 --- /dev/null +++ b/conf/Sccp.class.php @@ -0,0 +1,222 @@ +'pin', "label" => 'label', "accountcode" => 'account', + "context" =>'context',"incominglimit"=>'incominglimit', + "callgroup"=>'callgroup',"pickupgroup"=>'pickupgroup', + "transfer" => 'transfer', "echocancel" => 'echocancel', + "language" => 'language', "description" => 'callerid', + "cid_num" => 'cid_num', "cid_name" => 'label', "mailbox" => 'description', + "musicclass" => 'musicclass', + "dnd" => 'dnd', "silencesuppression" => 'silencesuppression', + 'namedcallgroup'=>'namedcallgroup', 'namedpickupgroup' => 'namedpickupgroup' + ); + + public function getInfo() { + return array( + "rawName" => "sccp", + "hardware" => "sccp_custom", + "prettyName" => _("Sccp Custom Driver"), + "shortName" => _("Sccp"), + "description" => _("Sccp Device") + ); + } + 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'); +// print_r($_REQUEST); +// echo '

'; +// die(print_r($settings)); + $settings['cid_num']['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; + } + $sql = 'INSERT INTO sccpline (name, id'; + $sqlv = 'values ("'.$id.'", "'.$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; + } + + public function delDevice($id) { + $sql = "DELETE FROM sccpline WHERE id = ?"; + $sth = $this->database->prepare($sql); + $sth->execute(array($id)); + return true; + } + + + public function getDevice($id) { + $sccp_line = array(); + $sql = "SELECT id"; + foreach($this->data_fld as $key => $val) { + $sql .= ',`'. $key .'` as '.$val; + } + $sql .= " FROM sccpline WHERE id = ?"; + $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; + } + + public function getDefaultDeviceSettings($id, $displayname, &$flag) { + $dial = 'SCCP'; + $settings = array( + "pin" => array( + "value" => "", + "flag" => $flag++ + ), + "incominglimit" => array( + "value" => "", + "flag" => $flag++ + ), + "context" => 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" => "no", + "flag" => $flag++ + ), + "silencesuppression" => array( + "value" => "no", + "flag" => $flag++ + ), + "musicclass" => array( + "value" => "default", + "flag" => $flag++ + ), + ); + return array( + "dial" => $dial, + "settings" => $settings + ); + } + + public function getDeviceDisplay($display, $deviceInfo, $currentcomponent, $primarySection) { + $section = _("Settings"); + $category = "general"; + $tmparr = array(); + $tt = _("The SCCP channel number for this port."); + $tmparr['incominglimit'] = array('prompttext' => _('Line incoming limit'), 'value' => '2', 'tt' => $tt, 'level' => 0, 'jsvalidation' => 'isEmpty()', 'failvalidationmsg' => $msgInvalidChannel); + $tt = _("Asterisk context this device will send calls to. Only change this is you know what you are doing."); + $tmparr['context'] = array('prompttext' => _('Line context'), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1); + $tt = _("Phone call group callgroup=1,3-4"); + $tmparr['callgroup'] = array('prompttext' => _('Call group id'),'value' => '', 'tt' => $tt, 'level' => 1); + $tt = _("Phone pickup group pickupgroup=1,3-4"); + $tmparr['namedcallgroup'] = array('prompttext' => _('Call group name'),'value' => '', 'tt' => $tt, 'level' => 1); + $tt = _("sets the named caller groups this line is a member of (ast111)"); + $tmparr['pickupgroup'] = array('prompttext' => _('Pickup group id'),'value' => '', 'tt' => $tt, 'level' => 1); + $tt = _("Phone pincode"); + $tmparr['namedpickupgroup'] = array('prompttext' => _('Pickup group name'),'value' => '', 'tt' => $tt, 'level' => 1); + $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); + + 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' => 'yes', 'text' => 'Yes'); + $select[] = array('value' => 'no', 'text' => 'No'); + $tt = _("Echo calcel"); + $tmparr['echocancel'] = array('prompttext' => _('Echo calcel'), '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'); + $tt = _("Do Not Disturb."); + $tmparr['dnd'] = array('prompttext' => _('DND'), 'value' => 'user', '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."); + $tmparr['silencesuppression'] = array('prompttext' => _('Silence Suppression'), 'value' => 'yes', '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)); + } + + $tt = _("Musik On Hold "); + $tmparr['musicclass'] = array('prompttext' => _('Musik On Hold'), 'value' => 'no', 'tt' => $tt, 'select' => $select, 'level' => 1); + + + + $devopts = $tmparr; + return $devopts; + } +} diff --git a/conf/sccp.conf b/conf/sccp.conf new file mode 100644 index 0000000..52af4a5 --- /dev/null +++ b/conf/sccp.conf @@ -0,0 +1,50 @@ +;========================================================================================= +; +; general definitions +; +;========================================================================================= +[general] +servername=VPBXSCCP +keepalive=60 +debug=1 +context=from-internal-xfer +bindaddr=0.0.0.0 +port=2000 +deny=0.0.0.0/0.0.0.0 +permit=0.0.0.0/0.0.0.0 +dateformat=D.M.Y +disallow=all +allow=alaw +allow=ulaw +firstdigittimeout=16 +digittimeout=8 +autoanswer_ring_time=1 +autoanswer_tone=0x32 +remotehangup_tone=0x32 +transfer_tone=0 +callwaiting_tone=0x2d +musicclass=default +language=en +echocancel=on +silencesuppression=off +private=on +directed_pickup_modeanswer=on +callanswerorder=oldestfirst +sccp_tos=0x68 +sccp_cos=4 +audio_tos=0xB8 +audio_cos=6 +video_tos=0x88 +video_cos=5 +hotline_enabled=yes +hotline_context=default +hotline_extension=111 +devicetable=sccpdevice +linetable=sccpline + +[KeySet1] ; Managed by sccp_manager +type=softkeyset +onhook=redial,newcall,cfwdall,dnd,pickup,gpickup,private +connected=hold,endcall,park,select,cfwdall,cfwdbusy +onhold=newcall + diff --git a/functions.inc.php b/functions.inc.php new file mode 100644 index 0000000..27a8a95 --- /dev/null +++ b/functions.inc.php @@ -0,0 +1,59 @@ +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($this, $inthat) { + if (!is_bool(strpos($inthat, $this))) + return substr($inthat, strpos($inthat, $this) + strlen($this)); +} + +function after_last($this, $inthat) { + if (!is_bool(strrevpos($inthat, $this))) + return substr($inthat, strrevpos($inthat, $this) + strlen($this)); +} + +function before($this, $inthat) { + return substr($inthat, 0, strpos($inthat, $this)); +} + +function before_last($this, $inthat) { + return substr($inthat, 0, strrevpos($inthat, $this)); +} + +function between($this, $that, $inthat) { + return before($that, after($this, $inthat)); +} + +function between_last($this, $that, $inthat) { + return after_last($this, 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); +} + + +?> \ No newline at end of file diff --git a/install.php b/install.php new file mode 100644 index 0000000..9d5da4c --- /dev/null +++ b/install.php @@ -0,0 +1,249 @@ +Sccp_manager; + +outn(_("checking for requery Sccp_manager table..")); +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); + out(_("none, Can't fient table: " . $value)); + out(_("none, Plz. Open chai-sccp/conf directory to create DB scheme")); + die(_("none, creating table: " . $value)); + } +} + + +$version = FreePBX::Config()->get('ASTVERSION'); +outn(_("checking Version : ").$version); + +if (!empty($version)) { + // Woo, we have a version + if (version_compare($version, "12.2.0", ">=")) { + $ver_compatable = true; + } +} else { + // Well. I don't know what version of Asterisk I'm running. + // Assume less than 12. + $ver_compatable = false; + die('Versin is not comapable'); +} + + out(_("none, creating table")); + $check = $db->query($sql); +// sql($sql); + if (db::IsError($check)) { + die_freepbx("Can not create sccpdevmodel table\n"); + } + + $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', + `nametemplet` VARCHAR(50) NULL DEFAULT NULL, + PRIMARY KEY (`model`), + KEY `model` (`model`) + ) ENGINE=MyISAM DEFAULT CHARSET=latin1"; + + $check = $db->query($sql); + if (db::IsError($check)) { + die_freepbx("Can not create sccpsettings table\n"); + } + if ($db->getAll('SHOW COLUMNS FROM sccpdevice WHERE FIELD = "pickupexten"')) { + out(_("none, modify table from old scheme")); + $sql = "ALTER TABLE `sccpdevice` + CHANGE COLUMN `pickupexten` `directed_pickup` VARCHAR(5) NULL DEFAULT 'yes', + CHANGE COLUMN `pickupcontext` `directed_pickup_context` VARCHAR(100) NULL DEFAULT '' , + CHANGE COLUMN `pickupmodeanswer` `directed_pickup_modeanswer` VARCHAR(5) NULL DEFAULT 'yes'"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not add loadinformationid into sccpdevmodel table\n"); + } + } + + + if (!$db->getAll('SHOW COLUMNS FROM sccpdevmodel WHERE FIELD = "loadinformationid"')) { + out(_("none, modify table from old scheme")); + $sql = "ALTER TABLE `sccpdevmodel` ADD `loadinformationid` varchar(30);"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not add loadinformationid into sccpdevmodel table\n"); + } + } + if (!$db->getAll('SHOW COLUMNS FROM sccpdevmodel WHERE FIELD = "nametemplet"')) { + out(_("none, modify table from old scheme")); + $sql = "ALTER TABLE `sccpdevmodel` ADD COLUMN `enabled` INT(2) NULL DEFAULT '0', ADD COLUMN `nametemplet` VARCHAR(50) NULL DEFAULT NULL,"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not add loadinformationid into sccpdevmodel table\n"); + } + } + if (!$db->getAll('SHOW COLUMNS FROM sccpdevice WHERE FIELD = "hwlang"')) { + out(_("none, modify table from old scheme")); + $sql = "ALTER TABLE `sccpdevice` ADD COLUMN `hwlang` varchar(12) NULL DEFAULT NULL, + ADD COLUMN `useRedialMenu` VARCHAR(5) NULL DEFAULT 'no' AFTER `hwlang` + "; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not add loadinformationid into sccpdevmodel table\n"); + } + } + if (!$db->getAll('SHOW COLUMNS FROM sccpdevice WHERE FIELD = "dtmfmode"')) { + out(_("none, modify table from old scheme")); + $sql = "ALTER TABLE `sccpdevice` ADD COLUMN `dtmfmode` varchar(10) default NULL"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not add loadinformationid into sccpdevmodel table\n"); + } + } + if (!$db->getAll('SHOW COLUMNS FROM sccpline WHERE FIELD = "adhocNumber"')) { + out(_("none, modify sccpline table from old scheme")); + $sql = "ALTER TABLE `sccpline` + ADD COLUMN `namedcallgroup` VARCHAR(45) NULL DEFAULT NULL AFTER `setvar`, + ADD COLUMN `namedpickupgroup` VARCHAR(45) NULL DEFAULT NULL AFTER `namedcallgroup`, + ADD COLUMN `adhocNumber` VARCHAR(45) NULL DEFAULT NULL AFTER `namedpickupgroup`, + ADD COLUMN `meetme` VARCHAR(5) NULL DEFAULT NULL AFTER `adhocNumber`, + ADD COLUMN `meetmenum` VARCHAR(45) NULL DEFAULT NULL AFTER `meetme`, + ADD COLUMN `meetmeopts` VARCHAR(45) NULL DEFAULT NULL AFTER `meetmenum`, + ADD COLUMN `regexten` VARCHAR(45) NULL DEFAULT NULL AFTER `meetmeopts`;"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not add loadinformationid into sccpdevmodel table\n"); + } + } + + + out(_("none, Uptade Table Info")); + +//$sql = "REPLACE INTO `sccpdevmodel` VALUES ('7925','CISCO',1,1,'',''),('7902','CISCO',1,1,'CP7902080002SCCP060817A','loadInformation30008'),('7905','CISCO',1,1,'CP7905080003SCCP070409A','loadInformation20000'),('7906','CISCO',1,1,'SCCP11.8-3-1S','loadInformation369'),('7910','CISCO',1,1,'P00405000700','loadInformation6'),('7911','CISCO',1,1,'SCCP11.8-3-1S','loadInformation307'),('7912','CISCO',1,1,'CP7912080003SCCP070409A','loadInformation30007'),('7914','CISCO',0,14,'S00105000300','loadInformation124'),('7920','CISCO',1,1,'cmterm_7920.4.0-03-02','loadInformation30002'),('7921','CISCO',1,1,'CP7921G-1.0.3','loadInformation365'),('7931','CISCO',1,1,'SCCP31.8-3-1S','loadInformation348'),('7936','CISCO',1,1,'cmterm_7936.3-3-13-0','loadInformation30019'),('7937','CISCO',1,1,'','loadInformation431'),('7940','CISCO',1,2,'P00308000500','loadInformation8'),('Digital Access+','CISCO',1,1,'D00303010033','loadInformation42'),('7941','CISCO',1,2,'P00308000500','loadInformation115'),('7941G-GE','CISCO',1,2,'P00308000500','loadInformation309'),('7942','CISCO',1,2,'P00308000500','loadInformation434'),('Digital Access','CISCO',1,1,'D001M022','loadInformation40'),('7945','CISCO',1,2,'P00308000500','loadInformation435'),('7960','CISCO',3,6,'P00308000500','loadInformation7'),('7961','CISCO',3,6,'P00308000500','loadInformation30018'),('7961G-GE','CISCO',3,6,'P00308000500','loadInformation308'),('7962','CISCO',3,6,'P00308000500','loadInformation404'),('7965','CISCO',3,6,'P00308000500','loadInformation436'),('7970','CISCO',3,8,'SCCP70.8-3-1S','loadInformation30006'),('7971','CISCO',3,8,'SCCP70.8-3-1S','loadInformation119'),('7975','CISCO',3,8,'SCCP70.8-3-1S','loadInformation437'),('7985','CISCO',3,8,'cmterm_7985.4-1-4-0','loadInformation302'),('ATA 186','CISCO',1,1,'ATA030203SCCP051201A','loadInformation12'),('IP Communicator','CISCO',1,1,'','loadInformation30016'),('12 SP','CISCO',1,1,'','loadInformation3'),('12 SP+','CISCO',1,1,'','loadInformation2'),('30 SP+','CISCO',1,1,'','loadInformation1'),('30 VIP','CISCO',1,1,'','loadInformation5'),('7914,7914','CISCO',0,28,'S00105000300','loadInformation124'),('7915','CISCO',0,14,'',''),('7916','CISCO',0,14,'',''),('7915,7915','CISCO',0,28,'',''),('7916,7916','CISCO',0,28,'',''),('CN622','MOTOROLA',1,1,'','loadInformation335'),('ICC','NOKIA',1,1,'',''),('E-Series','NOKIA',1,1,'',''),('3911','CISCO',1,1,'','loadInformation446'),('3951','CISCO',1,1,'','loadInformation412');"; + $sql = "REPLACE INTO `sccpdevmodel` (`model`, `vendor`, `dns`, `buttons`, `loadimage`, `loadinformationid`, `enabled`, `nametemplet`) 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-2-1-0', 'loadInformation496', 0, NULL), ('6941', 'CISCO', 1, 1, 'SCCP69xx.9-2-1-0', 'loadInformation495', 0, NULL), ('6945', 'CISCO', 1, 0, 'SCCP6945.9-2-1-0', '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-2-1S', 'loadInformation369', 1, 'SEP0000000000.cnf.xml_791x_template'), ('7910', 'CISCO', 1, 1, 'SCCP11.9-2-1S', 'loadInformation6', 1, 'SEP0000000000.cnf.xml_791x_template'), ('7911', 'CISCO', 1, 1, 'SCCP11.9-2-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', 'loadInformation227', 1, NULL), ('7915,7915', 'CISCO', 0, 48, 'B015-1-0-4', 'loadInformation228', 1, NULL), ('7916', 'CISCO', 0, 24, 'B015-1-0-4', 'loadInformation229', 1, NULL), " . + "('7916,7916', 'CISCO', 0, 48, 'B016-1-0-4', 'loadInformation230', 1, NULL), ('7920', 'CISCO', 1, 1, 'cmterm_7920.4.0-03-02', 'loadInformation30002', 0, NULL), ('7921', 'CISCO', 1, 1, 'CP7921G-1.4.1SR1', 'loadInformation365', 0, NULL),('7925', 'CISCO', 1, 2, 'CP7925G-1.4.1SR1', 'loadInformation484', 0, NULL), ('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-4-0', 'loadInformation431', 0, 'SEP0000000000.cnf.xml_7937_template'), ('7940', 'CISCO', 1, 2, 'P0030801SR02', 'loadInformation8', 1, 'SEP0000000000.cnf.xml_796x_template'), " . + "('7941', 'CISCO', 1, 2, 'SCCP41.9-2-1S', 'loadInformation115', 0, 'SEP0000000000.cnf.xml_796x_template'),('7941G-GE', 'CISCO', 1, 2, 'SCCP41.9-2-1S', 'loadInformation309', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7942', 'CISCO', 1, 2, 'SCCP42.9-2-1S', 'loadInformation434', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7945', 'CISCO', 1, 2, 'SCCP45.9-2-1S', 'loadInformation435', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7960', 'CISCO', 3, 6, 'P0030801SR02', 'loadInformation7', 1, 'SEP0000000000.cnf.xml_796x_template'), ('7961', 'CISCO', 3, 6, 'SCCP41.9-2-1S', 'loadInformation30018', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7961G-GE', 'CISCO', 3, 6, 'SCCP41.9-2-1S', 'loadInformation308', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7962', 'CISCO', 3, 6, 'SCCP42.9-2-1S', 'loadInformation404', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7965', 'CISCO', 3, 6, 'SCCP45.9-2-1S', 'loadInformation436', 0, 'SEP0000000000.cnf.xml_796x_template'), ('7970', 'CISCO', 3, 8, 'SCCP70.9-2-1S', 'loadInformation30006', 0, NULL), ('7971', 'CISCO', 1, 2, 'SCCP75.9-2-1S', 'loadInformation119', 0, NULL), ('7975', 'CISCO', 3, 8, 'SCCP75.9-2-1S', 'loadInformation437', 0, NULL), ('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, NULL), ('ATA 187', 'CISCO', 1, 1, 'ATA187.9-2-3-1', 'loadInformation550', 0, NULL), ('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), " . + "('IP Communicator', 'CISCO', 1, 1, '', 'loadInformation30016', 0, NULL), ('Nokia E', 'Nokia', 0, 28, '', 'loadInformation275', 0, NULL), ('VGC Phone', 'CISCO', 1, 1, '', 'loadInformation10', 0, NULL), ('VGC Virtual', 'CISCO', 1, 1, '', 'loadInformation11', 0, NULL);"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not REPLACE defaults into sccpdevmodel table\n"); + } + + $sql = "ALTER TABLE sccpline + ALTER COLUMN incominglimit SET DEFAULT '2', + ALTER COLUMN transfer SET DEFAULT 'on', + ALTER COLUMN vmnum SET DEFAULT '*97', + ALTER COLUMN musicclass SET DEFAULT 'default', + ALTER COLUMN echocancel SET DEFAULT 'on', + ALTER COLUMN silencesuppression SET DEFAULT 'off', + CHANGE COLUMN `dnd` `dnd` VARCHAR(12) NULL DEFAULT 'off' + "; + + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not modify sccpline table\n"); + } + + $sql = "ALTER TABLE sccpdevice + ALTER COLUMN transfer SET DEFAULT 'on', + ALTER COLUMN cfwdall SET DEFAULT 'on', + ALTER COLUMN cfwdbusy SET DEFAULT 'on', + ALTER COLUMN dtmfmode SET DEFAULT 'outofband', + ALTER COLUMN dndFeature SET DEFAULT 'on', + ALTER COLUMN directrtp SET DEFAULT 'off', + ALTER COLUMN earlyrtp SET DEFAULT 'progress', + ALTER COLUMN mwilamp SET DEFAULT 'on', + ALTER COLUMN mwioncall SET DEFAULT 'on', + ALTER COLUMN private SET DEFAULT 'on', + ALTER COLUMN privacy SET DEFAULT 'off', + ALTER COLUMN nat SET DEFAULT 'off', + ALTER COLUMN softkeyset SET DEFAULT 'softkeyset' + "; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not modify sccpdevice table\n"); + } + $sql = "DROP TRIGGER IF EXISTS trg_buttonconfig; + DELIMITER $$ + CREATE TRIGGER trg_buttonconfig BEFORE INSERT ON buttonconfig + FOR EACH ROW + BEGIN + IF NEW.`type` = 'line' THEN + IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = SUBSTRING_INDEX(NEW.`name`,'!',1)) = 0 + THEN + UPDATE `Foreign key contraint violated: line does not exist in sccpline` SET x=1; + END IF; + END IF; + END$$ + DELIMITER ;"; + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not modify sccpdevice table\n"); + } + $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.* + FROM sccpdevice + LEFT JOIN buttonconfig ON ( buttonconfig.device = sccpdevice.name ) + GROUP BY sccpdevice.name;"; + + $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`.`directed_pickup` AS `directed_pickup`, + `sccpdevice`.`directed_pickup_context` AS `directed_pickup_context`,`sccpdevice`.`directed_pickup_modeanswer` AS `directed_pickup_modeanswer`, + `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`,`sccpdevice`.`dtmfmode` AS `dtmfmode`,`sccpdevice`.`useRedialMenu` AS `useRedialMenu` + FROM sccpdevice + LEFT JOIN buttonconfig ON ( buttonconfig.device = sccpdevice.name ) + GROUP BY sccpdevice.name;"; + + $check = $db->query($sql); + if (DB::IsError($check)) { + die_freepbx("Can not modify sccpdevice table\n"); + } + + +// $ss->save_submit($request); +// $ss->sccp_create_sccp_init(); +// $ss->sccp_db_save_setting(); + +//} \ No newline at end of file diff --git a/module.xml b/module.xml new file mode 100644 index 0000000..cb592c6 --- /dev/null +++ b/module.xml @@ -0,0 +1,21 @@ + + sccp_manager + SCCP Manager + 13.0.0.1 + setup + SCCP Connectivity + Alex GP + SCCP Phone and Extention Manager + + SCCP Server Config + SCCP Phones Manager + + + * Version 13.0.0.1 * - Alfa Release tested on freepbx v.13.0.192.16, v.14.0.1.5 + + + + 13.0.0.1 + + + diff --git a/page.sccp_phone.php b/page.sccp_phone.php new file mode 100644 index 0000000..c0edffb --- /dev/null +++ b/page.sccp_phone.php @@ -0,0 +1,49 @@ +Sccp_manager; +$display_page = $spage->PhoneShowPage(); +$display_info = _("SCCP Phone Manager"); + +?> + +
+

+
+
+
+
+ +
+ $page) { ?> +
+ +
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/page.sccpsettings.php b/page.sccpsettings.php new file mode 100644 index 0000000..2c07da9 --- /dev/null +++ b/page.sccpsettings.php @@ -0,0 +1,42 @@ +Sccp_manager; +?> + +
+

+
+
+
+
+ +
+ myShowPage() as $key => $page) { ?> +
+ +
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/uninstall.php b/uninstall.php new file mode 100644 index 0000000..c46c827 --- /dev/null +++ b/uninstall.php @@ -0,0 +1,31 @@ +get('ASTVERSION'); + + echo "dropping table sccpdevmodel.."; + sql("DROP TABLE IF EXISTS `sccpdevmodel`"); + echo "dropping table sccpsettings.."; + sql("DROP TABLE IF EXISTS `sccpsettings`"); + if (!empty($version)) { + // Woo, we have a version + if (version_compare($version, "14.0.0", "<=")) { + echo "Deleting key FROM kvstore.."; + sql("DELETE FROM kvstore WHERE module = 'sccpsettings'"); + sql("DELETE FROM kvstore WHERE module = 'Sccp_manager'"); + } +/* DROP VIEW `sccpdeviceconfig`; + DROP TABLE `buttonconfig`; + DROP TABLE `sccpdevice`; + DROP TABLE `sccpdevmodel`; + DROP TABLE `sccpline`; + DROP TABLE `sccpsettings`; + * + */ + } + + echo "done
\n"; + +?> diff --git a/views/form.adddevice.php b/views/form.adddevice.php new file mode 100644 index 0000000..02e75d6 --- /dev/null +++ b/views/form.adddevice.php @@ -0,0 +1,57 @@ +get_db_SccpTableData('get_sccpdevice_byid', array("id" => $dev_id)); + foreach ($db_res as $key => $val) { + if (!empty($val)) { + switch ($key) { + case 'name': + $key = 'mac'; + $val = str_replace('SEP', '', $val); + break; + case 'hwlang': + $tmpar = explode(":",$val); + $def_val['netlang'] = array("keyword" => 'netlang', "data" => $tmpar[0], "seq" => "99"); + $def_val['devlang'] = array("keyword" => 'devlang', "data" => $tmpar[1], "seq" => "99"); + break; + case 'permit': + case 'deny': + $def_val[$key . '_net'] = array("keyword" => $key, "data" => before('/', $val), "seq" => "99"); + $key = $key . '_mask'; + $val = after('/', $val); + break; + } + $def_val[$key] = array("keyword" => $key, "data" => $val, "seq" => "99"); + } + } +} +?> + +
+ + + + '; + echo $this->ShowGroup('sccp_hw_dev', 1, 'sccp_hw_', $def_val); + } else { + echo ''; + echo $this->ShowGroup('sccp_hw_dev_edit', 1, 'sccp_hw_', $def_val); + } + echo $this->ShowGroup('sccp_hw_dev2', 1, 'sccp_hw_', $def_val); + echo $this->ShowGroup('sccp_hw_dev_advance', 1, 'sccp_hw_', $def_val); + echo $this->ShowGroup('sccp_hw_dev_conference', 1, 'sccp_hw_', $def_val); + echo $this->ShowGroup('sccp_hw_dev_network', 1, 'sccp_hw_', $def_val); + ?> +
diff --git a/views/form.buttons.php b/views/form.buttons.php new file mode 100644 index 0000000..1eb11de --- /dev/null +++ b/views/form.buttons.php @@ -0,0 +1,201 @@ +"dev_buttons",label=>"Buttons Configuration"), + array("name"=>"button",label=>"Buttons ",help=>"help.") + ); +//$buttons_type= array("empty","line","service","feature","speeddial"); +// "feature","service" -- Add leter ! +$buttons_type= array("empty","line","silent","monitor","speeddial","feature"); +$feature_list= array('parkinglot'=>'Park Slots','monitor'=> "Record Calls",'devstate'=> "Change Status"); + +$lines_list = $this->get_db_SccpTableData('SccpExtension'); +$hint_list = $this->get_db_SccpTableData('SccpExtension'); +//$hint_list = $this->sccp_list_hints(); +$line_id =0; +$max_buttons =56; +$show_buttons =1; +//print_r($hint_list); +if (!empty($_REQUEST['id'])) { + $dev_id = $_REQUEST['id']; + $db_butons = $this->get_db_SccpTableData('get_sccpdevice_buttons', array("id" => $dev_id)); + $db_device = $this->get_db_SccpTableData('get_sccpdevice_byid', array("id" => $dev_id)); + $max_buttons = $db_device['buttons']; + if (!empty($db_device['addon_buttons'])){ + $max_buttons += $db_device['addon_buttons']; + } + $show_buttons = $max_buttons; +} +?> + +
+ + + +
+

+
+
+
+
+ + +
+
+ +
    +
  • empty: Empty button (no options)
  • +
  • line: Registers the line with identifier specified as [name]
  • +
  • silent: butons equal 'Line' with out ring
  • +
  • monitor: butons mode speeddial + show status
  • +
  • speeddial: Adds a speeddial with label [name] and [option1] as number Optionally, [option2] can be used to specify a hint by extension@context as usual.
  • +
  • service (not implemented): Adds a service url Feature buttons have an on/off status represented on the device with a tick-box and can be used to set the device in a particular state. Currently Possible [option1],[option2] combinations:
  • +
      +
    • privacy,callpresent = Make a private call, number is suppressed
    • privacy,hint = Make a private call, hint is suppressed
    • cfwdall,number = Forward all calls
    • cfwbusy,number = Forward on busy
    • + cfwnoaswer,number = Forward on no-answer (not implemented yet)
      DND,busy = Do-not-disturb, return Busy signal to Caller
      DND,silent = Do-not-disturb, return nothing to caller
      + monitor = Record Calls using AutoMon (asterisk 1.6.x only)
    • devstate,custom_devstate = Device State Feature Button (asterisk 1.6.1 and up). custom_devstate is the name of the custom devicestate to be toggled (How to use devicestate) + hold = To be implemented
    • transfer = To be implemented
    • multiblink = To be implemented
    • mobility = To be implemented
    • conference = To be implemented
    • + ");?> +
+ +
+ 0) { + $defaul_btn = strtok($defaul_btn,'!'); + $defaul_tv = 'silent'; + $def_silent = 'checked'; + } + if ($defaul_tv == "feature") { + $defaul_ftr = $defaul_opt[0]; + $defaul_fcod = (empty($defaul_opt[1])) ? '': $defaul_opt[1]; + } + foreach ($defaul_opt as $data_i) { + if (strpos($data_i,'@') >0) { + $defaul_btn = strtok($data_i,'@'); + $def_hint = 'checked'; + if ($defaul_btn == $defaul_opt[0]) { + $show_form_mode = 'line'; + $defaul_tv = 'monitor'; + } + } + } + + echo ''; + echo '
'; + ?> +
+
+ +
+
+
+ + +
+ +
+ + + + +
+ '; + ?> +
+
+ +
+
+ +
+ '; + echo ''; + echo '
'; + echo ''; + echo ''; + echo '
'; + + echo ''; + echo '
'; + ?> +
+
+
+ '; + ?> +
+
+ '; + ?> +
+
+ + +
+ +
+
+ '; + } + + ?> + + + + +
diff --git a/views/formShow.php b/views/formShow.php new file mode 100644 index 0000000..7b36a96 --- /dev/null +++ b/views/formShow.php @@ -0,0 +1,523 @@ +checkStatus("soundlang")) { + $syslangs = \FreePBX::Soundlang()->getLanguages(); + if (!is_array($syslangs)) { + $syslangs = array(); + } +} +if (function_exists('music_list')){ + $moh_list = music_list(); +// $cur = (isset($mohsilence) && $mohsilence != "" ? $mohsilence : 'default'); +} +if (!is_array($moh_list)){ + $moh_list = array('default'); +} +$sofkey_list = \FreePBX::Sccp_manager()-> sccp_list_keysets(); +$model_list = \FreePBX::Sccp_manager()->get_db_SccpTableData("HWDevice"); +$extension_list = \FreePBX::Sccp_manager()->get_db_SccpTableData("HWextension"); + +$extension_list[]=array(model=>'none', vendor=>'CISCO', dns=>'0'); + +$items = $itm -> children(); +//print_r($sofkey_list); +//print_r($syslangs); +//print_r($moh_list); +if ($h_show==1) { + ?> + +
+

label) ?>

+
+
+ +input[0]->name; + if (empty($child->nameseparator)) { + $child->nameseparator = ' / '; + } + $i = 0; + + echo ''; + + ?> +
+
+
+ + +
+
+ xpath('input') as $value) { + $res_n = (string)$value->name; + $res_name = $npref . $res_n; + if (empty($res_id)) { + $res_id = $res_name; + } + + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $value->value = $fvalues[$res_n]['data']; + } + } + + if (empty($value->value)) { + $value->value = $value->default; + } + if (empty($value->type)) { + $value->type = 'text'; + } + if (empty($value->class)) { + $value->class = 'form-control'; + } + if ($i > 0) echo $child->nameseparator; +// + echo 'options)){ + foreach ($value->options ->attributes() as $optkey =>$optval){ + echo ' '.$optkey.'="'.$optval.'"'; + } + } + if (!empty($value->min)) echo ' min="'.$value->min.'"'; + if (!empty($value->max)) echo ' max="'.$value->max.'"'; + echo '>'; + $i ++; + + } + ?> +
+
+
+ help);?> +
+
+ + label.' -->'; + + } + if ($child['type'] == 'IED') { + $res_input = ''; + $res_name = ''; + $res_n = (string)$child->name; + +// $res_value + $lnhtm = ''; + $res_id = $napref.$child->name; + $i = 0; + + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $res_value = explode(';', $fvalues[$res_n]['data']); + } + } + if (empty($res_value)) { + $res_value = array((string) $child->default); +// $res_value = explode('/', (string) $child->default); + } + + echo ''; + ?> + +
+
+
+
+
+
+ + +
+
+ +
> + xpath('input') as $value) { + $res_n = $res_id.'['.$i.']['.$value['field'].']'; + $fields_id = (string)$value['field']; + $opt_at[$fields_id]['nameseparator']=(string)$value['nameseparator']; + if (!empty($value->class)) { + $opt_at[$fields_id]['class']='form-control ' .(string)$value->class; + } + $opt_at[$fields_id]['nameseparator']=(string)$value['nameseparator']; + + echo 'options)){ + foreach ($value->options ->attributes() as $optkey =>$optval){ + $opt_at[$fields_id]['options'][$optkey]=(string)$optval; + echo ' '.$optkey.'="'.$optval.'"'; + } + } + echo '> '.(string)$value['nameseparator'].' '; + $i2 ++; + + } + echo '
'; + $i++; + } + ?> + +
+
+ button).'" />'; + ?> +
+
+
+
+
+
+
+ help);?> +
+
+ label.' -->'; + + } + + if ($child['type'] == 'IS') { + $res_n = (string)$child->name; + $res_id = $npref.$child->name; + echo ''; + ?> +
+
+
+ + +
+
+ default)) { + $res_v = 'no'; + } else { + $res_v = (string)$child->default; + } + if (!empty($child->value)) { + $res_v = (string)$child->value; + } + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $res_v = (string)$fvalues[$res_n]['data']; + } + } + + foreach ($child->xpath('button') as $value) { + echo ''; + echo ''; + $i++; + } + ?> +
+
+
+ help);?> +
+
+ + label.' -->'; + + } + +/* + * Input element Select SLD - Date format + * SLZ - Time Zone + * SLT - TFTP Lang + * SLM - Music on hold + * SLK - System KeySet + */ + + if ($child['type'] == 'SLD' || $child['type'] == 'SLM'|| $child['type'] == 'SLK'|| $child['type'] == 'SLZ' || $child['type'] == 'SLZN') { +// $value = $child -> select; + $res_n = (string)$child ->name; + $res_id = $npref.$res_n; + if (empty($child->class)) { + $child->class = 'form-control'; + } + if ($child['type'] == 'SLD') { + $select_opt= $day_format; + } +// if ($child['type'] == 'SLT') { +// $select_opt= $tftp_lang; +// } + if ($child['type'] == 'SLM') { + $select_opt= $moh_list; + } + if ($child['type'] == 'SLK') { + $select_opt= $sofkey_list; + } + if ($child['type'] == 'SLZ') { + $select_opt= $time_zone; + } + if ($child['type'] == 'SLZN') { + $select_opt= $time_zone_name; + } + + echo ''; + + ?> +
+
+ +
+ + +
+
class . '" id="' . $res_id . '">'; + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $child->value = $fvalues[$res_n]['data']; + } + } + foreach ($select_opt as $key) { + echo ''; + } + ?> +
+
+
+ help);?> +
+
+ label.' -->'; + + } +/* + * Input element Select SLS - System Language + */ + + if ($child['type'] == 'SLS' || $child['type'] == 'SLT') { +// $value = $child -> select; + $res_n = (string)$child ->name; + $res_id = $npref.$res_n; + + if ($child['type'] == 'SLS') { + $select_opt= $syslangs; + } + if ($child['type'] == 'SLT') { + $select_opt= $tftp_lang; + } + + if (empty($child->class)) { + $child->class = 'form-control'; + } + + echo ''; + ?> +
+
+ +
+ + +
+
class . '" id="' . $res_id . '">'; + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $child->value = $fvalues[$res_n]['data']; + } + } + foreach ($select_opt as $key => $val) { + echo ''; + } + ?> +
+
+
+ help);?> +
+
+ + label.' -->'; + + } +/* + * Input element Select + */ + + if ($child['type'] == 'SL') { + $res_n = (string)$child->name; + $res_id = $npref.$child->name; + + if (empty($child ->class)) { + $child->class = 'form-control'; + } + echo ''; + + ?> + +
+
+ +
+ + +
+
class . '" id="' . $res_id . '">'; + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $child->value = $fvalues[$res_n]['data']; + } + } + foreach ($child->xpath('select') as $value) { + if (!empty($value[@value])) { + $key = $value[@value]; + } else { + $key = (string)$value; + } + echo ''; + } + ?> + +
+
+
+ help);?> +
+
+ + label.' -->'; + } + + /* + * Input element Select SDM - Model List + * SDE - Extension List + */ + + if ($child['type'] == 'SDM' || $child['type'] == 'SDE' ) { +// $value = $child -> select; + $res_n = (string)$child ->name; + $res_id = $npref.$res_n; + if (empty($child->class)) { + $child->class = 'form-control'; + } + if ($child['type'] == 'SDM') { + $select_opt= $model_list; + } + if ($child['type'] == 'SDE') { + $select_opt= $extension_list; + } + + echo ''; + + ?> +
+
+ +
+ + +
+
class . '" id="' . $res_id . '">'; + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $child->value = $fvalues[$res_n]['data']; + } + } + $fld = (string)$child->select['name']; + $flv = (string)$child->select; + $flk = (string)$child->select['dataid']; + $flkv= (string)$child->select['dataval']; + $key = (string)$child->default; + + foreach ($select_opt as $data) { + echo ''; + } + + ?> +
+
+
+ help);?> +
+
+ label.' -->'; + + } + +} +?> +'; + } + ?> + diff --git a/views/formShowError.php b/views/formShowError.php new file mode 100644 index 0000000..9b10fd1 --- /dev/null +++ b/views/formShowError.php @@ -0,0 +1,5 @@ +
+
+ +
+ diff --git a/views/hardware.extension.php b/views/hardware.extension.php new file mode 100644 index 0000000..1b2889b --- /dev/null +++ b/views/hardware.extension.php @@ -0,0 +1,39 @@ + +
+
+
+
+

+
+   + +
+ + + + + + + + + +
+
+
+
+
+ \ No newline at end of file diff --git a/views/hardware.phone.php b/views/hardware.phone.php new file mode 100644 index 0000000..c9ea9de --- /dev/null +++ b/views/hardware.phone.php @@ -0,0 +1,68 @@ + + +
+
+
+
+

+
+   + + + +
+ + + + + + + + + + + + + +
+
+
+
+
+ + \ No newline at end of file diff --git a/views/sccpgeneral.xml b/views/sccpgeneral.xml new file mode 100644 index 0000000..52d55d7 --- /dev/null +++ b/views/sccpgeneral.xml @@ -0,0 +1,849 @@ + + + + + + + + dev_sshUserId + cisco + + Help. + + + + dev_sshPassword + cisco + + Help. + + + + dev_deviceProtocol + SCCP + + Help. + + + + + + + + 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. + : + + + + externip + + sccp-custom + + + External IP Address of the firewall, required in case the PBX is running on a seperate 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. + + debug + none + + + + + + Debug: Enable debugging level in SCCP module. + + + + + + permit + 0.0.0.0/0.0.0.0 + + + + Local network settings. Blank fields will be ignored used Network 0.0.0.0. + + + + + deny + 0.0.0.0/0.0.0.0 + + + + All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. + + + + + localnet + 0.0.0.0/0.0.0.0 + + + + All RFC 1918 addresses are local networks, example '192.168.1.0/255.255.255.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 + Russian_Russia + + 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. + + echocancel + no + + + Echo Cancel: Echo Cancellation (On or Off). + + silencesuppression + no + + + Silence Suppression: Slience Suppression on the phone. + + private + yes + + + 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 + no + + + Directed Pickup Mode (Answer): If a call is sent with the "directed pickup" flag, the phone will answer when set to "Yes". + + 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 + no + + + Set the MWI on call. + + + + + + ntp_config_enabled + no + + + Enabling NTP settings in device configuration. + + + + ntp_server + pool.ntp.org + pool.ntp.org + + Help. + + ntp_server_mode + unicast + + + + + . + + + + + + 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 + + + + + + + + + + dev_servicesURL + + + + + + Help. + + + + dev_authenticationURL + + + + + Help. + + + + dev_idleURL + + + + + Help. + + + + dev_informationURL + + + + Help. + + + + dev_messagesURL + + + + Help. + + + + dev_directoryURL + + + + Help. + + + + dev_proxyServerURL + + + + + Help. + + + + + dev_idleTimeout + 60 + sccp-custom + number + + + Help. + + + + + + + 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. + + + + hotline_enabled + no + + + 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_context + defauly + 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. + + autoselectline_enabled + no + + + Help. + + meetme + no + + + 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 + + no + + + Help. + + backgroundImageAccess + no + + + 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. + + + + + + + tftp_path + /tftpboot + sccp-custom + + Help. + + + 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 + + + Help. + + + + + + + + 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. + + + + 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 + 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 + + + softkeyset + default + + Help. + + + 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/ directory with the rest of the config files. + + + + + + + mac + 000000000 + sccp-custom + + Help. + + + + + + transfer + no + + + Transfer allowed + + cfwdall + no + + + Activate the callforward softkeys. Default is On + + cfwdbusy + no + + + Activate the callforward busy softkeys. Default is On + + + useRedialMenu + + no + + + 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. + + + dndFeature + + on + + + Do Not Disturb. Default is Off + + + + dtmfmode + + outofband + + + Dual-Tone Multi-Frequency: outofband is the native cisco dtmf tone play + + + mwilamp + + on + + + + + + Set the MWI lamp style when MWI active to on, off, wink, flash or blink + + directed_pickup + yes + + + Enable Pickup function to direct pickup an extension. Default is On + + directed_pickup_modeanswer + yes + + + On (Default)= the call has been answered when picked up. Off = call manager way, the phone who picked up the call rings the call + + + + directed_pickup_context + + sccp-custom + + Context where direct pickup search for extensions. if not set current contect will be use. + + + + + + + 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_show_conflist + + yes + + + 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. + + + + + + + + + permit_net + 0.0.0.0 + sccp-custom + + + permit_mask + 0.0.0.0 + sccp-custom + + Local network settings. Blank fields will be ignored used Network 0.0.0.0. + / + + + + deny_net + 0.0.0.0 + sccp-custom + + + deny_mask + 0.0.0.0 + sccp-custom + + IP deny: IP Address deny netmask. Should always be at least '0.0.0.0/0.0.0.0'. + / + + + nat + + off + + + Device NAT support (default Off) + + + + directrtp + + off + + + This option allow devices to do direct RTP sessions (default Off) + + + earlyrtp + + progress + + + + + The audio strem will be open in the progress and connected state. Valid options: none, progress, offhook, dial, ringout. Default may be Progress. + + + + + + diff --git a/views/server.codec.php b/views/server.codec.php new file mode 100644 index 0000000..e40dfdb --- /dev/null +++ b/views/server.codec.php @@ -0,0 +1,116 @@ +getCodecs('audio', true); +if (!empty($_REQUEST['id'])) { + $dev_id = $_REQUEST['id']; + $db_res = $this->get_db_SccpTableData('get_sccpdevice_byid', array("id" => $dev_id)); + if (!empty($db_res['allow'])) { + $i = 1; + foreach(explode(',', $db_res['allow']) as $c){ + $codec_list[$c] = $i; + $i ++; + } + foreach ($sccp_codec as $c => $v) { + if (!isset($codec_list[$c])) { + $codec_list[$c] = false; + } + } + } +} else { + $codec_list = $sccp_codec; +} + +?> + +
+ + + + +
+

+
+
+ +
+
+
+
+
+
+ +
+
+ + '; + foreach ($codec_list as $codec => $codec_state) { + $codec_trans = _($codec); + $codec_checked = $codec_state ? 'checked' : ''; + echo '
  • ' + . 'move ' + . '' + . '  
  • \n"; + } + echo ''; + ?> +
    +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + diff --git a/views/server.datetime.php b/views/server.datetime.php new file mode 100644 index 0000000..74ce58a --- /dev/null +++ b/views/server.datetime.php @@ -0,0 +1,19 @@ + +
    + + + +ShowGroup('sccp_dev_ntp',1); + echo $this->ShowGroup('sccp_dev_time',1); + +?> +
    diff --git a/views/server.device.php b/views/server.device.php new file mode 100644 index 0000000..e163cf0 --- /dev/null +++ b/views/server.device.php @@ -0,0 +1,19 @@ + +
    + + +ShowGroup('sccp_dev_config',1); + echo $this->ShowGroup('sccp_dev_url',1); + echo $this->ShowGroup('sccp_hotline_config',1); + +?> +
    diff --git a/views/server.keyset.php b/views/server.keyset.php new file mode 100644 index 0000000..6eb4269 --- /dev/null +++ b/views/server.keyset.php @@ -0,0 +1,174 @@ +'>>', 'Right' => '>', 'AllLeft' => '<<', 'Left' => '<'); + +// ------------------------------------- Key Set Value --------------------------------------------------------- +$keysetarray = array('onhook' => array('redial','newcall','cfwdall','dnd','pickup','gpickup','private'), + 'connected' => array('hold','endcall','park','vidmode','select','cfwdall','cfwdbusy','idivert'), + 'onhold' => array('resume','newcall','endcall','transfer','conflist','select','dirtrfr','idivert','meetme'), + 'ringin' => array('answer','endcall','transvm','idivert'), + 'offhook' => array('redial','endcall','private','cfwdall','cfwdbusy','pickup','gpickup','meetme','barge'), + 'conntrans' => array('hold','endcall','transfer','conf','park','select','dirtrfr','vidmode','meetme','cfwdall','cfwdbusy'), + 'digitsfoll' => array('back','endcall','dial'), + 'connconf' => array('conflist','newcall','endcall','hold','vidmode'), + 'ringout' => array('empty','endcall','transfer','cfwdall','idivert'), + 'offhookfeat'=> array('redial','endcall'), + 'onhint' => array('redial','newcall','pickup','gpickup','barge'), + 'onstealable'=> array('redial','newcall','cfwdall','pickup','gpickup','dnd','intrcpt'), + 'holdconf' => array('resume','newcall','endcall','join'), + 'uriaction' => array('default')); + +// ------------------------------------- Key Set Display information --------------------------------------------------------- +$keynamearray = array('onhook' => array(sname => 'ONHOOK', name =>'Display Onhook',help =>'help.'), + 'connected' => array(sname => 'CONNECTED', name =>'Display Connected',help =>'help.'), + 'onhold' => array(sname => 'ONHOLD', name =>'Display onhold',help =>'help.'), + 'ringin' => array(sname => 'RINGIN', name =>'Display ringin',help =>'help.'), + 'offhook' => array(sname => 'OFFHOOK', name =>'Display offhook',help =>'help.'), + 'conntrans' => array(sname => 'CONNTRANS', name =>'Display conntrans',help =>'help.'), + 'digitsfoll' => array(sname => 'DIGITSFOLL', name =>'Display digitsfoll',help =>'help.'), + 'connconf' => array(sname => 'CONNCONF', name =>'Display connconf',help =>'help.'), + 'ringout' => array(sname => 'RINGOUT', name =>'Display ringout',help =>'help.'), + 'offhookfeat'=> array(sname => 'OFFHOOKFEAT', name =>'Display offhookfeat',help =>'help.'), + 'onhint' => array(sname => 'ONHINT', name =>'Display onhint',help =>'help.'), + 'onstealable'=> array(sname => 'onstealable', name =>'Display onstealable',help =>'help.'), + 'holdconf' => array(sname => 'HOLDCONF', name =>'Display holdconf',help =>'help.'), + 'uriaction' => array(sname => '', name =>'Display uriaction',help =>'help.') + ); +// print_r($this->sccp_list_keysets()); +// echo "

    "; +// print_r($this->sccp_conf_init); + +?> +
    + + + +
    +
    +
    +
    +
    + +
    + + + + + + $value) { + if ($i < 9 ){ + echo ''; + } + $i ++; + } +?> + + + + + + +
    '._($value['sname']).'
    +
    +
    +
    +
    +
    + + +