Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.

Commit ef3de4d

Browse files
author
Arbuzov Sergey
committed
Merge pull request #4 from ipoddubny/master
Updated the code to work with Welltime Отлично! В версию!
2 parents 340c29f + c0ed0e4 commit ef3de4d

File tree

3 files changed

+159
-64
lines changed

3 files changed

+159
-64
lines changed

mkdocs.php

100644100755
File mode changed.

phpagi-asmanager.php

Lines changed: 159 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,16 @@ class AGI_AsteriskManager
8888
*/
8989
private $event_handlers;
9090

91+
private $_buffer = NULL;
92+
9193
/**
9294
* Whether we're successfully logged in
9395
*
9496
* @access private
9597
* @var boolean
9698
*/
9799
private $_logged_in = FALSE;
98-
100+
99101
/**
100102
* Constructor
101103
*
@@ -119,6 +121,7 @@ function AGI_AsteriskManager($config=NULL, $optconfig=array())
119121
if(!isset($this->config['asmanager']['port'])) $this->config['asmanager']['port'] = 5038;
120122
if(!isset($this->config['asmanager']['username'])) $this->config['asmanager']['username'] = 'phpagi';
121123
if(!isset($this->config['asmanager']['secret'])) $this->config['asmanager']['secret'] = 'phpagi';
124+
if(!isset($this->config['asmanager']['write_log'])) $this->config['asmanager']['write_log'] = false;
122125
}
123126

124127
/**
@@ -131,19 +134,79 @@ function AGI_AsteriskManager($config=NULL, $optconfig=array())
131134
function send_request($action, $parameters=array())
132135
{
133136
$req = "Action: $action\r\n";
134-
foreach($parameters as $var=>$val)
135-
{
136-
// Модификация. Передача нескольких параметров
137-
if (is_array($val))
138-
foreach ($val as $l){
139-
$req .= "$var: $l\r\n";
137+
$actionid = null;
138+
foreach ($parameters as $var=>$val) {
139+
if (is_array($val)) {
140+
foreach ($val as $line) {
141+
$req .= "$var: $line\r\n";
140142
}
141-
else
143+
} else {
142144
$req .= "$var: $val\r\n";
145+
if (strtolower($var) == "actionid") {
146+
$actionid = $val;
147+
}
148+
}
149+
}
150+
if (!$actionid) {
151+
$actionid = $this->ActionID();
152+
$req .= "ActionID: $actionid\r\n";
143153
}
144154
$req .= "\r\n";
155+
145156
fwrite($this->socket, $req);
146-
return $this->wait_response();
157+
158+
return $this->wait_response(false, $actionid);
159+
}
160+
161+
function read_one_msg($allow_timeout = false)
162+
{
163+
$type = null;
164+
165+
while(false === ($pos = strpos($this->_buffer, "\r\n\r\n"))) {
166+
$this->_buffer .= @fgets($this->socket, 4096);
167+
}
168+
$msg = substr($this->_buffer, 0, $pos);
169+
$this->_buffer = substr($this->_buffer, $pos+4);
170+
171+
$msgarr = explode("\r\n", $msg);
172+
173+
$parameters = array();
174+
175+
$r = explode(': ', $msgarr[0]);
176+
$type = strtolower($r[0]);
177+
178+
if ($r[1] == 'Follows') {
179+
$str = array_pop($msgarr);
180+
$lastline = strpos($str, '--END COMMAND--');
181+
if (false !== $lastline) {
182+
$parameters['data'] = substr($str, 0, $lastline-1); // cut '\n' too
183+
}
184+
}
185+
186+
foreach ($msgarr as $num=>$str) {
187+
$kv = explode(': ', $str);
188+
$key = $kv[0];
189+
$val = $kv[1];
190+
$parameters[$key] = $val;
191+
}
192+
193+
// process response
194+
switch($type)
195+
{
196+
case '': // timeout occured
197+
$timeout = $allow_timeout;
198+
break;
199+
case 'event':
200+
$this->process_event($parameters);
201+
break;
202+
case 'response':
203+
break;
204+
default:
205+
$this->log('Unhandled response packet from Manager: ' . print_r($parameters, true));
206+
break;
207+
}
208+
209+
return $parameters;
147210
}
148211

149212
/**
@@ -152,64 +215,44 @@ function send_request($action, $parameters=array())
152215
* If a request was just sent, this will return the response.
153216
* Otherwise, it will loop forever, handling events.
154217
*
218+
* XXX this code is slightly better then the original one
219+
* however it's still totally screwed up and needs to be rewritten,
220+
* for two reasons at least:
221+
* 1. it does not handle socket errors in any way
222+
* 2. it is terribly synchronous, esp. with eventlists,
223+
* i.e. your code is blocked on waiting until full responce is received
224+
*
155225
* @param boolean $allow_timeout if the socket times out, return an empty array
156226
* @return array of parameters, empty on timeout
157227
*/
158-
function wait_response($allow_timeout=false)
228+
function wait_response($allow_timeout = false, $actionid = null)
159229
{
160-
$timeout = false;
161-
do
162-
{
163-
$type = NULL;
164-
$parameters = array();
165-
166-
$buffer = trim(fgets($this->socket, 4096));
167-
while($buffer != '')
168-
{
169-
$a = strpos($buffer, ':');
170-
if($a)
171-
{
172-
if(!count($parameters)) // first line in a response?
173-
{
174-
$type = strtolower(substr($buffer, 0, $a));
175-
if(substr($buffer, $a + 2) == 'Follows')
176-
{
177-
// A follows response means there is a miltiline field that follows.
178-
$parameters['data'] = '';
179-
$buff = fgets($this->socket, 4096);
180-
while(substr($buff, 0, 6) != '--END ')
181-
{
182-
$parameters['data'] .= $buff;
183-
$buff = fgets($this->socket, 4096);
184-
}
185-
}
186-
}
187-
188-
// store parameter in $parameters
189-
$parameters[substr($buffer, 0, $a)] = substr($buffer, $a + 2);
190-
}
191-
$buffer = trim(fgets($this->socket, 4096));
192-
}
230+
$res = array();
231+
if ($actionid) {
232+
do {
233+
$res = $this->read_one_msg($allow_timeout);
234+
} while (!( isset($res['ActionID']) && $res['ActionID']==$actionid ));
235+
} else {
236+
$res = $this->read_one_msg($allow_timeout);
237+
return $res;
238+
}
193239

194-
// process response
195-
switch($type)
196-
{
197-
case '': // timeout occured
198-
$timeout = $allow_timeout;
240+
if (isset($res['EventList']) && $res['EventList']=='start') {
241+
$evlist = array();
242+
do {
243+
$res = $this->wait_response(false, $actionid);
244+
if (isset($res['EventList']) && $res['EventList']=='Complete')
199245
break;
200-
case 'event':
201-
$this->process_event($parameters);
202-
break;
203-
case 'response':
204-
break;
205-
default:
206-
$this->log('Unhandled response packet from Manager: ' . print_r($parameters, true));
207-
break;
208-
}
209-
} while($type != 'response' && !$timeout);
210-
return $parameters;
246+
else
247+
$evlist[] = $res;
248+
} while(true);
249+
$res['events'] = $evlist;
250+
}
251+
252+
return $res;
211253
}
212254

255+
213256
/**
214257
* Connect to Asterisk
215258
*
@@ -344,6 +387,36 @@ function Events($eventmask)
344387
return $this->send_request('Events', array('EventMask'=>$eventmask));
345388
}
346389

390+
/**
391+
* Generate random ActionID
392+
**/
393+
function ActionID()
394+
{
395+
return "A".sprintf(rand(),"%6d");
396+
}
397+
398+
/**
399+
*
400+
* DBGet
401+
* http://www.voip-info.org/wiki/index.php?page=Asterisk+Manager+API+Action+DBGet
402+
* @param string $family key family
403+
* @param string $key key name
404+
**/
405+
function DBGet($family, $key, $actionid = NULL)
406+
{
407+
$parameters = array('Family'=>$family, 'Key'=>$key);
408+
if($actionid == NULL)
409+
$actionid = $this->ActionID();
410+
$parameters['ActionID'] = $actionid;
411+
$response = $this->send_request("DBGet", $parameters);
412+
if($response['Response'] == "Success")
413+
{
414+
$response = $this->wait_response(false, $actionid);
415+
return $response['Val'];
416+
}
417+
return "";
418+
}
419+
347420
/**
348421
* Check Extension Status
349422
*
@@ -453,7 +526,7 @@ function MailboxCount($mailbox, $actionid=NULL)
453526
* @param string $actionid message matching variable
454527
*/
455528
function MailboxStatus($mailbox, $actionid=NULL)
456-
{
529+
{
457530
$parameters = array('Mailbox'=>$mailbox);
458531
if($actionid) $parameters['ActionID'] = $actionid;
459532
return $this->send_request('MailboxStatus', $parameters);
@@ -516,7 +589,7 @@ function Originate($channel,
516589
if($actionid) $parameters['ActionID'] = $actionid;
517590

518591
return $this->send_request('Originate', $parameters);
519-
}
592+
}
520593

521594
/**
522595
* List parked calls
@@ -549,11 +622,13 @@ function Ping()
549622
* @param string $queue
550623
* @param string $interface
551624
* @param integer $penalty
625+
* @param string $memberName
552626
*/
553-
function QueueAdd($queue, $interface, $penalty=0)
627+
function QueueAdd($queue, $interface, $penalty=0, $memberName = false)
554628
{
555629
$parameters = array('Queue'=>$queue, 'Interface'=>$interface);
556630
if($penalty) $parameters['Penalty'] = $penalty;
631+
if($memberName) $parameters["MemberName"] = $memberName;
557632
return $this->send_request('QueueAdd', $parameters);
558633
}
559634

@@ -746,7 +821,7 @@ function log($message, $level=1)
746821
{
747822
if($this->pagi != false)
748823
$this->pagi->conlog($message, $level);
749-
else
824+
elseif($this->config['asmanager']['write_log'])
750825
error_log(date('r') . ' - ' . $message);
751826
}
752827

@@ -801,6 +876,24 @@ function add_event_handler($event, $callback)
801876
$this->event_handlers[$event] = $callback;
802877
return true;
803878
}
879+
/**
880+
*
881+
* Remove event handler
882+
*
883+
* @param string $event type or * for default handler
884+
* @return boolean sucess
885+
**/
886+
function remove_event_handler($event)
887+
{
888+
$event = strtolower($event);
889+
if(isset($this->event_handlers[$event]))
890+
{
891+
unset($this->event_handlers[$event]);
892+
return true;
893+
}
894+
$this->log("$event handler is not defined.");
895+
return false;
896+
}
804897

805898
/**
806899
* Process event
@@ -813,7 +906,7 @@ function process_event($parameters)
813906
{
814907
$ret = false;
815908
$e = strtolower($parameters['Event']);
816-
$this->log("Got event.. $e");
909+
$this->log("Got event.. $e");
817910

818911
$handler = '';
819912
if(isset($this->event_handlers[$e])) $handler = $this->event_handlers[$e];
@@ -823,6 +916,8 @@ function process_event($parameters)
823916
{
824917
$this->log("Execute handler $handler");
825918
$ret = $handler($e, $parameters, $this->server, $this->port);
919+
} elseif (is_array($handler)) {
920+
$ret = call_user_func($handler, $e, $parameters, $this->server, $this->port);
826921
}
827922
else
828923
$this->log("No event handler for event '$e'");

phpagi-fastagi.php

100644100755
File mode changed.

0 commit comments

Comments
 (0)