diff --git a/Sccp_manager.class.php b/Sccp_manager.class.php index 4be5dab..04b6474 100644 --- a/Sccp_manager.class.php +++ b/Sccp_manager.class.php @@ -69,8 +69,6 @@ * + dir "templates" * + dir "firmware" * + dir "locales" - * + Create Simple User Interface - * + sccpsimple.xml * + Add error information on the server information page (critical display error - the system can not work correctly) * - Add Warning Information on Server Info Page * - ADD Reload Line @@ -86,17 +84,15 @@ namespace FreePBX\modules; class Sccp_manager extends \FreePBX_Helpers implements \BMO { /* Field Values for type seq */ - private $SCCP_LANG_DICTIONARY = 'be-sccp.jar'; // CISCO LANG file search in /tftp-path private $pagedata = null; private $sccp_driver_ver = '11.4'; // Ver fore SCCP.CLASS.PHP public $sccp_manager_ver = '14.1.0.0'; public $sccp_branch = 'm'; // Ver fore SCCP.CLASS.PHP - private $tftpLang = array(); + private $installedLangs = array(); 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(); private $cnf_wr = null; public $sccppath = array(); public $sccpvalues = array(); @@ -104,6 +100,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { public $xml_data; public $class_error; //error construct public $info_warning; + public $sccpHelpInfo = array(); // Move all non sccp_manager specific functions to traits use \FreePBX\modules\Sccp_Manager\sccpManTraits\helperFunctions; @@ -139,59 +136,50 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return; } - $this->sccpvalues = $this->dbinterface->get_db_SccpSetting(); // Overwrite Exist - $this->initializeSccpPath(); - $this->initVarfromDefs(); - $this->initTftpLang(); - - if (!empty($this->sccpvalues['SccpDBmodel'])) { - if ($this->sccpvalues['sccp_compatible']['data'] > $this->sccpvalues['SccpDBmodel']['data']) { - $this->sccpvalues['sccp_compatible']['data'] = $this->sccpvalues['SccpDBmodel']['data']; - } - } - // Load Advanced Form Constructor Data - if (empty($this->sccpvalues['displayconfig'])) { - $xml_vars = __DIR__ . '/conf/sccpgeneral.xml.v' . $this->sccpvalues['sccp_compatible']['data']; - } else { - $xml_vars = __DIR__ . '/conf/' . $this->sccpvalues['displayconfig']['data'] . '.xml.v' . $this->sccpvalues['sccp_compatible']['data']; - } - if (!file_exists($xml_vars)) { - $xml_vars = __DIR__ . '/conf/sccpgeneral.xml'; - } - if (file_exists($xml_vars)) { - $this->xml_data = simplexml_load_file($xml_vars); - $this->initVarfromXml(); // Overwrite Exist - } - - //if (get_class($freepbx) === 'FreePBX') { - // only save settings when building a new FreePBX object - $this->saveSccpSettings(); - //} + $this->sccpvalues = $this->dbinterface->get_db_SccpSetting(); //Initialise core settings + $this->initializeSccpPath(); //Set required Paths + $this->updateTimeZone(); // Get timezone from FreePBX + //$this->findInstLangs(); + $this->saveSccpSettings(); } /* * Generate Input elements in Html Code from sccpgeneral.xml */ - public function showGroup($group_name, $show_Header, $form_prefix = 'sccp', $form_values = null) { - $htmlret = ""; - if (empty($form_values)) { - $form_values = $this->sccpvalues; + public function showGroup($group_name, $show_Header, $form_prefix = 'sccp', $form_values = array()) { + + // load xml data - moved from Construct to simplify Construct. + // TODO: This is static data so only load first time. Left as is for dbug. + $xml_vars = __DIR__ . '/conf/sccpgeneral.xml.v433'; + $this->xml_data = simplexml_load_file($xml_vars); + // load metainfo from chan-sccp - help information if not in xml. Only load first time as static data. + if (empty($this->sccpHelpInfo)) { + $sysConfiguration = $this->aminterface->getSCCPConfigMetaData('general'); + + foreach ($sysConfiguration['Options'] as $key => $valueArray) { + foreach ($valueArray['Description'] as $descKey => $descValue) { + $this->sccpHelpInfo[$valueArray['Name']] .= $descValue . '
'; + } + } + unset($sysConfiguration); } + if ((array) $this->xml_data) { foreach ($this->xml_data->xpath('//page_group[@name="' . $group_name . '"]') as $item) { - $htmlret .= load_view(__DIR__ . '/views/formShow.php', array( + $htmlret = load_view(__DIR__ . '/views/formShowSysDefs.php', array( 'itm' => $item, 'h_show' => $show_Header, 'form_prefix' => $form_prefix, 'fvalues' => $form_values, - 'tftp_lang' => $this->tftpLang, - 'metainfo' => $this->sccp_metainfo - ) - ); + 'installedLangs' => $this->findInstLangs(), + 'chanSccpHelp' => $this->sccpHelpInfo, + 'sccp_defaults' => $this->sccpvalues + ) + ); } } else { - $htmlret .= load_view(__DIR__ . '/views/formShowError.php'); + $htmlret = load_view(__DIR__ . '/views/formShowError.php'); } return $htmlret; } @@ -200,70 +188,14 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { * Load config vars from base array */ - public function initVarfromDefs() { - foreach ($this->extconfigs->getextConfig('sccpDefaults') as $key => $value) { - if (empty($this->sccpvalues[$key])) { - $this->sccpvalues[$key] = array('keyword' => $key, 'data' => $value, 'type' => '0', 'seq' => '0'); - } - } - // Check timezone has not been changed in FreePBX and update if has - if ($this->sccpvalues['ntp_timezone'] != \date_default_timezone_get()) { - $this->sccpvalues['ntp_timezone'] = array('keyword' => 'ntp_timezone', 'seq'=>95, 'type' => 2, 'data' => \date_default_timezone_get()); - } - } - - /* - * Load config vars from xml - */ - - public function initVarfromXml() { - if ((array) $this->xml_data) { - foreach ($this->xml_data->xpath('//page_group') as $item) { - foreach ($item->children() as $child) { - $seq = 0; - if (!empty($child['seq'])) { - $seq = (string) $child['seq']; - } - if ($seq < 99) { - if ($child['type'] == 'IE') { - foreach ($child->xpath('input') as $value) { - $tp = 0; - if (empty($value->value)) { - $datav = (string) $value->default; - } else { - $datav = (string) $value->value; - } - if (strtolower($value->type) == 'number') { - $tp = 1; - } - if (empty($this->sccpvalues[(string) $value->name])) { - $this->sccpvalues[(string) $value->name] = array('keyword' => (string) $value->name, 'data' => $datav, 'type' => $tp, 'seq' => $seq); - } - } - } - if ($child['type'] == 'IS' || $child['type'] == 'IED') { - if (empty($child->value)) { - $datav = (string) $child->default; - } else { - $datav = (string) $child->value; - } - if (empty($this->sccpvalues[(string) $child->name])) { - $this->sccpvalues[(string) $child->name] = array('keyword' => (string) $child->name, 'data' => $datav, 'type' => '2', 'seq' => $seq); - } - } - if (in_array($child['type'], array('SLD', 'SLS', 'SLT', 'SL', 'SLM', 'SLZ', 'SLTZN', 'SLA'))) { - if (empty($child->value)) { - $datav = (string) $child->default; - } else { - $datav = (string) $child->value; - } - if (empty($this->sccpvalues[(string) $child->name])) { - $this->sccpvalues[(string) $child->name] = array('keyword' => (string) $child->name, 'data' => $datav, 'type' => '2', 'seq' => $seq); - } - } - } - } - } + public function updateTimeZone() { + // Get latest FreePBX time $timeZoneOffsetList + $freepbxTZ = \date_default_timezone_get(); + $this->sccpvalues['ntp_timezone'] = array('keyword' => 'ntp_timezone', 'seq'=>95, 'type' => 2, 'data' => $freepbxTZ); + $TZdata = $this->extconfigs->getExtConfig('sccp_timezone', $freepbxTZ); + if (!empty($TZdata)) { + $value = $TZdata['offset']/60; // TODO: Is this correct (storing in hours not minutes) + $this->sccpvalues['tzoffset'] = array('keyword' => 'tzoffset', 'seq'=>98, 'type' => 2, 'data' => $value); } } @@ -272,12 +204,13 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { */ public function settingsShowPage() { + $this->checkTftpMapping(); $request = $_REQUEST; $action = !empty($request['action']) ? $request['action'] : ''; $this->pagedata = array( "general" => array( - "name" => _("General SCCP Settings"), + "name" => _("Site Default Settings"), "page" => 'views/server.setting.php' ), "sccpdevice" => array( @@ -456,8 +389,8 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { 'monitor' => array('name' => 'Record Calls', 'value' => '') ); - // $lines_list = $this->dbinterface->HWextension_db_SccpTableData('SccpExtension'); - $max_btn = ((!empty($get_settings['buttonscount']) ? $get_settings['buttonscount'] : 100)); + // $lines_list = $this->dbinterface->getSccpDeviceTableData('SccpExtension'); + $max_btn = (!empty($get_settings['buttonscount']) ? $get_settings['buttonscount'] : 60); $last_btn = $max_btn; for ($it = $max_btn; $it >= 0; $it--) { if (!empty($get_settings['button' . $it . '_type'])) { @@ -501,7 +434,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { case 'monitor': $btn_t = 'speeddial'; $btn_opt = (string) $get_settings['button' . $it . '_line']; - $db_res = $this->dbinterface->HWextension_db_SccpTableData('SccpExtension', array('name' => $btn_opt)); + $db_res = $this->dbinterface->getSccpDeviceTableData('SccpExtension', array('name' => $btn_opt)); $btn_n = $db_res[0]['label']; $btn_opt .= ',' . $btn_opt . $this->hint_context['default']; break; @@ -556,246 +489,13 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { 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); + $res[] = array('ref' => $ref_id, 'reftype' => $ref_type, 'instance' => (string) ($it + 1), 'buttontype' => $btn_t, 'name' => $btn_n, 'options' => $btn_opt); } } } return $res; } - function saveSccpDevice($get_settings, $validateonly = false) { - $hdr_prefix = 'sccp_hw_'; - $hdr_arprefix = 'sccp_hw-ar_'; - - $save_buttons = array(); - $save_settings = array(); - $save_codec = array(); - $name_dev = ''; - $db_field = $this->dbinterface->HWextension_db_SccpTableData("get_columns_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') ? 'add' : 'clear'; // Possible values are delete, replace, add, clear. - $hw_prefix = 'SEP'; - if (!empty($get_settings[$hdr_prefix . 'type'])) { - $value = $get_settings[$hdr_prefix . 'type']; - if (strpos($value, 'ATA') !== false) { - $hw_prefix = 'ATA'; - } - if (strpos($value, 'VG') !== false) { - $hw_prefix = 'VG'; - } - } - foreach ($db_field as $data) { - $key = (string) $data['Field']; - $value = ""; - switch ($key) { - case 'name': - if (!empty($get_settings[$hdr_prefix . 'mac'])) { - $value = $get_settings[$hdr_prefix . 'mac']; - $value = strtoupper(str_replace(array('.', '-', ':'), '', $value)); // Delete mac Seporated from string - $value = sprintf("%012s", $value); - if ($hw_prefix == 'VG') { - $value = $hw_prefix . $value . '0'; - } else { - $value = $hw_prefix . $value; - } - $name_dev = $value; - } - break; - case 'disallow': - $value = $get_settings['sccp_disallow']; - break; - - case 'allow': - $i = 0; - if (!empty($get_settings['voicecodecs'])) { - foreach ($get_settings['voicecodecs'] as $keycodeс => $valcodeс) { - $save_codec[$i] = $keycodeс; - $i++; - }; - $value = implode(";", $save_codec); - } else { - $value = 'all'; // Bug If not System Codecs - } - 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'; - } 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; - // Злобный ХАК ?!TODO!? - 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 this device. - $this->dbinterface->write('sccpdevice', $save_settings, 'replace'); - // Retrieve the phone buttons and write back to - // update sccpdeviceconfig via Trigger - $save_buttons = $this->getPhoneButtons($get_settings, $name_dev, $hw_type); - $this->dbinterface->write('sccpbuttons', $save_buttons, $update_hw, '', $name_dev); - // Create new XML for this device, and then reset or restart the device - // so that it loads the file from TFT. - $this->createSccpDeviceXML($name_dev); - if ($hw_id == 'new') { - $this->aminterface->sccpDeviceReset($name_dev, 'reset'); - } else { - $this->aminterface->sccpDeviceReset($name_dev, 'restart'); - } - - return $save_settings; - } - - function handleSubmit($get_settings, $validateonly = false) { - $hdr_prefix = 'sccp_'; - $hdr_arprefix = 'sccp-ar_'; - $save_settings = array(); - $save_codec = array(); - $integer_msg = _("%s must be a non-negative integer"); - $errors = array(); - $i = 0; - foreach ($get_settings as $key => $value) { - $pos = strpos($key, $hdr_prefix); - if ($pos !== false) { - $key1 = substr_replace($key, '', 0, strlen($hdr_prefix)); - if (!empty($this->sccpvalues[$key1])) { - if (!($this->sccpvalues[$key1]['data'] == $value)) { - $save_settings[] = array('keyword' => $this->sccpvalues[$key1]['keyword'], 'data' => $value, - 'seq' => $this->sccpvalues[$key1]['seq'], 'type' => $this->sccpvalues[$key1]['type']); - } - } - } - $pos = strpos($key, $hdr_arprefix); - if ($pos !== false) { - $key1 = substr_replace($key, '', 0, strlen($hdr_arprefix)); - $arr_data = ''; - if (!empty($this->sccpvalues[$key1])) { - foreach ($value as $vkey => $vval) { - $tmp_data = ''; - foreach ($vval as $vkey => $vval) { - switch ($vkey) { - case 'inherit': - 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 (!($this->sccpvalues[$key1]['data'] == $arr_data)) { - $save_settings[] = array('keyword' => $this->sccpvalues[$key1]['keyword'], 'data' => $arr_data, - 'seq' => $this->sccpvalues[$key1]['seq'], 'type' => $this->sccpvalues[$key1]['type']); - } - } - } - switch ($key) { - case 'voicecodecs': - case 'vcodec': - foreach ($value as $keycodeс => $valcodeс) { - $save_codec[$i] = $keycodeс; - $i++; - }; - $tmpv = implode(";", $save_codec); - if ($tmpv !== $this->sccpvalues['allow']['data']) { - $save_settings[] = array('keyword' => 'allow', 'data' => $tmpv, - 'seq' => $this->sccpvalues['allow']['seq'], - 'type' => $this->sccpvalues['allow']['type']); - } - break; - - case 'sccp_ntp_timezone': - $tz_id = $value; - $TZdata = $this->extconfigs->getextConfig('sccp_timezone', $tz_id); - if (!empty($TZdata)) { - $value = $TZdata['offset']/60; - if (!($this->sccpvalues['tzoffset']['data'] == $value)) { - $save_settings[] = array('keyword' => 'tzoffset', 'data' => $value, - 'seq' => '98', - 'type' => '2'); - } - } - break; - } - } - if (!empty($save_settings)) { - $this->saveSccpSettings($save_settings); - $this->sccpvalues = $this->dbinterface->get_db_SccpSetting(); - } - $this->createDefaultSccpConfig(); // Rewrite Config. - $save_settings[] = array('status' => true); - return $save_settings; - } - function handleRoamingUsers($get_settings, $validateonly = false) { $hdr_prefix = 'sccp_ru_'; $hdr_arprefix = 'sccp_ru-ar_'; @@ -803,7 +503,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $save_buttons = array(); $save_settings = array(); $name_dev = ''; - $db_field = $this->dbinterface->HWextension_db_SccpTableData("get_columns_sccpuser"); + $db_field = $this->dbinterface->getSccpDeviceTableData("get_columns_sccpuser"); $hw_prefix = 'SEP'; $name_dev = $get_settings[$hdr_prefix . 'id']; $save_buttons = $this->getPhoneButtons($get_settings, $name_dev, 'sccpline'); @@ -815,13 +515,6 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { 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]; @@ -876,169 +569,107 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->dbinterface->write('sccpuser', $save_settings, 'replace', 'name'); $this->dbinterface->write('sccpbuttons', $save_buttons, 'delete', '', $name_dev); //standardise to delete return $save_buttons; - // Why is there a second return here??????? - return $save_settings; - } - - public function getMyConfig($var = null, $id = "noid") { - switch ($var) { - case "voicecodecs": - $val = explode(";", $this->sccpvalues['allow']['data']); - $final = array(); - $i = 1; - foreach ($val as $value) { - $final[$value] = $i; - $i++; - } - break; - case "softkeyset": - $final = array(); - $i = 0; - if ($id == "noid") { - foreach ($this->sccp_conf_init as $key => $value) { - if ($this->sccp_conf_init[$key]['type'] == 'softkeyset') { - $final[$i] = $value; - $i++; - } - } - } else { - if (!empty($this->sccp_conf_init[$id])) { - if ($this->sccp_conf_init[$id]['type'] == 'softkeyset') { - $final = $this->sccp_conf_init[$id]; - } - } - } - - break; - } - return $final; } public function getCodecs($type, $showDefaults = false) { $allSupported = array(); - $Sccp_Codec = array('alaw', 'ulaw', 'g722', 'g723', 'g726', 'g729', 'gsm', 'h264', 'h263', 'h261'); + $sccpCodec = array_fill_keys(array('alaw', 'ulaw', 'g722', 'g723', 'g726', 'g729', 'gsm', 'h264', 'h263', 'h261'),0); + // First see if have any site defaults + $val = $this->sccpvalues['allow']['data']; + if (empty($val)) { + // No site defaults so return chan-sccp defaults + $val = $this->sccpvalues['allow']['systemdefault']; + } + $siteCodecs = array_fill_keys(explode(';',$val), 1); switch ($type) { case 'audio': - $lcodecs = $this->getMyConfig('voicecodecs'); - $allCodecs = $this->FreePBX->Codecs->getAudio(); + $fpbxCodecs = $this->FreePBX->Codecs->getAudio(); break; case 'video': - $lcodecs = $this->getMyConfig('voicecodecs'); - $allCodecs = $this->FreePBX->Codecs->getVideo(); + $fpbxCodecs = $this->FreePBX->Codecs->getVideo(); break; case 'text': - $lcodecs = $this->getConfig('textcodecs'); - $allCodecs = $this->FreePBX->Codecs->getText(true); + $siteCodecs = $this->getConfig('textcodecs'); + $fpbxCodecs = $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')); + $siteCodecs = $this->getConfig('imagecodecs'); + $fpbxCodecs = $this->FreePBX->Codecs->getImage(true); break; } - foreach ($allCodecs as $c => $v) { - if (in_array($c, $Sccp_Codec)) { - $allSupported[$c] = $v; - } - } - if (empty($lcodecs) || (!is_array($lcodecs))) { - if (empty($allSupported)) { - $lcodecs = $allCodecs; - } else { - $lcodecs = $allSupported; - } - } else { - foreach ($lcodecs as $c => $v) { - if (isset($allSupported[$c])) { - $codecs[$c] = true; - } - } - } - if ($showDefaults) { - foreach ($allSupported as $c => $v) { - if (!isset($codecs[$c])) { - $codecs[$c] = false; - } - } + // Below could be squashed to 1 line, but would be unreadable. + // These have value set to 1 + $enabledCodecs = array_intersect_key($siteCodecs, $sccpCodec, $fpbxCodecs); + // These have value set to 0 + $allSupported = array_intersect_key($sccpCodec,$fpbxCodecs); + $disabledCodecs = array_diff_key($allSupported,$enabledCodecs); + $codecs = array_merge($enabledCodecs, $disabledCodecs); - return $codecs; - } else { - //Remove non digits - $final = array(); - foreach ($codecs as $codec => $order) { - $order = trim($order); - if (ctype_digit($order)) { - $final[$codec] = $order; - } - } - asort($final); - return $final; - } - } - - /** - * Update or Set Codecs - * @param {string} $type Codec Type - * @param {array} $codecs=array() The codecs with order, if blank set defaults - */ - public function setCodecs($type, $codecs = array()) { - $default = empty($codecs) ? true : false; - switch ($type) { - case 'audio': - $codecs = $default ? $this->FreePBX->Codecs->getAudio(true) : $codecs; - $this->setConfig("voicecodecs", $codecs); - break; - case 'video': - $codecs = $default ? $this->FreePBX->Codecs->getVideo(true) : $codecs; - $this->setConfig("videocodecs", $codecs); - break; - case 'text': - $codecs = $default ? $this->FreePBX->Codecs->getText(true) : $codecs; - $this->setConfig("textcodecs", $codecs); - break; - case 'image': - $codecs = $default ? $this->FreePBX->Codecs->getImage(true) : $codecs; - $this->setConfig("imagecodecs", $codecs); - break; - default: - throw new Exception(_('Unknown Type')); - break; - } - return true; + return $codecs; } /** * Retrieve Active Codecs - * return fiends Lag pack + * return finds Language pack */ - private function initTftpLang() { - $result = array(); - if (empty($this->sccppath["tftp_path"]) || empty($this->sccppath["tftp_lang_path"])) { - return; - } - $dir = $this->sccppath["tftp_lang_path"]; + private function findInstLangs() { + //locales and country tones are installed in the tftp_lang_path + //Available packs from provisioner are in masterFilesStructure.xml in tftpRoot Path + // TODO: Need to include this file as part of module in case download not allowed/available - $cdir = scandir($dir); - foreach ($cdir as $key => $value) { - if (!in_array($value, array(".", ".."))) { - if (is_dir($dir . DIRECTORY_SEPARATOR . $value)) { - $filename = $dir . DIRECTORY_SEPARATOR . $value . DIRECTORY_SEPARATOR . $this->SCCP_LANG_DICTIONARY; + $searchDir = '/'; //set default for when called by installer on virgin system + $result = array(); + + if (!file_exists("{$this->sccppath['tftp_path']}/masterFilesStructure.xml")) { + if (!$this->getFileListFromProvisioner()) { + // File does not exist and cannot get from internet. + return $result; + }; + } + $tftpBootXml = simplexml_load_file("{$this->sccppath['tftp_path']}/masterFilesStructure.xml"); + + foreach (array('languages', 'countries') as $pack) { + switch ($pack) { + case 'languages': + if (!empty($this->sccppath['tftp_lang_path'])) { + $searchDir = $this->sccppath['tftp_lang_path']; + } + $simpleXmlArr = $tftpBootXml->xpath("//Directory[@name='languages']//DirectoryPath[contains(.,'languages/')]"); + array_shift($simpleXmlArr); // First element is the parent directory + foreach ($simpleXmlArr as $rowIn) { + $tmpArr = explode('/',(string)$rowIn); + array_pop($tmpArr); //last element is empty + $result[$pack]['available'][] = array_pop($tmpArr); + } + $fileToFind = 'be-sccp.jar'; // This file should exist if the locale is populated + break; + case 'countries': + if (!empty($this->sccppath["tftp_countries_path"])) { + $searchDir = $this->sccppath['tftp_countries_path']; + } + $simpleXmlArr = $tftpBootXml->xpath("//Directory[@name='countries']//DirectoryPath[contains(.,'countries/')]"); + array_shift($simpleXmlArr); // First element is the parent directory + foreach ($simpleXmlArr as $rowIn) { + $tmpArr = explode('/',(string)$rowIn); + array_pop($tmpArr); //last element is empty + $result[$pack]['available'][] = array_pop($tmpArr); + } + $fileToFind = 'g3-tones.xml'; // This file should exist if the locale is populated + break; + } + + foreach (array_diff(scandir($searchDir),array('.', '..')) as $subDir) { + if (is_dir($searchDir . DIRECTORY_SEPARATOR . $subDir)) { + $filename = $searchDir . DIRECTORY_SEPARATOR . $subDir . DIRECTORY_SEPARATOR . $fileToFind; if (file_exists($filename)) { - $lang_ar = $this->extconfigs->getextConfig('sccp_lang'); - foreach ($lang_ar as $lang_key => $lang_value) { - if ($lang_value['locale'] == $value) { - $result[$lang_key] = $value; - } - } -// $result[] = $value; + $result[$pack]['have'][] = $subDir; } } } } - $this->tftpLang = $result; + $this->installedLangs = $result; + return $result; } /* @@ -1047,11 +678,11 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { private function initializeTFtpLanguagePath() { $dir = $this->sccppath["tftp_lang_path"]; - foreach ($this->extconfigs->getextConfig('sccp_lang') as $lang_key => $lang_value) { - $filename = $dir . DIRECTORY_SEPARATOR . $lang_value['locale']; - if (!file_exists($filename)) { - if (!mkdir($filename, 0777, true)) { - die('Error create lang dir'); + foreach ($this->extconfigs->getExtConfig('sccp_lang') as $langKey => $langValueArr) { + $localeDir = $dir . DIRECTORY_SEPARATOR . $langValueArr['locale']; + if (!is_dir($localeDir)) { + if (!mkdir($localeDir, 0755, true)) { + die("Error creating $localeDir directory"); } } } @@ -1061,43 +692,19 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { * Check file paths and permissions */ - // !TODO!: -TODO-: This function is getting a little big. Might be possible to sperate tftp work into it's own file/class. Initially, you need to remove the not working section and commented out section function initializeSccpPath() { - global $db; - global $amp_conf; - $driver_revision = array('0' => '', '430' => '.v431', '431' => '.v432', '432' => '.v432', '433' => '.v433' . $this->sccp_branch); - $confDir = $amp_conf["ASTETCDIR"]; - if (empty($this->sccppath["asterisk"])) { - if (strlen($confDir) < 1) { - $this->sccppath["asterisk"] = "/etc/asterisk"; - } else { - $this->sccppath["asterisk"] = $confDir; - } - } - $ver_id = $this->aminterface->get_compatible_sccp(); - if (!empty($this->sccpvalues['SccpDBmodel'])) { - $ver_id = $this->sccpvalues['SccpDBmodel']['data']; - } - - $driver = $this->FreePBX->Core->getAllDriversInfo(); - // Below is always set to replace; good for Develop, but needs to be updated for release - $sccp_driver_replace = ''; - if (empty($driver['sccp'])) { - $sccp_driver_replace = 'yes'; - } else { - if (empty($driver['sccp']['Version'])) { - $sccp_driver_replace = 'yes'; - } else { - if ($driver['sccp']['Version'] != $this->sccp_driver_ver . $driver_revision[$ver_id]) { - $sccp_driver_replace = 'yes'; - } - } - } - - $this->sccpvalues['sccp_compatible'] = array('keyword' => 'sccp_compatible', 'data' => $ver_id, 'type' => '1', 'seq' => '99'); - $this->sccppath = $this->extconfigs->validate_init_path($confDir, $this->sccpvalues, $sccp_driver_replace); - $driver = $this->FreePBX->Core->getAllDriversInfo(); // Check that Sccp Driver has been updated by above + $this->sccppath = array( + 'asterisk' => $this->sccpvalues['asterisk_etc_path']['data'], + 'tftp_path' => $this->sccpvalues['tftp_path']['data'], + 'tftp_templates_path' => $this->sccpvalues['tftp_templates_path']['data'], + 'tftp_store_path' => $this->sccpvalues['tftp_store_path']['data'], + 'tftp_lang_path' => $this->sccpvalues['tftp_lang_path']['data'], + 'tftp_firmware_path' => $this->sccpvalues['tftp_firmware_path']['data'], + 'tftp_dialplan_path' => $this->sccpvalues['tftp_dialplan_path']['data'], + 'tftp_softkey_path' => $this->sccpvalues['tftp_softkey_path']['data'], + 'tftp_countries_path' => $this->sccpvalues['tftp_countries_path']['data'] + ); $read_config = $this->cnf_read->getConfig('sccp.conf'); $this->sccp_conf_init['general'] = $read_config['general']; @@ -1132,21 +739,18 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { */ function getDialPlanList() { - $dir = $this->sccppath["tftp_dialplan"] . '/dial*.xml'; - $base_len = strlen($this->sccppath["tftp_dialplan"]) + 1; + $dir = $this->sccppath["tftp_dialplan_path"] . '/dial*.xml'; + $base_len = strlen($this->sccppath["tftp_dialplan_path"]) + 1; $res = glob($dir); - $dp_list = array(); foreach ($res as $key => $value) { $res[$key] = array('id' => substr($value, $base_len, -4), 'file' => substr($value, $base_len)); } - return $res; } function getDialPlan($get_file) { - $file = $this->sccppath["tftp_dialplan"] . '/' . $get_file . '.xml'; + $file = $this->sccppath["tftp_dialplan_path"] . '/' . $get_file . '.xml'; if (file_exists($file)) { -// $load_xml_data = simplexml_load_file($file); $fileContents = file_get_contents($file); $fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents); @@ -1158,50 +762,46 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } function deleteDialPlan($get_file) { - if (!empty($get_file)) { - $file = $this->sccppath["tftp_dialplan"] . '/' . $get_file . '.xml'; - if (file_exists($file)) { - $res = unlink($file); - } + $file = $this->sccppath["tftp_dialplan_path"] . '/' . $get_file . '.xml'; + if (file_exists($file)) { + $res = unlink($file); } return $res; } function saveDialPlan($get_settings) { - $confDir = $this->sccppath["tftp_dialplan"]; + $confDir = $this->sccppath["tftp_dialplan_path"]; return $this->xmlinterface->saveDialPlan($confDir, $get_settings); } /* - * Update Butons Labels on mysql DB + * Update buttons Labels on mysql DB */ private function updateSccpButtons($hw_list = array()) { $save_buttons = array(); + $button_list = array(); if (!empty($hw_list)) { - $buton_list = array(); foreach ($hw_list as $value) { - $buton_tmp = $this->dbinterface->HWextension_db_SccpTableData("get_sccpdevice_buttons", array('buttontype' => 'speeddial', 'id' => $value['name'])); - if (!empty($buton_tmp)) { - $buton_list = array_merge($buton_list, $buton_tmp); - } + $button_tmp = (array)$this->dbinterface->getSccpDeviceTableData("get_sccpdevice_buttons", array('buttontype' => 'speeddial', 'id' => $value['name'])); + $button_list = array_merge($button_list, $button_tmp); } } else { - $buton_list = $this->dbinterface->HWextension_db_SccpTableData("get_sccpdevice_buttons", array('buttontype' => 'speeddial')); + $button_list = $this->dbinterface->getSccpDeviceTableData("get_sccpdevice_buttons", array('buttontype' => 'speeddial')); } - if (empty($buton_list)) { + if (empty($button_list)) { return array('Response' => ' 0 buttons found ', '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) { + $copy_fld = array('ref', 'reftype', 'instance', 'buttontype', 'options'); + $extList = $extList = $this->dbinterface->get_db_SccpTableByID("SccpExtension", array(), 'name'); + foreach ($button_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']; + if (!empty($extList[$btn_id])) { + if ($extList[$btn_id]['label'] != $value['name']) { + $btn_data['name'] = $extList[$btn_id]['label']; foreach ($copy_fld as $ckey) { $btn_data[$ckey] = $value[$ckey]; } @@ -1221,10 +821,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { */ private function saveSccpSettings($save_value = array()) { -// global $db; -// global $amp_conf; -// $save_settings = array(); if (empty($save_value)) { $this->dbinterface->write('sccpsettings', $this->sccpvalues, 'replace'); //Change to replace as clearer } else { @@ -1249,10 +846,10 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $model_information = $this->getSccpModelInformation($get = "all", $validate = false); // Get All } - $lang_data = $this->extconfigs->getextConfig('sccp_lang'); + $lang_data = $this->extconfigs->getExtConfig('sccp_lang'); $data_value['tftp_path'] = $this->sccppath["tftp_path"]; - $this->xmlinterface->create_default_XML($this->sccppath["tftp_path_store"], $data_value, $model_information, $lang_data); + $this->xmlinterface->create_default_XML($this->sccppath["tftp_store_path"], $data_value, $model_information, $lang_data); } /* @@ -1268,13 +865,13 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $data_value = array(); $dev_line_data = null; - $dev_config = $this->dbinterface->HWextension_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); + $dev_config = $this->dbinterface->getSccpDeviceTableData("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; $tmp_bind = $this->sipconfigs->getSipConfig(); - $dev_ext_config = $this->dbinterface->HWextension_db_SccpTableData("SccpDevice", array('name' => $dev_id, 'fields' => 'sip_ext')); + $dev_ext_config = $this->dbinterface->getSccpDeviceTableData("SccpDevice", array('name' => $dev_id, 'fields' => 'sip_ext')); $data_value = array_merge($data_value, $dev_ext_config); $data_tmp = explode(';', $dev_ext_config['sip_lines']); $data_value['sbind'] = array(); @@ -1308,12 +905,11 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } } } - foreach ($this->sccpvalues as $key => $value) { $data_value[$key] = $value['data']; } //Get Cisco Code only Old Device - $data_value['ntp_timezone_id'] = $this->extconfigs->getextConfig('sccp_timezone', $data_value['ntp_timezone']); // Old Cisco Device + $data_value['ntp_timezone_id'] = $this->extconfigs->getExtConfig('sccp_timezone', $data_value['ntp_timezone']); // Old Cisco Device // $data_value['ntp_timezone_id'] = $data_value['ntp_timezone']; // New Cisco Device ! // $data_value['ntp_timezone_id'] = // SPA Cisco Device ! $data_value['server_if_list'] = $this->getIpInformation('ip4'); @@ -1328,11 +924,11 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } } - $lang_data = $this->extconfigs->getextConfig('sccp_lang'); + $lang_data = $this->extconfigs->getExtConfig('sccp_lang'); 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_SIP_XML($this->sccppath["tftp_store_path"], $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); + return $this->xmlinterface->create_SEP_XML($this->sccppath["tftp_templates_path"], $data_value, $dev_config, $dev_id, $lang_data); } function deleteSccpDeviceXML($dev_id = '') { @@ -1340,17 +936,17 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { return false; } if ($dev_id == 'all') { - $xml_name = $this->sccppath["tftp_path_store"] . '/SEP*.cnf.xml'; + $xml_name = $this->sccppath["tftp_store_path"] . '/SEP*.cnf.xml'; array_map("unlink", glob($xml_name)); - $xml_name = $this->sccppath["tftp_path_store"] . '/ATA*.cnf.xml'; + $xml_name = $this->sccppath["tftp_store_path"] . '/ATA*.cnf.xml'; array_map("unlink", glob($xml_name)); - $xml_name = $this->sccppath["tftp_path_store"] . '/VG*.cnf.xml'; + $xml_name = $this->sccppath["tftp_store_path"] . '/VG*.cnf.xml'; array_map("unlink", glob($xml_name)); } else { if (!strpos($dev_id, 'SEP')) { return false; } - $xml_name = $this->sccppath["tftp_path_store"] . '/' . $dev_id . '.cnf.xml'; + $xml_name = $this->sccppath["tftp_store_path"] . '/' . $dev_id . '.cnf.xml'; if (file_exists($xml_name)) { unlink($xml_name); } @@ -1428,14 +1024,17 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { $this->sccp_conf_init['general'][$key] = explode(';', $content); break; case "devlang": - $lang_data = $this->extconfigs->getextConfig('sccp_lang', $value['data']); + /* + $lang_data = $this->extconfigs->getExtConfig('sccp_lang', $value['data']); if (!empty($lang_data)) { + // TODO: will always get here, but lang_data['codepage'] will be empty as not a valid key $this->sccp_conf_init['general']['phonecodepage'] = $lang_data['codepage']; } break; + */ case "netlang": // Remove Key case "tftp_path": - case "sccp_compatible": + case "sccp_compatible": // This is equal to SccpDBmodel break; default: if (!empty($value['data'])) { @@ -1461,77 +1060,66 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { ); } // ----- It is a very bad idea to add an external configuration file "sccp_custom.conf" !!!! - + // TODO: Should only rewrite the general section - if users have extensions, this may overwrite + // Should read first and then rewrite all existing sections. $this->cnf_wr->writeConfig('sccp.conf', $this->sccp_conf_init); } function getSccpModelInformation($get = "all", $validate = false, $format_list = "all", $filter = array()) { - // $file_ext = array('.loads', '.LOADS', '.sbn', '.SBN', '.bin', '.BIN','.zup','.ZUP'); - $file_ext = array('.loads', '.sbn', '.bin', '.zup'); - // $dir = $this->sccppath["tftp_path"]; - $dir = $this->sccppath["tftp_firmware_path"]; - $dir_tepl = $this->sccppath["tftp_templates"]; + $file_ext = array('.loads', '.sbn', '.bin', '.zup', '.sbin', '.SBN', '.LOADS'); + $dir = $this->sccppath['tftp_firmware_path']; - $search_mode = ''; - if (!empty($this->sccpvalues['tftp_rewrite'])) { - $search_mode = $this->sccpvalues['tftp_rewrite']['data']; - switch ($search_mode) { - case 'pro': - case 'on': - case 'internal': - $dir_list = $this->findAllFiles($dir, $file_ext, 'fileonly'); - break; - case 'off': - default: // Place in root TFTP dir - $dir_list = $this->findAllFiles($dir, $file_ext); - break; - } - } else { - $dir_list = $this->findAllFiles($dir, $file_ext, 'fileonly'); + $search_mode = $this->sccpvalues['tftp_rewrite']['data']; + switch ($search_mode) { + case 'pro': + case 'on': + case 'internal': + $dir_list = $this->findAllFiles($dir, $file_ext, 'fileBaseName'); + break; + case 'off': + default: // Place in root TFTP dir + $dir_list = $this->findAllFiles($dir, $file_ext, 'dirFileBaseName'); + break; } - $raw_settings = $this->dbinterface->getDb_model_info($get, $format_list, $filter); + $modelList = $this->dbinterface->getDb_model_info($get, $format_list, $filter); if ($validate) { - for ($i = 0; $i < count($raw_settings); $i++) { - $raw_settings[$i]['validate'] = '-;-'; - if (!empty($raw_settings[$i]['loadimage'])) { - $raw_settings[$i]['validate'] = 'no;'; - 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': - case 'on': - case 'internal': - if (strpos(strtolower($filek), strtolower($raw_settings[$i]['loadimage'])) !== false) { - $raw_settings[$i]['validate'] = 'yes;'; - } - break; - case 'internal2': - break; - case 'off': - default: // Place in root TFTP dir - if (strpos(strtolower($filek), strtolower($dir . '/' . $raw_settings[$i]['loadimage'])) !== false) { - $raw_settings[$i]['validate'] = 'yes;'; - } - break; + foreach ($modelList as &$raw_settings) { + if (!empty($raw_settings['loadimage'])) { + $raw_settings['validate'] = 'no;'; + switch ($search_mode) { + case 'pro': + case 'on': + case 'internal': + if (in_array($raw_settings['loadimage'], $dir_list, true)) { + $raw_settings['validate'] = 'yes;'; } - } + break; + case 'internal2': + break; + case 'off': + default: // Place in root TFTP dir + if (in_array("{$dir}/{$raw_settings['loadimage']}", $dir_list, true)) { + $raw_settings['validate'] = 'yes;'; + } + break; } } else { - $raw_settings[$i]['validate'] = '-;'; + $raw_settings['validate'] = '-;'; } - if (!empty($raw_settings[$i]['nametemplate'])) { - $file = $dir_tepl . '/' . $raw_settings[$i]['nametemplate']; + if (!empty($raw_settings['nametemplate'])) { + $file = $this->sccppath['tftp_templates_path'] . '/' . $raw_settings['nametemplate']; if (file_exists($file)) { - $raw_settings[$i]['validate'] .= 'yes'; + $raw_settings['validate'] .= 'yes'; } else { - $raw_settings[$i]['validate'] .= 'no'; + $raw_settings['validate'] .= 'no'; } } else { - $raw_settings[$i]['validate'] .= '-'; + $raw_settings['validate'] .= '-'; } } } - return $raw_settings; + unset($raw_settings); // passed as reference so must unset. + return $modelList; } function getHintInformation($sort = true, $filter = array()) { @@ -1547,7 +1135,7 @@ class Sccp_manager extends \FreePBX_Helpers implements \BMO { } // Update info from sccp_db - $tmp_data = $this->dbinterface->HWextension_db_SccpTableData('SccpExtension'); + $tmp_data = $this->dbinterface->getSccpDeviceTableData('SccpExtension'); foreach ($tmp_data as $value) { $name_l = $value['name']; if (!empty($res[$name_l . $default_hint])) { diff --git a/Technical.notes/SEP0000000000.cnf.xml_annotated b/Technical.notes/SEP0000000000.cnf.xml_annotated index fa5a73f..1b0401f 100644 --- a/Technical.notes/SEP0000000000.cnf.xml_annotated +++ b/Technical.notes/SEP0000000000.cnf.xml_annotated @@ -95,98 +95,98 @@ true 2 - + - 1 - false false 0 - + 1 - + 0 - + --> + 0 - - 1 - - + 0 - - 0 + + 0 - + 1,7 08:00 12:00 @@ -200,52 +200,52 @@ - + - + - + - + 1 - + 2 @@ -256,10 +256,10 @@ 1 1 - - + 0 22 0 0 @@ -300,11 +300,11 @@ @@ -331,7 +331,7 @@ --> @@ -420,10 +420,10 @@ {Jan 01 2003 00:00:00} P00308010100 - http://x.x.x.x/cisco_menu/idle.php 3600 1 1 + 1 1 false 1 1 - 1 + 1 @@ -488,7 +494,7 @@ *84 *85 - + 104 0 184 @@ -508,7 +514,7 @@ 1 = Use ServicerURL / DirectoryURL and MessagesURL (Above) 2 = Use Both (Merge Both) --> - + + + - + mac - 000000000 + sccp-custom + - The MAC address of the phone. You must specify 12 characters in the format XXXX.XXXX.XXXX or XX-XX-XX-XX-XX-XX or XXXXXXXXXXXX + The MAC address of the phone. You must specify 12 characters in the format XXXX.XXXX.XXXX, XX:XX:XX:XX:XX:XX, XX-XX-XX-XX-XX-XX or XXXXXXXXXXXX - type 7911 - hw_select sccp-custom + hw_select form-control The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. @@ -1282,7 +1283,7 @@ and open the template in the editor. Base Version before all crash :-) addon NONE - hw_select sccp-custom + hw_select form-control Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. @@ -1290,25 +1291,15 @@ and open the template in the editor. Base Version before all crash :-) - + mac - 000000000 + sccp-custom The MAC address of the phone - - - type - 7911 - - - hw_select sccp-custom - The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. - - @@ -1319,31 +1310,36 @@ and open the template in the editor. Base Version before all crash :-) The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. - + - - addon - NONE - sccp-custom - - + addon + NONE + + hw_select form-control Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. - - _description + description 000000000 sccp-custom The information in the upper right corner of the device screen. Only English letters and digits ! + + + defaultLine + + + lineSelect form-control + Select the default line for this device + softkeyset @@ -1358,19 +1354,27 @@ and open the template in the editor. Base Version before all crash :-) Time Zone offset - + + + devlang + English_United_States + + The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. If No language packs found is shown, you need to add locales in the tftp server + + netlang English_United_States - The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. + The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. If No language packs found is shown, you need to add locales in the tftp server - - - devlang - Russian_Russia - - The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. + + phonepersonalization + + + + + This needs to be enabled to allow the server to push background or ringtones to the phone in the SEPXXXXXXXXXX.cnf.xml of each phone: @@ -1388,14 +1392,14 @@ and open the template in the editor. Base Version before all crash :-) sccp-custom - The ringtone that the phone will default to. Can be overridden in the phone. The files RINGLIST.XML provice the basic phone ring tones, while DISTINCTIVERINGLIST.XML defines the list of possible ring tones for your other line types. They, along with the actual 'raw' ringtones, are stored in the /tftpboot/ringtones directory with the rest of the config files. + The ringtone that the phone will default to. Can be overridden in the phone. The files RINGLIST.XML provides the basic phone ring tones, while DISTINCTIVERINGLIST.XML defines the list of possible ring tones for your other line types. They, along with the actual 'raw' ringtones, are stored in the /tftpboot/ringtones directory with the rest of the config files. - + - + mac 000000000 @@ -1403,24 +1407,22 @@ and open the template in the editor. Base Version before all crash :-) - + transfer off - - - + + Transfer allowed park on - Inherit Take a look to the compile how-to. Park stuff is not compiled by default. @@ -1429,34 +1431,30 @@ and open the template in the editor. Base Version before all crash :-) cfwdall off - - - + + Activate the callforward softkeys. Default is On cfwdbusy off - - - + + Activate the callforward busy softkeys. Default is On cfwdnoanswer on - - - + + Activate the callforward NOANSWER stuff and softkeys. Default is On - dndFeature + dnd off - Do Not Disturb. Default is Off @@ -1472,16 +1470,14 @@ and open the template in the editor. Base Version before all crash :-) - - useRedialMenu off - - + + You can specifying 'useRedialMenu = yes' in the sccp.conf device section and the redial softkey will cause the "placed calls" list instead of immediately calling the last dialed number. @@ -1497,7 +1493,6 @@ and open the template in the editor. Base Version before all crash :-) mwioncall on - Set the MWI on call. @@ -1507,7 +1502,6 @@ and open the template in the editor. Base Version before all crash :-) mwilamp on - @@ -1523,9 +1517,8 @@ and open the template in the editor. Base Version before all crash :-) - + Do not update history for this Phonebook if answered by another extension - @@ -1533,7 +1526,7 @@ and open the template in the editor. Base Version before all crash :-) conf_play_general_announce - + on @@ -1541,7 +1534,7 @@ and open the template in the editor. Base Version before all crash :-) conf_play_part_announce - + on @@ -1571,8 +1564,10 @@ and open the template in the editor. Base Version before all crash :-) form-control Play music on hold of this class when no moderator is listening on the conference. If set to an empty string, no music on hold will be played. - + + + custom_network_acc @@ -1607,7 +1602,6 @@ and open the template in the editor. Base Version before all crash :-) Help. - @@ -1627,10 +1621,8 @@ and open the template in the editor. Base Version before all crash :-) Add Deny network All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. - - permit NONE Inherit @@ -1649,42 +1641,44 @@ and open the template in the editor. Base Version before all crash :-) Add Allow network Allow network settings. Blank fields will be ignored used Network 0.0.0.0. - nat auto - Device NAT support (default Auto) - directrtp - off - Auto - - - + + + This option allow devices to do direct RTP sessions (default Off) earlyrtp - NONE - - Immediate - - - - - - The audio stream will be open in the progress and connected state. Valid options: none, progress, offhook, dial, ringout. Default may be Progress. + + + + The audio stream will be open in the progress and connected state. Valid options: Yes/ No + + + + + keepalive + 60 + sccp-custom + number + + + Time between Keep Alive checks. Valid range is 60-300 seconds. After much trial-and-error, the minimum (60) seems to work just fine. + @@ -1695,8 +1689,8 @@ and open the template in the editor. Base Version before all crash :-) Help. - + @@ -1767,7 +1761,6 @@ and open the template in the editor. Base Version before all crash :-) - dialtemplate */10/* @@ -1814,9 +1807,7 @@ and open the template in the editor. Base Version before all crash :-) CallWaiting-4 Allow network settings. Blank fields will be ignored used Network 0.0.0.0. - - - - - - XML_info - - NONE - - - - - - - - - - - - dev_sshUserId - cisco - - Help. - - - - - dev_sshPassword - cisco - - Help. - - - - - dev_deviceProtocol - SCCP - - Help. - - - - - sccp_xml_about - XML Base ver: 11.2, Sccp ver: 431 - - Help. - - - - - autoanswer_tone - 0x32 - sccp-custom - - Autoanswer Tone: The tone the phone plays back when it picks up the phone in autoanswer mode. Default is '0x32'. Silence is '0x00'. There are lots of tones, all expressed as '0XNN' where 'NN' is a hexadecimal number. - - - - - remotehangup_tone - 0x32 - sccp-custom - - Remote Hangup Tone: The tone played by the phone when it received a remote hang-up signal. Use '0' to disable the tone. - - - - - transfer_tone - 0x32 - sccp-custom - - Transfer Tone: The tone played when a call is transferred. Use '0' to disable the tone. - - - - - callwaiting_tone - 0x2D - sccp-custom - - Call Waiting Tone: The tone played when a call is waiting. If you set this one to '0', you will not get a tone in your current call if a new call comes in, so you might want to disable call waiting for this line instead. - - - - - - - sccp_tos - 0x68 - sccp-custom - - - sccp_cos - 0x4 - sccp-custom - - SCCP Type Of Service / Class Of Service: SCCP Type or Class of Service - this is modifiable, but don't. - - - - - audio_tos - 0xB8 - sccp-custom - - - audio_cos - 0x6 - sccp-custom - - Audio Type Of Service / Class Of Service: Audio Type or Class of Service - this is modifiable, but don't. - - - - - video_tos - 0x88 - sccp-custom - - - video_cos - 0x5 - sccp-custom - - Video Type Of Service / Class Of Service: Video Type or Class of Service - this is modifiable, but don't. - - - - - - linetable - sccpline - sccp-custom - - Line Table: This is the linetable for your realtime configuration. Don't change this unless you know what you are doing and have made all the appropriate changes in the rest of your Asterisk config files. If you do not want to use the realtime database anymore, you can set this to blank. NOT RECOMMENDED. - - - - devicetable - sccpdevice - - - sccp-custom - Device Table: This is the devicetable for your realtime configuration. Don't change this unless you know what you are doing and have made all the appropriate changes in the rest of your Asterisk config files. There are two reasonable settings for this - the sccpdevice table or the sccpdeviceconfig view. If you do not want to use the realtime database anymore, you can set this to blank. NOT RECOMMENDED. - - - callhistory_answered_elsewhere - - Missed Calls - - - - - - - - callLogBlfEnabled - - 2 - - - Which does show numbers you can redial, but also include their current device state, so you know when they are currently busy. Note that the other phonebook entries will now also monitor the remove device state and show the current device state - - - - - - - - - - - - - - servername - Vt - - Servername: This is the type of server - usually, it will be Asterisk. - - - - - bindaddr - 0.0.0.0 - sccp-custom - - - port - 2000 - sccp-custom - - Bind Address: The address to bind to for SCCP. In general, it should be set to '0.0.0.0'. If you find problems with one-way audio, you can set this to a specific address in the server. Note that '127.0.0.1' is always wrong here. Also note that placing in your external IP address will cause the chan_sccp module to not load. A manual edit of the /etc/asterisk/sccp.conf file will be needed to fix and reload the module. - : - - - - - externip - - sccp-custom - - - External IP Address of the firewall, required in case the PBX is running on a separate host behind it. IP Address that we're going to notify in RTP media stream as the pbx source address. - / - - - - - keepalive - 60 - sccp-custom - number - - - Time between Keep Alive checks. Valid range is 60-300 seconds. After much trial-and-error, the minimum (60) seems to work just fine. - - - nat - - auto - - - - Global NAT support (default Auto) - - - debug - - NONE - - - - - - Debug: Enable debugging level in SCCP module. - - - displayconfig - - sccpgeneral - - - Help! - - - - - - - permit - Internal - 0.0.0.0/0.0.0.0 - - - - - - - + - Add Allow Range - Allow network settings. Blank fields will be ignored used Network 0.0.0.0/0.0.0.0 to resolve any existing connections. You can use the 'internal' connections only from the networks connected to the server. - - - - - - localnet - Internal - 0.0.0.0/0.0.0.0 - - - - - - - - - + - Add Internal Range - Local network settings. Blank fields will be ignored used Network 0.0.0.0. - - - - deny - 0.0.0.0/0.0.0.0 - - - - - - - - - + - Add Deny network - All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. - - - - - - - - - language - English - - SCCP Language: This is the language for your hints and other features of the phone. If you don't have any languages installed or are using a single language, you can leave this blank. - - - - netlang - English_United_States - - The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. - - - - devlang - English_United_States - - The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. - - - - - - - - - firstdigittimeout - 16 - sccp-custom - number - - - First Digit Timeout: The amount of time after your first digit to start dialing automatically. This can be over-ridden with settings in your dialplan.xml or by using the 'immediate dial' button. - - - - - digittimeout - 8 - sccp-custom - number - - - Digit Timeout: The amount of time to wait after the second (or subsequent) dialed digit. Override rules are the same as for firstdigittimeout. - - - - - autoanswer_ring_time - 0 - sccp-custom - number - - - Autoanswer Ring Time: The amount of time the phones will ring when being called as Intercom or Paging mode. - - - echocancel - - off - - - Echo Cancel: Echo Cancellation (On or Off). - - - silencesuppression - - off - - - Silence Suppression: Slience Suppression on the phone. - - - private - - on - - - Private Calling Enabled: Place a call with privacy Options (no Caller ID) turned on. Needs to be supported in Asterisk to work through SIP and DAHDI trunks. - - - callanswerorder - - oldestfirst - - - Call Answer Order: Which call should be answered first? The most common choice is "oldestfirst", but other orders are supported. - - - mwilamp - - On - - - - - - Set the MWI lamp style when MWI active to on, off, wink, flash or blink - - - mwioncall - - off - - - Set the MWI on call. - - - - - - - - context - from-internal - sccp-custom - - Context: This is the context in which your phones will operate. It should match the context you are using for the rest of your phones (if you have any). The FreePBX default is 'from-internal' - - - - - regcontext - sccpregistration - sccp-custom - - If regcontext is specified in sccp.conf chan-sccp-b will dynamically create and destroy a NoOp priority 1 extension for a given peer/line which registers with the server. If the context is not specified in extension.conf, then it will be dynamically created when an chan-sccp-b agent registers - - - - - directed_pickup_context - - - sccp-custom - - Context where direct pickup search for extensions. if not set current contect will be use. - - - - - pickupgroup - - - sccp-custom - - Context where direct pickup search for extensions. if not set current contect will be use. - - - - pickup_modeanswer - - off - - - Directed Pickup Mode (Answer): If a call is sent with the "directed pickup" flag, the phone will answer when set to "Yes". - - - transfer_on_hangup - - off - - - Complete transfer on hangup, without pressing transfer a second time. Will complete transfer, when the transferer puts the receiver on hook, after the destination has been reached. To cancel the transfer, either press resume on the transferred channel, press the 'endcall' softkey, or have the receiving party hangup first. - - - - - dial_template - NONE - - sccp-custom - Help. - - - autoselectline_enabled - - off - - - Enables and Disables auto line selection. - - - meetme - - off - - - Enable/Disable conferencing via meetme (on/off), make sure you have one of the meetme apps mentioned below activated in module.conf - - - - - meetmeopts - qxd - sccp-custom - - Other options (app_meetme: A,a,b,c,C,d,D,E,e,F,i,I,l,L,m,M,o,p,P,q,r,s,S,t,T,w,x,X,1) see meetme specific documentation - - - - autocall_select - - off - - - - - - backgroundImageAccess - - true - - - I'm guessing on this one, but on some devices, the background image on the display can be modified at the device. I think this is the thing that allows that to take. - - - phonePersonalization - - 0 - - - Phone personalization needs to be set to allow the server to push background or ringtones to the phone in the SEPXXXXXXXXXX.cnf.xml of each phone: - - - - musicclass - NONE - - form-control - Music Class: Available MOH Classes. These are the MOH classes listed in your current server. - - - - - - - - - - directrtp - - off - - - This option set global allow devices to do direct RTP sessions (default Off) - - - earlyrtp - - none - Immediate - - - - - - The audio strem will be open in the progress and connected state. Valid options: NONE, progress, offhook, dial, ringout. Default may be Progress. - - - simulate_enbloc - - on - - - Use simulated enbloc dialing to speedup connection when dialing while onhook (older phones) - - - - - - cfwdall - - off - - - Activate the callforward softkeys. Default is On - - - cfwdbusy - - off - - - Activate the callforward busy softkeys. Default is On - - - dndFeature - - on - - - Do Not Disturb. Default is Off - - - transfer - - on - - - Allow the use of the transfer feature - - - - - - - - ntp_config_enabled - - off - - - Enabling NTP settings in device configuration. - - - - - ntp_server - pool.ntp.org - pool.ntp.org - - NTP Server name or IP - - - ntp_server_mode - - unicast - - - - - Configure NTP Server protocol time synchronization - - - - - - - - dateformat - - Date Format: The date format for the on-screen display. Can be one of the following: (D-M-YA, M.D.Y, Y/M/D) where 'D' is Day, 'M' is Month, 'Y' is Year, 'A' is 24-hour, 'a' is 12-hour, and the separators can be '.','-','/' - - - - ntp_timezone - sccp-custom - - Date Format: Time zone - - - - - - - - Help_srst - You can also configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. This proves especially useful in a remote site configuration where the phones and Asterisk are connected over a WAN network. SRST provides users with fallback support for the IP phones that cannot access the primary, secondary, or tertiary Asterisk Node in the CallManager List because of an Asterisk Node failure or loss of connectivity across the WAN. For the remote sites attached to multiple-service routers across the WAN, SRST ensures that your remote users receive continuous (although minimal) service by providing call handling support directly from the SRST router. - When IP phones lose contact with primary, secondary, and tertiary Asterisk Nodes (CM's), they must establish a connection to a local SRST router to sustain the call-processing capability necessary to place and receive calls. The IP phone retains the IP address of the local SRST router as a default router in the Network Configuration area of the Settings menu. The Settings menu supports a maximum of five default router entries; however, the cnf.xml accommodates a maximum of three entries. When a secondary Asterisk Node is not available on the network, the local SRST Router's IP address is retained as the standby connection for Asterisk Node during normal operation. - - - - srst_Option - - disable - - - - You enabled/configured a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. - - - srst_userModifiable - - false - - - The user can change the personal SRST configuration on the device - - - srst_isSecure - - false - - - The user can change the personal SRST configuration on the device - - - - - - srst_Name - Enable - - You enabled configure a Survivable Remote Site Telephony (SRST) reference as the last device in the CallManager(CM) list. - - - - - srst_ip - 3 - / - - - - - - - - - Add Server - Help. - - - - srst_sip - 3 - / - - - - - - - - - Add Server - Help. - - - - - - - - - dev_servicesURL - - - - - - - - - - - dev_authenticationURL - - - - - The above is simply a dummy authentication page. It literally contains one word: AUTHORIZED (it receives UserId, Password, and devicename in the url - if you truly wish to implement special auth) - - - - - dev_idleURL - - - - - URL of CiscoIPPhoneImage. Requires a non-zero setting in idleTimeout. - - - - - dev_informationURL - - - - - - - - - dev_messagesURL - - - - - - - - - dev_directoryURL - - - - This is the URL for a CiscoIPPhoneMenu which gets appended to the end of the Missed/Received/Placed calls. I don't use it (I find it makes more sense to put my phone book under services) - - - - - dev_proxyServerURL - - - - - - - - - - - dev_idleTimeout - 60 - sccp-custom - number - - - - - - - - - - - Help_id2 - - Setting the hotline Feature on a device, will make it connect to a predefined extension as soon as the Receiver is picked up or the "New Call" Button is pressed. No number has to be given. This works even on devices which have no entry in the config file or realtime database. - The hotline function can be used in : - - - First time configuration - This will make it easier to register new devices and assign numbers - - - At a door - Where you want people to be able to only call one number - - - For unprovisioned phones - To only be able to call the helpdesk to get their phone set up - - - - Be careful with this function. Especially not to the internet. So i would restring the deny/permit to 'internal' by default in that case. - - - Allow = - Specify a list of your networks, for example: 192.168.1.0 - - - deny = - 0.0.0.0/0.0.0.0 - - - permit = - internal - - - hotline_context = - sccp - - - hotline_label = - hotline - - - - - - - hotline_enabled - - off - - - Hotline Enabled: This allows unregistered extensions to connect to the system and dial the number listed below. - - - - - hotline_extension - *111 - sccp-custom - - Hotline Extension: The number that gets called when a hotline is picked up. hint - - - - - hotline_label - Hot Line - sccp-custom - - Hotline Label: The label on the device - - - - - hotline_context - default - sccp-custom - - Hotline Context: This is the context through which the phone will connect. It should probably match your other contest. The default is "from-internal" but "from-internal-xfer" would also make sense by limiting the options for the person using the phone. - - - - dial_template - NONE - - sccp-custom - Help. - - - meetme - - off - - - Enable/Disable conferencing via meetme (on/off), make sure you have one of the meetme apps mentioned below activated in module.conf - - - - - meetmeopts - qxd - sccp-custom - - Other options (app_meetme: A,a,b,c,C,d,D,E,e,F,i,I,l,L,m,M,o,p,P,q,r,s,S,t,T,w,x,X,1) see meetme specific documentation - - - - - - - - Help_tftp_rewrite - This section is responsible for the modes of operation of external services: tftp http. - * off - Flat model cisco. All data is in the directory /tftproot - * Custom - The directory structure is strictly defined in the manager (for internal use). Requires tftpd rewrite support. - * Provision - Directory structure data is read from an external file. This project supports phones that can work on tftp and http. Support rewrite. - - - - provision_hide - - tftp_path - /tftpboot - sccp-custom - - Path to tftp home directory - - - - provision_show - - tftp_rewrite_path - /tftpboot - sccp-custom - - Use path from provision index.cnf file. You must first make sure that you have properly configured the "Provision" - - - - tftp_rewrite - - off - pro - pro - - Internal - - - Support the use of regular-expression-based filename remapping - - - - - createlangdir - - no - - - Say 'yes' if you need to create cisco default language directory in tftp path. - - - - - - - - - - mac - 000000000 - sccp-custom - - The MAC address of the phone. You must specify 12 characters in the format XXXX.XXXX.XXXX or XX-XX-XX-XX-XX-XX or XXXXXXXXXXXX - - - - - type - 7911 - - hw_select sccp-custom - The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. - - - - addon - NONE - - hw_select sccp-custom - Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. - - - - - - - - - mac - 000000000 - sccp-custom - - - The MAC address of the phone - - - - type - 7911 - - - hw_select sccp-custom - The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. - - - - - - type - 79XX - sccp-custom - - - The type of phone: 7911, 7940, 7960, etc. Important note: the 'G' models are handled as the base model (e.g., 7962G is handled as 7962). In the Display mode, this field is read-only because the MAC address and the model number are a pair. - - - - - addon - NONE - sccp-custom - - - Addon: Addons are model specific and only work with certain base phones. This phone model is identified as being a phone that does not accept sidecars. Update devmodel if this is not correct. - - - - - - - - - - description - 000000000 - sccp-custom - - - The information in the upper right corner of the device screen. Only English letters and digits ! - - - - softkeyset - default - - System Default Softkey - - - - tzoffset - 00 - - Time Zone offset - - - - netlang - English_United_States - - The Network locales allows the phone to play tones (ringing, busy etc.) native to the phone's country. - - - - devlang - Russian_Russia - - The user locale allows the phone to display text (menu items, soft keys etc.) native to the phone's language. - - - - - backgroundImage - - sccp-custom - - For phones that can display background images - display this one. Default is [empty] - - - - - ringtone - - sccp-custom - - The ringtone that the phone will default to. Can be overridden in the phone. The files RINGLIST.XML provice the basic phone ring tones, while DISTINCTIVERINGLIST.XML defines the list of possible ring tones for your other line types. They, along with the actual 'raw' ringtones, are stored in the /tftpboot/ringtones directory with the rest of the config files. - - - - - - - - - mac - 000000000 - sccp-custom - - - - - - - - - transfer - - NONE - - - - Transfer allowed - - - cfwdall - - NONE - - - - Activate the callforward softkeys. Default is On - - - cfwdbusy - - NONE - - - - Activate the callforward busy softkeys. Default is On - - - dndFeature - - NONE - - - - Do Not Disturb. Default is Off - - - directed_pickup - - on - off - - - Enable Pickup function to direct pickup an extension. Default is On - - - conf_allow - - on - off - - - Allow the use of conference - - - - - - pickup_hide - - - - directed_pickup_context - - sccp-custom - - Context where direct pickup search for extensions. if not set current contact will be use. - - - directed_pickup_modeanswer - - on - - - On (Default)= the call has been answered when picked up. Off = call manager way, the phone who picked up the call rings the call - Options: 'Immediate Answer' or 'Show CallerID' ?????? - - - - - - - useRedialMenu - - off - - - You can specifying 'useRedialMenu = yes' in the sccp.conf device section and the redial softkey will cause the "placed calls" list instead of immediately calling the last dialed number. - - - - force_dtmfmode - - auto - - - - Some phone models with bad firmware do send dtmf in a messed up order and need to be forced to skinny mode. - - - mwioncall - - NONE - - - - Set the MWI on call. - - - - mwilamp - - NONE - - - - - - - Set the MWI lamp style when MWI active to on, off, wink, flash or blink - - - - - conf_hide - - - conf_play_general_announce - - on - - - Playback General Announcements (like: 'You are Entering/Leaving the conference') - - - conf_play_part_announce - - on - - - Playback Personal/Participant Announcements, (like: 'You have been muted / You have been kicked') - - - conf_mute_on_entry - - off - - - Mute new participants from the start - - - conf_show_conflist - - on - - - Automatically show conference list to the moderator - - - - conf_music_on_hold_class - default - - form-control - Play music on hold of this class when no moderator is listening on the conference. If set to an empty string, no music on hold will be played. - - - - - - custom_network_acc - - permit - - - - Help. - - - custom_network_type - - ipv4 - - - Help. - - - - - custom_network_v - - - sccp-custom - - - custom_network_m - - sccp-custom - - - Help. - - - - - - - - - deny - / - sccp_hw_net_inherit - - - - - - - + - Add Deny network - All RFC 1918 addresses are local networks. Should always be at least '0.0.0.0/0.0.0.0'. - - - - - - permit - NONE - Inherit - false - - sccp_hw-ar_permit-grinternal - - sccp_hw_net_inherit - - - - - - - + - Add Allow network - Allow network settings. Blank fields will be ignored used Network 0.0.0.0. - - - - nat - - NONE - - - - - Device NAT support (default Auto) - - - - directrtp - - NONE - Auto - - - - This option allow devices to do direct RTP sessions (default Off) - - - earlyrtp - - NONE - - Immediate - - - - - - The audio stream will be open in the progress and connected state. Valid options: none, progress, offhook, dial, ringout. Default may be Progress. - - - - - - - dialtemplate_name - - form-control - - Help. - - - - - - - - Help_id1 - Specifies a pattern to match dialed digits against. Note: TEMPLATE must be in uppercase. - Rules: - - - match: - Pattern to match, consists of one or more elements - - - 0 1 2 3 4 5 6 7 8 9 - Match digit - - - . - Match one digit, # or * - - - * - Match zero or more digits, # or * - - - \* - Match a literal * - - - , - Play secondary dial-tone specified by tone - - - timeout: - Number of seconds to wait for more digits if this pattern matches - - - line: - Only apply template to the specified line (optional) - - - rewrite: - Rewrite the matched digits before dialing, consists of one or more elements (optional) - - - 0 1 2 3 4 5 6 7 8 9 - Replace with digit - - - %0 - The entire match - - - %1 %2 %3 %4 %5 - Replace with group of digits matched, grouping is done by consecutive literal digit or . elements - - - %% - A literal % - - - . - Each . is replaced by the digit that was matched by the corresponding . in the pattern - - - tone: - Secondary dial-tone to play when a , is matched, up to 3 can be specified (optional) - - - - - - dialtemplate - */10/* - - title - - - - - - - - text1 - - - - - - empty - Bellcore-Alerting - Bellcore-Inside - Bellcore-Outside - Bellcore-Busy - Bellcore-BusyVerify - Bellcore-Reorder - Bellcore-CallWaiting - Bellcore-Hold - Bellcore-Reminder - Bellcore-Confirmation - Bellcore-Stutter - Bellcore-Permanent - Bellcore-None - Cisco-Zip - Cisco-ZipZip - Cisco-BeepBonk - Bellcore-dr1 - Bellcore-dr2 - Bellcore-dr3 - Bellcore-dr4 - Bellcore-dr5 - Bellcore-dr6 - CallWaiting-2 - CallWaiting-3 - CallWaiting-4 - - Allow network settings. Blank fields will be ignored used Network 0.0.0.0. - - - - - diff --git a/contrib/index.cnf b/contrib/index.cnf deleted file mode 100644 index 7bec03f..0000000 --- a/contrib/index.cnf +++ /dev/null @@ -1,12 +0,0 @@ -[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/contrib/rewrite.rules b/contrib/rewrite.rules index f2c5a45..ddb84c6 100644 --- a/contrib/rewrite.rules +++ b/contrib/rewrite.rules @@ -174,27 +174,28 @@ 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 -#ri ^(.+\.sbn)$ firmware/\1 +ri ^(.+\.loads)$ firmware/\1 +ri ^(.+\.sbn)$ firmware/\1 -# Keep locales in a separate directory (optional) -ri ^(.+)\/(.+-sccp.jar)$ languages/\1/\2 -ri ^(.+)\/(.+-sip.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 -ri ^(.+)\/(.+-kate.xml)$ languages/\1/\2 -ri ^(.+)\/(gk.+)(\.cfg)$ languages/\1/\2\3 -#ri ^(.+)\/(.+-tones.xml)$ locales/countries/\1/\2 +ri ^(.+)\/(.+-sccp.jar)$ locales/languages/\1/\2 +ri ^(.+)\/(.+-sip.jar)$ locales/languages/\1/\2 +ri ^(.+)\/(.+-dictionary.xml)$ locales/languages/\1/\2 +ri ^(.+)\/(.+-dictionary-ext.xml)$ locales/languages/\1/\2 +#ri ^(.+)\/(.+-tones.xml)$ locales/languages/\1/\2 +ri ^(.+)\/(.+-font.xml)$ locales/languages/\1/\2 +ri ^(.+)\/(.+-kate.xml)$ locales/languages/\1/\2 +ri ^(.+)\/(gk.+)(\.cfg)$ locales/languages/\1/\2\3 + +ri ^(.+)\/(.+-tones.xml)$ locales/countries/\1/\2 + # Keep ring-tones in a separate directory (optional) ri ^([R|r]ing[L|l]ist)(\.xml|-wb\.xml)(\.sgn)?$ ringtones/ringlist.xml diff --git a/contrib/tftp.xinetd b/contrib/tftp.xinetd index 6ea6509..cfea06a 100644 --- a/contrib/tftp.xinetd +++ b/contrib/tftp.xinetd @@ -10,7 +10,7 @@ service tftp wait = yes user = root server = /usr/sbin/in.tftpd - server_args = -c -s -v /tftpboot -m /tftpboot/rewrite.rules + server_args = -c -s -v /tftpboot -m -m /etc/asterisk/sccpManagerRewrite.rules disable = no per_source = 11 cps = 100 2 diff --git a/i18n/ru_RU/LC_MESSAGES/sccp_manager.mo b/i18n/ru_RU/LC_MESSAGES/sccp_manager.mo index 4e99ebb..f18da95 100644 Binary files a/i18n/ru_RU/LC_MESSAGES/sccp_manager.mo and b/i18n/ru_RU/LC_MESSAGES/sccp_manager.mo differ diff --git a/i18n/ru_RU/LC_MESSAGES/sccp_manager.po b/i18n/ru_RU/LC_MESSAGES/sccp_manager.po index 4309487..3862a78 100644 --- a/i18n/ru_RU/LC_MESSAGES/sccp_manager.po +++ b/i18n/ru_RU/LC_MESSAGES/sccp_manager.po @@ -910,8 +910,8 @@ msgid "General Device configuration" msgstr "Абонентского устройство" #: views/sccpgeneral.xml: -msgid "Device SEP ID.[XXXXXXXXXXXX]=MAC" -msgstr "Устройство SEP ID : [XXXXXXXXXXXX]=MAC" +msgid "Device ID.[XXXXXXXXXXXX]=MAC" +msgstr "Устройство ID : [XXXXXXXXXXXX]=MAC" #: views/sccpgeneral.xml: msgid "" @@ -955,8 +955,8 @@ msgid "Device Label" msgstr "Название Устройства" #: views/sccpgeneral.xml: -msgid "Device SEP ID" -msgstr "Идентификатор устройства SEP ID" +msgid "Device ID" +msgstr "Идентификатор устройства ID" #: views/sccpgeneral.xml: msgid "The information in the upper right corner of the device screen" @@ -1005,7 +1005,7 @@ msgid "Buttons Configuration" msgstr "Настройка Кнопок" #: views/sccpgeneral.xml: -msgid "Device MAC SEP." +msgid "Device MAC." msgstr "Прямое подключение." #: views/sccpgeneral.xml: diff --git a/i18n/sccp_manager.pot b/i18n/sccp_manager.pot index e9b214d..16f2497 100644 --- a/i18n/sccp_manager.pot +++ b/i18n/sccp_manager.pot @@ -679,7 +679,7 @@ msgid "General Device configuration" msgstr "" #: views/sccpgeneral.xml: -msgid "Device SEP ID.[XXXXXXXXXXXX]=MAC" +msgid "Device ID.[XXXXXXXXXXXX]=MAC" msgstr "" #: views/sccpgeneral.xml: @@ -707,7 +707,7 @@ msgid "Device Label" msgstr "" #: views/sccpgeneral.xml: -msgid "Device SEP ID" +msgid "Device ID" msgstr "" #: views/sccpgeneral.xml: @@ -743,7 +743,7 @@ msgid "Buttons Configuration" msgstr "" #: views/sccpgeneral.xml: -msgid "Device MAC SEP." +msgid "Device MAC." msgstr "" #: views/sccpgeneral.xml: diff --git a/install.php b/install.php index 32dbe83..f033599 100644 --- a/install.php +++ b/install.php @@ -8,8 +8,13 @@ global $db; global $amp_conf; global $version; global $aminterface; +global $extconfigs; global $mobile_hw; global $useAmiForSoftKeys; +global $settingsFromDb; +global $thisInstaller; +global $cnf_int; +global $sccp_compatible; $mobile_hw = '0'; $autoincrement = (($amp_conf["AMPDBENGINE"] == "sqlite") || ($amp_conf["AMPDBENGINE"] == "sqlite3")) ? "AUTOINCREMENT" : "AUTO_INCREMENT"; $table_req = array('sccpdevice', 'sccpline', 'sccpsettings'); @@ -17,54 +22,58 @@ $sccp_compatible = 0; $chanSCCPWarning = true; $db_config = ''; $sccp_version = array(); +$cnf_int = \FreePBX::Config(); + +// Do not create Sccp_Manager object as not required. +// Only include required classes and create anonymous class for thisInstaller + +$thisInstaller = new class{ + use \FreePBX\modules\Sccp_Manager\sccpManTraits\helperFunctions; +}; + +$requiredClasses = array('aminterface', 'extconfigs'); +foreach ($requiredClasses as $className) { + $class = "\\FreePBX\\Modules\\Sccp_manager\\$className"; + if (!class_exists($class, false)) { + include(__DIR__ . "/sccpManClasses/$className.class.php"); + } + if (class_exists($class, false)) { + ${$className} = new $class(); + } +} -CheckSCCPManagerDBTables($table_req); CheckAsteriskVersion(); - -// Have essential tables so can create Sccp_manager object and verify have aminterface -$ss = FreePBX::create()->Sccp_manager; - -$class = "\\FreePBX\\Modules\\Sccp_manager\\aminterface"; -if (!class_exists($class, false)) { - include(__DIR__ . "/sccpManClasses/aminterface.class.php"); -} -if (class_exists($class, false)) { - $aminterface = new $class(); -} - $sccp_version = CheckChanSCCPCompatible(); $sccp_compatible = $sccp_version[0]; $chanSCCPWarning = $sccp_version[1] ^= 1; -outn("
  • " . _("Sccp model Compatible code : ") . $resultReturned[0] . "
  • "); +outn("
  • " . _("Sccp model Compatible code : ") . $sccp_compatible . "
  • "); if ($sccp_compatible == 0) { outn("
    "); outn("Chan Sccp not Found. Install it before continuing !"); die(); } -$db_config = Get_DB_config($sccp_compatible); -$sccp_db_ver = CheckSCCPManagerDBVersion(); // BackUp Old config createBackUpConfig(); RenameConfig(); +$db_config = Get_DB_config($sccp_compatible); InstallDB_updateSchema($db_config); -$stmt = $db->prepare('SELECT CASE WHEN EXISTS(SELECT 1 FROM sccpdevmodel) THEN 0 ELSE 1 END AS IsEmpty;'); -$stmt->execute(); -$result = $stmt->fetchAll(\PDO::FETCH_ASSOC); -if ($result[0]['IsEmpty']) { - outn("Populating sccpdevmodel..."); - InstallDB_fillsccpdevmodel(); -} + +cleanUpSccpSettings(); InstallDB_createButtonConfigTrigger(); -InstallDB_CreateSccpDeviceConfigView($sccp_compatible); +InstallDbCreateViews($sccp_compatible); +installDbPopulateSccpline(); InstallDB_updateDBVer($sccp_compatible); if ($chanSCCPWarning) { outn("
    "); outn("Error: installed version of chan-sccp is not compatible. Please upgrade chan-sccp"); } Setup_RealTime(); +addDriver($sccp_compatible); +checkTftpServer(); + outn("
    "); outn("Install Complete !"); outn("
    "); @@ -91,13 +100,12 @@ function Get_DB_config($sccp_compatible) 'disallow' => array('drop' => "yes"), 'callhistory_answered_elsewhere' => array('create' => "enum('Ignore','Missed Calls','Received Calls', 'Placed Calls') NOT NULL default 'Ignore'", 'modify' => "enum('Ignore','Missed Calls','Received Calls','Placed Calls')"), - 'description' => array('rename' => "_description"), 'hwlang' => array('rename' => "_hwlang"), - '_hwlang' => array('create' => 'varchar(12) NULL DEFAULT NULL'), - '_loginname' => array('create' => 'varchar(20) NULL DEFAULT NULL AFTER `_hwlang`'), + '_hwlang' => array('create' => 'VARCHAR(12) NULL DEFAULT NULL'), + '_loginname' => array('create' => 'VARCHAR(20) NULL DEFAULT NULL AFTER `_hwlang`'), '_profileid' => array('create' => "INT(11) NOT NULL DEFAULT '0' AFTER `_loginname`"), '_dialrules' => array('create' => "VARCHAR(255) NULL DEFAULT NULL AFTER `_profileid`"), - 'useRedialMenu' => array('create' => "VARCHAR(5) NULL DEFAULT 'no' AFTER `_dialrules`"), + 'useRedialMenu' => array('create' => "enum('yes','no') NOT NULL default 'no'", 'modify' => "enum('yes','no')"), 'dtmfmode' => array('drop' => "yes"), 'force_dtmfmode' => array('create' => "ENUM('auto','rfc2833','skinny') NOT NULL default 'auto'", 'modify' => "ENUM('auto','rfc2833','skinny')"), @@ -105,28 +113,26 @@ function Get_DB_config($sccp_compatible) 'permit' => array('create' => 'VARCHAR(100) NULL DEFAULT NULL', 'modify' => "VARCHAR(100)"), 'backgroundImage' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), 'ringtone' => array('create' => 'VARCHAR(255) NULL DEFAULT NULL', 'modify' => "VARCHAR(255)"), - 'transfer' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), - 'cfwdall' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), - 'cfwdbusy' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), - 'cfwdnoanswer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'transfer' => array('create' => "enum('no','yes') NOT NULL default 'no'", 'modify' => "enum('no','yes')"), + 'cfwdall' => array('create' => "enum('yes','no') NOT NULL default 'yes'", 'modify' => "enum('yes','no')"), + 'cfwdbusy' => array('create' => "enum('yes','no') NOT NULL default 'yes'", 'modify' => "enum('yes','no')"), + 'cfwdnoanswer' => array('create' => "enum('yes','no') NOT NULL default 'yes'", 'modify' => "enum('yes','no')"), 'park' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), - 'directrtp' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), - 'dndFeature' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), - 'earlyrtp' => array('create' => "ENUM('immediate','offHook','dialing','ringout','progress','none') NOT NULL default 'none'", - 'modify' => "ENUM('immediate','offHook','dialing','ringout','progress','none')"), + 'directrtp' => array('create' => "enum('no','yes') NOT NULL default 'no'", 'modify' => "enum('no','yes')"), + 'dndFeature' => array('create' => "enum('off','on') NOT NULL default 'off'", 'modify' => "enum('off','on')"), + 'earlyrtp' => array('create' => "ENUM('yes','no') NOT NULL default 'yes'", 'modify' => "ENUM('yes','no')"), 'monitor' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), - 'audio_tos' => array('def_modify' => "0xB8"), - 'audio_cos' => array('def_modify' => "6"), - 'video_tos' => array('def_modify' => "0x88"), - 'video_cos' => array('def_modify' => "5"), + 'audio_tos' => array('create' => "VARCHAR(11) NOT NULL default '0xB8'",'modify' => "0xB8"), + 'audio_cos' => array('create' => "VARCHAR(11) NOT NULL default '0x6'",'modify' => "0x6"), + 'video_tos' => array('create' => "VARCHAR(11) NOT NULL default '0x88'",'modify' => "0x88"), + 'video_cos' => array('create' => "VARCHAR(11) NOT NULL default '0x5'",'modify' => "0x5"), 'trustphoneip' => array('drop' => "yes"), - 'transfer_on_hangup' => array('create' => "enum('on','off') NOT NULL DEFAULT 'off'", 'modify' => "enum('on','off')"), + 'transfer_on_hangup' => array('create' => "enum('yes','no') NOT NULL DEFAULT 'no'", 'modify' => "enum('yes','no')"), 'phonecodepage' => array('create' => 'VARCHAR(50) NULL DEFAULT NULL', 'modify' => "VARCHAR(50)"), 'mwilamp' => array('create' => "enum('on','off','wink','flash','blink') NOT NULL default 'on'", 'modify' => "enum('on','off','wink','flash','blink')"), - 'mwioncall' => array('create' => "enum('on','off') NOT NULL default 'on'", - 'modify' => "enum('on','off')"), - 'private' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'mwioncall' => array('create' => "enum('no','yes') NOT NULL default 'yes'",'modify' => "enum('no','yes')"), + 'private' => array('create' => "enum('yes','no') NOT NULL default 'no'", 'modify' => "enum('yes','no')"), 'privacy' => array('create' => "enum('full','on','off') NOT NULL default 'full'", 'modify' => "enum('full','on','off')"), 'nat' => array('create' => "enum('on','off','auto') NOT NULL default 'off'", 'modify' => "enum('on','off','auto')"), 'conf_allow' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), @@ -138,13 +144,14 @@ function Get_DB_config($sccp_compatible) 'softkeyset' => array('def_modify' => "softkeyset") ), 'sccpline' => array( - 'directed_pickup' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'directed_pickup' => array('create' => "enum('yes','no') NOT NULL default 'no'", 'modify' => "enum('yes','no')"), 'directed_pickup_context' => array('create' => "VARCHAR(100) NULL DEFAULT NULL"), - 'pickup_modeanswer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'pickup_modeanswer' => array('create' => "enum('yes','no') NOT NULL default 'yes'", 'modify' => "enum('yes','no')"), 'namedcallgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `setvar`", 'modify' => "VARCHAR(100)"), 'namedpickupgroup' => array('create' => "VARCHAR(100) NULL DEFAULT NULL AFTER `namedcallgroup`", 'modify' => "VARCHAR(100)"), 'adhocNumber' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `namedpickupgroup`"), 'meetme' => array('create' => "VARCHAR(5) NULL DEFAULT NULL AFTER `adhocNumber`"), + 'context' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `description`", 'def_modify' => 'from-internal'), 'meetmenum' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetme`"), 'meetmeopts' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmenum`"), 'regexten' => array('create' => "VARCHAR(45) NULL DEFAULT NULL AFTER `meetmeopts`"), @@ -153,27 +160,27 @@ function Get_DB_config($sccp_compatible) 'audio_cos' => array('drop' => "yes"), 'video_tos' => array('drop' => "yes"), 'video_cos' => array('drop' => "yes"), - 'videomode' => array('create' => "enum('user','auto','off') NOT NULL default 'auto'", 'modify' => "enum('user','auto','off')"), + 'videomode' => array('create' => "enum('auto','user','off') NOT NULL default 'auto'", 'modify' => "enum('auto','user','off')"), 'incominglimit' => array('create' => "INT(11) DEFAULT '6'", 'modify' => 'INT(11)', 'def_modify' => "6"), - 'transfer' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'transfer' => array('create' => "enum('yes','no') NOT NULL default 'yes'", 'modify' => "enum('yes','no')"), 'vmnum' => array('def_modify' => "*97"), 'musicclass' => array('def_modify' => "default"), - 'disallow' => array('create' => "VARCHAR(255) NULL DEFAULT NULL"), + 'disallow' => array('create' => "VARCHAR(255) NULL DEFAULT 'all'", 'modify' => 'VARCHAR(255)'), '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'), - '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") + 'echocancel' => array('create' => "enum('yes','no') NOT NULL default 'yes'", 'modify' => "enum('yes','no')"), + 'silencesuppression' => array('create' => "enum('no','yes') NOT NULL default 'no'", 'modify' => "enum('no','yes')"), + 'dnd' => array('create' => "enum('reject','off','silent','user') NOT NULL default 'reject'", 'modify' => "enum('reject','off','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') NOT NULL DEFAULT 'off'", 'modify' => "ENUM('on','off','multi')" ), + '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('off','on','multi') NOT NULL DEFAULT 'off'", 'modify' => "ENUM('on','off','multi')" ), 'auto_logout' => array('create' => "ENUM('on','off') NOT NULL DEFAULT 'off'", 'modify' => "ENUM('on','off')" ), - 'homedevice' => array('create' => "varchar(20) NOT NULL", 'modify' => "VARCHAR(20)" ), - 'devicegroup' => array('create' => "varchar(7) NOT NULL", 'modify' => "VARCHAR(7)" ), + 'homedevice' => array('create' => "VARCHAR(20) NOT NULL", 'modify' => "VARCHAR(20)" ), + 'devicegroup' => array('create' => "VARCHAR(7) NOT NULL", 'modify' => "VARCHAR(7)" ), ), 'sccpbuttonconfig' => array( 'reftype' => array('create' => "enum('sccpdevice', 'sipdevice', 'sccpuser') NOT NULL default 'sccpdevice'", @@ -188,7 +195,7 @@ function Get_DB_config($sccp_compatible) 'sccpdevice' => array( 'pickupexten' => array('drop' => "yes"), 'directed_pickup' => array('drop' => "yes"), - 'cfwdnoanswer' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), + 'cfwdnoanswer' => array('create' => "enum('yes','no') NULL default 'yes'", 'modify' => "enum('yes','no')"), 'park' => array('create' => "enum('on','off') NULL default 'on'", 'modify' => "enum('on','off')"), 'monitor' => array('create' => "enum('on','off') NULL default NULL", 'modify' => "enum('on','off')"), '_description' => array('rename' => "description"), @@ -202,8 +209,107 @@ function Get_DB_config($sccp_compatible) 'videomode' => array('create' => "enum('user','auto','off') NULL default 'auto'", 'modify' => "enum('user','auto','off')"), ), 'sccpuser' => array( - 'id' => array('create' => "varchar(20) NOT NULL", 'modify' => "VARCHAR(20)" ), - 'name' => array('create' => "varchar(45) NOT NULL", 'modify' => "VARCHAR(45)" ), + 'id' => array('create' => "VARCHAR(20) NOT NULL", 'modify' => "VARCHAR(20)" ), + 'name' => array('create' => "VARCHAR(45) NOT NULL", 'modify' => "VARCHAR(45)" ), + ) + ); + // Below fields allow configuration of these settings on a per device basis + // whereas previously they were all global.Some of these are not supported by chan-sccp; + // The supported fields are listed in the view sccpdeviceconfig. + $db_config_v5 = array( + 'sccpdevice' => array( + 'logserver' => array('create' => "VARCHAR(100) NULL default null", 'modify' => "VARCHAR(20)"), + 'daysdisplaynotactive' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'displayontime' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'displayonduration' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'displayidletimeout' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'settingsaccess' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'videocapability' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'webaccess' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'webadmin' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'pcport' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'spantopcport' => array('create' => "enum('on','off') NOT NULL default 'on'", 'modify' => "enum('on','off')"), + 'voicevlanaccess' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'enablecdpswport' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'enablecdppcport' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'enablelldpswport' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'enablelldppcport' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'firstdigittimeout' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'digittimeout' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'cfwdnoanswer_timeout' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'autoanswer_ring_time' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'autoanswer_tone' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'remotehangup_tone' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'transfer_tone' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'callwaiting_tone' => array('create' => "VARCHAR(20) NULL default null", 'modify' => "VARCHAR(20)"), + 'callanswerorder' => array('create' => "enum('oldestfirst','latestfirst') NOT NULL default 'latestfirst'", + 'modify' => "enum('oldestfirst','latestfirst')"), + 'sccp_tos' => array('create' => "VARCHAR(11) NOT NULL default '0x68'", 'modify' => "VARCHAR(11)"), + 'sccp_cos' => array('create' => "VARCHAR(11) NOT NULL default '0x4'", 'modify' => "VARCHAR(11)"), + 'dev_sshPassword' => array('create' => "VARCHAR(25) NOT NULL default 'cisco'"), + 'dev_sshUserId' => array('create' => "VARCHAR(25) NOT NULL default 'cisco'"), + 'phonepersonalization' => array('create' => "VARCHAR(25) NOT NULL default '0'", 'modify' => "VARCHAR(25)"), + 'loginname' => array('create' => 'VARCHAR(20) NULL DEFAULT NULL'), + 'profileid' => array('create' => "INT(11) NOT NULL DEFAULT '0'"), + 'dialrules' => array('create' => "VARCHAR(255) NULL DEFAULT NULL"), + 'description' => array('create' => "VARCHAR(45) NULL DEFAULT NULL"), + '_hwlang' => array ('drop' => 'yes'), + 'devlang' => array('create' => "VARCHAR(50) NULL default NULL", 'modify' => "VARCHAR(50)"), + 'netlang' => array('create' => "VARCHAR(50) NULL default NULL", 'modify' => "VARCHAR(50)"), + '_devlang' => array('rename' => "devlang"), + '_netlang' => array('rename' => "netlang"), + '_logserver' => array('rename' => 'logserver'), + '_daysdisplaynotactive' => array('rename' => 'daysdisplaynotactive'), + '_displayontime' => array('rename' => 'displayontime'), + '_displayonduration' => array('rename' => 'displayonduration'), + '_displayidletimeout' => array('rename' => 'displayidletimeout'), + '_settingsaccess' => array('rename' => 'settingsaccess'), + '_videocapability' => array('rename' => 'videocapability'), + '_webaccess' => array('rename' => 'webaccess'), + '_webadmin' => array('rename' => 'webadmin'), + '_pcport' => array('rename' => 'pcport'), + '_spantopcport' => array('rename' => 'spantopcport'), + '_voicevlanaccess' => array('rename' => 'voicevlanaccess'), + '_enablecdpswport' => array('rename' => 'enablecdpswport'), + '_enablecdppcport' => array('rename' => 'enablecdppcport'), + '_enablelldpswport' => array('rename' => 'enablelldpswport'), + '_enablelldppcport' => array('rename' => 'enablelldppcport'), + '_firstdigittimeout' => array('rename' => 'firstdigittimeout'), + '_digittimeout' => array('rename' => 'digittimeout'), + '_cfwdnoanswer_timeout' => array('rename' => 'cfwdnoanswer_timeout'), + '_autoanswer_ring_time' => array('rename' => 'autoanswer_ring_time'), + '_autoanswer_tone' => array('rename' => 'autoanswer_tone'), + '_remotehangup_tone' => array('rename' => 'remotehangup_tone'), + '_transfer_tone' => array('rename' => 'transfer_tone'), + '_callwaiting_tone' => array('rename' => 'callwaiting_tone'), + '_callanswerorder' => array('rename' => 'callanswerorder'), + '_sccp_tos' => array('rename' => 'sccp_tos'), + '_sccp_cos' => array('rename' => 'sccp_cos'), + '_dev_sshPassword' => array('rename' => 'dev_sshPassword'), + '_dev_sshUserId' => array('rename' => 'dev_sshUserId'), + '_phonepersonalization' => array('rename' => '_phonepersonalization'), + '_loginname' => array('rename' => 'loginname'), + '_profileid' => array('rename' => 'profileid'), + '_dialrules' => array('rename' => 'dialrules'), + '_description' => array('rename' => 'description'), + 'keepalive' => array('create' => "INT(11) DEFAULT '60'", 'modify' => 'INT(11)', 'def_modify' => "60") + ), + 'sccpline' => array ( + 'regcontext' => array('create' => "VARCHAR(20) NULL default 'sccpregistration'", 'modify' => "VARCHAR(20)"), + 'transfer_on_hangup' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'autoselectline_enabled' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'autocall_select' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'backgroundImageAccess' => array('create' => "enum('on','off') NOT NULL default 'off'", 'modify' => "enum('on','off')"), + 'callLogBlfEnabled' => array('create' => "enum('3','2') NOT NULL default '2'", 'modify' => "enum('3','2')"), + '_regcontext' => array('rename' => 'regcontext'), + '_transfer_on_hangup' => array('rename' => 'transfer_on_hangup'), + '_autoselectline_enabled' => array('rename' => 'autoselectline_enabled'), + '_autocall_select' => array('rename' => 'autocall_select'), + '_backgroundImageAccess' => array('rename' => 'backgroundImageAccess'), + '_callLogBlfEnabled' => array('rename' => 'callLogBlfEnabled') + ), + 'sccpsettings' => array ( + 'systemdefault' => array('create' => "VARCHAR(255) NULL default ''") ) ); @@ -211,58 +317,38 @@ function Get_DB_config($sccp_compatible) if ($mobile_hw == '1') { return $db_config_v4M; } - return $db_config_v4; - } -} - -function CheckSCCPManagerDBTables($table_req) -{ - // These tables should already exist having been created by FreePBX through module.xml - global $amp_conf; - global $db; - outn("
  • " . _("Checking for required Sccp_manager database tables..") . "
  • "); - foreach ($table_req as $value) { - $check = $db->getRow("SELECT 1 FROM `$value` LIMIT 0", DB_FETCHMODE_ASSOC); - if (DB::IsError($check)) { - outn(_("Can't find table: " . $value)); - outn(_("Please goto the chan-sccp/conf directory and create the DB schema manually (See wiki)")); - die_freepbx("!!!! Installation error: Can not find required " . $value . " table !!!!!!\n"); + // This looks extraneous, but is for future compatibility - do not delete + // If integrated into chan-sccp, the version number will change + if ($sccp_compatible >= 433) { + $db_config_v4['sccpdevice'] = array_merge($db_config_v4['sccpdevice'],$db_config_v5['sccpdevice']); + $db_config_v4['sccpline'] = array_merge($db_config_v4['sccpline'],$db_config_v5['sccpline']); + $db_config_v4['sccpsettings'] = $db_config_v5['sccpsettings']; } + return $db_config_v4; } } function CheckSCCPManagerDBVersion() { - global $db; - outn("
  • " . _("Checking for previous version of Sccp_manager.") . "
  • "); - $check = $db->getRow("SELECT data FROM `sccpsettings` where keyword ='sccp_compatible'", DB_FETCHMODE_ASSOC); - if (DB::IsError($check)) { - outn(_("No previous version found ")); - return false; - } - if (!empty($check['data'])) { - outn(_("Found DB Schema : " . $check['data'])); - return $check['data']; - } else { - return false; - } + } /* notused */ function CheckPermissions() { + global $amp_conf; outn("
  • " . _("Checking Filesystem Permissions") . "
  • "); - $dst = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/views'; - if (fileowner($_SERVER['DOCUMENT_ROOT']) != fileowner($dst)) { + $dst = $amp_conf['AMPWEBROOT'] . '/admin/modules/sccp_manager/views'; + if (fileowner($amp_conf['AMPWEBROOT']) != fileowner($dst)) { die_freepbx('Please (re-)check permissions by running "amportal chown. Installation Failed"'); } } function CheckAsteriskVersion() { - outn("
  • " . _("Checking Asterisk Version : ") . $version . "
  • "); $version = FreePBX::Config()->get('ASTVERSION'); + outn("
  • " . _("Checking Asterisk Version : ") . $version . "
  • "); if (!empty($version)) { // Woo, we have a version if (version_compare($version, "12.2.0", ">=")) { @@ -295,254 +381,272 @@ function InstallDB_updateSchema($db_config) } $count_modify = 0; outn("
  • " . _("Modify Database schema") . "
  • "); - foreach ($db_config as $tabl_name => &$tab_modif) { - // 0 - name 1-type 4- default - $sql = "DESCRIBE {$tabl_name};"; - $stmt = $db->prepare("DESCRIBE {$tabl_name}"); - $stmt->execute(); - $db_result = $stmt->fetchAll(); - if (DB::IsError($db_result)) { - die_freepbx("Can not get information from " . $tabl_name . " table\n"); - } - foreach ($db_result as $tabl_data) { - $fld_id = $tabl_data[0]; - $db_config[$tabl_name][$fld_id]['fieldExists'] = FALSE; - // Filter commands to avoid applying unnecessary - if (!empty($tab_modif[$fld_id])) { - // Potentially have something to modify in schema - $db_config[$tabl_name][$fld_id]['fieldExists'] = TRUE; - if (!empty($tab_modif[$fld_id]['modify'])) { - if (strtoupper($tab_modif[$fld_id]['modify']) == strtoupper($tabl_data[1])) { - unset($db_config[$tabl_name][$fld_id]['modify']); - } - // Modifying field so do not then need to modify defaults as this should do that - if (!empty($tab_modif[$fld_id]['def_modify'])) { - unset($db_config[$tabl_name][$fld_id]['def_modify']); - } - } - if (!empty($tab_modif[$fld_id]['def_modify'])) { - if (strtoupper($tab_modif[$fld_id]['def_modify']) == strtoupper($tabl_data[4])) { - unset($db_config[$tabl_name][$fld_id]['def_modify']); - } - } - if (!empty($tab_modif[$fld_id]['rename'])) { - $fld_id_source = $tab_modif[$fld_id]['rename']; - $db_config[$tabl_name][$fld_id_source]['fieldExists'] = TRUE; - 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]."'" ); - } - } - } - } + foreach ($db_config as $tabl_name => $tab_modif) { $sql_create = ''; $sql_modify = ''; - $sql_update = ''; + $sql_rename = ''; - foreach ($tab_modif as $row_fld => $row_data) { - if (!$row_data['fieldExists']) { - if (!empty($row_data['create'])) { - $sql_create .= "ADD COLUMN {$row_fld} {$row_data['create']}, "; - $count_modify ++; - } - } else { - if (!empty($row_data['rename'])) { - $sql_modify .= "CHANGE COLUMN {$row_fld} {$row_data['rename']} {$row_data['create']}, "; - $count_modify ++; - } - $row_data['fieldModified'] = FALSE; - if (!empty($row_data['modify'])) { - if (!empty($row_data['create'])) { - // Use values in create to set defaults - $sql_modify .= "MODIFY COLUMN {$row_fld} {$row_data['create']}, "; - } else { - $sql_modify .= "MODIFY COLUMN {$row_fld} {$row_data['modify']} DEFAULT {$row_data['def_modify']}, "; - } - if (strpos($row_data['modify'], 'enum') !== false) { - $sql_update .= "UPDATE " . $tabl_name . " set `" . $row_fld . "`=case when lower(`" . $row_fld . "`) in ('yes','true','1') then 'on' when lower(`" . $row_fld . "`) in ('no', 'false', '0') then 'off' else `" . $row_fld . "` end; "; - } - $count_modify ++; - } - if (!empty($row_data['def_modify'])) { - $sql_modify .= "ALTER COLUMN {$row_fld} SET DEFAULT '{$row_data['def_modify']}', "; - $count_modify ++; - } - if (!empty($row_data['drop'])) { + $stmt = $db->prepare("DESCRIBE {$tabl_name}"); + $stmt->execute(); + $db_result = $stmt->fetchAll(\PDO::FETCH_ASSOC|\PDO::FETCH_UNIQUE); + if (DB::IsError($db_result)) { + die_freepbx("Can not get information for " . $tabl_name . " table\n"); + } + + // filter modifications based on field existance and prepare sql + foreach ($db_result as $fld_id => $tabl_data) { + if (!empty($tab_modif[$fld_id])) { + // have column in table so potentially something to update + // if dropping column, prepare sql and continue + if (!empty($tab_modif[$fld_id]['drop'])) { $sql_create .= "DROP COLUMN {$row_fld}, "; + unset($tab_modif[$fld_id]['drop']); + continue; + } + + if (!empty($tab_modif[$fld_id]['modify'])) { + // Check if modify type is same as current type + if (strtoupper($tab_modif[$fld_id]['modify']) == strtoupper($tabl_data['Type'])) { + // Type has not changed so unset + unset($tab_modif[$fld_id]['modify']); + } else { + if (!empty($tab_modif[$fld_id]['def_modify'])) { + // if a default has been modified, use it here and unset + $sql_modify .= "MODIFY COLUMN {$fld_id} {$tab_modif[$fld_id]['modify']} DEFAULT '{$tab_modif[$fld_id]['def_modify']}', "; + // def_modify has been used so unset + unset($tab_modif[$fld_id]['def_modify']); + } else if (!empty($tab_modif[$fld_id]['create'])) { + // use create attributes + $sql_modify .= "MODIFY COLUMN {$fld_id} {$tab_modif[$fld_id]['create']}, "; + } else { + // No default to modify so leave unchanged + $sql_modify .= "MODIFY COLUMN {$fld_id} {$tab_modif[$fld_id]['modify']}, "; + } + $count_modify ++; + } + } + + if (!empty($tab_modif[$fld_id]['def_modify'])) { + // Check if def_modify value is same as current value + if (strtoupper($tab_modif[$fld_id]['def_modify']) == strtoupper($tabl_data['Default'])) { + // Defaults have not changed so unset + unset($tab_modif[$fld_id]['def_modify']); + } else { + $sql_modify .= "ALTER COLUMN {$fld_id} SET DEFAULT '{$tab_modif[$fld_id]['def_modify']}', "; + $count_modify ++; + } + } + + if (!empty($tab_modif[$fld_id]['rename'])) { + // Field currently exists so need to rename (and keep data) + // for backward compatibility use CHANGE - REPLACE is only available in MariaDb > 10.5. + $fld_id_newName = $tab_modif[$fld_id]['rename']; + // Does a create exist for newName + if (!empty($tab_modif[$fld_id_newName]['create'])) { + //carry the attributes from the new create to the rename + $sql_rename .= "CHANGE COLUMN {$fld_id} {$fld_id_newName} {$tab_modif[$fld_id_newName]['create']}, "; + // do not create newName as modifying existing + unset($tab_modif[$fld_id_newName]['create']); + } else { + // add current attributes to the new name. + $existingAttrs = strtoupper($tabl_data['Type']).(($tabl_data['Null'] == 'NO') ?' NOT NULL': ' NULL') . + ((empty($tabl_data['Default']))?'': ' DEFAULT ' . "'" . $tabl_data['Default']."'"); + $sql_rename .= "CHANGE COLUMN {$fld_id} {$fld_id_newName} {$existingAttrs}, "; + } + unset($tab_modif[$fld_id]['rename']); $count_modify ++; } + // is there a create for this field + if (!empty($tab_modif[$fld_id]['create'])) { + // unset as cannot create existing field + unset($tab_modif[$fld_id]['create']); + } } } - if (!empty($sql_update)) { - $sql_update = 'BEGIN; ' . $sql_update . ' COMMIT;'; - sql($sql_update); - $affected_rows = $db->affectedRows(); - outn("
  • " . _("Updated table rows :") . $affected_rows . "
  • "); + // only case left to handle is create as all others handled above + foreach ($tab_modif as $row_fld => $row_data) { + if (!empty($row_data['create'])) { + $sql_create .= "ADD COLUMN {$row_fld} {$row_data['create']}, "; + $count_modify ++; + } } - + //Now execute sql statements if (!empty($sql_create)) { - outn("
  • " . _("Adding new FILTER_VALIDATE_INT") . "
  • "); - $sql_create = "ALTER TABLE `" . $tabl_name . "` " . substr($sql_create, 0, -2); + outn("
  • " . _("Adding/dropping columns ...") . "
  • "); + $sql_create = "ALTER TABLE {$tabl_name} " .substr($sql_create, 0, -2); + try { $check = $db->query($sql_create); - if (DB::IsError($check)) { - die_freepbx("Can not create " . $tabl_name . " table sql: " . $sql_create . "n"); + } catch (\Exception $e) { + die_freepbx("Can't add/drop column in {$tabl_name}. SQL: {$sql_create} \n"); } } if (!empty($sql_modify)) { - outn("
  • " . _("Modifying table ") . $tabl_name ."
  • "); - - $sql_modify = "ALTER TABLE `" . $tabl_name . "` " . substr($sql_modify, 0, -2) . ';'; - $check = $db->query($sql_modify); - if (DB::IsError($check)) { - out("
  • " . print_r($check, 1) . "
  • "); - die("Can not modify " . $tabl_name . " table sql: " . $sql_modify . "n"); - die_freepbx("Can not modify " . $tabl_name . " table sql: " . $sql_modify . "n"); + outn("
  • " . _("Modifying table columns ") . $tabl_name ."
  • "); + $sql_modify = "ALTER TABLE {$tabl_name} " . substr($sql_modify, 0, -2); + try { + $check = $db->query($sql_modify); + } catch (\Exception $e) { + die_freepbx("Can not modify {$tabl_name}. SQL: {$sql_modify} \n"); + } + } + if (!empty($sql_rename)) { + outn("
  • " . _("Renaming table columns ") . $tabl_name ."
  • "); + $sql_rename = "ALTER TABLE {$tabl_name} " . substr($sql_rename, 0, -2); + try { + $check = $db->query($sql_rename); + } catch (\Exception $e) { + die_freepbx("Can not modify {$tabl_name}. SQL: {$sql_rename} \n"); } } } outn("
  • " . _("Total modify count :") . $count_modify . "
  • "); - return true; -} + /* + $stmt = $db->prepare('SELECT CASE WHEN EXISTS(SELECT 1 FROM sccpdevmodel) THEN 0 ELSE 1 END AS IsEmpty;'); + $stmt->execute(); + $result = $stmt->fetchAll(\PDO::FETCH_ASSOC); + if (!$result[0]['IsEmpty']) { + return; + } else { -function InstallDB_fillsccpdevmodel() -{ - global $db; + */ + + // Force update of sccp devmodel to ensure changes are taken into account + outn("Updating sccpdevmodel..."); outn("
  • " . _("Fill sccpdevmodel") . "
  • "); $sql = "REPLACE INTO sccpdevmodel (model, vendor, dns, buttons, loadimage, loadinformationid, enabled, nametemplate) VALUES - ('12 SP', 'CISCO', 1, 1, '', 'loadInformation3', 0, NULL), - ('12 SP+', 'CISCO', 1, 1, '', 'loadInformation2', 0, NULL), - ('30 SP+', 'CISCO', 1, 1, '', 'loadInformation1', 0, NULL), - ('30 VIP', 'CISCO', 1, 1, '', 'loadInformation5', 0, NULL), - ('3911', 'CISCO', 1, 1, '', 'loadInformation446', 0, NULL), - ('3951', 'CISCO', 1, 1, '', 'loadInformation412', 0, ''), - ('6901', 'CISCO', 1, 1, 'SCCP6901.9-2-1-a', 'loadInformation547', 0, NULL), - ('6911', 'CISCO', 1, 1, 'SCCP6911.9-2-1-a', 'loadInformation548', 0, NULL), - ('6921', 'CISCO', 1, 1, 'SCCP69xx.9-4-1-3SR3', 'loadInformation496', 0, NULL), - ('6941', 'CISCO', 1, 1, 'SCCP69xx.9-3-1-3', 'loadInformation495', 0, NULL), - ('6945', 'CISCO', 1, 1, 'SCCP6945.9-3-1-3', 'loadInformation564', 0, NULL), - ('6961', 'CISCO', 1, 1, 'SCCP69xx.9-2-1-0', 'loadInformation497', 0, NULL), - ('7902', 'CISCO', 1, 1, 'CP7902080002SCCP060817A', 'loadInformation30008', 0, NULL), - ('7905', 'CISCO', 1, 1, 'CP7905080003SCCP070409A', 'loadInformation20000', 0, NULL), - ('7906', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation369', 1, 'SEP0000000000.cnf.xml_791x_template'), - ('7910', 'CISCO', 1, 1, 'P00405000700', 'loadInformation6', 1, 'SEP0000000000.cnf.xml_791x_template'), - ('7911', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_template'), - ('7912', 'CISCO', 1, 1, 'CP7912080004SCCP080108A', 'loadInformation30007', 0, NULL), - ('7914', 'CISCO', 0, 14, 'S00105000400', 'loadInformation124', 1, NULL), - ('7914;7914', 'CISCO', 0, 28, 'S00105000400', 'loadInformation124', 1, NULL), - ('7915', 'CISCO', 0, 24, 'B015-1-0-4-2', 'loadInformation227', 1, NULL), - ('7915;7915', 'CISCO', 0, 48, 'B015-1-0-4-2', 'loadInformation228', 1, NULL), - ('7916', 'CISCO', 0, 24, 'B016-1-0-4-2', 'loadInformation229', 1, NULL), - ('7916;7916', 'CISCO', 0, 48, 'B016-1-0-4-2', 'loadInformation230', 1, NULL), - ('7920', 'CISCO', 1, 1, 'cmterm_7920.4.0-03-02', 'loadInformation30002', 0, NULL), - ('7921', 'CISCO', 1, 1, 'CP7921G-1.4.6.3', 'loadInformation365', 0, NULL), - ('7925', 'CISCO', 1, 6, 'CP7925G-1.4.1SR1', 'loadInformation484', 0, 'SEP0000000000.cnf.xml_7925_template'), - ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.1SR1', 'loadInformation557', 0, NULL), - ('7931', 'CISCO', 1, 34, 'SCCP31.9-2-1S', 'loadInformation348', 0, NULL), - ('7935', 'CISCO', 1, 2, 'P00503021900', 'loadInformation9', 0, NULL), - ('7936', 'CISCO', 1, 1, 'cmterm_7936.3-3-21-0', 'loadInformation30019', 0, NULL), - ('7937', 'CISCO', 1, 1, 'apps37sccp.1-4-5-7', 'loadInformation431', 0, 'SEP0000000000.cnf.xml_7937_template'), - ('7940', 'CISCO', 1, 2, 'P0030801SR02', 'loadInformation8', 1, 'SEP0000000000.cnf.xml_7940_template'), - ('7941', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation115', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7941G-GE', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation309', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7942', 'CISCO', 1, 2, 'SCCP42.9-4-2SR3-1S', 'loadInformation434', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7945', 'CISCO', 1, 2, 'SCCP45.9-3-1SR1-1S', 'loadInformation435', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7960', 'CISCO', 3, 6, 'P0030801SR02', 'loadInformation7', 1, 'SEP0000000000.cnf.xml_7940_template'), - ('7961', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation30018', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7961G-GE', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation308', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7962', 'CISCO', 3, 6, 'SCCP42.9-4-2SR3-1S', 'loadInformation404', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7965', 'CISCO', 3, 6, 'SCCP45.9-3-1SR1-1S', 'loadInformation436', 0, 'SEP0000000000.cnf.xml_796x_template'), - ('7970', 'CISCO', 3, 8, 'SCCP70.9-4-2SR3-1S', 'loadInformation30006', 0, 'SEP0000000000.cnf.xml_797x_template'), - ('7971', 'CISCO', 1, 2, 'SCCP70.9-4-2SR3-1S', 'loadInformation119', 0, 'SEP0000000000.cnf.xml_797x_template'), - ('7975', 'CISCO', 3, 8, 'SCCP75.9-4-2SR3-1S', 'loadInformation437', 0, 'SEP0000000000.cnf.xml_7975_template'), - ('7985', 'CISCO', 3, 8, 'cmterm_7985.4-1-7-0', 'loadInformation302', 0, NULL), - ('8941', 'CISCO', 1, 1, 'SCCP894x.9-2-2-0', 'loadInformation586', 0, NULL), - ('8945', 'CISCO', 1, 1, 'SCCP894x.9-2-2-0', 'loadInformation585', 0, NULL), - ('ATA 186', 'CISCO', 1, 1, 'ATA030204SCCP090202A', 'loadInformation12', 0, 'SEP0000000000.cnf.xml_ATA_template'), - ('ATA 187', 'CISCO', 1, 1, 'ATA187.9-2-3-1', 'loadInformation550', 0, 'SEP0000000000.cnf.xml_ATA_template'), - ('CN622', 'MOTOROLA', 1, 1, '', 'loadInformation335', 0, NULL), - ('Digital Access', 'CISCO', 1, 1, 'D001M022', 'loadInformation40', 0, NULL), - ('Digital Access+', 'CISCO', 1, 1, 'D00303010033', 'loadInformation42', 0, NULL), - ('E-Series', 'NOKIA', 1, 1, '', '', 0, NULL), - ('ICC', 'NOKIA', 1, 1, '', '', 0, NULL), - ('Analog Access', 'CISCO', 1, 1, 'A001C030', 'loadInformation30', 0, ''),('WS-X6608', 'CISCO', 1, 1, 'D00404000032', 'loadInformation43', 0, ''), - ('WS-X6624', 'CISCO', 1, 1, 'A00204000013', 'loadInformation43', 0, ''), - ('WS-X6608', 'CISCO', 1, 1, 'C00104000003', 'loadInformation51', 0, ''), - ('H.323 Phone', 'CISCO', 1, 1, '', 'loadInformation61', 0, ''), - ('Simulator', 'CISCO', 1, 1, '', 'loadInformation100', 0, ''), - ('MTP', 'CISCO', 1, 1, '', 'loadInformation111', 0, ''), - ('MGCP Station', 'CISCO', 1, 1, '', 'loadInformation120', 0, ''), - ('MGCP Trunk', 'CISCO', 1, 1, '', 'loadInformation121', 0, ''), - ('UPC', 'CISCO', 1, 1, '', 'loadInformation358', 0, ''), - ('TelePresence', 'TELEPRESENCE', 1, 1, '', 'loadInformation375', 0, ''), - ('1000', 'TELEPRESENCE', 1, 1, '', 'loadInformation478', 0, ''), - ('3000', 'TELEPRESENCE', 1, 1, '', 'loadInformation479', 0, ''), - ('3200', 'TELEPRESENCE', 1, 1, '', 'loadInformation480', 0, ''), - ('500-37', 'TELEPRESENCE', 1, 1, '', 'loadInformation481', 0, ''), - ('1300-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation505', 0, ''), - ('1100', 'TELEPRESENCE', 1, 1, '', 'loadInformation520', 0, ''), - ('200', 'TELEPRESENCE', 1, 1, '', 'loadInformation557', 0, ''), - ('400', 'TELEPRESENCE', 1, 1, '', 'loadInformation558', 0, ''), - ('EX90', 'TELEPRESENCE', 1, 1, '', 'loadInformation584', 0, ''), - ('500-32', 'TELEPRESENCE', 1, 1, '', 'loadInformation590', 0, ''), - ('1300-47', 'TELEPRESENCE', 1, 1, '', 'loadInformation591', 0, ''), - ('TX1310-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation596', 0, ''), - ('EX60', 'TELEPRESENCE', 1, 1, '', 'loadInformation604', 0, ''), - ('C90', 'TELEPRESENCE', 1, 1, '', 'loadInformation606', 0, ''), - ('C60', 'TELEPRESENCE', 1, 1, '', 'loadInformation607', 0, ''), - ('C40', 'TELEPRESENCE', 1, 1, '', 'loadInformation608', 0, ''), - ('C20', 'TELEPRESENCE', 1, 1, '', 'loadInformation609', 0, ''), - ('C20-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation610', 0, ''), - ('C60-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation611', 0, ''), - ('C40-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation612', 0, ''), - ('C60-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation613', 0, ''), - ('C60-52D', 'TELEPRESENCE', 1, 1, '', 'loadInformation614', 0, ''), - ('C60-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation615', 0, ''), - ('C90-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation616', 0, ''), - ('MX200', 'TELEPRESENCE', 1, 1, '', 'loadInformation617', 0, ''), - ('TX9000', 'TELEPRESENCE', 1, 1, '', 'loadInformation619', 0, ''), - ('TX9200', 'TELEPRESENCE', 1, 1, '', 'loadInformation620', 0, ''), - ('SX20', 'TELEPRESENCE', 1, 1, '', 'loadInformation626', 0, ''), - ('MX300', 'TELEPRESENCE', 1, 1, '', 'loadInformation627', 0, ''), - ('C40-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation633', 0, ''), - ('Jabber', 'CISCO', 1, 1, '', 'loadInformation652', 0, ''), - ('S60', 'NOKIA', 0, 1, '', 'loadInformation376', 0, ''), - ('9971', 'CISCO', 1, 1, '', 'loadInformation493', 0, ''), - ('9951', 'CISCO', 1, 1, '', 'loadInformation537', 0, ''), - ('8961', 'CISCO', 1, 1, '', 'loadInformation540', 0, ''), - ('Iphone', 'APPLE', 0, 1, '', 'loadInformation562', 0, ''), - ('Android', 'ANDROID', 0, 1, '', 'loadInformation575', 0, ''), - ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.5.3', 'loadInformation577', 0, ''), - ('7821', 'CISCO', 1, 1, '', 'loadInformation621', 0, ''), - ('7841', 'CISCO', 1, 1, '', 'loadInformation622', 0, ''), - ('7861', 'CISCO', 1, 1, '', 'loadInformation623', 0, ''), - ('VXC 6215', 'CISCO', 1, 1, '', 'loadInformation634', 0, ''), - ('8831', 'CISCO', 1, 1, '', 'loadInformation659', 0, ''), - ('8841', 'CISCO', 1, 1, '', 'loadInformation683', 0, ''), - ('8851', 'CISCO', 1, 1, '', 'loadInformation684', 0, ''), - ('8861', 'CISCO', 1, 1, '', 'loadInformation685', 0, ''), - ('Analog', 'CISCO', 1, 1, '', 'loadInformation30027', 0, ''), - ('ISDN', 'CISCO', 1, 1, '', 'loadInformation30028', 0, ''), - ('SCCP GW', 'CISCO', 1, 1, '', 'loadInformation30032', 0, ''), - ('IP-STE', 'CISCO', 1, 1, '', 'loadInformation30035', 0, ''), - ('SPA 521S', 'CISCO', 1, 1, '', 'loadInformation80000', 0, ''), - ('SPA 502G', 'CISCO', 1, 1, '', 'loadInformation80003', 0, ''), - ('SPA 504G', 'CISCO', 1, 1, '', 'loadInformation80004', 0, ''), - ('SPA 525G', 'CISCO', 1, 1, '', 'loadInformation80005', 0, ''), - ('SPA 525G2', 'CISCO', 1, 1, '', 'loadInformation80009', 0, ''), - ('SPA 303G', 'CISCO', 1, 1, '', 'loadInformation80011', 0, ''), - ('IP Communicator', 'CISCO', 1, 1, '', 'loadInformation30016', 0, NULL), - ('Nokia E', 'Nokia', 1, 28, '', 'loadInformation275', 0, NULL), - ('VGC Phone', 'CISCO', 1, 1, '', 'loadInformation10', 0, NULL), - ('7911-sip', 'CISCO-SIP', 1, 1, 'SIP11.9-2-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_sip_template'), - ('9951-sip', 'CISCO-SIP', 1, 1, 'sip9951.9-2-2SR1-9', 'loadinformation537', 1, 'SEP0000000000.cnf.xml_99xx_sip_template'), - ('VGC Virtual', 'CISCO', 1, 1, '', 'loadInformation11', 0, NULL);"; + ('12 SP', 'CISCO', 1, 1, '', 'loadInformation3', 0, NULL), + ('12 SP+', 'CISCO', 1, 1, '', 'loadInformation2', 0, NULL), + ('30 SP+', 'CISCO', 1, 1, '', 'loadInformation1', 0, NULL), + ('30 VIP', 'CISCO', 1, 1, '', 'loadInformation5', 0, NULL), + ('3911', 'CISCO', 1, 1, '', 'loadInformation446', 0, NULL), + ('3951', 'CISCO', 1, 1, '', 'loadInformation412', 0, ''), + ('6901', 'CISCO', 1, 1, 'SCCP6901.9-2-1-a', 'loadInformation547', 0, NULL), + ('6911', 'CISCO', 1, 1, 'SCCP6911.9-2-1-a', 'loadInformation548', 0, NULL), + ('6921', 'CISCO', 1, 1, 'SCCP69xx.9-4-1-3SR3', 'loadInformation496', 0, NULL), + ('6941', 'CISCO', 1, 1, 'SCCP69xx.9-3-1-3', 'loadInformation495', 0, NULL), + ('6945', 'CISCO', 1, 1, 'SCCP6945.9-3-1-3', 'loadInformation564', 0, NULL), + ('6961', 'CISCO', 1, 1, 'SCCP69xx.9-2-1-0', 'loadInformation497', 0, NULL), + ('7902', 'CISCO', 1, 1, 'CP7902080002SCCP060817A', 'loadInformation30008', 0, NULL), + ('7905', 'CISCO', 1, 1, 'CP7905080003SCCP070409A', 'loadInformation20000', 0, NULL), + ('7906', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation369', 1, 'SEP0000000000.cnf.xml_791x_template'), + ('7910', 'CISCO', 1, 1, 'P00405000700', 'loadInformation6', 1, 'SEP0000000000.cnf.xml_791x_template'), + ('7911', 'CISCO', 1, 1, 'SCCP11.9-4-2SR3-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_template'), + ('7912', 'CISCO', 1, 1, 'CP7912080004SCCP080108A', 'loadInformation30007', 0, NULL), + ('7914', 'CISCO', 0, 14, 'S00105000400', 'loadInformation124', 1, NULL), + ('7914;7914', 'CISCO', 0, 28, 'S00105000400', 'loadInformation124', 1, NULL), + ('7915', 'CISCO', 0, 24, 'B015-1-0-4-2', 'loadInformation227', 1, NULL), + ('7915;7915', 'CISCO', 0, 48, 'B015-1-0-4-2', 'loadInformation228', 1, NULL), + ('7916', 'CISCO', 0, 24, 'B016-1-0-4-2', 'loadInformation229', 1, NULL), + ('7916;7916', 'CISCO', 0, 48, 'B016-1-0-4-2', 'loadInformation230', 1, NULL), + ('7920', 'CISCO', 1, 1, 'cmterm_7920.4.0-03-02', 'loadInformation30002', 0, NULL), + ('7921', 'CISCO', 1, 1, 'CP7921G-1.4.6.3', 'loadInformation365', 0, NULL), + ('7925', 'CISCO', 1, 6, 'CP7925G-1.4.1SR1', 'loadInformation484', 0, 'SEP0000000000.cnf.xml_7925_template'), + ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.1SR1', 'loadInformation557', 0, NULL), + ('7931', 'CISCO', 1, 34, 'SCCP31.9-2-1S', 'loadInformation348', 0, NULL), + ('7935', 'CISCO', 1, 2, 'P00503021900', 'loadInformation9', 0, NULL), + ('7936', 'CISCO', 1, 1, 'cmterm_7936.3-3-21-0', 'loadInformation30019', 0, NULL), + ('7937', 'CISCO', 1, 1, 'apps37sccp.1-4-5-7', 'loadInformation431', 0, 'SEP0000000000.cnf.xml_7937_template'), + ('7940', 'CISCO', 1, 2, 'P0030801SR02', 'loadInformation8', 1, 'SEP0000000000.cnf.xml_7940_template'), + ('7941', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation115', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7941G-GE', 'CISCO', 1, 2, 'SCCP41.9-4-2SR3-1S', 'loadInformation309', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7942', 'CISCO', 1, 2, 'SCCP42.9-4-2SR3-1S', 'loadInformation434', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7945', 'CISCO', 1, 2, 'SCCP45.9-3-1SR1-1S', 'loadInformation435', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7960', 'CISCO', 3, 6, 'P0030801SR02', 'loadInformation7', 1, 'SEP0000000000.cnf.xml_7940_template'), + ('7961', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation30018', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7961G-GE', 'CISCO', 3, 6, 'SCCP41.9-4-2SR3-1S', 'loadInformation308', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7962', 'CISCO', 3, 6, 'SCCP42.9-4-2SR3-1S', 'loadInformation404', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7965', 'CISCO', 3, 6, 'SCCP45.9-3-1SR1-1S', 'loadInformation436', 0, 'SEP0000000000.cnf.xml_796x_template'), + ('7970', 'CISCO', 3, 8, 'SCCP70.9-4-2SR3-1S', 'loadInformation30006', 0, 'SEP0000000000.cnf.xml_797x_template'), + ('7971', 'CISCO', 1, 2, 'SCCP70.9-4-2SR3-1S', 'loadInformation119', 0, 'SEP0000000000.cnf.xml_797x_template'), + ('7975', 'CISCO', 3, 8, 'SCCP75.9-4-2SR3-1S', 'loadInformation437', 0, 'SEP0000000000.cnf.xml_7975_template'), + ('7985', 'CISCO', 3, 8, 'cmterm_7985.4-1-7-0', 'loadInformation302', 0, NULL), + ('8941', 'CISCO', 1, 4, 'SCCP894x.9-4-2SR1-2', 'loadInformation586', 0, 'SEP0000000000.cnf.xml_797x_template'), + ('8945', 'CISCO', 1, 4, 'SCCP894x.9-4-2SR1-2', 'loadInformation585', 0, 'SEP0000000000.cnf.xml_7975_template'), + ('ATA 186', 'CISCO', 1, 1, 'ATA030204SCCP090202A', 'loadInformation12', 0, 'SEP0000000000.cnf.xml_ATA_template'), + ('ATA 187', 'CISCO', 1, 1, 'ATA187.9-2-3-1', 'loadInformation550', 0, 'SEP0000000000.cnf.xml_ATA_template'), + ('CN622', 'MOTOROLA', 1, 1, '', 'loadInformation335', 0, NULL), + ('Digital Access', 'CISCO', 1, 1, 'D001M022', 'loadInformation40', 0, NULL), + ('Digital Access+', 'CISCO', 1, 1, 'D00303010033', 'loadInformation42', 0, NULL), + ('E-Series', 'NOKIA', 1, 1, '', '', 0, NULL), + ('ICC', 'NOKIA', 1, 1, '', '', 0, NULL), + ('Analog Access', 'CISCO', 1, 1, 'A001C030', 'loadInformation30', 0, ''),('WS-X6608', 'CISCO', 1, 1, 'D00404000032', 'loadInformation43', 0, ''), + ('WS-X6624', 'CISCO', 1, 1, 'A00204000013', 'loadInformation43', 0, ''), + ('WS-X6608', 'CISCO', 1, 1, 'C00104000003', 'loadInformation51', 0, ''), + ('H.323 Phone', 'CISCO', 1, 1, '', 'loadInformation61', 0, ''), + ('Simulator', 'CISCO', 1, 1, '', 'loadInformation100', 0, ''), + ('MTP', 'CISCO', 1, 1, '', 'loadInformation111', 0, ''), + ('MGCP Station', 'CISCO', 1, 1, '', 'loadInformation120', 0, ''), + ('MGCP Trunk', 'CISCO', 1, 1, '', 'loadInformation121', 0, ''), + ('UPC', 'CISCO', 1, 1, '', 'loadInformation358', 0, ''), + ('TelePresence', 'TELEPRESENCE', 1, 1, '', 'loadInformation375', 0, ''), + ('1000', 'TELEPRESENCE', 1, 1, '', 'loadInformation478', 0, ''), + ('3000', 'TELEPRESENCE', 1, 1, '', 'loadInformation479', 0, ''), + ('3200', 'TELEPRESENCE', 1, 1, '', 'loadInformation480', 0, ''), + ('500-37', 'TELEPRESENCE', 1, 1, '', 'loadInformation481', 0, ''), + ('1300-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation505', 0, ''), + ('1100', 'TELEPRESENCE', 1, 1, '', 'loadInformation520', 0, ''), + ('200', 'TELEPRESENCE', 1, 1, '', 'loadInformation557', 0, ''), + ('400', 'TELEPRESENCE', 1, 1, '', 'loadInformation558', 0, ''), + ('EX90', 'TELEPRESENCE', 1, 1, '', 'loadInformation584', 0, ''), + ('500-32', 'TELEPRESENCE', 1, 1, '', 'loadInformation590', 0, ''), + ('1300-47', 'TELEPRESENCE', 1, 1, '', 'loadInformation591', 0, ''), + ('TX1310-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation596', 0, ''), + ('EX60', 'TELEPRESENCE', 1, 1, '', 'loadInformation604', 0, ''), + ('C90', 'TELEPRESENCE', 1, 1, '', 'loadInformation606', 0, ''), + ('C60', 'TELEPRESENCE', 1, 1, '', 'loadInformation607', 0, ''), + ('C40', 'TELEPRESENCE', 1, 1, '', 'loadInformation608', 0, ''), + ('C20', 'TELEPRESENCE', 1, 1, '', 'loadInformation609', 0, ''), + ('C20-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation610', 0, ''), + ('C60-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation611', 0, ''), + ('C40-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation612', 0, ''), + ('C60-52', 'TELEPRESENCE', 1, 1, '', 'loadInformation613', 0, ''), + ('C60-52D', 'TELEPRESENCE', 1, 1, '', 'loadInformation614', 0, ''), + ('C60-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation615', 0, ''), + ('C90-65', 'TELEPRESENCE', 1, 1, '', 'loadInformation616', 0, ''), + ('MX200', 'TELEPRESENCE', 1, 1, '', 'loadInformation617', 0, ''), + ('TX9000', 'TELEPRESENCE', 1, 1, '', 'loadInformation619', 0, ''), + ('TX9200', 'TELEPRESENCE', 1, 1, '', 'loadInformation620', 0, ''), + ('SX20', 'TELEPRESENCE', 1, 1, '', 'loadInformation626', 0, ''), + ('MX300', 'TELEPRESENCE', 1, 1, '', 'loadInformation627', 0, ''), + ('C40-42', 'TELEPRESENCE', 1, 1, '', 'loadInformation633', 0, ''), + ('Jabber', 'CISCO', 1, 1, '', 'loadInformation652', 0, ''), + ('S60', 'NOKIA', 0, 1, '', 'loadInformation376', 0, ''), + ('9971', 'CISCO', 1, 1, '', 'loadInformation493', 0, ''), + ('9951', 'CISCO', 1, 1, '', 'loadInformation537', 0, ''), + ('8961', 'CISCO', 1, 1, '', 'loadInformation540', 0, ''), + ('Iphone', 'APPLE', 0, 1, '', 'loadInformation562', 0, ''), + ('Android', 'ANDROID', 0, 1, '', 'loadInformation575', 0, ''), + ('7926', 'CISCO', 1, 1, 'CP7926G-1.4.5.3', 'loadInformation577', 0, ''), + ('7821', 'CISCO', 1, 1, '', 'loadInformation621', 0, ''), + ('7841', 'CISCO', 1, 1, '', 'loadInformation622', 0, ''), + ('7861', 'CISCO', 1, 1, '', 'loadInformation623', 0, ''), + ('VXC 6215', 'CISCO', 1, 1, '', 'loadInformation634', 0, ''), + ('8831', 'CISCO', 1, 1, '', 'loadInformation659', 0, ''), + ('8841', 'CISCO', 1, 1, '', 'loadInformation683', 0, ''), + ('8851', 'CISCO', 1, 1, '', 'loadInformation684', 0, ''), + ('8861', 'CISCO', 1, 1, '', 'loadInformation685', 0, ''), + ('Analog', 'CISCO', 1, 1, '', 'loadInformation30027', 0, ''), + ('ISDN', 'CISCO', 1, 1, '', 'loadInformation30028', 0, ''), + ('SCCP GW', 'CISCO', 1, 1, '', 'loadInformation30032', 0, ''), + ('IP-STE', 'CISCO', 1, 1, '', 'loadInformation30035', 0, ''), + ('SPA 521S', 'CISCO', 1, 1, '', 'loadInformation80000', 0, ''), + ('SPA 502G', 'CISCO', 1, 1, '', 'loadInformation80003', 0, ''), + ('SPA 504G', 'CISCO', 1, 1, '', 'loadInformation80004', 0, ''), + ('SPA 525G', 'CISCO', 1, 1, '', 'loadInformation80005', 0, ''), + ('SPA 525G2', 'CISCO', 1, 1, '', 'loadInformation80009', 0, ''), + ('SPA 303G', 'CISCO', 1, 1, '', 'loadInformation80011', 0, ''), + ('IP Communicator', 'CISCO', 1, 1, '', 'loadInformation30016', 0, NULL), + ('Nokia E', 'Nokia', 1, 28, '', 'loadInformation275', 0, NULL), + ('VGC Phone', 'CISCO', 1, 1, '', 'loadInformation10', 0, NULL), + ('7911-sip', 'CISCO-SIP', 1, 1, 'SIP11.9-2-1S', 'loadInformation307', 1, 'SEP0000000000.cnf.xml_791x_sip_template'), + ('9951-sip', 'CISCO-SIP', 1, 1, 'sip9951.9-2-2SR1-9', 'loadinformation537', 1, 'SEP0000000000.cnf.xml_99xx_sip_template'), + ('VGC Virtual', 'CISCO', 1, 1, '', 'loadInformation11', 0, NULL);"; $check = $db->query($sql); if (DB::IsError($check)) { die_freepbx("Can not create sccpdevmodel table, error:$check\n"); } - return true; + //} + return; } function InstallDB_createButtonConfigTrigger() @@ -577,7 +681,6 @@ function InstallDB_createButtonConfigTrigger() die_freepbx("Can not modify sccpdevice table\n"); } outn("
  • " . _("(Re)Create trigger Ok") . "
  • "); -// outn("
  • " . $sql . "
  • "); return true; } function InstallDB_updateDBVer($sccp_compatible) @@ -592,12 +695,15 @@ function InstallDB_updateDBVer($sccp_compatible) return true; } -function InstallDB_CreateSccpDeviceConfigView($sccp_compatible) +function InstallDbCreateViews($sccp_compatible) { global $db; outn("
  • " . _("(Re)Create sccpdeviceconfig view") . "
  • "); $sql = "DROP VIEW IF EXISTS sccpdeviceconfig; - DROP VIEW IF EXISTS sccpuserconfig;"; + DROP VIEW IF EXISTS sccpuserconfig; + "; + /// global $hw_mobil; + // From logserver to end only applies to db ver > 433 global $mobile_hw; if ($mobile_hw == '1') { @@ -617,32 +723,89 @@ function InstallDB_CreateSccpDeviceConfigView($sccp_compatible) 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.* + 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.name, sccpdevice.type, + sccpdevice.addon, sccpdevice.tzoffset, sccpdevice.imageversion, sccpdevice.deny, sccpdevice.permit, sccpdevice.earlyrtp, sccpdevice.mwilamp, + sccpdevice.mwioncall, sccpdevice.dndFeature, sccpdevice.transfer, sccpdevice.cfwdall, sccpdevice.cfwdbusy, sccpdevice.private, sccpdevice.privacy, + sccpdevice.nat, sccpdevice.directrtp, sccpdevice.softkeyset, sccpdevice.audio_tos, sccpdevice.audio_cos, sccpdevice.video_tos, sccpdevice.video_cos, + sccpdevice.conf_allow, sccpdevice.conf_play_general_announce, sccpdevice.conf_play_part_announce, sccpdevice.conf_mute_on_entry, + sccpdevice.conf_music_on_hold_class, sccpdevice.conf_show_conflist, sccpdevice.force_dtmfmode, sccpdevice.setvar, sccpdevice.backgroundImage, + sccpdevice.backgroundThumbnail, sccpdevice.ringtone, sccpdevice.callhistory_answered_elsewhere, sccpdevice.useRedialMenu, sccpdevice.cfwdnoanswer, + sccpdevice.park, sccpdevice.monitor, sccpdevice.phonecodepage, sccpdevice.keepalive FROM sccpdevice - LEFT JOIN sccpuser sccpuser ON ( sccpuser.name = sccpdevice._loginname ) + LEFT JOIN sccpuser sccpuser ON ( sccpuser.name = sccpdevice.loginname ) GROUP BY sccpdevice.name;"; } - - $results = $db->query($sql); - if (DB::IsError($results)) { + $stmt = $db->prepare($sql); + $stmt->execute(); + if (DB::IsError($stmt)) { die_freepbx(sprintf(_("Error updating sccpdeviceconfig view. Command was: %s; error was: %s "), $sql, $results->getMessage())); } + + outn("
  • " . _("(Re)Create sccplineconfig view") . "
  • "); + + $sql = "DROP VIEW IF EXISTS sccplineconfig; + "; + $sql .= "CREATE OR REPLACE + VIEW sccplineconfig AS + SELECT sccpline.name, sccpline.id, sccpline.pin ,sccpline.label, sccpline.description, sccpline.context, sccpline.incominglimit, sccpline.transfer, sccpline.mailbox, + sccpline.vmnum, sccpline.cid_name, sccpline.cid_num, sccpline.disallow, sccpline.allow, sccpline.trnsfvm, sccpline.secondary_dialtone_digits, + sccpline.secondary_dialtone_tone, sccpline.musicclass, sccpline.language, sccpline.accountcode, sccpline.echocancel, sccpline.silencesuppression, + sccpline.callgroup, sccpline.pickupgroup, sccpline.adhocNumber, sccpline.meetme, sccpline.meetmenum, sccpline.meetmeopts, sccpline.regexten, + sccpline.directed_pickup, sccpline.directed_pickup_context, sccpline.pickup_modeanswer, sccpline.amaflags, sccpline.dnd, sccpline.setvar, + sccpline.namedcallgroup, sccpline.namedpickupgroup, sccpline.phonecodepage, sccpline.videomode + FROM sccpline"; + $stmt = $db->prepare($sql); + $stmt->execute(); + if (DB::IsError($stmt)) { + die_freepbx(sprintf(_("Error updating sccplineconfig view. Command was: %s; error was: %s "), $sql, $results->getMessage())); + } return true; } + +function installDbPopulateSccpline() { + // Lines in Sccp_manager are devices in FreePbx. Need to ensure that these two tables are synchronised on install + global $db; + $freePbxExts = array (); + $sccpExts =array(); + $sql = "SELECT id AS name, user AS accountcode, description AS label FROM devices WHERE tech='sccp'"; + $stmt = $db->prepare($sql); + $stmt->execute(); + $freePbxExts = $stmt->fetchAll(\PDO::FETCH_ASSOC|\PDO::FETCH_UNIQUE); + + $sql = "SELECT name, accountcode, label FROM sccpline"; + $stmt = $db->prepare($sql); + $stmt->execute(); + $sccpExts = $stmt->fetchAll(\PDO::FETCH_ASSOC|\PDO::FETCH_UNIQUE); + $linesToCreate = array_diff_assoc($freePbxExts, $sccpExts); + + foreach ($linesToCreate as $key => $valArr) { + $stmt = $db->prepare("INSERT into sccpline (name, accountcode, description, label) VALUES (:name, :accountcode, :description, :label)"); + $stmt->bindParam(':name',$key,\PDO::PARAM_STR); + $description = "{$valArr['label']} <{$key}>"; + $stmt->bindParam(':accountcode',$valArr['accountcode'],\PDO::PARAM_STR); + $stmt->bindParam(':description',$description,\PDO::PARAM_STR); + $stmt->bindParam(':label',$valArr['label'],\PDO::PARAM_STR); + $stmt->execute(); + if (DB::IsError($stmt)) { + die_freepbx(sprintf(_("Error inserting into sccpline. Command was: %s; error was: %s "), $stmt, $stmt->getMessage())); + } + } +} + function createBackUpConfig() { global $amp_conf; + global $cnf_int; outn("
  • " . _("Creating Config BackUp") . "
  • "); - $cnf_int = \FreePBX::Config(); $backup_files = array('extensions','extconfig','res_mysql', 'res_config_mysql','sccp','sccp_hardware','sccp_extensions'); $backup_ext = array('_custom.conf', '_additional.conf','.conf'); $dir = $cnf_int->get('ASTETCDIR'); @@ -657,7 +820,7 @@ function createBackUpConfig() outn("PHPx.x-zip not installed where x.x is the installed PHP version. Install it before continuing !"); die_freepbx(); } - $filename = $dir . "/sccp_install_backup" . date("Ymd"). ".zip"; + $filename = $dir . "/sccp_install_backup" . date("Ymdhis"). ".zip"; if ($zip->open($filename, \ZIPARCHIVE::CREATE)) { foreach ($backup_files as $file) { foreach ($backup_ext as $b_ext) { @@ -679,9 +842,8 @@ function createBackUpConfig() function RenameConfig() { - global $amp_conf; outn("
  • " . _("Move Old Config") . "
  • "); - $cnf_int = \FreePBX::Config(); + global $cnf_int; $rename_files = array('sccp_hardware','sccp_extensions'); $rename_ext = array('_custom.conf', '_additional.conf','.conf'); $dir = $cnf_int->get('ASTETCDIR'); @@ -698,7 +860,7 @@ function Setup_RealTime() { outn("
  • " . _("Checking realtime configuration ...") . "
  • "); global $amp_conf; - $cnf_int = \FreePBX::Config(); + global $cnf_int; $cnf_wr = \FreePBX::WriteConfig(); $cnf_read = \FreePBX::LoadConfig(); @@ -719,7 +881,7 @@ function Setup_RealTime() } } $def_bd_section = $amp_conf['AMPDBNAME']; - $def_ext_config = array('sccpdevice' => "mysql,{$def_bd_section},sccpdeviceconfig",'sccpline' => "mysql,{$def_bd_section},sccpline"); + $def_ext_config = array('sccpdevice' => "mysql,{$def_bd_section},sccpdeviceconfig",'sccpline' => "mysql,{$def_bd_section},sccplineconfig"); // Check extconfig file for correct connector values $ext_conf = ''; @@ -763,7 +925,7 @@ function Setup_RealTime() } // Check database settings - $res_conf = ''; + $res_conf = array(); if (file_exists($dir . '/res_mysql.conf')) { $res_conf = $cnf_read->getConfig('res_mysql.conf'); if (empty($res_conf[$def_bd_section])) { @@ -771,19 +933,282 @@ function Setup_RealTime() $cnf_wr->writeConfig('res_mysql.conf', $res_conf); outn("
  • " . _("Updating res_mysql.conf file ...") . "
  • "); } - } - if (file_exists($dir . '/res_config_mysql.conf')) { + } elseif (file_exists($dir . '/res_config_mysql.conf')) { $res_conf = $cnf_read->getConfig('res_config_mysql.conf'); if (empty($res_conf[$def_bd_section])) { $res_conf[$def_bd_section] = $def_bd_config; $cnf_wr->writeConfig('res_config_mysql.conf', $res_conf); outn("
  • " . _("Updating res_config_mysql.conf file ...") . "
  • "); } - } - if (empty($res_conf)) { + } else { + // Have not found either res_mysql.conf or res_config_mysql.config + // So create the latter $res_conf[$def_bd_section] = $def_bd_config; $cnf_wr->writeConfig('res_config_mysql.conf', $res_conf, false); } } +function addDriver($sccp_compatible) { + global $amp_conf; + global $cnf_int; + outn("
  • " . _("Adding driver ...") . "
  • "); + $file = $amp_conf['AMPWEBROOT'] . '/admin/modules/core/functions.inc/drivers/Sccp.class.php'; + $contents = ""; + file_put_contents($file, $contents); + + $dir = $cnf_int->get('ASTETCDIR'); + if (!file_exists("{$dir}/sccp.conf")) { // System re Config + outn("
  • " . _("Adding default configuration file ...") . "
  • "); + $sccpfile = file_get_contents($amp_conf['AMPWEBROOT'] . '/admin/modules/sccp_manager/conf/sccp.conf'); + file_put_contents("{$dir}/sccp.conf", $sccpfile); + } +} +function checkTftpServer() { + outn("
  • " . _("Checking TFTP server path and availability ...") . "
  • "); + global $db; + global $cnf_int; + global $settingsFromDb; + global $extconfigs; + global $thisInstaller; + global $amp_conf; + $confDir = $cnf_int->get('ASTETCDIR'); + $tftpRootPath = ""; + // put the rewrite rules into the required location + if (file_exists("{$confDir}/sccpManagerRewrite.rules")) { + rename("{$confDir}/sccpManagerRewrite.rules", "{$confDir}/sccpManagerRewrite.rules.bu"); + } + copy($amp_conf['AMPWEBROOT'] . '/admin/modules/sccp_manager/conf/mappingRulesHeader',"{$confDir}/sccpManagerRewrite.rules"); + file_put_contents("{$confDir}/sccpManagerRewrite.rules", file_get_contents($amp_conf['AMPWEBROOT'] . '/admin/modules/sccp_manager/contrib/rewrite.rules'), FILE_APPEND); + file_put_contents("{$confDir}/sccpManagerRewrite.rules", "\n# Do not disable this rule - this is required by sccp_manager\nri ^(.+\.tlzz)?$ settings/\\1", FILE_APPEND); + // TODO: add option to use external server + $remoteFileName = ".sccp_manager_installer_probe_sentinel_temp".mt_rand(0, 9999999); + $remoteFileContent = "# This is a test file created by Sccp_Manager. It can be deleted without impact"; + $possibleFtpDirs = array('/srv', '/srv/tftp','/var/lib/tftp', '/tftpboot'); + + // write a couple of sentinels to different distro tftp locations in the filesystem + // TODO: Depending on distro, do we have write permissions + foreach ($possibleFtpDirs as $dirToTest) { + if (is_dir($dirToTest) && is_writable($dirToTest)) { + $tempFile = "${dirToTest}/{$remoteFileName}"; + file_put_contents($tempFile, $remoteFileContent); + + // try to pull the written file through tftp. + // this way we can determine if tftp server is active, and what it's + // source directory is. + if ($remoteFileContent == $thisInstaller->tftpReadTestFile($remoteFileName)) { + $tftpRootPath = $dirToTest; + outn("
  • " . _("Found ftp root dir at {$tftpRootPath}") . "
  • "); + if ($settingsFromDb['tftp_path']['data'] != $tftpRootPath) { + $settingsFromDb["tftp_path"] = array( 'keyword' => 'tftp_path', 'seq' => 2, 'type' => 0, 'data' => $tftpRootPath, 'systemdefault' => ''); + } + // Found sentinel file. Remove it and exit loop + if (file_exists($tempFile)) { + unlink($tempFile); + } + break; + } + // Did not find sentinel so remove and continue + if (file_exists($tempFile)) { + unlink($tempFile); + } + } + } + if (empty($tftpRootPath)) { + die_freepbx(_("Either TFTP server is down or TFTP root is non standard. Please fix, refresh, and try again")); + } + + $settingsFromDb['asterisk_etc_path'] = array( 'keyword' => 'asterisk_etc_path', 'seq' => 20, 'type' => 0, 'data' => $confDir, 'systemdefault' => ''); + + // Get TFTP mapping Status + $settingsFromDb['tftp_rewrite'] = array('keyword' => 'tftp_rewrite', 'seq' => 20, 'type' => 0, 'data' => 'off', 'systemdefault' => ''); + if ($thisInstaller->checkTftpMapping()) { + $settingsFromDb['tftp_rewrite']['data'] = 'pro'; + } + + // Populate TFTP paths in SccpSettings + $settingsFromDb = $extconfigs->updateTftpStructure($settingsFromDb); + + foreach ($settingsFromDb as $settingToSave) { + $sql = "REPLACE INTO sccpsettings (keyword, data, seq, type, systemdefault) VALUES ('{$settingToSave['keyword']}', '{$settingToSave['data']}', {$settingToSave['seq']}, {$settingToSave['type']}, '{$settingToSave['systemdefault']}')"; + $results = $db->query($sql); + if (DB::IsError($results)) { + die_freepbx(_("Error updating sccpsettings. $sql")); + } + } + return; +} + +function cleanUpSccpSettings() { + global $thisInstaller; + global $settingsFromDb; + global $db; + global $aminterface; + global $sccp_compatible; + global $amp_conf; + + // Get current default settings from db + $stmt = $db->prepare("SELECT keyword, sccpsettings.* FROM sccpsettings"); + $stmt->execute(); + $settingsFromDb = $stmt->fetchAll(\PDO::FETCH_ASSOC|\PDO::FETCH_UNIQUE); + + // See if a previous version was installed + outn("
  • " . _("Checking for previous version of Sccp_manager.") . "
  • "); + if (!isset($settingsFromDb['sccp_compatible']['data'])) { + outn(_("No previous version found ")); + } else { + outn(_("Found DB Schema : {$settingsFromDb['sccp_compatible']['data']}")); + } + // Check that required settings are initialised and update db and $settingsFromDb if not + /* + foreach ($extconfigs->getExtConfig('sccpDefaults') as $key => $value) { + if (empty($settingsFromDb[$key])) { + $settingsFromDb[$key] = array('keyword' => $key, 'data' => $value, 'type' => 0, 'seq' => 0); + + $sql = "REPLACE INTO sccpsettings (keyword, data, seq, type) VALUES ('{$key}', '{$value}', 0, 0)"; + $results = $db->query($sql); + if (DB::IsError($results)) { + die_freepbx(_("Error updating sccpsettings: $key")); + } + } + } + */ + // Clean up sccpsettings to remove legacy values. + $xml_vars = $amp_conf['AMPWEBROOT'] . "/admin/modules/sccp_manager/conf/sccpgeneral.xml.v{$sccp_compatible}"; + $thisInstaller->xml_data = simplexml_load_file($xml_vars); + $thisInstaller->initVarfromXml(); + foreach ( array_diff_key($settingsFromDb,$thisInstaller->sccpvalues) as $key => $valueArray) { + // Remove legacy values + unset($settingsFromDb[$key]); + } + foreach ($settingsFromDb as $key => $valueArray) { + $settingsFromDb[$key]['seq'] = $thisInstaller->sccpvalues[$key]['seq']; + $settingsFromDb[$key]['type'] = $thisInstaller->sccpvalues[$key]['type']; + } + $settingsFromDb = array_merge($settingsFromDb, array_diff_key($thisInstaller->sccpvalues, $settingsFromDb)); + unset($thisInstaller->sccpvalues); + + // get chan-sccp defaults + + foreach (array('general','line', 'device') as $section) { + $sysConfig = $aminterface->getSCCPConfigMetaData($section); + foreach ($sysConfig['Options'] as $valueArray) { + if ($valueArray['Flags'][0] == 'Obsolete' || $valueArray['Flags'][0] == 'Deprecated') { + continue; + } + if (isset($sysConfiguration[$valueArray['Name']])) { + continue; + } + $sysConfiguration[$valueArray['Name']] = $valueArray; + } + } + unset($sysConfig); + foreach ($sysConfiguration as $key => $valueArray) { + + // 2 special cases deny|permit & disallow|allow where need to parse on |. + $newKeyword = explode("|", $key, 2); + if (isset($newKeyword[1])) { + // chan-sccp sets sysdef as comma separated list for sccp.conf, but expects ; separated list + // when returned from db + $newSysDef = explode("|", $valueArray['DefaultValue'], 2); + $newSysDef = str_replace(',',';', $newSysDef); + $i = 0; + foreach ($newKeyword as $dummy) { + if (array_key_exists($newKeyword[$i],$settingsFromDb)) { + if (!empty($newSysDef[$i])) { + $settingsFromDb[$newKeyword[$i]]['systemdefault'] = $newSysDef[$i]; + } + } else { + $settingsFromDb[$newKeyword[$i]] = array('keyword' => $newKeyword[$i], 'seq' => 0, 'type' => 0, 'data' => '', 'systemdefault' => $newSysDef[$i]); + } + $i++; + } + if (array_key_exists($key, $settingsFromDb)){ + unset($settingsFromDb[$key]); + } + } else { + dbug($sysConfiguration); + $sysConfiguration[$key]['DefaultValue'] = ($sysConfiguration[$key]['DefaultValue'] == '(null)') ? '' : $sysConfiguration[$key]['DefaultValue']; + if (array_key_exists($key,$settingsFromDb)) { + // Preserve sequence and type + $settingsFromDb[$key]['systemdefault'] = $sysConfiguration[$key]['DefaultValue']; + } else { + $settingsFromDb[$key] = array('keyword' => $key, 'seq' => 0, 'type' => 0, 'data' => '', 'systemdefault' => $sysConfiguration[$key]['DefaultValue']); + } + } + dbug($settingsFromDb); + // Override certain chan-sccp defaults as they are based on a non-FreePbx system + $settingsFromDb['context']['systemdefault'] = 'from-internal'; + $settingsFromDb['directed_pickup']['systemdefault'] = 'no'; + + unset($sysConfiguration[$key]); + } + unset($sysConfiguration); + + // Update enums in sccpsettings - values have changed over versions so need to update values in db that are not compliant + outn("
  • " . _("Updating invalid enums in sccpsettings") . "
  • "); + $rowsToTest = array(); + $tablesToDescribe = array('sccpline', 'sccpdevice'); + foreach ($tablesToDescribe as $theTable) { + $stmt = $db->prepare("DESCRIBE {$theTable}"); + $stmt->execute(); + $tableDesc = $stmt->fetchAll(\PDO::FETCH_ASSOC|\PDO::FETCH_UNIQUE); + foreach ($tableDesc as $key => $valArr) { + if (strpos($valArr['Type'], 'enum') !== 0) { + continue; + } + $rowsToTest[$key] = explode(',',rtrim(str_replace('enum(', '',$valArr['Type']), ')')); + } + } + $count = 0; + foreach ($rowsToTest as $key => $valArr) { + if (empty($settingsFromDb[$key]['data'])) { + continue; + } + if (in_array("'{$settingsFromDb[$key]['data']}'", $valArr, true)) { + continue; + } + // clear site setting so that will return to system defaults. + // Try to convert based on change from on/off to yes/no. + if (in_array($settingsFromDb[$key]['data'], array('on','off'), true)) { + if (in_array("'yes'", $valArr, true)) { + $settingsFromDb[$key]['data'] = ($settingsFromDb[$key]['data'] = 'on') ? 'yes' : 'no'; + continue; + } + } + // Test for case + if (in_array("'" . strtolower($settingsFromDb[$key]['data']) . "'", $valArr, true)) { + $settingsFromDb[$key]['data'] = strtolower($settingsFromDb[$key]['data']); + continue; + } + // No easy choices so reset to system default + $settingsFromDb[$key]['data'] = ''; + $count++; + } + + // Write settings back to db + $sql = "TRUNCATE sccpsettings"; + $results = $db->query($sql); + foreach ( $settingsFromDb as $key =>$valueArray ) { + $sql = "REPLACE INTO sccpsettings + (keyword, seq, type, data, systemdefault) + VALUES + ( '{$settingsFromDb[$key]['keyword']}', + {$settingsFromDb[$key]['seq']}, + {$settingsFromDb[$key]['type']}, + '{$settingsFromDb[$key]['data']}', + '{$settingsFromDb[$key]['systemdefault']}' + )"; + $results = $db->query($sql); + } + // have to correct prior verion sccpline lists for allow/disallow and deny permit. Prior + // versions used csl, but chan-sccp expects ; separated lists when returned by db. + + outn("
  • " . _("Replacing invalid values in sccpline") . "
  • "); + $db->query("UPDATE sccpline SET allow = REPLACE(allow, ',',';') WHERE allow like '%,%'"); + $db->query("UPDATE sccpline SET disallow = REPLACE(disallow, ',',';') WHERE disallow like '%,%'"); + + // Ensure that disallow is set to all if unset (and not NULL) + $db->query("UPDATE sccpline SET disallow = 'all' WHERE disallow like ''"); + +} ?> diff --git a/module.xml b/module.xml index a42dcb6..abe9e4f 100644 --- a/module.xml +++ b/module.xml @@ -1,7 +1,7 @@ sccp_manager SCCP Manager - 14.2.0.11 + 14.3.0.13 setup SCCP Connectivity Steve Lad, Alex GP @@ -23,6 +23,7 @@ * Version 14.2.0.8 * - Fix uninstaller and create backup * Version 14.2.0.9 * - Bug Fix - incorrect response class for Reset Token Device * Version 14.2.0.10 * - Bug Fix - line not assigned on device creation + * Version 14.3.0.0 * - New Minor Version - Change DB and add new settings https://github.com/chan-sccp/sccp_manager @@ -70,7 +71,6 @@ - @@ -165,9 +165,10 @@ - + +
    diff --git a/sccpManClasses/Sccp.class.php.v433 b/sccpManClasses/Sccp.class.php.v433 new file mode 100644 index 0000000..f6e568c --- /dev/null +++ b/sccpManClasses/Sccp.class.php.v433 @@ -0,0 +1,483 @@ +'pin', "label" => 'label', "accountcode" => 'account', + "context" =>'context',"incominglimit"=>'incominglimit', + "callgroup"=>'callgroup',"pickupgroup"=>'pickupgroup', + "transfer" => 'transfer', "echocancel" => 'echocancel', + "language" => 'language', "description" => 'callerid', + "cid_num" => 'cid_num', "cid_name" => 'label', "mailbox" => 'mailbox', + "musicclass" => 'musicclass', "allow" => 'allow',"disallow" => 'disallow', + "videomode" => 'videomode', 'pickup_modeanswer' => 'pickup_modeanswer', + "dnd" => 'dnd', "silencesuppression" => 'silencesuppression', + "secondary_dialtone_digits" => 'secondary_dialtone_digits', + "secondary_dialtone_tone" => 'secondary_dialtone_tone', + 'namedcallgroup'=>'namedcallgroup', 'namedpickupgroup' => 'namedpickupgroup', + 'directed_pickup' => 'directed_pickup' + ); + // These are gui defaults used by freePBX for the elements in the SCCP tab in add/edit phone. + private $guiDefaults =array( + 'gui_checkset' => array( "elemname" => "", + "prompttext" => "", //ok + "helptext" => "", + "currentvalue" => "", + "valarray" => array(), + "jsonclick" => '', + "jsvalidation" => "", //ok + "failvalidationmsg" => "", //ok + "canbeempty" => true, + "maxchars" => 0, + "disable" => false, //ok + "inputgroup" => false, + "class" => "", + "cblabel" => 'Enable', + "disabled_value" => 'DEFAULT', + "check_enables" => 'true', + "cbdisable" => false, + "cbclass" => '') + ); + + private $line_defaults = array(); + + public function __construct($parent_class = null) { + + $this->freepbx = $parent_class; + $this->database = $parent_class->Database(); + // Get system defaults [systemdefault] and sitedefaults [data] from sccpsettings. + $stmt = $this->database->prepare("SELECT * FROM sccpsettings"); + $stmt->execute(); + $raw_settings = $stmt->fetchAll(\PDO::FETCH_ASSOC); + foreach ($raw_settings as $key => $valueArray) { + $sccpDefaults[$valueArray['keyword']] = $valueArray['systemdefault']; + $siteDefaults[$valueArray['keyword']] = $valueArray['data']; + } + // This will produce an array where site defaults take precedence over system defaults + $this->line_defaults = array_intersect_key($siteDefaults,$sccpDefaults); + // If have no site codecs, use system defaults - must have a codec! + if (empty($this->line_defaults['allow'])) { + $this->line_defaults['allow'] = $sccpDefaults['allow']; + } + if (empty($this->line_defaults['disallow'])) { + $this->line_defaults['disallow'] = $sccpDefaults['disallow']; + } + unset($raw_settings, $siteDefaults, $sccpDefaults); + } + + public function getInfo() { + return array( + "rawName" => "sccp", + "hardware" => "sccp_custom", + "prettyName" => _("Sccp Custom Driver"), + "shortName" => "SCCP", + "description" => _("Sccp Device"), + "Version" => "11.5", + "about" => "Sccp class Base ver: 11.5, Sccp ver: default" + ); + } + + public function addDevice($id, $settings) { + // This is actually save line and is used by add and edit. + $add_fld = array ("name"=>'label',"outboundcid"=>'cid_num',"langcode"=>'language',"extdisplay"=>'description','devinfo_mailbox'=>'mailbox'); + $settings['cid_num']['value'] = ''; + $settings['cid_name']['value'] = ''; + $settings['mailbox']['value']= ''; + + // Add $_REQUEST values to settings + if (isset($_REQUEST)){ + foreach($add_fld as $key => $val) { + if (!empty($_REQUEST[$key])){ + $settings[$val]['value'] = $_REQUEST[$key]; + } + } + } + $allow_codec = array(); + foreach($settings as $key => $val) { + if (strncmp($key,'codec_',6) === 0 ) { + $allow_codec[] = str_replace('codec_','',$key); + } + } + $settings['allow']['value'] = implode(";", $allow_codec); + // Reset to line defaults if no value selected + if (empty($settings['allow']['value'])) { + $settings['allow']['value'] = $this->line_defaults['allow']; + } + + // If set, parse outboundcid content into cid_num and cid_name sccpline fields + if (!empty($settings['cid_num']['value'])) { + $outboundcid = $settings['cid_num']['value']; + if (preg_match('/"(.*)"\s?<(.*)>/', $outboundcid, $matches)) { + $settings['cid_num']['value'] = $matches[2]; + $settings['cid_name']['value'] = $matches[1]; + } else if (is_integer($outboundcid)) { + $settings['cid_num']['value'] = $outboundcid; + } + } + + if ($this->line_defaults['dndFeature'] == 'off') { + $settings['dnd']['value'] = 'off'; + } + + if (!empty($_REQUEST['vm']) && ($_REQUEST['vm'] =='enabled')){ // mailbox + if (empty($settings['mailbox']['value'])) { + $settings['mailbox']['value']= $id; + } + } + + // only store values that have been set; if need to display a default, must show in page. + $sqlSet = "name='{$id}'"; + foreach($this->data_fld as $key => $val) { + if (!empty($settings[$val]['value'])) { + $sqlSet .= ", {$key}='{$settings[$val]['value']}'"; + } + } + + $stmt = "INSERT INTO sccpline SET {$sqlSet} ON DUPLICATE KEY UPDATE {$sqlSet}"; + $sth = $this->database->prepare($stmt); + $sth->execute(); + /* + If called from SCCP Phone, redirect to SCCP Phone page on submit. + This was last function in add so should be safe. + Prefer to add in Hooks, but is not followed even if set for $currentComponent + Do nothing if called from QuickCreateExtension when display is not set + */ + if (isset($_REQUEST['display'])) { + redirect("config.php?display=sccp_phone", false); + } + // Have changed something so need to reload the device + // TODO: are we reloading the device or reloading Asterisk + $this->reload_line($id); + return true; + } + + public function delDevice($id) { + //Required by FreePBX. + // Delete associated default line buttons or will leave orphans + foreach (array($id) as $openId) { + $sth = $this->database->prepare("DELETE FROM sccpbuttonconfig WHERE name LIKE :openID AND buttontype = 'line'"); + $openId = "{$openId}%"; + $sth->bindParam(':openID', $openId); + $sth->execute(); + } + + $sth = $this->database->prepare("DELETE FROM sccpline WHERE name = ?"); + $sth->execute(array($id)); + return true; + } + + public function getDevice($id) { + // FreePBX required method + $sql = "SELECT name AS id, name AS name "; + foreach($this->data_fld as $key => $val) { + $sql .= ", {$key} AS {$val}"; + } + $sql .= " FROM sccpline WHERE name = '{$id}'"; + $sth = $this->database->prepare($sql); + $tech = array(); + try { + $sth->execute(array($id)); + $tech = $sth->fetch(\PDO::FETCH_ASSOC); + $tech['dial']="SCCP/{$id}"; + } catch(\Exception $e) {} + return $tech; + } + + public function getDefaultDeviceSettings($id, $displayname, &$flag) { + // FreePBX required method + $settings = array(); + dbug($this->line_defaults); + $settingsFields = array('mailbox', 'incominglimit', 'context', 'directed_pickup_context', 'callgroup', 'pickupgroup', 'namedcallgroup', + 'namedpickupgroup', 'adhocNumber', 'secondary_dialtone_digits', 'secondary_dialtone_tone', 'directed_pickup', 'pickup_modeanswer', + 'transfer', 'echocancel', 'dnd', 'silencesuppression', 'musicclass', 'pin', 'allow', 'disallow'); + foreach ($settingsFields as $key) { + $settings[$key] = array('value' => $this->line_defaults[$key], 'flag' => $flag++); + } + return array('dial' => 'SCCP', 'settings' => $settings); + } + + public function getDeviceDisplay($display, $deviceInfo, $currentComponent, $primarySection) { + global $amp_conf; + $activeCodecs = array(); + // load xml data to get help from same source as rest of module + $xml_vars = $amp_conf['AMPWEBROOT'] . '/admin/modules/sccp_manager/conf/sccpgeneral.xml.v433'; + $this->xml_data = simplexml_load_file($xml_vars); + // load metainfo from chan-sccp - help information if not in xml. Only load first time as static data. + if (empty($this->sccpHelpInfo)) { + $sysConfiguration = \FreePbx::sccp_manager()->aminterface->getSCCPConfigMetaData('general'); + foreach ($sysConfiguration['Options'] as $key => $valueArray) { + foreach ($valueArray['Description'] as $descKey => $descValue) { + $this->sccpHelpInfo[$valueArray['Name']] .= $descValue . '
    '; + } + } + unset($sysConfiguration); + } + + $section = _("SCCP Extension Details"); + $section_с = _("SCCP Codec Details"); + $gn_category = "sccp"; + //add sccp category + $currentComponent->addTabTranslation('sccp',_('SCCP')); + + // get site and system defaults + $systemCodecs = array_fill_keys(explode(';',$this->line_defaults['allow']),true); + $siteAudioCodecs = array_intersect_key($systemCodecs, $this->freepbx->Codecs->getAudio()); + $siteVideoCodecs = array_intersect_key($systemCodecs, $this->freepbx->Codecs->getVideo()); + + if (empty($deviceInfo['allow'])) { + // No allowed codecs so reset to site defaults + foreach ($systemCodecs as $lineCodec => $dummyVal) { + $activeCodecs[] = "devinfo_codec_{$lineCodec}"; + } + } else { + // have allowed codecs for this line + foreach (explode(';',$deviceInfo['allow']) as $lineCodec) { + $activeCodecs[] = "devinfo_codec_{$lineCodec}"; + } + } + + // Fill Audio codecs information + foreach ($siteAudioCodecs as $key => $value) { + $audioCodecButtons[] = array('value' => "devinfo_codec_{$key}", 'text' => $key); + } + // Fill Video codecs information + foreach ($siteVideoCodecs as $key => $value) { + $videoCodecButtons[] = array('value' => "devinfo_codec_{$key}", 'text' => $key); + } + + $tmparr['disallow'] = array('prompttext' => _('Disallowed Codecs'), + 'value' => $this->line_defaults['disallow'], + 'tt' => 'Codecs that are disallowed. Default and recommended value is all', + 'level' => 1, + 'section' => $section_с, + 'category' => $gn_category + ); + + $el = array( + "elemname" => "devinfo_sccp_codec", + "prompttext" => _('Line Audio Codec:'), + "helptext" => _("Line Audio Codec. Uncheck all Audio and Video codecs to return to site defaults"), + "currentvalue" => $activeCodecs, + "valarray" => $audioCodecButtons, + "class" => $section_с, + "disable" => 0 + ); + // Override defaults with $el + $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" => $activeCodecs, + "valarray" => $videoCodecButtons, + "class" => $section_с, + "disable" => 0 + ); + $currentComponent->addguielem($section_с, new \gui_checkset(array_merge($this->guiDefaults['gui_checkset'],$el)), $gn_category); + + $pageGroup = $this->xml_data->xpath('//page_group[@name="sccp_extension_config"]'); + $elements = $pageGroup[0]->children(); + + foreach ($elements as $child) { + if (empty($child->help)) { + $child->help = 'Help is not available.'; + $child->meta_help = '1'; + } + switch ($child['type']) { + case 'IE': + $elementID = (string)$child->input[0]->name; + if (!empty($metainfo[$elementID])) { + if ($child->meta_help == '1' || $child->help == 'Help!') { + $child->help = $metainfo[$shortId]; + } + } + $tmparr[$elementID] = array('prompttext' => _((string)$child->label), + 'value' => $this->line_defaults[$elementID], + 'tt' => (string)$child->help, + 'level' => 1, + 'section' => $section, + 'category' => $gn_category + ); + break; + case 'IS': + $select = array(); + foreach ($child->xpath('button') as $value) { + $select[] = array('value' => strtolower((string)$value[@value]), 'text' => (string)$value); + } + $hideButton = false; + if (($this->line_defaults['dndFeature'] == 'off') && ($child['id'] == 5)) { + $hideButton = true; + } + $tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label), + 'value' => $this->line_defaults[(string)$child->name], + 'tt' => (string)$child->help, + 'select' => $select, + 'level' => 1, + 'disable' => $hideButton, + 'hidden' => $hideButton, + 'type' => 'radio', + 'section' => $section, + 'category' => $gn_category + ); + unset($select); + break; + case 'SLD': + $select = array( + array( 'value' => '0x21', 'text' => 'Inside Dial Tone'), + array( 'value' => '0x22', 'text' => 'Outside Dial Tone'), + array( 'value' => '0x23', 'text' => 'Line Busy Tone'), + array( 'value' => '0x24', 'text' => 'Alerting Tone'), + array( 'value' => '0x25', 'text' => 'Reorder Tone'), + array( 'value' => '0x26', 'text' => 'Recorder Warning Tone'), + array( 'value' => '0x27', 'text' => 'Recorder Detected Tone'), + array( 'value' => '0x28', 'text' => 'Reverting Tone'), + array( 'value' => '0x29', 'text' => 'Receiver OffHook Tone'), + array( 'value' => '0x2A', 'text' => 'Partial Dial Tone'), + array( 'value' => '0x2B', 'text' => 'No Such Number Tone'), + array( 'value' => '0x2C', 'text' => 'Busy Verification Tone'), + array( 'value' => '0x2D', 'text' => 'Call Waiting Tone'), + array( 'value' => '0x2E', 'text' => 'Confirmation Tone'), + array( 'value' => '0x2F', 'text' => 'Camp On Indication Tone'), + array( 'value' => '0x30', 'text' => 'Recall Dial Tone'), + array( 'value' => '0x31', 'text' => 'Zip Zip'), + array( 'value' => '0x32', 'text' => 'Zip'), + array( 'value' => '0x33', 'text' => 'Beep Bonk'), + array( 'value' => '0x34', 'text' => 'Music Tone'), + array( 'value' => '0x35', 'text' => 'Hold Tone'), + array( 'value' => '0x36', 'text' => 'Test Tone'), + array( 'value' => '0x37', 'text' => 'DT Monitor Warning Tone'), + array( 'value' => '0x40', 'text' => 'Add Call Waiting'), + array( 'value' => '0x41', 'text' => 'Priority Call Wait'), + array( 'value' => '0x42', 'text' => 'Recall Dial'), + array( 'value' => '0x43', 'text' => 'Barg In'), + array( 'value' => '0x44', 'text' => 'Distinct Alert'), + array( 'value' => '0x45', 'text' => 'Priority Alert'), + array( 'value' => '0x46', 'text' => 'Reminder Ring'), + array( 'value' => '0x47', 'text' => 'Precedence RingBank'), + array( 'value' => '0x48', 'text' => 'Pre-EmptionTone'), + array( 'value' => '0x67', 'text' => '2105 HZ'), + array( 'value' => '0x68', 'text' => '2600 HZ'), + array( 'value' => '0x69', 'text' => '440 HZ'), + array( 'value' => '0x6A', 'text' => '300 HZ'), + array( 'value' => '0x77', 'text' => 'MLPP Pala'), + array( 'value' => '0x78', 'text' => 'MLPP Ica'), + array( 'value' => '0x79', 'text' => 'MLPP Vca'), + array( 'value' => '0x7A', 'text' => 'MLPP Bpa'), + array( 'value' => '0x7B', 'text' => 'MLPP Bnea'), + array( 'value' => '0x7C', 'text' => 'MLPP Upa') + ); + + + $tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label), + 'value' => $this->line_defaults[(string)$child->name], + 'tt' => (string)$child->help, + 'select' => $select, + 'level' => 1, + 'type' => 'select', + 'section' => $section, + 'category' => $gn_category + ); + unset($select); + break; + case 'SLG': + $elementID = (string)$child->name; + $named_group = \FreePbx::sccp_manager()->dbinterface->getNamedGroup($elementID); + if (!empty($named_group[$elementID])) { + foreach ($named_group[$elementID] as $val) { + $select[] = array('value' => $val, 'text' => $val); + } + } + // Disable and hide list elements if there are no valid values + $tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label), + 'value' => $this->line_defaults[(string)$child->name], + 'tt' => (string)$child->help, + 'select' => $select, + 'level' => 1, + 'disable' => empty($named_group[$elementID][0]), + 'hidden' => empty($named_group[$elementID][0]), + 'section' => $section, + 'category' => $gn_category + ); + unset($select); + break; + case 'SLM': + if (function_exists('music_list')){ + foreach (music_list() as $value) { + $select[] = array('value' => $value, 'text' => _($value)); + } + } else { + $select[] = array('value' => 'default', 'text' => _('default')); + } + $tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label), + 'value' => $this->line_defaults[(string)$child->name], + 'tt' => (string)$child->help, + 'select' => $select, + 'level' => 1, + 'type' => 'select', + 'section' => $section, + 'category' => $gn_category + ); + unset($select); + break; + } + } + + $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); + + return $tmparr; + } + + public function reload_line($id) { + global $astman; + // TODO: Change to use amInterfaceClasses + $result = $astman->Command('sccp reload line ' . $id); + return $result; + } + + + + public function getDeviceHeaders() { + return array( + 'secret' => array('identifier' => _('Secret'), 'description' => sprintf(_('Secret [Enter "%s" to regenerate]'),"REGEN")), + ); + } +} diff --git a/sccpManClasses/amInterfaceClasses/Event.class.php b/sccpManClasses/amInterfaceClasses/Event.class.php index a08c50f..d222189 100644 --- a/sccpManClasses/amInterfaceClasses/Event.class.php +++ b/sccpManClasses/amInterfaceClasses/Event.class.php @@ -100,8 +100,9 @@ class SCCPShowDevice_Event extends Event // This is a list of tables public function getCapabilities() { + // TODO unused method - to be deleted? $ret = array(); - $codecs = explode(", ", substr($this->getKey('Capabilities'), 1, -1)); + $codecs = explode(';', substr($this->getKey('Capabilities'), 1, -1)); foreach ($codecs as $codec) { $codec_parts = explode(" ", $codec); $ret[] = array("name" => $codec_parts[0], "value" => substr($codec_parts[1], 1, -1)); @@ -111,8 +112,9 @@ class SCCPShowDevice_Event extends Event public function getCodecsPreference() { + // TODO unused method - to be deleted? $ret = array(); - $codecs = explode(", ", substr($this->getKey('CodecsPreference'), 1, -1)); + $codecs = explode(';', substr($this->getKey('CodecsPreference'), 1, -1)); foreach ($codecs as $codec) { $codec_parts = explode(" ", $codec); $ret[] = array("name" => $codec_parts[0], "value" => substr($codec_parts[1], 1, -1)); diff --git a/sccpManClasses/aminterface.class.php b/sccpManClasses/aminterface.class.php index dac5f47..341e359 100644 --- a/sccpManClasses/aminterface.class.php +++ b/sccpManClasses/aminterface.class.php @@ -392,7 +392,7 @@ class aminterface $result = array(); if ($this->_connect_state) { $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPShowDevicesAction(); - $result = $this->send($_action)->getResult(); + $result = (array)$this->send($_action)->getResult(); } return $result; } @@ -431,14 +431,19 @@ class aminterface } return $result; } + function getSCCPConfigMetaData($segment = '') { + if ($this->_connect_state) { + $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPConfigMetaDataAction($segment); + $metadata = $this->send($_action)->getResult(); + } + return $metadata; + } + function getSCCPVersion() { //Initialise result array - $result = array( 'RevisionHash' => '', 'vCode' => 0, 'RevisionNum' => 0, 'futures' => '', 'Version' => 0); - if ($this->_connect_state) { - $_action = new \FreePBX\modules\Sccp_manager\aminterface\SCCPConfigMetaDataAction(); - $metadata = $this->send($_action)->getResult(); - } + $result = array( 'RevisionHash' => '', 'vCode' => 0, 'RevisionNum' => 0, 'buildInfo' => '', 'Version' => 0); + $metadata = $this->getSCCPConfigMetaData(); if (isset($metadata['Version'])) { $result['Version'] = $metadata['Version']; @@ -472,7 +477,7 @@ class aminterface $result['RevisionNum'] = $metadata["RevisionNum"]; } if (isset($metadata['ConfigureEnabled'])) { - $result['futures'] = implode(';', $metadata['ConfigureEnabled']); + $result['buildInfo'] = $metadata['ConfigureEnabled']; } } return $result; diff --git a/sccpManClasses/dbinterface.class.php b/sccpManClasses/dbinterface.class.php index e58faba..4e3f45d 100644 --- a/sccpManClasses/dbinterface.class.php +++ b/sccpManClasses/dbinterface.class.php @@ -17,11 +17,12 @@ class dbinterface public function __construct($parent_class = null) { $this->paren_class = $parent_class; + $this->db = \FreePBX::Database(); } public function info() { - $Ver = '13.0.2'; // This should be updated + $Ver = '13.0.10'; // This should be updated return array('Version' => $Ver, 'about' => 'Data access interface ver: ' . $Ver); } @@ -32,7 +33,7 @@ class dbinterface public function get_db_SccpTableByID($dataid, $data = array(), $indexField = '') { $result = array(); - $raw = $this->HWextension_db_SccpTableData($dataid, $data); + $raw = $this->getSccpDeviceTableData($dataid, $data); if (empty($raw) || empty($indexField)) { return $raw; } @@ -43,27 +44,46 @@ class dbinterface return $result; } - public function HWextension_db_SccpTableData($dataid, $data = array()) + public function getSccpDeviceTableData($dataid, $data = array()) { - // $stmt is a single row fetch, $stmts is a fetchAll. - $dbh = \FreePBX::Database(); + // $stmt is a single row fetch, $stmts is a fetchAll while stmtU is fetchAll UNIQUE $stmt = ''; $stmts = ''; + $stmtU = ''; if ($dataid == '') { return false; } switch ($dataid) { + case 'extGrid': + // only called by getExtensionGrid from hardware.extension.php view + $stmts = $this->db->prepare("SELECT sccpline.name, sccpline.label, sccpbuttonconfig.ref AS mac, '-|-' AS line_status + FROM sccpline LEFT JOIN sccpbuttonconfig + ON sccpline.name = TRIM(TRAILING '!silent' FROM sccpbuttonconfig.name) ORDER BY sccpline.name"); + break; case 'SccpExtension': if (empty($data['name'])) { - $stmts = $dbh->prepare('SELECT * FROM sccpline ORDER BY name'); + $stmtU = $this->db->prepare('SELECT name, sccpline.* FROM sccpline ORDER BY name'); } else { - $stmts = $dbh->prepare('SELECT * FROM sccpline WHERE name = :name'); + $stmts = $this->db->prepare('SELECT * FROM sccpline WHERE name = :name'); $stmts->bindParam(':name', $data['name'],\PDO::PARAM_STR); } break; + case 'phoneGrid': + switch ($data['type']) { + case "cisco-sip": + $stmts = $this->db->prepare("SELECT name, type, button, addon, description, 'not connected' AS status, '- -' AS address, 'N' AS new_hw + FROM sccpdeviceconfig WHERE type LIKE '%-sip' ORDER BY name"); + break; + case "sccp": // Fall through to default intentionally + default: + $stmts = $this->db->prepare("SELECT name, type, button, addon, description, 'not connected' AS status, '- -' AS address, 'N' AS new_hw + FROM sccpdeviceconfig WHERE type not LIKE '%-sip' ORDER BY name"); + break; + } + break; case 'SccpDevice': if (empty($data['fields'])) { - $fld = 'name, name as mac, type, button, addon, _description as description'; + $fld = 'name, name as mac, type, button, addon, description'; } else { switch ($data['fields']) { case "all": @@ -78,48 +98,49 @@ class dbinterface } } if (!empty($data['name'])) { //either filter by name or by type - $stmt = $dbh->prepare('SELECT ' . $fld . ' FROM sccpdeviceconfig WHERE name = :name ORDER BY name'); + $stmt = $this->db->prepare('SELECT ' . $fld . ' FROM sccpdeviceconfig WHERE name = :name ORDER BY name'); $stmt->bindParam(':name', $data['name'],\PDO::PARAM_STR); } elseif (!empty($data['type'])) { switch ($data['type']) { case "cisco-sip": - $stmts = $dbh->prepare("SELECT {$fld} FROM sccpdeviceconfig WHERE TYPE LIKE '%-sip' ORDER BY name"); + $stmts = $this->db->prepare("SELECT {$fld} FROM sccpdeviceconfig WHERE TYPE LIKE '%-sip' ORDER BY name"); break; case "cisco": // Fall through to default intentionally default: - $stmts = $dbh->prepare("SELECT {$fld} FROM sccpdeviceconfig WHERE TYPE not LIKE '%-sip' ORDER BY name"); + $stmts = $this->db->prepare("SELECT {$fld} FROM sccpdeviceconfig WHERE TYPE not LIKE '%-sip' ORDER BY name"); break; } } else { //no filter and no name provided - return all - $stmts = $dbh->prepare("SELECT {$fld} FROM sccpdeviceconfig ORDER BY name"); + $stmts = $this->db->prepare("SELECT {$fld} FROM sccpdeviceconfig ORDER BY name"); } break; - case 'HWSipDevice': - $raw_settings = $this->getDb_model_info($get = "sipphones", $format_list = "model"); - break; - case 'HWDevice': - $raw_settings = $this->getDb_model_info($get = "ciscophones", $format_list = "model"); - break; - case 'HWextension': - $raw_settings = $this->getDb_model_info($get = "extension", $format_list = "model"); - break; case 'get_columns_sccpdevice': - $stmts = $dbh->prepare('DESCRIBE sccpdevice'); + $stmtU = $this->db->prepare('DESCRIBE sccpdevice'); break; case 'get_columns_sccpuser': - $stmts = $dbh->prepare('DESCRIBE sccpuser'); + $stmts = $this->db->prepare('DESCRIBE sccpuser'); + break; + case 'get_columns_sccpline': + $stmtU = $this->db->prepare('DESCRIBE sccpline'); break; case 'get_sccpdevice_byid': - $stmt = $dbh->prepare('SELECT t1.*, types.dns, types.buttons, types.loadimage, types.nametemplate as nametemplate, + $stmt = $this->db->prepare('SELECT t1.*, types.dns, types.buttons, types.loadimage, types.nametemplate as nametemplate, addon.buttons as addon_buttons FROM sccpdevice AS t1 LEFT JOIN sccpdevmodel as types ON t1.type=types.model LEFT JOIN sccpdevmodel as addon ON t1.addon=addon.model WHERE name = :name'); $stmt->bindParam(':name', $data['id'],\PDO::PARAM_STR); break; case 'get_sccpuser': - $stmt = $dbh->prepare('SELECT * FROM sccpuser WHERE name = :name'); + $stmt = $this->db->prepare('SELECT * FROM sccpuser WHERE name = :name'); $stmt->bindParam(':name', $data['id'],\PDO::PARAM_STR); break; + case 'getAssignedExtensions': + // all extensions that are designed as default lines + $stmtU = $this->db->prepare("SELECT DISTINCT name, name FROM sccpbuttonconfig WHERE buttontype = 'line' AND instance =1"); + break; + case 'getDefaultLine': + $stmt = $this->db->prepare("SELECT name FROM sccpbuttonconfig WHERE ref = '{$data['id']}' and instance =1 and buttontype = 'line'"); + break; case 'get_sccpdevice_buttons': $sql = ''; if (!empty($data['buttontype'])) { @@ -129,7 +150,7 @@ class dbinterface $sql .= (empty($sql)) ? 'ref = :ref' : ' and ref = :ref'; } if (!empty($sql)) { - $stmts = $dbh->prepare("SELECT * FROM sccpbuttonconfig WHERE {$sql} ORDER BY instance"); + $stmts = $this->db->prepare("SELECT * FROM sccpbuttonconfig WHERE {$sql} ORDER BY instance"); // Now bind labels - only bind label if it exists or bind will create exception. // can only bind once have prepared, so need to test again. if (!empty($data['buttontype'])) { @@ -142,6 +163,8 @@ class dbinterface $raw_settings = array(); } break; + // No default case so will give exception of $raw_settings undefined if the + // dataid is not in the switch. } if (!empty($stmt)) { $stmt->execute(); @@ -149,25 +172,25 @@ class dbinterface } elseif (!empty($stmts)) { $stmts->execute(); $raw_settings = $stmts->fetchAll(\PDO::FETCH_ASSOC); + } elseif (!empty($stmtU)) { + //returns an assoc array indexed on first field + $stmtU->execute(); + $raw_settings = $stmtU->fetchAll(\PDO::FETCH_ASSOC|\PDO::FETCH_UNIQUE); } return $raw_settings; } public function get_db_SccpSetting() { - $dbh = \FreePBX::Database(); - $stmt = $dbh->prepare('SELECT keyword, data, type, seq FROM sccpsettings ORDER BY type, seq'); + $stmt = $this->db->prepare('SELECT keyword, sccpsettings.* FROM sccpsettings ORDER BY type, seq'); $stmt->execute(); - foreach ($stmt->fetchAll() as $var) { - $mysccpvalues[$var['keyword']] = array('keyword' => $var['keyword'], 'data' => $var['data'], 'seq' => $var['seq'], 'type' => $var['type']); - } - return $mysccpvalues; + $settingsFromDb = $stmt->fetchAll(\PDO::FETCH_ASSOC|\PDO::FETCH_UNIQUE); + return $settingsFromDb; } public function get_db_sysvalues() { - $dbh = \FreePBX::Database(); - $stmt = $dbh->prepare('SHOW VARIABLES LIKE \'%group_concat%\''); + $stmt = $this->db->prepare('SHOW VARIABLES LIKE \'%group_concat%\''); $stmt->execute(); return $stmt->fetch(\PDO::FETCH_ASSOC); } @@ -178,10 +201,9 @@ class dbinterface function getDb_model_info($get = 'all', $format_list = 'all', $filter = array()) { - $dbh = \FreePBX::Database(); $sel_inf = '*, 0 as validate'; if ($format_list === 'model') { - $sel_inf = 'model, vendor, dns, buttons, 0 as validate'; + $sel_inf = "model, vendor, dns, buttons, '-;-' as validate"; } switch ($get) { case 'byciscoid': @@ -190,10 +212,10 @@ class dbinterface if (!strpos($filter['model'], 'loadInformation')) { $filter['model'] = 'loadInformation' . $filter['model']; } - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (loadinformationid = :model ) ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (loadinformationid = :model ) ORDER BY model"); $stmt->bindParam(':model', $filter['model'], \PDO::PARAM_STR); } else { - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel ORDER BY model"); } break; } @@ -201,32 +223,32 @@ class dbinterface case 'byid': if (!empty($filter)) { if (!empty($filter['model'])) { - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE model = :model ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE model = :model ORDER BY model"); $stmt->bindParam(':model', $filter['model'],\PDO::PARAM_STR); } else { - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel ORDER BY model"); } break; } break; case 'extension': - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns = 0) and (enabled = 1) ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns = 0) and (enabled = 1) ORDER BY model"); break; case 'enabled': //$stmt = $db->prepare('SELECT ' . {$sel_inf} . ' FROM sccpdevmodel WHERE enabled = 1 ORDER BY model'); //previously this fell through to phones. //break; // above includes expansion modules but was not original behaviour so commented out. Falls through to phones. case 'phones': - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns != 0) and (enabled = 1) ORDER BY model"); break; case 'ciscophones': - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) AND vendor NOT LIKE '%-sip' ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) AND vendor NOT LIKE '%-sip' ORDER BY model"); break; case 'sipphones': - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) AND vendor LIKE '%-sip' ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel WHERE (dns > 0) and (enabled = 1) AND vendor LIKE '%-sip' ORDER BY model"); break; case 'all': // Fall through to default default: - $stmt = $dbh->prepare("SELECT {$sel_inf} FROM sccpdevmodel ORDER BY model"); + $stmt = $this->db->prepare("SELECT {$sel_inf} FROM sccpdevmodel ORDER BY model"); break; } $stmt->execute(); @@ -237,26 +259,24 @@ class dbinterface { // mode clear - Empty table before update // mode update - update / replace record - $dbh = \FreePBX::Database(); $result = false; switch ($table_name) { case 'sccpsettings': if ($mode == 'replace') { // Change mode name to be more transparent - $dbh->prepare('TRUNCATE sccpsettings')->execute(); - $stmt = $dbh->prepare('INSERT INTO sccpsettings (keyword, data, seq, type) VALUES (:keyword,:data,:seq,:type)'); + $this->db->prepare('TRUNCATE sccpsettings')->execute(); + $stmt = $this->db->prepare('INSERT INTO sccpsettings (keyword, data, seq, type, systemdefault) VALUES (:keyword,:data,:seq,:type,:systemdefault)'); } else { - $stmt = $dbh->prepare('REPLACE INTO sccpsettings (keyword, data, seq, type) VALUES (:keyword,:data,:seq,:type)'); + $stmt = $this->db->prepare('REPLACE INTO sccpsettings (keyword, data, seq, type, systemdefault) VALUES (:keyword,:data,:seq,:type,:systemdefault)'); } foreach ($save_value as $key => $dataArr) { - if (!empty($dataArr) && isset($dataArr['data'])) { - if (empty($dataArr['data'])) { + if (empty($dataArr)) { continue; - } } $stmt->bindParam(':keyword',$dataArr['keyword'],\PDO::PARAM_STR); $stmt->bindParam(':data',$dataArr['data'],\PDO::PARAM_STR); $stmt->bindParam(':seq',$dataArr['seq'],\PDO::PARAM_INT); $stmt->bindParam(':type',$dataArr['type'],\PDO::PARAM_INT); + $stmt->bindParam(':systemdefault',$dataArr['systemdefault'],\PDO::PARAM_STR); $result = $stmt->execute(); } break; @@ -281,13 +301,13 @@ class dbinterface if (!empty($sql_var)) { switch ($mode) { case 'delete': - $stmt = $dbh->prepare("DELETE FROM {$table_name} WHERE {$sql_key}"); + $stmt = $this->db->prepare("DELETE FROM {$table_name} WHERE {$sql_key}"); break; case 'update': - $stmt = $dbh->prepare("UPDATE {$table_name} SET {$sql_var} WHERE {$sql_key}"); + $stmt = $this->db->prepare("UPDATE {$table_name} SET {$sql_var} WHERE {$sql_key}"); break; case 'replace': - $stmt = $dbh->prepare("REPLACE INTO {$table_name} SET {$sql_var}"); + $stmt = $this->db->prepare("REPLACE INTO {$table_name} SET {$sql_var}"); break; // no default mode - must be explicit. } @@ -298,35 +318,57 @@ class dbinterface switch ($mode) { case 'delete': $sql = 'DELETE FROM sccpbuttonconfig WHERE ref = :hwid'; - $stmt = $dbh->prepare($sql); + $stmt = $this->db->prepare($sql); $stmt->bindParam(':hwid', $hwid,\PDO::PARAM_STR); $result = $stmt->execute(); break; case 'replace': foreach ($save_value as $button_array) { - $stmt = $dbh->prepare('UPDATE sccpbuttonconfig SET name =:name WHERE ref = :ref AND reftype =:reftype AND instance = :instance AND buttontype = :buttontype'); + $stmt = $this->db->prepare('UPDATE sccpbuttonconfig SET name =:name WHERE ref = :ref AND reftype =:reftype AND instance = :instance AND buttontype = :buttontype AND options = :options'); $stmt->bindParam(':ref', $button_array['ref'],\PDO::PARAM_STR); $stmt->bindParam(':reftype', $button_array['reftype'],\PDO::PARAM_STR); $stmt->bindParam(':instance', $button_array['instance'],\PDO::PARAM_INT); - $stmt->bindParam(':buttontype', $button_array['type'],\PDO::PARAM_STR); + $stmt->bindParam(':buttontype', $button_array['buttontype'],\PDO::PARAM_STR); $stmt->bindParam(':name', $button_array['name'],\PDO::PARAM_STR); + $stmt->bindParam(':options', $button_array['options'],\PDO::PARAM_STR); $result= $stmt->execute(); } break; case 'add': foreach ($save_value as $button_array) { - $stmt = $dbh->prepare('INSERT INTO sccpbuttonconfig (ref, reftype, instance, buttontype, name, options) VALUES (:ref, :reftype, :instance, :buttontype, :name, :options)'); + $stmt = $this->db->prepare("INSERT INTO sccpbuttonconfig SET ref = :ref, reftype = :reftype, instance = :instance, buttontype = :buttontype, name = :name, options = :options + ON DUPLICATE KEY UPDATE ref = :refU, reftype = :reftypeU, instance = :instanceU, buttontype = :buttontypeU, name = :nameU, options = :optionsU"); $stmt->bindParam(':ref', $button_array['ref'],\PDO::PARAM_STR); $stmt->bindParam(':reftype', $button_array['reftype'],\PDO::PARAM_STR); $stmt->bindParam(':instance', $button_array['instance'],\PDO::PARAM_INT); - $stmt->bindParam(':buttontype', $button_array['type'],\PDO::PARAM_STR); + $stmt->bindParam(':buttontype', $button_array['buttontype'],\PDO::PARAM_STR); + $stmt->bindParam(':name', $button_array['name'],\PDO::PARAM_STR); + $stmt->bindParam(':options', $button_array['options'],\PDO::PARAM_STR); + $stmt->bindParam(':refU', $button_array['ref'],\PDO::PARAM_STR); + $stmt->bindParam(':reftypeU', $button_array['reftype'],\PDO::PARAM_STR); + $stmt->bindParam(':instanceU', $button_array['instance'],\PDO::PARAM_INT); + $stmt->bindParam(':buttontypeU', $button_array['buttontype'],\PDO::PARAM_STR); + $stmt->bindParam(':nameU', $button_array['name'],\PDO::PARAM_STR); + $stmt->bindParam(':optionsU', $button_array['options'],\PDO::PARAM_STR); + $result = $stmt->execute(); + } + break; + /* + case 'add': + foreach ($save_value as $button_array) { + $stmt = $this->db->prepare('INSERT INTO sccpbuttonconfig (ref, reftype, instance, buttontype, name, options) VALUES (:ref, :reftype, :instance, :buttontype, :name, :options)'); + $stmt->bindParam(':ref', $button_array['ref'],\PDO::PARAM_STR); + $stmt->bindParam(':reftype', $button_array['reftype'],\PDO::PARAM_STR); + $stmt->bindParam(':instance', $button_array['instance'],\PDO::PARAM_INT); + $stmt->bindParam(':buttontype', $button_array['buttontype'],\PDO::PARAM_STR); $stmt->bindParam(':name', $button_array['name'],\PDO::PARAM_STR); $stmt->bindParam(':options', $button_array['options'],\PDO::PARAM_STR); $result = $stmt->execute(); } break; + */ case 'clear'; - // Clear is equivalent of delete + insert. + // Clear is equivalent of delete + insert. Mode is used in order to activate trigger. $this->write('sccpbuttons', '', $mode = 'delete','', $hwid); $this->write('sccpbuttons', $save_value, $mode = 'add','', $hwid); break; @@ -347,19 +389,22 @@ class dbinterface return $filename; } + public function updateTableDefaults($table, $field, $value) { + $stmt = $this->db->prepare("ALTER TABLE {$table} ALTER COLUMN {$field} SET DEFAULT '{$value}'"); + $stmt->execute(); + } + /* * Check Table structure */ public function validate() { - $dbh = \FreePBX::Database(); $result = 0; $check_fields = [ - '430' => ['_hwlang' => "varchar(12)"], '431' => ['private'=> "enum('on','off')"], '433' => ['directed_pickup'=>''] ]; - $stmt = $dbh->prepare('DESCRIBE sccpdevice'); + $stmt = $this->db->prepare('DESCRIBE sccpdevice'); $stmt->execute(); foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $value) { $id_result[$value['Field']] = $value['Type']; @@ -379,4 +424,19 @@ class dbinterface return $result; } + + public function getNamedGroup($callGroup) { + $sql = "SELECT {$callGroup} FROM sccpline GROUP BY {$callGroup}"; + $sth = $this->db->prepare($sql); + $result = array(); + $tech = array(); + try { + $sth->execute(); + $result = $sth->fetchAll(); + foreach($result as $val) { + $tech[$callGroup][] = $val[0]; + } + } catch(\Exception $e) {} + return $tech; + } } diff --git a/sccpManClasses/extconfigs.class.php b/sccpManClasses/extconfigs.class.php index c969263..d8dd747 100644 --- a/sccpManClasses/extconfigs.class.php +++ b/sccpManClasses/extconfigs.class.php @@ -1,32 +1,32 @@ paren_class = $parent_class; } public function info() { - $Ver = '13.1.1'; + $Ver = '13.2.0'; return array('Version' => $Ver, - 'about' => 'Default Setings and Enums ver: ' . $Ver); + 'about' => 'Default Settings and Enums ver: ' . $Ver); } - public function getextConfig($id = '', $index = '') { + public function getExtConfig($id = '', $index = '') { + $result = array(); switch ($id) { case 'keyset': $result = $this->keysetdefault; break; case 'sccp_lang': - $result = $this->cisco_language; + if (empty($index)) { + return $this->cisco_language; // return language array + } elseif (!empty($this->cisco_language[$index])) { + return $this->cisco_language[$index]; // return the matched value + } break; case 'sccpDefaults': $result = $this->sccpDefaults; @@ -96,20 +96,40 @@ class extconfigs } private $sccpDefaults = array( - "servername" => 'VPBXSCCP', - "bindaddr" => '0.0.0.0', "port" => '2000', # chan_sccp also supports ipv6 - "deny" => '0.0.0.0/0.0.0.0', - "permit" => '0.0.0.0/0.0.0.0', # !TODO!: please change this to 'internal' which would mean: - # permit:127.0.0.0/255.0.0.0,permit:10.0.0.0/255.0.0.0,permit:172.0.0.0/255.224.0.0,permit:192.168.0.0/255.255.0.0" - "dateformat" => 'D.M.Y', - "disallow" => 'all', "allow" => 'alaw;ulaw', - "hotline_enabled" => 'off', - "hotline_context" => 'default', # !TODO!: Should this not be from-internal on FreePBX ? - "hotline_extension" => '*60', # !TODO!: Is this a good default extension to dial for hotline ? - "hotline_label" => 'hotline', - "devicetable" => 'sccpdevice', - "linetable" => 'sccpline', - "tftp_path" => '/tftpboot' + 'servername' => 'VPBXSCCP', + 'bindaddr' => '0.0.0.0', "port" => '2000', # chan_sccp also supports ipv6 + 'deny' => '0.0.0.0/0.0.0.0', + 'permit' => '0.0.0.0/0.0.0.0', # !TODO!: please change this to 'internal' which would mean: + 'dateformat' => 'D.M.Y', + 'disallow' => 'all', "allow" => 'alaw;ulaw', + 'hotline_enabled' => 'off', + 'hotline_context' => 'default', # !TODO!: Should this not be from-internal on FreePBX ? + 'hotline_extension' => '*60', # !TODO!: Is this a good default extension to dial for hotline ? + 'hotline_label' => 'hotline', + 'devicetable' => 'sccpdevice', + 'linetable' => 'sccpline', + 'displayconfig' => 'sccpgeneral', + '_dev_sshPassword' => 'cisco', + '_dev_sshUserId' => 'cisco', + 'dev_deviceProtocol' => 'SCCP', + 'dev_idleTimeout' => '60', + 'ntp_config_enabled' => 'off', + 'ntp_server' => 'pool.ntp.org', + 'ntp_server_mode' => 'unicast', + 'devlang' => 'English_United_States', + 'dev_authenticationURL' => '', + 'dev_informationURL' => '', + 'dev_messagesURL' => '', + 'dev_servicesURL' => '', + 'dev_directoryURL' => '', + 'dev_idleURL' => '', + 'dev_secureauthenticationURL' => '', + 'dev_secureinformationURL' => '', + 'dev_securemessagesURL' => '', + 'dev_secureservicesURL' => '', + 'dev_securedirectoryURL' => '', + 'dev_secureidleURL' => '', + 'dev_proxyServerURL' => '' ); private $keysetdefault = array('onhook' => 'redial,newcall,cfwdall,cfwdbusy,cfwdnoanswer,pickup,gpickup,dnd,private', 'connected' => 'hold,endcall,park,vidmode,select,cfwdall,cfwdbusy,idivert,monitor', @@ -216,85 +236,95 @@ class extconfigs 'New Zealand' => array('offset' => '720', 'daylight' => true) ); - public function validate_init_path($confDir = '', $db_vars, $sccp_driver_replace = '') - { -// global $db; -// global $amp_conf; -// *** Setings for Provision Sccp - $adv_config = array('tftproot' => '', 'firmware' => 'firmware', 'settings' => 'settings', - 'locales' => 'locales', 'languages' => 'languages', 'templates' => 'templates', 'dialplan' => 'dialplan', 'softkey' => 'softkey'); -// 'pro' /tftpboot - root dir -// /tftpboot/locales/locales/%Languge_name% -// /tftpboot/settings/XMLdefault.cnf.xml -// /tftpboot/settings/SEP[MAC].cnf.xml -// /tftpboot/firmware/79xx/SCCPxxxx.loads - $adv_tree['pro'] = array('templates' => 'tftproot', 'settings' => 'tftproot', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'locales', 'dialplan' => 'tftproot', 'softkey' => 'tftproot'); + public function updateTftpStructure($settingsFromDb) { + global $amp_conf; + $adv_config = array('tftproot' => $settingsFromDb['tftp_path']['data'], + 'firmware' => 'firmware', + 'settings' => 'settings', + 'locales' => 'locales', + 'languages' => 'languages', + 'templates' => 'templates', + 'dialplan' => 'dialplan', + 'softkey' => 'softkey', + 'ringtones' => 'ringtones', + 'wallpapers' => 'wallpapers', + 'countries' => 'countries' + ); + $adv_tree = array('pro' => array('templates' => 'tftproot', + 'firmware' => 'tftproot', + 'settings' => 'tftproot', + 'locales' => 'tftproot', + 'languages' => 'locales', + 'templates' => 'tftproot', + 'dialplan' => 'tftproot', + 'softkey' => 'tftproot', + 'ringtones' => 'tftproot', + 'wallpapers' => 'tftproot', + 'countries' => 'locales' + ), + 'def' => array('templates' => 'tftproot', + 'firmware' => '', + 'settings' => '', + 'locales' => '', + 'languages' => 'tftproot', + 'dialplan' => '', + 'softkey' => '', + 'ringtones' => '', + 'wallpapers' => '', + 'countries' => '' + ) + ); + $base_tree = array('tftp_templates_path' => 'templates', + 'tftp_firmware_path' => 'firmware', + 'tftp_store_path' => 'settings', + 'tftp_lang_path' => 'languages', + 'tftp_dialplan_path' => 'dialplan', + 'tftp_softkey_path' => 'softkey', + 'tftp_ringtones_path' => 'ringtones', + 'tftp_wallpapers_path' => 'wallpapers', + 'tftp_countries_path' => 'countries' + ); + $baseConfig = array(); -// 'def' /tftpboot - root dir -// /tftpboot/languages/%Languge_name% -// /tftpboot/XMLdefault.cnf.xml -// /tftpboot/SEP[MAC].cnf.xml -// /tftpboot/SCCPxxxx.loads - $adv_tree['def'] = array('templates' => 'tftproot', 'settings' => '', 'locales' => '', 'firmware' => '', 'languages' => 'tftproot', 'dialplan' => '', 'softkey' => ''); -// $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => ''); -// $adv_tree['def'] = Array('templates' => 'tftproot', 'settings' => '', 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'tftproot'); -//* **************------ **** - $base_tree = array('tftp_templates' => 'templates', 'tftp_path_store' => 'settings', 'tftp_lang_path' => 'languages', 'tftp_firmware_path' => 'firmware', 'tftp_dialplan' => 'dialplan', 'tftp_softkey' => 'softkey'); - - if (empty($confDir)) { - return array('error' => 'empty СonfDir'); - } - - $base_config = array('asterisk' => $confDir, 'sccp_conf' => $confDir . '/sccp.conf', 'tftp_path' => ''); - -// Test Base dir (/tftproot) - if (!empty($db_vars["tftp_path"])) { - if (file_exists($db_vars["tftp_path"]["data"])) { - $base_config["tftp_path"] = $db_vars["tftp_path"]["data"]; + if (empty($settingsFromDb['tftp_rewrite_path']['data'])) { + $settingsFromDb['tftp_rewrite_path']['data'] = $settingsFromDb['tftp_path']['data']; + } else { + // Have a setting in sccpsettings. It should start with $tftp_path + // If not we will replace it with $tftp_path. Avoids issues with legacy values + if (!strpos($settingsFromDb['tftp_rewrite_path']["data"],$settingsFromDb['tftp_path']['data'])) { + $settingsFromDb['tftp_rewrite_path']['data'] = $settingsFromDb['tftp_path']['data']; } } - if (empty($base_config["tftp_path"])) { - if (file_exists($this->getextConfig('sccpDefaults', "tftp_path"))) { - $base_config["tftp_path"] = $this->getextConfig('sccpDefaults', "tftp_path"); - } - } - if (empty($base_config["tftp_path"])) { - if (!empty($this->paren_class)) { - $this->paren_class->class_error['tftp_path'] = 'Tftp path not exist or not defined'; - } - return array('error' => 'empty tftp_path'); - } - if (!is_writeable($base_config["tftp_path"])) { - if (!empty($this->paren_class)) { - $this->paren_class->class_error['tftp_path'] = 'No write permission on tftp DIR'; - } - return array('error' => 'No write permission on tftp DIR'); - } -// END Test Base dir (/tftproot) - - if (!empty($db_vars['tftp_rewrite_path'])) { - $adv_ini = $db_vars['tftp_rewrite_path']["data"]; - } - + $adv_ini = "{$settingsFromDb['tftp_rewrite_path']["data"]}/index.cnf"; $adv_tree_mode = 'def'; - if (empty($db_vars["tftp_rewrite"])) { - $db_vars["tftp_rewrite"]["data"] = "off"; - } - $adv_config['tftproot'] = $base_config["tftp_path"]; - if ($db_vars["tftp_rewrite"]["data"] == 'pro') { - $adv_tree_mode = 'pro'; - if (!empty($adv_ini)) { // something found in external conflicts - $adv_ini .= '/index.cnf'; - if (file_exists($adv_ini)) { + switch ($settingsFromDb['tftp_rewrite']['data']) { + case 'pro': + $adv_tree_mode = 'pro'; + if (!empty($adv_ini) && file_exists($adv_ini)) { $adv_ini_array = parse_ini_file($adv_ini); $adv_config = array_merge($adv_config, $adv_ini_array); } - } - } - if ($db_vars["tftp_rewrite"]["data"] == 'on') { - $adv_tree_mode = 'def'; + // rewrite adv_ini to reflect the new $adv_config + if (file_exists($adv_ini)){ + rename($adv_ini, "{$adv_ini}.old"); + } + $indexFile = fopen($adv_ini,'w'); + fwrite($indexFile, "[main]\n"); + foreach ($adv_config as $advKey => $advVal) { + fwrite($indexFile, "{$advKey} = {$advVal}\n"); + } + fclose($indexFile); + $settingsFromDb['tftp_rewrite']['data'] = 'pro'; + break; + case 'on': + case 'internal': + case 'off': + default: + // not defined so set here to off + $settingsFromDb['tftp_rewrite']['data'] = 'off'; } + foreach ($adv_tree[$adv_tree_mode] as $key => $value) { if (!empty($adv_config[$key])) { if (!empty($value)) { @@ -306,66 +336,35 @@ class extconfigs } } } + foreach ($base_tree as $key => $value) { - $base_config[$key] = $adv_config[$value]; - if (!file_exists($base_config[$key])) { - if (!mkdir($base_config[$key], 0777, true)) { - die('Error creating dir : ' . $base_config[$key]); + $baseConfig[$key] = $adv_config[$value]; + if (!is_dir($baseConfig[$key])) { + if (!mkdir($baseConfig[$key], 0755, true)) { + die_freepbx(_("Error creating dir: $baseConfig[$key]")); } } } - print_r($base_config, 1); -// die(print_r($base_config,1)); -// $base_config['External_ini'] = $adv_config; -// $base_config['External_mode'] = $adv_tree_mode; - - /* - if (!empty($this->sccppath["tftp_path"])) { - $this->sccppath["tftp_DP"] = $this->sccppath["tftp_path"] . '/Dialplan'; - if (!file_exists($this->sccppath["tftp_DP"])) { - if (!mkdir($this->sccppath["tftp_DP"], 0777, true)) { - die('Error creating DialPlan template dir'); - } - } - } - */ - // TFTP -REWrite double model - if (empty($_SERVER['DOCUMENT_ROOT'])) { - if (!empty($this->paren_class)) { - $this->paren_class->class_error['DOCUMENT_ROOT'] = 'Empty DOCUMENT_ROOT'; + // Set up tftproot/settings so that can test if mapping is Enabled and configured. + if (!is_dir("{$settingsFromDb['tftp_path']['data']}/settings")) { + if (!mkdir("{$settingsFromDb['tftp_path']['data']}/settings", 0755, true)) { + die_freepbx(_("Error creating dir: {$settingsFromDb['tftp_path']['data']}/settings")); } - $base_config['error'] = 'Empty DOCUMENT_ROOT'; - return $base_config; } - - if (!file_exists($base_config["tftp_templates"] . '/XMLDefault.cnf.xml_template')) { - $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/'; - $dst_path = $base_config["tftp_templates"] . '/'; - foreach (glob($src_path . '*.*_template') as $filename) { + // TODO: Need to add index.cnf, after setting defaults correctly + if (!file_exists("{$baseConfig['tftp_templates_path']}/XMLDefault.cnf.xml_template")) { + $src_path = $amp_conf['AMPWEBROOT'] . '/admin/modules/sccp_manager/conf/'; + $dst_path = "{$baseConfig["tftp_templates_path"]}/"; + foreach (glob("{$src_path}*.*_template") as $filename) { copy($filename, $dst_path . basename($filename)); } } - - $dst = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/core/functions.inc/drivers/Sccp.class.php'; - if (!file_exists($dst) || $sccp_driver_replace == 'yes') { - $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/' . basename($dst) . '.v' . $db_vars['sccp_compatible']['data']; - if (file_exists($src_path)) { - copy($src_path, $dst); - } else { - // Set new default - $src_path = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/' . basename($dst) . '.v433'; - copy($src_path, $dst); - } + foreach ($baseConfig as $baseKey => $baseValue) { + $settingsFromDb[$baseKey] = array('keyword' => $baseKey, 'seq' => 20, 'type' => 0, 'data' => $baseValue, 'systemdefault' => ''); } - - if (!file_exists($base_config["sccp_conf"])) { // System re Config - $sccpfile = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/sccp.conf'); - file_put_contents($base_config["sccp_conf"], $sccpfile); - } - - return $base_config; + return $settingsFromDb; } - // Type declaration in below function is incompatible with PHP 5 + public function validate_RealTime( $connector ) { // This method only checks that asterisk is correctly configured for Realtime @@ -381,7 +380,7 @@ class extconfigs $cnf_read = \FreePBX::LoadConfig(); // We are running inside FreePBX so must use the same database - $def_config = array('sccpdevice' => 'mysql,' . $amp_conf['AMPDBNAME'] . ',sccpdeviceconfig', 'sccpline' => 'mysql,' . $amp_conf['AMPDBNAME'] . ',sccpline'); + $def_config = array('sccpdevice' => 'mysql,' . $amp_conf['AMPDBNAME'] . ',sccpdeviceconfig', 'sccpline' => 'mysql,' . $amp_conf['AMPDBNAME'] . ',sccplineconfig'); $backup_ext = array('_custom.conf', '.conf', '_additional.conf'); $def_bd_config = array('dbhost' => $amp_conf['AMPDBHOST'], 'dbname' => $amp_conf['AMPDBNAME'], 'dbuser' => $amp_conf['AMPDBUSER'], 'dbpass' => $amp_conf['AMPDBPASS'], diff --git a/views/formShow.php b/sccpManClasses/formcreate.class.php similarity index 57% rename from views/formShow.php rename to sccpManClasses/formcreate.class.php index 66e9fdf..cb0634a 100644 --- a/views/formShow.php +++ b/sccpManClasses/formcreate.class.php @@ -1,147 +1,153 @@ 'GMT -12', '-11' => 'GMT -11', '-10' => 'GMT -10', '-09' => 'GMT -9', - '-08' => 'GMT -8', '-07' => 'GMT -7', '-06' => 'GMT -6', '-05' => 'GMT -5', - '-04' => 'GMT -4', '-03' => 'GMT -3', '-02' => 'GMT -2', '-01' => 'GMT -1', - '00' => 'GMT', '01' => 'GMT +1', '02' => 'GMT +2', '03' => 'GMT +3', - '04' => 'GMT +4', '05' => 'GMT +5', '06' => 'GMT +6', '07' => 'GMT +7', - '08' => 'GMT +8', '09' => 'GMT +9', '10' => 'GMT +10', '11'=> 'GMT +11', '12' => 'GMT +12'); +namespace FreePBX\modules\Sccp_manager; - -$time_zone_name = array(); -$extension_list = array(); -$sofkey_list = array(); -$model_list = array(); -$device_list = array(); -$dialplan_list = array(); - -//$time_zone = \FreePBX::Sccp_manager()-> extconfigs-> getextConfig('cisco_time'); -//$system_time_zone = \FreePBX::Sccp_manager()->getSysnemTimeZone(); -//$sofkey_list = \FreePBX::Sccp_manager()-> aminterface->sccp_list_keysets(); -//$model_list = \FreePBX::Sccp_manager()->dbinterface->HWextension_db_SccpTableData("HWDevice"); -//$extension_list = \FreePBX::Sccp_manager()->dbinterface->HWextension_db_SccpTableData("HWextension"); -//$device_list = \FreePBX::Sccp_manager()->dbinterface->HWextension_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")) { - $syslangs = \FreePBX::Soundlang()->getLanguages(); - if (!is_array($syslangs)) { - $syslangs = array(); +class formcreate +{ + public function __construct($parent_class = null) { + $this->buttonDefLabel = 'chan-sccp'; + $this->buttonHelpLabel = 'site'; } -} -if (function_exists('music_list')) { - $moh_list = music_list(); -// $cur = (isset($mohsilence) && $mohsilence != "" ? $mohsilence : 'default'); -} -if (!is_array($moh_list)) { - $moh_list = array('default'); -} - - -$items = $itm -> children(); - -if ($h_show==1) { - $sec_class =''; - if (!empty($items ->class)) { - $sec_class = (string)$items ->class; - } - ?> - -
    -

    label) ?>

    -
    -
    - - help)) { - $child->help = 'Help is not available.'; - $child->meta_help = '1'; - } -// $child->meta_help = '1'; // Remove comments to see original help ! - - if ($child['type'] == 'IE') { + function addElementIE ($child, $fvalues, $sccp_defaults, $npref) { $res_input = ''; $res_name = ''; - $res_oid = (string)$child->input[0]->name; - $res_id = $npref.$res_oid; - if (!empty($metainfo[$res_oid])) { + if ($npref == 'sccp_hw_') { + $this->buttonDefLabel = 'site'; + $this->buttonHelpLabel = 'device'; + } + $usingSysDefaults = true; + // if there are multiple inputs, take the first for res_id and shortId + $shortId = (string)$child->input[0]->name; + $res_id = $npref.$shortId; + if (!empty($metainfo[$shortId])) { if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_oid]['Description']; + $child->help = $metainfo[$shortId]; } } - // --- Add Hiden option + // --- Add Hidden option $res_sec_class =''; if (!empty($child ->class)) { $res_sec_class = (string)$child ->class; } - if (empty($child->nameseparator)) { $child->nameseparator = ' / '; } $i = 0; - - echo ''; - ?>
    -
    +
    +
    + "; + + // Can have multiple inputs for a field which are displayed with a separator + foreach ($child->xpath('input') as $value) { + $res_n = (string)$value->name; + $res_name = $npref . $res_n; + //if (!empty($fvalues[$res_n])) { + $value->value = $fvalues[$res_n]['data']; + if (!empty($fvalues[$res_n]['data'])) { + if (!empty($sccp_defaults[$res_n]['systemdefault']) && ($sccp_defaults[$res_n]['systemdefault'] != $fvalues[$res_n]['data'])) { + $usingSysDefaults = false; + } + } + //} + // Default to chan-sccp defaults, not xml defaults. + //if (empty($value->value)) { + //$value->value = $sccp_defaults[$res_n]['systemdefault']; + //} + if (empty($value->type)) { + $value->type = 'text'; + } + if (empty($value->class)) { + $value->class = 'form-control'; + } + if ($i > 0) { + echo $child->nameseparator; + } + // Output current value + if (empty($value->value)) { + echo "Value not found for {$res_n}"; + } + echo $value->value; + $i ++; + } + ?> +
    +
    + + + > + + + +
    +
    +
    + -
    +
    +
    +
    +
    help);?> -
    +
    +
    - label.' -->'; } - if ($child['type'] == 'IED') { + + function addElementIED($child, $fvalues, $sccp_defaults,$npref, $napref) { $res_input = ''; - $res_name = ''; $res_value = ''; $opt_at = array(); $res_n = (string)$child->name; if (!empty($metainfo[$res_n])) { if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_n]['Description']; + $child->help = $metaInfo[$res_n]; } } -// $res_value + // $res_value $lnhtm = ''; $res_id = $napref.$child->name; $i = 0; @@ -207,10 +213,7 @@ foreach ($items as $child) { } if (empty($res_value)) { $res_value = array((string) $child->default); -// $res_value = explode('/', (string) $child->default); } - - echo ''; ?>
    @@ -276,17 +279,19 @@ foreach ($items as $child) { ?>
    > xpath('input') as $value) { $res_n = $res_id.'['.$i.']['.$value['field'].']'; $fields_id = (string)$value['field']; - $opt_at[$fields_id]['nameseparator']=(string)$value['nameseparator']; + //$opt_at[$fields_id]['nameseparator']=(string)$value['nameseparator']; if (!empty($value->class)) { $opt_at[$fields_id]['class']='form-control ' .(string)$value->class; } - $opt_at[$fields_id]['nameseparator']=(string)$value['nameseparator']; - + //$opt_at[$fields_id]['nameseparator']=(string)$value['nameseparator']; + if (!empty((string)$value['nameseparator'])) { + $res_vf = explode((string)$value['nameseparator'], $dat_v); + } echo 'options)) { foreach ($value->options ->attributes() as $optkey => $optval) { @@ -304,7 +309,6 @@ foreach ($items as $child) { $i++; } ?> -
    addbutton)) { @@ -323,48 +327,118 @@ foreach ($items as $child) {
    label.' -->'; } - if ($child['type'] == 'IS') { + function addElementIS($child, $fvalues, $sccp_defaults,$npref, $disabledButtons) { + if ($npref == 'sccp_hw_') { + $this->buttonDefLabel = 'site'; + $this->buttonHelpLabel = 'device'; + } $res_n = (string)$child->name; - $res_id = $npref.$child->name; + $res_id = $npref.$res_n; + $res_ext = str_replace($npref,'',$res_n); + $usingSysDefaults = true; if (!empty($metainfo[$res_n])) { if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_n]['Description']; + $child->help = $metaInfo[$res_n]; } } - // --- Add Hiden option + // --- Add Hidden option $res_sec_class =''; if (!empty($child ->class)) { $res_sec_class = (string)$child ->class; } - - echo ''; ?>
    -
    +
    +
    - +
    -
    - default)) { - $res_v = (string)$child->default; + + default)) { + $res_v = (string)$child->default; + } + if (!empty($child->value)) { + $res_v = (string)$child->value; + } + if (!empty($fvalues[$res_n])) { + if (($fvalues[$res_n]['data'] != '') ) { + $res_v = (string)$fvalues[$res_n]['data']; } - if (!empty($child->value)) { - $res_v = (string)$child->value; - } - if (!empty($fvalues[$res_n])) { - if (($fvalues[$res_n]['data'] != '') ) { - $res_v = (string)$fvalues[$res_n]['data']; + } + if (!empty($sccp_defaults[$res_n]['systemdefault'])) { + // There is a system default, so add button to customise or reset + // the closing } is after the code to include the button at line ~498 + + //-- Start include of defaults button -- + echo "
    "; + + if (!empty($sccp_defaults[$res_n]['systemdefault']) && ($sccp_defaults[$res_n]['systemdefault'] != $res_v)) { + $usingSysDefaults = false; + } + + // Output current value + echo $res_v; + ?> +
    +
    + + + > + + +
    +
    +
    + + +
    +
    help);?>
    label.' -->'; } -/* - * Input element Select SLD - Date format - * SLZ - Time Zone - * - * SLM - Music on hold - * SLK - System KeySet - * SLP - Dial Paterns - */ - - if ($child['type'] == 'SLD' || $child['type'] == 'SLM'|| $child['type'] == 'SLK'|| $child['type'] == 'SLP') { -// $value = $child -> select; + function addElementSL($child, $fvalues, $sccp_defaults,$npref, $installedLangs) { + // Input element Select SLS - System Language $res_n = (string)$child ->name; $res_id = $npref.$res_n; + $child->value =''; + // $select_opt is an associative array for these types. if (!empty($metainfo[$res_n])) { if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_n]['Description']; + $child->help = $metaInfo[$res_n]; } } + switch ($child['type']) { + case 'SLS': + $syslangs = array(); + if (\FreePBX::Modules()->checkStatus("soundlang")) { + $syslangs = \FreePBX::Soundlang()->getLanguages(); + } + $select_opt= $syslangs; + break; + case 'SLTD': + // Device Language + $select_opt = array('xx' => 'No language packs found'); + if (!empty($installedLangs['languages']['have'])) { + $select_opt = (array)$installedLangs['languages']['have']; + } + break; + case 'SLTN': + // Network Language + $select_opt = array('xx' => 'No country packs found'); + if (!empty($installedLangs['countries']['have'])) { + $select_opt = (array)$installedLangs['countries']['have']; + } + break; + case 'SLZ': + $timeZoneOffsetList = array('-12' => 'GMT -12', '-11' => 'GMT -11', '-10' => 'GMT -10', '-09' => 'GMT -9', + '-08' => 'GMT -8', '-07' => 'GMT -7', '-06' => 'GMT -6', '-05' => 'GMT -5', + '-04' => 'GMT -4', '-03' => 'GMT -3', '-02' => 'GMT -2', '-01' => 'GMT -1', + '00' => 'GMT', '01' => 'GMT +1', '02' => 'GMT +2', '03' => 'GMT +3', + '04' => 'GMT +4', '05' => 'GMT +5', '06' => 'GMT +6', '07' => 'GMT +7', + '08' => 'GMT +8', '09' => 'GMT +9', '10' => 'GMT +10', '11'=> 'GMT +11', '12' => 'GMT +12'); + $select_opt= $timeZoneOffsetList; + break; + case 'SLA': + $select_opt = array(); + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $res_value = explode(';', $fvalues[$res_n]['data']); + } + if (empty($res_value)) { + $res_value = array((string) $child->default); + } + foreach ($res_value as $key) { + $select_opt[$key]= $key; + } + } - if (empty($child->class)) { - $child->class = 'form-control'; - } - - if ($child['type'] == 'SLD') { - $select_opt= $day_format; - } - - if ($child['type'] == 'SLM') { - $select_opt= $moh_list; - } - if ($child['type'] == 'SLK') { - if (empty($sofkey_list)) { - $sofkey_list = \FreePBX::Sccp_manager()->aminterface->sccp_list_keysets(); - } - $select_opt= $sofkey_list; - } - if ($child['type'] == 'SLP') { - if (empty($dialplan_list)) { + case 'SLM': + if (function_exists('music_list')) { + $moh_list = music_list(); + } + if (!is_array($moh_list)) { + $moh_list = array('default'); + } + $select_opt= $moh_list; + break; + case 'SLD': + $day_format = array("D.M.Y", "D.M.YA", "Y.M.D", "YA.M.D", "M-D-Y", "M-D-YA", "D-M-Y", "D-M-YA", "Y-M-D", "YA-M-D", "M/D/Y", "M/D/YA", + "D/M/Y", "D/M/YA", "Y/M/D", "YA/M/D", "M/D/Y", "M/D/YA"); + $select_opt= $day_format; + break; + case 'SLK': + $softKeyList = array(); + $softKeyList = \FreePBX::Sccp_manager()->aminterface->sccp_list_keysets(); + $select_opt= $softKeyList; + break; + case 'SLP': + $dialplan_list = array(); foreach (\FreePBX::Sccp_manager()->getDialPlanList() as $tmpkey) { $tmp_id = $tmpkey['id']; $dialplan_list[$tmp_id] = $tmp_id; } - } - $select_opt= $dialplan_list; + $select_opt= $dialplan_list; + break; + case 'SL': + $select_opt = array(); + break; } -// if ($child['type'] == 'SLZ') { -// $select_opt= $time_zone; -// } - - echo ''; - - ?> -
    -
    - -
    - - -
    -
    class . '" id="' . $res_id . '">'; - if (!empty($fvalues[$res_n])) { - if (!empty($fvalues[$res_n]['data'])) { - $child->value = $fvalues[$res_n]['data']; - } - } - foreach ($select_opt as $key) { - echo ''; - } - ?> -
    -
    -
    - help);?> -
    -
    - label.' -->'; - } -/* - * Input element Select SLS - System Language - */ - - if ($child['type'] == 'SLS' || $child['type'] == 'SLT' || $child['type'] == 'SLA' || $child['type'] == 'SLZ') { -// $value = $child -> select; - $res_n = (string)$child ->name; - $res_id = $npref.$res_n; - $child->value =''; - - if (!empty($metainfo[$res_n])) { - if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_n]['Description']; - } - } - - if ($child['type'] == 'SLS') { - $select_opt= $syslangs; - } - if ($child['type'] == 'SLT') { - $select_opt= $tftp_lang; - } - if ($child['type'] == 'SLZ') { - $select_opt= $time_zone; -// $child->value = ($system_time_zone[offset]/60); - } - - if ($child['type'] == 'SLA') { - $select_opt =''; - if (!empty($fvalues[$res_n])) { - if (!empty($fvalues[$res_n]['data'])) { - $res_value = explode(';', $fvalues[$res_n]['data']); - } - if (empty($res_value)) { - $res_value = array((string) $child->default); - } - foreach ($res_value as $key) { - $select_opt[$key]= $key; - } - } - } - if (empty($child->class)) { $child->class = 'form-control'; } - if (!empty($fvalues[$res_n])) { if (!empty($fvalues[$res_n]['data'])) { $child->value = $fvalues[$res_n]['data']; } } + if (empty($child->value)) { + if (!empty($child->default)) { + $child->value = $child->default; + } + } + ?> +
    +
    +
    +
    + + +
    +
    +
    + class . '" id="' . $res_id . '">'; + foreach ($select_opt as $key => $val) { + if (is_array($val)) { + $opt_key = (isset($val['id'])) ? $val['id'] : $key; + $opt_val = (isset($val['val'])) ? $val['val'] : $val; + } else if (\FreePBX::Sccp_manager()->is_assoc($select_opt)){ + // have associative array + $opt_key = $key; + $opt_val = $val; + } else { + // Have simple array + $opt_key = $val; + $opt_val = $val; + } + echo '"; + } + ?> + +
    +
    +
    +
    +
    +
    + help);?> +
    +
    +
    + name; + $res_id = $npref.$res_n; + $child->value =''; + $selectArray = array(); + // $select_opt is an associative array for these types. + if (!empty($metainfo[$res_n])) { + if ($child->meta_help == '1' || $child->help == 'Help!') { + $child->help = $metaInfo[$res_n]; + } + } + + switch ($child['type']) { + case 'SLDA': + $select_opt = array('xx' => 'No language packs found'); + if (!empty($installedLangs['languages']['have'])) { + $select_opt = $installedLangs['languages']['have']; + } + $selectArray = $installedLangs['languages']['available']; + $requestType = 'locale'; + break; + + case 'SLNA': + $select_opt = array('xx' => 'No country packs found'); + if (!empty($installedLangs['countries']['have'])) { + $select_opt = $installedLangs['countries']['have']; + } + $selectArray = $installedLangs['countries']['available']; + $requestType = 'country'; + break; + } + + + if (empty($child->class)) { + $child->class = 'form-control'; + } + if (!empty($fvalues[$res_n])) { + if (!empty($fvalues[$res_n]['data'])) { + $child->value = $fvalues[$res_n]['data']; + } + } if (empty($child->value)) { if (!empty($child->default)) { $child->value = $child->default; } } - echo ''; ?>
    -
    +
    +
    + -
    +
    -
    +
    + class . '" id="' . $res_id . '">'; - foreach ($select_opt as $key => $val) { - if (is_array($val)) { - $opt_key = (isset($val['id'])) ? $val['id'] : $key; - $opt_val = (isset($val['val'])) ? $val['val'] : $val; - } else { - $opt_key = $key; - $opt_val = $val; - } - echo ''; - } - ?> -
    -
    -
    - help);?> -
    -
    - - label.' -->'; - } -/* - * Input element Select - */ - - if ($child['type'] == 'SL') { - $res_n = (string)$child->name; - $res_id = $npref.$child->name; - - if (!empty($metainfo[$res_n])) { - if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_n]['Description']; - } - } - - if (empty($child ->class)) { - $child->class = 'form-control'; - } - echo ''; - - ?> -
    -
    - -
    - - + foreach ($select_opt as $key => $val) { + $opt_key = $key; + $opt_val = $val; + echo '"; + } + ?> + +
    -
    class . '" id="' . $res_id . '">'; - if (!empty($fvalues[$res_n])) { - if (!empty($fvalues[$res_n]['data'])) { - $child->value = $fvalues[$res_n]['data']; - } - } - foreach ($child->xpath('select') as $value) { - if (!empty($value[@value])) { - $key = $value[@value]; - } else { - $key = (string)$value; - } - echo ''; - } - ?> - -
    -
    -
    +
    + +
    +
    +
    +
    +
    help);?> -
    +
    +
    + label.' -->'; + } - /* - * Input element Select SDM - Model List - * SDMS - Sip model List - * SDE - Extension List - */ - - if ($child['type'] == 'SDM' || $child['type'] == 'SDMS' || $child['type'] == 'SDE' || $child['type'] == 'SDD') { -// $value = $child -> select; + function addElementSD($child, $fvalues, $sccp_defaults,$npref) { + /* + * Input element Select SDM - Model List + * SDMS - Sip model List + * SDE - Extension List + */ $res_n = (string)$child ->name; $res_id = $npref.$res_n; if (!empty($metainfo[$res_n])) { if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_n]['Description']; + $child->help = $metaInfo[$res_n]; } } if (empty($child->class)) { $child->class = 'form-control'; } - if ($child['type'] == 'SDM') { - if (empty($model_list)) { - $model_list = \FreePBX::Sccp_manager()->dbinterface->HWextension_db_SccpTableData("HWDevice"); - } - $select_opt= $model_list; - } - if ($child['type'] == 'SDMS') { - if (empty($model_list)) { - $model_list = \FreePBX::Sccp_manager()->dbinterface->HWextension_db_SccpTableData("HWSipDevice"); - } - $select_opt= $model_list; - } - if ($child['type'] == 'SDE') { - if (empty($extension_list)) { - $extension_list = \FreePBX::Sccp_manager()->dbinterface->HWextension_db_SccpTableData("HWextension"); - $extension_list[]=array( 'model' => 'NONE', 'vendor' => 'CISCO', 'dns' => '0'); + switch ($child['type']) { + case 'SDM': + $model_list = \FreePBX::Sccp_manager()->dbinterface->getDb_model_info('ciscophones', 'model'); + $select_opt= $model_list; + break; + case 'SDMS': + $model_list = \FreePBX::Sccp_manager()->dbinterface->getDb_model_info('sipphones', 'model'); + $select_opt= $model_list; + break; + case 'SDML': + $assignedExts = \FreePBX::Sccp_manager()->dbinterface->getSccpDeviceTableData('getAssignedExtensions'); + $select_opt = \FreePBX::Sccp_manager()->dbinterface->getSccpDeviceTableData('SccpExtension'); + foreach ($assignedExts as $name => $nameArr ) { + $select_opt[$name]['label'] .= " - in use"; + } + $child->default = $fvalues['defaultLine']; + break; + case 'SDE': + $extension_list = \FreePBX::Sccp_manager()->dbinterface->getDb_model_info('extension', 'model'); + $extension_list[] = array( 'model' => 'NONE', 'vendor' => 'CISCO', 'dns' => '0'); foreach ($extension_list as &$data) { $d_name = explode(';', $data['model']); if (is_array($d_name) && (count($d_name) > 1)) { @@ -682,23 +770,17 @@ foreach ($items as $child) { } } unset($data); - } - $select_opt= $extension_list; - } - if ($child['type'] == 'SDD') { - if (empty($device_list)) { - $device_list = \FreePBX::Sccp_manager()->dbinterface->HWextension_db_SccpTableData("SccpDevice"); + $select_opt= $extension_list; + break; + case 'SDD': + $device_list = \FreePBX::Sccp_manager()->dbinterface->getSccpDeviceTableData("SccpDevice"); $device_list[]=array('name' => 'NONE', 'description' => 'No Device'); - } - $select_opt = $device_list; + $select_opt = $device_list; + break; } - - echo ''; - ?>
    -
    @@ -713,7 +795,7 @@ foreach ($items as $child) { echo '>'; $fld = (string)$child->select['name']; - $flv = (string)$child->select; + $flv = (string)$child->select['name']; $flv2 = (string)$child->select['addlabel']; $flk = (string)$child->select['dataid']; $flkv = (string)$child->select['dataval']; @@ -724,7 +806,6 @@ foreach ($items as $child) { $key = $fvalues[$res_n]['data']; } } - foreach ($select_opt as $data) { echo '
    -
    + ?> + +
    +
    + +
    help);?>
    label.' -->'; } - if ($child['type'] == 'ITED') { + + function addElementITED($child, $fvalues, $sccp_defaults, $npref, $napref) { $res_input = ''; - $res_name = ''; $res_na = (string)$child->name; -// $res_value + // $res_value $lnhtm = ''; $res_id = $napref.$child->name; $i = 0; @@ -770,14 +853,9 @@ foreach ($items as $child) { } if (empty($res_value)) { $res_value = array((string) $child->default); -// $res_value = explode('/', (string) $child->default); } + echo ""; - echo ''; - ?> -
    - - '; if (!empty($child->label)) { @@ -854,17 +932,14 @@ foreach ($items as $child) { $i++; } echo '
    '; - echo ''; } - if ($child['type'] == 'HLP') { + function addElementHLP($child, $fvalues, $sccp_defaults,$npref) { $res_n = (string)$child ->name; $res_id = $npref.$res_n; if (empty($child->class)) { $child->class = 'form-control'; } - echo ''; - ?>
    @@ -897,52 +972,20 @@ foreach ($items as $child) { } } ?> -
    label.' -->'; } - if ($child['type'] == 'MINFO') { - $res_n = (string)$child ->name; - $res_id = $npref.$res_n; - if (empty($child->class)) { - $child->class = 'form-control'; - } - echo ''; - ?> - - label.' -->'; - } -/* - * Input element Select SLTZN - System Time Zone - */ - if ($child['type'] == 'SLTZN') { -// $value = $child -> select; + function addElementSLTZN($child, $fvalues, $sccp_defaults,$npref) { + // Input element Select SLTZN - System Time Zone $res_n = (string)$child ->name; $res_id = $npref.$res_n; $child->value =''; if (!empty($metainfo[$res_n])) { if ($child->meta_help == '1' || $child->help == 'Help!') { - $child->help = $metainfo[$res_n]['Description']; + $child->help = $metaInfo[$res_n]; } } @@ -957,8 +1000,6 @@ foreach ($items as $child) { } $child->value = \date_default_timezone_get(); - - echo ''; ?>
    @@ -977,14 +1018,8 @@ foreach ($items as $child) { help);?>
    - label.' -->'; } } -?> -'; -} + ?> diff --git a/sccpManClasses/xmlinterface.class.php b/sccpManClasses/xmlinterface.class.php index 394400c..7d5d926 100644 --- a/sccpManClasses/xmlinterface.class.php +++ b/sccpManClasses/xmlinterface.class.php @@ -112,12 +112,56 @@ class xmlinterface $node->addAttribute('model', $var['vendor'] . ' ' . $var['model']); } } - $xml_work->asXml($xml_name); // Save XMLDefault1.cnf.xml + \FreePBX::Sccp_manager()->saveXml($xml_work, $xml_name); // Save XMLDefault1.cnf.xml } } - function create_SEP_XML($store_path = '', $data_values = array(), $dev_config = array(), $dev_id = '', $lang_info = array()) + function create_SEP_XML($store_path, $data_values, $dev_config, $dev_id, $lang_info = array()) { + // TODO: $data_values are system wide defaults, $dev_config are specific defice values. + // Need to merge the two arrays so that device specific values override system values + $langCodeArray = array( + 'Arabic_Saudi_Arabia' => 'ar', + 'Bulgarian_Bulgaria' => 'bg', + 'Czech_Czech_Republic' => 'cz', + 'Danish_Denmark' => 'da', + 'German_Germany' => 'de', + 'Greek_Greece' => 'el', + 'AU_English_United_States' => 'en', + 'English_United_Kingdom' => 'en', + 'English_United_States' => 'en', + 'Spanish_Spain' => 'es', + 'Estonian_Estonia' => 'et', + 'Finnish_Finland' => 'fi', + 'French_Canada' => 'fr', + 'French_France' => 'fr', + 'Hebrew_Israel' => 'he', + 'Croatian_Croatia' => 'hr', + 'Hungarian_Hungary' => 'hu', + 'Italian_Italy' => 'it', + 'Japanese_Japan' => 'ja', + 'Korean_Korea_Republic' => 'ko', + 'Lithuanian_Lithuania' => 'lt', + 'Latvian_Latvia' => 'lv', + 'Dutch_Netherlands' => 'nl', + 'Norwegian_Norway' => 'no', + 'Polish_Poland' => 'pl', + 'Portuguese_Brazil' => 'pt', + 'Portuguese_Portugal' => 'pt', + 'Romanian_Romania' => 'ro', + 'Russian_Russian_Federation' => 'ru', + 'Slovak_Slovakia' => 'sk', + 'Slovenian_Slovenia' => 'sl', + 'Serbian_Republic_of_Montenegro' => 'sr', + 'Serbian_Republic_of_Serbia' => 'rs', + 'Swedish_Sweden' => 'sv', + 'Thai_Thailand' => 'th', + 'Turkish_Turkey' => 'tr', + 'Chinese_China' => 'cn', + 'Chinese_Taiwan' => 'zh' + ); + + $data_values = array_merge($data_values, $dev_config); $var_xml_general_fields = array('authenticationurl' => 'dev_authenticationURL', 'informationurl' => 'dev_informationURL', 'messagesurl' => 'dev_messagesURL', 'servicesurl' => 'dev_servicesURL', 'directoryurl' => 'dev_directoryURL', 'idleurl' => 'dev_idleURL', 'secureauthenticationurl' => 'dev_secureauthenticationURL', @@ -125,226 +169,233 @@ class xmlinterface 'secureservicesurl'=>'dev_secureservicesURL', 'securedirectoryurl'=>'dev_securedirectoryURL', 'secureidleurl' => 'dev_secureidleURL', 'proxyserverurl' => 'dev_proxyServerURL', 'idletimeout' => 'dev_idleTimeout', 'sshuserid' => 'dev_sshUserId', 'sshpassword' => 'dev_sshPassword', 'deviceprotocol' => 'dev_deviceProtocol', - 'phonepersonalization' => 'phonePersonalization' + 'phonepersonalization' => 'phonepersonalization' ); $var_xml_general_vars = array('capfAuthMode' => 'null', 'capfList' => 'null', 'mobility' => 'null', 'phoneServices' => 'null', 'certHash' => 'null', 'deviceSecurityMode' => '1'); - if (empty($dev_config)) { - return false; + $data_path = $dev_config['tftp_templates_path']; + if (empty($data_path)) { + die('Create_SEP_XML tftp_templates_path not defined'); } - $data_path = $dev_config['tftp_path']; - if (empty($store_path) || empty($data_path) || empty($data_values) || empty($dev_id)) { - return; + $store_path = $dev_config['tftp_store_path']; + if (empty($store_path)) { + die('Create_SEP_XML tftp_store_path not defined'); } if (!empty($dev_config['nametemplate'])) { - $xml_template = $data_path . '/templates/' . $dev_config['nametemplate']; + $xml_template = "{$data_path}/{$dev_config['nametemplate']}"; } else { - $xml_template = $data_path . '/templates/SEP0000000000.cnf.xml_79df_template'; + $xml_template = "{$data_path}/templates/SEP0000000000.cnf.xml_79df_template"; } - $xml_name = $store_path . '/' . $dev_id . '.cnf.xml'; - if (file_exists($xml_template)) { - $xml_work = simplexml_load_file($xml_template); - - foreach ($var_xml_general_vars as $key => $data) { - if (isset($xml_work->$key)) { - if ($data != 'null') { - $xml_work->$key = $data; - } else { - $node = $xml_work->$key; - unset($node[0][0]); - } - } - } - - foreach ($xml_work as $key => $data) { -// Set System global Values - $key_l = strtolower($key); - if (!empty($var_xml_general_fields[$key_l])) { - $xml_work->$key = $data_values[$var_xml_general_fields[$key_l]]; - } -// Set section Values - $xml_node = $xml_work->$key; - switch ($key_l) { - case 'devicepool': - $xml_node = $xml_work->$key; - foreach ($xml_work->$key->children() as $dkey => $ddata) { - switch (strtolower($dkey)) { - case 'datetimesetting': - $xnode = &$xml_node->$dkey; - $tz_id = $data_values['ntp_timezone']; - $TZdata = $data_values['ntp_timezone_id']; - if (empty($TZdata)) { - $TZdata = array('offset' => '0', 'daylight' => '', 'cisco_code' => 'Greenwich Standard Time'); - } - $xnode->name = $tz_id; - $xnode->dateTemplate = $data_values['dateformat']; - $xnode->timeZone = $TZdata['cisco_code']; -// $xnode->timeZone = $tz_id.' Standard'.((empty($TZdata['daylight']))? '': '/'.$TZdata['daylight']).' Time'; - - if ($data_values['ntp_config_enabled'] == 'on') { - $xnode->ntps->ntp->name = $data_values['ntp_server']; - $xnode->ntps->ntp->ntpMode = $data_values['ntp_server_mode']; - } else { - $xnode->ntps = null; - } - // Ntp Config - break; - case 'srstinfo': - if ($data_values['srst_Option'] == 'user') { - break; - } - $xnode = &$xml_node->$dkey; - $xnode->name = $data_values['srst_Name']; - $xnode->srstOption = $data_values['srst_Option']; - $xnode->userModifiable = $data_values['srst_userModifiable']; - $xnode->isSecure = $data_values['srst_isSecure']; - - $srst_fld = array('srst_ip' => array('ipAddr', 'port')); - foreach ($srst_fld as $srst_pro => $srs_put) { - if (empty($data_values[$srst_pro]) || ($data_values['srst_Option'] == 'disable') ) { - $srst_data =array(); - } else { - $srst_data = explode(';', $data_values[$srst_pro]); - } - $si = 1; - foreach ($srst_data as $value) { - $srs_val = explode('/', $value); - $nod = $srs_put[0] . $si; - $xnode->$nod = $srs_val[0]; - $nod = $srs_put[1] . $si; - $xnode->$nod = ((empty($srs_val[1])) ? "2000": $srs_val[1]); - $si++; - } - while ($si < 4) { - $nod = $srs_put[0] . $si; - $xnode->$nod = ''; - $nod = $srs_put[1] . $si; - $xnode->$nod = ''; - $si++; - } - } - break; - case 'connectionmonitorduration': - $xml_node->$dkey = strval(intval(intval($data_values['keepalive']) * 0.75)); - break; - case 'callmanagergroup': - $xnode = &$xml_node->$dkey->members; - $bind_tmp = $this->get_server_sccp_bind($data_values); - $ifc = 0; - foreach ($bind_tmp as $bind_value) { - $xnode_obj = clone $xnode->member; - $xnode_obj['priority'] = $ifc; - $xnode_obj->callManager->name = $data_values['servername']; - if (!is_null($xnode_obj->callManager->description)) { - $xnode_obj->callManager->description = $data_values['servername']; - } - $xnode_obj->callManager->ports->ethernetPhonePort = $bind_value['port']; - $xnode_obj->callManager->processNodeName = $bind_value['ip']; - if (!empty($xnode_obj->callManager->ports->mgcpPorts)) { - unset($xnode_obj->callManager->ports->mgcpPorts); - } - - if ($ifc === 0) { - $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); - } else { - $this->appendSimpleXmlNode($xnode->member, $xnode_obj); - } - $ifc++; - } - } - } - $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); - break; - case 'vendorconfig': - $xml_node = $xml_work->$key; - foreach ($xml_work->$key->children() as $dkey => $ddata) { - $dkey_l = strtolower($dkey); - $vtmp_key = $key_l.'_'.$dkey_l; - if (isset($data_values[$vtmp_key])) { - $vtmp_data = $data_values[$vtmp_key]; - if ((!empty($vtmp_data)) || ($vtmp_data == "0")) { - $xml_node->$dkey = $vtmp_data; - } - } - } - $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); - break; - - case 'versionstamp': - $xml_work->$key = time(); - break; - case 'loadinformation': -// Set Path Image ???? - if (isset($dev_config["tftp_firmware"])) { - $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["tftp_firmware"] . $dev_config["loadimage"] : ''; - } else { - $xml_work->$key = (isset($dev_config["loadimage"])) ? $dev_config["loadimage"] : ''; - } - if (!empty($dev_config['addon'])) { - $xnode = $xml_work->addChild('addOnModules'); - $ti = 1; - $hw_addon = explode(';', $dev_config['addon']); - foreach ($hw_addon as $add_key) { - if (!empty($dev_config['addon_info'][$dev_config['addon']])) { - $add_val = $dev_config['addon_info'][$dev_config['addon']]; - $xnode_obj = $xnode->addChild('addOnModule'); - $xnode_obj->addAttribute('idx', $ti); - $xnode_obj->addChild('loadInformation', $add_val); - $ti++; - } - } - } - break; - case 'commonprofile': - $xml_node->phonePassword = $data_values['dev_sshPassword']; - $xml_node->backgroundImageAccess = (($data_values['backgroundImageAccess'] == 'on') || ($data_values['backgroundImageAccess'] == 'true') ) ? 'true' : 'false'; - $xml_node->callLogBlfEnabled = $data_values['callLogBlfEnabled']; - break; - - case 'userlocale': - case 'networklocaleinfo': - case 'networklocale': - $hwlang = ''; - $lang = ''; - if (!empty($dev_config["_hwlang"])) { - $hwlang = explode(':', $dev_config["_hwlang"]); - } - if (($key_l == 'networklocaleinfo') || ($key_l == 'networklocale')) { - $lang = (empty($hwlang[0])) ? $data_values['netlang'] : $hwlang[0]; - } else { - $lang = (empty($hwlang[1])) ? $data_values['devlang'] : $hwlang[1]; - } - if (($lang != 'null') && (!empty($lang))) { - if ($key_l == 'networklocale') { - $xml_work->$key = $lang; - } else { - if (isset($lang_info[$lang])) { - $xml_node->name = $lang_info[$lang]['locale']; - $xml_node->langCode = $lang_info[$lang]['code']; - if ($key_l == 'userlocale') { - $xml_node->winCharSet = $lang_info[$lang]['codepage']; - } - $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); - } - } - } else { - $xml_work->$key = ''; - } - break; - default: - break; - } - } - -// print_r($xml_work); - $xml_work->asXml($xml_name); // Save - } else { + $xml_name = "{$store_path}/{$dev_id}.cnf.xml"; + if (!file_exists($xml_template)) { die('Error Hardware template :' . $xml_template . ' not found'); } + $xml_work = simplexml_load_file($xml_template); + + foreach ($var_xml_general_vars as $key => $data) { + if (isset($xml_work->$key)) { + if ($data != 'null') { + $xml_work->$key = $data; + } else { + $node = $xml_work->$key; + unset($node[0][0]); + } + } + } + + foreach ($xml_work as $key => $data) { +// Set System global Values + $key_l = strtolower($key); + if (!empty($var_xml_general_fields[$key_l])) { + $xml_work->$key = $data_values[$var_xml_general_fields[$key_l]]; + } +// Set section Values + $xml_node = $xml_work->$key; + switch ($key_l) { + case 'devicepool': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + switch (strtolower($dkey)) { + case 'datetimesetting': + $xnode = &$xml_node->$dkey; + $tz_id = $data_values['ntp_timezone']; + $TZdata = $data_values['ntp_timezone_id']; + if (empty($TZdata)) { + $TZdata = array('offset' => '0', 'daylight' => '', 'cisco_code' => 'Greenwich Standard Time'); + } + $xnode->name = $tz_id; + $xnode->dateTemplate = $data_values['dateformat']; + $xnode->timeZone = $TZdata['cisco_code']; +// $xnode->timeZone = $tz_id.' Standard'.((empty($TZdata['daylight']))? '': '/'.$TZdata['daylight']).' Time'; + + if ($data_values['ntp_config_enabled'] == 'on') { + $xnode->ntps->ntp->name = $data_values['ntp_server']; + $xnode->ntps->ntp->ntpMode = $data_values['ntp_server_mode']; + } else { + $xnode->ntps = null; + } + // Ntp Config + break; + case 'srstinfo': + if ($data_values['srst_Option'] == 'user') { + break; + } + $xnode = &$xml_node->$dkey; + $xnode->name = $data_values['srst_Name']; + $xnode->srstOption = $data_values['srst_Option']; + $xnode->userModifiable = $data_values['srst_userModifiable']; + $xnode->isSecure = $data_values['srst_isSecure']; + + $srst_fld = array('srst_ip' => array('ipAddr', 'port')); + foreach ($srst_fld as $srst_pro => $srs_put) { + if (empty($data_values[$srst_pro]) || ($data_values['srst_Option'] == 'disable') ) { + $srst_data =array(); + } else { + $srst_data = explode(';', $data_values[$srst_pro]); + } + $si = 1; + foreach ($srst_data as $value) { + $srs_val = explode('/', $value); + $nod = $srs_put[0] . $si; + $xnode->$nod = $srs_val[0]; + $nod = $srs_put[1] . $si; + $xnode->$nod = ((empty($srs_val[1])) ? "2000": $srs_val[1]); + $si++; + } + while ($si < 4) { + $nod = $srs_put[0] . $si; + $xnode->$nod = ''; + $nod = $srs_put[1] . $si; + $xnode->$nod = ''; + $si++; + } + } + break; + case 'connectionmonitorduration': + $xml_node->$dkey = strval(intval(intval($data_values['keepalive']) * 0.75)); + break; + case 'callmanagergroup': + $xnode = &$xml_node->$dkey->members; + $bind_tmp = $this->get_server_sccp_bind($data_values); + $ifc = 0; + foreach ($bind_tmp as $bind_value) { + $xnode_obj = clone $xnode->member; + $xnode_obj['priority'] = $ifc; + $xnode_obj->callManager->name = $data_values['servername']; + if (!is_null($xnode_obj->callManager->description)) { + $xnode_obj->callManager->description = $data_values['servername']; + } + $xnode_obj->callManager->ports->ethernetPhonePort = $bind_value['port']; + $xnode_obj->callManager->processNodeName = $bind_value['ip']; + if (!empty($xnode_obj->callManager->ports->mgcpPorts)) { + unset($xnode_obj->callManager->ports->mgcpPorts); + } + + if ($ifc === 0) { + $this->replaceSimpleXmlNode($xnode->member, $xnode_obj); + } else { + $this->appendSimpleXmlNode($xnode->member, $xnode_obj); + } + $ifc++; + } + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + case 'vendorconfig': + $xml_node = $xml_work->$key; + foreach ($xml_work->$key->children() as $dkey => $ddata) { + $dkey_l = strtolower($dkey); + $vtmp_key = $key_l.'_'.$dkey_l; + if (isset($data_values[$vtmp_key])) { + $vtmp_data = $data_values[$vtmp_key]; + if ((!empty($vtmp_data)) || ($vtmp_data == "0")) { + $xml_node->$dkey = $vtmp_data; + } + } + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + + case 'versionstamp': + $xml_work->$key = time(); + break; + case 'loadinformation': + 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"] : ''; + } + if (!empty($dev_config['addon'])) { + $xnode = $xml_work->addChild('addOnModules'); + $ti = 1; + $hw_addon = explode(';', $dev_config['addon']); + foreach ($hw_addon as $add_key) { + if (!empty($dev_config['addon_info'][$dev_config['addon']])) { + $add_val = $dev_config['addon_info'][$dev_config['addon']]; + $xnode_obj = $xnode->addChild('addOnModule'); + $xnode_obj->addAttribute('idx', $ti); + $xnode_obj->addChild('loadInformation', $add_val); + $ti++; + } + } + } + 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': + // Device language + $lang = $data_values['devlang']; + if (!empty($dev_config['devlang'])) { + $lang = $dev_config['devlang']; + } + $xml_node->winCharSet = $dev_config['phonecodepage']; + $xml_node->name = $dev_config['devlang']; + $xml_node->langCode = 'en'; + if (isset($langCodeArray['devlang'])) { + $xml_node->langCode = $langCodeArray['devlang']; + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + case 'networklocale': + $lang = $data_values['netlang']; + if (!empty($dev_config['netlang'])) { + $lang = $dev_config['netlang']; + } + if (isset($lang)) { + $xml_work->$key = $lang; + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + } else { + $xml_work->$key = ''; + } + break; + case 'networklocaleinfo': + $lang = $data_values['netlang']; + if (!empty($dev_config['netlang'])) { + $lang = $dev_config['netlang']; + } + if (isset($lang)) { + $xml_node->name = $lang; + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + } else { + $xml_work->$key = ''; + } + break; + default: + break; + } + } + + \FreePBX::Sccp_manager()->saveXml($xml_work, $xml_name); // Save + return time(); } @@ -418,7 +469,7 @@ class xmlinterface 'phoneServices' => 'null', 'certHash' => 'null', 'deviceProtocol' => 'SIP', 'deviceSecurityMode' => '1'); -// $var_hw_config = $this->dbinterface->HWextension_db_SccpTableData("get_sccpdevice_byid", array('id' => $dev_id)); +// $var_hw_config = $this->dbinterface->getSccpDeviceTableData("get_sccpdevice_byid", array('id' => $dev_id)); if (empty($dev_config)) { return false; @@ -578,15 +629,15 @@ class xmlinterface case 'softKeyFile': case 'dialTemplate': // Доработать ! $xml_ext_file = ''; - $templet_path = (($dkey == 'softKeyFile') ? $dev_config['tftp_softkey'] : $dev_config['tftp_dialplan']); + $template_path = (($dkey == 'softKeyFile') ? $dev_config['tftp_softkey_path'] : $dev_config['tftp_dialplan_path']); $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'); } - if (empty($xml_ext_file) || !file_exists($templet_path . '/' . $xml_ext_file)) { + if (empty($xml_ext_file) || !file_exists($template_path . '/' . $xml_ext_file)) { $xml_ext_file = (($dkey == 'softKeyFile') ? 'softkeydefault.xml' : 'dialplan.xml'); } - if (file_exists($templet_path . '/' . $xml_ext_file)) { + if (file_exists($template_path . '/' . $xml_ext_file)) { $xml_node->$dkey = $xml_ext_file; } else { $xml_node->$dkey = null; @@ -627,33 +678,40 @@ class xmlinterface $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"]); + case 'userlocale': + // Device language + $lang = $data_values['devlang']; + if (!empty($dev_config['devlang'])) { + $lang = $dev_config['devlang']; } - if (($key == 'networkLocaleInfo') || ($key == 'networkLocale')) { - $lang = (empty($hwlang[0])) ? $data_values['netlang'] : $hwlang[0]; + $xml_node->winCharSet = $dev_config['phonecodepage']; + $xml_node->name = $dev_config['devlang']; + $xml_node->langCode = 'en'; + if (isset($langCodeArray['devlang'])) { + $xml_node->langCode = $langCodeArray['devlang']; + } + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); + break; + case 'networklocale': + $lang = $data_values['netlang']; + if (!empty($dev_config['netlang'])) { + $lang = $dev_config['netlang']; + } + if (isset($lang)) { + $xml_work->$key = $lang; + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); } else { - $lang = (empty($hwlang[1])) ? $data_values['devlang'] : $hwlang[1]; + $xml_work->$key = ''; } - 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); - } - } + break; + case 'networklocaleinfo': + $lang = $data_values['netlang']; + if (!empty($dev_config['netlang'])) { + $lang = $dev_config['netlang']; + } + if (isset($lang)) { + $xml_node->name = $lang; + $this->replaceSimpleXmlNode($xml_work->$key, $xml_node); } else { $xml_work->$key = ''; } @@ -663,7 +721,7 @@ class xmlinterface } } - $xml_work->asXml($xml_name); // Save + \FreePBX::Sccp_manager()->saveXml($xml_work, $xml_name); // Save } else { die('Error Hardware template :' . $xml_template . ' not found'); } @@ -710,7 +768,7 @@ class xmlinterface $put_file = (string) $get_settings['idtemplate']; } } else { - $errors = array('Fields Dial Plan Name is requered !!'); + $errors = array('Fields Dial Plan Name is required !!'); } if (empty($errors)) { @@ -726,9 +784,9 @@ class xmlinterface { if (empty($config[$name])) { if ($name == 'default') { - $typeSoft = $confDir["tftp_templates"] . '/SIPDefaultSoftKey.xml_template'; + $typeSoft = $confDir["tftp_templates_path"] . '/SIPDefaultSoftKey.xml_template'; if (file_exists($typeSoft)) { - $file = $confDir["tftp_softkey"] . '/softkey' . $name . '.xml'; + $file = $confDir["tftp_softkey_path"] . '/softkey' . $name . '.xml'; if (!copy($typeSoft, $file)) { return array('error' => 'Access error' . $name); } @@ -741,7 +799,7 @@ class xmlinterface $errors = array(); $xmlstr = "\n"; $xmlstr .= "" . time() . "\n"; - $typeSoft = $confDir["tftp_templates"] . '/SIPTypeSoftKey.xml_template'; + $typeSoft = $confDir["tftp_templates_path"] . '/SIPTypeSoftKey.xml_template'; $read_soft = ""; if (file_exists($typeSoft)) { $f_read = fopen($typeSoft, 'r'); @@ -763,7 +821,7 @@ class xmlinterface $xmlstr .= ''; if (empty($errors)) { - $file = $confDir["tftp_softkey"] . '/softkey' . $name . '.xml'; + $file = $confDir["tftp_softkey_path"] . '/softkey' . $name . '.xml'; file_put_contents($file, $xmlstr); } diff --git a/sccpManTraits/ajaxHelper.php b/sccpManTraits/ajaxHelper.php index 33e2620..c7d7e05 100644 --- a/sccpManTraits/ajaxHelper.php +++ b/sccpManTraits/ajaxHelper.php @@ -21,6 +21,7 @@ trait ajaxHelper { case 'getUserGrid': case 'getSoftKey': case 'getDialTemplate': + case 'get_ext_files': case 'create_hw_tftp': case 'reset_dev': case 'reset_token': @@ -35,6 +36,9 @@ trait ajaxHelper { case 'delete_dialplan': return true; break; + case 'validateMac': + return true; + break; default: return false; } @@ -47,18 +51,13 @@ trait ajaxHelper { $cmd_id = $request['command']; switch ($cmd_id) { case 'savesettings': - $action = isset($request['sccp_createlangdir']) ? $request['sccp_createlangdir'] : ''; - if ($action == 'yes') { - $this->initializeTFtpLanguagePath(); - } + // Consolidate this into a separate method to improve legibility $this->handleSubmit($request); - // $this->saveSccpSettings(); - //$this->createDefaultSccpConfig(); - $this->createDefaultSccpXml(); + // TODO: Need to be more specific on reload and only reload if critical settings changed. $res = $this->aminterface->core_sccp_reload(); - $msg [] = 'Config Saved: ' . $res['Response']; - $msg [] = 'Info :' . $res['data']; + $msg [] = array ("Config Saved: {$res['Response']}", "Info : {$res['data']}"); + // !TODO!: It is necessary in the future to check, and replace all server responses on correct messages. Use _(msg) return array('status' => true, 'message' => $msg, 'reload' => true); break; @@ -66,7 +65,6 @@ trait ajaxHelper { case 'save_device': $this->saveSccpDevice($request); return array('status' => true, 'search' => '?display=sccp_phone', 'hash' => 'sccpdevice'); - break; case 'save_ruser': //$res = $request; @@ -117,7 +115,7 @@ trait ajaxHelper { } } else { $this->deleteSccpDeviceXML('all'); - $models = $this->dbinterface->HWextension_db_SccpTableData("SccpDevice"); + $models = $this->dbinterface->getSccpDeviceTableData("SccpDevice"); } $this->createDefaultSccpXml(); // Default XML @@ -258,7 +256,7 @@ trait ajaxHelper { if (!empty($request['id'])) { $id_name = preg_replace('/[^A-Za-z0-9]/', '', $request['id']); $this->sccp_conf_init[$id_name]['type'] = "softkeyset"; - foreach ($this->extconfigs->getextConfig('keyset') as $keyl => $vall) { + foreach ($this->extconfigs->getExtConfig('keyset') as $keyl => $vall) { if (!empty($request[$keyl])) { $this->sccp_conf_init[$id_name][$keyl] = $request[$keyl]; } @@ -278,7 +276,7 @@ trait ajaxHelper { foreach ($this->aminterface->sccp_list_keysets() as $keyl => $vall) { $result[$i]['softkeys'] = $keyl; if ($keyl == 'default') { - foreach ($this->extconfigs->getextConfig('keyset') as $key => $value) { + foreach ($this->extconfigs->getExtConfig('keyset') as $key => $value) { $result[$i][$key] = str_replace(',', '
    ', $value); } } else { @@ -292,68 +290,83 @@ trait ajaxHelper { return $result; break; case 'getExtensionGrid': - $result = $this->dbinterface->HWextension_db_SccpTableData('SccpExtension'); - if (empty($result)) { + $lineList = $this->dbinterface->getSccpDeviceTableData($request['type']); + if (empty($lineList)) { return array(); } - return $result; + $activeDevices = $this->aminterface->sccp_get_active_device(); + $uniqueLineList = array(); + foreach ($lineList as $key => &$lineArr) { + if (array_key_exists($lineArr['mac'], $activeDevices)) { + $lineArr['line_status'] = "{$activeDevices[$lineArr['mac']]['status']} | {$activeDevices[$lineArr['mac']]['act']}"; + } + if (array_key_exists($lineArr['name'], $uniqueLineList)) { + $lineList[$uniqueLineList[$lineArr['name']]]['mac'] .= '
    ' . $lineArr['mac']; + $lineList[$uniqueLineList[$lineArr['name']]]['line_status'] .= '
    ' . $lineArr['line_status']; + unset($lineList[$key]); // Drop this array as no longer used + continue; + } + $uniqueLineList[$lineArr['name']] = $key; + } + unset($lineArr, $uniqueLineList); // unset reference and temp vars. + return array_values($lineList); // Reindex array and return break; case 'getPhoneGrid': - $cmd_type = !empty($request['type']) ? $request['type'] : ''; + $dbDevices = array(); + // Find all devices defined in the database. + $dbDevices = $this->dbinterface->getSccpDeviceTableData('phoneGrid', array('type' => $request['type'])); - $result = $this->dbinterface->HWextension_db_SccpTableData('SccpDevice', array('type' => $cmd_type)); - if ($cmd_type == 'cisco-sip') { - return $result; + // Return if only interested in SIP devices + if ($request['type'] == 'cisco-sip') { + return $dbDevices; //this may be empty } - $staus = $this->aminterface->sccp_get_active_device(); - if (empty($result)) { - $result = array(); - } else { - foreach ($result as &$dev_id) { - $id_name = $dev_id['name']; - if (!empty($staus[$id_name])) { - $dev_id['description'] = $staus[$id_name]['descr']; - $dev_id['status'] = $staus[$id_name]['status']; - $dev_id['address'] = $staus[$id_name]['address']; - $dev_id['new_hw'] = 'N'; - $staus[$id_name]['news'] = 'N'; - } else { - $dev_id['description'] = '- -'; - $dev_id['status'] = 'not connected'; - $dev_id['address'] = '- -'; - } + // Find all devices currently connected + $activeDevices = $this->aminterface->sccp_get_active_device(); + + foreach ($dbDevices as &$dev_id) { + if (!empty($activeDevices[$dev_id['name']])) { + // Device is in db and is connected + $dev_id['description'] = $activeDevices[$dev_id['name']]['descr']; + $dev_id['status'] = $activeDevices[$dev_id['name']]['status']; + $dev_id['address'] = $activeDevices[$dev_id['name']]['address']; + $dev_id['new_hw'] = 'N'; + // No further action required on this active device + unset($activeDevices[$dev_id['name']]); } } - if (!empty($staus)) { - foreach ($staus as $dev_ids) { + unset($dev_id); // unset reference. + + if (!empty($activeDevices)) { + // Have a device that is connected but is not currently in the database + // This device must have connected via hotline or config in sccp.conf. + // Pass parameters to addDevice so that can be added to db. + foreach ($activeDevices as $dev_ids) { $id_name = $dev_ids['name']; - if (empty($dev_ids['news'])) { - $dev_data = $this->aminterface->sccp_getdevice_info($id_name); - if (!empty($dev_data['SCCP_Vendor']['model_id'])) { - $dev_addon = $dev_data['SCCP_Vendor']['model_addon']; - if (empty($dev_addon)) { - $dev_addon = null; - } - $dev_schema = $this->getSccpModelInformation('byciscoid', false, "all", array('model' => $dev_data['SCCP_Vendor']['model_id'])); - if (empty($dev_schema)) { - $dev_schema[0]['model'] = "ERROR in Model Schema"; - } - $result[] = array( - 'name' => $id_name, - 'mac' => $id_name, - 'button' => '---', - 'type' => $dev_schema[0]['model'], - 'new_hw' => 'Y', - 'description' => '*NEW* ' . $dev_ids['descr'], - 'status' => '*NEW* ' . $dev_ids['status'], - 'address' => $dev_ids['address'], - 'addon' => $dev_addon - ); + $dev_data = $this->aminterface->sccp_getdevice_info($id_name); + if (!empty($dev_data['SCCP_Vendor']['model_id'])) { + $dev_addon = $dev_data['SCCP_Vendor']['model_addon']; + if (empty($dev_addon)) { + $dev_addon = null; } + $dev_schema = $this->getSccpModelInformation('byciscoid', false, "all", array('model' => $dev_data['SCCP_Vendor']['model_id'])); + if (empty($dev_schema)) { + $dev_schema[0]['model'] = "ERROR in Model Schema"; + } + $dbDevices[] = array( + 'name' => $id_name, + 'mac' => $id_name, + 'button' => '---', + 'type' => $dev_schema[0]['model'], + 'new_hw' => 'Y', + 'description' => '*NEW* ' . $dev_ids['descr'], + 'status' => '*NEW* ' . $dev_ids['status'], + 'address' => $dev_ids['address'], + 'addon' => $dev_addon + ); } } } - return $result; + return $dbDevices; break; case 'getDialTemplate': // ------------------------------- Old device support - In the development--- @@ -378,8 +391,388 @@ trait ajaxHelper { // return array('status' => false, 'message' => $result); return $result; break; + case 'validateMac': + break; + case 'get_ext_files': + return $this->getFilesFromProvisioner($request); + break; } } + + function handleSubmit($request, $validateonly = false) { + $hdr_prefix = 'sccp_'; + $hdr_arprefix = 'sccp-ar_'; + $save_settings = array(); + $save_codec = array(); + $count_mods = 0; + $dbSaveArray = array(); + $errors = array(); + + if (isset($request["{$hdr_prefix}createlangdir"]) && ($request["{$hdr_prefix}createlangdir"] == 'yes')) { + $this->initializeTFtpLanguagePath(); + } + // if uncheck all codecs, audiocodecs key is missing so nothing changes in db. + // Unsetting all codecs will now return to chan-sccp defaults. + // all codecs are currently treated as audiocodecs. To treat videocodecs separately name in video codec section of + // server.codec needs to be changed from audiocodecs to videocodecs. + if (!isset($request['audiocodecs'])) { + $save_settings['allow'] = $this->sccpvalues['allow']; + $save_settings['allow']['data'] = $this->sccpvalues['allow']['systemdefault']; + } else { + foreach ($request['audiocodecs'] as $keycodeс => $dumVal) { + $save_codec[] = $keycodeс; + } + $save_settings['allow'] = $this->sccpvalues['allow']; + $save_settings['allow']['data'] = implode(";", $save_codec); + } + unset($request['audiocodecs']); + + if (isset($request[$hdr_prefix . 'ntp_timezone'])) { + $TZdata = $this->extconfigs->getExtConfig('sccp_timezone', $request[$hdr_prefix . 'ntp_timezone']); + if (!empty($TZdata)) { + $save_settings['tzoffset'] = array( + 'keyword' => 'tzoffset', + 'data' => $TZdata['offset']/60, + 'seq' => '98', + 'type' => '2', + 'systemdefault' => '' + ); + } + unset($request[$hdr_prefix . 'ntp_timezone']); + } + // Now handle remaining data. First get table defaults + $sccpdevice_def = (array)$this->getTableDefaults('sccpdevice', false); + $sccpline_def = (array)$this->getTableDefaults('sccpline', false); + + foreach ($request as $key => $value) { + // First handle any arrays as their prefix is part common with normal data + $key = (str_replace($hdr_arprefix, '', $key, $count_mods)); + if ($count_mods) { + $arr_data = ''; + if (!empty($this->sccpvalues[$key])) { + foreach ($value as $valArr) { + foreach ($valArr as $vkey => $vval) { + switch ($vkey) { + case 'inherit': + case 'internal': + if ($vval == 'on') { + $arr_data .= 'internal;'; + } + break; + case 'port': + $arr_data .= ":{$vval}"; + break; + case 'mask': + $arr_data .= "/{$vval}"; + break; + default: + $arr_data .= $vval; + break; + } + } + } + if (!($this->sccpvalues[$key]['data'] == $arr_data)) { + $save_settings[$key] = $this->sccpvalues[$key]; + $save_settings[$key]['data'] = $arr_data; + } + } + continue; + } + // Now handle any normal data - arrays will not match as already handled. + if (strpos($key, $hdr_prefix) === 0) { + $key = (str_replace($hdr_prefix, '', $key, $count_mods)); + if (($count_mods) && (!empty($this->sccpvalues[$key])) && ($this->sccpvalues[$key]['data'] != $value)) { + $save_settings[$key] = $this->sccpvalues[$key]; + $save_settings[$key]['data'] = $value; + } + continue; + } + // Finally treat values to be saved to sccpdevice and sccpline defaults. + // TODO: Need to verify the tables defined in showGroup - some options maybe + // device options, but if set by freePbx extensions, be in sccpline. + foreach (array('sccpdevice', 'sccpline') as $tableName) { + $key = (str_replace("{$tableName}_", '', $key, $count_mods)); + if ($count_mods) { + // Have default to be saved to db table default + $tableName_def = "{$tableName}_def"; + if ((array_key_exists($key, ${$tableName_def})) && (${$tableName_def}[$key]['data'] == $value)) { + // Value unchanged so ignore + } else { + $dbSaveArray[$key] = array('table' => $tableName, 'field' => $key, 'Default' => $value); + } + // If have matched on device, cannot match on line + continue 2; + } + } + } + + $extSettings = $this->extconfigs->updateTftpStructure(array_merge($this->sccpvalues, $save_settings)); + $save_settings = array_merge($save_settings, $extSettings); + if (!empty($save_settings)) { + $this->saveSccpSettings($save_settings); + $this->sccpvalues = $this->dbinterface->get_db_SccpSetting(); + } + + foreach ($dbSaveArray as $key => $rowToSave) { + $this->dbinterface->updateTableDefaults($rowToSave['table'], $rowToSave['field'], $rowToSave['Default']); + } + + $this->createDefaultSccpConfig(); // Rewrite Config. + $save_settings[] = array('status' => true, ); + $this->createDefaultSccpXml(); + + return $save_settings; + } + + public function getMyConfig($var = null, $id = "noid") { + // TODO: this function has little purpose - need to integrate into AjaxHelper + switch ($var) { + case "softkeyset": + $final = array(); + $i = 0; + if ($id == "noid") { + foreach ($this->sccp_conf_init as $key => $value) { + if ($this->sccp_conf_init[$key]['type'] == 'softkeyset') { + $final[$i] = $value; + $i++; + } + } + } else { + if (!empty($this->sccp_conf_init[$id])) { + if ($this->sccp_conf_init[$id]['type'] == 'softkeyset') { + $final = $this->sccp_conf_init[$id]; + } + } + } + + break; + } + return $final; + } + + public function getFilesFromProvisioner($request) { + $filesToGet = array(); + $totalFiles = 0; + $provisionerUrl = "https://github.com/dkgroot/provision_sccp/raw/master/"; + if (!file_exists("{$this->sccppath['tftp_path']}/masterFilesStructure.xml")) { + if (!$this->getFileListFromProvisioner()) { + return array('status' => false, + 'message' => "{$provisionerUrl}tools/tftpbootFiles.xml cannot be found. Check your internet connection, and that this path exists", + 'reload' => false); + } + } + $tftpBootXml = simplexml_load_file("{$this->sccppath['tftp_path']}/masterFilesStructure.xml"); + + switch ($request['type']) { + case 'firmware': + $device = $request['device']; + $firmwareDir = $tftpBootXml->xpath("//Directory[@name='firmware']"); + $result = $firmwareDir[0]->xpath("//Directory[@name='{$device}']"); + $filesToGet['firmware'] = (array)$result[0]->FileName; + $totalFiles += count($filesToGet['firmware']); + $srcDir['firmware'] = $provisionerUrl . (string)$result[0]->DirectoryPath; + $dstDir['firmware'] = "{$this->sccppath['tftp_firmware_path']}/{$device}"; + + $msg = "Firmware for {$device} has been successfully downloaded"; + break; + case 'locale': + $language = $request['locale']; + // Get locales + $localeDir = $tftpBootXml->xpath("//Directory[@name='languages']"); + $result = $localeDir[0]->xpath("//Directory[@name='{$language}']"); + $filesToGet['language'] = (array)$result[0]->FileName; + $totalFiles += count($filesToGet['language']); + $srcDir['language'] = $provisionerUrl . (string)$result[0]->DirectoryPath; + $dstDir['language'] = "{$this->sccppath['tftp_lang_path']}/{$language}"; + + // Get countries. Country is a substring of locale with exception of korea + $country = explode('_', $language); + array_shift($country); + $countryName = array_shift($country); + while (count($country)>=1) { + $countryName .= '_' . array_shift($country); + } + $msg = "{$language} Locale and Country tones have been successfully downloaded"; + //fall through intentionally to also get country files + + case 'country': + if ($totalFiles == 0) { + //Request is for countries; if >0, have fallen through from locale + $countryName = $request['country']; + $msg = "{$countryName} country tones have been successfully downloaded"; + } + + $result = $tftpBootXml->xpath("//Directory[@name='{$countryName}']"); + $filesToGet['country'] = (array)$result[0]->FileName; + $totalFiles += count($filesToGet['country']); + $srcDir['country'] = $provisionerUrl . (string)$result[0]->DirectoryPath; + $dstDir['country'] = "{$this->sccppath['tftp_countries_path']}/{$countryName}"; + break; + default: + return array('status' => false, 'message' => 'Invalid request', 'reload' => false); + break; + } + // Now get the files + $filesRetrieved = 0; + foreach (array('language','country', 'firmware') as $section){ + if (!isset($dstDir[$section])) { + // No request for this section + continue; + } + $srcDir = $srcDir[$section]; + $dstDir = $dstDir[$section]; + if (!is_dir($dstDir)) { + mkdir($dstDir, 0755); + } + foreach ($filesToGet[$section] as $srcFile) { + try { + file_put_contents("{$dstDir}/{$srcFile}", + file_get_contents($srcDir. $srcFile)); + } catch (\Exception $e) { + return array('status' => false, + 'message' => "{$countriesSrcDir}{$srcFile} cannot be found. Check your internet connection, and that this path exists", + 'reload' => false); + } + $filesRetrieved ++; + $percentComplete = $filesRetrieved *100 / $totalFiles; + $data = "{$percentComplete},"; + echo $data; + ob_flush(); + flush(); + } + } + + return array('status' => true, 'message' => $msg, 'reload' => true); + } + + function saveSccpDevice($get_settings, $validateonly = false) { + $hdr_prefix = 'sccp_hw_'; + $hdr_arprefix = 'sccp_hw-ar_'; + $hdr_vendPrefix = 'vendorconfig_'; + + $save_buttons = array(); + $save_settings = array(); + $save_codec = array(); + $name_dev = ''; + $db_field = array_keys($this->dbinterface->getSccpDeviceTableData("get_columns_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') ? 'add' : 'clear'; // Clear is delete + add + $hw_prefix = 'SEP'; + if (!empty($get_settings[$hdr_prefix . 'type'])) { + $value = $get_settings[$hdr_prefix . 'type']; + if (strpos($value, 'ATA') !== false) { + $hw_prefix = 'ATA'; + } + if (strpos($value, 'VG') !== false) { + $hw_prefix = 'VG'; + } + } + foreach ($db_field as $key) { + $value = ""; + switch ($key) { + case 'name': + if (!empty($get_settings[$hdr_prefix . 'mac'])) { + $value = $get_settings[$hdr_prefix . 'mac']; + $value = strtoupper(str_replace(array('.', '-', ':'), '', $value)); // Delete mac separators from string + $value = sprintf("%012s", $value); + if ($hw_prefix == 'VG') { + $value = $hw_prefix . $value . '0'; + } else { + $value = $hw_prefix . $value; + } + $name_dev = $value; + } + break; + case 'phonecodepage': + // TODO: May be other exceptions so use switch. Historically this is the only one handled + if (!empty($get_settings["{$hdr_prefix}devlang"])) { + switch ($get_settings["{$hdr_prefix}devlang"]) { + case 'Russian_Russian_Federation': + $value = 'CP1251'; + break; + default: + $value = 'ISO8859-1'; + break; + } + } + break; + default: + // handle vendor prefix + if (!empty($get_settings[$hdr_vendPrefix . $key])) { + $value = $get_settings[$hdr_vendPrefix . $key]; + } + // handle array prefix + 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; + // Злобный ХАК ?!TODO!? + 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; + } + } + // Now only have normal prefix + if (!empty($get_settings["{$hdr_prefix}{$key}"])) { + $value = $get_settings["{$hdr_prefix}{$key}"]; + } + } + if (!empty($value)) { + $save_settings[$key] = $value; + } + } + // Save this device. + $this->dbinterface->write('sccpdevice', $save_settings, 'replace'); + // Retrieve the phone buttons from $_REQUEST ($get_settings) and write back to + // update sccpdeviceconfig via Trigger + $save_buttons = $this->getPhoneButtons($get_settings, $name_dev, $hw_type); + $this->dbinterface->write('sccpbuttons', $save_buttons, $update_hw, '', $name_dev); + // Create new XML for this device, and then reset or restart the device + // so that it loads the file from TFT. + $this->createSccpDeviceXML($name_dev); + if ($hw_id == 'new') { + $this->aminterface->sccpDeviceReset($name_dev, 'reset'); + } else { + $this->aminterface->sccpDeviceReset($name_dev, 'restart'); + } + $msg = "Device Saved"; + + return array('status' => true, 'message' => $msg, 'reload' => true); + } + } ?> diff --git a/sccpManTraits/bmoFunctions.php b/sccpManTraits/bmoFunctions.php index 1bd6817..633ad4f 100644 --- a/sccpManTraits/bmoFunctions.php +++ b/sccpManTraits/bmoFunctions.php @@ -5,11 +5,12 @@ namespace FreePBX\modules\Sccp_manager\sccpManTraits; trait bmoFunctions { //Need to reload freePBX for modifications below to work - +/* //want to catch extensions public static function myConfigPageInits() { return array("extensions"); } +*/ public function doConfigPageInit($page) { if ($page == "extensions") { @@ -18,25 +19,27 @@ trait bmoFunctions { } // Try to change extensions which is part of core +/* public static function myGuiHooks() { return array('core'); } - +*/ +/* public function doGuiHook(&$cc) { if ($_REQUEST['display'] == "extensions" ) { if ($_REQUEST['tech_hardware'] == 'sccp_custom') { - /* + this is the add extensions form On submit returns to extensions page. Users prefer that it returns To Sccp Phone. Below adds redirect URL, but it is not followed $cc->setRedirectURL("config.php?display=sccp_phone"); so force redirect at end of addDevice in SccpClass - */ + } } } - +*/ /* unused but FPBX API requires it */ public function install() { @@ -115,6 +118,7 @@ trait bmoFunctions { ); break; case 'sccpsettings': + // TODO: Need to change to have save and save and continue $buttons = array( 'submit' => array( 'name' => 'ajaxsubmit', @@ -134,8 +138,9 @@ trait bmoFunctions { } public function getRightNav($request) { + global $amp_conf; if (isset($request['tech_hardware']) && ($request['tech_hardware'] == 'cisco')) { - return load_view($_SERVER['DOCUMENT_ROOT'] .'/admin/modules/sccp_manager/views/hardware.rnav.php', array('request' => $request)); + return load_view($amp_conf['AMPWEBROOT'] .'/admin/modules/sccp_manager/views/hardware.rnav.php', array('request' => $request)); } } diff --git a/sccpManTraits/helperFunctions.php b/sccpManTraits/helperFunctions.php index 4441e46..e6fa71b 100644 --- a/sccpManTraits/helperFunctions.php +++ b/sccpManTraits/helperFunctions.php @@ -69,56 +69,251 @@ trait helperfunctions { } return FALSE; } + private function getTableDefaults($table, $trim_underscore = true) { + $def_val = array(); + // TODO: This is ugly and overkill - needs to be cleaned up in dbinterface + if ($table == 'sccpsettings') { + // sccpsettings has a different structure and already have values in $sccpvalues + return $this->sccpvalues; + } + $sccpTableDesc = $this->dbinterface->getSccpDeviceTableData("get_columns_{$table}"); + foreach ($sccpTableDesc as $key => $data) { + // function has 2 roles: return actual table keys (trim_underscore = false) + // return sanitised keys to add defaults (trim_underscore = true) + if ($trim_underscore) { + // Remove any leading (or trailing but should be none) underscore + // These are only used to hide fields from chan-sccp for compatibility + $key = trim($key,'_'); + } + $def_val[$key] = array("keyword" => $key, "data" => $data['Default'], "seq" => "99"); + } + return $def_val; + } - private function findAllFiles($dir, $file_mask = null, $mode = 'full') { - $result = null; - if (empty($dir) || (!file_exists($dir))) { + private function getTableEnums($table, $trim_underscore = true) { + $enumFields = array(); + $sccpTableDesc = $this->dbinterface->getSccpDeviceTableData("get_columns_{$table}"); + foreach ($sccpTableDesc as $key => $data) { + // function has 2 roles: return actual table keys (trim_underscore = false) + // return sanitised keys to add defaults (trim_underscore = true) + if ($trim_underscore) { + // Remove any leading (or trailing but should be none) underscore + // These are only used to hide fields from chan-sccp for compatibility + $key = trim($key,'_'); + } + $typeArray = explode('(', $data['Type']); + if ($typeArray[0] == 'enum') { + $enumOptions = explode(',', trim($typeArray[1],')')); + $enumFields[$key] = $enumOptions; + } + } + return $enumFields; + } + + private function findAllFiles($searchDir, $file_mask = array(), $mode = 'full') { + $result = array(); + if (!is_dir($searchDir)) { return $result; } - - $root = scandir($dir); - foreach ($root as $value) { - if ($value === '.' || $value === '..') { - continue; - } - if (is_file("$dir/$value")) { - $filter = false; + foreach (array_diff(scandir($searchDir),array('.', '..')) as $value) { + if (is_file("$searchDir/$value")) { + $extFound = ''; + $foundFile = true; if (!empty($file_mask)) { - if (is_array($file_mask)) { - foreach ($file_mask as $k) { - if (strpos(strtolower($value), strtolower($k)) !== false) { - $filter = true; - } - } - } else { - if (strpos(strtolower($value), strtolower($file_mask)) !== false) { - $filter = true; + $foundFile = false; + foreach ($file_mask as $k) { + if (strpos($value, $k) !== false) { + $foundFile = true; + $extFound = $k; + break; } } - } else { - $filter = true; } - if ($filter) { - if ($mode == 'fileonly') { - $result[] = "$value"; - } else { - $result[] = "$dir/$value"; + if ($foundFile) { + switch ($mode) { + case 'fileonly': + $result[] = $value; + break; + case 'fileBaseName': + $result[] = basename("/$value", $extFound); + break; + case 'dirFileBaseName': + $result[] = $searchDir . "/" . basename("/$value", $extFound); + break; + default: + $result[] = "$searchDir/$value"; + break; } - } else { - $result[] = null; } continue; } - $sub_fiend = $this->findAllFiles("$dir/$value", $file_mask, $mode); - if (!empty($sub_fiend)) { - foreach ($sub_fiend as $sub_value) { - if (!empty($sub_value)) { - $result[] = $sub_value; - } + // Now iterate over sub directories + $sub_find = $this->findAllFiles("$searchDir/$value", $file_mask, $mode); + if (!empty($sub_find)) { + foreach ($sub_find as $sub_value) { + $result[] = $sub_value; } } } return $result; } + + function is_assoc($array) { + foreach (array_keys($array) as $k => $v) { + if ($k !== $v) + return true; + } + return false; + } + + function tftpReadTestFile($remoteFileName, $host = "127.0.0.1") + { + // https://datatracker.ietf.org/doc/html/rfc1350 + $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + // Set timeout so that do not hang if no data received. + socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array('sec'=>1, 'usec'=>0)); + + if ($socket) { + $port = 69; // Initial TFTP port. Changed in received packet. + + // create the RRQ request packet + $packet = chr(0) . chr(1) . $remoteFileName . chr(0) . 'netascii' . chr(0); + // UDP is connectionless, so we just send it. + socket_sendto($socket, $packet, strlen($packet), MSG_EOR, $host, $port); + + $buffer = null; + $port = ""; + $ret = ""; + // MSG_WAITALL is blocking but socket has timeout set to 1 sec. + $numbytes = socket_recvfrom($socket, $buffer, 84, MSG_WAITALL, $host, $port); + + if ($numbytes < 2) { + // socket has timed out before data received. + return false; + } + // unpack the returned buffer and discard the first two bytes. + $pkt = unpack("nopcode/nblockno/a*data", $buffer); + + // send ack and close socket. + $packet = chr(4) . chr($pkt["blockno"]); + socket_sendto($socket, $packet, strlen($packet), MSG_EOR, $host, $port); + + socket_close($socket); + + if ($pkt["opcode"] == 3 && $numbytes) { + return $pkt["data"]; + } + } + return false; + } + + public function checkTftpMapping(){ + exec('in.tftpd -V', $tftpInfo); + $info['TFTP Server'] = array('Version' => 'Not Found', 'about' => 'Mapping not available'); + + if (isset($tftpInfo[0])) { + $tftpInfo = explode(',',$tftpInfo[0]); + $info['TFTP Server'] = array('Version' => $tftpInfo[0], 'about' => 'Mapping not available'); + $tftpInfo[1] = trim($tftpInfo[1]); + $this->sccpvalues['tftp_rewrite']['data'] = 'off'; + if ($tftpInfo[1] == 'with remap') { + $info['TFTP Server'] = array('Version' => $tftpInfo[0], 'about' => $tftpInfo[1]); + + $remoteFileName = ".sccp_manager_remap_probe_sentinel_temp".mt_rand(0, 9999999).".tlzz"; + $remoteFileContent = "# This is a test file created by Sccp_Manager. It can be deleted without impact"; + $testFtpDir = "{$this->sccpvalues['tftp_path']['data']}/settings"; + + // write a sentinel to a tftp subdirectory to see if mapping is working + + if (is_dir($testFtpDir) && is_writable($testFtpDir)) { + $tempFile = "${testFtpDir}/{$remoteFileName}"; + file_put_contents($tempFile, $remoteFileContent); + // try to pull the written file through tftp. + // this way we can determine if mapping is active and using sccp_manager maps + if ($remoteFileContent == $this->tftpReadTestFile($remoteFileName)) { + //found the file and contents are correct + $this->sccpvalues['tftp_rewrite']['data'] = 'pro'; + } else { + // Did not find sentinel so mapping not available + $this->sccpvalues['tftp_rewrite']['data'] = 'off'; + } + unlink($tempFile); + } + return true; + } + } + return false; + } + // helper function to save xml with proper indentation + public function saveXml($xml, $filename) { + $dom = new \DOMDocument("1.0"); + $dom->preserveWhiteSpace = false; + $dom->formatOutput = true; + $dom->loadXML($xml->asXML()); + $dom->save($filename); + } + + public function getFileListFromProvisioner() { + + $provisionerUrl = "https://github.com/dkgroot/provision_sccp/raw/master/"; + // Get master tftpboot directory structure + try { + file_put_contents("{$this->sccppath['tftp_path']}/masterFilesStructure.xml",file_get_contents("{$provisionerUrl}tools/tftpbootFiles.xml")); + } catch (\Exception $e) { + return false; + } + return true; + } + + public function initVarfromXml() { + if ((array) $this->xml_data) { + foreach ($this->xml_data->xpath('//page_group') as $item) { + foreach ($item->children() as $child) { + $seq = 0; + if (!empty($child['seq'])) { + $seq = (string) $child['seq']; + } + if ($seq < 99) { + if ($child['type'] == 'IE') { + foreach ($child->xpath('input') as $value) { + $tp = 0; + if (empty($value->value)) { + $datav = (string) $value->default; + } else { + $datav = (string) $value->value; + } + if (strtolower($value->type) == 'number') { + $tp = 1; + } + if (empty($this->sccpvalues[(string) $value->name])) { + $this->sccpvalues[(string) $value->name] = array('keyword' => (string) $value->name, 'data' => $datav, 'type' => $tp, 'seq' => $seq, 'systemdefault' => ''); + } + } + } + if ($child['type'] == 'IS' || $child['type'] == 'IED') { + if (empty($child->value)) { + $datav = (string) $child->default; + } else { + $datav = (string) $child->value; + } + if (empty($this->sccpvalues[(string) $child->name])) { + $this->sccpvalues[(string) $child->name] = array('keyword' => (string) $child->name, 'data' => $datav, 'type' => '2', 'seq' => $seq, 'systemdefault' => ''); + } + } + if (in_array($child['type'], array('SLD', 'SLS', 'SLT', 'SLNA', 'SLDA', 'SL', 'SLM', 'SLZ', 'SLTZN', 'SLA'))) { + if (empty($child->value)) { + $datav = (string) $child->default; + } else { + $datav = (string) $child->value; + } + if (empty($this->sccpvalues[(string) $child->name])) { + $this->sccpvalues[(string) $child->name] = array('keyword' => (string) $child->name, 'data' => $datav, 'type' => '2', 'seq' => $seq, 'systemdefault' => ''); + } + } + } + } + } + } + } } ?> diff --git a/views/advserver.keyset.php b/views/advserver.keyset.php index 6228047..6d610d7 100644 --- a/views/advserver.keyset.php +++ b/views/advserver.keyset.php @@ -8,7 +8,7 @@ $keymultiselect = array('AllRight' =>'>>', 'Right' => '>', 'AllLeft' => '<<', 'Left' => '<'); // ------------------------------------- Key Set Value --------------------------------------------------------- -$keysetarray = $this->extconfigs->getextConfig('keyset'); +$keysetarray = $this->extconfigs->getExtConfig('keyset'); /*$keysetarray1 = array('onhook' => array('redial','newcall','cfwdall','dnd','pickup','gpickup','private'), 'connected' => array('hold','endcall','park','vidmode','select','cfwdall','cfwdbusy','idivert'), diff --git a/views/advserver.model.php b/views/advserver.model.php index 22f6f4a..081cebb 100644 --- a/views/advserver.model.php +++ b/views/advserver.model.php @@ -4,7 +4,8 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ - +$requestType = 'firmware'; +global $amp_conf; ?>
    @@ -32,6 +33,8 @@
  • + @@ -42,9 +45,9 @@ - + - + @@ -61,7 +64,7 @@
    +
    - - + + diff --git a/views/hardware.phone.php b/views/hardware.phone.php index a18f259..6f24829 100644 --- a/views/hardware.phone.php +++ b/views/hardware.phone.php @@ -31,12 +31,15 @@ -
    +
    - - + + diff --git a/views/hardware.sphone.php b/views/hardware.sphone.php index 7d5094a..c1321a7 100644 --- a/views/hardware.sphone.php +++ b/views/hardware.sphone.php @@ -29,7 +29,7 @@ - + diff --git a/views/server.advanced.php b/views/server.advanced.php index 61cf630..b1b09f9 100644 --- a/views/server.advanced.php +++ b/views/server.advanced.php @@ -12,9 +12,12 @@ getTableDefaults('sccpdevice', true); + echo $this->showGroup('sccp_srst', 1); - echo $this->showGroup('sccp_dev_vendor_conf', 1); -// echo $this->showGroup('sccp_dev_time',1); + echo $this->showGroup('sccp_dev_vendor_conf', 1, 'sccpdevice', $defaultVals); ?> diff --git a/views/server.codec.php b/views/server.codec.php index ff543f4..89b2a86 100644 --- a/views/server.codec.php +++ b/views/server.codec.php @@ -6,39 +6,19 @@ * and open the template in the editor. */ - $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; +$audio_codecs = $this->getCodecs('audio'); +$video_codecs = $this->getCodecs('video'); +$sccp_disallow_def = $this->sccpvalues['disallow']['data']; +$sys_disallow_def = $this->sccpvalues['disallow']['systemdefault']; -if (!empty($_REQUEST['id'])) { - $dev_id = $_REQUEST['id']; - $db_res = $this->dbinterface->HWextension_db_SccpTableData('get_sccpdevice_byid', array("id" => $dev_id)); - if (!empty($db_res['allow'])) { - $i = 1; - foreach (explode(';', $db_res['allow']) as $c) { - $codec_list[$c] = $i; - $i ++; - } - foreach ($sccp_codec as $c => $v) { - if (!isset($codec_list[$c])) { - $codec_list[$c] = false; - } - } - } - if (!empty($db_res['disallow'])) { - $sccp_disalow = $db_res['disallow']; - } -} else { - $codec_list = $sccp_codec; +if (empty($sccp_disallow_def)) { + $sccp_disallow_def = $sys_disallow_def; } - ?> - + @@ -55,8 +35,8 @@ if (!empty($_REQUEST['id'])) {
    - - + +
    @@ -64,7 +44,7 @@ if (!empty($_REQUEST['id'])) {
    - +
    @@ -89,20 +69,25 @@ if (!empty($_REQUEST['id'])) {
    - + Order can be changed by dragging and dropping to indicate priority. This priority applies for all extensions +
    Higher priority enabled codecs are at the top +
    Precedence for ulaw and alaw, if used, should be set according to your region +
    If your region uses alaw, it is important that alaw has the highest priority +
    To return to chan-sccp defaults, uncheck ALL codecs (both Audio and Video)."),"Helpful information",true) ?>
    '; - foreach ($codec_list as $codec => $codec_state) { + foreach ($audio_codecs as $codec => $codec_state) { $codec_trans = _($codec); $codec_checked = $codec_state ? 'checked' : ''; echo '
  • ' . 'move ' . '
    - +
    '; + // Although classed as video codecs, all stored under allow so name is audiocodecs. foreach ($video_codecs as $codec => $codec_state) { $codec_trans = _($codec); $codec_checked = $codec_state ? 'checked' : ''; @@ -153,9 +139,9 @@ if (!empty($_REQUEST['id'])) { . 'move ' . '' . '  
  • getTableDefaults('sccpdevice'); + echo $this->showGroup('sccp_general', 1); echo $this->showGroup('sccp_dev_time_s', 1); echo $this->showGroup('sccp_net', 1); echo $this->showGroup('sccp_lang', 1); - echo $this->showGroup('sccp_qos_config', 1); echo $this->showGroup('sccp_extpath_config', 1); - - ?> + + ?> @@ -39,21 +40,20 @@ + + - diff --git a/views/server.url.php b/views/server.url.php index ceb8a1f..79cc7ec 100644 --- a/views/server.url.php +++ b/views/server.url.php @@ -9,6 +9,6 @@ showGroup('sccp_dev_url', 1); -?> + echo $this->showGroup('sccp_dev_url', 1,); +?>