From dda16b191f06ea1128b3e38dab34897658802123 Mon Sep 17 00:00:00 2001 From: direct Date: Thu, 23 Nov 2017 15:46:21 +1000 Subject: [PATCH] new --- astapilib/agi.php | 646 +++++++++++ astapilib/ami.php | 1982 ++++++++++++++++++++++++++++++++++ astapilib/baseagi.php | 113 ++ astapilib/baseami.php | 345 ++++++ astapilib/common.php | 50 + balancechan_new.php | 130 +++ balancechan_reset.php | 35 + nbproject/project.properties | 7 + nbproject/project.xml | 9 + 9 files changed, 3317 insertions(+) create mode 100644 astapilib/agi.php create mode 100644 astapilib/ami.php create mode 100644 astapilib/baseagi.php create mode 100644 astapilib/baseami.php create mode 100644 astapilib/common.php create mode 100644 balancechan_new.php create mode 100644 balancechan_reset.php create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml diff --git a/astapilib/agi.php b/astapilib/agi.php new file mode 100644 index 0000000..c74de23 --- /dev/null +++ b/astapilib/agi.php @@ -0,0 +1,646 @@ + $pval) + { + if (is_null($pval)) + { + break; + } + $retval .= ' "'.$pval.'"'; + } + return $retval; + } + + //Logs a message to the asterisk verbose log. + public function Verbose ($message, $level = 1) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'verbose'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Answer channel + public function Answer() + { + $cmd = 'answer'; + $process_result = $this->ProcessCmd($cmd); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 0) + { + return TRUE; + } + } + return FALSE; + } + + //Hangup a channel. + public function Hangup($channelname = NULL) + { + $cmd = 'hangup'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return TRUE; + } + } + return FALSE; + } + + //Does nothing. + public function Noop() + { + $cmd = 'noop'; + $process_result = $this->ProcessCmd($cmd); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return TRUE; + } + } + return FALSE; + } + + //Returns status of the connected channel. + /*Return values: + 0 - Channel is down and available. + 1 - Channel is down, but reserved. + 2 - Channel is off hook. + 3 - Digits (or equivalent) have been dialed. + 4 - Line is ringing. + 5 - Remote end is ringing. + 6 - Line is up. + 7 - Line is busy. + */ + public function ChannelStatus ($channelname = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'channel status'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == -1) + { + return FALSE; + } + return $process_result['result']['val']; + } + return FALSE; + } + + //Gets a channel variable. + public function GetVariable ($variablename) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'get variable'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return $process_result['result']['data']; + } + } + return FALSE; + } + + //Evaluates a channel expression + public function GetFullVariable ($variablename, $channelname = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'get full variable'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return $process_result['result']['data']; + } + } + return FALSE; + } + + //Sets a channel variable. + public function SetVariable ($variablename , $value) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'Set variable'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Adds/updates database value + public function DatabasePut ($family, $key, $value) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'database put'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return TRUE; + } + } + return FALSE; + } + + //Gets database value + public function DatabaseGet ($family, $key) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'database get'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return $process_result['result']['data']; + } + } + return FALSE; + } + + //Removes database key/value + public function DatabaseDel ($family, $key) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'database del'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return TRUE; + } + } + return FALSE; + } + + //Removes database keytree/value + public function DatabaseDeltree ($family, $keytree = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'get data'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 0) // в документации сказано, что должна быть еденица, на деле, все наоборот, возможно будет исправлено в будущем + { + return TRUE; + } + } + return FALSE; + } + + //Executes a given Application + public function Exec ($application, $options = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'exec'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -2) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Prompts for DTMF on a channel + public function GetData ($file, $timeout = NULL, $maxdigits = NULL) + { + $timeout = $timeout * 1000; + $params = $this->make_params(get_defined_vars()); + $cmd = 'get data'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Stream file, prompt for DTMF, with timeout. + public function GetOption ($file, $escape_digits, $timeout = NULL) + { + $timeout = $timeout * 1000; + $params = $this->make_params(get_defined_vars()); + $cmd = 'get option'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']]; + } + } + return FALSE; + } + + //Sends audio file on channel. + public function StreamFile ($filename, $escape_digits, $sample_offset = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'stream file'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']]; + } + } + return FALSE; + } + + //Receives one character from channels supporting it. + //нет возможности проверить + public function ReceiveChar ($timeout) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'receive char'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Receives text from channels supporting it. + //нет возможности проверить + public function ReceiveText ($timeout) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'receive text'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['data']; + } + } + return FALSE; + } + + //Records to a given file. + public function RecordFile ($filename, $format, $escape_digits, $timeout = -1, $offset_samples = NULL, $BEEP = NULL, $silence = NULL) + { + if ($timeout != -1) + { + $timeout = $timeout * 1000; + } + if ($silence !== NULL) + { + $silence = 's='.$silence; + } + $params = $this->make_params(get_defined_vars()); + $cmd = 'record file'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']]; + } + } + return FALSE; + } + + //Says a given character string. + public function SayAlpha ($number, $escape_digits = '') + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'say alpha'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Says a given digit string. + public function SayDigits ($number, $escape_digits = '') + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'say digits'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Says a given number. + public function SayNumber ($number, $escape_digits = '', $gender = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'say number'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Says a given character string with phonetics. + public function SayPhonetic ($number, $escape_digits = '') + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'say phonetic'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + //Says a given date. (Unix time) + public function SayDate ($date, $escape_digits = '') + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'say date'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Says a given time. (Unix time) + public function SayTime ($time, $escape_digits = '') + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'say time'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Says a given time as specified by the format given. (почему то не работает, не понятен формат) + public function SayDatetime ($time, $escape_digits = '', $format = NULL, $timezone = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'say datetime'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Sends images to channels supporting it. + public function SendImage ($image) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'send image'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return TRUE; + } + } + return FALSE; + } + + //Sends text to channels supporting it. + public function SendText ($text_to_send) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'send text'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return TRUE; + } + } + return FALSE; + } + + //Autohangup channel in some time. + public function SetAutohangup ($time) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'set autohangup'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Sets callerid for the current channel. + public function SetCallerid ($number) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'set callerid'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Sets channel context. + public function SetContext ($context) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'set context'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Changes channel extension. + public function SetExtension ($extension) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'set extension'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Enable/Disable Music on hold generator + public function SetMusicOn ($class = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'set music on'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Enable/Disable Music on hold generator + public function SetMusicOff ($class = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'set music off'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Enable/Disable Music on hold generator + public function SetPriority ($priority) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'set priority'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + return TRUE; + } + return FALSE; + } + + //Sends audio file on channel and allows the listener to control the stream. + public function ControlStreamFile ($filename, $escape_digits, $skipms = NULL, $ffchar = NULL, $rewchr = NULL, $pausechr = NULL, $offsetms = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'control stream file'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return ['result' => $process_result['result']['val'], 'endpos' => $process_result['endpos']['val']]; + } + } + return FALSE; + } + + //Toggles TDD mode (for the deaf). параметры следует уточнить, не понятно что указывать + public function TddMode ($mode) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'tdd mode'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] == 1) + { + return TRUE; + } + } + return FALSE; + } + + //Waits for a digit to be pressed. + public function WaitForDigit ($timeout = -1) + { + if ($timeout != -1) + { + $timeout = $timeout * 1000; + } + $params = $this->make_params(get_defined_vars()); + $cmd = 'wait for digit'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } + + //Cause the channel to execute the specified dialplan subroutine. Должным образом не проверялось,что должно возвращаться не понятно. + public function Gosub ($context, $extension, $priority, $optional_argument = NULL) + { + $params = $this->make_params(get_defined_vars()); + $cmd = 'gosub'; + $process_result = $this->ProcessCmd($cmd.$params); + if ($process_result['code'] == 200) + { + if ($process_result['result']['val'] != -1) + { + return $process_result['result']['val']; + } + } + return FALSE; + } +} diff --git a/astapilib/ami.php b/astapilib/ami.php new file mode 100644 index 0000000..aeafd56 --- /dev/null +++ b/astapilib/ami.php @@ -0,0 +1,1982 @@ + $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 index 0000000..5daa8ee --- /dev/null +++ b/astapilib/baseagi.php @@ -0,0 +1,113 @@ +request = $this->ProcessRequest(); + if ($this->request === FALSE) + { + return FALSE; + } + } + //получение запроса + protected function ProcessRequest() + { + while(TRUE) + { + $line = stream_get_line (STDIN , 1500, PHP_EOL); //получение сырых данных с парсингом по переводу строк + if ($line === ''){break;} //пустая строка означает конец пакета + if ($line === FALSE){return FALSE;} //false означает осутствие данных + $parse_result = preg_match('/(^.[^ ]*): (.*)/', $line, $parsed_line); + if ($parse_result === 1) + { + $request[$parsed_line[1]] = $parsed_line[2]; + } + } + + if (isset($request)) + { + return $request; + } + else + { + return FALSE; + } + } + //обработка комманды + protected function ProcessCmd($cmd) + { + fwrite(STDOUT, $cmd.PHP_EOL); + $line = stream_get_line (STDIN , 1500, PHP_EOL); //получение сырых данных с парсингом по переводу строк + $parse_result = preg_match('/(\d+)(?:.)(.*)/', $line, $parsed_line); + if ($parse_result === 1) + { + $resp['code'] = (int) $parsed_line[1]; + $data = $parsed_line[2]; + if ($resp['code'] == 200) + { + $parse_result = preg_match_all("/(?:(?'rval'[^\ ]+=[^\ ]*))|(?:\s\((?'aval'.*?)\)(?:\s|$))/", $data, $parsed_line, PREG_SET_ORDER); + if ($parse_result != FALSE) + { + foreach ($parsed_line as $parsed_set) + { + if(isset($parsed_set['rval']) && !isset($parsed_set['aval'])) + { + $kv = explode('=', $parsed_set['rval']); + $resp[$kv[0]]['val'] = $kv[1]; + $lastparam = $kv[0]; + } + if(isset($parsed_set['aval']) && isset($lastparam)) + { + $resp[$lastparam]['data'] = $parsed_set['aval']; + } + } + } + $this->last_response = $resp; + return $resp; + } + else + { + $resp['error'] = $data; + $this->last_response = $resp; + return $resp; + } + } + else + { + $this->last_response = FALSE; + return FALSE; + } + } + //получение обработанного запроса или его частей + public function GetRequest($key = NULL) + { + if ($this->request === FALSE) + { + return FALSE; + } + if ($key === NULL) + { + return $this->request; + } + if (!isset($this->request[$key])) + { + return FALSE; + } + else + { + return $this->request[$key]; + } + } + + //получение последнего ответа целиком + public function GetLastResponse() + { + return $this->last_response; + } + +} \ No newline at end of file diff --git a/astapilib/baseami.php b/astapilib/baseami.php new file mode 100644 index 0000000..ca3bd13 --- /dev/null +++ b/astapilib/baseami.php @@ -0,0 +1,345 @@ + $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 index 0000000..f4fd641 --- /dev/null +++ b/astapilib/common.php @@ -0,0 +1,50 @@ +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 index 0000000..782d373 --- /dev/null +++ b/balancechan_reset.php @@ -0,0 +1,35 @@ +#!/usr/bin/env php +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 index 0000000..8b7302c --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,7 @@ +include.path=${php.global.include.path} +php.version=PHP_54 +source.encoding=UTF-8 +src.dir=. +tags.asp=false +tags.short=false +web.root=. diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..d4f7c72 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,9 @@ + + + org.netbeans.modules.php.project + + + dev + + + -- 2.39.5