From c2b97fe3eeb26a58336d746a91f99d23c3a151a3 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 25 Mar 2019 15:25:51 +0300 Subject: [PATCH 001/100] Initial add of feature mobility user table: - Add extra user fields and sccp_config entries - Create new buttonconfig table --- Sccp_manager.class.php | 441 ++++++++----- Sccp_manager.inc/aminterface.class.php | 792 ++++++++++++++++++++++++ Sccp_manager.inc/dbinterface.class.php | 22 +- Sccp_manager.inc/extconfigs.class.php | 92 +-- Sccp_manager.inc/srvinterface.class.php | 319 ++-------- Sccp_manager.inc/xmlinterface.class.php | 2 +- assets/js/sccp_manager.js | 7 + conf/sccpgeneral.xml.v433 | 115 +++- contrib/rewrite.rules | 13 +- install.php | 194 +++++- uninstall.php | 17 +- views/form.addruser.php | 34 + views/form.buttons.php | 31 +- views/formShow.php | 25 +- views/hardware.extension.php | 16 +- views/server.info.php | 29 +- 16 files changed, 1639 insertions(+), 510 deletions(-) create mode 100644 Sccp_manager.inc/aminterface.class.php create mode 100644 views/form.addruser.php diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index b41fe2b..740a074 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -10,11 +10,11 @@ // http://chan-sccp-b.sourceforge.net/doc/_howto.xhtml#nf_adhoc_plar // https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cuipph/all_models/xsi/9-1-1/CUIP_BK_P82B3B16_00_phones-services-application-development-notes/CUIP_BK_P82B3B16_00_phones-services-application-development-notes_chapter_011.html // https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cuipph/7960g_7940g/sip/4_4/english/administration/guide/ver4_4/sipins44.html +// http://usecallmanager.nz/ /* !TODO!: * + Cisco Format Mac * + Model Information - * + Device Right Menu - + * + Device Right Menu @@ -38,14 +38,15 @@ * + Make Var elements from separate class * + To make creating XML files in a separate class * + Add Switch to select XML schema (display) - * - Bootstrap encodeURI(row['type']) ??????? - * - Check Time zone .... * + SRST Config + * + secondary_dialtone_digits = "" line config + * + secondary_dialtone_tone = 0x22 line config + * - deviceSecurityMode http://usecallmanager.nz//itl-file-tlv.html + * - transportLayerProtocol http://usecallmanager.nz//itl-file-tlv.html + * - Check Time zone .... * - Failover config * + Auto Addons! * + DND Mode - * + secondary_dialtone_digits = "" line config - * + secondary_dialtone_tone = 0x22 line config * - support kv-store ????? * + Shared Line * - bug Soft key set (empty keysets ) @@ -98,7 +99,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { private $hint_context = array('default' => '@ext-local'); /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Get it from Config !!! private $val_null = 'NONE'; /// REPLACE to null Field public $sccp_model_list = array(); - public $sccp_metainfo = array(); + public $sccp_metainfo = array(); private $cnf_wr = null; public $sccppath = array(); public $sccpvalues = array(); @@ -238,7 +239,8 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { // $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' || $child['type'] == 'SLA') { +// if ($child['type'] == 'SLD' || $child['type'] == 'SLS' || $child['type'] == 'SLT' || $child['type'] == 'SL' || $child['type'] == 'SLM' || $child['type'] == 'SLZ' || $child['type'] == 'SLZN' || $child['type'] == 'SLA') { + if (in_array($child['type'], array('SLD','SLS','SLT','SL','SLM','SLZ','SLZN','SLA') )) { if (empty($child->value)) { $datav = (string) $child->default; } else { @@ -366,7 +368,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $request = $_REQUEST; $action = !empty($request['action']) ? $request['action'] : ''; if ($this->sccpvalues['sccp_compatible']['data'] >= '433') { - $this->sccp_metainfo = $this->srvinterface->getеtestChanSCCP_GlablsInfo('general'); +// $this->sccp_metainfo = $this->srvinterface->getеtestChanSCCP_GlablsInfo('general'); } if (!empty($this->sccpvalues['displayconfig'])) { @@ -497,7 +499,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $action = !empty($request['action']) ? $request['action'] : ''; $inputform = !empty($request['tech_hardware']) ? $request['tech_hardware'] : ''; if ($this->sccpvalues['sccp_compatible']['data'] >= '433') { - $this->sccp_metainfo = $this->srvinterface->getеtestChanSCCP_GlablsInfo('device'); +// $this->sccp_metainfo = $this->srvinterface->getеtestChanSCCP_GlablsInfo('device'); } // print_r($inputform); @@ -521,6 +523,20 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { break; + case r_user: + $this->pagedata = array( + "general" => array( + "name" => _("Rouming User configuration"), + "page" => 'views/form.addruser.php' + ), + "buttons" => array( + "name" => _("Device Buttons"), + "page" => 'views/form.buttons.php' + ), + ); + + break; + default: $this->pagedata = array( "general" => array( @@ -587,6 +603,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { case 'backupsettings': case 'savesettings': case 'save_hardware': + case 'save_ruser': case 'save_dialplan_template': case 'delete_hardware': case 'getPhoneGrid': @@ -641,6 +658,12 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return $this->save_hw_phone($request); break; + case 'save_ruser': +// $res = $request; + $res = $this->save_rouming_users($request); + return array('status' => true, 'search' => '?display=sccp_phone', 'hash' => 'general'); + return array('status' => false, 'message' => print_r($res)); + break; /* !TODO!: -TODO-: dialplan templates should be removed (only required for very old devices (like ATA) */ // ------------------------------- Old deviece suport - In the development--- case 'save_dialplan_template': @@ -841,8 +864,23 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { case 'getExtensionGrid': $result = $this->dbinterface->get_db_SccpTableData('SccpExtension'); if (empty($result)) { - $result = array(); + return array(); } +/* $res_info = $this->aminterface->core_list_all_exten('exten'); + if (!empty($res_info)) { + foreach ($result as $key => $value) { + $tpm_info = $res_info[$value['name']]; + if (!empty($tpm_info)) { + $result[$key]['line_status'] = $tpm_info['status']; + $result[$key]['line_statustext'] = $tpm_info['statustext']; + } else { + $result[$key]['line_status'] = ''; + $result[$key]['line_statustext'] = ''; + } + } + } + * + */ return $result; break; case 'getPhoneGrid': @@ -908,7 +946,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { readfile($filename); unlink($filename); - + // return array('status' => false, 'message' => $result); // return $result; break; @@ -926,6 +964,111 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { * * Save Hardware Device Information to Db + ???? Create / update XML Profile * */ + function get_buttons_phone($get_settings, $ref_id = '', $ref_type = 'sccpdevice') { +// Get Model Buttons info + $res = array(); + + $lines_list = $this->dbinterface->get_db_SccpTableData('SccpExtension'); + $max_btn = ((!empty($get_settings['buttonscount']) ? $get_settings['buttonscount'] : 100)); + $last_btn = $max_btn; + for ($it = $max_btn; $it >= 0; $it--) { + if (!empty($get_settings['button' . $it . '_type'])) { + $last_btn = $it; + $btn_t = $get_settings['button' . $it . '_type']; + if ($btn_t != 'empty') { + break; + } + } + } + + for ($it = 0; $it <= $last_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->dbinterface->get_db_SccpTableData('SccpExtension', array('name' => $btn_opt)); + $btn_n = $db_res[0]['label']; + $btn_opt .= ',' . $btn_opt . $this->hint_context['default']; + 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['default']; + $btn_opt .= ',' . $get_settings['button' . $it . '_hline']; + } + } + } + break; + case 'adv.line': + $btn_t = 'line'; + $btn_n = (string) $get_settings['button' . $it . '_line']; + $btn_n .= '@' . (string) $get_settings['button' . $it . '_advline']; + $btn_opt = (string) $get_settings['button' . $it . '_advopt']; + + break; + case 'line': + case 'silent': + if (isset($get_settings['button' . $it . '_line'])) { + $btn_n = (string) $get_settings['button' . $it . '_line']; + if ($it > 0) { + if ($btn_t == 'silent') { + $btn_n .= '!silent'; + $btn_t = 'line'; + } + } + } else { + $btn_t = 'empty'; + $btn_n = ''; + } + break; + case 'empty': + $btn_t = 'empty'; + break; + } + if (!empty($btn_t)) { + $res[] = array('ref' => $ref_id, 'reftype' => $ref_type, 'instance' => (string) ($it + 1), 'type' => $btn_t, 'name' => $btn_n, 'options' => $btn_opt); + } + } + } + return $res; + + } function save_hw_phone($get_settings, $validateonly = false) { $hdr_prefix = 'sccp_hw_'; @@ -1043,105 +1186,8 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->dbinterface->sccp_save_db("sccpdevice", $save_settings, 'replace'); // Get Model Buttons info - $lines_list = $this->dbinterface->get_db_SccpTableData('SccpExtension'); - $max_btn = ((!empty($get_settings['buttonscount']) ? $get_settings['buttonscount'] : 100)); - $last_btn = $max_btn; - for ($it = $max_btn; $it >= 0; $it--) { - if (!empty($get_settings['button' . $it . '_type'])) { - $last_btn = $it; - $btn_t = $get_settings['button' . $it . '_type']; - if ($btn_t != 'empty') { - break; - } - } - } - - for ($it = 0; $it <= $last_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->dbinterface->get_db_SccpTableData('SccpExtension', array('name' => $btn_opt)); - $btn_n = $db_res[0]['label']; - $btn_opt .= ',' . $btn_opt . $this->hint_context['default']; - 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['default']; - $btn_opt .= ',' . $get_settings['button' . $it . '_hline']; - } - } - } - break; - case 'adv.line': - $btn_t = 'line'; - $btn_n = (string) $get_settings['button' . $it . '_line']; - $btn_n .= '@' . (string) $get_settings['button' . $it . '_advline']; - $btn_opt = (string) $get_settings['button' . $it . '_advopt']; - - break; - case 'line': - case 'silent': - if (isset($get_settings['button' . $it . '_line'])) { - $btn_n = (string) $get_settings['button' . $it . '_line']; - if ($it > 0) { - if ($btn_t == 'silent') { - $btn_n .= '!silent'; - $btn_t = 'line'; - } - } - } else { - $btn_t = 'empty'; - $btn_n = ''; - } - break; - case 'empty': - $btn_t = 'empty'; - break; - } - if (!empty($btn_t)) { - $save_buttons[] = array('device' => $name_dev, 'instance' => (string) ($it + 1), 'type' => $btn_t, 'name' => $btn_n, 'options' => $btn_opt); - } - } - } - + $save_buttons = $this-> get_buttons_phone($get_settings,$name_dev, 'sccpdevice'); + // Sace Buttons config $this->dbinterface->sccp_save_db("sccpbuttons", $save_buttons, $update_hw, '', $name_dev); @@ -1247,6 +1293,111 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return $save_settings; } + + + function save_rouming_users($get_settings, $validateonly = false) { + $hdr_prefix = 'sccp_ru_'; + $hdr_arprefix = 'sccp_ru-ar_'; + + $save_buttons = array(); + $save_settings = array(); +/* + $def_feature = array('parkinglot' => array('name' => 'P.slot', 'value' => 'default'), + 'devstate' => array('name' => 'Coffee', 'value' => 'coffee'), + 'monitor' => array('name' => 'Record Calls', 'value' => '') + ); + * + */ + $name_dev = ''; + $db_field = $this->dbinterface->get_db_SccpTableData("get_colums_sccpusers"); +// $hw_id = (empty($get_settings['sccp_deviceid'])) ? 'new' : $get_settings['sccp_deviceid']; +// $update_hw = ($hw_id == 'new') ? 'update' : 'clear'; + $hw_prefix = 'SEP'; + $name_dev = $get_settings[$hdr_prefix . 'id']; + + foreach ($db_field as $data) { + $key = (string) $data['Field']; + $value = ""; + switch ($key) { + case 'name': + $value = $name_dev; + 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($get_settings[$hdr_arprefix . $key])) { + $arr_data = ''; + $arr_clear = FALSE; + foreach ($get_settings[$hdr_arprefix . $key] as $vkey => $vval) { + $tmp_data = ''; + foreach ($vval as $vkey => $vval) { + switch ($vkey) { + case 'inherit': + if ($vval == 'on') { + $arr_clear = TRUE; + // Злобный ХАК + if ($key == 'permit') { + $save_settings['deny'] = 'NONE'; + } + } + break; + case 'internal': + if ($vval == 'on') { + $tmp_data .= 'internal;'; + } + break; + default: + $tmp_data .= $vval . '/'; + break; + } + } + if (strlen($tmp_data) > 2) { + while (substr($tmp_data, -1) == '/') { + $tmp_data = substr($tmp_data, 0, -1); + } + $arr_data .= $tmp_data . ';'; + } + } + while (substr($arr_data, -1) == ';') { + $arr_data = substr($arr_data, 0, -1); + } + if ($arr_clear) { + $value = 'NONE'; + } else { + $value = $arr_data; + } + } + } + if (!empty($value)) { + $save_settings[$key] = $value; + } + } +// Save / Updade Base +// return $save_settings; + // $update_hw = ($hw_id == 'new') ? 'update' : 'clear'; + + $this->dbinterface->sccp_save_db("sccpusers", $save_settings, 'replace', 'name'); + + $save_buttons = $this-> get_buttons_phone($get_settings,$name_dev, 'sccpline'); +// Sace Buttons config + $this->dbinterface->sccp_save_db("sccpbuttons", $save_buttons,'clear', '', $name_dev); + return $save_buttons; + + return $save_settings; + } + + + + + public function getSccpSettingFromDB() { $raw_data = $this->dbinterface->get_db_SccpSetting(); foreach ($raw_data as $var) { @@ -1755,11 +1906,11 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $backup_files = array($amp_conf['ASTETCDIR'] . '/sccp', $amp_conf['ASTETCDIR'] . '/extensions', $amp_conf['ASTETCDIR'] . '/extconfig', $amp_conf['ASTETCDIR'] . '/res_config_mysql', $amp_conf['ASTETCDIR'] . '/res_mysql'); $backup_ext = array('.conf', '_additional.conf', '_custom.conf'); - $backup_info = $this->sccppath["tftp_path"].'/sccp_dir.info'; + $backup_info = $this->sccppath["tftp_path"] . '/sccp_dir.info'; $result = $this->dbinterface->dump_sccp_tables($this->sccppath["tftp_path"], $amp_conf['AMPDBNAME'], $amp_conf['AMPDBUSER'], $amp_conf['AMPDBPASS']); - $dir_info['asterisk'] = $this->find_all_files($amp_conf['ASTETCDIR']); - $dir_info['tftpdir'] = $this-> find_all_files($this->sccppath["tftp_path"]); + $dir_info['asterisk'] = $this->find_all_files($amp_conf['ASTETCDIR']); + $dir_info['tftpdir'] = $this->find_all_files($this->sccppath["tftp_path"]); $dir_info['driver'] = $this->FreePBX->Core->getAllDriversInfo(); $dir_info['core'] = $this->srvinterface->getSCCPVersion(); $dir_info['realtime'] = $this->srvinterface->sccp_realtime_status(); @@ -1768,23 +1919,23 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $dir_info['dbinterface'] = $this->dbinterface->info(); $dir_info['XML'] = $this->xmlinterface->info(); - + $fh = fopen($backup_info, 'w'); $dir_str = "Begin JSON data ------------\r\n"; - fwrite($fh,$dir_str); - fwrite($fh,json_encode($dir_info)); + fwrite($fh, $dir_str); + fwrite($fh, json_encode($dir_info)); $dir_str = "\r\n\r\nBegin TEXT data ------------\r\n"; foreach ($dir_info['asterisk'] as $data) { - $dir_str .= $data."\r\n"; + $dir_str .= $data . "\r\n"; } foreach ($dir_info['tftpdir'] as $data) { - $dir_str .= $data."\r\n"; + $dir_str .= $data . "\r\n"; } fputs($fh, $dir_str); fclose($fh); - + $zip = new \ZipArchive(); - $filename = $result .".". gethostname().".zip"; + $filename = $result . "." . gethostname() . ".zip"; if ($zip->open($filename, \ZIPARCHIVE::CREATE)) { $zip->addFile($result); $zip->addFile($backup_info); @@ -1920,34 +2071,51 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return $raw_settings; } - function get_hint_info($get = "all", $format_list = "all", $filter = array()) { + function get_hint_info($sort = true, $filter = array()) { $res = array(); $default_hint = '@ext-local'; -// get all hints [101@ext-local] => 101@ext-local - $tmp_data = $this->srvinterface->sccp_list_all_hints(); - foreach ($tmp_data as $value) { - /* !TODO!: Add Hint Filtred List */ - $res[$value] = array('hint' => $value, 'name' => before('@', $value), 'label' => $value); + +// get all extension + $res = $this->aminterface->core_list_all_exten('hint', $filter); + if (empty($res)) { +// Old Req get all hints + $tmp_data = $this->srvinterface->sccp_list_all_hints(); + foreach ($tmp_data as $value) { + $res[$value] = array('key' => $value, 'exten' => before('@', $value), 'label' => $value); + } } + // Update info from sccp_db $tmp_data = $this->dbinterface->get_db_SccpTableData('SccpExtension'); foreach ($tmp_data as $value) { $name_l = $value['name']; if (!empty($res[$name_l . $default_hint])) { - $res[$name_l . $default_hint]['name'] = $name_l; + $res[$name_l . $default_hint]['exten'] = $name_l; $res[$name_l . $default_hint]['label'] = $value['label']; } else { // if not exist in system hints ..... ??????? - $res[$name_l . $default_hint] = array('hint' => $name_l . $default_hint, 'name' => $name_l, 'label' => $value['label']); + $res[$name_l . $default_hint] = array('key' => $name_l . $default_hint, 'exten' => $name_l, 'label' => $value['label']); } } + if (!$sort) { + return $res; + } + + foreach ($res as $key => $value) { + $data_sort[$value['exten']] = $key; + } + ksort($data_sort); + foreach ($data_sort as $key => $value) { + $res_sort[$value] = $res[$value]; + } + // Update info from sip DB /* !TODO!: Update Hint info from sip DB ??? */ - return $res; + return $res_sort; } function getIP_information2($type = '') { - $interfaces= array(); + $interfaces = array(); switch ($type) { case 'ip4': exec("/sbin/ip -4 -o addr", $result, $ret); @@ -1966,18 +2134,16 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { continue; if ($vals[2] != "inet" && $vals[2] != "inet6") continue; - if (preg_match("/(.+?)(?:@.+)?:$/", $vals[1], $res)) { + if (preg_match("/(.+?)(?:@.+)?:$/", $vals[1], $res)) { continue; } - $ret = preg_match("/(\d*+.\d*+.\d*+.\d*+)[\/(\d*+)]*/", $vals[3], $ip); - - $interfaces[$vals[1].':'.$vals[2]] = Array('name' => $vals[1],'type' => $vals[2], 'ip' => ((empty($ip[1]) ? '' : $ip[1]))); + $ret = preg_match("/(\d*+.\d*+.\d*+.\d*+)[\/(\d*+)]*/", $vals[3], $ip); + + $interfaces[$vals[1] . ':' . $vals[2]] = Array('name' => $vals[1], 'type' => $vals[2], 'ip' => ((empty($ip[1]) ? '' : $ip[1]))); } return $interfaces; } - - function getIP_information_old() { $interfaces['auto'] = array('0.0.0.0', 'All', '0'); @@ -2105,5 +2271,4 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } return $result; } - } diff --git a/Sccp_manager.inc/aminterface.class.php b/Sccp_manager.inc/aminterface.class.php new file mode 100644 index 0000000..f2e9f5a --- /dev/null +++ b/Sccp_manager.inc/aminterface.class.php @@ -0,0 +1,792 @@ +_responseHandler) > 0) { + //throw new PAMIException('Hier:' . $this->_responseHandler); + return (string) $this->_responseHandler; + } else { + return ""; + } + } + + public function setResponseHandler($responseHandler) { + if (0 == strlen($responseHandler)) { + return ; + } + $className = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\Message\\Response\\' . $responseHandler . 'Response'; + if (class_exists($className, true)) { + $this->_responseHandler = $responseHandler; + } else { + return ; + } + } + + public function setVariable($key, $value) { + $key = strtolower($key); + $this->variables[$key] = $value; + } + + public function getVariable($key) { + $key = strtolower($key); + if (!isset($this->variables[$key])) { + return null; + } + return $this->variables[$key]; + } + + protected function setKey($key, $value) { + $key = strtolower((string) $key); + $this->keys[$key] = (string) $value; + } + + public function getKey($key) { + $key = strtolower($key); + if (!isset($this->keys[$key])) { + return null; + } + //return (string)$this->keys[$key]; + return $this->keys[$key]; + } + + public function getVariables() { + return $this->variables; + } + + public function getActionID() { + return $this->getKey('ActionID'); + } + + public function getKeys() { + return $this->keys; + } + + private function serializeVariable($key, $value) { + return "Variable: $key=$value"; + } + + protected function finishMessage($message) { + return $message . self::EOL . self::EOL; + } + + public function serialize() { + $result = array(); + foreach ($this->getKeys() as $k => $v) { + $result[] = $k . ': ' . $v; + } + foreach ($this->getVariables() as $k => $v) { + if (is_array($v)) { + foreach ($v as $singleValue) { + $result[] = $this->serializeVariable($k, $singleValue); + } + } else { + $result[] = $this->serializeVariable($k, $v); + } + } + $mStr = $this->finishMessage(implode(self::EOL, $result)); + return $mStr; + } + + public function setActionID($actionID) { + if (0 == strlen($actionID)) { +// throw new PAMIException('ActionID cannot be empty.'); + return; + } + + if (strlen($actionID) > 69) { +// throw new PAMIException('ActionID can be at most 69 characters long.'); + return; + } + + $this->setKey('ActionID', $actionID); + } + + public function __construct() { + $this->lines = array(); + $this->variables = array(); + $this->keys = array(); + $this->createdDate = time(); + } + +} + +namespace FreePBX\modules\Sccp_manager\aminterface\Message; + +abstract class Response { + + protected $_events; + protected $_completed; + protected $keys; + + public function isSuccess() { + return stristr($this->getKey('Response'), 'Error') === false; + } + + public function isComplete() { + return $this->_completed; + } + + public function isList() { + return + stristr($this->getKey('EventList'), 'start') !== false || stristr($this->getMessage(), 'follow') !== false + ; + } + + public function setActionId($actionId) { + $this->setKey('ActionId', $actionId); + } + + public function getMessage() { + return $this->getKey('Message'); + } + + public function __construct($rawContent) { + parent::__construct($rawContent); + + $this->_events = array(); + $this->_eventsCount = 0; + $this->_completed = !$this->isList(); + } + +} + +//namespace FreePBX\modules\Sccp_manager\aminterface\Message; + +class LoginAction extends \FreePBX\modules\Sccp_manager\aminterface\Message { + + /** + * Constructor. + * + * @param string $user AMI username. + * @param string $password AMI password. + * + * @return void + */ + public function __construct($user, $password) { + parent::__construct('Login'); + $this->setKey('Action', $what); + $this->setKey('ActionID', microtime(true)); + $this->setKey('Username', $user); + $this->setKey('Secret', $password); + } + +} + +namespace FreePBX\modules\Sccp_manager; + +class aminterface { + + var $_socket; + var $_error; + var $_config; +// var $ProcessingMessage; + private $_lastActionClass; + private $_lastActionId; + private $_lastRequestedResponseHandler; + private $_ProcessingMessage; + private $_responseFactory; + + public function __construct($parent_class = null) { + global $amp_conf; + $this->paren_class = $parent_class; + $this->_socket = false; + $this->_error = array(); + $this->_config = array('host' => 'localhost', 'user' => '', 'pass' => '', 'port' => '5038', 'tsoket' => 'tcp://', 'timeout' => 30, 'enabled' => false); + $fld_conf = array('user' => 'AMPMGRUSER', 'pass' => 'AMPMGRPASS'); + if (isset($amp_conf['AMPMGRUSER'])) { + foreach ($fld_conf as $key => $value) { + if (isset($amp_conf[$value])) { + $this->_config[$key] = $amp_conf[$value]; + } + } + } + } + + public function info() { + $Ver = '13.0.4'; + if ($this->_config['enabled']) { + return Array('Version' => $Ver, + 'about' => 'AMI data ver: ' . $Ver); + } else { + return Array('Version' => $Ver, + 'about' => 'Disabled AMI ver: ' . $Ver); + } + } + + /** + * Opens a tcp connection to ami. + * + */ + public function open() { + $cString = $this->_config['tsoket'] . $this->_config['host'] . ':' . $this->_config['port']; + $this->_context = stream_context_create(); + $errno = 0; + $errstr = ''; + $this->_socket = @stream_socket_client( + $cString, $errno, $errstr, + $this->_config['timeout'], STREAM_CLIENT_CONNECT, $this->_context + ); + if ($this->_socket === false) { + $this->_errorException('Error connecting to ami: ' . $errstr . $cString); + return false; + } +// FreePBX\modules\Sccp_manager\aminterface\Message\LoginAction:: + $msg = new aminerface\Message\LoginAction($this->_config['user'], $this->_config['pass']); + + $response = $this->send($msg); + return $response; + /* + $params = array('Action' => 'Login', 'UserName' => $this->_config['user'], 'Secret' => $this->_config['pass'], 'Events' => 'on'); + $id = @stream_get_line($this->_socket, 1024, aminterface\Message::EOL); + + if (strstr($id, 'Asterisk') === false) { + $this->_errorException('Unknown peer. Is this an ami?: ' . $id); + return false; + } + $response = $this->send($params); + if (!$response->isSuccess()) { + $this->_errorException('Could not connect: ' . $response->getMessage()); + return false; + } + @stream_set_blocking($this->_socket, 0); + $this->_ProcessingMessage = ''; + //register_tick_function(array($this, 'process')); + * + */ + } + + /** + * Closes the connection to ami. + */ + public function close() { + @stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR); + } + + public function send($message) { + $messageToSend = $message->serialize(); + /* foreach ($params as $key => $value) { + $messageToSend .= $key . ': ' . $value . aminterface\Message::EOL; + } + $messageToSend .= aminterface\Message::EOL; + * + */ + $length = strlen($messageToSend); + + $this->_lastActionId = $message->getActionId(); + $this->_lastRequestedResponseHandler = $message->getResponseHandler(); + $this->_lastActionClass = $message; + + if (@fwrite($this->_socket, $messageToSend) < $length) { + $this->_errorException('Could not send message'); + return false; + } + while (1) { + stream_set_timeout($this->_socket, 1); +// stream_set_timeout($this->_socket, (isset($this->socket_param['timeout']) ? $this->socket_param['timeout'] : 1)); + $this->process(); + $info = stream_get_meta_data($this->_socket); + if ($info['timed_out'] == false) { + $response = $this->getRelated($message); + if ($response != false) { + $this->_lastActionId = false; + return $response; + } + } else { + break; + } + } + $this->_errorException("Read waittime: " . ($this->socket_param['timeout']) . " exceeded (timeout).\n"); + return false; + } + + protected function getRelated($message) { + $ret = false; + $id = 0; +// $id = $message->getActionID('ActionID'); + if (isset($this->_incomingQueue[$id])) { + $response = $this->_incomingQueue[$id]; + if ($response->isComplete()) { + unset($this->_incomingQueue[$id]); + $ret = $response; + } + } + return $ret; + } + + protected function getMessages() { + $msgs = array(); + // Read something. + $read = @fread($this->_socket, 65535); + if ($read === false || @feof($this->_socket)) { + $this->_errorException('Error reading'); + } + $this->_ProcessingMessage .= $read; + // If we have a complete message, then return it. Save the rest for + // later. + return $msgs; + while (($marker = strpos($this->_ProcessingMessage, Message::EOM))) { + $msg = substr($this->_ProcessingMessage, 0, $marker); + $this->_ProcessingMessage = substr( + $this->_ProcessingMessage, $marker + strlen(Message::EOM) + ); + $msgs[] = $msg; + } + return $msgs; + } + + public function process() { + $msgs = $this->getMessages(); + foreach ($msgs as $aMsg) { + $resPos = strpos($aMsg, 'Response:'); + $evePos = strpos($aMsg, 'Event:'); + if (($resPos !== false) && (($resPos < $evePos) || $evePos === false)) { + $response = $this->_msgToResponse($aMsg); + $this->_incomingQueue[$this->_lastActionId] = $response; + } else if ($evePos !== false) { + /* $event = $this->_messageToEvent($aMsg); + $response = $this->findResponse($event); + if ($response === false || $response->isComplete()) { + $this->dispatch($event); + } else { + $response->addEvent($event); + } + * + */ + } else { + // broken ami.. sending a response with events without + // Event and ActionId + $bMsg = 'Event: ResponseEvent' . "\r\n"; + $bMsg .= 'ActionId: ' . $this->_lastActionId . "\r\n" . $aMsg; + $event = $this->_messageToEvent($bMsg); + $response = $this->findResponse($event); + $response->addEvent($event); + } + } + } + + private function _msgToResponse($msg) { + $response = $this->_msgFromRaw($msg, $this->_lastActionClass, $this->_lastRequestedResponseHandler); + /* $actionId = $response->getActionId(); + if ($actionId === null) { + $actionId = $this->_lastActionId; + $response->setActionId($this->_lastActionId); + } + * + */ + return $response; + } + + public function _msgFromRaw($message, $requestingaction = false, $responseHandler = false) { + + $_className = false; + if ($responseHandler != false) { + $_className = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\Response'; +// $_className = '\\FreePBX\\modules\\Sccp_manager\\aminterface\\' . $responseHandler . 'Response'; + } else if ($requestingaction != false) { + switch ($requestingaction) { + case 'login': + + break; + + default: + break; + } +// $_className = '\\FreePBX\\modules\\Sccp_manager\\Response\\' . substr(get_class($requestingaction), 20, -6) . 'Response'; + $_className = '\\FreePBX\\modules\\Sccp_manager\\Response'; + } + if ($_className) { + if (class_exists($_className, true)) { + $responseclass = $_className; + } else if ($responseHandler != false) { + $this->_errorException('Response Class ' . $_className . ' requested via responseHandler, could not be found'); + } + } +// return new $responseclass($message); + } + + protected function _errorException($msg) { + $this->_error[] = $msg; + } + + /* + * Replace or dublicate to AMI interface + */ + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- + function core_list_all_exten($keyfld = '', $filter = array()) { + $result = array(); + return $result; + } + + /* + public function sccp_list_extnint() { + $hint_key = array(); + $hint_all = $this->sccp_list_all_hints(); + foreach ($hint_all as $value) { + $res = $this->loc_after('@', $value); + // array_search($res, $hint_key)) != NULL) + if (!isset($hint_key[$res])) { + $hint_key[$res] = '@' . $res; + } + } + return $hint_key; + } + + private function astman_retrieveJSFromMetaData($segment = "") { + global $astman; + $params = array(); + if ($segment != "") { + $params["Segment"] = $segment; + } + $response = $astman->send_request('SCCPConfigMetaData', $params); + if ($response["Response"] == "Success") { + //outn(_("JSON-content:").$response["JSON"]); + $decode = json_decode($response["JSON"], true); + return $decode; + } else { + return false; + } + } + + function getеtestChanSCC() { + global $astman; + // $action = Array('SCCPShowGlobals',); + $params = array(); + $action = 'SCCPShowSoftkeySets'; + // $params = array('Segment' => 'device', 'ResultFormat'=>'command' ); + // $params = array('Segment' => 'device'); + // $params = array(); + $metadata = $astman->send_request($action, $params); + return $metadata; + } + + + function core_list_all_exten($keyfld = '', $filter = array()) { + $result = array(); + $fld_data = array('exten', 'context', 'statustext', 'status'); + $row_data = $this->astman_GetRaw('ExtensionStateList'); + if (empty($row_data) || empty($row_data['eventlist'])) { + return $result; + } + if ($row_data['eventlist'] == 'Complete') { + foreach ($row_data['list'] as $value) { + $exten = $value['exten']; + $context = $value['context']; + $exclude = empty($exten); + switch ($keyfld) { + case 'exten': + $store_key = $exten; + break; + case 'hint': + default: + $store_key = $exten . '@' . $context; + break; + } + + if (!empty($filter)) { + foreach ($filter as $fkey => $fvalue) { + if (!empty($value[$fkey])) { + if (strpos(';' . $fvalue . ';', ';' . $value[$fkey] . ';') !== false) { + $exclude = true; + } + } + } + } + if (!$exclude) { + foreach ($fld_data as $key) { + $result[$store_key][$key] = (empty($value[$key]) ? '' : $value[$key] ); + } + $result[$store_key]['key'] = $exten . '@' . $context; + $result[$store_key]['label'] = $exten . '@' . $context; + } + } + } + return $result; + } + + private function astLogin($host = "", $username = "", $password = "") { + if ($this->Sok_param['enabled'] != true) { + return FALSE; + } + + if (empty($host) || empty($username) || empty($password)) { + if (empty($this->Sok_param['host']) || empty($this->Sok_param['user']) || empty($this->Sok_param['pass'])) { + return FALSE; + } + $host = (empty($host) ? $this->Sok_param['host'] : $host); + $username = (empty($username) ? $this->Sok_param['user'] : $username); + $password = (empty($password) ? $this->Sok_param['pass'] : $password); + } + $this->socket = @fsockopen($host, "5038", $errno, $errstr, 1); + + if (!$this->socket) { + $this->error = "Could not connect - $errstr ($errno)"; + return FALSE; + } else { + stream_set_timeout($this->socket, 1); + + // $wrets = $this->astQuery("Action: Login\r\nUserName: $username\r\nSecret: $password\r\nEvents: off\r\n\r\n"); + $wrets = $this->astQuery("Action: Login\r\nUserName: $username\r\nSecret: $password\r\nEvents: on\r\n\r\n"); + + if (strpos($wrets['raw'], "Message: Authentication accepted") != FALSE) { + return TRUE; + } else { + $this->error = "Could not login - Authentication failed "; + fclose($this->socket); + $this->socket = FALSE; + return FALSE; + } + } + } + + private function astLogout() { + if ($this->socket) { + fputs($this->socket, "Action: Logoff\r\n\r\n"); + while (!feof($this->socket)) { + $wrets .= fread($this->socket, 8192); + } + fclose($this->socket); + $this->socket = "FALSE"; + } + return; + } + + private function astQuery($query, $rawdata = false) { + $wrets = ""; + // return $this->socket; + if ($this->socket === FALSE) { + return FALSE; + } + $time_Query = microtime(true); + $parameters = array(); + $parameters['raw'] = ''; + $data_store = 'data'; + $parameters[$data_store] = ''; + fputs($this->socket, $query); + $parameters['raw_q'] = $query; + $stop_data = false; + $row_list = false; + $row_list_arr = Array(); + $stop_data = false; + $row_list = !$rawdata; + do { + $line = fgets($this->socket, 4096); + $parameters['raw'] .= $line; + if (!$rawdata) { + // if (true) { + $a = strpos($line, ':'); + if ($a) { + $key = trim(strtolower(substr($line, 0, $a))); + switch ($key) { + case 'eventlist': + if (strpos($line, 'start') !== false) { + $row_list = true; + } else { + $row_list = false; + } + case 'response': + case 'message': + $parameters[$key] = trim(substr($line, $a + 2)); + if (!empty($parameters['response']) && !empty($parameters['message'])) { + if ($parameters['response'] == 'Error') { + $stop_data = true; + } + } + break; + case 'json': + $parameters[$key] = substr($line, $a + 2); + $data_store = $key; + break; + default: + if ($row_list) { + $row_list_arr[$key] = trim(str_replace("\r\n", "", substr($line, $a + 2))); + ; + } + $parameters[$data_store] .= $line; + break; + } + // store parameter in $parameters + } else { + if (!isset($parameters[$data_store])) { + $parameters[$data_store] = ''; + } + $parameters[$data_store] .= $line; + } + } + if ($line == "\r\n") { + if ($row_list == false) { + $stop_data = true; + } else { + $parameters['list'][] = $row_list_arr; + $row_list_arr = array(); + } + } + $info = stream_get_meta_data($this->socket); + } while ($stop_data == false && $info['timed_out'] == false); + + $parameters['time_Query'] = microtime(true) - $time_Query; + $this->Sok_param['total'] = $this->Sok_param['total'] + $parameters['time_Query']; + // $this->astLogout(); + return $parameters; + } + + function GetError() { + return $this->error; + } + + function astman_GetRaw($action = "", $parameters = array()) { + $option = ""; + $result = array(); + + if ($this->_socket === FALSE) { + if (!$this->astLogin()) { + $result["Response"] = "Faild"; + $result["Error"] = $this->error; + return $result; + } + } + + $query = "Action: $action\r\n"; + + foreach ($parameters as $var => $val) { + if (is_array($val)) { + foreach ($val as $k => $v) { + $query .= "$var: $k=$v\r\n"; + } + } else { + $query .= "$var: $val\r\n"; + } + } + $result = $this->astQuery($query . "\r\n", true); + $result = $this->astQuery($query . "\r\n", false); + return $result; + } + + /* + private function astman_retrieveMeta($action = "", $parameters=array(), $rawdata = false) { + // $parameters=array() + global $amp_conf; + + if (empty($action)) { + $action = 'SCCPConfigMetaData'; + } + $query = "Action: $action\r\n"; + + foreach($parameters as $var=>$val) { + if (is_array($val)) { + foreach($val as $k => $v) { + $query .= "$var: $k=$v\r\n"; + } + } else { + $query .= "$var: $val\r\n"; + } + } + + $result = $this->astQuery($query."\r\n",$rawdata); + + if ($result["Response"] == "Success") { + if ($rawdata) { + return $result; + } else { + if (!empty($result["JSON"])) { + $decode = json_decode($response["JSON"], true); + return $decode; + } else { + return $result; + } + } + } else { + return $result; + return array(); + } + } + */ + + function t_get_meta_data() { + global $amp_conf; + $fp = fsockopen("127.0.0.1", "5038", $errno, $errstr, 10); + + if (!$fp) { + echo "$errstr ($errno)
\n"; + } else { + fputs($fp, "Action: login\r\n"); + fputs($fp, "Username: " . $amp_conf[AMPMGRUSER] . "\r\n"); +// fputs ($fp,"Secret: secret\r\n"); + fputs($fp, "Secret: " . $amp_conf[AMPMGRPASS] . "\r\n"); + fputs($fp, "Events: on\r\n\r\n"); + +// fputs ($fp,"Action: SCCPShowDevices\r\n"); +// fputs ($fp,"Action: DeviceStateList\r\n"); + fputs($fp, "Action: ExtensionStateList\r\n"); + fputs($fp, "Action: Status\r\n"); + +// fputs ($fp,"Segment: general\r\n"); +// "Segments":["general","device","line","softkey"]} +// fputs ($fp,"Segment: device\r\n"); +// fputs ($fp,"ResultFormat: command\r\n"); + fputs($fp, "\r\n"); + + /* + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"\r\n"); + + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: general\r\n"); + fputs ($fp,"\r\n"); + + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: general\r\n"); + fputs ($fp,"ListResult: yes\r\n"); + fputs ($fp,"Option: fallback\r\n"); + fputs ($fp,"\r\n"); + + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: device\r\n"); + fputs ($fp,"ListResult: freepbx\r\n"); + fputs ($fp,"\r\n"); + + fputs ($fp,"Action: SCCPConfigMetaData\r\n"); + fputs ($fp,"Segment: device\r\n"); + fputs ($fp,"Option: dtmfmode\r\n"); + fputs ($fp,"ListResult: yes\r\n"); + fputs ($fp,"\r\n"); + */ + + fputs($fp, "Action: logoff\r\n\r\n"); +// print_r(fgets($fp)); + $resp = ''; + while (!feof($fp)) { + $resp .= fgets($fp); + } +// print_r(fgets($fp)); +// print_r('
'); +// echo fgets($fp, 128); + } + fclose($fp); + return $resp; + } + +} diff --git a/Sccp_manager.inc/dbinterface.class.php b/Sccp_manager.inc/dbinterface.class.php index ce2eb80..9cdcb0b 100644 --- a/Sccp_manager.inc/dbinterface.class.php +++ b/Sccp_manager.inc/dbinterface.class.php @@ -43,7 +43,7 @@ class dbinterface { break; case "SccpDevice": // $sql = "SELECT * FROM `sccpdeviceconfig` ORDER BY `name`"; - $sql = "select `name`,`name` as `mac`, `type`, `button`, `addon` from `sccpdeviceconfig` ORDER BY `name`"; + $sql = "select `name`,`name` as `mac`, `type`, `button`, `addon`, `_description` as description from `sccpdeviceconfig` ORDER BY `name`"; $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); break; case "HWDevice": @@ -56,6 +56,10 @@ class dbinterface { $sql = "DESCRIBE sccpdevice"; $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); break; + case "get_colums_sccpusers": + $sql = "DESCRIBE sccpusers"; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + break; case "get_sccpdevice_byid": $sql = 'SELECT t1.*, types.dns, types.buttons, types.loadimage, types.nametemplate as nametemplate, ' . 'addon.buttons as addon_buttons FROM sccpdevice AS t1 ' @@ -63,8 +67,16 @@ class dbinterface { . '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_sccpdusers": + $sql = "SELECT * FROM `sccpusers` "; + if (!empty($data['id'])) { + $sql .= 'WHERE name="' . $data['id'] . '" '; + } + $sql .= "ORDER BY `name`;"; + $raw_settings = sql($sql, "getRow", DB_FETCHMODE_ASSOC); + break; case "get_sccpdevice_buttons": - $sql = 'SELECT * FROM buttonconfig WHERE device="' . $data['id'] . '";'; + $sql = 'SELECT * FROM sccpbuttonconfig WHERE ref="' . $data['id'] . '" ORDER BY `instance`;'; $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); break; } @@ -161,6 +173,7 @@ class dbinterface { break; case 'sccpdevmodel': case 'sccpdevice': + case 'sccpusers': $sql_db = $db_name; $sql_key = ""; $sql_var = ""; @@ -193,7 +206,7 @@ class dbinterface { break; case 'sccpbuttons': if (($mode == 'clear') || ($mode == 'delete')) { - $sql = 'DELETE FROM `buttonconfig` WHERE device="' . $hwid . '";'; + $sql = 'DELETE FROM `sccpbuttonconfig` WHERE ref="' . $hwid . '";'; $stmt = $db->prepare($sql); $stmt->execute(); } @@ -201,7 +214,8 @@ class dbinterface { break; } if (!empty($save_value)) { - $sql = 'INSERT INTO `buttonconfig` (`device`, `instance`, `type`, `name`, `options`) VALUES (?,?,?,?,?);'; + $sql = 'INSERT INTO `sccpbuttonconfig` (`ref`, `reftype`,`instance`, `buttontype`, `name`, `options`) VALUES (?,?,?,?,?,?);'; +// die(print_r($save_value,1)); $stmt = $db->prepare($sql); $res = $db->executeMultiple($stmt, $save_value); } diff --git a/Sccp_manager.inc/extconfigs.class.php b/Sccp_manager.inc/extconfigs.class.php index e3dd9c0..3432c3b 100644 --- a/Sccp_manager.inc/extconfigs.class.php +++ b/Sccp_manager.inc/extconfigs.class.php @@ -100,45 +100,45 @@ class extconfigs { 'holdconf' => 'resume,newcall,endcall,join', 'uriaction' => 'default'); // Cisco Language Code / Directory - - private $cisco_language = array('ar_SA' => array('code' => 'ar', 'language' => 'Arabic', 'locale' => 'Arabic_Saudi_Arabia'), - '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') +// + private $cisco_language = array('ar_SA' => array('code' => 'ar', 'language' => 'Arabic', 'locale' => 'Arabic_Saudi_Arabia', 'codepage' => 'ISO8859-1'), + 'bg_BG' => array('code' => 'bg', 'language' => 'Bulgarian', 'locale' => 'Bulgarian_Bulgaria', 'codepage' => 'ISO8859-1'), + 'cz_CZ' => array('code' => 'cz', 'language' => 'Czech', 'locale' => 'Czech_Czech_Republic', 'codepage' => 'ISO8859-1'), + 'da_DK' => array('code' => 'da', 'language' => 'Danish', 'locale' => 'Danish_Denmark', 'codepage' => 'ISO8859-1'), + 'de_DE' => array('code' => 'de', 'language' => 'German', 'locale' => 'German_Germany', 'codepage' => 'ISO8859-1'), + 'el_GR' => array('code' => 'el', 'language' => 'Greek', 'locale' => 'Greek_Greece', 'codepage' => 'ISO8859-1'), + 'en_AU' => array('code' => 'en', 'language' => 'English', 'locale' => 'AU_English_United_States', 'codepage' => 'ISO8859-1'), + 'en_GB' => array('code' => 'en', 'language' => 'English', 'locale' => 'English_United_Kingdom', 'codepage' => 'ISO8859-1'), + 'en_US' => array('code' => 'en', 'language' => 'English', 'locale' => 'English_United_States', 'codepage' => 'ISO8859-1'), + 'es_ES' => array('code' => 'es', 'language' => 'Spanish', 'locale' => 'Spanish_Spain', 'codepage' => 'ISO8859-1'), + 'et_EE' => array('code' => 'et', 'language' => 'Estonian', 'locale' => 'Estonian_Estonia', 'codepage' => 'ISO8859-1'), + 'fi_FI' => array('code' => 'fi', 'language' => 'Finnish', 'locale' => 'Finnish_Finland', 'codepage' => 'ISO8859-1'), + 'fr_CA' => array('code' => 'fr', 'language' => 'French', 'locale' => 'French_Canada', 'codepage' => 'ISO8859-1'), + 'fr_FR' => array('code' => 'fr', 'language' => 'French', 'locale' => 'French_France', 'codepage' => 'ISO8859-1'), + 'he_IL' => array('code' => 'he', 'language' => 'Hebrew', 'locale' => 'Hebrew_Israel', 'codepage' => 'ISO8859-1'), + 'hr_HR' => array('code' => 'hr', 'language' => 'Croatian', 'locale' => 'Croatian_Croatia', 'codepage' => 'ISO8859-1'), + 'hu_HU' => array('code' => 'hu', 'language' => 'Hungarian', 'locale' => 'Hungarian_Hungary', 'codepage' => 'ISO8859-1'), + 'it_IT' => array('code' => 'it', 'language' => 'Italian', 'locale' => 'Italian_Italy', 'codepage' => 'ISO8859-1'), + 'ja_JP' => array('code' => 'ja', 'language' => 'Japanese', 'locale' => 'Japanese_Japan', 'codepage' => 'ISO8859-1'), + 'ko_KO' => array('code' => 'ko', 'language' => 'Korean', 'locale' => 'Korean_Korea_Republic', 'codepage' => 'ISO8859-1'), + 'lt_LT' => array('code' => 'lt', 'language' => 'Lithuanian', 'locale' => 'Lithuanian_Lithuania', 'codepage' => 'ISO8859-1'), + 'lv_LV' => array('code' => 'lv', 'language' => 'Latvian', 'locale' => 'Latvian_Latvia', 'codepage' => 'ISO8859-1'), + 'nl_NL' => array('code' => 'nl', 'language' => 'Dutch', 'locale' => 'Dutch_Netherlands', 'codepage' => 'ISO8859-1'), + 'no_NO' => array('code' => 'no', 'language' => 'Norwegian', 'locale' => 'Norwegian_Norway', 'codepage' => 'ISO8859-1'), + 'pl_PL' => array('code' => 'pl', 'language' => 'Polish', 'locale' => 'Polish_Poland', 'codepage' => 'ISO8859-1'), + 'pt_BR' => array('code' => 'pt', 'language' => 'Portuguese', 'locale' => 'Portuguese_Brazil', 'codepage' => 'ISO8859-1'), + 'pt_PT' => array('code' => 'pt', 'language' => 'Portuguese', 'locale' => 'Portuguese_Portugal', 'codepage' => 'ISO8859-1'), + 'ro_RO' => array('code' => 'ro', 'language' => 'Romanian', 'locale' => 'Romanian_Romania', 'codepage' => 'ISO8859-1'), + 'ru_RU' => array('code' => 'ru', 'language' => 'Russian', 'locale' => 'Russian_Russian_Federation', 'codepage' => 'CP1251'), + 'sk_SK' => array('code' => 'sk', 'language' => 'Slovakian', 'locale' => 'Slovak_Slovakia', 'codepage' => 'ISO8859-1'), + 'sl_SL' => array('code' => 'sl', 'language' => 'Slovenian', 'locale' => 'Slovenian_Slovenia', 'codepage' => 'ISO8859-1'), + 'sr_ME' => array('code' => 'sr', 'language' => 'Serbian', 'locale' => 'Serbian_Republic_of_Montenegro', 'codepage' => 'ISO8859-1'), + 'sr_RS' => array('code' => 'rs', 'language' => 'Serbian', 'locale' => 'Serbian_Republic_of_Serbia', 'codepage' => 'ISO8859-1'), + 'sv_SE' => array('code' => 'sv', 'language' => 'Swedish', 'locale' => 'Swedish_Sweden', 'codepage' => 'ISO8859-1'), + 'th_TH' => array('code' => 'th', 'language' => 'Thailand', 'locale' => 'Thai_Thailand', 'codepage' => 'ISO8859-1'), + 'tr_TR' => array('code' => 'tr', 'language' => 'Turkish', 'locale' => 'Turkish_Turkey', 'codepage' => 'ISO8859-1'), + 'zh_CN' => array('code' => 'cn', 'language' => 'Chinese', 'locale' => 'Chinese_China', 'codepage' => 'ISO8859-1'), + 'zh_TW' => array('code' => 'zh', 'language' => 'Chinese', 'locale' => 'Chinese_Taiwan', 'codepage' => 'ISO8859-1') ); private $cisco_timezone = array( 'Dateline' => array('offset' => '-720', 'daylight' => ''), @@ -217,10 +217,22 @@ class extconfigs { // *** Setings for Provision Sccp $adv_config = Array('tftproot' => '', 'firmware' => 'firmware', 'settings' => 'settings', 'locales' => 'locales', 'languages' => 'languages', 'templates' => 'templates'); +// 'pro' /tftpboot - root dir +// /tftpboot/locales/locales/%Languge_name% +// /tftpboot/settings/XMLdefault.cnf.xml +// /tftpboot/settings/SEP[MAC].cnf.xml +// /tftpboot/firmware/79xx/SCCPxxxx.loads $adv_tree['pro'] = Array('templates' => 'tftproot', 'settings' => 'tftproot', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'locales'); +// 'def' /tftpboot - root dir +// /tftpboot/languages/%Languge_name% +// /tftpboot/XMLdefault.cnf.xml +// /tftpboot/SEP[MAC].cnf.xml +// /tftpboot/SCCPxxxx.loads + $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => '', 'firmware' => '', 'languages' => 'tftproot'); // $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => ''); - $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'tftproot'); +// $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'tftproot'); + //* **************------ **** $base_tree = Array('tftp_templates' => 'templates', 'tftp_path_store' => 'settings', 'tftp_lang_path' => 'languages', 'tftp_firmware_path' => 'firmware'); diff --git a/Sccp_manager.inc/srvinterface.class.php b/Sccp_manager.inc/srvinterface.class.php index e3edc0e..a5ff79a 100644 --- a/Sccp_manager.inc/srvinterface.class.php +++ b/Sccp_manager.inc/srvinterface.class.php @@ -11,24 +11,16 @@ namespace FreePBX\modules\Sccp_manager; class srvinterface { - var $socket; + var $error; - + public function __construct($parent_class = null) { - global $amp_conf; - $this->paren_class = $parent_class; - $this->socket = FALSE; + $this->paren_class = $parent_class; $this->error = ""; -/* - if (isset($amp_conf[AMPMGRUSER])) { - $this->astLogin('localhost', $amp_conf[AMPMGRUSER],$amp_conf[AMPMGRPASS]); - } - -*/ } public function info() { - $Ver = '13.0.3'; + $Ver = '13.0.4'; return Array('Version' => $Ver, 'about' => 'Server interface data ver: ' . $Ver); } @@ -37,10 +29,11 @@ class srvinterface { Core Access Function */ - -/* - * Replace or dublicate to AMI interface - */ + + /* + * Replace or dublicate to AMI interface + */ + public function sccp_core_commands($params = array()) { global $astman; $cmd_list = array('get_softkey' => array('cmd' => "sccp show softkeyssets", 'param' => ''), @@ -134,19 +127,20 @@ class srvinterface { /* * A function should be used in the form of buttons for getting all hint. Not working. I don't know how to use properly. */ + public function sccp_list_hints() { $hint_key = array(); $hint_all = $this->sccp_list_all_hints(); foreach ($hint_all as $value) { - $res = $this->loc_after('@', $value); + $res = $this->loc_after('@', $value); // array_search($res, $hint_key)) != NULL) - if (!isset($hint_key[$res])) { - $hint_key[$res] = '@'.$res; - } + if (!isset($hint_key[$res])) { + $hint_key[$res] = '@' . $res; + } } return $hint_key; } - + public function sccp_list_all_hints() { $ast_out = $this->sccp_core_commands(array('cmd' => 'get_hints')); $ast_out = preg_split("/[\n]/", $ast_out['data']); @@ -160,7 +154,7 @@ class srvinterface { foreach ($ast_out as $line) { if (strlen($line) > 3) { list ($line, $junk) = explode(' ', $line); - if (!is_bool(strpos($line,':'))) { + if (!is_bool(strpos($line, ':'))) { $line = trim(substr($line, 0, strpos($line, ':'))); } if (isset($ast_key[$line])) { @@ -177,15 +171,15 @@ class srvinterface { public function sccp_realtime_status() { $ast_res = array(); - $ast_out = $this->sccp_core_commands(array('cmd'=>'get_realtime_status')); - $ast_out = preg_split("/[\n]/", $ast_out['data']); - if (strpos($ast_out[0], 'Privilege') !== false){ + $ast_out = $this->sccp_core_commands(array('cmd' => 'get_realtime_status')); + $ast_out = preg_split("/[\n]/", $ast_out['data']); + if (strpos($ast_out[0], 'Privilege') !== false) { $ast_out[0] = ""; } foreach ($ast_out as $line) { if (strlen($line) > 3) { - $ast_key = strstr(trim($line), ' ', true); - $ast_res[$ast_key] = array('message' => $line, 'status'=> strpos($line, 'connected') ? 'OK' : 'ERROR'); + $ast_key = strstr(trim($line), ' ', true); + $ast_res[$ast_key] = array('message' => $line, 'status' => strpos($line, 'connected') ? 'OK' : 'ERROR'); } } return $ast_res; @@ -209,16 +203,16 @@ class srvinterface { default: return 430; } -/* if ($res["vCode"] >= 433) { - - } - if ($res["vCode"] >= 431) { - return 431; - } else { - return 430; - } - * - */ + /* if ($res["vCode"] >= 433) { + + } + if ($res["vCode"] >= 431) { + return 431; + } else { + return 430; + } + * + */ // return $res["vCode"]; } @@ -226,7 +220,7 @@ class srvinterface { $res = $this->getChanSCCPVersion(); if (empty($res)) { $res = $this->getCoreSCCPVersion(); - } + } return $res; } @@ -240,7 +234,7 @@ class srvinterface { $result["develop"] = $ast_out[1]; $res = 10; // !TODO!: This does not work as you might expect - if (base_convert($ast_out[3], 16, 10) == base_convert('702487a', 16, 10)) { + if (base_convert($ast_out[3], 16, 10) == base_convert('702487a', 16, 10)) { $result["vCode"] = 431; } if (base_convert($ast_out[3], 16, 10) >= "10403") { // new method, RevisionNum is incremental @@ -428,26 +422,26 @@ class srvinterface { return false; } } + private function strpos_array($haystack, $needles) { if (is_array($needles)) { - foreach ($needles as $str) { - if (is_array($str)) { - $pos = strpos_array($haystack, $str); - } else { - $pos = strpos($haystack, $str); - } - if ($pos !== FALSE) { - return $pos; + foreach ($needles as $str) { + if (is_array($str)) { + $pos = strpos_array($haystack, $str); + } else { + $pos = strpos($haystack, $str); + } + if ($pos !== FALSE) { + return $pos; + } } + } else { + return strpos($haystack, $needles); } - } else { - return strpos($haystack, $needles); - } - return FALSE; + return FALSE; } - private function loc_after($value, $inthat) - { + private function loc_after($value, $inthat) { if (!is_bool(strpos($inthat, $value))) return substr($inthat, strpos($inthat, $value) + strlen($value)); } @@ -463,234 +457,35 @@ class srvinterface { $metadata = $astman->send_request($action, $params); return $metadata; } - /* - * [Segments] => ( [0] => general [1] => device [2] => line [3] => softkey ) - */ - function getеtestChanSCCP_GlablsInfo($Segment='') { + + /* + * [Segments] => ( [0] => general [1] => device [2] => line [3] => softkey ) + */ + function getеtestChanSCCP_GlablsInfo($Segment = '') { global $astman; $params = array(); - $response = $astman->send_request('SCCPConfigMetaData', $params); $action = 'SCCPConfigMetaData'; if (empty($Segment)) { $Segment = 'general'; } - $params = array('Segment' => $Segment, 'ResultFormat'=>'command' ); + $params = array('Segment' => $Segment, 'ResultFormat' => 'command'); $metadata = $astman->send_request($action, $params); if (!empty($metadata['data'])) { - $tmp_data = $metadata['data']; - if (strpos($tmp_data, 'JSON:')!==false ) { - $decode = json_decode(substr ($tmp_data,strpos($tmp_data, 'JSON:') + 5), true); + $tmp_data = $metadata['data']; + if (strpos($tmp_data, 'JSON:') !== false) { + $decode = json_decode(substr($tmp_data, strpos($tmp_data, 'JSON:') + 5), true); $result = array(); if (!empty($decode['Options'])) { foreach ($decode['Options'] as $value) { - $result[$value['Name']] = $value; + $result[$value['Name']] = $value; } return $result; } return $decode; } - } return $metadata; } - - /* - private function astLogin($host="localhost", $username="admin", $password="amp111"){ - - $this->socket = @fsockopen("127.0.0.1","5038", $errno, $errstr, 1); - - if (!$this->socket) { - $this->error = "Could not connect - $errstr ($errno)"; - return FALSE; - }else{ - stream_set_timeout($this->socket, 1); - - $wrets = $this->astQuery("Action: Login\r\nUserName: $username\r\nSecret: $password\r\nEvents: off\r\n\r\n"); - - if (strpos($wrets['raw'], "Message: Authentication accepted") != FALSE) { - return TRUE; - }else{ - $this->error = "Could not login - Authentication failed "; - fclose($this->socket); - $this->socket = FALSE; - return FALSE; - } - } - } - - private function astLogout(){ - if ($this->socket){ - fputs($this->socket, "Action: Logoff\r\n\r\n"); - while (!feof($this->socket)) { - $wrets .= fread($this->socket, 8192); - } - fclose($this->socket); - $this->socket = "FALSE"; - } - return; - } - - private function astQuery($query, $rawdata = false){ - $wrets = ""; - - if ($this->socket === FALSE) - return FALSE; - $parameters = array(); - $data_store = 'data'; - fputs($this->socket, $query); - $parameters['raw_q'] = $query; - do - { - $line = fgets($this->socket, 4096); - $parameters['raw'] .= $line; - if (!$rawdata) { - $a = strpos($line, ':'); - if($a) { - $key = substr($line, 0, $a); - switch ($key) { - case 'Response': - case 'Message': - case 'EventList': - $parameters[$key] = trim(substr($line, $a + 2)); - break; - case 'JSON': - $parameters[$key] = substr($line, $a + 2); - $data_store = $key; - break; - default: - $parameters[$data_store] .= $line; - break; - } - // store parameter in $parameters - } else { - $parameters[$data_store] .= $line; - } - } - $info = stream_get_meta_data($this->socket); - }while ($line != "\r\n" && $info['timed_out'] == false ); - - return $parameters; - } - - function GetError(){ - return $this->error; - } - - private function astman_retrieveMeta($action = "", $parameters=array(), $rawdata = false) { - // $parameters=array() - global $amp_conf; - $option = ""; - $result = array(); - if ($this->socket === FALSE) { - if (!$this->astLogin(localhost, $amp_conf[AMPMGRUSER],$amp_conf[AMPMGRPASS])) { - $result["Response"] = "Faild"; - $result["Error"] = $this->error; - return $result; - } - } - - if (empty($action)) { - $action = 'SCCPConfigMetaData'; - } - $query = "Action: $action\r\n"; - - foreach($parameters as $var=>$val) { - if (is_array($val)) { - foreach($val as $k => $v) { - $query .= "$var: $k=$v\r\n"; - } - } else { - $query .= "$var: $val\r\n"; - } - } - - $result = $this->astQuery($query."\r\n",$rawdata); - - if ($result["Response"] == "Success") { - if ($rawdata) { - return $result; - } else { - if (!empty($result["JSON"])) { - $decode = json_decode($response["JSON"], true); - return $decode; - } else { - return $result; - } - } - } else { - return $result; - return array(); - } - } - - */ - - function t_get_meta_data() { - global $amp_conf; - $fp = fsockopen("127.0.0.1", "5038", $errno, $errstr, 10); - - if (!$fp) { - echo "$errstr ($errno)
\n"; - } else { - fputs ($fp,"Action: login\r\n"); - fputs ($fp,"Username: ".$amp_conf[AMPMGRUSER]."\r\n"); -// fputs ($fp,"Secret: secret\r\n"); - fputs ($fp,"Secret: ".$amp_conf[AMPMGRPASS]."\r\n"); - fputs ($fp,"Events: on\r\n\r\n"); - -// fputs ($fp,"Action: SCCPShowDevices\r\n"); - - fputs ($fp,"Action: SCCPConfigMetaData\r\n"); -// fputs ($fp,"Segment: general\r\n"); -// "Segments":["general","device","line","softkey"]} - fputs ($fp,"Segment: device\r\n"); - fputs ($fp,"ResultFormat: command\r\n"); - fputs ($fp,"\r\n"); - -/* - fputs ($fp,"Action: SCCPConfigMetaData\r\n"); - fputs ($fp,"\r\n"); - - fputs ($fp,"Action: SCCPConfigMetaData\r\n"); - fputs ($fp,"Segment: general\r\n"); - fputs ($fp,"\r\n"); - - fputs ($fp,"Action: SCCPConfigMetaData\r\n"); - fputs ($fp,"Segment: general\r\n"); - fputs ($fp,"ListResult: yes\r\n"); - fputs ($fp,"Option: fallback\r\n"); - fputs ($fp,"\r\n"); - - fputs ($fp,"Action: SCCPConfigMetaData\r\n"); - fputs ($fp,"Segment: device\r\n"); - fputs ($fp,"ListResult: freepbx\r\n"); - fputs ($fp,"\r\n"); - - fputs ($fp,"Action: SCCPConfigMetaData\r\n"); - fputs ($fp,"Segment: device\r\n"); - fputs ($fp,"Option: dtmfmode\r\n"); - fputs ($fp,"ListResult: yes\r\n"); - fputs ($fp,"\r\n"); -*/ - - fputs ($fp,"Action: logoff\r\n\r\n"); -// print_r(fgets($fp)); - $resp = ''; - while (!feof($fp)) { - $resp .= fgets($fp); - - } -// print_r(fgets($fp)); -// print_r('
'); - -// echo fgets($fp, 128); - } - fclose($fp); - return $resp; - } - - - } diff --git a/Sccp_manager.inc/xmlinterface.class.php b/Sccp_manager.inc/xmlinterface.class.php index e150904..2adf974 100644 --- a/Sccp_manager.inc/xmlinterface.class.php +++ b/Sccp_manager.inc/xmlinterface.class.php @@ -199,7 +199,7 @@ class xmlinterface { } $xnode->name = $tz_id; $xnode->dateTemplate = $data_values['dateformat']; - $xnode->timeZone = $TZdata['cisco_code']; + $xnode->timeZone = $TZdata['cisco_code']; // $xnode->timeZone = $tz_id.' Standard'.((empty($TZdata['daylight']))? '': '/'.$TZdata['daylight']).' Time'; if ($data_values['ntp_config_enabled'] == 'yes') { diff --git a/assets/js/sccp_manager.js b/assets/js/sccp_manager.js index 84b3575..36bec58 100644 --- a/assets/js/sccp_manager.js +++ b/assets/js/sccp_manager.js @@ -58,12 +58,16 @@ $(document).ready(function () { $('#ajaxsubmit2').on('click', function (e) { var vdata = ''; var snd_command = 'savesettings'; + console.log($('.fpbx-submit').data('id')); $('.fpbx-submit').each(function () { vdata = vdata + $(this).serialize() + '&'; }); if ($('.fpbx-submit').data('id') == "hw_edit") { snd_command = 'save_hardware'; } + if ($('.fpbx-submit').data('id') == "ruser_edit") { + snd_command = 'save_ruser'; + } if ($('.fpbx-submit').data('id') == "dial_template") { snd_command = 'save_dialplan_template'; } @@ -99,6 +103,9 @@ $(document).ready(function () { if ($('.fpbx-submit').data('id') == "hw_edit") { snd_command = 'save_hardware'; } + if ($('.fpbx-submit').data('id') == "ruser_edit") { + snd_command = 'save_ruser'; + } if ($('.fpbx-submit').data('id') == "dial_template") { snd_command = 'save_dialplan_template'; } diff --git a/conf/sccpgeneral.xml.v433 b/conf/sccpgeneral.xml.v433 index f495bb4..e05a2dc 100644 --- a/conf/sccpgeneral.xml.v433 +++ b/conf/sccpgeneral.xml.v433 @@ -17,7 +17,7 @@ and open the template in the editor. Base Version before all crash :-) * SLK - System KeySet * * Input element Select SLS - System Language * Input element Select SDM - Model List - * SDE - Extension List + * SDE - Extension List tftp_rewrite * Help elemen HLP - Help Element --> @@ -995,6 +995,15 @@ and open the template in the editor. Base Version before all crash :-) Say 'yes' if you need to create cisco default language directory in tftp path. + + + system_rouminguser + + no + + + Experemental Function Rouming Users + @@ -1078,7 +1087,7 @@ and open the template in the editor. Base Version before all crash :-) - description + _description 000000000 sccp-custom @@ -1540,4 +1549,106 @@ and open the template in the editor. Base Version before all crash :-) + + + + + + + id + 000000000 + sccp-custom + + + Help! + + + + + + description + + + Help! + + + + + pin + + + Help! + + + + + pin + + + Help! + + + rouminglogin + + off + + + + + + + auto_logout + + off + + + + + + + + homedevice + NONE + + sccp-custom + Help! + + + + + + + work_time + + off + + + + + + + + + work_group + + + Help! + + + + + time_extend + 30 + + Help! + + + + + + diff --git a/contrib/rewrite.rules b/contrib/rewrite.rules index 2824494..915c83e 100644 --- a/contrib/rewrite.rules +++ b/contrib/rewrite.rules @@ -106,10 +106,10 @@ ri ^(cmterm_7936.3-3-21-0.bin)$ firmware/7936/\1 ri ^(apps37sccp.1-4-5-7.bin)$ firmware/7937/\1 # 7940_7960 firmware (ancient) -ri ^(P0030801SR01.bin)$ firmware/7940/\1 -ri ^(P0030801SR01.loads)$ firmware/7940/\1 -ri ^(P0030801SR01.sb2)$ firmware/7940/\1 -ri ^(P0030801SR01.sbn)$ firmware/7940/\1 +ri ^(P0030801SR)(+\.bin)$ firmware/7940/\1 +ri ^(P0030801SR)(+\.loads)$ firmware/7940/\1 +ri ^(P0030801SR)(+\.sb2)$ firmware/7940/\1 +ri ^(P0030801SR)(+\.sbn)$ firmware/7940/\1 # 7941_7961 firmware (java-based) ri ^(apps41)(.+\.sbn)$ firmware/7941/\1\2 @@ -187,6 +187,11 @@ ri ^\/((SPA504G-cfg.xml)(\.enc)?(\.sgn)?)$ settings/\1 # Keep locales in a separate directory (optional) ri ^(.+)\/(.+-sccp.jar)$ locales/\1/\2 ri ^(.+)\/(.+-dictionary.xml)$ locales/\1/\2 +ri ^(.+)\/(.+-dictionary-ext.xml)$ languages/\1/\2 +ri ^(.+)\/(.+-tones.xml)$ languages/\1/\2 +ri ^(.+)\/(.+-font.xml)$ languages/\1/\2 +ri ^(.+)\/(.+-kate.xml)$ languages/\1/\2 + #ri ^(.+)\/(.+-tones.xml)$ locales/countries/\1/\2 # Keep ring-tones in a separate directory (optional) diff --git a/install.php b/install.php index 84e3a59..aad3ef4 100644 --- a/install.php +++ b/install.php @@ -155,9 +155,13 @@ function Get_DB_config($sccp_compatible) { 'directed_pickup_context' => array('create' => "VARCHAR(100) NULL DEFAULT NULL"), 'pickupmodeanswer' => array('rename' => "directed_pickup_modeanswer"), 'directed_pickup_modeanswer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'description' => array('rename' => "_description"), 'hwlang' => array('rename' => "_hwlang"), '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), - 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_hwlang`"), + '_loginname' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_hwlang`'), + '_profileid' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_loginname`'), + + 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_profileid`"), //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), 'dtmfmode' => array('drop' => "yes"), // 'force_dtmfmode' => array('create' => "VARCHAR(10) default 'auto'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'auto'), @@ -203,6 +207,7 @@ function Get_DB_config($sccp_compatible) { 'audio_cos' => array('drop' => "yes"), 'video_tos' => array('drop' => "yes"), 'video_cos' => array('drop' => "yes"), + 'phonecodepage' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL', 'modify' => "VARCHAR(50)"), 'incominglimit' => array('create' => "INT(11) DEFAULT '6'", 'modify' => 'INT(11)', 'def_modify' => "6"), 'transfer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), 'vmnum' => array('def_modify' => "*97"), @@ -228,11 +233,17 @@ function Get_DB_config($sccp_compatible) { 'pickupcontext' => array('drop' => "yes"), 'directed_pickup_modeanswer' => array('drop' => "yes"), 'pickupmodeanswer' => array('drop' => "yes"), + 'disallow' => array('drop' => "yes"), + 'disallow' => array('drop' => "yes"), 'callhistory_answered_elsewhere' => array('create' => "enum('Ignore','Missed Calls','Received Calls', 'Placed Calls') NULL default NULL", 'modify' => "enum('Ignore','Missed Calls','Received Calls','Placed Calls')"), + 'description' => array('rename' => "_description"), 'hwlang' => array('rename' => "_hwlang"), '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), - 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_hwlang`"), + '_loginname' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_hwlang`'), + '_profileid' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_loginname`'), + + 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_profileid`"), //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), 'dtmfmode' => array('drop' => "yes"), // 'force_dtmfmode' => array('create' => "VARCHAR(10) default 'auto'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'auto'), @@ -252,6 +263,7 @@ function Get_DB_config($sccp_compatible) { 'video_tos' => array('def_modify' => "0x88"), 'video_cos' => array('def_modify' => "5"), 'trustphoneip' => array('drop' => "yes"), + 'phonecodepage' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL', 'modify' => "VARCHAR(50)"), 'mwilamp' => array('create' => "enum('on','off','wink','flash','blink') NULL default 'on'", 'modify' => "enum('on','off','wink','flash','blink')"), 'mwioncall' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), 'private' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), // Что-то лишенне @@ -285,6 +297,8 @@ function Get_DB_config($sccp_compatible) { 'transfer' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), 'vmnum' => array('def_modify' => "*97"), 'musicclass' => array('def_modify' => "default"), + 'disallow' => array('create' => "VARCHAR(255) NULL DEFAULT NULL"), + 'allow' => array('create' => "VARCHAR(255) NULL DEFAULT NULL"), 'id' => array('create' => 'MEDIUMINT(9) NOT NULL AUTO_INCREMENT, ADD UNIQUE(id);', 'modify' => "MEDIUMINT(9)", 'index' => 'id'), // 'id' =>array('create' => 'VARCHAR( 20 ) NULL DEFAULT NULL', 'modify' => "VARCHAR(20)", 'def_modify' =>"NULL"), 'echocancel' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), @@ -305,7 +319,7 @@ function Get_DB_config($sccp_compatible) { $autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT" : "AUTO_INCREMENT"; -$table_req = array('sccpdevice', 'sccpline', 'buttonconfig'); +$table_req = array('sccpdevice', 'sccpline'); $ss = FreePBX::create()->Sccp_manager; $astman = FreePBX::create()->astman; $sccp_compatible = 0; @@ -381,6 +395,64 @@ function CheckChanSCCPCompatible() { return $sccp_compatible; } +function InstallDB_Buttons() { + global $db; + outn("
  • " . _("Creating buttons table...") . "
  • "); +// $check = $db->getRow("SELECT 1 FROM buttonconfig LIMIT 0", DB_FETCHMODE_ASSOC); +// if (DB::IsError($check)) { + $sql = "DROP TABLE IF EXISTS `buttonconfig`; + CREATE TABLE IF NOT EXISTS `sccpbuttonconfig` ( + `ref` varchar(15) NOT NULL default '', + `reftype` enum('sccpdevice', 'sccpuser') NOT NULL default 'sccpdevice', + `instance` tinyint(4) NOT NULL default 0, + `buttontype` enum('line','speeddial','service','feature','empty') NOT NULL default 'line', + `name` varchar(36) default NULL, + `options` varchar(100) default NULL, + PRIMARY KEY (`ref`,`reftype`,`instance`,`buttontype`), + KEY `ref` (`ref`,`reftype`) + ) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; + $check = $db->query($sql); + if (db::IsError($check)) { + die_freepbx("Can not create sccpbuttonconfig table, error:$check\n"); + } +/* + } else { + $db_result = $db->getAll("SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE " + . "WHERE TABLE_SCHEMA = 'asterisk' AND TABLE_NAME = 'buttonconfig' AND REFERENCED_COLUMN_NAME IS NOT NULL;"); + + if (DB::IsError($db_result)) { + die_freepbx("Can not get informations TABLE_SCHEMA\n"); + } + + $sql = ''; + $sql = 'RENAME TABLE `buttonconfig` TO `sccpbuttonconfig`;'; + $sql .= "ALTER TABLE `sccpbuttonconfig` ADD COLUMN `user` VARCHAR(20) NOT NULL DEFAULT '' AFTER `device`;"; + $check = $db->query($sql); + if (db::IsError($check)) { + die_freepbx("Can not create sccpsettings table, error:$check\n"); + } + $sql = ''; + foreach ($db_result as $tabl_data) { + $fld_id = $tabl_data[2]; + if (!empty($fld_id)) { + $sql .= "ALTER TABLE `sccpbuttonconfig` DROP FOREIGN KEY `".$fld_id."`\n"; + } + } + + $sql .= "ALTER TABLE `sccpbuttonconfig` CHANGE COLUMN `device` `device` varchar(15) NULL default NULL"; + $sql .= "ALTER TABLE `sccpbuttonconfig` ADD FOREIGN KEY (device) REFERENCES sccpdevice(name) ON DELETE CASCADE;"; + + $check = $db->query($sql); + if (DB::IsError($db_result)) { + die_freepbx("Can not get drop old FOREIGN KEY \n"); + + } + } + */ + return true; + +} + function InstallDB_sccpsettings() { global $db; outn("
  • " . _("Creating sccpsettings table...") . "
  • "); @@ -412,7 +484,29 @@ function InstallDB_sccpdevmodel() { `nametemplate` VARCHAR(50) NULL DEFAULT NULL, PRIMARY KEY (`model`), KEY `model` (`model`) - ) ENGINE=MyISAM DEFAULT CHARSET=latin1;"; + ) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; + $check = $db->query($sql); + if (db::IsError($check)) { + die_freepbx("Can not create sccpdevmodel table, error:$check\n"); + } + return true; +} + +function InstallDB_sccpusers() { + global $db; + outn("
  • " . _("Creating sccpusers table...") . "
  • "); + $sql = "CREATE TABLE IF NOT EXISTS `sccpusers` ( + `name` VARCHAR(20) NULL DEFAULT NULL, + `pin` VARCHAR(7) NULL DEFAULT NULL, + `password` VARCHAR(7) NULL DEFAULT NULL, + `description` VARCHAR(45) NULL DEFAULT NULL, + `rouminglogin` ENUM('on','off','multi') NULL DEFAULT 'off', + `devicegroup` VARCHAR(20) NULL DEFAULT 'all', + `auto_logout` ENUM('on','off') NULL DEFAULT 'off', + `homedevice` VARCHAR(20) NULL DEFAULT NULL, + UNIQUE INDEX (`name`), + PRIMARY KEY (`name`) + ) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; $check = $db->query($sql); if (db::IsError($check)) { die_freepbx("Can not create sccpdevmodel table, error:$check\n"); @@ -569,26 +663,55 @@ function InstallDB_updateSccpDevice() { function InstallDB_createButtonConfigTrigger() { global $db; outn("
  • " . _("(Re)Create buttonconfig trigger") . "
  • "); - $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 - SET @line_x = SUBSTRING_INDEX(NEW.`name`,'!',1); - SET @line_x = SUBSTRING_INDEX(@line_x,'@',1); - IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = @line_x ) = 0 - THEN - UPDATE `Foreign key contraint violated: line does not exist in sccpline` SET x=1; + $sql = "DROP TRIGGER IF EXISTS sccp_trg_buttonconfig;"; +/* $sql = "DELIMITER $$ +CREATE TRIGGER sccp_trg_buttonconfig BEFORE INSERT ON sccpbuttonconfig +FOR EACH ROW +BEGIN + IF NEW.`reftype` = 'sccpdevice' THEN + IF (SELECT COUNT(*) FROM `sccpdevice` WHERE `sccpdevice`.`name` = NEW.`ref` ) = 0 THEN + UPDATE `Foreign key contraint violated: ref does not exist in sccpdevice` SET x=1; END IF; END IF; - END $$ - DELIMITER ;"; + IF NEW.`reftype` = 'sccpline' THEN + IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = NEW.`ref`) = 0 THEN + UPDATE `Foreign key contraint violated: ref does not exist in sccpline` SET x=1; + END IF; + END IF; + IF NEW.`buttontype` = 'line' THEN + SET @line_x = SUBSTRING_INDEX(NEW.`name`,'!',1); + SET @line_x = SUBSTRING_INDEX(@line_x,'@',1); + IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = @line_x ) = 0 THEN + UPDATE `Foreign key contraint violated: line does not exist in sccpline` SET x=1; + END IF; + END IF; +END $$ +DELIMITER ;";*/ + $sql .= " + CREATE TRIGGER `sccp_trg_buttonconfig` BEFORE INSERT ON `sccpbuttonconfig` FOR EACH ROW BEGIN + IF NEW.`reftype` = 'sccpdevice' THEN + IF (SELECT COUNT(*) FROM `sccpdevice` WHERE `sccpdevice`.`name` = NEW.`ref` ) = 0 THEN + UPDATE `Foreign key contraint violated: ref does not exist in sccpdevice` SET x=1; + END IF; + END IF; + IF NEW.`reftype` = 'sccpline' THEN + IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = NEW.`ref`) = 0 THEN + UPDATE `Foreign key contraint violated: ref does not exist in sccpline` SET x=1; + END IF; + END IF; + IF NEW.`buttontype` = 'line' THEN + SET @line_x = SUBSTRING_INDEX(NEW.`name`,'!',1); + SET @line_x = SUBSTRING_INDEX(@line_x,'@',1); + IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = @line_x ) = 0 THEN + UPDATE `Foreign key contraint violated: line does not exist in sccpline` SET x=1; + END IF; + END IF; + END"; $check = $db->query($sql); if (DB::IsError($check)) { die_freepbx("Can not modify sccpdevice table\n"); } + outn("
  • " . $sql . "
  • "); return true; } function InstallDB_updateDBVer($sccp_compatible) { @@ -627,18 +750,38 @@ function InstallDB_CreateSccpDeviceConfigView($sccp_compatible) { `sccpdevice`.`conf_show_conflist` AS `conf_show_conflist`,`sccpdevice`.`setvar` AS `setvar`,`sccpdevice`.`disallow` AS `disallow`, `sccpdevice`.`allow` AS `allow`,`sccpdevice`.`backgroundImage` AS `backgroundImage`,`sccpdevice`.`ringtone` AS `ringtone`,`sccpdevice`.`name` AS `name` FROM sccpdevice - LEFT JOIN buttonconfig ON ( buttonconfig.device = sccpdevice.name ) + LEFT JOIN sccpbuttonconfig buttonconfig ON ( buttonconfig.device = sccpdevice.name ) GROUP BY sccpdevice.name;"; } else { + /* $sql = " + CREATE OR REPLACE + ALGORITHM = MERGE + VIEW sccpdeviceconfig AS + SELECT IF(sccpdevice._profileid = 0, + GROUP_CONCAT(CONCAT_WS( ',', defbutton.buttontype, defbutton.name, defbutton.options ) ORDER BY defbutton.instance ASC SEPARATOR ';' ), + GROUP_CONCAT( CONCAT_WS( ',', userbutton.buttontype, userbutton.name, userbutton.options ) ORDER BY userbutton.instance ASC SEPARATOR ';' ) + ) AS button, + sccpdevice.* + FROM sccpdevice + LEFT JOIN sccpbuttonconfig defbutton ON ( defbutton.ref = sccpdevice.name ) + LEFT JOIN sccpbuttonconfig userbutton ON ( userbutton.ref = sccpdevice._loginname ) + LEFT JOIN sccpline ON ( sccpline.name = sccpdevice._loginname) + GROUP BY sccpdevice.name;"; +*/ $sql = " 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.* + SELECT case sccpdevice._profileid + when 0 then + (select GROUP_CONCAT(CONCAT_WS( ',', defbutton.buttontype, defbutton.name, defbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as defbutton where defbutton.ref = sccpdevice.name ORDER BY defbutton.instance ) + when 1 then + (select GROUP_CONCAT(CONCAT_WS( ',', userbutton.buttontype, userbutton.name, userbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as userbutton where userbutton.ref = sccpdevice._loginname ORDER BY userbutton.instance ) + when 2 then + (select GROUP_CONCAT(CONCAT_WS( ',', homebutton.buttontype, homebutton.name, homebutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as homebutton where homebutton.ref = sccpusers.homedevice ORDER BY homebutton.instance ) + end as button, sccpdevice.*, if(sccpdevice._profileid = 0, sccpdevice._description, sccpusers.description) as description FROM sccpdevice - LEFT JOIN buttonconfig ON ( buttonconfig.device = sccpdevice.name ) + LEFT JOIN sccpusers sccpusers ON ( sccpusers.name = sccpdevice._loginname ) GROUP BY sccpdevice.name;"; } $results = $db->query($sql); @@ -729,6 +872,10 @@ CheckAsteriskVersion(); $sccp_compatible = CheckChanSCCPCompatible(); $db_config = Get_DB_config($sccp_compatible); $sccp_db_ver = CheckSCCPManagerDBVersion(); + +InstallDB_sccpusers(); +InstallDB_Buttons(); + InstallDB_sccpsettings(); InstallDB_sccpdevmodel(); InstallDB_updateSchema($db_config); @@ -738,6 +885,7 @@ if (!$sccp_db_ver) { } else { outn("Skip update Device model"); } + InstallDB_createButtonConfigTrigger(); InstallDB_CreateSccpDeviceConfigView($sccp_compatible); InstallDB_updateDBVer($sccp_compatible); diff --git a/uninstall.php b/uninstall.php index c465fe2..340e7dd 100644 --- a/uninstall.php +++ b/uninstall.php @@ -10,13 +10,18 @@ if (!defined('FREEPBX_IS_AUTH')) { die('No direct script access allowed'); } global $db; $version = FreePBX::Config()->get('ASTVERSION'); - echo "dropping table sccpdevmodel.."; - sql("DROP TABLE IF EXISTS `sccpdevmodel`"); - echo "dropping table sccpsettings.."; - sql("DROP TABLE IF EXISTS `sccpsettings`"); + out('Remove all SCCP tables'); + $tables = array('sccpdevmodel', 'sccpsettings'); + foreach ($tables as $table) { + $sql = "DROP TABLE IF EXISTS {$table}"; + $result = $db->query($sql); + if (DB::IsError($result)) { + die_freepbx($result->getDebugInfo()); + } + unset($result); + } if (!empty($version)) { // Woo, we have a version - $check = $db->getRow("SELECT 1 FROM `kvstore` LIMIT 0", DB_FETCHMODE_ASSOC); if (!(DB::IsError($check))) { //print_r("none, creating table :". $value); @@ -29,7 +34,7 @@ if (!defined('FREEPBX_IS_AUTH')) { die('No direct script access allowed'); } /* So that you know if it is save to drop/delete them */ /* DROP VIEW `sccpdeviceconfig`; - DROP TABLE `buttonconfig`; + DROP TABLE `sccpbuttonconfig`; DROP TABLE `sccpdevice`; DROP TABLE `sccpdevmodel`; DROP TABLE `sccpline`; diff --git a/views/form.addruser.php b/views/form.addruser.php new file mode 100644 index 0000000..43cd908 --- /dev/null +++ b/views/form.addruser.php @@ -0,0 +1,34 @@ + 'id', "data" => $dev_id, "seq" => "99"); + $db_res = $this->dbinterface->get_db_SccpTableData('get_sccpdusers', array("id" => $dev_id)); + if (!empty($db_res) ) { + foreach ($db_res as $key => $val) { + if (!empty($val)) { + $def_val[$key] = array("keyword" => $key, "data" => $val, "seq" => "99"); + } + } + } +} + +?> + +
    + + + + ShowGroup('sccp_ruser', 1, 'sccp_ru', $def_val); + echo $this->ShowGroup('sccp_ruser_time', 1, 'sccp_ru', $def_val); + ?> +
    diff --git a/views/form.buttons.php b/views/form.buttons.php index 0969948..5cf70b7 100644 --- a/views/form.buttons.php +++ b/views/form.buttons.php @@ -16,20 +16,9 @@ $feature_list= array('parkinglot'=>'Park Slots','monitor'=> "Record Calls",'dev $lines_list = $this->dbinterface->get_db_SccpTableData('SccpExtension'); //$hint_list = $this->dbinterface->get_db_SccpTableData('SccpExtension'); -$data_sort = Array(); -$hint_list1 = $this->get_hint_info(); -foreach ($hint_list1 as $key => $value) { - $data_sort[$value['name']] = $key; -} -ksort($data_sort); -//print_r(count($data_sort)); -//print_r(count($hint_list1)); -foreach ($data_sort as $key => $value) { - $hint_list[$value] = $hint_list1[$value]; -} -//print_r($hint_list); -//ksort($hint_list); -//natsort($hint_list); +$hint_list = $this->get_hint_info(true,array('context'=>'park-hints')) ; + +// print_r($hint_list); $line_id =0; $max_buttons =56; $show_buttons =1; @@ -56,6 +45,11 @@ if (!empty($_REQUEST['new_id'])) { } $show_buttons = $max_buttons; } +if (!empty($_REQUEST['ru_id'])) { + $dev_id = $_REQUEST['ru_id']; + $db_buttons = $this->dbinterface->get_db_SccpTableData('get_sccpdevice_buttons', array("id" => $dev_id)); + $show_buttons = $max_buttons; +} ?> @@ -94,7 +88,7 @@ if (!empty($_REQUEST['new_id'])) { for ($line_id = 0; $line_id <=$max_buttons; $line_id ++){ // print_r($db_buttons[$line_id]); $show_form_mode = ''; - $defaul_tv = (empty($db_buttons[$line_id])) ? "empty": $db_buttons[$line_id]['type']; + $defaul_tv = (empty($db_buttons[$line_id])) ? "empty": $db_buttons[$line_id]['buttontype']; $defaul_btn = (empty($db_buttons[$line_id])) ? "": $db_buttons[$line_id]['name']; $defaul_opt = (empty($db_buttons[$line_id])) ? array(''): explode(',',$db_buttons[$line_id]['options']); @@ -122,6 +116,7 @@ if (!empty($_REQUEST['new_id'])) { $defaul_fcod = (empty($defaul_opt[1])) ? '': $defaul_opt[1]; // print_r($defaul_fcod); } + foreach ($defaul_opt as $data_i) { if (strpos($data_i,'@')>0) { $test_btn = strtok($data_i,'@'); @@ -140,7 +135,7 @@ if (!empty($_REQUEST['new_id'])) { } } } -// print_r($defaul_btn); +// print_r($def_hint_btn); // print_r($defaul_opt); echo ''; @@ -211,8 +206,8 @@ if (!empty($_REQUEST['new_id'])) { echo ''; echo ''; diff --git a/views/formShow.php b/views/formShow.php index 1e0df54..4e6fda8 100644 --- a/views/formShow.php +++ b/views/formShow.php @@ -56,8 +56,11 @@ if (!is_array($moh_list)){ $sofkey_list = \FreePBX::Sccp_manager()-> srvinterface -> sccp_list_keysets(); $model_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWDevice"); $extension_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWextension"); +$device_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("SccpDevice"); $extension_list[]=array(model=>'NONE', vendor=>'CISCO', dns=>'0'); +$device_list[]=array(name=>'NONE', description=>'No Device'); + $items = $itm -> children(); @@ -619,7 +622,7 @@ foreach ($items as $child) { * SDE - Extension List */ - if ($child['type'] == 'SDM' || $child['type'] == 'SDE' ) { + if ($child['type'] == 'SDM' || $child['type'] == 'SDE' || $child['type'] == 'SDD') { // $value = $child -> select; $res_n = (string)$child ->name; $res_id = $npref.$res_n; @@ -639,6 +642,9 @@ foreach ($items as $child) { if ($child['type'] == 'SDE') { $select_opt= $extension_list; } + if ($child['type'] == 'SDD') { + $select_opt = $device_list; + } echo ''; @@ -659,11 +665,12 @@ foreach ($items as $child) { } echo '>'; - $fld = (string)$child->select['name']; - $flv = (string)$child->select; - $flk = (string)$child->select['dataid']; - $flkv= (string)$child->select['dataval']; - $key = (string)$child->default; + $fld = (string)$child->select['name']; + $flv = (string)$child->select; + $flv2 = (string)$child->select['addlabel']; + $flk = (string)$child->select['dataid']; + $flkv = (string)$child->select['dataval']; + $key = (string)$child->default; if (!empty($fvalues[$res_n])) { if (!empty($fvalues[$res_n]['data'])) { $child->value = $fvalues[$res_n]['data']; @@ -682,7 +689,11 @@ foreach ($items as $child) { if (!empty($flkv)){ echo ' data-val="'.$data[$flkv].'"'; } - echo '>' . $data[$flv] . ''; + echo '>' . $data[$flv]; + if (!empty($flv2)){ + echo ' / '.$data[$flv2]; + } + echo ''; } ?> diff --git a/views/hardware.extension.php b/views/hardware.extension.php index 1b2889b..ce7a759 100644 --- a/views/hardware.extension.php +++ b/views/hardware.extension.php @@ -5,7 +5,12 @@ * and open the template in the editor. */ // vim: set ai ts=4 sw=4 ft=phtml: - +$roming_enable = ''; +if (!empty($this->sccpvalues['system_rouminguser'])) { + if ($this->sccpvalues['system_rouminguser']['data'] == 'yes'){ + $roming_enable = 'yes'; + } +} ?>
    @@ -24,6 +29,7 @@ + @@ -34,6 +40,14 @@
    \ No newline at end of file diff --git a/views/server.info.php b/views/server.info.php index 47466a7..abfec8c 100644 --- a/views/server.info.php +++ b/views/server.info.php @@ -27,6 +27,7 @@ $info = array(); $info['srvinterface'] = $this->srvinterface->info(); $info['extconfigs'] = $this->extconfigs->info(); $info['dbinterface'] = $this->dbinterface->info(); +$info['aminterface'] = $this->aminterface->info(); $db_Schema = $this->dbinterface->validate(); $info['XML'] = $this->xmlinterface->info(); @@ -90,29 +91,49 @@ if (empty($conf_realtime)) { } } //global $amp_conf; -/* +// ************************************************************************************ print_r("
    Request:
    ");
      $json = '';
      print_r("
    "); // print_r($conf_realtime); print_r("
    "); print_r("
    "); - print_r($this->dbinterface->validate()); // print_r("DIRECT START"); // print_r($this->sccpvalues['ccm_address']); + //print_r($this->get_php_classes('\\FreePBX\\modules\\')); +/* + print_r(get_declared_classes()); + print_r($this->aminterface->open()); + + + print_r($this->aminterface->_error); print_r("
    "); -// print_r($this->getIP_information2()); + + */ + + + + //print_r($this->dbinterface->get_db_SccpTableData('SccpExtension')); // print_r($this->srvinterface->getеtestChanSCCP_GlablsInfo()); +// $test_data = $this->srvinterface-> astman_GetRaw('ExtensionStateList'); +// print_r($test_data); +// print_r($this->srvinterface-> core_list_all_exten()); +// print_r($this->get_hint_info()); +// print_r($this->aminterface-> core_list_all_exten('exten')); +// print_r($this->aminterface->Sok_param['total']); +// print_r($this->srvinterface->t_get_meta_data()); // print_r($this->sccp_metainfo); print("
    "); +// ************************************************************************************ + // $lang_arr = $this->extconfigs->getextConfig('sccp_lang','sk_SK'); // print_r('
    '); // print_r(timezone_identifiers_list()); // print_r('
    '); //print_r($this->dbinterface->info()); -*/ + if (!empty($this->class_error)) { ?>
    From f686274189a0930bbe7ce3d414d70d84d10cc210 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 25 Mar 2019 16:55:44 +0300 Subject: [PATCH 002/100] Initial add of feature mobility user table: - Add extra user fields and sccp_config entries - Create new buttonconfig table - Add PhoneCodepages like cp1251 --- Sccp_manager.class.php | 31 ++++++++++++++++++------- Sccp_manager.inc/srvinterface.class.php | 25 ++++++++++---------- Sccp_manager.inc/xmlinterface.class.php | 3 +++ install.php | 4 ++-- module.xml | 1 + 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 740a074..c097bbe 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -514,12 +514,13 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { "buttons" => array( "name" => _("Device Buttons"), "page" => 'views/form.buttons.php' - ), - "sccpcodec" => array( - "name" => _("Device SCCP Codec"), - "page" => 'views/server.codec.php' - ), - ); + )); + if ($this->sccpvalues['sccp_compatible']['data'] < '433') { + $this->pagedata["sccpcodec"] = array( + "name" => _("Device SCCP Codec"), + "page" => 'views/server.codec.php' + ); + } break; @@ -1124,6 +1125,15 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { }; $value = implode(";", $save_codec); break; + case 'phonecodepage': + $value = 'null'; + if (!empty($get_settings[$hdr_prefix . 'devlang'])) { + $lang_data = $this->extconfigs->getextConfig('sccp_lang',$get_settings[$hdr_prefix . 'devlang']); + if (!empty($lang_data)) { + $value = $lang_data['codepage']; + } + } + break; case '_hwlang': if (empty($get_settings[$hdr_prefix . 'netlang']) || empty($get_settings[$hdr_prefix . 'devlang'])) { $value = 'null'; @@ -1197,7 +1207,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { if ($hw_id == 'new') { $this->srvinterface->sccp_core_commands(array('cmd' => 'reset_phone', 'name' => $name_dev)); } else { - $this->srvinterface->sccp_core_commands(array('cmd' => 'reload_phone', 'name' => $name_dev)); + $this->srvinterface->sccp_core_commands(array('cmd' => 'restart_phone', 'name' => $name_dev)); } return $save_settings; @@ -1966,8 +1976,13 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { case "permit": $this->sccp_conf_init['general'][$key] = explode(';', $value['data']); break; + case "devlang": + $lang_data = $this->extconfigs->getextConfig('sccp_lang',$value['data']); + if (!empty($lang_data)) { + $this->sccp_conf_init['general']['phonecodepage'] = $lang_data['codepage']; + } + break; case "netlang": // Remove Key - case "devlang": case "tftp_path": case "sccp_compatible": break; diff --git a/Sccp_manager.inc/srvinterface.class.php b/Sccp_manager.inc/srvinterface.class.php index a5ff79a..eaf5664 100644 --- a/Sccp_manager.inc/srvinterface.class.php +++ b/Sccp_manager.inc/srvinterface.class.php @@ -1,9 +1,9 @@ array('cmd' => "sccp show device", 'param' => 'name'), 'get_hints' => array('cmd' => "core show hints", 'param' => ''), 'sccp_reload' => array('cmd' => "sccp reload force", 'param' => ''), - 'reset_phone' => array('cmd' => "sccp reset ", 'param' => 'name'), // Жесткая перезагрузка + 'reset_phone' => array('cmd' => "sccp reset ", 'param' => 'name'), // Жесткая перезагрузка + 'restart_phone' => array('cmd' => "sccp restart ", 'param' => 'name'), 'reload_phone' => array('cmd' => "sccp reload device ", 'param' => 'name'), 'reset_token' => array('cmd' => "sccp tokenack ", 'param' => 'name'), 'get_realtime_status' => array('cmd' => "realtime mysql status", 'param' => ''), @@ -75,7 +76,7 @@ class srvinterface { if (!empty($params['name'])) { $astman->Command('sccp device ' . $params['name'] . ' ' . $msg); } else { - + } break; default: @@ -133,7 +134,7 @@ class srvinterface { $hint_all = $this->sccp_list_all_hints(); foreach ($hint_all as $value) { $res = $this->loc_after('@', $value); -// array_search($res, $hint_key)) != NULL) +// array_search($res, $hint_key)) != NULL) if (!isset($hint_key[$res])) { $hint_key[$res] = '@' . $res; } @@ -185,7 +186,7 @@ class srvinterface { return $ast_res; } -// !TODO!: -TODO-: install.php is still using the other version number. This is actually where I use another method ? +// !TODO!: -TODO-: install.php is still using the other version number. This is actually where I use another method ? public function get_compatible_sccp() { @@ -211,7 +212,7 @@ class srvinterface { } else { return 430; } - * + * */ // return $res["vCode"]; } @@ -233,7 +234,7 @@ class srvinterface { if (!empty($ast_out[1]) && $ast_out[1] == 'develop') { $result["develop"] = $ast_out[1]; $res = 10; -// !TODO!: This does not work as you might expect +// !TODO!: This does not work as you might expect if (base_convert($ast_out[3], 16, 10) == base_convert('702487a', 16, 10)) { $result["vCode"] = 431; } @@ -383,7 +384,7 @@ class srvinterface { explode(";|", implode(";|", $line_arr)); list ($descr, $adress, $devname, $status, $token, $junk) = explode(";|", implode(";|", $line_arr)); -// list ($descr, $adress, $devname, $status, $junk) = $line_arr; +// list ($descr, $adress, $devname, $status, $junk) = $line_arr; // if (strlen($ast_key[$devname]) < 1) { if (strlen($devname) > 1) { $ast_key[$devname] = Array('name' => $devname, 'status' => $status, 'address' => $adress, 'descr' => $descr, 'token' => $token); @@ -396,7 +397,7 @@ class srvinterface { } else { $ast_key[$devname] = Array('name' => $devname, 'status' => $status, 'address' => $adress, 'descr' => $descr, 'token' => $token); } - * + * */ } } diff --git a/Sccp_manager.inc/xmlinterface.class.php b/Sccp_manager.inc/xmlinterface.class.php index 2adf974..66bfb8c 100644 --- a/Sccp_manager.inc/xmlinterface.class.php +++ b/Sccp_manager.inc/xmlinterface.class.php @@ -343,6 +343,9 @@ class xmlinterface { if (isset($lang_info[$lang])) { $xml_node->name = $lang_info[$lang]['locale']; $xml_node->langCode = $lang_info[$lang]['code']; + if ($key == 'userLocale') { + $xml_node->winCharSet = $lang_info[$lang]['codepage']; + } $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); } } diff --git a/install.php b/install.php index aad3ef4..2d71dc9 100644 --- a/install.php +++ b/install.php @@ -159,7 +159,7 @@ function Get_DB_config($sccp_compatible) { 'hwlang' => array('rename' => "_hwlang"), '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), '_loginname' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_hwlang`'), - '_profileid' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_loginname`'), + '_profileid' => array('create' => "INT(11) NOT NULL DEFAULT '0' AFTER `_loginname`"), 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_profileid`"), //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), @@ -241,7 +241,7 @@ function Get_DB_config($sccp_compatible) { 'hwlang' => array('rename' => "_hwlang"), '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), '_loginname' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_hwlang`'), - '_profileid' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_loginname`'), + '_profileid' => array('create' => "INT(11) NOT NULL DEFAULT '0' AFTER `_loginname`"), 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_profileid`"), //'dtmfmode' => array('create' => "VARCHAR(10) default 'outofband'", 'modify' => "VARCHAR(10)", 'def_modify'=> 'outofband'), diff --git a/module.xml b/module.xml index 6c324cb..2aa6fd8 100644 --- a/module.xml +++ b/module.xml @@ -15,6 +15,7 @@ * Version 13.0.0.1 * - Alfa Release tested on freepbx v.13.0.192.16, v.14.0.1.5 * Version 13.0.0.2 * - Release tested + * Version 14.0.0.1 * - Alfa Release new DB structure Add User mobility From d6dc2a2071d84ad92bd04a4d5c496cef63410cca Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 25 Mar 2019 18:16:17 +0300 Subject: [PATCH 003/100] Initial add of feature mobility user table: - Add extra user fields and sccp_config entries - Create new buttonconfig table - Add PhoneCodepages like cp1251 - Add BackUp Config before Install --- install.php | 31 +++++++++++++++++++++++++++++-- uninstall.php | 25 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/install.php b/install.php index 2d71dc9..eb2caa9 100644 --- a/install.php +++ b/install.php @@ -711,7 +711,8 @@ DELIMITER ;";*/ if (DB::IsError($check)) { die_freepbx("Can not modify sccpdevice table\n"); } - outn("
  • " . $sql . "
  • "); + outn("
  • " . _("(Re)Create trigger Ok") . "
  • "); +// outn("
  • " . $sql . "
  • "); return true; } function InstallDB_updateDBVer($sccp_compatible) { @@ -790,6 +791,29 @@ function InstallDB_CreateSccpDeviceConfigView($sccp_compatible) { } return true; } +function CreateBackUpConfig() { + global $amp_conf; + outn("
  • " . _("Create Config BackUp") . "
  • "); + $cnf_int = \FreePBX::Config(); + $backup_files = array('extconfig','extconfig','res_mysql', 'res_config_mysql','sccp'); + $backup_ext = array('_custom.conf', '.conf'); + $dir = $cnf_int->get('ASTETCDIR'); + $zip = new \ZipArchive(); + $filename = $dir . "/sccp_instal_backup" . date("Ymd"). ".zip"; + if ($zip->open($filename, \ZIPARCHIVE::CREATE)) { + foreach ($backup_files as $file) { + foreach ($backup_ext as $b_ext) { + if (file_exists($dir . '/'.$file . $b_ext)) { + $zip->addFile($dir . '/'.$file . $b_ext); + } + } + } + $zip->close(); + } else { + outn("
  • " . _("Error Create BackUp: ") . $filename ."
  • "); + } + outn("
  • " . _("Create Config BackUp: ") . $filename ."
  • "); +} function Setup_RealTime() { global $amp_conf; @@ -802,7 +826,7 @@ function Setup_RealTime() { $def_config = array('sccpdevice' => 'mysql,sccp,sccpdeviceconfig', 'sccpline' => ' mysql,sccp,sccpline'); $def_bd_config = array('dbhost' => $amp_conf['AMPDBHOST'], 'dbname' => $amp_conf['AMPDBNAME'], 'dbuser' => $amp_conf['AMPDBUSER'], 'dbpass' => $amp_conf['AMPDBPASS'], - 'dbport' => '3306', 'dbsock' => '/var/lib/mysql/mysql.sock'); + 'dbport' => '3306', 'dbsock' => '/var/lib/mysql/mysql.sock','dbcharset'=>'utf8'); $def_bd_sec = 'sccp'; $dir = $cnf_int->get('ASTETCDIR'); @@ -873,6 +897,9 @@ $sccp_compatible = CheckChanSCCPCompatible(); $db_config = Get_DB_config($sccp_compatible); $sccp_db_ver = CheckSCCPManagerDBVersion(); +// BackUp Old config +CreateBackUpConfig(); + InstallDB_sccpusers(); InstallDB_Buttons(); diff --git a/uninstall.php b/uninstall.php index 340e7dd..6090e0f 100644 --- a/uninstall.php +++ b/uninstall.php @@ -5,6 +5,31 @@ /* !TODO!: This would require the install.php to make a note of all the actions that were skipped and/or performed */ /* !TODO!: Might be a good idea to create a backup of the database before removing anything */ // !TODO!: -TODO-: I remove only that which is related to the Manager, it is in my opinion not a critical configuration information. This information is partially present in other files. +/* +function CreateBackUpConfig() { + global $amp_conf; + outn("
  • " . _("Create Config BackUp") . "
  • "); + $cnf_int = \FreePBX::Config(); + $backup_files = array('extconfig','extconfig','res_mysql', 'res_config_mysql','sccp'); + $backup_ext = array('_custom.conf', '.conf'); + $dir = $cnf_int->get('ASTETCDIR'); + $zip = new \ZipArchive(); + $filename = $dir . "/sccp_uninstall_backup" . date("Ymd"). ".zip"; + if ($zip->open($filename, \ZIPARCHIVE::CREATE)) { + foreach ($backup_files as $file) { + foreach ($backup_ext as $b_ext) { + if (file_exists($dir . '/'.$file . $b_ext)) { + $zip->addFile($dir . '/'.$file . $b_ext); + } + } + } + $zip->close(); + } else { + outn("
  • " . _("Error Create BackUp: ") . $filename ."
  • "); + } + outn("
  • " . _("Create Config BackUp: ") . $filename ."
  • "); +} +*/ if (!defined('FREEPBX_IS_AUTH')) { die('No direct script access allowed'); } global $db; From c5004e780de107e756e9bb3b5e1788d3662be78b Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 1 Apr 2019 09:33:13 +0300 Subject: [PATCH 004/100] Initial add of feature mobility user table: - Add extra user fields and sccp_config entries - Create new buttonconfig table - Add PhoneCodepages like cp1251 - Add BackUp Config before Install --- !Readme.txt/freppbx.txt | 1 + Sccp_manager.class.php | 2 +- conf/sccpgeneral.xml.v433 | 2 +- contrib/rewrite.rules | 20 ++++++++++---------- install.php | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 !Readme.txt/freppbx.txt diff --git a/!Readme.txt/freppbx.txt b/!Readme.txt/freppbx.txt new file mode 100644 index 0000000..f5a405c --- /dev/null +++ b/!Readme.txt/freppbx.txt @@ -0,0 +1 @@ +https://github.com/chan-sccp/chan-sccp/wiki/Monitor-and-Pickup-Incoming-Calls-via-Speeddial-Using-Custom-Devstate diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index c097bbe..0cb91a2 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -1945,7 +1945,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { fclose($fh); $zip = new \ZipArchive(); - $filename = $result . "." . gethostname() . ".zip"; + $filename = $result . "." . gethostname() . ".zip"; if ($zip->open($filename, \ZIPARCHIVE::CREATE)) { $zip->addFile($result); $zip->addFile($backup_info); diff --git a/conf/sccpgeneral.xml.v433 b/conf/sccpgeneral.xml.v433 index e05a2dc..f65b27e 100644 --- a/conf/sccpgeneral.xml.v433 +++ b/conf/sccpgeneral.xml.v433 @@ -1590,7 +1590,7 @@ and open the template in the editor. Base Version before all crash :-) Help! - rouminglogin + roaminglogin off diff --git a/contrib/rewrite.rules b/contrib/rewrite.rules index 915c83e..7e3bbed 100644 --- a/contrib/rewrite.rules +++ b/contrib/rewrite.rules @@ -106,10 +106,10 @@ ri ^(cmterm_7936.3-3-21-0.bin)$ firmware/7936/\1 ri ^(apps37sccp.1-4-5-7.bin)$ firmware/7937/\1 # 7940_7960 firmware (ancient) -ri ^(P0030801SR)(+\.bin)$ firmware/7940/\1 -ri ^(P0030801SR)(+\.loads)$ firmware/7940/\1 -ri ^(P0030801SR)(+\.sb2)$ firmware/7940/\1 -ri ^(P0030801SR)(+\.sbn)$ firmware/7940/\1 +ri ^(P0030801SR)(.+\.bin)$ firmware/7940/\1 +ri ^(P0030801SR)(.+\.loads)$ firmware/7940/\1 +ri ^(P0030801SR)(.+\.sb2)$ firmware/7940/\1 +ri ^(P0030801SR)(.+\.sbn)$ firmware/7940/\1 # 7941_7961 firmware (java-based) ri ^(apps41)(.+\.sbn)$ firmware/7941/\1\2 @@ -174,11 +174,11 @@ ri ^(ATA030204SCCP090202A.zup)$ firmware/ata186/\1 # Sub-Directory Handling # settings -ri ^(.+\.tlv)?$ settings/\1 -ri ^\/(.+\.tlv)?$ settings/\1 -ri ^((.+\.cnf.xml)(\.enc)?(\.sgn)?)$ settings/\1 -ri ^\/((.+\-cnf.xml)(\.enc)?(\.sgn)?)$ settings/\1 -ri ^\/((SPA504G-cfg.xml)(\.enc)?(\.sgn)?)$ settings/\1 +#ri ^(.+\.tlv)?$ settings/\1 +#ri ^\/(.+\.tlv)?$ settings/\1 +#ri ^((.+\.cnf.xml)(\.enc)?(\.sgn)?)$ settings/\1 +#ri ^\/((.+\-cnf.xml)(\.enc)?(\.sgn)?)$ settings/\1 +#ri ^\/((SPA504G-cfg.xml)(\.enc)?(\.sgn)?)$ settings/\1 # Keep firmware in a separate directory (optional) #ri ^(.+\.loads)$ firmware/\1 @@ -197,7 +197,7 @@ ri ^(.+)\/(.+-kate.xml)$ languages/\1/\2 # Keep ring-tones in a separate directory (optional) ri ^([R|r]ing[L|l]ist)(\.xml|-wb\.xml)(\.sgn)?$ ringtones/ringlist.xml ri ^(Distinctive[R|r]ing[L|l]ist)(\.xml|-wb\.xml)(\.sgn)?$ ringtones/ringlist.xml -ri ^(.+)(\.raw|\.rwb)(\.sgn)?$ ringtones/\1\2\3 +ri ^(.+)(\.raw|\.rwb|\.pcm)(\.sgn)?$ ringtones/\1\2\3 # Rename Desktops to wallpapers (optional) #ri ^Desktops/(.+)/(List\.xml)(\.sgn)?$ wallpapers/\1/\2\3 diff --git a/install.php b/install.php index eb2caa9..a7a4e3a 100644 --- a/install.php +++ b/install.php @@ -500,7 +500,7 @@ function InstallDB_sccpusers() { `pin` VARCHAR(7) NULL DEFAULT NULL, `password` VARCHAR(7) NULL DEFAULT NULL, `description` VARCHAR(45) NULL DEFAULT NULL, - `rouminglogin` ENUM('on','off','multi') NULL DEFAULT 'off', + `roaminglogin` ENUM('on','off','multi') NULL DEFAULT 'off', `devicegroup` VARCHAR(20) NULL DEFAULT 'all', `auto_logout` ENUM('on','off') NULL DEFAULT 'off', `homedevice` VARCHAR(20) NULL DEFAULT NULL, From 510935134b1f62165d1193b38ca306708a01ce4c Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Tue, 2 Apr 2019 14:57:57 +0300 Subject: [PATCH 005/100] - Change Version --- Sccp_manager.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 0cb91a2..bda0ece 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -93,7 +93,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { private $SCCP_LANG_DICTIONARY = 'be-sccp.jar'; // CISCO LANG file search in /tftp-path private $pagedata = null; private $sccp_driver_ver = '11.3'; // Ver fore SCCP.CLASS.PHP - public $sccp_manager_ver = '13.0.0.4'; + public $sccp_manager_ver = '13.0.0.4(M)'; private $tftpLang = array(); // private $hint_context = '@ext-local'; /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Get it from Config !!! private $hint_context = array('default' => '@ext-local'); /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Get it from Config !!! From ce3bee1341f6a4bc095ad29eaf905ef11c0d2e64 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 8 Apr 2019 16:46:18 +0300 Subject: [PATCH 006/100] - Change Db Code page --- install.php | 11 +++++++++-- module.xml | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/install.php b/install.php index a7a4e3a..c33f2b2 100644 --- a/install.php +++ b/install.php @@ -327,7 +327,9 @@ $sccp_compatible = 0; $db_config = ''; function CheckSCCPManagerDBTables($table_req) { - global $db; +global $amp_conf; +global $astman; + global $db; outn("
  • " . _("Checking for Sccp_manager database tables..") . "
  • "); foreach ($table_req as $value) { $check = $db->getRow("SELECT 1 FROM `$value` LIMIT 0", DB_FETCHMODE_ASSOC); @@ -545,7 +547,12 @@ function InstallDB_updateSchema($db_config) { if (!empty($tab_modify[$fld_id]['rename'])) { $fld_id_source = $tab_modify[$fld_id]['rename']; $db_config[$tabl_name][$fld_id_source]['status'] = 'yes'; - $db_config[$tabl_name][$fld_id]['create'] = $db_config[$tabl_name][$fld_id_source]['create']; + if (!empty($db_config[$tabl_name][$fld_id_source]['create'])) { + $db_config[$tabl_name][$fld_id]['create'] = $db_config[$tabl_name][$fld_id_source]['create']; + } else { + $db_config[$tabl_name][$fld_id]['create'] = strtoupper($tabl_data[1]).(($tabl_data[2] == 'NO') ?' NOT NULL': ' NULL'); + $db_config[$tabl_name][$fld_id]['create'] .= ' DEFAULT '. ((empty($tabl_data[4]))?'NULL': "'". $tabl_data[4]."'" ); + } } } } diff --git a/module.xml b/module.xml index 2aa6fd8..7491ec1 100644 --- a/module.xml +++ b/module.xml @@ -1,7 +1,7 @@ sccp_manager SCCP Manager - 13.0.0.4 + 13.0.0.4M setup SCCP Connectivity Alex GP @@ -19,7 +19,7 @@ - 13.0.0.1 + 13.0.0.1M https://github.com/PhantomVl/sccp_manager GPL From 8d8d45d2d96d4b8b90e3fe48d51309d55eaa363f Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Tue, 23 Apr 2019 13:32:52 +0300 Subject: [PATCH 007/100] - Create Cisco phone service for user mobility. --- Sccp_manager.class.php | 4 +- Sccp_manager.inc/dbinterface.class.php | 10 +- {!Readme.txt => Technical.note}/ATA.txt | 0 .../Conferencing.txt | 0 .../RedialMenu.txt | 0 .../SEP0000000000.cnf.xml_annotated | 0 {!Readme.txt => Technical.note}/SEPXML.txt | 0 .../backgroundImage.txt | 0 {!Readme.txt => Technical.note}/dialplan.txt | 0 {!Readme.txt => Technical.note}/freppbx.txt | 0 .../help.tftprewrite | 0 {!Readme.txt => Technical.note}/make_sccp.txt | 0 .../sccp.conf.annotated | 0 conf/sccpgeneral.xml.v433 | 2 +- install.php | 190 +++++++++--------- views/form.addruser.php | 2 +- views/hardware.phone.php | 5 +- 17 files changed, 108 insertions(+), 105 deletions(-) rename {!Readme.txt => Technical.note}/ATA.txt (100%) rename {!Readme.txt => Technical.note}/Conferencing.txt (100%) rename {!Readme.txt => Technical.note}/RedialMenu.txt (100%) rename {!Readme.txt => Technical.note}/SEP0000000000.cnf.xml_annotated (100%) rename {!Readme.txt => Technical.note}/SEPXML.txt (100%) rename {!Readme.txt => Technical.note}/backgroundImage.txt (100%) rename {!Readme.txt => Technical.note}/dialplan.txt (100%) rename {!Readme.txt => Technical.note}/freppbx.txt (100%) rename {!Readme.txt => Technical.note}/help.tftprewrite (100%) rename {!Readme.txt => Technical.note}/make_sccp.txt (100%) rename {!Readme.txt => Technical.note}/sccp.conf.annotated (100%) diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index bda0ece..be1ac21 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -1319,7 +1319,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { * */ $name_dev = ''; - $db_field = $this->dbinterface->get_db_SccpTableData("get_colums_sccpusers"); + $db_field = $this->dbinterface->get_db_SccpTableData("get_colums_sccpuser"); // $hw_id = (empty($get_settings['sccp_deviceid'])) ? 'new' : $get_settings['sccp_deviceid']; // $update_hw = ($hw_id == 'new') ? 'update' : 'clear'; $hw_prefix = 'SEP'; @@ -1394,7 +1394,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { // return $save_settings; // $update_hw = ($hw_id == 'new') ? 'update' : 'clear'; - $this->dbinterface->sccp_save_db("sccpusers", $save_settings, 'replace', 'name'); + $this->dbinterface->sccp_save_db("sccpuser", $save_settings, 'replace', 'name'); $save_buttons = $this-> get_buttons_phone($get_settings,$name_dev, 'sccpline'); // Sace Buttons config diff --git a/Sccp_manager.inc/dbinterface.class.php b/Sccp_manager.inc/dbinterface.class.php index 9cdcb0b..5be7aa3 100644 --- a/Sccp_manager.inc/dbinterface.class.php +++ b/Sccp_manager.inc/dbinterface.class.php @@ -56,8 +56,8 @@ class dbinterface { $sql = "DESCRIBE sccpdevice"; $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); break; - case "get_colums_sccpusers": - $sql = "DESCRIBE sccpusers"; + case "get_colums_sccpuser": + $sql = "DESCRIBE sccpuser"; $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); break; case "get_sccpdevice_byid": @@ -67,8 +67,8 @@ class dbinterface { . '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_sccpdusers": - $sql = "SELECT * FROM `sccpusers` "; + case "get_sccpuser": + $sql = "SELECT * FROM `sccpuser` "; if (!empty($data['id'])) { $sql .= 'WHERE name="' . $data['id'] . '" '; } @@ -173,7 +173,7 @@ class dbinterface { break; case 'sccpdevmodel': case 'sccpdevice': - case 'sccpusers': + case 'sccpuser': $sql_db = $db_name; $sql_key = ""; $sql_var = ""; diff --git a/!Readme.txt/ATA.txt b/Technical.note/ATA.txt similarity index 100% rename from !Readme.txt/ATA.txt rename to Technical.note/ATA.txt diff --git a/!Readme.txt/Conferencing.txt b/Technical.note/Conferencing.txt similarity index 100% rename from !Readme.txt/Conferencing.txt rename to Technical.note/Conferencing.txt diff --git a/!Readme.txt/RedialMenu.txt b/Technical.note/RedialMenu.txt similarity index 100% rename from !Readme.txt/RedialMenu.txt rename to Technical.note/RedialMenu.txt diff --git a/!Readme.txt/SEP0000000000.cnf.xml_annotated b/Technical.note/SEP0000000000.cnf.xml_annotated similarity index 100% rename from !Readme.txt/SEP0000000000.cnf.xml_annotated rename to Technical.note/SEP0000000000.cnf.xml_annotated diff --git a/!Readme.txt/SEPXML.txt b/Technical.note/SEPXML.txt similarity index 100% rename from !Readme.txt/SEPXML.txt rename to Technical.note/SEPXML.txt diff --git a/!Readme.txt/backgroundImage.txt b/Technical.note/backgroundImage.txt similarity index 100% rename from !Readme.txt/backgroundImage.txt rename to Technical.note/backgroundImage.txt diff --git a/!Readme.txt/dialplan.txt b/Technical.note/dialplan.txt similarity index 100% rename from !Readme.txt/dialplan.txt rename to Technical.note/dialplan.txt diff --git a/!Readme.txt/freppbx.txt b/Technical.note/freppbx.txt similarity index 100% rename from !Readme.txt/freppbx.txt rename to Technical.note/freppbx.txt diff --git a/!Readme.txt/help.tftprewrite b/Technical.note/help.tftprewrite similarity index 100% rename from !Readme.txt/help.tftprewrite rename to Technical.note/help.tftprewrite diff --git a/!Readme.txt/make_sccp.txt b/Technical.note/make_sccp.txt similarity index 100% rename from !Readme.txt/make_sccp.txt rename to Technical.note/make_sccp.txt diff --git a/!Readme.txt/sccp.conf.annotated b/Technical.note/sccp.conf.annotated similarity index 100% rename from !Readme.txt/sccp.conf.annotated rename to Technical.note/sccp.conf.annotated diff --git a/conf/sccpgeneral.xml.v433 b/conf/sccpgeneral.xml.v433 index f65b27e..e5df4aa 100644 --- a/conf/sccpgeneral.xml.v433 +++ b/conf/sccpgeneral.xml.v433 @@ -1584,7 +1584,7 @@ and open the template in the editor. Base Version before all crash :-) - pin + password Help! diff --git a/install.php b/install.php index c33f2b2..a9c3c71 100644 --- a/install.php +++ b/install.php @@ -16,7 +16,8 @@ global $amp_conf; global $astman; global $version; global $srvinterface; - +global $mobile_hw; +$mobile_hw = '0'; $class = "\\FreePBX\\Modules\\Sccp_manager\\srvinterface"; if (!class_exists($class, false)) { @@ -27,6 +28,7 @@ if (class_exists($class, false)) { } function Get_DB_config($sccp_compatible) { + global $mobile_hw; $db_config_v0 = array( 'sccpdevmodel' => array( 'enabled' => array('create' => "INT(2) NULL DEFAULT '0'"), @@ -220,6 +222,7 @@ function Get_DB_config($sccp_compatible) { ) ); + // Software mobile $db_config_v4 = array( 'sccpdevmodel' => array( 'enabled' => array('create' => "INT(2) NULL DEFAULT '0'"), @@ -304,10 +307,44 @@ function Get_DB_config($sccp_compatible) { 'echocancel' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), 'silencesuppression' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), 'dnd' => array('create' => "enum('off','reject','silent','user') NOT NULL default 'reject'", 'modify' => "enum('off','reject','silent','user')", 'def_modify' => "reject") + ), + 'sccpuser' => array( + 'name' => array('create' => "varchar(20) NOT NULL", 'modify' => "VARCHAR(20)" ), + 'pin' => array('create' => "varchar(7) NOT NULL", 'modify' => "VARCHAR(7)" ), + 'password' => array('create' => "varchar(7) NOT NULL", 'modify' => "VARCHAR(7)" ), + 'description' => array('create' => "varchar(45) NOT NULL", 'modify' => "VARCHAR(45)" ), + 'roaminglogin' => array('create' => "ENUM('on','off','multi') NULL DEFAULT 'off'", 'modify' => "ENUM('on','off','multi')" ), + 'auto_logout' => array('create' => "ENUM('on','off') NULL DEFAULT 'off'", 'modify' => "ENUM('on','off')" ), + 'homedevice' => array('create' => "varchar(20) NOT NULL", 'modify' => "VARCHAR(20)" ), + 'devicegroup' => array('create' => "varchar(7) NOT NULL", 'modify' => "VARCHAR(7)" ), + ) + ); +// Hardware Mobile. Can switch Softwate to Hardware + $db_config_v4M = array( + 'sccpdevmodel' => array( + 'loadinformationid' => array('create' => "VARCHAR(30) NULL DEFAULT NULL") + ), + 'sccpdevice' => array( + 'pickupexten' => array('drop' => "yes"), + 'directed_pickup' => array('drop' => "yes"), + '_description' => array('rename' => "description"), + '_loginname' => array('drop' => "yes"), + '_profileid' => array('drop' => "yes"), + + ), + 'sccpline' => array( + 'directed_pickup' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), + ), + 'sccpuser' => array( + 'id' => array('create' => "varchar(20) NOT NULL", 'modify' => "VARCHAR(20)" ), + 'name' => array('create' => "varchar(45) NOT NULL", 'modify' => "VARCHAR(45)" ), ) ); if ($sccp_compatible >= 433 ) { + if ($mobile_hw == '1') { + return $db_config_v4M; + } return $db_config_v4; } if ($sccp_compatible >= 430) { @@ -417,40 +454,6 @@ function InstallDB_Buttons() { if (db::IsError($check)) { die_freepbx("Can not create sccpbuttonconfig table, error:$check\n"); } -/* - } else { - $db_result = $db->getAll("SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE " - . "WHERE TABLE_SCHEMA = 'asterisk' AND TABLE_NAME = 'buttonconfig' AND REFERENCED_COLUMN_NAME IS NOT NULL;"); - - if (DB::IsError($db_result)) { - die_freepbx("Can not get informations TABLE_SCHEMA\n"); - } - - $sql = ''; - $sql = 'RENAME TABLE `buttonconfig` TO `sccpbuttonconfig`;'; - $sql .= "ALTER TABLE `sccpbuttonconfig` ADD COLUMN `user` VARCHAR(20) NOT NULL DEFAULT '' AFTER `device`;"; - $check = $db->query($sql); - if (db::IsError($check)) { - die_freepbx("Can not create sccpsettings table, error:$check\n"); - } - $sql = ''; - foreach ($db_result as $tabl_data) { - $fld_id = $tabl_data[2]; - if (!empty($fld_id)) { - $sql .= "ALTER TABLE `sccpbuttonconfig` DROP FOREIGN KEY `".$fld_id."`\n"; - } - } - - $sql .= "ALTER TABLE `sccpbuttonconfig` CHANGE COLUMN `device` `device` varchar(15) NULL default NULL"; - $sql .= "ALTER TABLE `sccpbuttonconfig` ADD FOREIGN KEY (device) REFERENCES sccpdevice(name) ON DELETE CASCADE;"; - - $check = $db->query($sql); - if (DB::IsError($db_result)) { - die_freepbx("Can not get drop old FOREIGN KEY \n"); - - } - } - */ return true; } @@ -494,10 +497,10 @@ function InstallDB_sccpdevmodel() { return true; } -function InstallDB_sccpusers() { +function InstallDB_sccpuser() { global $db; - outn("
  • " . _("Creating sccpusers table...") . "
  • "); - $sql = "CREATE TABLE IF NOT EXISTS `sccpusers` ( + outn("
  • " . _("Creating sccpuser table...") . "
  • "); + $sql = "CREATE TABLE IF NOT EXISTS `sccpuser` ( `name` VARCHAR(20) NULL DEFAULT NULL, `pin` VARCHAR(7) NULL DEFAULT NULL, `password` VARCHAR(7) NULL DEFAULT NULL, @@ -671,49 +674,26 @@ function InstallDB_createButtonConfigTrigger() { global $db; outn("
  • " . _("(Re)Create buttonconfig trigger") . "
  • "); $sql = "DROP TRIGGER IF EXISTS sccp_trg_buttonconfig;"; -/* $sql = "DELIMITER $$ -CREATE TRIGGER sccp_trg_buttonconfig BEFORE INSERT ON sccpbuttonconfig -FOR EACH ROW -BEGIN - IF NEW.`reftype` = 'sccpdevice' THEN - IF (SELECT COUNT(*) FROM `sccpdevice` WHERE `sccpdevice`.`name` = NEW.`ref` ) = 0 THEN - UPDATE `Foreign key contraint violated: ref does not exist in sccpdevice` SET x=1; + + $sql .= "CREATE TRIGGER `sccp_trg_buttonconfig` BEFORE INSERT ON `sccpbuttonconfig` FOR EACH ROW BEGIN + IF NEW.`reftype` = 'sccpdevice' THEN + IF (SELECT COUNT(*) FROM `sccpdevice` WHERE `sccpdevice`.`name` = NEW.`ref` ) = 0 THEN + UPDATE `Foreign key contraint violated: ref does not exist in sccpdevice` SET x=1; + END IF; END IF; - END IF; - IF NEW.`reftype` = 'sccpline' THEN - IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = NEW.`ref`) = 0 THEN - UPDATE `Foreign key contraint violated: ref does not exist in sccpline` SET x=1; + IF NEW.`reftype` = 'sccpline' THEN + IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = NEW.`ref`) = 0 THEN + UPDATE `Foreign key contraint violated: ref does not exist in sccpline` SET x=1; + END IF; END IF; - END IF; - IF NEW.`buttontype` = 'line' THEN - SET @line_x = SUBSTRING_INDEX(NEW.`name`,'!',1); - SET @line_x = SUBSTRING_INDEX(@line_x,'@',1); - IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = @line_x ) = 0 THEN - UPDATE `Foreign key contraint violated: line does not exist in sccpline` SET x=1; + IF NEW.`buttontype` = 'line' THEN + SET @line_x = SUBSTRING_INDEX(NEW.`name`,'!',1); + SET @line_x = SUBSTRING_INDEX(@line_x,'@',1); + IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = @line_x ) = 0 THEN + UPDATE `Foreign key contraint violated: line does not exist in sccpline` SET x=1; + END IF; END IF; - END IF; -END $$ -DELIMITER ;";*/ - $sql .= " - CREATE TRIGGER `sccp_trg_buttonconfig` BEFORE INSERT ON `sccpbuttonconfig` FOR EACH ROW BEGIN - IF NEW.`reftype` = 'sccpdevice' THEN - IF (SELECT COUNT(*) FROM `sccpdevice` WHERE `sccpdevice`.`name` = NEW.`ref` ) = 0 THEN - UPDATE `Foreign key contraint violated: ref does not exist in sccpdevice` SET x=1; - END IF; - END IF; - IF NEW.`reftype` = 'sccpline' THEN - IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = NEW.`ref`) = 0 THEN - UPDATE `Foreign key contraint violated: ref does not exist in sccpline` SET x=1; - END IF; - END IF; - IF NEW.`buttontype` = 'line' THEN - SET @line_x = SUBSTRING_INDEX(NEW.`name`,'!',1); - SET @line_x = SUBSTRING_INDEX(@line_x,'@',1); - IF (SELECT COUNT(*) FROM `sccpline` WHERE `sccpline`.`name` = @line_x ) = 0 THEN - UPDATE `Foreign key contraint violated: line does not exist in sccpline` SET x=1; - END IF; - END IF; - END"; + END;"; $check = $db->query($sql); if (DB::IsError($check)) { die_freepbx("Can not modify sccpdevice table\n"); @@ -775,22 +755,42 @@ function InstallDB_CreateSccpDeviceConfigView($sccp_compatible) { LEFT JOIN sccpbuttonconfig userbutton ON ( userbutton.ref = sccpdevice._loginname ) LEFT JOIN sccpline ON ( sccpline.name = sccpdevice._loginname) GROUP BY sccpdevice.name;"; -*/ - $sql = " - CREATE OR REPLACE - ALGORITHM = MERGE - VIEW sccpdeviceconfig AS - SELECT case sccpdevice._profileid - when 0 then - (select GROUP_CONCAT(CONCAT_WS( ',', defbutton.buttontype, defbutton.name, defbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as defbutton where defbutton.ref = sccpdevice.name ORDER BY defbutton.instance ) - when 1 then - (select GROUP_CONCAT(CONCAT_WS( ',', userbutton.buttontype, userbutton.name, userbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as userbutton where userbutton.ref = sccpdevice._loginname ORDER BY userbutton.instance ) - when 2 then - (select GROUP_CONCAT(CONCAT_WS( ',', homebutton.buttontype, homebutton.name, homebutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as homebutton where homebutton.ref = sccpusers.homedevice ORDER BY homebutton.instance ) - end as button, sccpdevice.*, if(sccpdevice._profileid = 0, sccpdevice._description, sccpusers.description) as description - FROM sccpdevice - LEFT JOIN sccpusers sccpusers ON ( sccpusers.name = sccpdevice._loginname ) - GROUP BY sccpdevice.name;"; +*/ + $sql = "DROP VIEW IF EXISTS `sccpdeviceconfig`; + DROP VIEW IF EXISTS `sccpuserconfig`;"; + /// global $hw_mobil; + + global $mobile_hw; + if ($mobile_hw == '1') { + $sql .= "CREATE OR REPLACE ALGORITHM = MERGE VIEW sccpdeviceconfig AS + SELECT GROUP_CONCAT( CONCAT_WS( ',', sccpbuttonconfig.buttontype, sccpbuttonconfig.name, sccpbuttonconfig.options ) + ORDER BY instance ASC SEPARATOR ';' ) AS sccpbutton, sccpdevice.* + FROM sccpdevice + LEFT JOIN sccpbuttonconfig ON (sccpbuttonconfig.reftype = 'sccpdevice' AND sccpbuttonconfig.ref = sccpdevice.name ) + GROUP BY sccpdevice.name; "; + $sql .= "CREATE OR REPLACE ALGORITHM = MERGE VIEW sccpuserconfig AS + SELECT GROUP_CONCAT( CONCAT_WS( ',', sccpbuttonconfig.buttontype, sccpbuttonconfig.name, sccpbuttonconfig.options ) + ORDER BY instance ASC SEPARATOR ';' ) AS button, sccpuser.* + FROM sccpuser + LEFT JOIN sccpbuttonconfig ON ( sccpbuttonconfig.reftype = 'sccpuser' AND sccpbuttonconfig.ref = sccpuser.id) + GROUP BY sccpuser.name; "; + + } else { + $sql .= "CREATE OR REPLACE + ALGORITHM = MERGE + VIEW sccpdeviceconfig AS + SELECT case sccpdevice._profileid + when 0 then + (select GROUP_CONCAT(CONCAT_WS( ',', defbutton.buttontype, defbutton.name, defbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as defbutton where defbutton.ref = sccpdevice.name ORDER BY defbutton.instance ) + when 1 then + (select GROUP_CONCAT(CONCAT_WS( ',', userbutton.buttontype, userbutton.name, userbutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as userbutton where userbutton.ref = sccpdevice._loginname ORDER BY userbutton.instance ) + when 2 then + (select GROUP_CONCAT(CONCAT_WS( ',', homebutton.buttontype, homebutton.name, homebutton.options ) SEPARATOR ';') from `sccpbuttonconfig` as homebutton where homebutton.ref = sccpuser.homedevice ORDER BY homebutton.instance ) + end as button, if(sccpdevice._profileid = 0, sccpdevice._description, sccpuser.description) as description, sccpdevice.* + FROM sccpdevice + LEFT JOIN sccpuser sccpuser ON ( sccpuser.name = sccpdevice._loginname ) + GROUP BY sccpdevice.name;"; + } } $results = $db->query($sql); if (DB::IsError($check)) { @@ -907,7 +907,7 @@ $sccp_db_ver = CheckSCCPManagerDBVersion(); // BackUp Old config CreateBackUpConfig(); -InstallDB_sccpusers(); +InstallDB_sccpuser(); InstallDB_Buttons(); InstallDB_sccpsettings(); diff --git a/views/form.addruser.php b/views/form.addruser.php index 43cd908..7e57120 100644 --- a/views/form.addruser.php +++ b/views/form.addruser.php @@ -11,7 +11,7 @@ $dev_new = null; if (!empty($_REQUEST['ru_id'])) { $dev_id = $_REQUEST['ru_id']; $def_val['id'] = array("keyword" => 'id', "data" => $dev_id, "seq" => "99"); - $db_res = $this->dbinterface->get_db_SccpTableData('get_sccpdusers', array("id" => $dev_id)); + $db_res = $this->dbinterface->get_db_SccpTableData('get_sccpuser', array("id" => $dev_id)); if (!empty($db_res) ) { foreach ($db_res as $key => $val) { if (!empty($val)) { diff --git a/views/hardware.phone.php b/views/hardware.phone.php index 0e0edcd..38fee97 100644 --- a/views/hardware.phone.php +++ b/views/hardware.phone.php @@ -32,7 +32,7 @@ - + @@ -73,6 +73,9 @@ } function LineFormatter(value, row, index) { + if (value === null) { + return '-- EMPTY --'; + } var data = value.split(";"); result = ''; for (var i = 0; i < data.length; i++) { From 47f92a0c5383744af778adb7ec856a35f64d703a Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Wed, 24 Apr 2019 13:38:51 +0300 Subject: [PATCH 008/100] - Bug fix, provision sccp --- Sccp_manager.inc/extconfigs.class.php | 2 +- contrib/index.cnf | 12 ++++++++++++ install.php | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 contrib/index.cnf diff --git a/Sccp_manager.inc/extconfigs.class.php b/Sccp_manager.inc/extconfigs.class.php index 3432c3b..2b1d79d 100644 --- a/Sccp_manager.inc/extconfigs.class.php +++ b/Sccp_manager.inc/extconfigs.class.php @@ -280,7 +280,7 @@ class extconfigs { if ($db_vars["tftp_rewrite"]["data"] == 'pro') { $adv_tree_mode = 'pro'; if (!empty($adv_ini)) { // something found in external conflicts - $adv_ini .= 'index.cnf'; + $adv_ini .= '/index.cnf'; if (file_exists($adv_ini)) { $adv_ini_array = parse_ini_file($adv_ini); $adv_config = array_merge($adv_config, $adv_ini_array); diff --git a/contrib/index.cnf b/contrib/index.cnf new file mode 100644 index 0000000..7bec03f --- /dev/null +++ b/contrib/index.cnf @@ -0,0 +1,12 @@ +[main] +debug = on ; The output in the browser window for more information +tftproot = /tftpboot +;default_language = English_United_States + +firmware = firmware +settings = /tftpboot +wallpapers = /tftpboot/Desktops +ringtones = ringtones +locales = locales +countries = countries +languages = /tftpboot/languages diff --git a/install.php b/install.php index a9c3c71..fbcfc27 100644 --- a/install.php +++ b/install.php @@ -805,6 +805,10 @@ function CreateBackUpConfig() { $backup_files = array('extconfig','extconfig','res_mysql', 'res_config_mysql','sccp'); $backup_ext = array('_custom.conf', '.conf'); $dir = $cnf_int->get('ASTETCDIR'); + + $filename = $dir.'/sccp_backup_'.date("Ymd").'.sql'; + $result = exec('mysqldump '.$amp_conf['AMPDBNAME'].' --password='.$amp_conf['AMPDBPASS'].' --user='.$amp_conf['AMPDBUSER'].' --single-transaction >'.$filename ,$output); + $zip = new \ZipArchive(); $filename = $dir . "/sccp_instal_backup" . date("Ymd"). ".zip"; if ($zip->open($filename, \ZIPARCHIVE::CREATE)) { From c23a69723446e2cf7cb251cae1839bff288d7fc2 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Wed, 24 Apr 2019 20:31:38 +0300 Subject: [PATCH 009/100] - Installation procedure, detect chan_sccp --- Sccp_manager.inc/srvinterface.class.php | 9 +++++++++ install.php | 23 +++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Sccp_manager.inc/srvinterface.class.php b/Sccp_manager.inc/srvinterface.class.php index eaf5664..0f4933b 100644 --- a/Sccp_manager.inc/srvinterface.class.php +++ b/Sccp_manager.inc/srvinterface.class.php @@ -195,6 +195,8 @@ class srvinterface { return 0; } switch ($res["vCode"]) { + case 0: + return 0; case 433: return 433; @@ -229,6 +231,10 @@ class srvinterface { $result = array(); $ast_out = $this->sccp_version(); $result["Version"] = $ast_out[0]; + if ($ast_out[0] == '-1') { + $result["vCode"] = 0; + return $result; + } $version_parts = explode(".", $ast_out[0]); $result["vCode"] = implode('', $version_parts); if (!empty($ast_out[1]) && $ast_out[1] == 'develop') { @@ -247,6 +253,9 @@ class srvinterface { private function sccp_version() { $ast_out = $this->sccp_core_commands(array('cmd' => 'get_version')); + if ( ($ast_out['Response'] == 'Error') || (strpos($ast_out['data'], 'No such command') != false) ) { + return array('-1'); + } if (preg_match("/Release.*\(/", $ast_out['data'], $matches)) { $ast_out = substr($matches[0], 9, -1); return explode(' ', $ast_out); diff --git a/install.php b/install.php index fbcfc27..4d908ce 100644 --- a/install.php +++ b/install.php @@ -802,12 +802,12 @@ function CreateBackUpConfig() { global $amp_conf; outn("
  • " . _("Create Config BackUp") . "
  • "); $cnf_int = \FreePBX::Config(); - $backup_files = array('extconfig','extconfig','res_mysql', 'res_config_mysql','sccp'); + $backup_files = array('extensions','extconfig','res_mysql', 'res_config_mysql','sccp'); $backup_ext = array('_custom.conf', '.conf'); $dir = $cnf_int->get('ASTETCDIR'); - $filename = $dir.'/sccp_backup_'.date("Ymd").'.sql'; - $result = exec('mysqldump '.$amp_conf['AMPDBNAME'].' --password='.$amp_conf['AMPDBPASS'].' --user='.$amp_conf['AMPDBUSER'].' --single-transaction >'.$filename ,$output); + $fsql = $dir.'/sccp_backup_'.date("Ymd").'.sql'; + $result = exec('mysqldump '.$amp_conf['AMPDBNAME'].' --password='.$amp_conf['AMPDBPASS'].' --user='.$amp_conf['AMPDBUSER'].' --single-transaction >'.$fsql ,$output); $zip = new \ZipArchive(); $filename = $dir . "/sccp_instal_backup" . date("Ymd"). ".zip"; @@ -819,10 +819,14 @@ function CreateBackUpConfig() { } } } + if (file_exists($fsql)) { + $zip->addFile($fsql); + } $zip->close(); } else { outn("
  • " . _("Error Create BackUp: ") . $filename ."
  • "); } + unlink($fsql); outn("
  • " . _("Create Config BackUp: ") . $filename ."
  • "); } @@ -905,14 +909,21 @@ CheckSCCPManagerDBTables($table_req); #CheckPermissions(); CheckAsteriskVersion(); $sccp_compatible = CheckChanSCCPCompatible(); +if ($sccp_compatible == 0) { +// die_freepbx('Chan Sccp not Found. Install it before continuing'); + outn("
    "); + outn("Chan Sccp not Found. Install it before continuing !"); + die(); +} $db_config = Get_DB_config($sccp_compatible); $sccp_db_ver = CheckSCCPManagerDBVersion(); // BackUp Old config CreateBackUpConfig(); - -InstallDB_sccpuser(); -InstallDB_Buttons(); +if ($sccp_compatible > 431) { + InstallDB_sccpuser(); + InstallDB_Buttons(); +} InstallDB_sccpsettings(); InstallDB_sccpdevmodel(); From fd57b885e65c1977d007f71c1060cb3c7f4ac211 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 6 May 2019 18:22:19 +0300 Subject: [PATCH 010/100] - Add Buton "Update Buton Labels". If you replace User nams, this functon Regenerate device labels --- Sccp_manager.class.php | 67 ++++++++++++++++++++++++++ Sccp_manager.inc/dbinterface.class.php | 46 ++++++++++++++++-- assets/js/sccp_manager.js | 14 +++++- contrib/rewrite.rules | 4 +- install.php | 3 +- views/form.buttons.php | 3 ++ views/hardware.phone.php | 3 ++ views/server.info.php | 57 ++++++++++++++++------ 8 files changed, 173 insertions(+), 24 deletions(-) diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index be1ac21..14cf855 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -106,6 +106,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { public $sccp_conf_init = array(); public $xml_data; public $class_error; //error construct + public $info_warning; public function __construct($freepbx = null) { if ($freepbx == null) { @@ -621,6 +622,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { case 'model_update': case 'model_add': case 'model_delete': + case 'update_button_label': case 'updateSoftKey': case 'deleteSoftKey': case 'delete_dialplan': @@ -646,6 +648,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->sccp_create_tftp_XML(); $res = $this->srvinterface->sccp_core_commands(array('cmd' => 'sccp_reload')); +// $res = $this->srvinterface->sccp_core_commands(array('cmd' => 'restart_phone')); $msg = 'Config Saved: ' . $res['Response'] . '. Info :' . $res['data']; // needreload(); // !TODO!: It is necessary in the future to check, and replace all server responses on correct messages. Use _(msg) @@ -755,6 +758,24 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return array('status' => true, 'message' => 'Reset command send ' . $msg, 'reload' => true); // } break; + case 'update_button_label': + $msg = ''; + $hw_list = array(); +// return array('status' => false, 'message' => 'update_button_label send ' . $msg, 'reload' => false); + if (!empty($request['name'])) { + foreach ($request['name'] as $idv) { + if (!(strpos($idv, 'SEP') === false)) { + $hw_list[] = array('name' => $idv); + } + if ($idv == 'all') { + } + } + } + $res = $this->sccp_db_update_butons($hw_list); + $msg .= $res['Response'] . ' raw: ' . $res['data'] . ' '; +// !TODO!: It is necessary in the future to check, and replace all server responses on correct messages. Use _(msg) + return array('status' => true, 'message' => 'Update Butons Labels Complite ' . $msg, 'reload' => true); + case 'model_add': $save_settings = array(); $key_name = array('model', 'vendor', 'dns', 'buttons', 'loadimage', 'loadinformationid', 'nametemplate'); @@ -1792,6 +1813,52 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return $errors; } + /* + * Update Butons Labels on mysql DB + * + */ + private function sccp_db_update_butons($hw_list = array()) { + + $save_buttons = array(); + if (!empty($hw_list)) { + $buton_list = array(); + foreach ($hw_list as $value) { + $buton_tmp =$this->dbinterface->get_db_SccpTableData("get_sccpdevice_buttons", array('buttontype'=>'speeddial','id'=>$value['name'])); +// die(print_r($buton_tmp,1)); + if (!empty($buton_tmp)) { + $buton_list = array_merge($buton_list, $buton_tmp); + } + } + } else { + $buton_list = $this->dbinterface->get_db_SccpTableData("get_sccpdevice_buttons", array('buttontype'=>'speeddial')); + } +// die(print_r($buton_list,1)); + if (empty($buton_list)) { + return array('Response'=> ' Found 0 device ', 'data'=> ''); + } + $copy_fld = array('ref','reftype','instance','buttontype'); + $user_list = $user_list = $this->dbinterface->get_db_SccpTableByID("SccpExtension",Array(),'name'); + foreach ($buton_list as $value) { + $btn_opt = explode(',',$value['options']); + $btn_id = $btn_opt[0]; + if (!empty($user_list[$btn_id])){ + if ($user_list[$btn_id]['label'] != $value['name']) { + $btn_data['name'] = $user_list[$btn_id]['label']; + foreach ($copy_fld as $ckey) { + $btn_data[$ckey] = $value[$ckey]; + } + $save_buttons[] = $btn_data; + } + + } + } + if (empty($save_buttons)) { + return array('Response'=> 'No update required', 'data'=> ' 0 - records '); + } + $res = $this->dbinterface->sccp_save_db("sccpbuttons", $save_buttons, 'replace', '',''); + return array('Response'=> 'Update records :'.count($save_buttons),'data'=>$res); + } + /* * Save Config Value to mysql DB * sccp_db_save_setting(empty) - Save All settings from $sccpvalues diff --git a/Sccp_manager.inc/dbinterface.class.php b/Sccp_manager.inc/dbinterface.class.php index 5be7aa3..ee0bb0e 100644 --- a/Sccp_manager.inc/dbinterface.class.php +++ b/Sccp_manager.inc/dbinterface.class.php @@ -26,6 +26,18 @@ class dbinterface { /* * Core Access Function */ + public function get_db_SccpTableByID($dataid, $data = array(), $indexField = '') { + $resut = array(); + $raw = $this->get_db_SccpTableData($dataid, $data); + if ( empty($raw) || empty($indexField)) { + return $raw; + } + foreach ($raw as $value) { + $id = $value[$indexField]; + $resut[$id] = $value; + } + return $resut; + } public function get_db_SccpTableData($dataid, $data = array()) { if ($dataid == '') { @@ -76,8 +88,19 @@ class dbinterface { $raw_settings = sql($sql, "getRow", DB_FETCHMODE_ASSOC); break; case "get_sccpdevice_buttons": - $sql = 'SELECT * FROM sccpbuttonconfig WHERE ref="' . $data['id'] . '" ORDER BY `instance`;'; - $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + $sql = ''; + if (!empty($data['buttontype'])) { + $sql .= 'buttontype="' . $data['buttontype'] . '" '; + } + if (!empty($data['id'])) { + $sql .= (empty($sql)) ? 'ref="' . $data['id'] . '" ' : 'and ref="' . $data['id'] . '" '; + } + if (!empty($sql)) { + $sql = 'SELECT * FROM sccpbuttonconfig WHERE ' .$sql. 'ORDER BY `instance`;'; + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + } else { + $raw_settings = Array(); + } break; } @@ -90,6 +113,12 @@ class dbinterface { return $raw_settings; } + public function get_db_sysvalues() { + $sql = "SHOW VARIABLES LIKE '%group_concat%'"; + $raw_settings = sql($sql, "getRow", DB_FETCHMODE_ASSOC); + return $raw_settings; + } + /* * Get Sccp Device Model information */ @@ -213,11 +242,20 @@ class dbinterface { if ($mode == 'delete') { break; } - if (!empty($save_value)) { + if (empty($save_value)) { + break; + } + if ($mode == 'replace') { + $sql = 'UPDATE `sccpbuttonconfig` SET `name`=? WHERE `ref`= ? AND `reftype`=? AND `instance`=? AND `buttontype`=?;'; +// $sql = 'INSERT INTO `sccpbuttonconfig` (`ref`, `reftype`,`instance`, `buttontype`, `name`, `options`) VALUES (?,?,?,?,?,?);'; +// die(print_r($save_value,1)); + $stmt = $db->prepare($sql); + $result= $db->executeMultiple($stmt, $save_value); + } else { $sql = 'INSERT INTO `sccpbuttonconfig` (`ref`, `reftype`,`instance`, `buttontype`, `name`, `options`) VALUES (?,?,?,?,?,?);'; // die(print_r($save_value,1)); $stmt = $db->prepare($sql); - $res = $db->executeMultiple($stmt, $save_value); + $result = $db->executeMultiple($stmt, $save_value); } break; diff --git a/assets/js/sccp_manager.js b/assets/js/sccp_manager.js index 36bec58..81640b4 100644 --- a/assets/js/sccp_manager.js +++ b/assets/js/sccp_manager.js @@ -601,16 +601,26 @@ $(document).ready(function () { } } - if ($(this).data('id') === 'reset_dev' || $(this).data('id') === 'reset_token') { + if ($(this).data('id') === 'reset_dev' || $(this).data('id') === 'reset_token' || $(this).data('id') === 'update_button_label' ) { var dev_cmd = $(this).data('id'); var datas = ''; var i = 0; + var conf_msg = '??????'; + if ($(this).data('id') === 'reset_dev') { + conf_msg = 'Reset All device ?'; + } + if ($(this).data('id') === 'reset_token') { + conf_msg = 'Reset Token on All device ?'; + } + if ($(this).data('id') === 'update_button_label') { + conf_msg = 'Update Butons Labels on All device ?'; + } $('table').bootstrapTable('getSelections').forEach(function (entry) { datas = datas + 'name[' + i + ']=' + entry['name'] + '&'; i++; }); if (datas === '') { - if (confirm('Resaet All device')) { + if (confirm(conf_msg)) { datas = 'name[0]=all'; } else { dev_cmd = ''; diff --git a/contrib/rewrite.rules b/contrib/rewrite.rules index 7e3bbed..d8edaf3 100644 --- a/contrib/rewrite.rules +++ b/contrib/rewrite.rules @@ -185,8 +185,8 @@ ri ^(ATA030204SCCP090202A.zup)$ firmware/ata186/\1 #ri ^(.+\.sbn)$ firmware/\1 # Keep locales in a separate directory (optional) -ri ^(.+)\/(.+-sccp.jar)$ locales/\1/\2 -ri ^(.+)\/(.+-dictionary.xml)$ locales/\1/\2 +ri ^(.+)\/(.+-sccp.jar)$ languages/\1/\2 +ri ^(.+)\/(.+-dictionary.xml)$ languages/\1/\2 ri ^(.+)\/(.+-dictionary-ext.xml)$ languages/\1/\2 ri ^(.+)\/(.+-tones.xml)$ languages/\1/\2 ri ^(.+)\/(.+-font.xml)$ languages/\1/\2 diff --git a/install.php b/install.php index 4d908ce..8d00870 100644 --- a/install.php +++ b/install.php @@ -266,6 +266,7 @@ function Get_DB_config($sccp_compatible) { 'video_tos' => array('def_modify' => "0x88"), 'video_cos' => array('def_modify' => "5"), 'trustphoneip' => array('drop' => "yes"), + 'transfer_on_hangup' => array('create' => "enum('on','off') NULL DEFAULT NULL", 'modify' => "enum('on','off')"), 'phonecodepage' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL', 'modify' => "VARCHAR(50)"), 'mwilamp' => array('create' => "enum('on','off','wink','flash','blink') NULL default 'on'", 'modify' => "enum('on','off','wink','flash','blink')"), 'mwioncall' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), @@ -330,7 +331,7 @@ function Get_DB_config($sccp_compatible) { '_description' => array('rename' => "description"), '_loginname' => array('drop' => "yes"), '_profileid' => array('drop' => "yes"), - + 'transfer_on_hangup' => array('create' => "enum('on','off') NULL DEFAULT NULL", 'modify' => "enum('on','off')"), ), 'sccpline' => array( 'directed_pickup' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), diff --git a/views/form.buttons.php b/views/form.buttons.php index 5cf70b7..acae18d 100644 --- a/views/form.buttons.php +++ b/views/form.buttons.php @@ -254,3 +254,6 @@ if (!empty($_REQUEST['ru_id'])) {
    +
    +

    +
    diff --git a/views/hardware.phone.php b/views/hardware.phone.php index 38fee97..36eaade 100644 --- a/views/hardware.phone.php +++ b/views/hardware.phone.php @@ -21,6 +21,9 @@ + diff --git a/views/server.info.php b/views/server.info.php index abfec8c..bf64082 100644 --- a/views/server.info.php +++ b/views/server.info.php @@ -30,6 +30,9 @@ $info['dbinterface'] = $this->dbinterface->info(); $info['aminterface'] = $this->aminterface->info(); $db_Schema = $this->dbinterface->validate(); +$mysql_info = $this->dbinterface->get_db_sysvalues(); + + $info['XML'] = $this->xmlinterface->info(); $info['sccp_class'] = $driver['sccp']; $info['Core_sccp'] = array('Version' => $core['Version'], 'about'=> 'Sccp ver.'. $core['Version'].' r'.$core['vCode']. ' Revision :'. $core['RevisionNum']. ' Hash :'. $core['RevisionHash']); @@ -89,30 +92,27 @@ if (empty($conf_realtime)) { if (!empty($rt_info)) { $info['ConfigsRealTime'] = array('Version' => 'Error', 'about'=> $rt_info); } +} +// $mysql_info +if ($mysql_info['Value'] <= '2000') { + $this->info_warning['MySql'] = Array('Increase Mysql Group Concat Max. Length','Step 1: Go to mysql path
    nano /etc/my.cnf', + 'Step 2: And add the following line below [mysqld] as shown below
    [mysql]
    group_concat_max_len = 4096 or more', + 'Step 3: Save and restart
    systemctl restart mariadb.service
    Or
    service mysqld restart'); } //global $amp_conf; // ************************************************************************************ -print_r("
    Request:
    ");
    - $json = '';
    +$buton_list = $this->dbinterface->get_db_SccpTableData("get_sccpdevice_buttons", array('buttontype'=>'speeddial'));
    +$user_list = $this->dbinterface->get_db_SccpTableByID("SccpExtension",Array(),'name');
    +
    +print_r("
    Help Info:
    ");
      print_r("
    "); -// print_r($conf_realtime); + //print_r($buton_list); print_r("
    "); + print_r($user_list); print_r("
    "); // print_r("DIRECT START"); // print_r($this->sccpvalues['ccm_address']); //print_r($this->get_php_classes('\\FreePBX\\modules\\')); -/* - print_r(get_declared_classes()); - print_r($this->aminterface->open()); - - - print_r($this->aminterface->_error); - print_r("
    "); - - */ - - - //print_r($this->dbinterface->get_db_SccpTableData('SccpExtension')); // print_r($this->srvinterface->getеtestChanSCCP_GlablsInfo()); // $test_data = $this->srvinterface-> astman_GetRaw('ExtensionStateList'); @@ -134,6 +134,33 @@ print_r("
    Request:
    ");
     
     //print_r($this->dbinterface->info());
     
    + if (!empty($this->info_warning)) {
    +    ?>    
    +    
    +
    +
    +

    Sccp Manager Warning

    +
    +
    There are Warning in the SCCP Module:
    +                        info_warning as $key => $value) {
    +                                echo '

    '.$key.'

    '; + if (is_array($value)) { + echo '
  • '.implode('
  • ',$value).'
  • '; + } else { + echo '
  • '.$value.'
  • '; + } + } + ?> +
    +

    Check these problems before continuing to work.


    +
    +
    +
    +
    +
    +class_error)) { ?>
    From 14ff3d74c2cd3bff8d9c76404ea68947b72ff807 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Tue, 7 May 2019 11:12:39 +0300 Subject: [PATCH 011/100] - Add Buton "Update Buton Labels". If you replace User nams, this functon Regenerate device labels --- views/server.info.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/views/server.info.php b/views/server.info.php index bf64082..768960a 100644 --- a/views/server.info.php +++ b/views/server.info.php @@ -22,8 +22,9 @@ foreach ($ast_realtime as $key => $value) { } } } -$conf_realtime = $this->extconfigs->validate_RealTime($ast_realm); $info = array(); + +$conf_realtime = $this->extconfigs->validate_RealTime($ast_realm); $info['srvinterface'] = $this->srvinterface->info(); $info['extconfigs'] = $this->extconfigs->info(); $info['dbinterface'] = $this->dbinterface->info(); @@ -101,9 +102,7 @@ if ($mysql_info['Value'] <= '2000') { } //global $amp_conf; // ************************************************************************************ -$buton_list = $this->dbinterface->get_db_SccpTableData("get_sccpdevice_buttons", array('buttontype'=>'speeddial')); -$user_list = $this->dbinterface->get_db_SccpTableByID("SccpExtension",Array(),'name'); - +/* print_r("
    Help Info:
    ");
      print_r("
    "); //print_r($buton_list); @@ -124,7 +123,7 @@ print_r("
    Help Info:
    ");
     //  print_r($this->srvinterface->t_get_meta_data());
     //  print_r($this->sccp_metainfo);
      print("
    "); - +*/ // ************************************************************************************ // $lang_arr = $this->extconfigs->getextConfig('sccp_lang','sk_SK'); From 8bfc08beaaf76f231917d129b8db97a06f35f115 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Sat, 18 May 2019 11:34:32 +0300 Subject: [PATCH 012/100] - Bug Fix --- Sccp_manager.inc/srvinterface.class.php | 2 +- views/formShow.php | 37 ++++++++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Sccp_manager.inc/srvinterface.class.php b/Sccp_manager.inc/srvinterface.class.php index 0f4933b..589ae86 100644 --- a/Sccp_manager.inc/srvinterface.class.php +++ b/Sccp_manager.inc/srvinterface.class.php @@ -37,7 +37,7 @@ class srvinterface { public function sccp_core_commands($params = array()) { global $astman; $cmd_list = array('get_softkey' => array('cmd' => "sccp show softkeyssets", 'param' => ''), - 'get_version' => array('cmd' => "sccp show version", 'param' => ''), + 'get_version' => array('cmd' => "sccp show version", 'param' => ''), 'get_device' => array('cmd' => "sccp show devices", 'param' => ''), 'get_dev_info' => array('cmd' => "sccp show device", 'param' => 'name'), 'get_hints' => array('cmd' => "core show hints", 'param' => ''), diff --git a/views/formShow.php b/views/formShow.php index 4e6fda8..35cfeb2 100644 --- a/views/formShow.php +++ b/views/formShow.php @@ -35,7 +35,9 @@ $time_zone = array('-12' => 'GTM -12', '-11' => 'GTM -11', '-10' => 'GTM -10', ' '04' => 'GTM +4', '05' => 'GTM +5', '06' => 'GTM +6', '07' => 'GTM +7', '08' => 'GTM +8', '09' => 'GTM +9', '10' => 'GTM +10', '11'=> 'GTM +11', '12' => 'GTM +12'); -$time_zone_name = \FreePBX::Sccp_manager()-> extconfigs-> getextConfig('cisco_timezone'); +$time_zone_name = array(); + +//$time_zone_name = \FreePBX::Sccp_manager()-> extconfigs-> getextConfig('cisco_timezone'); //$time_zone = \FreePBX::Sccp_manager()-> extconfigs-> getextConfig('cisco_time'); //$system_time_zone = \FreePBX::Sccp_manager()->getSysnemTimeZone(); //print_r($metainfo); @@ -53,13 +55,17 @@ if (function_exists('music_list')){ if (!is_array($moh_list)){ $moh_list = array('default'); } -$sofkey_list = \FreePBX::Sccp_manager()-> srvinterface -> sccp_list_keysets(); -$model_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWDevice"); -$extension_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWextension"); -$device_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("SccpDevice"); +$sofkey_list = array(); +$model_list = array(); +$extension_list = array(); +$device_list = array(); -$extension_list[]=array(model=>'NONE', vendor=>'CISCO', dns=>'0'); -$device_list[]=array(name=>'NONE', description=>'No Device'); +//$sofkey_list = \FreePBX::Sccp_manager()-> srvinterface -> sccp_list_keysets(); +// $model_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWDevice"); +//$extension_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWextension"); +//$device_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("SccpDevice"); +//$extension_list[]=array(model=>'NONE', vendor=>'CISCO', dns=>'0'); +//$device_list[]=array(name=>'NONE', description=>'No Device'); $items = $itm -> children(); @@ -420,6 +426,9 @@ foreach ($items as $child) { $select_opt= $moh_list; } if ($child['type'] == 'SLK') { + if (empty($sofkey_list)) { + $sofkey_list = \FreePBX::Sccp_manager()-> srvinterface -> sccp_list_keysets(); + } $select_opt= $sofkey_list; } // if ($child['type'] == 'SLZ') { @@ -484,6 +493,9 @@ foreach ($items as $child) { $select_opt= $tftp_lang; } if ($child['type'] == 'SLZN') { + if (empty($time_zone_name)) { + $time_zone_name = \FreePBX::Sccp_manager()-> extconfigs-> getextConfig('cisco_timezone'); + } $select_opt= $time_zone_name; } if ($child['type'] == 'SLZ') { @@ -637,12 +649,23 @@ foreach ($items as $child) { $child->class = 'form-control'; } if ($child['type'] == 'SDM') { + if (empty($model_list)) { + $model_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWDevice"); + } $select_opt= $model_list; } if ($child['type'] == 'SDE') { + if (empty($extension_list)) { + $extension_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWextension"); + $extension_list[]=array(model=>'NONE', vendor=>'CISCO', dns=>'0'); + } $select_opt= $extension_list; } if ($child['type'] == 'SDD') { + if (empty($device_list)) { + $device_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("SccpDevice"); + $device_list[]=array(name=>'NONE', description=>'No Device'); + } $select_opt = $device_list; } From cf54bb400a0022f97596c37f90cc44fbd8b57300 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Wed, 22 May 2019 08:47:28 +0300 Subject: [PATCH 013/100] - Bug Fix --- Sccp_manager.inc/extconfigs.class.php | 2 +- views/formShow.php | 21 ++++++------ views/server.info.php | 48 +++++++++++++-------------- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/Sccp_manager.inc/extconfigs.class.php b/Sccp_manager.inc/extconfigs.class.php index 2b1d79d..5220621 100644 --- a/Sccp_manager.inc/extconfigs.class.php +++ b/Sccp_manager.inc/extconfigs.class.php @@ -255,7 +255,7 @@ class extconfigs { } if (empty($base_config["tftp_path"])) { if (!empty($this->paren_class)) { - $this->paren_class->class_error['tftp_path'] = 'Tftp path not defined'; + $this->paren_class->class_error['tftp_path'] = 'Tftp path not exist or not defined'; } return array('error' => 'empty tftp_path'); } diff --git a/views/formShow.php b/views/formShow.php index 35cfeb2..5f4cb46 100644 --- a/views/formShow.php +++ b/views/formShow.php @@ -36,10 +36,21 @@ $time_zone = array('-12' => 'GTM -12', '-11' => 'GTM -11', '-10' => 'GTM -10', ' '08' => 'GTM +8', '09' => 'GTM +9', '10' => 'GTM +10', '11'=> 'GTM +11', '12' => 'GTM +12'); $time_zone_name = array(); +$extension_list = array(); +$sofkey_list = array(); +$model_list = array(); +$device_list = array(); //$time_zone_name = \FreePBX::Sccp_manager()-> extconfigs-> getextConfig('cisco_timezone'); //$time_zone = \FreePBX::Sccp_manager()-> extconfigs-> getextConfig('cisco_time'); //$system_time_zone = \FreePBX::Sccp_manager()->getSysnemTimeZone(); +//$sofkey_list = \FreePBX::Sccp_manager()-> srvinterface -> sccp_list_keysets(); +//$model_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWDevice"); +//$extension_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWextension"); +//$device_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("SccpDevice"); +//$extension_list[]=array(model=>'NONE', vendor=>'CISCO', dns=>'0'); +//$device_list[]=array(name=>'NONE', description=>'No Device'); + //print_r($metainfo); if (\FreePBX::Modules()->checkStatus("soundlang")) { @@ -55,17 +66,7 @@ if (function_exists('music_list')){ if (!is_array($moh_list)){ $moh_list = array('default'); } -$sofkey_list = array(); -$model_list = array(); -$extension_list = array(); -$device_list = array(); -//$sofkey_list = \FreePBX::Sccp_manager()-> srvinterface -> sccp_list_keysets(); -// $model_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWDevice"); -//$extension_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("HWextension"); -//$device_list = \FreePBX::Sccp_manager()->dbinterface->get_db_SccpTableData("SccpDevice"); -//$extension_list[]=array(model=>'NONE', vendor=>'CISCO', dns=>'0'); -//$device_list[]=array(name=>'NONE', description=>'No Device'); $items = $itm -> children(); diff --git a/views/server.info.php b/views/server.info.php index 768960a..42f3406 100644 --- a/views/server.info.php +++ b/views/server.info.php @@ -4,10 +4,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -// vim: set ai ts=4 sw=4 ft=phtml: -// print_r($this->sccp_conf_init); -// print_r($this->sccpvalues); -//print_r('

    '); + $driver = $this->FreePBX->Core->getAllDriversInfo(); $core = $this->srvinterface->getSCCPVersion(); @@ -22,22 +19,23 @@ foreach ($ast_realtime as $key => $value) { } } } -$info = array(); -$conf_realtime = $this->extconfigs->validate_RealTime($ast_realm); +$conf_realtime = $this->extconfigs->validate_RealTime($ast_realm); +$db_Schema = $this->dbinterface->validate(); +$mysql_info = $this->dbinterface->get_db_sysvalues(); +$compatable = $this->srvinterface->get_compatible_sccp(); +$info = array(); + $info['srvinterface'] = $this->srvinterface->info(); -$info['extconfigs'] = $this->extconfigs->info(); -$info['dbinterface'] = $this->dbinterface->info(); -$info['aminterface'] = $this->aminterface->info(); -$db_Schema = $this->dbinterface->validate(); - -$mysql_info = $this->dbinterface->get_db_sysvalues(); +$info['extconfigs'] = $this->extconfigs->info(); +$info['dbinterface'] = $this->dbinterface->info(); +$info['aminterface'] = $this->aminterface->info(); +$info['XML'] = $this->xmlinterface->info(); +$info['sccp_class'] = $driver['sccp']; +$info['Core_sccp'] = array('Version' => $core['Version'], 'about'=> 'Sccp ver.'. $core['Version'].' r'.$core['vCode']. ' Revision :'. $core['RevisionNum']. ' Hash :'. $core['RevisionHash']); +$info['Asterisk'] = array('Version' => FreePBX::Config()->get('ASTVERSION'), 'about'=> 'Asterisk.'); -$info['XML'] = $this->xmlinterface->info(); -$info['sccp_class'] = $driver['sccp']; -$info['Core_sccp'] = array('Version' => $core['Version'], 'about'=> 'Sccp ver.'. $core['Version'].' r'.$core['vCode']. ' Revision :'. $core['RevisionNum']. ' Hash :'. $core['RevisionHash']); -$info['Asterisk'] = array('Version' => FreePBX::Config()->get('ASTVERSION'), 'about'=> 'Asterisk.'); if (!empty($this->sccpvalues['SccpDBmodel'])) { $info['DB Model'] = array('Version' => $this->sccpvalues['SccpDBmodel']['data'], 'about'=> 'SCCP DB Configure'); } @@ -48,16 +46,16 @@ if (!empty($this->sccpvalues['tftp_rewrite'])) { $info['TFTP_Rewrite'] = array('Version' => 'base', 'about'=> 'Rewrite Supported'); } } -$info['Сompatible'] = array('Version' => $this->srvinterface->get_compatible_sccp(), 'about'=> 'Ok'); +$info['Сompatible'] = array('Version' => $compatable, 'about'=> 'Ok'); if (!empty($this->sccpvalues['SccpDBmodel'])) { - if ($this->srvinterface->get_compatible_sccp()> $this->sccpvalues['SccpDBmodel']['data']){ + if ($compatable > $this->sccpvalues['SccpDBmodel']['data']){ $info['Сompatible']['about'] = '
    Reinstall SCCP manager required
    '; } } if ($db_Schema == 0) { $info['DB_Schema'] = array('Version' => 'Error', 'about'=> '
    ERROR DB Version
    '); } else { - $info['DB_Schema'] = array('Version' => $db_Schema, 'about'=> (($this->srvinterface->get_compatible_sccp() == $db_Schema ) ? 'Ok' : 'Incompatable Version')); + $info['DB_Schema'] = array('Version' => $db_Schema, 'about'=> (($compatable == $db_Schema ) ? 'Ok' : 'Incompatable Version')); } if (empty($ast_realtime)) { @@ -69,7 +67,7 @@ if (empty($ast_realtime)) { if ($key == $ast_realm) { if ($value['status'] == 'OK') { $rt_sccp = 'TEST OK'; - $rt_info .= 'SCCP conettions found'; + $rt_info .= 'SCCP Connections found'; } else { $rt_sccp = 'SCCP ERROR'; $rt_info .= '
    Error : '. $value['message']. '
    '; @@ -145,9 +143,9 @@ print_r("
    Help Info:
    ");
                                 foreach ($this->info_warning as $key => $value) {
                                     echo '

    '.$key.'

    '; if (is_array($value)) { - echo '
  • '.implode('
  • ',$value).'
  • '; + echo '
  • '.implode('
  • ', $value).'
  • '; } else { - echo '
  • '.$value.'
  • '; + echo '
  • '. _($value).'
  • '; } } ?> @@ -165,13 +163,13 @@ if (!empty($this->class_error)) {
    -

    Sccp Manager Error

    +

    Diagnostic information about SCCP Manager errors

    -
    There are Error in the SCCP Module:
    +                    
    There is an error in the :
                             class_error); ?>
                         

    Correct these problems before continuing to work.
    -

    Open 'SCCP Conectivity -> Server Config' to change global settings


    +

    Open 'SCCP Connectivity' -> Server Config' to change global settings


    From aadd1deb5b21afe7af7f1c7a3498a5569570440e Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Wed, 29 May 2019 20:47:15 +0300 Subject: [PATCH 014/100] - Remove spaces and special characters from the name Softkey --- Sccp_manager.class.php | 2 +- views/server.info.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 14cf855..9ff4fa2 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -845,7 +845,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { break; case 'updateSoftKey': if (!empty($request['id'])) { - $id_name = $request['id']; + $id_name = preg_replace('/[^A-Za-z0-9]/', '', $request['id']); $this->sccp_conf_init[$id_name]['type'] = "softkeyset"; foreach ($this->extconfigs->getextConfig('keyset') as $keyl => $vall) { if (!empty($request[$keyl])) { diff --git a/views/server.info.php b/views/server.info.php index 42f3406..8f3e123 100644 --- a/views/server.info.php +++ b/views/server.info.php @@ -143,7 +143,7 @@ print_r("
    Help Info:
    ");
                                 foreach ($this->info_warning as $key => $value) {
                                     echo '

    '.$key.'

    '; if (is_array($value)) { - echo '
  • '.implode('
  • ', $value).'
  • '; + echo '
  • '._(implode('
  • ', $value)).'
  • '; } else { echo '
  • '. _($value).'
  • '; } From a8af9a32fcbf94cb6e2117eea6be1e8f00c8bbf5 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 8 Jul 2019 15:43:18 +0300 Subject: [PATCH 015/100] - Remove sccp_extensions.conf - Remove sccp_hardware.conf --- install.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/install.php b/install.php index 8d00870..c1936f6 100644 --- a/install.php +++ b/install.php @@ -803,7 +803,7 @@ function CreateBackUpConfig() { global $amp_conf; outn("
  • " . _("Create Config BackUp") . "
  • "); $cnf_int = \FreePBX::Config(); - $backup_files = array('extensions','extconfig','res_mysql', 'res_config_mysql','sccp'); + $backup_files = array('extensions','extconfig','res_mysql', 'res_config_mysql','sccp','sccp_hardware','sccp_extensions'); $backup_ext = array('_custom.conf', '.conf'); $dir = $cnf_int->get('ASTETCDIR'); @@ -831,6 +831,22 @@ function CreateBackUpConfig() { outn("
  • " . _("Create Config BackUp: ") . $filename ."
  • "); } +function RenameConfig() { + global $amp_conf; + outn("
  • " . _("Move Old Config") . "
  • "); + $cnf_int = \FreePBX::Config(); + $rename_files = array('sccp_hardware','sccp_extensions'); + $rename_ext = array('_custom.conf', '.conf'); + $dir = $cnf_int->get('ASTETCDIR'); + foreach ($rename_files as $file) { + foreach ($rename_ext as $b_ext) { + if (file_exists($dir . '/'.$file . $b_ext)) { + rename($dir . '/'.$file . $b_ext, $dir . '/'.$file . $b_ext.'.old'); + } + } + } +} + function Setup_RealTime() { global $amp_conf; outn("
  • " . _("Pre config RealTime") . "
  • "); @@ -921,6 +937,7 @@ $sccp_db_ver = CheckSCCPManagerDBVersion(); // BackUp Old config CreateBackUpConfig(); +RenameConfig(); if ($sccp_compatible > 431) { InstallDB_sccpuser(); InstallDB_Buttons(); From c09cbc3aaedcd9a2f842817bd5e63480d8adaa1f Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Mon, 8 Jul 2019 15:50:44 +0300 Subject: [PATCH 016/100] - Remove sccp_extensions.conf - Remove sccp_hardware.conf --- install.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install.php b/install.php index c1936f6..519942c 100644 --- a/install.php +++ b/install.php @@ -804,7 +804,7 @@ function CreateBackUpConfig() { outn("
  • " . _("Create Config BackUp") . "
  • "); $cnf_int = \FreePBX::Config(); $backup_files = array('extensions','extconfig','res_mysql', 'res_config_mysql','sccp','sccp_hardware','sccp_extensions'); - $backup_ext = array('_custom.conf', '.conf'); + $backup_ext = array('_custom.conf', '_additional.conf','.conf'); $dir = $cnf_int->get('ASTETCDIR'); $fsql = $dir.'/sccp_backup_'.date("Ymd").'.sql'; @@ -836,7 +836,7 @@ function RenameConfig() { outn("
  • " . _("Move Old Config") . "
  • "); $cnf_int = \FreePBX::Config(); $rename_files = array('sccp_hardware','sccp_extensions'); - $rename_ext = array('_custom.conf', '.conf'); + $rename_ext = array('_custom.conf', '_additional.conf','.conf'); $dir = $cnf_int->get('ASTETCDIR'); foreach ($rename_files as $file) { foreach ($rename_ext as $b_ext) { @@ -853,7 +853,7 @@ function Setup_RealTime() { $cnf_int = \FreePBX::Config(); $cnf_wr = \FreePBX::WriteConfig(); $cnf_read = \FreePBX::LoadConfig(); - $backup_ext = array('_custom.conf', '.conf'); + $backup_ext = array('_custom.conf', '_additional.conf','.conf'); $def_config = array('sccpdevice' => 'mysql,sccp,sccpdeviceconfig', 'sccpline' => ' mysql,sccp,sccpline'); $def_bd_config = array('dbhost' => $amp_conf['AMPDBHOST'], 'dbname' => $amp_conf['AMPDBNAME'], From 2bca6e4d8d9a24317833d9b11cc6da22080d5d19 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Wed, 10 Jul 2019 20:52:50 +0300 Subject: [PATCH 017/100] - Add Video codecs supported in Global config --- views/server.codec.php | 65 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/views/server.codec.php b/views/server.codec.php index 8164c92..29ceddc 100644 --- a/views/server.codec.php +++ b/views/server.codec.php @@ -10,6 +10,7 @@ $def_val = null; $dev_id = null; $sccp_codec = $this->getCodecs('audio', true); +$video_codecs = $this->getCodecs('video', true); $sccp_disalow_def = $this->extconfigs->getextConfig('sccpDefaults','disallow'); $sccp_disalow = $sccp_disalow_def; @@ -44,7 +45,7 @@ if (!empty($_REQUEST['id'])) {
    -

    +

    @@ -54,7 +55,7 @@ if (!empty($_REQUEST['id'])) {
    - +
    @@ -90,6 +91,62 @@ if (!empty($_REQUEST['id'])) {
    + +
    + +
    +

    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    + '; + foreach ($video_codecs as $codec => $codec_state) { + $codec_trans = _($codec); + $codec_checked = $codec_state ? 'checked' : ''; + echo '
  • ' + . 'move ' + . '' + . '  
  • \n"; + } + echo ''; + ?> +
    +
    +
    +
    +
    +
    + + +
    + +
    +

    +
    +
    @@ -116,9 +173,9 @@ if (!empty($_REQUEST['id'])) {
    - -
    + + From 633e67285fbd4ccf5594115b1b9f8969b15bba99 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Wed, 10 Jul 2019 20:53:00 +0300 Subject: [PATCH 018/100] - Add Video codecs supported in Global config --- Sccp_manager.class.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 9ff4fa2..68fd987 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -1291,6 +1291,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } switch ($key) { case 'voicecodecs': + case 'vcodec': foreach ($value as $keycodeс => $valcodeс) { $save_codec[$i] = $keycodeс; $i++; @@ -1473,32 +1474,36 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } public function getCodecs($type, $showDefaults = false) { - + $codecs_res = array(); switch ($type) { case 'audio': - $codecs = $this->getMyConfig('voicecodecs'); + $lcodecs = $this->getMyConfig('voicecodecs'); + $allCodecs = $this->FreePBX->Codecs->getAudio(); break; case 'video': - $codecs = $this->getConfig('videocodecs'); + $lcodecs = $this->getMyConfig('voicecodecs'); + $allCodecs = array('h264'=>'1','h263'=>'','h265'=>'','h261'=>''); +// $allCodecs = $this->FreePBX->Codecs->getVideo(); break; case 'text': - $codecs = $this->getConfig('textcodecs'); + $lcodecs = $this->getConfig('textcodecs'); break; case 'image': - $codecs = $this->getConfig('imagecodecs'); + $lcodecs = $this->getConfig('imagecodecs'); break; default: throw new Exception(_('Unknown Type')); break; } - if (empty($codecs) || !is_array($codecs)) { + if (empty($lcodecs) || !is_array($lcodecs)) { switch ($type) { case 'audio': $codecs = $this->FreePBX->Codecs->getAudio(true); break; case 'video': - $codecs = $this->FreePBX->Codecs->getVideo(true); +// $codecs = $this->FreePBX->Codecs->getVideo(true); + $codecs = array('h264'=>'1','h263'=>'','h265'=>'','h261'=>''); break; case 'text': $codecs = $this->FreePBX->Codecs->getText(true); @@ -1507,6 +1512,12 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $codecs = $this->FreePBX->Codecs->getImage(true); break; } + } else { + foreach ($lcodecs as $c => $v) { + if (isset($allCodecs[$c])) { + $codecs[$c] = true; + } + } } if ($showDefaults) { @@ -1515,7 +1526,8 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $allCodecs = $this->FreePBX->Codecs->getAudio(); break; case 'video': - $allCodecs = $this->FreePBX->Codecs->getVideo(); +// $allCodecs = $this->FreePBX->Codecs->getVideo(); + $allCodecs = array('h264'=>'1','h263'=>'','h265'=>'','h261'=>''); break; case 'text': $allCodecs = $this->FreePBX->Codecs->getText(); From e7270846afa62f79fbe9fe4b21ed5911c54c7fb0 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Thu, 11 Jul 2019 10:59:53 +0300 Subject: [PATCH 019/100] - Add Video codecs supported in Global config --- Sccp_manager.class.php | 57 ++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 38 deletions(-) diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 68fd987..5e28008 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -1474,7 +1474,9 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } public function getCodecs($type, $showDefaults = false) { - $codecs_res = array(); + $allSupported = array(); +// $Sccp_Codec = array('gsm','slin16','alow','ulaw','g722','g723','g726','g728','g729','ilibc','isac','opus','h224','aac','h264','h263','h265','h261'); + $Sccp_Codec = array('gsm','slin16','alaw','ulaw','g722','g723','g726','g728','g729','ilibc','opus','h264','h263','h265','h261'); switch ($type) { case 'audio': $lcodecs = $this->getMyConfig('voicecodecs'); @@ -1482,63 +1484,42 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { break; case 'video': $lcodecs = $this->getMyConfig('voicecodecs'); - $allCodecs = array('h264'=>'1','h263'=>'','h265'=>'','h261'=>''); -// $allCodecs = $this->FreePBX->Codecs->getVideo(); + $allCodecs = $this->FreePBX->Codecs->getVideo(); break; case 'text': $lcodecs = $this->getConfig('textcodecs'); + $allCodecs = $this->FreePBX->Codecs->getText(true); break; case 'image': $lcodecs = $this->getConfig('imagecodecs'); + $allCodecs = $this->FreePBX->Codecs->getImage(true); break; default: throw new Exception(_('Unknown Type')); break; } + foreach ($allCodecs as $c => $v) { + if (array_search($c,$Sccp_Codec) !=null) { + $allSupported[$c] =$v; + } + } - if (empty($lcodecs) || !is_array($lcodecs)) { - switch ($type) { - case 'audio': - $codecs = $this->FreePBX->Codecs->getAudio(true); - break; - case 'video': -// $codecs = $this->FreePBX->Codecs->getVideo(true); - $codecs = array('h264'=>'1','h263'=>'','h265'=>'','h261'=>''); - break; - case 'text': - $codecs = $this->FreePBX->Codecs->getText(true); - break; - case 'image': - $codecs = $this->FreePBX->Codecs->getImage(true); - break; + if (empty($lcodecs) || (!is_array($lcodecs)) ) { + if (empty($allSupported)) { + $lcodecs = $allCodecs; + } else { + $lcodecs = $allSupported; } } else { foreach ($lcodecs as $c => $v) { - if (isset($allCodecs[$c])) { + if (isset($allSupported[$c])) { $codecs[$c] = true; - } + } } } if ($showDefaults) { - switch ($type) { - case 'audio': - $allCodecs = $this->FreePBX->Codecs->getAudio(); - break; - case 'video': -// $allCodecs = $this->FreePBX->Codecs->getVideo(); - $allCodecs = array('h264'=>'1','h263'=>'','h265'=>'','h261'=>''); - 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) { + foreach ($allSupported as $c => $v) { if (!isset($codecs[$c])) { $codecs[$c] = false; } From 197eb8f1fa373a4dfa9b19c7ac6ed5132104b69e Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Fri, 19 Jul 2019 11:11:00 +0300 Subject: [PATCH 020/100] - Change Sccp class driver --- README.md | 2 +- README.ru.md | 4 +- conf/Sccp.class.php.v433 | 170 ++++++++++++++++++++++++++++++--------- 3 files changed, 135 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index bf47ca3..317af5d 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Make sure you have the following installed on your system: ### Requirements - Chan_SCCP module 4.3.1 (or later) channel driver for Asterisk: [See our WIKI] (https://github.com/chan-sccp/chan-sccp/wiki/Building-and-Installation-Guide) - expected configure flags: - ```./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate``` + ```./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate --enable-video``` - Creating mysql DB from sorce ```mysql -u root asterisk < mysql-v5_enum.sql``` diff --git a/README.ru.md b/README.ru.md index 0917896..73ba04a 100644 --- a/README.ru.md +++ b/README.ru.md @@ -60,8 +60,8 @@ Make sure you have the following installed on your system: > git clone https://github.com/chan-sccp/chan-sccp.git > git checkout develop - - Собираем с флагами и создаем БД для работы: -> ./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate + - Важно ! **_Собираем с флагами и создаем БД для работы:_** +> ./configure ./configure --enable-conference --enable-advanced-functions --enable-distributed-devicestate --enable-video > mysql -u root asterisk < mysql-v5_enum.sql - Настраиваем TFTP Server, он нужен для телефонов /tftpboot/ [See our WIKI] (https://github.com/chan-sccp/chan-sccp/wiki/setup-tftp-service) diff --git a/conf/Sccp.class.php.v433 b/conf/Sccp.class.php.v433 index ae7b591..840523b 100644 --- a/conf/Sccp.class.php.v433 +++ b/conf/Sccp.class.php.v433 @@ -20,10 +20,16 @@ class Sccp extends \FreePBX\modules\Core\Driver { "transfer" => 'transfer', "echocancel" => 'echocancel', "language" => 'language', "description" => 'callerid', "cid_num" => 'cid_num', "cid_name" => 'label', "mailbox" => 'mailbox', - "musicclass" => 'musicclass', + "musicclass" => 'musicclass',"allow" => 'allow',"disallow" => 'disallow', + "videomode" => 'videomode', "dnd" => 'dnd', "silencesuppression" => 'silencesuppression', "secondary_dialtone_digits" => 'secondary_dialtone_digits', "secondary_dialtone_tone" => 'secondary_dialtone_tone' ); + private $guidefaults =array( + 'gui_checkset' => array( "elemname" => "", "prompttext" => "", "helptext" => "", "currentvalue" => "", "valarray" => array(), "jsonclick" => '', + "jsvalidation" => "", "failvalidationmsg" => "", "canbeempty" => true, "maxchars" => 0, "disable" => false, "inputgroup" => false, + "class" => "", "cblabel" => 'Enable', "disabled_value" => 'DEFAULT', "check_enables" => 'true', "cbdisable" => false, "cbclass" => '') ); + public function __construct($freepbx) { parent::__construct($freepbx); @@ -37,21 +43,10 @@ class Sccp extends \FreePBX\modules\Core\Driver { "prettyName" => _("Sccp Custom Driver"), "shortName" => "SCCP", "description" => _("Sccp Device"), - "Version" => "11.3.v433", - "about" => "Sccp mysql class Base ver: 11.3, Sccp ver: 433" + "Version" => "11.3.v434", + "about" => "Sccp mysql class Base ver: 11.3, Sccp ver: 434" ); } -/* - public function addDevice1($id, $settings) { - $sql = 'INSERT INTO sccp (id, keyword, data, flags) values (?,?,?,?)'; - $sth = $this->database->prepare($sql); - $settings = is_array($settings)?$settings:array(); - foreach($settings as $key => $setting) { - $sth->execute(array($id,$key,$setting['value'],$setting['flag'])); - } - return true; - } -*/ public function addDevice($id, $settings) { $add_fld = array ("name"=>'label',"outboundcid"=>'cid_num',"langcode"=>'language',"extdisplay"=>'description','devinfo_mailbox'=>'mailbox'); // print_r($_REQUEST); @@ -66,6 +61,14 @@ class Sccp extends \FreePBX\modules\Core\Driver { } } } + $allow_codec = array(); + foreach($settings as $key => $val) { + if (strpos($key,'codec_') !== false ) { + $allow_codec[] =substr($key,6); + } + } + $settings['allow']['value'] = implode(",", $allow_codec); + if (empty($settings['cid_num']['value'])) { $settings['cid_num']['value']= $id; } @@ -138,13 +141,20 @@ class Sccp extends \FreePBX\modules\Core\Driver { $sth = $this->database->prepare($sql); $result = array(); $tech = array(); +// print_r($sql); try { $sth->execute(array($id)); - $result = $sth->fetch(\PDO::FETCH_ASSOC); - $tech = $result; + $tech = $sth->fetch(); +// $tech = $sth->fetch(\PDO::FETCH_ASSOC); +// die(print_r($tech)); +// $tech = $sth->fetch(\PDO::FETCH_ASSOC); $tech['dial']='SCCP/'.$id; } catch(\Exception $e) {} - +// $tech['sccp_codec'] = Array ('g729'); +// $tech['allow'] = 'g729'; +// $tech['sccp_codec2'] = Array ('g729','gsm'); +// $tech['devinfo_sccp_codec'] = Array ('g729'); + // print_r($tech); // echo '

    '; // print_r($sql); @@ -251,6 +261,18 @@ class Sccp extends \FreePBX\modules\Core\Driver { "musicclass" => array( "value" => "default", "flag" => $flag++ + ), + "allow" => array( + "value" => "all", + "flag" => $flag++ + ), + "disallow" => array( + "value" => "all", + "flag" => $flag++ + ), + "videomode" => array( + "value" => "auto", + "flag" => $flag++ ), ); return array( @@ -261,23 +283,82 @@ class Sccp extends \FreePBX\modules\Core\Driver { public function getDeviceDisplay($display, $deviceInfo, $currentcomponent, $primarySection) { $section = _("SCCP Extension Details"); -// $category = "general"; -// Assigned DID/CID + $section_с = _("SCCP Codec Details"); + $gn_category = "sccp"; + global $currentcomponent, $display; $named_group = $this->getNamedGroup(); + //add sccp category + $currentcomponent->addTabTranslation('sccp',_('SCCP')); +// $currentcomponent->addTabTranslation('Codec',_('Codec')); + + //Fill Codecs Informations + + $Sccp_Codec = array('gsm','slin16','alaw','ulaw','g722','g723','g726','g728','g729','ilibc','opus','h264','h263','h265','h261'); + $allCodecs = $this->freepbx->Codecs->getAudio(true); + $allVCodecs = $this->freepbx->Codecs->getVideo(); + $ACodec_cur = array('all'); + $VCodec_cur = array('all'); + + foreach ($allCodecs as $c => $v) { + if (array_search($c,$Sccp_Codec) !=null) { + $currentcomponent->addoptlistitem('devinfo_sccp_codec', "devinfo_codec_"."$c", "$c"); + if (isset($deviceInfo['allow'])) { + if (strpos($deviceInfo['allow'],$c)!== false) { + $ACodec_cur[] ="devinfo_codec_"."$c"; + } + } + } + } + + foreach ($allVCodecs as $c => $v) { + if (array_search($c,$Sccp_Codec) !=null) { + $currentcomponent->addoptlistitem('devinfo_sccp_vcodec', "devinfo_codec_"."$c", "$c"); + if (isset($deviceInfo['allow'])) { + if (strpos($deviceInfo['allow'],$c)!== false) { + $VCodec_cur[] ="devinfo_codec_"."$c"; + } + } + } + } + + $el = array( + "elemname" => "devinfo_sccp_codec", + "prompttext" => _('Line Audio Codec:'), + "helptext" => _("Line Audio Codec"), + "currentvalue" => $ACodec_cur, + "valarray" => $currentcomponent->getoptlist('devinfo_sccp_codec'), + "class" => $section_с, + "disable" => 0 + ); + + $currentcomponent->addguielem($section_с, new \gui_checkset(array_merge($this->guidefaults['gui_checkset'],$el)), $gn_category); + unset($el); + + $el = array( + "elemname" => "devinfo_sccp_vcodec", + "prompttext" => _('Line Video Codec:'), + "helptext" => _("Line Video Codec"), + "currentvalue" => $VCodec_cur, + "valarray" => $currentcomponent->getoptlist('devinfo_sccp_vcodec'), + "class" => $section_с, + "disable" => 0 + ); + $currentcomponent->addguielem($section_с, new \gui_checkset(array_merge($this->guidefaults['gui_checkset'],$el)), $gn_category); + $tmparr = array(); $tt = _("Name or id of lincked maibox"); - $tmparr['mailbox'] = array('prompttext' => _('Mailbox'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tmparr['mailbox'] = array('prompttext' => _('Mailbox'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section,'category' => $gn_category); $tt = _("The SCCP channel number for this port. If you plaining to use this line as 'Shared' or use on several devices - leave this field blank or set limit to 10 calls."); // $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '2', 'tt' => $tt, 'level' => 0, 'jsvalidation' => 'isEmpty()', 'failvalidationmsg' => $msgInvalidChannel); // $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section, 'category' => 'general'); - $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tmparr['incominglimit'] = array('prompttext' => _('Incoming Call Limit'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section,'category' => $gn_category); $tt = _("Asterisk context this device will send calls to. Only change this is you know what you are doing."); - $tmparr['lcontext'] = array('prompttext' => _('Line context'), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tmparr['lcontext'] = array('prompttext' => _('Line context'), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1, 'section' => $section,'category' => $gn_category); $tt = _("Asterisk context this device will can pickup calls. Only change this is you know what you are doing."); - $tmparr['directed_pickup_context'] = array('prompttext' => _('Directed PickUp Сontext '), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tmparr['directed_pickup_context'] = array('prompttext' => _('Directed PickUp Сontext '), 'value' => 'from-internal', 'tt' => $tt, 'level' => 1, 'section' => $section,'category' => $gn_category); // $tt = _("Phone call group callgroup=1,3-4"); // $tmparr['callgroup'] = array('prompttext' => _('Call group id'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); @@ -289,7 +370,7 @@ class Sccp extends \FreePBX\modules\Core\Driver { } $tt .= '... '; } - $tmparr['namedcallgroup'] = array('prompttext' => _('Named Call Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tmparr['namedcallgroup'] = array('prompttext' => _('Named Call Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section,'category' => $gn_category); // $tmparr['namedcallgroup'] = array('prompttext' => _('Named Call Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section, 'category' => 'general'); // $tt = _("Phone pickup group pickupgroup=1,3-4"); // $tmparr['pickupgroup'] = array('prompttext' => _('Pickup group id'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); @@ -300,10 +381,10 @@ class Sccp extends \FreePBX\modules\Core\Driver { } $tt .= '... '; } - $tmparr['namedpickupgroup'] = array('prompttext' => _('Named Pickup Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tmparr['namedpickupgroup'] = array('prompttext' => _('Named Pickup Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section,'category' => $gn_category); // $tmparr['namedpickupgroup'] = array('prompttext' => _('Named Pickup Group'),'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section, 'category' => 'general'); $tt = _("Digits to indicate an external line to user (secondary dialtone) Sample 9 or 8 (max 9 digits)"); - $tmparr['secondary_dialtone_digits'] = array('prompttext' => _('Secondary dialtone digits'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); + $tmparr['secondary_dialtone_digits'] = array('prompttext' => _('Secondary dialtone digits'), 'value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section,'category' => $gn_category); unset($select); $select[] = array( 'value' => '0x21', 'text' => 'Inside Dial Tone'); @@ -364,7 +445,7 @@ class Sccp extends \FreePBX\modules\Core\Driver { $select[] = array('value' => 'no', 'text' => 'No'); $tt = _("Outside dialtone frequency (defaul 0x22)"); - $tmparr['secondary_dialtone_tone'] = array('prompttext' => _('Secondary dialtone'), 'value' => '0x22', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'select', 'section' => $section); + $tmparr['secondary_dialtone_tone'] = array('prompttext' => _('Secondary dialtone'), 'value' => '0x22', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'select', 'section' => $section,'category' => $gn_category); @@ -373,14 +454,14 @@ class Sccp extends \FreePBX\modules\Core\Driver { $select[] = array('value' => 'on', 'text' => 'Yes'); $select[] = array('value' => 'off', 'text' => 'No'); $tt = _("Enable/Disable the `directed` pickup softkey"); - $tmparr['directed_pickup'] = array('prompttext' => _('Directed pickup'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + $tmparr['directed_pickup'] = array('prompttext' => _('Directed pickup'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section,'category' => $gn_category); unset($select); $select[] = array('value' => '', 'text' => 'Inherit'); $select[] = array('value' => 'on', 'text' => 'Yes'); $select[] = array('value' => 'off', 'text' => 'No'); $tt = _("Should the picked/gpicked-up call be answered automatically"); - $tmparr['pickup_modeanswer'] = array('prompttext' => _('Pickup Modeanswer'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + $tmparr['pickup_modeanswer'] = array('prompttext' => _('Pickup Modeanswer'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section,'category' => $gn_category); unset($select); $select[] = array('value' => '', 'text' => 'Inherit'); @@ -388,13 +469,13 @@ class Sccp extends \FreePBX\modules\Core\Driver { $select[] = array('value' => 'off', 'text' => 'No'); $tt = _("Allow call transfer."); // $tmparr['transfer'] = array('prompttext' => _('Call Transfer'), 'value' => 'yes', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section, 'category' => 'general'); - $tmparr['transfer'] = array('prompttext' => _('Call Transfer'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + $tmparr['transfer'] = array('prompttext' => _('Call Transfer'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section,'category' => $gn_category); unset($select); $select[] = array('value' => 'on', 'text' => 'Yes'); $select[] = array('value' => 'off', 'text' => 'No'); $tt = _("Echo cancel"); - $tmparr['echocancel'] = array('prompttext' => _('Echo cancel'), 'value' => 'on', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + $tmparr['echocancel'] = array('prompttext' => _('Echo cancel'), 'value' => 'on', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section,'category' => $gn_category); unset($select); $select[] = array('value' => 'off', 'text' => 'Off'); @@ -405,13 +486,13 @@ class Sccp extends \FreePBX\modules\Core\Driver { _("Cycle - dnd that cycles through all three states off -> reject -> silent -> off (this is the normal behaviour)").'
    '. _("Reject - Usesr can only switch off and on (in reject/busy mode)").'
    '. _("Silent - Usesr can only switch off and on (in silent mode)"); - $tmparr['dnd'] = array('prompttext' => _('DND'), 'value' => 'reject', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + $tmparr['dnd'] = array('prompttext' => _('DND'), 'value' => 'reject', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section,'category' => $gn_category); unset($select); $select[] = array('value' => 'on', 'text' => 'Yes'); $select[] = array('value' => 'off', 'text' => 'No'); $tt = _("Silence Suppression. Asterisk Not suported"); - $tmparr['silencesuppression'] = array('prompttext' => _('Silence Suppression'), 'value' => 'off', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section); + $tmparr['silencesuppression'] = array('prompttext' => _('Silence Suppression'), 'value' => 'off', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section,'category' => $gn_category); unset($select); $select[] = array('value' => 'default', 'text' => _('default')); @@ -425,13 +506,26 @@ class Sccp extends \FreePBX\modules\Core\Driver { } $tt = _("Music on hold"); - $tmparr['musicclass'] = array('prompttext' => _('Music on hold'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'section' => $section); + $tmparr['musicclass'] = array('prompttext' => _('Music on hold'), 'value' => '', 'tt' => $tt, 'select' => $select, 'level' => 1, 'section' => $section,'category' => $gn_category); + unset($select); $tt = _("Sets the named pickup groups this line is a member of (this phone can pickup calls from remote phones which are in this caller group (ast111)"); - $tmparr['pin'] = array('value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section); - - - $devopts = $tmparr; + $tmparr['pin'] = array('value' => '', 'tt' => $tt, 'level' => 1, 'section' => $section ,'category' => $gn_category); + unset($select); + + + $select[] = array('value' => 'off', 'text' => 'Off'); + $select[] = array('value' => 'user', 'text' => 'User'); + $select[] = array('value' => 'auto', 'text' => 'Auto'); + $tt = _("Automatic or Manual video mode. Valid values are 'auto', 'user' or 'off'. When set to 'auto', video will automatically start if both parties have a compatible code enabled. In 'user' mode the user needs to press the vidmode softkey before video will be tried. Default:'auto'"); + $tmparr['videomode'] = array('prompttext' => _('Video Mode '), 'value' => 'auto', 'tt' => $tt, 'select' => $select, 'level' => 1, 'type' => 'radio', 'section' => $section_с, 'category' => $gn_category); + unset($select); + + $tt = _("Codec disallow"); + $tmparr['disallow'] = array('prompttext' => _('Codec disallow'), 'value' => 'all', 'tt' => $tt, 'level' => 1, 'section' => $section_с,'category' => $gn_category); + unset($select); + + $devopts = $tmparr; return $devopts; } public function getDeviceHeaders() { From f98e7fb774b7721b1f3a5ab5694fc9073e3fc632 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Tue, 6 Aug 2019 11:18:27 +0300 Subject: [PATCH 021/100] - Change Sccp class driver --- README.md | 2 ++ README.ru.md | 3 +++ conf/Sccp.class.php.v433 | 7 ------- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 317af5d..010a499 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,8 @@ Make sure you have the following installed on your system: > cd /var/www/html/admin/modules/sccp_manager/ > git fetch > git pull +> git checkout extension_mobility +> or > git checkout develop diff --git a/README.ru.md b/README.ru.md index 73ba04a..ec09cdf 100644 --- a/README.ru.md +++ b/README.ru.md @@ -83,8 +83,11 @@ Make sure you have the following installed on your system: > cd /var/www/html/admin/modules/sccp_manager/ > git fetch > git pull +> git checkout extension_mobility +> or > git checkout develop + ### Важно: - !!! Если это это проект не заработал на твоей системе - переключись на ветку мастер [master](https://github.com/PhantomVl/sccp_manager/tree/master) !!! Но есть ограничение - ветка master не поддерживает изменения в chan-sccp сделаные после октября 2018 г. diff --git a/conf/Sccp.class.php.v433 b/conf/Sccp.class.php.v433 index 840523b..6ab4417 100644 --- a/conf/Sccp.class.php.v433 +++ b/conf/Sccp.class.php.v433 @@ -145,15 +145,8 @@ class Sccp extends \FreePBX\modules\Core\Driver { try { $sth->execute(array($id)); $tech = $sth->fetch(); -// $tech = $sth->fetch(\PDO::FETCH_ASSOC); -// die(print_r($tech)); -// $tech = $sth->fetch(\PDO::FETCH_ASSOC); $tech['dial']='SCCP/'.$id; } catch(\Exception $e) {} -// $tech['sccp_codec'] = Array ('g729'); -// $tech['allow'] = 'g729'; -// $tech['sccp_codec2'] = Array ('g729','gsm'); -// $tech['devinfo_sccp_codec'] = Array ('g729'); // print_r($tech); // echo '

    '; From f75a486701d2389af082281d577aa027e9e6d535 Mon Sep 17 00:00:00 2001 From: PhantomVl Date: Wed, 21 Aug 2019 18:00:57 +0300 Subject: [PATCH 022/100] - ADD SIP TFTP - Activate Dial Template --- Sccp_manager.class.php | 206 ++++--- Sccp_manager.inc/dbinterface.class.php | 60 +- Sccp_manager.inc/extconfigs.class.php | 11 +- Sccp_manager.inc/sipconfigs.class.php | 104 ++++ Sccp_manager.inc/xmlinterface.class.php | 595 +++++++++++++++++-- assets/js/sccp_manager.js | 6 + conf/SEP0000000000.cnf.xml_791x_sip_template | 300 ++++++++++ conf/SEP0000000000.cnf.xml_79df_sip_template | 255 ++++++++ conf/SIPDefaultSoftKey.xml_template | 201 +++++++ conf/SIPTypeSoftKey.xml_template | 142 +++++ conf/dialplan.xml_template | 8 + conf/sccpgeneral.xml.v433 | 47 +- contrib/rewrite.rules | 1 + install.php | 11 +- views/advserver.dialtemplate.php | 4 +- views/form.adddevice.php | 44 +- views/form.addsdevice.php | 125 ++++ views/form.dptemplate.php | 4 +- views/form.sbuttons.php | 260 ++++++++ views/formShow.php | 26 +- views/hardware.phone.php | 2 +- views/hardware.sphone.php | 87 +++ views/server.info.php | 25 +- 23 files changed, 2341 insertions(+), 183 deletions(-) create mode 100644 Sccp_manager.inc/sipconfigs.class.php create mode 100644 conf/SEP0000000000.cnf.xml_791x_sip_template create mode 100644 conf/SEP0000000000.cnf.xml_79df_sip_template create mode 100644 conf/SIPDefaultSoftKey.xml_template create mode 100644 conf/SIPTypeSoftKey.xml_template create mode 100644 conf/dialplan.xml_template create mode 100644 views/form.addsdevice.php create mode 100644 views/form.sbuttons.php create mode 100644 views/hardware.sphone.php diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 5e28008..bb8e1c1 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -23,6 +23,7 @@ * + Dial Templates + Configuration * + Dial Templates in Global Configuration ( Enabled / Disabled ; default template ) * ? Dial Templates - Howto IT Include in XML.Config ??????? + * + Dial Templates - SIP Device * - Dial Templates in device Configuration ( Enabled / inheret / Disabled ; template ) * - WiFi Config (Bulk Deployment Utility for Cisco 7921, 7925, 7926)????? @@ -58,6 +59,7 @@ * + Create ATADefault.cnf.xml * - Create Second line Use MAC AABBCCDDEEFF rotation MAC BBCCDDEEFF01 (ATA 187 ) * + Add SEP, ATA, VG prefix. + * + Add Cisco SIP device Tftp config. * - VG248 ports start with VGXXXXXXXXXXXX0. * * I think this file should be split in 3 parts (as in Model-View-Controller(MVC)) * * XML/Database Parts -> Model directory @@ -477,10 +479,10 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { "name" => _("SCCP Device Keyset"), "page" => 'views/advserver.keyset.php' ), -// "sccpdialplan" => array( -// "name" => _("SCCP Dial Plan information"), -// "page" => 'views/advserver.dialtemplate.php' -// ) + "sccpdialplan" => array( + "name" => _("SIP Dial Plan information"), + "page" => 'views/advserver.dialtemplate.php' + ) ); break; } @@ -506,7 +508,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { // print_r($inputform); if (empty($this->pagedata)) { switch ($inputform) { - case cisco: + case "cisco": $this->pagedata = array( "general" => array( "name" => _("Device configuration"), @@ -524,8 +526,25 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } break; + case "cisco-sip": + $this->pagedata = array( + "general" => array( + "name" => _("Sip device configuration"), + "page" => 'views/form.addsdevice.php' + ), + "buttons" => array( + "name" => _("Sip device Buttons"), + "page" => 'views/form.sbuttons.php' + )); +// if ($this->sccpvalues['sccp_compatible']['data'] < '433') { +// $this->pagedata["sccpcodec"] = array( +// "name" => _("Device SCCP Codec"), +// "page" => 'views/server.codec.php' +// ); +// } + break; - case r_user: + case "r_user": $this->pagedata = array( "general" => array( "name" => _("Rouming User configuration"), @@ -548,6 +567,10 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { "sccpdevice" => array( "name" => _("SCCP Phone"), "page" => 'views/hardware.phone.php' + ), + "sipdevice" => array( + "name" => _("SIP CISCO Phone"), + "page" => 'views/hardware.sphone.php' ) ); break; @@ -605,6 +628,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { case 'backupsettings': case 'savesettings': case 'save_hardware': + case 'save_sip_hardware': case 'save_ruser': case 'save_dialplan_template': case 'delete_hardware': @@ -654,6 +678,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { // !TODO!: It is necessary in the future to check, and replace all server responses on correct messages. Use _(msg) return array('status' => true, 'message' => $msg, 'reload' => true); break; + case 'save_sip_hardware': case 'save_hardware': $this->save_hw_phone($request); // return array('status' => true, 'href' => 'config.php?display=sccp_phone', 'reload' => true); @@ -669,9 +694,10 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return array('status' => false, 'message' => print_r($res)); break; /* !TODO!: -TODO-: dialplan templates should be removed (only required for very old devices (like ATA) */ -// ------------------------------- Old deviece suport - In the development--- +// ------------------------------- Old + Sip deviece suport - In the development--- case 'save_dialplan_template': - $res = $this->save_DialPlant($request); + $res = $this->save_DialPlan($request); + //public if (empty($res)) { return array('status' => true, 'search' => '?display=sccp_adv', 'hash' => 'sccpdialplan'); } else { @@ -682,7 +708,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { case 'delete_dialplan': if (!empty($request['dialplan'])) { $get_file = $request['dialplan']; - $res = $this->del_DialPlant($get_file); + $res = $this->del_DialPlan($get_file); // !TODO!: It is necessary in the future to check, and replace all server responses on correct messages. Use _(msg) return array('status' => true, 'message' => 'Dial Template has been deleted ! ', 'table_reload' => true); } else { @@ -717,6 +743,8 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { foreach ($models as $data) { $ver_id = $this->sccp_create_device_XML($data['name']); }; +// !TODO!: -TODO-: Check SIP Suport Enabled + $this->sccp_create_xmlSoftkey(); // Create Softkey Sets for SIP // !TODO!: -TODO-: Do these returned message strings work with i18n ? // !TODO!: It is necessary in the future to check, and replace all server responses on correct messages. Use _(msg) return array('status' => true, 'message' => 'Create new config files (version:' . $ver_id . ')'); @@ -855,6 +883,10 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } } $this->sccp_create_sccp_init(); + +// !TODO!: -TODO-: Check SIP Suport Enabled + $this->sccp_create_xmlSoftkey(); + $msg = print_r($this->srvinterface->sccp_core_commands(array('cmd' => 'sccp_reload')), 1); return array('status' => true, 'table_reload' => true); @@ -906,7 +938,12 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return $result; break; case 'getPhoneGrid': - $result = $this->dbinterface->get_db_SccpTableData('SccpDevice'); + $cmd_type = !empty($request['type']) ? $request['type'] : ''; + + $result = $this->dbinterface->get_db_SccpTableData('SccpDevice', array('type'=>$cmd_type)); + if ($cmd_type == 'cisco-sip'){ + return $result; + } $staus = $this->srvinterface->sccp_get_active_device(); if (empty($result)) { $result = array(); @@ -990,7 +1027,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { // Get Model Buttons info $res = array(); - $lines_list = $this->dbinterface->get_db_SccpTableData('SccpExtension'); +// $lines_list = $this->dbinterface->get_db_SccpTableData('SccpExtension'); $max_btn = ((!empty($get_settings['buttonscount']) ? $get_settings['buttonscount'] : 100)); $last_btn = $max_btn; for ($it = $max_btn; $it >= 0; $it--) { @@ -1106,6 +1143,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $name_dev = ''; $db_field = $this->dbinterface->get_db_SccpTableData("get_colums_sccpdevice"); $hw_id = (empty($get_settings['sccp_deviceid'])) ? 'new' : $get_settings['sccp_deviceid']; + $hw_type = (empty($get_settings['sccp_device_typeid'])) ? 'sccpdevice' : $get_settings['sccp_device_typeid']; $update_hw = ($hw_id == 'new') ? 'update' : 'clear'; $hw_prefix = 'SEP'; if (!empty($get_settings[$hdr_prefix . 'type'])) { @@ -1162,6 +1200,11 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $value = $get_settings[$hdr_prefix . 'netlang'] . ':' . $get_settings[$hdr_prefix . 'devlang']; } break; +// case '_json': +// foreach ($get_settings[$hdr_arprefix . $key.'_sip'] as $vkey => $vval) { +// } +// break; +// default : if (!empty($get_settings[$hdr_prefix . $key])) { $value = $get_settings[$hdr_prefix . $key]; @@ -1217,7 +1260,8 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->dbinterface->sccp_save_db("sccpdevice", $save_settings, 'replace'); // Get Model Buttons info - $save_buttons = $this-> get_buttons_phone($get_settings,$name_dev, 'sccpdevice'); +// $save_buttons = $this-> get_buttons_phone($get_settings,$name_dev, 'sccpdevice'); + $save_buttons = $this-> get_buttons_phone($get_settings,$name_dev, $hw_type); // Sace Buttons config $this->dbinterface->sccp_save_db("sccpbuttons", $save_buttons, $update_hw, '', $name_dev); @@ -1714,15 +1758,25 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } } } - + /* + * Soft Key + * + */ + + function sccp_create_xmlSoftkey(){ + foreach ($this->srvinterface->sccp_list_keysets() as $keyl => $vall) { + $this->xmlinterface->create_xmlSoftkeyset($this->sccp_conf_init,$this->sccppath,$keyl); + } + } + /* * DialPlan * */ function get_DialPlanList() { - $dir = $this->sccppath["tftp_DP"] . '/*.xml'; - $base_len = strlen($this->sccppath["tftp_DP"]) + 1; + $dir = $this->sccppath["tftp_dialplan"] . '/dial*.xml'; + $base_len = strlen($this->sccppath["tftp_dialplan"]) + 1; $res = glob($dir); $dp_list = array(); foreach ($res as $key => $value) { @@ -1733,7 +1787,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } function get_DialPlan($get_file) { - $file = $this->sccppath["tftp_DP"] . '/' . $get_file . '.xml'; + $file = $this->sccppath["tftp_dialplan"] . '/' . $get_file . '.xml'; if (file_exists($file)) { // $load_xml_data = simplexml_load_file($file); @@ -1748,7 +1802,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { function del_DialPlan($get_file) { if (!empty($get_file)) { - $file = $this->sccppath["tftp_DP"] . '/' . $get_file . '.xml'; + $file = $this->sccppath["tftp_dialplan"] . '/' . $get_file . '.xml'; if (file_exists($file)) { $res = unlink($file); } @@ -1757,53 +1811,9 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } function save_DialPlan($get_settings) { - $xmlstr = "\n"; - $dialFelds = array('match', 'timeout', 'rewrite', 'tone'); //str -to lo ! - - $hdr_prefix = 'sccp_dial_'; - $hdr_arprefix = 'sccp_dial-ar_'; - $save_data = array(); - $integer_msg = _("%s must be a non-negative integer"); - $errors = array(); - foreach ($get_settings[$hdr_arprefix . 'dialtemplate'] as $key => $value) { - $xmlstr .= 'sccppath["tftp_DP"] . '/' . $put_file . '.xml'; - file_put_contents($file, $xmlstr); - } - - return $errors; + + $confDir = $this->sccppath["tftp_dialplan"]; + return $this->xmlinterface->save_DialPlan($confDir, $get_settings); } /* @@ -1907,33 +1917,38 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { if (empty($dev_id)) { return false; } - + $sccp_native = true; + $data_value = array(); + $dev_line_data = null; + $dev_config = $this->dbinterface->get_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); - +// Support Cisco Sip Device + if (!empty($dev_config['type'])) { + if (strpos($dev_config['type'],'sip') !== false) { + $sccp_native = false; + $data_tmp =$this->sipconfigs->getSipConfig(); + $dev_ext_config = $this->dbinterface->get_db_SccpTableData("SccpDevice", array('name' => $dev_id, 'fields'=>'sip_ext')); + $data_value = array_merge($data_value, $dev_ext_config, $data_tmp); + $data_tmp = explode(';',$dev_ext_config['sip_lines']); + foreach ($data_tmp as $value) { + $tmp_line = explode(',',$value); + if ($tmp_line[0] == 'line') { + $dev_line_data= $this->sipconfigs->get_db_sip_TableData('DeviceById',array('id'=>$tmp_line[1])); + if (!empty($dev_line_data)) { + $data_value['siplines'][] = $dev_line_data; + } + } + } +// return print_r($dev_line_data,true); + } + } foreach ($this->sccpvalues as $key => $value) { $data_value[$key] = $value['data']; } $data_value['ntp_timezone_id'] = $this->extconfigs->getextConfig('sccp_timezone', $data_value['ntp_timezone']); $data_value['server_if_list'] = $this->getIP_information2('ip4'); - $dev_config['tftp_path'] = $this->sccppath["tftp_path"]; + $dev_config = array_merge($dev_config, $this->sccppath); $dev_config['tftp_firmware'] = ''; - /* if (!empty($this->sccpvalues['tftp_rewrite'])) { - if ( $this->sccpvalues['tftp_rewrite']['data'] == 'internal' ) { - $dir_list = $this->find_all_files($dev_config['tftp_path'], $dev_config['loadimage']); - foreach ($dir_list as $filek){ - if (!empty($filek)) { - $fnd_path= ''; - $fnd_path = str_replace($dev_config['tftp_path'],'',$filek); - $fnd_path = substr($fnd_path,1,strpos($fnd_path, $dev_config['loadimage'])-1); - if (!empty($fnd_path)) { - $dev_config['tftp_firmware'] = $fnd_path; - } - break; - } - } - } - } - */ $dev_config['addon_info'] = array(); if (!empty($dev_config['addon'])) { $hw_addon = explode(',', $dev_config['addon']); @@ -1942,9 +1957,12 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $dev_config['addon_info'][$key] = $hw_data[0]['loadimage']; } } +// return print_r($dev_config,true); + $lang_data = $this->extconfigs->getextConfig('sccp_lang'); -// return $this->sccppath["tftp_path_store"]; - + if (!$sccp_native) { + return $this->xmlinterface->create_SEP_SIP_XML($this->sccppath["tftp_path_store"], $data_value, $dev_config, $dev_id, $lang_data); + } return $this->xmlinterface->create_SEP_XML($this->sccppath["tftp_path_store"], $data_value, $dev_config, $dev_id, $lang_data); } @@ -2068,10 +2086,16 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $search_mode = ''; if (!empty($this->sccpvalues['tftp_rewrite'])) { $search_mode = $this->sccpvalues['tftp_rewrite']['data']; - if ($search_mode == 'pro') { - $dir_list = $this->find_all_files($dir, $file_ext, 'fileonly'); - } else { - $dir_list = $this->find_all_files($dir, $file_ext); + switch ($search_mode) { + case 'pro': + case 'on': + case 'internal': + $dir_list = $this->find_all_files($dir, $file_ext, 'fileonly'); + break; + case 'off': + default: // Place in root TFTP dir + $dir_list = $this->find_all_files($dir, $file_ext); + break; } } else { $dir_list = $this->find_all_files($dir, $file_ext, 'fileonly'); @@ -2084,7 +2108,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $raw_settings[$i]['validate'] = '-;-'; if (!empty($raw_settings[$i]['loadimage'])) { $raw_settings[$i]['validate'] = 'no;'; - if ((strtolower($raw_settings[$i]['vendor'] == 'cisco')) || !empty($dir_list)) { + if (((strtolower($raw_settings[$i]['vendor']) == 'cisco') || (strtolower($raw_settings[$i]['vendor']) == 'cisco-sip')) && !empty($dir_list) ){ foreach ($dir_list as $filek) { switch ($search_mode) { case 'pro': diff --git a/Sccp_manager.inc/dbinterface.class.php b/Sccp_manager.inc/dbinterface.class.php index ee0bb0e..8173022 100644 --- a/Sccp_manager.inc/dbinterface.class.php +++ b/Sccp_manager.inc/dbinterface.class.php @@ -49,17 +49,59 @@ class dbinterface { $sql = "SELECT * FROM `sccpline` ORDER BY `name`"; $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); } else { - $sql = "SELECT * FROM `sccpline` WHERE `name`=" . $data['name']; + $sql = "SELECT * FROM `sccpline` WHERE `name`='" . $data['name']. "'";; $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`, `addon`, `_description` as description from `sccpdeviceconfig` ORDER BY `name`"; - $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + $filtred =''; + $singlrow = false; + if (empty($data['fields'])) { + $fld = '`name`,`name` as `mac`, `type`, `button`, `addon`, `_description` as description'; + } else { + switch ($data['fields']) { + case "all": + $fld ='*'; + break; + case "sip_ext": + $fld ='button as sip_lines, description as description, addon'; + break; + default: + $fld = $data['fields']; + break; + } + } + if (!empty($data['name'])) { + $filtred = "`name`='" . $data['name']. "'";; + $singlrow = true; + } + if (!empty($data['type'])) { + switch ($data['type']) { + case "cisco-sip": + $filtred = "`TYPE` LIKE '%-sip'"; + break; + case "cisco": + default: + $filtred = "`TYPE` not LIKE '%-sip'"; + break; + } + } + if (empty($filtred)) { + $sql = "SELECT ". $fld ." FROM `sccpdeviceconfig` ORDER BY `name`"; + } else { + $sql = "SELECT ". $fld ." FROM `sccpdeviceconfig` WHERE ".$filtred." ORDER BY `name`"; + } + if ($singlrow) { + $raw_settings = sql($sql, "getRow", DB_FETCHMODE_ASSOC); + } else { + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + } + break; + case "HWSipDevice": + $raw_settings = $this->getDb_model_info($get = "sipphones", $format_list = "model"); break; case "HWDevice": - $raw_settings = $this->getDb_model_info($get = "phones", $format_list = "model"); + $raw_settings = $this->getDb_model_info($get = "ciscophones", $format_list = "model"); break; case "HWextension": $raw_settings = $this->getDb_model_info($get = "extension", $format_list = "model"); @@ -169,6 +211,14 @@ class dbinterface { 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 "ciscophones": + $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (dns > 0) and (enabled > 0) AND `vendor` not LIKE '%-sip' ORDER BY model "; +// $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (enabled > 0) ORDER BY model "; + break; + case "sipphones": + $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (dns > 0) and (enabled > 0) AND `vendor` LIKE '%-sip' ORDER BY model "; // $sql = "SELECT " . $sel_inf . " FROM sccpdevmodel WHERE (enabled > 0) ORDER BY model "; break; case "all": diff --git a/Sccp_manager.inc/extconfigs.class.php b/Sccp_manager.inc/extconfigs.class.php index 5220621..d27b6cf 100644 --- a/Sccp_manager.inc/extconfigs.class.php +++ b/Sccp_manager.inc/extconfigs.class.php @@ -216,25 +216,25 @@ class extconfigs { // global $amp_conf; // *** Setings for Provision Sccp $adv_config = Array('tftproot' => '', 'firmware' => 'firmware', 'settings' => 'settings', - 'locales' => 'locales', 'languages' => 'languages', 'templates' => 'templates'); + 'locales' => 'locales', 'languages' => 'languages', 'templates' => 'templates', 'dialplan' => 'dialplan', 'softkey' => 'softkey'); // 'pro' /tftpboot - root dir // /tftpboot/locales/locales/%Languge_name% // /tftpboot/settings/XMLdefault.cnf.xml // /tftpboot/settings/SEP[MAC].cnf.xml // /tftpboot/firmware/79xx/SCCPxxxx.loads - $adv_tree['pro'] = Array('templates' => 'tftproot', 'settings' => 'tftproot', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'locales'); + $adv_tree['pro'] = Array('templates' => 'tftproot', 'settings' => 'tftproot', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'locales', 'dialplan' => 'tftproot', 'softkey' => 'tftproot'); // 'def' /tftpboot - root dir // /tftpboot/languages/%Languge_name% // /tftpboot/XMLdefault.cnf.xml // /tftpboot/SEP[MAC].cnf.xml // /tftpboot/SCCPxxxx.loads - $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => '', 'firmware' => '', 'languages' => 'tftproot'); + $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => '', 'firmware' => '', 'languages' => 'tftproot','dialplan' => '', 'softkey' => ''); // $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => ''); // $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'tftproot'); //* **************------ **** - $base_tree = Array('tftp_templates' => 'templates', 'tftp_path_store' => 'settings', 'tftp_lang_path' => 'languages', 'tftp_firmware_path' => 'firmware'); + $base_tree = Array('tftp_templates' => 'templates', 'tftp_path_store' => 'settings', 'tftp_lang_path' => 'languages', 'tftp_firmware_path' => 'firmware', 'tftp_dialplan' => 'dialplan', 'tftp_softkey' => 'softkey'); if (empty($confDir)) { return array('error' => 'empty СonfDir'); @@ -309,7 +309,8 @@ class extconfigs { } } } - + print_r($base_config,1); +// die(print_r($base_config,1)); // $base_config['External_ini'] = $adv_config; // $base_config['External_mode'] = $adv_tree_mode; diff --git a/Sccp_manager.inc/sipconfigs.class.php b/Sccp_manager.inc/sipconfigs.class.php new file mode 100644 index 0000000..461f8d3 --- /dev/null +++ b/Sccp_manager.inc/sipconfigs.class.php @@ -0,0 +1,104 @@ +paren_class = $parent_class; +// $freepbx +// $this->database = $freepbx->Database; + } + + public function info() { + $Ver = '13.0.4'; + return Array('Version' => $Ver, + 'about' => 'Sip Setings ver: ' . $Ver); + } + + public function get_db_sip_TableData($dataid, $data = array()) { + global $db; + if ($dataid == '') { + return False; + } + switch ($dataid) { + case "Device": + $sql = "SELECT * FROM sip ORDER BY `id`"; + $tech = array(); + try { + $raw_settings = sql($sql, "getAll", DB_FETCHMODE_ASSOC); + foreach ($raw_settings as $value) { + if (empty($tech[$value['id']]['id'])) { + $tech[$value['id']]['id']= $value['id']; + } + $tech[$value['id']][$value['keyword']]=$value['data']; + } + } catch (\Exception $e) { + + } + return $tech; + case "DeviceById": + $sql = "SELECT keyword,data FROM sip WHERE id = ?"; + $sth = $db->prepare($sql); + $tech = array(); + try { + $id = $data['id']; + $sth->execute(array($id)); + $tech = $sth->fetchAll(\PDO::FETCH_COLUMN | \PDO::FETCH_GROUP); + foreach ($tech as &$value) { + $value = $value[0]; + } + } catch (\Exception $e) { + + } + return $tech; + } + + } + + public function getSipConfig() { + $result = array(); + $def_sip_proto = 'sip'; + $def_proto = 'tcp'; + $supp_proto = ''; + + $result['sipport'] = \FreePBX::Sipsettings()->getConfig('bindport'); + $result['tlsport'] = \FreePBX::Sipsettings()->getConfig('tlsbindport'); + $tmp_sipsetigs = \FreePBX::Sipsettings()->getChanSipSettings(); + $tmp_sip_binds = \FreePBX::Sipsettings()->getBinds(); + + $tmp_bind_ip = !empty($tmp_sipsetigs['externhost_val']) ? $tmp_sipsetigs['externhost_val'] : ''; + $tmp_bind_ip = !empty($tmp_sipsetigs['externip_val']) ? $tmp_sipsetigs['externip_val'] : $tmp_bind_ip; + $tmp_bind_ip = !empty($tmp_sipsetigs['bindaddr']) ? $tmp_sipsetigs['bindaddr'] : $tmp_bind_ip; + +// $result['sipbind'] = $tmp_bind_ip; + if (empty($tmp_sip_binds[$def_sip_proto])){ + $def_proto = 'pjsip'; + } + + foreach ($tmp_sip_binds[$def_sip_proto] as $key => $value) { + if (empty($value[$def_proto])) { + $def_proto = 'udp'; + $supp_proto = 'udp'; + } else { + $supp_proto = !empty($value['udp']) ? 'tcp;udp' : 'tcp'; + } + if (empty($def_key)) { + $def_key = $key; + } + if ($key != '0.0.0.0') { + $tmp_bind_ip = $key; + } + $result['sipbindport'] = $value[$def_proto]; + } + $result['sipbind'] = $tmp_bind_ip; + $result['sipsuportproto'] = $supp_proto; + return $result; + } +} diff --git a/Sccp_manager.inc/xmlinterface.class.php b/Sccp_manager.inc/xmlinterface.class.php index 66bfb8c..88fa965 100644 --- a/Sccp_manager.inc/xmlinterface.class.php +++ b/Sccp_manager.inc/xmlinterface.class.php @@ -18,11 +18,11 @@ class xmlinterface { private $val_null = 'NONE'; /// REPLACE to null Field public function __construct($parent_class = null) { - $this->paren_class = $parent_class; + $this->paren_class = $parent_class; } public function info() { - $Ver = '13.0.3'; + $Ver = '13.0.4'; return Array('Version' => $Ver, 'about' => 'Create XML data interface ver: ' . $Ver); } @@ -49,7 +49,7 @@ class xmlinterface { if (!empty($value['ip'])) { $ip_valid = true; if (!empty($data_values['ccm_address'])) { - if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false ) { + if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false) { // Skip } else { if (strpos($data_values['ccm_address'], $value['ip']) === false) { @@ -90,7 +90,6 @@ class xmlinterface { $node = $xml_work->$value; unset($node[0][0]); } - } foreach ($def_xml_locale as $key) { if (!empty($xml_work->$key)) { @@ -137,7 +136,7 @@ class xmlinterface { } function create_SEP_XML($store_path = '', $data_values = array(), $dev_config = array(), $dev_id = '', $lang_info = array()) { - + $var_xml_general_fields = array('authenticationURL' => 'dev_authenticationURL', 'informationURL' => 'dev_informationURL', 'messagesURL' => 'dev_messagesURL', 'servicesURL' => 'dev_servicesURL', 'directoryURL' => 'dev_directoryURL', 'proxyServerURL' => 'dev_proxyServerURL', 'idleTimeout' => 'dev_idleTimeout', 'idleURL' => 'dev_idleURL', 'sshUserId' => 'dev_sshUserId', 'sshPassword' => 'dev_sshPassword', 'deviceProtocol' => 'dev_deviceProtocol', @@ -146,7 +145,7 @@ class xmlinterface { $var_xml_general_vars = array('capfAuthMode' => 'null', 'capfList' => 'null', 'mobility' => 'null', 'phoneServices' => 'null', 'certHash' => 'null', 'deviceSecurityMode' => '1'); - + // $var_hw_config = $this->dbinterface->get_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); if (empty($dev_config)) { @@ -199,14 +198,14 @@ class xmlinterface { } $xnode->name = $tz_id; $xnode->dateTemplate = $data_values['dateformat']; - $xnode->timeZone = $TZdata['cisco_code']; + $xnode->timeZone = $TZdata['cisco_code']; // $xnode->timeZone = $tz_id.' Standard'.((empty($TZdata['daylight']))? '': '/'.$TZdata['daylight']).' Time'; if ($data_values['ntp_config_enabled'] == 'yes') { $xnode->ntps->ntp->name = $data_values['ntp_server']; $xnode->ntps->ntp->ntpMode = $data_values['ntp_server_mode']; } else { - $xnode->ntps = ''; + $xnode->ntps = null; } // Ntp Config break; @@ -248,48 +247,65 @@ class xmlinterface { break; case 'callManagerGroup': $xnode = &$xml_node->$dkey->members; - if ($data_values['bindaddr'] == '0.0.0.0') { - $ifc = 0; - foreach ($data_values['server_if_list'] as $value) { - - if (!empty($value['ip'])) { - $ip_valid = true; - if (!empty($data_values['ccm_address'])) { - if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false ) { - // Skip - } else { - if (strpos($data_values['ccm_address'], $value['ip']) === false) { - $ip_valid = false; - } - } - } - if (!in_array($value['ip'], array('0.0.0.0', '127.0.0.1'), true) && ($ip_valid)) { - - $xnode_obj = clone $xnode->member; -// $xnode_obj = $xnode -> member; -// $xnode_obj = $xnode -> addChild($xnode->member); - $xnode_obj['priority'] = $ifc; - //$xnode_obj = &$xnode -> member -> callManager; - $xnode_obj->callManager->name = $data_values['servername']; - $xnode_obj->callManager->ports->ethernetPhonePort = $data_values['port']; - $xnode_obj->callManager->processNodeName = $value['ip']; - if ($ifc === 0) { - $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); - } else { - $this->appendSimpleXmlNode($xnode->member, $xnode_obj); - } - $ifc ++; - } - } + $bind_tmp = $this->get_server_sccp_bind($data_values); + $ifc = 0; + foreach ($bind_tmp as $bind_value) { + $xnode_obj = clone $xnode->member; + $xnode_obj['priority'] = $ifc; + $xnode_obj->callManager->name = $data_values['servername']; + $xnode_obj->callManager->ports->ethernetPhonePort = $bind_value['port']; + $xnode_obj->callManager->processNodeName = $bind_value['ip']; + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); } - } else { - $xnode->member['priority'] = '0'; - $xnode_obj = &$xnode->member->callManager; - $xnode_obj->name = $data_values['servername']; - $xnode_obj->ports->ethernetPhonePort = $data_values['port']; - $xnode_obj->processNodeName = $data_values['bindaddr']; + $ifc ++; } - break; + /* if ($data_values['bindaddr'] == '0.0.0.0') { + $ifc = 0; + foreach ($data_values['server_if_list'] as $value) { + + if (!empty($value['ip'])) { + $ip_valid = true; + if (!empty($data_values['ccm_address'])) { + if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false ) { + // Skip + } else { + if (strpos($data_values['ccm_address'], $value['ip']) === false) { + $ip_valid = false; + } + } + } + if (!in_array($value['ip'], array('0.0.0.0', '127.0.0.1'), true) && ($ip_valid)) { + + $xnode_obj = clone $xnode->member; + // $xnode_obj = $xnode -> member; + // $xnode_obj = $xnode -> addChild($xnode->member); + $xnode_obj['priority'] = $ifc; + //$xnode_obj = &$xnode -> member -> callManager; + $xnode_obj->callManager->name = $data_values['servername']; + $xnode_obj->callManager->ports->ethernetPhonePort = $data_values['port']; + $xnode_obj->callManager->processNodeName = $value['ip']; + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); + } + $ifc ++; + } + } + } + } else { + $xnode->member['priority'] = '0'; + $xnode_obj = &$xnode->member->callManager; + $xnode_obj->name = $data_values['servername']; + $xnode_obj->ports->ethernetPhonePort = $data_values['port']; + $xnode_obj->processNodeName = $data_values['bindaddr']; + } + break; + * + */ } } $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); @@ -300,7 +316,7 @@ class xmlinterface { case 'loadInformation': // Set Path Image ???? if (isset($dev_config["tftp_firmware"])) { - $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["tftp_firmware"].$dev_config["loadimage"] : ''; + $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["tftp_firmware"] . $dev_config["loadimage"] : ''; } else { $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["loadimage"] : ''; } @@ -319,10 +335,10 @@ class xmlinterface { break; case 'commonProfile': $xml_node->phonePassword = $data_values['dev_sshPassword']; - $xml_node->backgroundImageAccess = (($data_values['backgroundImageAccess'] =='on') || ($data_values['backgroundImageAccess'] =='true') ) ? 'true':'false'; + $xml_node->backgroundImageAccess = (($data_values['backgroundImageAccess'] == 'on') || ($data_values['backgroundImageAccess'] == 'true') ) ? 'true' : 'false'; $xml_node->callLogBlfEnabled = $data_values['callLogBlfEnabled']; break; - + case 'userLocale': case 'networkLocaleInfo': case 'networkLocale': @@ -336,19 +352,19 @@ class xmlinterface { } else { $lang = (empty($hwlang[1])) ? $data_values['devlang'] : $hwlang[1]; } - if (($lang != 'null') && (!empty($lang))) { - if ($key == 'networkLocale') { - $xml_work->$key = $lang; - } else { - if (isset($lang_info[$lang])) { - $xml_node->name = $lang_info[$lang]['locale']; - $xml_node->langCode = $lang_info[$lang]['code']; - if ($key == 'userLocale') { - $xml_node->winCharSet = $lang_info[$lang]['codepage']; - } - $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + if (($lang != 'null') && (!empty($lang))) { + if ($key == 'networkLocale') { + $xml_work->$key = $lang; + } else { + if (isset($lang_info[$lang])) { + $xml_node->name = $lang_info[$lang]['locale']; + $xml_node->langCode = $lang_info[$lang]['code']; + if ($key == 'userLocale') { + $xml_node->winCharSet = $lang_info[$lang]['codepage']; } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); } + } } else { $xml_work->$key = ''; } @@ -373,6 +389,461 @@ class xmlinterface { return time(); } + private function get_server_sccp_bind($data_values = array()) { + $res = array(); + + if ($data_values['bindaddr'] == '0.0.0.0') { + $ifc = 0; + foreach ($data_values['server_if_list'] as $value) { + if (!empty($value['ip'])) { + $ip_valid = true; + if (!empty($data_values['ccm_address'])) { + if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false) { + // Skip + } else { + if (strpos($data_values['ccm_address'], $value['ip']) === false) { + $ip_valid = false; + } + } + } + if (!in_array($value['ip'], array('0.0.0.0', '127.0.0.1'), true) && ($ip_valid)) { + $res[] = array('ip' => $value['ip'], 'port' => $data_values['port']); + } + } + } + } else { + $res[0] = array('ip' => $data_values['bindaddr'], 'port' => $data_values['port']); + } + return $res; + } + + private function get_server_sip_bind($data_values = array()) { + $res = array(); + + if (!empty($data_values['sipbind']) and ( $data_values['sipbind'] != '0.0.0.0')) { + $res[0] = array('ip' => $data_values['sipbind'], 'port' => $data_values['sipbindport'], 'tlsport' => $data_values['tlsport'], 'proto' => $data_values['sipsuportproto']); + } + + $ifc = 0; + foreach ($data_values['server_if_list'] as $value) { + if (!empty($value['ip'])) { + $ip_valid = true; + if (!empty($data_values['ccm_address'])) { + if (strpos($data_values['ccm_address'], 'internal') !== false || strpos($data_values['ccm_address'], '0.0.0.0') !== false) { + // Skip + } else { + if (strpos($data_values['ccm_address'], $value['ip']) === false) { + $ip_valid = false; + } + } + } + if (!in_array($value['ip'], array('0.0.0.0', '127.0.0.1', $data_values['sipbind']), true) && ($ip_valid)) { + $res[] = array('ip' => $value['ip'], 'port' => $data_values['sipbindport'], 'tlsport' => $data_values['tlsport'], 'proto' => $data_values['sipsuportproto']); + } + } + } + return $res; + } + + function create_SEP_SIP_XML($store_path = '', $data_values = array(), $dev_config = array(), $dev_id = '', $lang_info = array()) { + + $var_xml_general_fields = array('authenticationURL' => 'dev_authenticationURL', 'informationURL' => 'dev_informationURL', 'messagesURL' => 'dev_messagesURL', + 'servicesURL' => 'dev_servicesURL', 'directoryURL' => 'dev_directoryURL', 'proxyServerURL' => 'dev_proxyServerURL', 'idleTimeout' => 'dev_idleTimeout', + 'idleURL' => 'dev_idleURL', 'sshUserId' => 'dev_sshUserId', 'sshPassword' => 'dev_sshPassword', + 'phonePersonalization' => 'phonePersonalization' + ); + $var_xml_sipProfile = array('phoneLabel' => 'description', + 'transferOnhookEnabled' => 'transferOnhookEnabled', 'enableVad' => 'enableVad', 'voipControlPort' => 'sipport' + ); + $var_xml_sipline = array('name' => 'account', 'featureLabel' => 'account', 'displayName' => 'callerid', 'contact' => 'account', + 'authName' => 'account', 'authPassword' => 'secret'); + $var_xml_general_vars = array('capfAuthMode' => 'null', 'capfList' => 'null', 'mobility' => 'null', + 'phoneServices' => 'null', 'certHash' => 'null', 'deviceProtocol' => 'SIP', + 'deviceSecurityMode' => '1'); + +// $var_hw_config = $this->dbinterface->get_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); + + if (empty($dev_config)) { + return false; + } + $data_path = $dev_config['tftp_path']; + + if (empty($store_path) || empty($data_path) || empty($data_values) || empty($dev_id)) { + return; + } + + if (!empty($dev_config['nametemplate'])) { + $xml_template = $data_path . '/templates/' . $dev_config['nametemplate']; + if (!file_exists($xml_template)) { + $xml_template = $data_path . '/templates/SEP0000000000.cnf.xml_79df_sip_template'; + } + } else { + $xml_template = $data_path . '/templates/SEP0000000000.cnf.xml_79df_sip_template'; + } + $xml_name = $store_path . '/' . $dev_id . '.cnf.xml'; + $sip_bind = $this->get_server_sip_bind($data_values); + + if (file_exists($xml_template)) { + $xml_work = simplexml_load_file($xml_template); + + foreach ($var_xml_general_vars as $key => $data) { + if (isset($xml_work->$key)) { + if ($data != 'null') { + $xml_work->$key = $data; + } else { + $node = $xml_work->$key; + unset($node[0][0]); + } + } + } + + foreach ($xml_work as $key => $data) { +// Set System global Values + if (!empty($var_xml_general_fields[$key])) { + $xml_work->$key = $data_values[$var_xml_general_fields[$key]]; + } +// Set section Values + $xml_node = $xml_work->$key; + switch ($key) { + case 'devicePool': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + switch ($dkey) { + case 'dateTimeSetting': + $xnode = &$xml_node->$dkey; + $tz_id = $data_values['ntp_timezone']; + $TZdata = $data_values['ntp_timezone_id']; + if (empty($TZdata)) { + $TZdata = array('offset' => '0', 'daylight' => '', 'cisco_code' => 'Greenwich Standard Time'); + } +// $xnode->name = $tz_id; + $xnode->dateTemplate = $data_values['dateformat']; + $xnode->timeZone = $TZdata['cisco_code']; +// $xnode->timeZone = $tz_id.' Standard'.((empty($TZdata['daylight']))? '': '/'.$TZdata['daylight']).' Time'; + + if ($data_values['ntp_config_enabled'] == 'yes') { + $xnode->ntps->ntp->name = $data_values['ntp_server']; + $xnode->ntps->ntp->ntpMode = $data_values['ntp_server_mode']; + } else { + $xnode->ntps = null; + } + // Ntp Config + break; + /* case 'srstInfo': + if ($data_values['srst_Option'] == 'user') { + break; + } + $xnode = &$xml_node->$dkey; + $xnode->name = $data_values['srst_Name']; + $xnode->srstOption = $data_values['srst_Option']; + $xnode->userModifiable = $data_values['srst_userModifiable']; + $xnode->isSecure = $data_values['srst_isSecure']; + + $srst_fld = array('srst_ip' => array('ipAddr', 'port')); + // $srst_fld = array('srst_ip' => array('ipAddr','port') , 'srst_sip' => array('sipIpAddr','sipPort') ); + foreach ($srst_fld as $srst_pro => $srs_put) { + $srst_data = explode(';', $data_values[$srst_pro]); + $si = 1; + // $xnode['test'] = $srst_data[0]; + foreach ($srst_data as $value) { + $srs_val = explode('/', $value); + $nod = $srs_put[0] . $si; + $xnode->$nod = $srs_val[0]; + $nod = $srs_put[1] . $si; + $xnode->$nod = $srs_val[1]; + $si ++; + } + while ($si < 4) { + $nod = $srs_put[0] . $si; + $xnode->$nod = ''; + $nod = $srs_put[1] . $si; + $xnode->$nod = ''; + $si ++; + } + } + break; + case 'connectionMonitorDuration': + $xml_node->$dkey = strval(intval(intval($data_values['keepalive']) * 0.75)); + break; + */ + case 'callManagerGroup': + $xnode = &$xml_node->$dkey->members; + $ifc = 0; + foreach ($sip_bind as $bind_value) { + $xnode_obj = clone $xnode->member; + $xnode_obj['priority'] = $ifc; + $xnode_obj->callManager->name = $data_values['servername']; + $xnode_obj->callManager->ports->sipPort = $bind_value['port']; + $xnode_obj->callManager->ports->securedSipPort = $bind_value['tlsport']; + $xnode_obj->callManager->processNodeName = $bind_value['ip']; + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); + } + $ifc ++; + } + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + case 'sipProfile': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + if (!empty($var_xml_sipProfile[$dkey])) { + if (!empty($data_values[$var_xml_sipProfile[$dkey]])) { + $xml_node->$dkey = $data_values[$var_xml_sipProfile[$dkey]]; + } else { + $xml_node->$dkey = null; + } + } + switch ($dkey) { + case 'sipProxies': + $xnode = &$xml_node->$dkey; + $xnode->backupProxy = $sip_bind[0]['ip']; + $xnode->backupProxyPort = $sip_bind[0]['port']; + $xnode->emergencyProxy = $sip_bind[0]['ip']; + $xnode->emergencyProxyPort = $sip_bind[0]['port']; + $xnode->outboundProxy = $sip_bind[0]['ip']; + $xnode->outboundProxyPort = $sip_bind[0]['port']; + $xnode->registerWithProxy = "true"; + + break; + case 'sipLines': + $xnode = &$xml_node->$dkey; + $ifc = 0; + if (!empty($data_values['siplines'])) { + foreach ($data_values['siplines'] as $spkey => $spvalue) { + $xnode_obj = clone $xnode->line; + + $xnode_obj['button'] = $ifc + 1; + $xnode_obj['lineIndex'] = $ifc + 1; + //$xnode_obj->proxy = $data_values['bindaddr']; + if ($xnode_obj->proxy != 'USECALLMANAGER') { + $xnode_obj->proxy = $sip_bind[0]['ip']; + $xnode_obj->port = $sip_bind[0]['port']; + } + + foreach ($var_xml_sipline as $line_key => $line_val) { + $xnode_obj->$line_key = $spvalue[$line_val]; + } + + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->line, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->line, $xnode_obj); + } + $ifc ++; + } + } +// $xnode = &$xml_node->$dkey->members; + //$xnode = null; + break; + case 'softKeyFile': + case 'dialTemplate': // Доработать ! + $xml_ext_file = ''; + $templet_path = (($dkey == 'softKeyFile') ? $dev_config['tftp_softkey'] : $dev_config['tftp_dialplan']); + $tmp_key = ($dkey == 'softKeyFile') ? 'softkeyset' : '_dialrules'; + if (!empty($dev_config[$tmp_key])) { + $xml_ext_file = (($dkey == 'softKeyFile') ? 'softkey'.$dev_config[$tmp_key].'.xml' : $dev_config[$tmp_key].'.xml'); + } +// $xml_node->$dkey = $templet_path . '/' . $xml_ext_file.'---'.$dev_config[$tmp_key]; +// break; + if (empty($xml_ext_file) || !file_exists($templet_path . '/' . $xml_ext_file)) { + $xml_ext_file = (($dkey == 'softKeyFile') ? 'softkeydefault.xml' : 'dialplan.xml'); + } + if (file_exists($templet_path . '/' . $xml_ext_file)) { + $xml_node->$dkey = $xml_ext_file; + } else { + $xml_node->$dkey = null; + } + break; + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + + case 'versionStamp': + $xml_work->$key = time(); + break; + case 'loadInformation': +// Set Path Image ???? + if (isset($dev_config["tftp_firmware"])) { + $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["tftp_firmware"] . $dev_config["loadimage"] : ''; + } else { + $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["loadimage"] : ''; + } +// $xml_work->$key = $dev_config["loadimage"]; + if (!empty($dev_config['addon'])) { + $xnode = $xml_work->addChild('addOnModules'); + $ti = 1; + foreach ($dev_config['addon_info'] as $add_key => $add_val) { + $xnode_obj = $xnode->addChild('addOnModule'); + $xnode_obj->addAttribute('idx', $ti); + $xnode_obj->addChild('loadInformation', $add_val); + $ti ++; + } +// $this->appendSimpleXmlNode($xml_work , $xnode_obj); + } + break; + case 'commonProfile': + $xml_node->phonePassword = $data_values['dev_sshPassword']; + $xml_node->backgroundImageAccess = (($data_values['backgroundImageAccess'] == 'on') || ($data_values['backgroundImageAccess'] == 'true') ) ? 'true' : 'false'; + $xml_node->callLogBlfEnabled = $data_values['callLogBlfEnabled']; + break; + + case 'userLocale': + case 'networkLocaleInfo': + case 'networkLocale': + $hwlang = ''; + $lang = ''; + if (!empty($dev_config["_hwlang"])) { + $hwlang = explode(':', $dev_config["_hwlang"]); + } + if (($key == 'networkLocaleInfo') || ($key == 'networkLocale')) { + $lang = (empty($hwlang[0])) ? $data_values['netlang'] : $hwlang[0]; + } else { + $lang = (empty($hwlang[1])) ? $data_values['devlang'] : $hwlang[1]; + } + if (($lang != 'null') && (!empty($lang))) { + if ($key == 'networkLocale') { + $xml_work->$key = $lang; + } else { + if (isset($lang_info[$lang])) { + $xml_node->name = $lang_info[$lang]['locale']; + $xml_node->langCode = $lang_info[$lang]['code']; + if ($key == 'userLocale') { + $xml_node->winCharSet = $lang_info[$lang]['codepage']; + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + } + } + } else { + $xml_work->$key = ''; + } + break; +// Move all set to $var_xml_general_vars +// case 'mobility': +// case 'capfList': +// break; +// case 'phoneServices': +// break; +// $xml_work->$key = ''; + default: + break; + } + } + +// print_r($xml_work); + $xml_work->asXml($xml_name); // Save + } else { + die('Error Hardware template :' . $xml_template . ' not found'); + } + return time(); + } + + function save_DialPlan($confDir,$get_settings) { + $xmlstr = "\n"; + $xmlstr .= "".time()."\n"; + $dialFelds = array('match', 'timeout', 'rewrite', 'tone'); //str -to lo ! + + $hdr_prefix = 'sccp_dial_'; + $hdr_arprefix = 'sccp_dial-ar_'; + $save_data = array(); + $integer_msg = _("%s must be a non-negative integer"); + $errors = array(); + foreach ($get_settings[$hdr_arprefix . 'dialtemplate'] as $key => $value) { + $xmlstr .= ''Access error'.$name); + } + } + return array(); + } else { + return array('error'=>'Invalid softkey Name'.$name); + } + } + $errors = array(); + $xmlstr = "\n"; + $xmlstr .= "".time()."\n"; +// $xmlstr .= "\n"; + $typeSoft = $confDir["tftp_templates"].'/SIPTypeSoftKey.xml_template'; + $read_soft = ""; + if(file_exists($typeSoft)){ + $f_read = fopen($typeSoft,'r'); + while (!feof($f_read)) { + $read_soft .= fread($f_read, 8192); + } + fclose($f_read); + } + $xmlstr .= $read_soft; +// $xmlstr .= $read_soft."\n\n"; + $xmlstr .= " \n"; + foreach ($config[$name] as $key => $value) { + $xmlstr .=' '."\n"; + foreach (explode(",",$value) as $keyvalue ) { + $xmlstr .= ' '."\n"; + } + $xmlstr .=" \n"; + } + $xmlstr .= " \n"; + + $xmlstr .= ''; + if (empty($errors)) { +// $put_file = str_replace(array("\n", "\r", "\t", "/", "\\", ".", ","), '', $put_file); + $file = $confDir["tftp_softkey"] . '/softkey' . $name . '.xml'; + file_put_contents($file, $xmlstr); + } + + return $errors; + + } + private function replaceSimpleXmlNode($xml, $element = SimpleXMLElement) { $dom = dom_import_simplexml($xml); $import = $dom->ownerDocument->importNode( diff --git a/assets/js/sccp_manager.js b/assets/js/sccp_manager.js index 81640b4..735a7bb 100644 --- a/assets/js/sccp_manager.js +++ b/assets/js/sccp_manager.js @@ -65,6 +65,9 @@ $(document).ready(function () { if ($('.fpbx-submit').data('id') == "hw_edit") { snd_command = 'save_hardware'; } + if ($('.fpbx-submit').data('id') == "hw_sedit") { + snd_command = 'save_sip_hardware'; + } if ($('.fpbx-submit').data('id') == "ruser_edit") { snd_command = 'save_ruser'; } @@ -103,6 +106,9 @@ $(document).ready(function () { if ($('.fpbx-submit').data('id') == "hw_edit") { snd_command = 'save_hardware'; } + if ($('.fpbx-submit').data('id') == "hw_sedit") { + snd_command = 'save_sip_hardware'; + } if ($('.fpbx-submit').data('id') == "ruser_edit") { snd_command = 'save_ruser'; } diff --git a/conf/SEP0000000000.cnf.xml_791x_sip_template b/conf/SEP0000000000.cnf.xml_791x_sip_template new file mode 100644 index 0000000..a8a5edf --- /dev/null +++ b/conf/SEP0000000000.cnf.xml_791x_sip_template @@ -0,0 +1,300 @@ + + true + SIP + + + D/M/Y + + + + + unicast + + + + + + + + + 5060 + 5061 + + + + + + + + + + true + + + true + x-cisco-serviceuri-cfwdall + x-cisco-serviceuri-pickup + x-cisco-serviceuri-opickup + x-cisco-serviceuri-gpickup + x-cisco-serviceuri-meetme + x-cisco-serviceuri-abbrdial + false + 1 + true + true + 3 + 3 + 0 + true + false + 1 + + + 6 + 10 + 180 + 3600 + 5 + 120 + 120 + 5 + 500 + 4000 + 70 + true + Phone + + 1 + false + true + true + false + none + 101 + 3 + avt + false + false + 0 + + 0 + true + 15000 + 10 + false + 16384 + 32766 + false + false + + + + 9 + + USECALLMANAGER + 5060 + + + + 0 + + 3 + + + + false + 3 + 0 + + 4 + 5 + + true + true + false + true + + 5 + 4 + + + + 5060 + 184 + 0 + + + + 1 + + + + true + 2 + + + + false + false + false + true + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 0,1,2 + 1 + 1 + 1 + 0,1 + 0 + 0 + 0 + 1 + 1 + 10 + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + + 0 + 0 + 1 + 2 + 2 + 1 + 1 + 1,7 + 08:00 + 10:00 + 00:10 + 1 + 0 + 1,7 + 08:00 + 10:00 + 00:10 + 1 + 0 + 100 + 50 + + 5 + 0 + + + 1 + 0 + 1 + 0 + true + 0 + 2 + + 0 + 0 + + 0 + 0 + 0 + 1 + 1 + 1 + 1 + + d902ed5a-c1e5-4233-b1d6-a960d53d1c3a + + + 2 + + Missed Calls + Application:Cisco/MissedCalls + + + + + Received Calls + Application:Cisco/ReceivedCalls + + + + + Placed Calls + Application:Cisco/PlacedCalls + + + + + Voicemail + Application:Cisco/Voicemail + + + + + + + 1 + + + utf-8 + + + + + + + 1 + 0 + + + + + + + + + + + + + + 1 + 3600 + 1 + true + 0 + 0 + 1 + 5 + 1 + 0 + 0 + 0 + + + false + + + diff --git a/conf/SEP0000000000.cnf.xml_79df_sip_template b/conf/SEP0000000000.cnf.xml_79df_sip_template new file mode 100644 index 0000000..babaa5c --- /dev/null +++ b/conf/SEP0000000000.cnf.xml_79df_sip_template @@ -0,0 +1,255 @@ + + true + SIP + + + D/M/Y + + + + + unicast + + + + + + + + + 5060 + 5061 + + + + + + + + + + true + $ASTERISK + 5060 + $ASTERISK + 5060 + $ASTERISK + 5060 + + + true + x-cisco-serviceuri-cfwdall + x-cisco-serviceuri-pickup + x-cisco-serviceuri-opickup + x-cisco-serviceuri-gpickup + x-cisco-serviceuri-meetme + x-cisco-serviceuri-abbrdial + false + 1 + true + true + 3 + 3 + 0 + true + false + + + 6 + 10 + 180 + 3600 + 5 + 120 + 120 + 5 + 500 + 4000 + 70 + true + Phone + + 1 + false + true + true + false + g711alaw + 101 + 3 + avt + false + false + 0 + + 0 + true + 15000 + 10 + false + 16384 + 32766 + false + false + + + + 9 + + USECALLMANAGER + 5060 + + + + 0 + + 3 + + + + false + 3 + 0 + + 4 + 5 + + true + true + false + true + + 5 + 4 + + + + 5060 + 184 + 0 + + + + 1 + + + true + 2 + + + false + false + false + true + 0 + 1 + 0 + 1 + 0 + 1 + 0 + 1 + 1 + + 1 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 1 + 1 + 1,7 + 08:00 + 10:00 + 00:10 + 1 + 0 + 0 + 100 + 50 + + 5 + 0 + + 1 + 0 + 1 + 0 + + d902ed5a-c1e5-4233-b1d6-a960d53d1c3a + + + 2 + + Missed Calls + Application:Cisco/MissedCalls + + + + + Received Calls + Application:Cisco/ReceivedCalls + + + + + Placed Calls + Application:Cisco/PlacedCalls + + + + + Voicemail + Application:Cisco/Voicemail + + + + + + + 1 + + 10 + utf-8 + + + + + 10 + + 1 + 0 + + + + + + + + + + + + + + 1 + 3600 + 1 + true + 0 + 0 + 1 + 5 + 1 + 0 + 0 + 0 + + + false + + + diff --git a/conf/SIPDefaultSoftKey.xml_template b/conf/SIPDefaultSoftKey.xml_template new file mode 100644 index 0000000..22c35de --- /dev/null +++ b/conf/SIPDefaultSoftKey.xml_template @@ -0,0 +1,201 @@ + + 0200d4f8-e302-4315-b91e-9490e0b37fc5 + + + 0 + 0 + 0 + + + 1 + 1 + 301 + + + 2 + 2 + 302 + + + 3 + 3 + 303 + + + 4 + 4 + 304 + + + 5 + 5 + 305 + + + 8 + 8 + 308 + + + 9 + 9 + 309 + + + 10 + 10 + 310 + + + 11 + 11 + 311 + + + 13 + 13 + 313 + + + 14 + 14 + 314 + + + 15 + 15 + 315 + + + 16 + 16 + 316 + + + 17 + 17 + 317 + + + 18 + 18 + 318 + + + 57 + 19 + 319 + + + 63 + 69 + 369 + + + 65 + 20 + 320 + + + 75 + 22 + 322 + + + 76 + 27 + 327 + + + 78 + 29 + 329 + + + 79 + 30 + 330 + + + 80 + 31 + 331 + + + 91 + 34 + 334 + + + 92 + 35 + 335 + + + 7740 + 71 + 371 + + + 7747 + 74 + 374 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/SIPTypeSoftKey.xml_template b/conf/SIPTypeSoftKey.xml_template new file mode 100644 index 0000000..c330246 --- /dev/null +++ b/conf/SIPTypeSoftKey.xml_template @@ -0,0 +1,142 @@ + + + 0 + 0 + 0 + + + 1 + 1 + 301 + + + 2 + 2 + 302 + + + 3 + 3 + 303 + + + 4 + 4 + 304 + + + 5 + 5 + 305 + + + 8 + 8 + 308 + + + 9 + 9 + 309 + + + 10 + 10 + 310 + + + 11 + 11 + 311 + + + 13 + 13 + 313 + + + 14 + 14 + 314 + + + 15 + 15 + 315 + + + 16 + 16 + 316 + + + 17 + 17 + 317 + + + 18 + 18 + 318 + + + 57 + 19 + 319 + + + 63 + 69 + 369 + + + 65 + 20 + 320 + + + 75 + 22 + 322 + + + 76 + 27 + 327 + + + 78 + 29 + 329 + + + 79 + 30 + 330 + + + 80 + 31 + 331 + + + 91 + 34 + 334 + + + 92 + 35 + 335 + + + 7740 + 71 + 371 + + + 7747 + 74 + 374 + + diff --git a/conf/dialplan.xml_template b/conf/dialplan.xml_template new file mode 100644 index 0000000..e7a9ca4 --- /dev/null +++ b/conf/dialplan.xml_template @@ -0,0 +1,8 @@ + + e68d54c1-0354-4b1a-aca4-adffc4b7de2f +