From c19cd89bc509416e232ea487f0a3e1e7209c60e9 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Mon, 24 Aug 2015 10:34:33 +0400 Subject: [PATCH 1/6] Fix. Delete some keys from memcache --- app/call_centers/call_center_queue_delete.php | 2 +- app/call_centers/call_center_queue_edit.php | 2 +- app/call_flows/call_flow_edit.php | 2 +- app/calls/call_edit.php | 5 ++++- app/calls/resources/classes/call_forward.php | 10 ++++++---- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/call_centers/call_center_queue_delete.php b/app/call_centers/call_center_queue_delete.php index edcf624951..bad7ad96cc 100644 --- a/app/call_centers/call_center_queue_delete.php +++ b/app/call_centers/call_center_queue_delete.php @@ -86,7 +86,7 @@ if (strlen($id) > 0) { //clear the cache $cache = new cache; - $cache->delete("memcache delete dialplan:".$_SESSION["context"]); + $cache->delete("dialplan:".$_SESSION["context"]); //synchronize configuration save_dialplan_xml(); diff --git a/app/call_centers/call_center_queue_edit.php b/app/call_centers/call_center_queue_edit.php index 77ab53a661..05f82c1580 100644 --- a/app/call_centers/call_center_queue_edit.php +++ b/app/call_centers/call_center_queue_edit.php @@ -329,7 +329,7 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { //clear the cache $cache = new cache; - $cache->delete("memcache delete dialplan:".$_SESSION["context"]); + $cache->delete("dialplan:".$_SESSION["context"]); //set the update message $_SESSION["message"] = $text['message-update']; diff --git a/app/call_flows/call_flow_edit.php b/app/call_flows/call_flow_edit.php index 254601b5d8..1380c69912 100644 --- a/app/call_flows/call_flow_edit.php +++ b/app/call_flows/call_flow_edit.php @@ -337,7 +337,7 @@ if (count($_POST) > 0 && strlen($_POST["persistformvar"]) == 0) { //clear the cache $cache = new cache; - $cache->delete("memcache delete dialplan:".$call_flow_context); + $cache->delete("dialplan:".$call_flow_context); //set the message if ($action == "add") { diff --git a/app/calls/call_edit.php b/app/calls/call_edit.php index 85e26d0ad9..b9b149b954 100644 --- a/app/calls/call_edit.php +++ b/app/calls/call_edit.php @@ -379,7 +379,10 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { //clear the cache $cache = new cache; - $cache->delete("memcache delete directory:".$extension."@".$_SESSION['domain_name']); + $cache->delete("directory:".$extension."@".$_SESSION['domain_name']); + if(strlen($number_alias) > 0){ + $cache->delete("directory:".$number_alias."@".$_SESSION['domain_name']); + } //redirect the user $_SESSION["message"] = $text['confirm-update']; diff --git a/app/calls/resources/classes/call_forward.php b/app/calls/resources/classes/call_forward.php index 9b7fe294f7..74688572ed 100644 --- a/app/calls/resources/classes/call_forward.php +++ b/app/calls/resources/classes/call_forward.php @@ -35,6 +35,7 @@ include "root.php"; public $domain_name; public $extension_uuid; private $extension; + private $number_alias; public $forward_all_destination; public $forward_all_enabled; private $dial_string; @@ -58,6 +59,7 @@ include "root.php"; if (count($result) > 0) { foreach ($result as &$row) { $this->extension = $row["extension"]; + $this->number_alias = $row["number_alias"]; $this->accountcode = $row["accountcode"]; $this->toll_allow = $row["toll_allow"]; $this->outbound_caller_id_name = $row["outbound_caller_id_name"]; @@ -155,10 +157,10 @@ include "root.php"; unset($sql); //delete extension from memcache - $fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']); - if ($fp) { - $switch_cmd = "memcache delete directory:".$this->extension."@".$this->domain_name; - $switch_result = event_socket_request($fp, 'api '.$switch_cmd); + $cache = new cache; + $cache->delete("directory:".$this->extension."@".$this->domain_name); + if(strlen($this->number_alias) > 0){ + $cache->delete("directory:".$this->number_alias."@".$this->domain_name); } } //function From 50d52a2c6288b5de34c101ac67eab80c95710a68 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Tue, 25 Aug 2015 14:14:28 +0400 Subject: [PATCH 2/6] Fix. Parse ESL response more accurate. Problem with commands that do not return Content (e.g. sendevent) In this case `event_socket_request` go to busy wait cycle without chance to success. On my system it require alot process time and may take >30 sec to save one extension. --- resources/classes/EventSocket.php | 196 ++++++++++++++++++++++++++++++ resources/switch.php | 84 +++---------- 2 files changed, 213 insertions(+), 67 deletions(-) create mode 100644 resources/classes/EventSocket.php diff --git a/resources/classes/EventSocket.php b/resources/classes/EventSocket.php new file mode 100644 index 0000000000..0f4bb239fd --- /dev/null +++ b/resources/classes/EventSocket.php @@ -0,0 +1,196 @@ +content = ''; + $this->eol = "\n"; + } + + public function append($str) { + $this->content .= $str; + } + + public function read_line() { + $ar = explode($this->eol, $this->content, 2); + if (count($ar) != 2) { + return false; + } + $this->content = $ar[1]; + return $ar[0]; + } + + public function read_n($n) { + if (strlen($this->content) < $n) { + return false; + } + $s = substr($this->content, 0, $n); + $this->content = substr($this->content, $n); + return $s; + } + + public function read_all($n) { + $tmp = $this->content; + $this->content = ''; + return $tmp; + } +} + +//$b = new Buffer; +//$b->append("hello\nworld\n"); +//print($b->read_line()); +//print($b->read_line()); + +class EventSocket { + private $buffer; + private $fp; + + public function __construct($fp = false) { + $this->buffer = new Buffer; + $this->fp = $fp; + } + + public function __destructor() { + $this->close(); + } + + public function read_event() { + if (!$this->fp) { + return false; + } + + $b = $this->buffer; + $content_length = 0; + $content = Array(); + + while (true) { + while(($line = $b->read_line()) !== false ) { + if ($line == '') { + break 2; + } + $kv = explode(':', $line, 2); + $content[trim($kv[0])] = trim($kv[1]); + } + usleep(100); + + if (feof($this->fp)) { + break; + } + + $buffer = fgets($this->fp, 1024); + $b->append($buffer); + } + + if (array_key_exists('Content-Length', $content)) { + $str = $b->read_n($content['Content-Length']); + if ($str === false) { + while (!feof($this->fp)) { + $buffer = fgets($this->fp, 1024); + $b->append($buffer); + $str = $b->read_n($content['Content-Length']); + if ($str !== false) { + break; + } + } + } + if ($str !== false) { + $content['$'] = $str; + } + } + + return $content; + } + + public function connect($host, $port, $password) { + $fp = fsockopen($host, $port, $errno, $errdesc, 3); + + if (!$fp) { + return false; + } + + socket_set_blocking($fp, false); + $this->fp = $fp; + + // Wait auth request and send response + while (!feof($fp)) { + $event = $this->read_event(); + if(@$event['Content-Type'] == 'auth/request'){ + fputs($fp, "auth $password\n\n"); + break; + } + } + + // Wait auth response + while (!feof($fp)) { + $event = $this->read_event(); + if (@$event['Content-Type'] == 'command/reply') { + if (@$event['Reply-Text'] == '+OK accepted') { + return $fp; + } + $this->fp = false; + fclose($fp); + return false; + } + } + + return false; + } + + public function request($cmd) { + if (!$this->fp) { + return false; + } + + $cmd_array = explode("\n", $cmd); + foreach ($cmd_array as &$value) { + fputs($this->fp, $value."\n"); + } + fputs($this->fp, "\n"); //second line feed to end the headers + + $event = $this->read_event(); + + if (array_key_exists('$', $event)) { + return $event['$']; + } + return $event; + } + + public function reset_fp($fp = false){ + $tmp = $this->fp; + $this->fp = $fp; + return $tmp; + } + + public function close() { + if ($this->fp) { + fclose($fp); + $this->fp = false; + } + } +} + +/* +function event_socket_create($host, $port, $password) { + $esl = new EventSocket; + if ($esl->connect($host, $port, $password)) { + return $esl->reset_fp(); + } + return false; +} + +function event_socket_request($fp, $cmd) { + $esl = new EventSocket($fp); + $result = $esl->request($cmd); + $esl->reset_fp(); + return $result; +} +*/ + +// $esl = new EventSocket; +// $esl->connect('127.0.0.1', 8021, 'ClueCon'); +// print($esl->request('api sofia status')); + +// $fp = event_socket_create('127.0.0.1', 8021, 'ClueCon'); +// print(event_socket_request($fp, 'api sofia status')); diff --git a/resources/switch.php b/resources/switch.php index 753639d677..ff873d1ca7 100644 --- a/resources/switch.php +++ b/resources/switch.php @@ -110,76 +110,22 @@ function load_extensions() { load_extensions(); function event_socket_create($host, $port, $password) { - $fp = fsockopen($host, $port, $errno, $errdesc, 3); - socket_set_blocking($fp,false); - - if (!$fp) { - //error "invalid handle
\n"; - //echo "error number: ".$errno."
\n"; - //echo "error description: ".$errdesc."
\n"; + $esl = new EventSocket; + if ($esl->connect($host, $port, $password)) { + return $esl->reset_fp(); } - else { - //connected to the socket return the handle - while (!feof($fp)) { - $buffer = fgets($fp, 1024); - usleep(100); //allow time for reponse - if (trim($buffer) == "Content-Type: auth/request") { - fputs($fp, "auth $password\n\n"); - break; - } - } - return $fp; - } -} //end function + return false; +} function event_socket_request($fp, $cmd) { - if ($fp) { - $cmd_array = explode("\n",$cmd); - foreach ($cmd_array as &$value) { - fputs($fp, $value."\n"); - } - fputs($fp, "\n"); //second line feed to end the headers - - $response = ''; - $i = 0; - $content_length = 0; - while (!feof($fp)) { - $buffer = fgets($fp, 4096); - if ($content_length > 0) { - $response .= $buffer; - } - - if ($content_length == 0) { //if the content has length don't process again - if (strlen(trim($buffer)) > 0) { //run only if buffer has content - $array = explode(":", trim($buffer)); - if ($array[0] == "Content-Length") { - $content_length = trim($array[1]); - } - } - } - - if ($content_length > 0) { //is content_length set - //stop reading if all content has been read. - if (strlen($response) >= $content_length) { - break; - } - } - else { - //prevent an endless loop - if ($i > 300000) { break; } - } - $i++; - } - - return $response; - } - else { - echo "no handle"; - } + $esl = new EventSocket($fp); + $result = $esl->request($cmd); + $esl->reset_fp(); + return $result; } function event_socket_request_cmd($cmd) { - global $db, $domain_uuid, $host; + global $db; if (file_exists($_SERVER['DOCUMENT_ROOT'].PROJECT_PATH."/app/settings/app_config.php")) { $sql = "select * from v_settings "; @@ -195,9 +141,13 @@ function event_socket_request_cmd($cmd) { unset ($prep_statement); } - $fp = event_socket_create($event_socket_ip_address, $event_socket_port, $event_socket_password); - $response = event_socket_request($fp, $cmd); - fclose($fp); + $esl = new EventSocket; + if (!$esl->connect($event_socket_ip_address, $event_socket_port, $event_socket_password)) { + return false; + } + $response = $esl->request($cmd); + $esl->close(); + return $response; } function byte_convert($bytes, $decimals = 2) { From 8c0bba7446a083e0af81fb74b5667d3d1b106883 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Tue, 25 Aug 2015 14:56:01 +0400 Subject: [PATCH 3/6] Fix. Start record when b-leg answer. This fix problem when DID transfers to IVR. After that user make direct-dial to extension. IVR do transfer but a-leg already answered and api_on_answer did not call. --- app/dialplan/resources/switch/conf/dialplan/050_user_record.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dialplan/resources/switch/conf/dialplan/050_user_record.xml b/app/dialplan/resources/switch/conf/dialplan/050_user_record.xml index 034bf464e3..801857d1d0 100644 --- a/app/dialplan/resources/switch/conf/dialplan/050_user_record.xml +++ b/app/dialplan/resources/switch/conf/dialplan/050_user_record.xml @@ -46,7 +46,7 @@ - + From 8fababb50887e3e4ed4377f413f5879cbff3ec4a Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Tue, 25 Aug 2015 16:12:12 +0400 Subject: [PATCH 4/6] Fix. Display names for global gateways on SIP Status page. --- app/sip_status/sip_status.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/sip_status/sip_status.php b/app/sip_status/sip_status.php index 029f979e55..1a23445a96 100644 --- a/app/sip_status/sip_status.php +++ b/app/sip_status/sip_status.php @@ -93,8 +93,8 @@ if ($_GET['a'] == "download") { } //get the gateways - $sql = "select g.domain_uuid, g.gateway, g.gateway_uuid, d.domain_name from v_gateways as g, v_domains as d "; - $sql .= "where d.domain_uuid = g.domain_uuid "; + $sql = "select g.domain_uuid, g.gateway, g.gateway_uuid, d.domain_name "; + $sql .= "from v_gateways as g left outer join v_domains as d on d.domain_uuid = g.domain_uuid"; $prep_statement = $db->prepare(check_sql($sql)); $prep_statement->execute(); $gateways = $prep_statement->fetchAll(PDO::FETCH_NAMED); From 480f41f1382837140c22547ccd7e9bfb83b50bf1 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Tue, 25 Aug 2015 16:46:31 +0400 Subject: [PATCH 5/6] Fix. Display only profiles which related to specific FS. --- app/sip_status/sip_status.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/sip_status/sip_status.php b/app/sip_status/sip_status.php index 029f979e55..abb921be11 100644 --- a/app/sip_status/sip_status.php +++ b/app/sip_status/sip_status.php @@ -100,9 +100,18 @@ if ($_GET['a'] == "download") { $gateways = $prep_statement->fetchAll(PDO::FETCH_NAMED); unset ($prep_statement, $sql); + if ($fp) { + $hostname = trim(event_socket_request($fp, 'api switchname')); + } + //get the sip profiles $sql = "select sip_profile_name from v_sip_profiles "; $sql .= "where sip_profile_enabled = 'true' "; + if ($hostname) { + $sql .= "and (sip_profile_hostname = '" . $hostname . "' "; + $sql .= "or sip_profile_hostname = '' "; + $sql .= "or sip_profile_hostname is null ) "; + } $sql .= "order by sip_profile_name asc "; $prep_statement = $db->prepare(check_sql($sql)); $prep_statement->execute(); From 2d94062cca0d0577eac319909507335c3cc937bd Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Tue, 25 Aug 2015 16:49:56 +0400 Subject: [PATCH 6/6] Fix. Escape hostname string. --- app/sip_status/sip_status.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/sip_status/sip_status.php b/app/sip_status/sip_status.php index abb921be11..1ad33c4e78 100644 --- a/app/sip_status/sip_status.php +++ b/app/sip_status/sip_status.php @@ -108,7 +108,7 @@ if ($_GET['a'] == "download") { $sql = "select sip_profile_name from v_sip_profiles "; $sql .= "where sip_profile_enabled = 'true' "; if ($hostname) { - $sql .= "and (sip_profile_hostname = '" . $hostname . "' "; + $sql .= "and (sip_profile_hostname = '" . check_str($hostname) . "' "; $sql .= "or sip_profile_hostname = '' "; $sql .= "or sip_profile_hostname is null ) "; }