]> Untitled Git - dev/commitdiff
new
authordirect <direct@1423-sleepy.empl.vvsu.ru>
Thu, 23 Nov 2017 05:46:21 +0000 (15:46 +1000)
committerdirect <direct@1423-sleepy.empl.vvsu.ru>
Thu, 23 Nov 2017 05:46:21 +0000 (15:46 +1000)
astapilib/agi.php [new file with mode: 0644]
astapilib/ami.php [new file with mode: 0644]
astapilib/baseagi.php [new file with mode: 0644]
astapilib/baseami.php [new file with mode: 0644]
astapilib/common.php [new file with mode: 0644]
balancechan_new.php [new file with mode: 0644]
balancechan_reset.php [new file with mode: 0644]
nbproject/project.properties [new file with mode: 0644]
nbproject/project.xml [new file with mode: 0644]

diff --git a/astapilib/agi.php b/astapilib/agi.php
new file mode 100644 (file)
index 0000000..c74de23
--- /dev/null
@@ -0,0 +1,646 @@
+<?php\r
+\r
+require_once(__DIR__.DIRECTORY_SEPARATOR.'baseagi.php');\r
+\r
+class AGI extends baseAGI\r
+{\r
+    public function __construct()\r
+    {\r
+       parent::__construct();\r
+    }\r
+    \r
+    //подготовка параметров для передачи\r
+    protected function make_params($inparams)\r
+    {\r
+       $retval = '';\r
+       foreach ($inparams as $pname => $pval)\r
+       {\r
+           if (is_null($pval))\r
+           {\r
+               break;\r
+           }\r
+           $retval .= ' "'.$pval.'"';\r
+       }\r
+       return $retval;\r
+    }\r
+\r
+    //Logs a message to the asterisk verbose log.\r
+    public function Verbose ($message, $level = 1)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'verbose';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;\r
+    }\r
+    \r
+    //Answer channel\r
+    public function Answer()\r
+    {\r
+       $cmd = 'answer';\r
+       $process_result = $this->ProcessCmd($cmd);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 0)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Hangup a channel.\r
+    public function Hangup($channelname = NULL)\r
+    {\r
+       $cmd = 'hangup';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Does nothing.\r
+    public function Noop()\r
+    {\r
+       $cmd = 'noop';\r
+       $process_result = $this->ProcessCmd($cmd);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Returns status of the connected channel.\r
+    /*Return values:\r
+    0 - Channel is down and available.\r
+    1 - Channel is down, but reserved.\r
+    2 - Channel is off hook.\r
+    3 - Digits (or equivalent) have been dialed.\r
+    4 - Line is ringing.\r
+    5 - Remote end is ringing.\r
+    6 - Line is up.\r
+    7 - Line is busy.\r
+    */\r
+    public function ChannelStatus ($channelname = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'channel status';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == -1)\r
+           {\r
+               return FALSE;\r
+           }\r
+           return $process_result['result']['val'];\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Gets a channel variable.\r
+    public function GetVariable ($variablename)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'get variable';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return $process_result['result']['data'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Evaluates a channel expression\r
+    public function GetFullVariable ($variablename, $channelname = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'get full variable';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return $process_result['result']['data'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Sets a channel variable.\r
+    public function SetVariable ($variablename , $value)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'Set variable';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Adds/updates database value\r
+    public function DatabasePut ($family, $key, $value)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'database put';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+\r
+    //Gets database value\r
+    public function DatabaseGet ($family, $key)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'database get';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return $process_result['result']['data'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+\r
+    //Removes database key/value\r
+    public function DatabaseDel ($family, $key)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'database del';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+    \r
+    //Removes database keytree/value\r
+    public function DatabaseDeltree ($family, $keytree = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'get data';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 0) // в документации сказано, что должна быть еденица, на деле, все наоборот, возможно будет исправлено в будущем\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Executes a given Application\r
+    public function Exec ($application, $options = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'exec';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -2) \r
+           {\r
+               return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Prompts for DTMF on a channel\r
+    public function GetData ($file, $timeout = NULL, $maxdigits = NULL)\r
+    {\r
+       $timeout = $timeout * 1000;\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'get data';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+        \r
+    //Stream file, prompt for DTMF, with timeout.\r
+    public function GetOption ($file, $escape_digits, $timeout = NULL)\r
+    {\r
+       $timeout = $timeout * 1000;\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'get option';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+\r
+    //Sends audio file on channel.\r
+    public function StreamFile ($filename, $escape_digits, $sample_offset = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'stream file';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+\r
+    //Receives one character from channels supporting it.\r
+    //нет возможности проверить\r
+    public function ReceiveChar ($timeout)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'receive char';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+\r
+    //Receives text from channels supporting it.\r
+    //нет возможности проверить\r
+    public function ReceiveText ($timeout)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'receive text';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return $process_result['result']['data'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+\r
+    //Records to a given file.\r
+    public function RecordFile ($filename, $format, $escape_digits, $timeout = -1, $offset_samples = NULL, $BEEP = NULL, $silence = NULL)\r
+    {\r
+       if ($timeout != -1)\r
+       {\r
+           $timeout = $timeout * 1000;\r
+       }\r
+       if ($silence !== NULL)\r
+       {\r
+           $silence = 's='.$silence;\r
+       }\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'record file';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+    \r
+    //Says a given character string.\r
+    public function SayAlpha ($number, $escape_digits = '')\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'say alpha';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+                   return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Says a given digit string.\r
+    public function SayDigits ($number, $escape_digits = '')\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'say digits';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+                   return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Says a given number.\r
+    public function SayNumber ($number, $escape_digits = '', $gender = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'say number';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+                   return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Says a given character string with phonetics.\r
+    public function SayPhonetic ($number, $escape_digits = '')\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'say phonetic';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+                   return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+    //Says a given date. (Unix time)\r
+    public function SayDate ($date, $escape_digits = '')\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'say date';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+                   return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Says a given time. (Unix time)\r
+    public function SayTime ($time, $escape_digits = '')\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'say time';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+                   return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Says a given time as specified by the format given. (почему то не работает, не понятен формат)\r
+    public function SayDatetime ($time, $escape_digits = '', $format = NULL, $timezone = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'say datetime';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+                   return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Sends images to channels supporting it.\r
+    public function SendImage ($image)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'send image';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Sends text to channels supporting it.\r
+    public function SendText ($text_to_send)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'send text';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+    \r
+    //Autohangup channel in some time.\r
+    public function SetAutohangup ($time)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'set autohangup';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Sets callerid for the current channel.\r
+    public function SetCallerid ($number)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'set callerid';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }    \r
+    \r
+    //Sets channel context.\r
+    public function SetContext  ($context)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'set context';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Changes channel extension.\r
+    public function SetExtension  ($extension)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'set extension';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }    \r
+    \r
+    //Enable/Disable Music on hold generator\r
+    public function SetMusicOn  ($class = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'set music on';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }    \r
+    \r
+    //Enable/Disable Music on hold generator\r
+    public function SetMusicOff  ($class = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'set music off';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Enable/Disable Music on hold generator\r
+    public function SetPriority  ($priority)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'set priority';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           return TRUE;\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Sends audio file on channel and allows the listener to control the stream.\r
+    public function ControlStreamFile  ($filename, $escape_digits, $skipms = NULL, $ffchar = NULL, $rewchr = NULL, $pausechr = NULL, $offsetms = NULL)\r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'control stream file';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+          if ($process_result['result']['val'] != -1)\r
+           {\r
+               return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }    \r
+\r
+    //Toggles TDD mode (for the deaf). параметры следует уточнить, не понятно что указывать\r
+    public function TddMode ($mode) \r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'tdd mode';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] == 1)\r
+           {\r
+               return TRUE;\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Waits for a digit to be pressed.\r
+    public function WaitForDigit ($timeout = -1) \r
+    {\r
+       if ($timeout != -1)\r
+       {\r
+           $timeout = $timeout * 1000;\r
+       }\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'wait for digit';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }\r
+    \r
+    //Cause the channel to execute the specified dialplan subroutine. Должным образом не проверялось,что должно возвращаться не понятно.\r
+    public function Gosub ($context, $extension, $priority, $optional_argument = NULL) \r
+    {\r
+       $params = $this->make_params(get_defined_vars());\r
+       $cmd = 'gosub';\r
+       $process_result = $this->ProcessCmd($cmd.$params);\r
+       if ($process_result['code'] == 200)\r
+       {\r
+           if ($process_result['result']['val'] != -1)\r
+           {\r
+               return $process_result['result']['val'];\r
+           }\r
+       }\r
+       return FALSE;   \r
+    }        \r
+}\r
diff --git a/astapilib/ami.php b/astapilib/ami.php
new file mode 100644 (file)
index 0000000..aeafd56
--- /dev/null
@@ -0,0 +1,1982 @@
+<?php
+/*
+
+
+*/
+
+require_once(__DIR__.DIRECTORY_SEPARATOR.'common.php');
+require_once(__DIR__.DIRECTORY_SEPARATOR.'baseami.php');
+require_once(__DIR__.DIRECTORY_SEPARATOR.'timer.php');
+
+class AMI extends baseAMI
+{
+    protected $semaphores = [];
+    protected $TMP = [];
+     
+    //конструктор установка параметров
+    public function __construct($config = [])
+    {
+       parent::__construct($config);
+       //default parameters
+       //if (!isset($config['keepalive']){$config['keepalive'] = TRUE;})
+       //parse parameters
+       foreach ($config as $opt => $val)
+       {
+           if ($opt == 'use_dev_state_list' and $val == TRUE)
+           {
+
+           }
+               
+       }
+    }
+    
+    //генерирует MD5 challenge для аутентификации (не понятно где применять)
+    public function Challenge($authtype)
+    {
+       $response = $this->get_response($this->send_action('Challenge',array('AuthType' => $authtype)));
+       if($response["Response"] == "Success")
+       {
+           return $response["Challenge"];
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //возвращает список всех каналов с состояниями DEVSTATE
+    public function DeviceStateList()
+    {
+       $id = $this->Listcmd_CommonConstructor('DeviceStateChange', 'DeviceStateListComplete', 'DeviceStateList');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       $retval = [];
+       foreach ($this->TMP[$id] as $val)
+       {
+           $retval[$val['Device']] = $val['State']; 
+       }
+       unset($this->TMP[$id]);
+       return $retval;
+    }
+    
+    //возвращает список всех presense
+    public function PresenceStateList()
+    {
+       $id = $this->Listcmd_CommonConstructor('PresenceStateChange', 'PresenceStateListComplete', 'PresenceStateList');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       $retval = [];
+       foreach ($this->TMP[$id] as $val)
+       {
+           $retval[$val['Presentity']]["Status"] = $val["Status"]; 
+           $retval[$val['Presentity']]["Subtype"] = $val["Subtype"]; 
+           $retval[$val['Presentity']]["Message"] = $val["Message"]; 
+       }
+       unset($this->TMP[$id]);
+       return $retval;
+    }
+    
+    //возвращает все ExtensionState
+    public function ExtensionStateList()
+    {
+       $id = $this->Listcmd_CommonConstructor('ExtensionStatus', 'ExtensionStateListComplete', 'ExtensionStateList');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       $retval = [];
+       foreach ($this->TMP[$id] as $val)
+       {
+           $retval[$val["Context"]][$val["Exten"]]["Hint"] = $val["Hint"];
+           $retval[$val["Context"]][$val["Exten"]]["Status"] = $val["Status"]; 
+           $retval[$val["Context"]][$val["Exten"]]["StatusText"] = $val["StatusText"]; 
+
+       }
+       unset($this->TMP[$id]);
+       return $retval;
+    }
+    
+    //возвращает extensionstate
+    public function ExtensionState($Context, $Exten)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('ExtensionState', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           unset($response['Response'], $response['ActionID']);
+           return $response;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //возвращает presensestate
+    public function PresenceState($Provider)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('PresenceState', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           unset($response['Response'], $response['ActionID']);
+           return $response;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Набор методов для работы со встроенной БД asterisk
+    public function DBPut($Family, $Key, $Value=NULL)
+    {  
+       $params = $this->make_params(get_defined_vars());
+       $ActId = $this->send_action('DBPut', $params);
+       $response = $this->get_response($ActId);
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //реализация DBGet
+    public function DBGet($Family, $Key)
+    {  
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('dbgetresponse', 'dbgetcomplete', 'DBGet',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       $retval = $this->TMP[$id][0]['Val'];
+       unset($this->TMP[$id]);
+       return $retval;
+    }
+    
+    //реализация DBDelTree
+    public function DBDelTree($Family, $Key = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DBDelTree', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //реализация DBDel
+    public function DBDel($Family, $Key)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DBDel', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //получение переменной
+    public function Getvar($Variable, $Channel = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('Getvar', $params));
+       if ($response['Response'] == 'Success')
+       {
+           return $response['Value'];
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //установка переменной
+    public function Setvar($Value, $Variable, $Channel = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('Setvar', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //возвращает dialplan или его отдельные части
+    public function ShowDialPlan($Context = NULL, $Extension = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('listdialplan', 'showdialplancomplete', 'ShowDialPlan',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval;
+    }
+    
+    //Hangup на канале
+    public function Hangup($Channel, $Cause = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('channelhungup', 'channelshunguplistcomplete', 'Hangup',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       $retval = [];
+       foreach ($this->TMP[$id] as $val)
+       {
+           $retval[] = $val['Channel'];
+       }
+       unset($this->TMP[$id]);
+       return $retval;
+    }
+    
+    //отправка сообщения
+    public function MessageSend($To, $From = NULL, $Body = NULL, $Variable = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       if(isset($params['Body']))
+       {
+           if(strpos($params['Body'], "\n") !== FALSE)
+           {
+               $params['Base64Body'] = base64_encode($params['Body']);
+               unset($params['Body']);
+           }
+       }
+       if(isset($params['Variable']))
+       {
+           $var = $params['Variable'];
+           $params['Variable'] = '';
+           foreach ($var as $varname => $varval)
+           {
+               $params['Variable'] .= $varname.'='.$varval.',';
+           }
+           $params['Variable'] = substr($params['Variable'], 0, -1);       
+       }
+       $response = $this->get_response($this->send_action('MessageSend', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //отправка текста в канал во время звонка
+    public function SendText($Channel, $Message)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('SendText', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    
+    //отправка CLI комманды
+    public function Command($cmd)
+    {
+       $response = $this->get_response($this->send_action('Command', ['Command' => $cmd]));
+       return $response['RAW'];
+    }
+    
+    //получение списка комманд
+    public function ListCommands()
+    {
+       $response = $this->get_response($this->send_action('ListCommands'));
+       unset($response['Response'], $response['ActionID']);
+       return $response;
+    }
+    
+    //реализация originate
+    public function Originate($Channel, $Context = NULL, $Exten = NULL, $Priority = NULL, $Application = NULL, $Data = NULL, $Timeout = NULL, $CallerID = NULL, $Variable = NULL, $Account = NULL, $EarlyMedia = NULL, $Codecs = NULL, $ChannelId = NULL, $OtherChannelId = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $params['Async'] = 'true';
+       if (isset($params['Context']) or isset($params['Exten']) or isset($params['Priority']))
+       {
+           if (!isset($params['Context']) or !isset($params['Exten']) or !isset($params['Priority']))
+           {
+               LOG::log(__METHOD__.' CONTEXT, EXTENSION and PRIORITY must be setted if you use one of them.', 3);
+               return FALSE;
+           }
+       }
+       if ((isset($params['Application'])) and (isset($params['Context']) or isset($params['Exten']) or isset($params['Priority'])))
+       {
+           LOG::log(__METHOD__.' CONTEXT, EXTENSION and PRIORITY must not be setted if you use Application.', 3);
+           return FALSE;
+       }
+       if (!isset($params['Application']) and isset($params['Data']))
+       {
+           LOG::log(__METHOD__.' DATA must not be setted if you not use Application.', 3);
+           return FALSE;
+       }
+       if (isset($params['Timeout']))
+       {
+           $params['Timeout'] = $params['Timeout'] * 1000;
+       }
+       if (isset($params['Variable']))
+       {
+           if (!is_array($params['Variable']))
+           {
+               LOG::log(__METHOD__.' VARIABLE must be an array.', 3);
+               return FALSE;
+           }
+           $variable = $params['Variable'];
+           $params['Variable'] = '';
+           foreach ($variable as $varname => $varvalue)
+           {
+               $params['Variable'] .= $varname.'='.$varvalue.',';
+           }
+           $params['Variable'] = substr($params['Variable'], 0, -1);
+       }
+
+       if (isset($params['Codecs']))
+       {
+           if (!is_array($params['Codecs']))
+           {
+               LOG::log(__METHOD__.' CODECS must be an array.', 3);
+               return FALSE;
+           }
+           $codecs = $params['Codecs'];
+           $params['Codecs'] = '';
+           foreach ($codecs as $varvalue)
+           {
+               $params['Codecs'] .= $varvalue.',';
+           }
+           $params['Codecs'] = substr($params['Codecs'], 0, -1);
+       }
+       
+       $response = $this->get_response($this->send_action('Originate',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return $response['ActionID'];
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //возвращает колличество сообщений в голосовой почте
+    public function MailboxCount($Mailbox)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('MailboxCount',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           unset($response['Response'], $response['ActionID'],$response['Message']);
+           return $response;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //возвращает колличество сообщений в голосовой почте
+    public function MailboxStatus($Mailbox)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('MailboxStatus',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           unset($response['Response'], $response['ActionID'],$response['Message']);
+           return $response;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //установка абсолютного таймаута на канале
+    public function AbsoluteTimeout($Channel, $Timeout)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('AbsoluteTimeout', $params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Optimize away a local channel when possible.
+    public function LocalOptimizeAway($chan)
+    {
+       $response = $this->get_response($this->send_action('LocalOptimizeAway',['Channel' => $chan]));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Send an event to manager sessions.
+    public function UserEvent($event, $eventpack)
+    {
+       $eventpack['UserEvent'] = $event;
+       $response = $this->get_response($this->send_action('UserEvent',$eventpack));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Show PBX core status variables.
+    public function CoreStatus()
+    {
+       $response = $this->get_response($this->send_action('CoreStatus'));
+       unset($response['Response'], $response['ActionID']);
+       return $response;
+    }
+    
+    //Show PBX core settings (version etc).
+    public function CoreSettings()
+    {
+       $response = $this->get_response($this->send_action('CoreSettings'));
+       unset($response['Response'], $response['ActionID']);
+       return $response;
+    }
+    
+    //Send a reload event.
+    public function Reload($Module = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('Reload',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+        //Send a reload event.
+    public function LoggerRotate()
+    {
+       $response = $this->get_response($this->send_action('Reload'));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Attended transfer.
+    public function Atxfer($Channel, $Exten, $Context = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('Atxfer',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+  
+    //Blind transfer channel(s) to the given destination
+    public function BlindTransfer($Channel, $Exten, $Context = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('BlindTransfer',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Redirect (transfer) a call.
+    public function Redirect($Channel, $Exten, $Context, $Priority)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('Redirect',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    public function CoreShowChannels()
+    {
+       $id = $this->Listcmd_CommonConstructor('CoreShowChannel', 'CoreShowChannelsComplete', 'CoreShowChannels');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Play DTMF signal on a specific channel.
+    public function PlayDTMF($Channel, $digits, $Duration = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       unset($params['digits']);
+       if (strlen($digits) == 0)
+       {
+           LOG::log(__METHOD__.' '.'Parameter DIGITS is empty', 5);
+           return FALSE;
+       }
+       for ($c = 0; $c < strlen($digits); $c++)
+       {
+           $params['Digit'] = $digits{$c};
+           $response = $this->get_response($this->send_action('PlayDTMF',$params));
+           usleep(70000);
+       }
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Bridge two channels already in the PBX.
+    public function Bridge($Channel1, $Channel2, $Tone = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('Bridge',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //List available bridging technologies and their statuses.
+    public function BridgeTechnologyList()
+    {
+       $id = $this->Listcmd_CommonConstructor('bridgetechnologylistitem', 'bridgetechnologylistcomplete', 'BridgeTechnologyList');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Suspend a bridging technology.
+    public function BridgeTechnologySuspend($BridgeTechnology)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('BridgeTechnologySuspend',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Unsuspend a bridging technology.
+    public function BridgeTechnologyUnsuspend($BridgeTechnology)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('BridgeTechnologyUnsuspend',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Get a list of bridges in the system.
+    public function BridgeList($BridgeType = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('bridgelistitem', 'bridgelistcomplete', 'BridgeList',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Get information about a bridge.
+    public function BridgeInfo($BridgeUniqueid)
+    {
+       $params = $this->make_params(get_defined_vars());  
+       $id = $this->Listcmd_CommonConstructor('BridgeInfoChannel', 'BridgeInfoComplete', 'BridgeInfo',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Destroy a bridge.
+    public function BridgeDestroy($BridgeUniqueid)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('BridgeDestroy',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Kick a channel from a bridge.
+    public function BridgeKick($Channel, $BridgeUniqueid = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('BridgeKick',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+
+
+    //Tell Asterisk to poll mailboxes for a change
+    public function VoicemailRefresh($Context = NULL, $Mailbox = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('VoicemailRefresh',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+    
+    //Get information about a bridge.
+    public function VoicemailUsersList()
+    {
+       $id = $this->Listcmd_CommonConstructor('voicemailuserentry', 'voicemailuserentrycomplete', 'VoicemailUsersList');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Tell Asterisk to poll mailboxes for a change
+    public function MuteAudio($Channel, $Direction, $State)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('MuteAudio',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+    
+    //Control the playback of a file being played to a channel
+    public function ControlPlayback($Channel, $Control)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('ControlPlayback',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+    
+    //Check the status of one or more queues.
+    public function QueueStatus($Queue = NULL, $Member = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('queueparams', 'queuestatuscomplete', 'QueueStatus', $params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $queueparams = $this->TMP[$id];
+       unset($this->TMP[$id]);
+               
+       $id = $this->Listcmd_CommonConstructor('queuemember', 'queuestatuscomplete', 'QueueStatus', $params);
+       
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $queuemember = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       $retval['queueparams'] = $queueparams;
+       $retval['queuemember'] = $queuemember;
+       return $retval; 
+    }
+    
+    
+    //Request the manager to send a QueueSummary event.
+    public function QueueSummary($Queue = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('queuesummary', 'queuesummarycomplete', 'QueueSummary',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Add interface to queue.
+    public function QueueAdd($Queue, $Interface, $Penalty = NULL, $Paused = NULL, $MemberName = NULL, $StateInterface = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueueAdd',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+
+    //Remove interface from queue.
+    public function QueueRemove($Queue, $Interface)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueueRemove',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+    //Makes a queue member temporarily unavailable.
+    public function QueuePause($Interface, $Paused, $Queue = NULL, $Reason = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueuePause',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+
+    //Adds custom entry in queue_log.
+    public function QueueLog($Queue, $Event, $Reason, $Message = NULL, $Interface = NULL, $Uniqueid = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueueLog',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+
+    //Set the penalty for a queue member.
+    public function QueuePenalty($Interface, $Penalty, $Queue = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueuePenalty',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+
+    //Set the ringinuse value for a queue member.
+    public function QueueMemberRingInUse($Interface, $RingInUse, $Queue = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueueMemberRingInUse',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+    
+    //List queue rules defined in queuerules.conf
+    public function QueueRule ($Rule = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueueRule',$params));
+       if ($response['Response'] != 'Success')
+       {
+           return FALSE;
+       }
+       unset($response['Response'], $response['ActionID']);
+       $retval = $response;
+       return $retval; 
+    }
+    
+    //Reload a queue, queues, or any sub-section of a queue or queues.
+    public function QueueReload ($Queue = NULL, $Members = NULL, $Rules = NULL, $Parameters = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueueReload',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+    
+    //Reset queue statistics.
+    public function QueueReset ($Queue = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('QueueReset',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+
+    //Record a call and mix the audio during the recording.
+    public function MixMonitor ($Channel, $File = NULL, $options = NULL, $Command = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('MixMonitor',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Stop recording a call through MixMonitor, and free the recording's file handle.
+    public function StopMixMonitor ($Channel, $MixMonitorID = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('StopMixMonitor',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Mute / unMute a Mixmonitor recording.
+    public function MixMonitorMute ($Channel, $Direction = NULL, $State = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('MixMonitorMute',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Monitor a channel.
+    public function Monitor ($Channel, $File = NULL, $Format = NULL, $Mix = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('Monitor',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Stop monitoring a channel.
+    public function StopMonitor ($Channel)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('StopMonitor',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Change monitoring filename of a channel.
+    public function ChangeMonitor ($Channel, $File)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('StopMonitor',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Pause monitoring of a channel.
+    public function PauseMonitor ($Channel)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('PauseMonitor',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Unpause monitoring of a channel.
+    public function UnpauseMonitor ($Channel)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('UnpauseMonitor',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Lists active FAX sessions
+    public function FAXSessions()
+    {
+       $id = $this->Listcmd_CommonConstructor('faxsessionsentry', 'FAXSessionsComplete', 'FAXSessions');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+
+    //Responds with fax statistics
+    public function FAXStats()
+    {
+       $id = $this->EventAsVal('faxstats', 'FAXStats');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }       
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       unset($retval['Event']);
+       unset($retval['ActionID']);
+       return $retval; 
+    }
+
+    //Responds with a detailed description of a single FAX session
+    public function FAXSession ($SessionNumber)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->EventAsVal('faxsession', 'FAXSession',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }       
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       unset($retval['Event']);
+       unset($retval['ActionID']);
+       return $retval; 
+    }    
+    
+    //Lists agents and their status.
+    public function Agents()
+    {
+       $id = $this->Listcmd_CommonConstructor('Agents', 'AgentsComplete', 'Agents');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Sets an agent as no longer logged in.
+    public function AgentLogoff ($Agent, $Soft = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('AgentLogoff',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }
+    }    
+    
+    //Park a channel.
+    public function Park ($Channel, $TimeoutChannel = NULL, $AnnounceChannel = NULL, $Timeout = NULL, $Parkinglot = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('Park',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }    
+    
+    //List parked calls.
+    public function ParkedCalls ($ParkingLot = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('parkedcall', 'parkedcallscomplete', 'ParkedCalls',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Get a list of parking lots
+    public function Parkinglots ()
+    {
+       $id = $this->Listcmd_CommonConstructor('parkinglot', 'parkinglotscomplete', 'Parkinglots');
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Module management
+    public function ModuleLoad ($LoadType, $Module = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('ModuleLoad',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }       
+    }
+    
+    //Check if module is loaded
+    public function ModuleCheck ($Module)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('ModuleCheck',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return $response['Version'];
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //List channel status
+    public function Status ($Channel = NULL, $Variables = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('Status', 'StatusComplete', 'Status',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Add an extension to the dialplan
+    public function DialplanExtensionAdd ($Context, $Extension, $Priority, $Application, $ApplicationData = NULL, $Replace = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DialplanExtensionAdd',$params));
+       if ($response['Response'] == 'Success')
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+    
+    //Remove an extension from the dialplan
+    public function DialplanExtensionRemove ($Context, $Extension, $Priority = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DialplanExtensionRemove',$params));
+       if ($response['Response'] == 'Success')
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+        
+    //List SIP peers (text format).
+    public function SIPpeers ()
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('peerentry', 'PeerlistComplete', 'SIPpeers',$params);    
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+
+    //show SIP peer (text format).
+    public function SIPshowpeer ($Peer)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('SIPshowpeer',$params));
+       if ($response['Response'] == 'Success')
+       {
+           unset($response['Response']);
+           unset($response['ActionID']);
+           return $response;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    
+    //Qualify SIP peers.
+    public function SIPqualifypeer ($Peer)
+    {
+       $params = $this->make_params(get_defined_vars());
+       //$response = $this->get_response($this->send_action('SIPqualifypeer',$params));
+       $id  = $this->EventAsVal('sipqualifypeerdone', 'SIPqualifypeer',$params);
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }       
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       unset($retval['Event']);
+       unset($retval['ActionID']);
+       return $retval;
+    }
+    
+    //Show SIP registrations (text format).
+    public function SIPshowregistry ()
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('registryentry', 'registrationscomplete', 'SIPshowregistry',$params);    
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+     //Send a SIP notify.
+    public function SIPnotify ($Channel, $Variable)
+    {
+       $params = $this->make_params(get_defined_vars());
+       if(isset($params['Variable']))
+       {
+           if (!is_array($params['Variable']))
+           {
+               LOG::log(__METHOD__.' Argument "Variable" must be an array!' , 5);
+               return FALSE;
+           }
+           $var = $params['Variable'];
+           $params['Variable'] = '';
+           foreach ($var as $varname => $varval)
+           {
+               $params['Variable'] .= $varname.'='.$varval.',';
+           }
+           $params['Variable'] = substr($params['Variable'], 0, -1);       
+       }
+       $response = $this->get_response($this->send_action('SIPnotify',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //Show the status of one or all of the sip peers.
+    public function SIPpeerstatus ($Peer = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('peerstatus', 'sippeerstatuscomplete', 'SIPpeerstatus',$params); 
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+
+    //Set the file used for PRI debug message output
+    public function PRIDebugFileSet ($File)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('PRIDebugFileSet',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //Disables file output for PRI debug messages
+    public function PRIDebugFileUnset ()
+    {
+       $response = $this->get_response($this->send_action('PRIDebugFileUnset'));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+
+    //Set PRI debug levels for a span
+    public function PRIDebugSet ($Span, $Level)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('PRIDebugSet',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //Show status of PRI spans.
+    public function PRIShowSpans ($Span = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('prishowspans', 'prishowspanscomplete', 'PRIShowSpans',$params); 
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+
+    //Show status of DAHDI channels.
+    public function DAHDIShowChannels ($DAHDIChannel = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('dahdishowchannels', 'dahdishowchannelscomplete', 'DAHDIShowChannels',$params);  
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    
+    //Toggle DAHDI channel Do Not Disturb status ON.
+    public function DAHDIDNDon ($DAHDIChannel)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DAHDIDNDon',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //Toggle DAHDI channel Do Not Disturb status OFF.
+    public function DAHDIDNDoff ($DAHDIChannel)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DAHDIDNDoff',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+    
+    //Dial over DAHDI channel while offhook.
+    public function DAHDIDialOffhook ($DAHDIChannel, $Number)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DAHDIDialOffhook',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //Hangup DAHDI Channel.
+    public function DAHDIHangup ($DAHDIChannel)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DAHDIHangup',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //Transfer DAHDI Channel.
+    public function DAHDITransfer ($DAHDIChannel)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $response = $this->get_response($this->send_action('DAHDITransfer',$params));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //Fully Restart DAHDI channels (terminates calls).
+    public function DAHDIRestart ()
+    {
+       $response = $this->get_response($this->send_action('DAHDIRestart'));
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           LOG::log(__METHOD__.' '.$response['Message'], 5);
+           return FALSE;
+       }       
+    }
+
+    //List participants in a conference.
+    public function ConfbridgeList ($Conference)
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('ConfbridgeList', 'ConfbridgeListComplete', 'ConfbridgeList',$params);   
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+
+
+    //List active conferences.
+    public function ConfbridgeListRooms ()
+    {
+       $params = $this->make_params(get_defined_vars());
+       $id = $this->Listcmd_CommonConstructor('ConfbridgeListRooms', 'ConfbridgeListRoomsComplete', 'ConfbridgeListRooms',$params);    
+       if ($id === FALSE)
+       {
+           return FALSE;
+       }
+       array_walk($this->TMP[$id], function (&$a1){unset($a1['Event']);unset($a1['ActionID']);});
+       $retval = $this->TMP[$id];
+       unset($this->TMP[$id]);
+       return $retval; 
+    }
+    //Mute a Confbridge user.
+    public function ConfbridgeMute ($Conference, $Channel)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeMute',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Unmute a Confbridge user.
+    public function ConfbridgeUnmute ($Conference, $Channel)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeUnmute',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Kick a Confbridge user.
+    public function ConfbridgeKick ($Conference, $Channel)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeKick',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Lock a Confbridge conference.
+    public function ConfbridgeLock ($Conference)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeLock',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Unlock a Confbridge conference.
+    public function ConfbridgeUnlock ($Conference)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeUnlock',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Start recording a Confbridge conference.
+    public function ConfbridgeStartRecord ($Conference, $RecordFile = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeStartRecord',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Stop recording a Confbridge conference.
+    public function ConfbridgeStopRecord ($Conference)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeStopRecord',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Set a conference user as the single video source distributed to all other participants.
+    public function ConfbridgeSetSingleVideoSrc ($Conference, $Channel)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ConfbridgeSetSingleVideoSrc',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //Creates an empty file in the configuration directory.
+    public function CreateConfig ($Filename)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('CreateConfig',$params));
+       LOG::log(__METHOD__.' '.$response['Message'], 5);
+       if ($response['Response'] == 'Success')
+       {
+           return TRUE;
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+    //Retrieve configuration.
+    public function GetConfig ($Filename, $Category = NULL, $Filter = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('GetConfig',$params));
+       if ($response['Response'] != 'Success')
+       {
+           return FALSE;
+       }
+       unset($response['Response'], $response['ActionID']);
+       $retval = $response;
+       return $retval; 
+    }
+    
+    //Retrieve configuration (JSON format).
+    public function GetConfigJSON ($Filename, $Category = NULL, $Filter = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('GetConfigJSON',$params));
+       if ($response['Response'] != 'Success')
+       {
+           return FALSE;
+       }
+       unset($response['Response'], $response['ActionID']);
+       $retval = $response;
+       return $retval; 
+    }    
+
+    //List categories in configuration file.
+    public function ListCategories ($Filename)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       $response = $this->get_response($this->send_action('ListCategories',$params));
+       if ($response['Response'] != 'Success')
+       {
+           return FALSE;
+       }
+       unset($response['Response'], $response['ActionID']);
+       $retval = $response;
+       return $retval; 
+    }    
+
+    //Update basic configuration.
+    public function UpdateConfig ($SrcFilename, $DstFilename, $Reload = NULL, $Action = NULL, $Cat = NULL, $Var = NULL, $Value = NULL, $Match = NULL, $Line = NULL, $Options = NULL)
+    {
+       $params = $this->make_params(get_defined_vars());       
+       foreach ($params as $key => $value)
+       {
+           if ($key != 'SrcFilename' && $key != 'DstFilename' && $key != 'Reload')
+           {
+               $params[$key.'-000000'] = $value;
+               unset($params[$key]);
+           }
+       }
+       $response = $this->get_response($this->send_action('UpdateConfig',$params));
+       if ($response['Response'] != 'Success')
+       {
+           return FALSE;
+       }
+       else
+       {
+           return TRUE;
+       }       
+    }    
+    
+  
+    ////////////////////////////////////////////////////////////////////////////
+    
+    //конструктор запросов и сборщик множественных событий
+    protected function Listcmd_CommonConstructor ($unit_event, $complete_event, $init_action, $params = [])
+    {
+       $old_ev_hdl = $this->get_event_handler($unit_event);
+       if ($old_ev_hdl !== FALSE)
+       {
+           $this->remove_event_handler($unit_event);
+       }
+       $this->add_event_handler($unit_event, array(&$this,'grouped_events_hdl'));      
+       $this->add_event_handler($complete_event, array(&$this,'ListComplete_hdl'));
+       $this->refresh_lock = TRUE;
+       $id = $this->send_action($init_action,$params);
+       $this->TMP[$id] = [];
+       $this->set_semaphore($id, FALSE);
+       $this->refresh_lock = FALSE;
+       $response = $this->get_response($id);   
+       if ($response['Response'] != 'Success')
+       {
+           $this->set_semaphore($id, TRUE);
+       }
+       $this->wait_semaphore($id);
+       $this->remove_event_handler($unit_event);
+       $this->remove_event_handler($complete_event);
+       if ($old_ev_hdl !== FALSE)
+       {
+           $this->add_event_handler($unit_event, $old_ev_hdl);
+       }
+       if ($response['Response'] == 'Success')
+       {
+           return $id;
+       }
+       else
+       {
+           unset($this->TMP[$id]);
+           return FALSE;
+       }
+    }
+    
+    //обработчик групированных событий
+    protected function grouped_events_hdl( $event_name, $event)
+    {  
+       if (isset($event["ActionID"]))
+       {
+           $this->TMP[$event["ActionID"]][] = $event;
+       }
+    }
+    
+    //обработчик конца списка группированных событий
+    protected function ListComplete_hdl( $event_name, $event)
+    {
+       $this->set_semaphore($event["ActionID"], TRUE);
+       
+    }
+        
+    //Ожидание события, возврат события
+    protected function EventAsVal($unit_event, $init_action, $params = [])
+    {
+       $old_ev_hdl = $this->get_event_handler($unit_event);
+       if ($old_ev_hdl !== FALSE)
+       {
+           $this->remove_event_handler($unit_event);
+       }
+       $this->add_event_handler($unit_event, array(&$this,'one_events_hdl'));
+       $this->refresh_lock = TRUE;
+       $id = $this->send_action($init_action, $params);
+       $this->TMP[$id] = [];
+       $this->set_semaphore($id, FALSE);
+       $this->refresh_lock = FALSE;
+       $response = $this->get_response($id);   
+       if ($response['Response'] != 'Success')
+       {
+           $this->set_semaphore($id, TRUE);
+       }
+       $this->wait_semaphore($id);
+       $this->remove_event_handler($unit_event);
+       if ($old_ev_hdl !== FALSE)
+       {
+           $this->add_event_handler($unit_event, $old_ev_hdl);
+       }
+       if ($response['Response'] == 'Success')
+       {
+           return $id;
+       }
+       else
+       {
+           unset($this->TMP[$id]);
+           return FALSE;
+       }       
+    }
+
+    //обработчик получения одиночного события
+    protected function one_events_hdl( $event_name, $event)
+    {  
+       if (isset($event["ActionID"]))
+       {
+           $this->TMP[$event["ActionID"]] = $event;
+           $this->set_semaphore($event["ActionID"], TRUE);
+       }
+       
+    }
+
+    
+    //установка семафора
+    protected function set_semaphore($sem,$val)
+    {
+        $this->semaphores[$sem] = $val;
+    }
+    
+    //ожидание разрешающего семафора
+    protected function wait_semaphore($sem)
+    {
+       if(!isset($this->semaphores[$sem]))
+       {
+           return FALSE;
+       }
+       while (!$this->semaphores[$sem])
+       {
+           usleep(10000);
+       }
+       unset($this->semaphores[$sem]);
+       return TRUE;
+    }
+    
+    //подготовка параметров для передачи
+    protected function make_params($inparams)
+    {
+       $retval = [];
+       foreach ($inparams as $pname => $pval)
+       {
+           if (!is_null($pval))
+           {
+               $retval[$pname] = $pval;
+           }
+       }
+       return $retval;
+    }
+}
\ No newline at end of file
diff --git a/astapilib/baseagi.php b/astapilib/baseagi.php
new file mode 100644 (file)
index 0000000..5daa8ee
--- /dev/null
@@ -0,0 +1,113 @@
+<?php\r
+\r
+class baseAGI\r
+{\r
+    protected $request = FALSE;\r
+    protected $last_response = NULL;\r
+\r
+\r
+    public function __construct()\r
+    {\r
+       $this->request = $this->ProcessRequest();\r
+       if ($this->request === FALSE)\r
+       {\r
+           return FALSE;\r
+       }\r
+    }\r
+    //получение запроса\r
+    protected function ProcessRequest()\r
+    {\r
+       while(TRUE)\r
+       {\r
+           $line = stream_get_line (STDIN , 1500, PHP_EOL); //получение сырых данных с парсингом по переводу строк\r
+           if ($line === ''){break;} //пустая строка означает конец пакета\r
+           if ($line === FALSE){return FALSE;} //false означает осутствие данных\r
+           $parse_result = preg_match('/(^.[^ ]*): (.*)/', $line, $parsed_line);\r
+               if ($parse_result === 1)\r
+               {\r
+                   $request[$parsed_line[1]] = $parsed_line[2];\r
+               }\r
+       }\r
+       \r
+       if (isset($request))\r
+       {\r
+           return $request;\r
+       }\r
+       else\r
+       {\r
+           return FALSE;\r
+       }\r
+    }\r
+    //обработка комманды\r
+    protected function ProcessCmd($cmd)\r
+    {\r
+       fwrite(STDOUT, $cmd.PHP_EOL);\r
+       $line = stream_get_line (STDIN , 1500, PHP_EOL); //получение сырых данных с парсингом по переводу строк\r
+       $parse_result = preg_match('/(\d+)(?:.)(.*)/', $line, $parsed_line);\r
+       if ($parse_result === 1)\r
+       {\r
+           $resp['code'] = (int) $parsed_line[1];\r
+           $data = $parsed_line[2];\r
+           if ($resp['code'] == 200)\r
+           {\r
+               $parse_result = preg_match_all("/(?:(?'rval'[^\ ]+=[^\ ]*))|(?:\s\((?'aval'.*?)\)(?:\s|$))/", $data, $parsed_line, PREG_SET_ORDER);\r
+               if ($parse_result != FALSE)\r
+               {\r
+                   foreach ($parsed_line as $parsed_set)\r
+                   {\r
+                       if(isset($parsed_set['rval']) && !isset($parsed_set['aval']))\r
+                       {\r
+                           $kv = explode('=', $parsed_set['rval']);\r
+                           $resp[$kv[0]]['val'] = $kv[1];\r
+                           $lastparam = $kv[0];\r
+                       }\r
+                       if(isset($parsed_set['aval']) && isset($lastparam))\r
+                       {\r
+                           $resp[$lastparam]['data'] = $parsed_set['aval'];\r
+                       }\r
+                   }\r
+               }\r
+               $this->last_response = $resp;\r
+               return $resp;\r
+           }\r
+           else\r
+           {\r
+               $resp['error'] = $data;\r
+               $this->last_response = $resp;\r
+               return $resp;\r
+           }\r
+       }\r
+       else\r
+       {\r
+           $this->last_response = FALSE;\r
+           return FALSE;\r
+       }\r
+    }\r
+    //получение обработанного запроса или его частей\r
+    public function GetRequest($key = NULL)\r
+    {\r
+       if ($this->request === FALSE)\r
+       {\r
+           return FALSE;\r
+       }\r
+       if ($key === NULL)\r
+       {\r
+           return $this->request;\r
+       }\r
+       if (!isset($this->request[$key]))\r
+       {\r
+           return FALSE;\r
+       }\r
+       else\r
+       {\r
+           return $this->request[$key];\r
+       }\r
+    }\r
+    \r
+    //получение последнего ответа целиком\r
+    public function GetLastResponse()\r
+    {\r
+       return $this->last_response;\r
+    }\r
+           \r
+}
\ No newline at end of file
diff --git a/astapilib/baseami.php b/astapilib/baseami.php
new file mode 100644 (file)
index 0000000..ca3bd13
--- /dev/null
@@ -0,0 +1,345 @@
+<?php
+
+class baseAMI
+{
+    protected $conn_handle = FALSE;
+    protected $inbound_stream_buffer = [];
+    protected $events = [];
+    protected $responses = [];
+    protected $event_handlers = [];
+    protected $refresh_lock = FALSE;
+    
+    //конструктор, настройка по умолчанию 
+    public function __construct($config = [])
+    {
+       //default parameters
+       if (!isset($config['keepalive'])){$config['keepalive'] = TRUE;}
+       //parse parameters
+       foreach ($config as $opt => $val)
+       {
+           if ($opt == 'autorefresh' and $val === TRUE) {new Timer(0.5, array(&$this,'refresh'), TRUE);}
+           if ($opt == 'logverbose') {LOG::set_verbose($val);}
+           if ($opt == 'keepalive' and $val === TRUE) {new Timer(60, array(&$this,'ping'), TRUE);}
+       }
+    }
+    
+    public function __destruct()
+    {
+       $this->disconnect();
+    }
+    
+    //подключение к серверу, инициализация
+    public function connect($host,$login,$password)
+    {
+       //add default ami port
+       if(count(explode(':', $host)) != 2)
+       {
+           $host .= ':5038';
+       }
+       //tcp connect
+        $this->conn_handle = @stream_socket_client("tcp://".$host, $errno, $errstr, 30);
+       if ($errno !== 0)
+       {
+           LOG::log('Could not connect to tcp socket. Reason: '.$errstr,2);
+           return FALSE;
+       }
+       if (!is_resource($this->conn_handle))
+       {
+           LOG::log('Socket not created! Check host and port options. Value: '.$host,2);
+           return FALSE;
+       }
+       stream_set_blocking($this->conn_handle,0);
+       LOG::log('Socket connected',4);
+       LOG::log('Server greeting phrase: '.stream_get_line ($this->conn_handle , 1500, "\r\n"),4);
+       $loginstatus =  $this->login($login, $password);
+       if ($loginstatus === FALSE)
+       {
+           stream_socket_shutdown($this->conn_handle,STREAM_SHUT_RDWR);
+           $this->conn_handle = FALSE;
+           return FALSE;
+       }
+       else
+       {    
+           return TRUE;
+       }    
+    }
+    
+    //отключение от сервера
+    public function disconnect()
+    {
+       if(!is_resource($this->conn_handle)){LOG::log('Call method '.__METHOD__.' failure. TCP connection is not established.',1);return FALSE;}
+       $this->logout();
+       stream_socket_shutdown($this->conn_handle,STREAM_SHUT_RDWR);
+       $this->conn_handle = FALSE;
+       LOG::log('Socket disconnected',4);
+    }
+    
+    //посылает запрос ping для реализации механизма keepalive
+    public function ping()
+    {
+       $response = $this->get_response($this->send_action('Ping'));
+       LOG::log('PING? PONG!: '.date("H:i:s", floatval($response["Timestamp"])),5);
+       return $response["Timestamp"];
+    }
+    
+    //авторизация на сервере
+    protected function login($login, $password)
+    {  
+       if(!is_resource($this->conn_handle)){LOG::log('Call method '.__METHOD__.' failure. TCP connection is not established.',1);return FALSE;}
+       $resp = $this->get_response($this->send_action('login', array('Username' => $login, 'Secret' => $password)));
+       if ($resp['Response'] == 'Success')
+       {
+           LOG::log('Authentication accepted',4);
+           return TRUE;
+       }
+       else
+       {
+           LOG::log('Authentication failed',2);
+           return FALSE;
+       }
+       
+    }
+    
+    //завершение сессии на сервере
+    protected function logout()
+    {
+       if(!is_resource($this->conn_handle)){LOG::log('Call method '.__METHOD__.' failure. TCP connection is not established.',1);return FALSE;}
+       $resp = $this->get_response($this->send_action('Logoff'));
+       LOG::log('Logout... Server goodbye phrase: '.$resp['Message'],4);
+    }
+
+    //низкоуровневое получение ответов по ID запроса
+    protected function get_response($ActId)
+    {  
+       $retval = FALSE;
+       for($cnt=0;$cnt<500;$cnt++)
+       {
+           usleep(10000);
+           if (isset($this->responses[$ActId]))
+           {
+               $retval = $this->responses[$ActId];
+               unset($this->responses[$ActId]);
+               break;
+           }
+           $this->refresh();
+       }
+       return $retval;
+    }
+    
+    //добавление обработчика событий
+    public function add_event_handler($event, $callback)
+    {
+       $event = strtolower($event);
+       if (is_array($callback))
+       {
+           $callbackname = get_class($callback[0])."->".$callback[1];
+       }
+       else
+       {
+           $callbackname = $callback;
+       }
+       if(!is_callable($callback))
+       {
+           LOG::log("${callbackname} does not exist! Nothing to add as event handler...",3);
+           return FALSE;
+       }
+       if (!isset($this->event_handlers[$event]))
+       {
+           $this->event_handlers[$event] = $callback;
+           LOG::log('Event handler for events type "'.$event.'" was added as callable "'.$callbackname.'"',4);
+           return TRUE;
+       }
+       else
+       {
+           LOG::log('Event handler for events type "'.$event.'" already exist as callable "'.$this->event_handlers[$event].'"',3);
+           return FALSE;
+       }   
+    }
+    
+    //удаление обработчика событий
+    public function remove_event_handler($event)
+    {
+       $event = strtolower($event);
+       if (isset($this->event_handlers[$event]))
+       {
+           unset($this->event_handlers[$event]);   
+           LOG::log('Event handler for events type "'.$event.'" was removed',4);
+           return TRUE;
+       }
+       else
+       {
+           LOG::log('Event handler for events type "'.$event.'" not exist',3);
+           return FALSE;
+       }
+    }
+    
+    //получение callback обработчика
+    public function get_event_handler($event)
+    {
+       $event = strtolower($event);
+       if (isset($this->event_handlers[$event]))
+       {
+           return $this->event_handlers[$event];
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+
+
+    //подписка на события ami
+    public function enable_events($toggle = FALSE)
+    {
+       if(!is_resource($this->conn_handle)){LOG::log('Call method '.__METHOD__.' failure. TCP connection is not established.',1);return FALSE;}
+       if($toggle === TRUE)
+       {
+           $eventlist = 'on';
+       }
+       else
+       {
+           $eventlist = 'off';
+       }
+               $ActId = $this->send_action('Events', array('Eventmask' => $eventlist));
+       
+       $res=$this->get_response($ActId);
+       if (isset($res['Events']))
+       {
+           if ($res['Events'] == 'On')
+           {
+               LOG::log('Events enabled',4);
+               return TRUE;
+           }
+       }
+       LOG::log('Events disabled',4);
+       return FALSE;
+    }
+    
+    //обработчик событий
+    protected function event_poller()
+    {
+       foreach ($this->events as $index => $event)
+       {
+           
+           $event_name = strtolower($event['Event']);
+           if (isset($this->event_handlers[$event_name]))
+           {
+               $run_handler = $this->event_handlers[$event_name];
+           }
+           elseif (isset($this->event_handlers['*']))
+           {
+               $run_handler = $this->event_handlers['*'];
+           }
+           else
+           {
+               $run_handler = FALSE;
+           }
+           if(is_array($run_handler))
+           {
+               $run_handler_name = get_class($run_handler[0])."->".$run_handler[1];
+           }
+           else
+           {
+               $run_handler_name = $run_handler;
+           }
+           if ($run_handler === FALSE)
+           {
+               LOG::log("Got event '${event_name}', but no handler for processing it.",6);
+           }
+           else
+           {
+               LOG::log("Got event '${event_name}', runing '${run_handler_name}' handler for processing it.",5);
+               $ret_h_data = call_user_func($run_handler, $event_name, $event);
+           }
+           unset($this->events[$index]);
+       }
+    }
+
+    //низкоуровневая отправка запросов
+    protected function send_action($action,$params = [])
+    {  
+       if(!is_resource($this->conn_handle)){LOG::log('Call method '.__METHOD__.' failure. TCP connection is not established.',1);return FALSE;}
+       if (!is_string($action)){return FALSE;}
+       if (!is_array($params)){return FALSE;}
+       if (!isset($params['ActionID'])){$params['ActionID'] = uniqid();}
+       $packet = 'Action: '.$action."\r\n";
+       foreach ($params as $param => $param_value)
+       {
+           $packet .= $param.': '.$param_value."\r\n";
+       }
+       $packet .= "\r\n";
+       stream_socket_sendto ($this->conn_handle, $packet);
+       $this->refresh();
+       return $params['ActionID'];
+    }
+    
+    //обновление данных от сервера
+    public function refresh()
+    {
+       if ($this->refresh_lock){return;}
+       $this->refresh_lock = TRUE;
+       if(!is_resource($this->conn_handle)){LOG::log('Call method '.__METHOD__.' failure. TCP connection is not established.',1);return FALSE;}
+       
+       while($this->update_inbound_stream())
+       {
+           $this->parse_inbound_stream_buffer();
+       }
+       $this->event_poller();
+       $this->refresh_lock = FALSE;
+    }
+    //получение одной пачки данных из входящего потока от сервера в буфер пачек
+    protected function update_inbound_stream()
+    {
+       if(!is_resource($this->conn_handle)){LOG::log('Call method '.__METHOD__.' failure. TCP connection is not established.',1);return FALSE;}
+       while(TRUE)
+       {
+           $raw_data = stream_get_line ($this->conn_handle , 1500, "\r\n"); //получение сырых данных с парсингом по переводу строк
+           if ($raw_data === ''){break;} //пустая строка означает конец пакета
+           if ($raw_data === FALSE){return FALSE;} //false означает осутствие данных
+           $inbound_packet[] = $raw_data;  //формирование пакета для помещения во входной буфер
+       }
+       if (isset($inbound_packet)) //если пакет сформирован (а бывает и наоборот), то помещаем в буфер, иначе считаем что данных нет
+       {
+           $this->inbound_stream_buffer[] = $inbound_packet; 
+           return TRUE;    
+       }
+       else
+       {
+           return FALSE;
+       }
+    }
+    
+    //парсер пачек извлекаемых из буфера и помещаемых в буферы ответов и очередей
+    protected function parse_inbound_stream_buffer()
+    {
+       foreach ($this->inbound_stream_buffer as $index => $inbound_packet)
+       {
+           foreach ($inbound_packet as $line)
+           {
+               $parse_result = preg_match('/(^.[^ ]*): (.*)/', $line, $parsed_line);
+               if ($parse_result === 1)
+               {
+                   $pack[$parsed_line[1]] = $parsed_line[2];
+               }
+               else
+               {
+                   $pack['RAW'] = $line;
+               }
+           }
+           if (isset($pack['Response']))
+           {
+               if ($pack['Response'] == "Error")
+               {
+                   LOG::log('ERROR RESPONSE: '.$pack["Message"],3);
+               }
+               $this->responses[$pack['ActionID']] = $pack;
+           }
+           if (isset($pack['Event']))
+           {
+               $this->events[] = $pack;
+           }
+           unset($pack);
+           unset($this->inbound_stream_buffer[$index]);            
+       }
+    }
+}
\ No newline at end of file
diff --git a/astapilib/common.php b/astapilib/common.php
new file mode 100644 (file)
index 0000000..f4fd641
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+class LOG
+{
+    private static $mode='console';
+    private static $verbose = 0;
+    public function __construct()
+    {
+       
+    }
+
+    private static function console($message)
+    {
+       echo date("M d H:i:s"),  substr(microtime(),1,6),' ',$message,PHP_EOL;
+    }
+
+    public static function set_verbose($level)
+    {
+       self::$verbose = (int)$level;
+    }
+    public static function get_verbose()
+    {
+       return self::$verbose;
+    }
+
+    public static function set_mode($mode)
+    {
+       self::$mode = $mode;
+    }
+    public static function get_mode()
+    {
+       return self::$mode;
+    }
+
+    public static function log($message, $level = 9)
+    {
+       if (self::$verbose < $level)
+       {
+           return;
+       }
+       switch (self::$mode)
+       {
+           case 'console':
+               self::console($message);
+               break;
+           default:
+               
+       }
+    }
+}
\ No newline at end of file
diff --git a/balancechan_new.php b/balancechan_new.php
new file mode 100644 (file)
index 0000000..4c35738
--- /dev/null
@@ -0,0 +1,130 @@
+#!/usr/bin/env php
+<?php
+//init
+date_default_timezone_set('Etc/GMT-11');
+require_once('astapilib/agi.php');
+set_time_limit(0);
+declare(ticks = 1);
+function on_hangup($signo)
+{
+    global $AGI;
+    $AGI->Verbose('Originate channel hanguped');
+    store_to_db();
+    die();
+}
+
+function store_to_db()
+{
+    global $AGI, $db, $usedchan;
+    $dur =(int) $AGI->GetVariable('CDR(billsec)');
+    $AGI->Verbose("STORE DATA: channel {$usedchan} duration {$dur} secs.",3);
+    if ($dur == 0)
+    {
+       return;
+    }
+    try {
+       $qdb = $db->exec("UPDATE channels SET duration = duration + {$dur} WHERE channel = '{$usedchan}'");
+    }
+    catch(PDOException $e) {
+           $AGI->Verboseerbose("DB ALERT: ".$e->getMessage(),3);
+           die();
+    }
+    if ($qdb == 0){
+           $AGI->Verbose("DATABASE NOT UPDATED!",3);
+    }
+    
+}
+
+pcntl_signal(SIGHUP,  "on_hangup");
+$AGI = new AGI();
+
+$timeout = 90;
+$opts = '';
+
+// Удаляется имя звонящего из CALLERID на всякий случай, поскольку на шлюзах может только проблемы создавать и не используется
+$AGI->SetVariable('CALLERID(name)', '');
+$dialnumber = $argv[2];
+
+$db = new PDO('sqlite:'.dirname(__FILE__).'/extastcfg.db');
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+try 
+{
+    $db->exec('CREATE TABLE IF NOT EXISTS channels (
+    id INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
+    channel VARCHAR(255)  NOT NULL UNIQUE,
+    groupname VARCHAR(255)  NOT NULL,
+    duration INTEGER,
+    is_active INTEGER
+    )');
+}
+catch(PDOException $e) 
+{
+    $AGI->Verboseerbose("DB ALERT: ".$e->getMessage(),3);
+    die();
+}
+
+// Получаю массив с информацией о группе каналов
+try
+{
+    $qdb = $db->query("SELECT * FROM channels WHERE groupname = '{$argv[1]}' and is_active = 1 order by duration");
+}
+catch(PDOException $e) 
+{
+    $AGI->Verboseerbose("DB ALERT: ".$e->getMessage(),3);
+    die();
+}
+$qdb->setFetchMode(PDO::FETCH_ASSOC);
+$rows = $qdb->fetchAll();
+//перебор каналов, совершение вызова
+foreach ($rows as $row)
+{
+    $usedchan = $row['channel'];
+    $AGI->Exec('Dial',$row['channel'].$dialnumber.','.$timeout.',Ttg'.$opts);
+    $CAUSECODE = $AGI->GetVariable('HANGUPCAUSE');
+    $SIP_CAUSE = $AGI->GetVariable('SIP_CAUSE');
+    $AGI->Verbose("CAUSECODE = ".$CAUSECODE);
+    // 17 - channel is used
+    if ($CAUSECODE == '16') //NORMAL
+    {
+       break;
+       
+    } 
+    if ($CAUSECODE == '0') //CANCEL
+    {
+       break;
+    } 
+    if ($CAUSECODE == '19') //cause translate from 19 (addpack busy) 17 (isdn busy)
+    {
+       $AGI->Exec('Playtones','busy');
+       $AGI->Exec('Busy');
+       break;
+    } 
+}
+if ($CAUSECODE == '17' || $CAUSECODE == '20') //last cause code 
+{
+    $logdata = date("Y-m-d H:i:s")." All channels are busy S:{$SIP_CAUSE} I:{$CAUSECODE}\n";
+    file_put_contents(dirname(__FILE__).'/balancechan.log',$logdata,FILE_APPEND);
+    $AGI->Exec('Playtones','info');
+    sleep(2);
+    $AGI->Exec('Playback','all-circuits-busy-now&pls-try-call-later,noanswer');
+    $AGI->Exec('Playtones','congestion');
+    $AGI->Exec('Congestion');
+}
+store_to_db();
+unset($qdb);
+unset($db);
+
+/*    case 'reset':
+               try {
+                   $qdb = $db->exec("UPDATE channels SET duration = 0 WHERE  groupname = '{$argv[2]}'");
+               }
+               catch(PDOException $e) {
+                       print("DB ALERT: ".$e->getMessage());
+                       die();
+               }
+               
+               break;
+    default:
+               die("Illegal command\n");
+
+*/
diff --git a/balancechan_reset.php b/balancechan_reset.php
new file mode 100644 (file)
index 0000000..782d373
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+<?php
+
+
+$db = new PDO('sqlite:'.dirname(__FILE__).'/extastcfg.db');
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+try 
+{
+    $db->exec('CREATE TABLE IF NOT EXISTS channels (
+    id INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
+    channel VARCHAR(255)  NOT NULL UNIQUE,
+    groupname VARCHAR(255)  NOT NULL,
+    duration INTEGER,
+    is_active INTEGER
+    )');
+}
+catch(PDOException $e) 
+{
+    $AGI->Verboseerbose("DB ALERT: ".$e->getMessage(),3);
+    die();
+}
+try 
+{
+    $qdb = $db->exec("UPDATE channels SET duration = 0 WHERE  groupname = '{$argv[1]}'");
+}
+catch(PDOException $e) 
+{
+    print("DB ALERT: ".$e->getMessage());
+    die();
+}
+               
+
+unset($qdb);
+unset($db);
+
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644 (file)
index 0000000..8b7302c
--- /dev/null
@@ -0,0 +1,7 @@
+include.path=${php.global.include.path}\r
+php.version=PHP_54\r
+source.encoding=UTF-8\r
+src.dir=.\r
+tags.asp=false\r
+tags.short=false\r
+web.root=.\r
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644 (file)
index 0000000..d4f7c72
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://www.netbeans.org/ns/project/1">\r
+    <type>org.netbeans.modules.php.project</type>\r
+    <configuration>\r
+        <data xmlns="http://www.netbeans.org/ns/php-project/1">\r
+            <name>dev</name>\r
+        </data>\r
+    </configuration>\r
+</project>\r