<?php
###################################################################################################
# Aastra XML API - AastraAsterisk.php
# Copyright Aastra Telecom 2010
#
# Adapted from the phpagi manager available on Sourceforge
#
# This file includes a class that interfaces with the Asterisk Manager
#
# Public methods
#   connect(server,username,secret)
#   disconnect()
#   Command(command,actionid)
#   Originate(...)
#   database_show(family) 
#   database_put(family,key,value) 
#   database_get(family,key) 
#   database_del(family,key) 
#   ExtensionState(exten,context,actionid)
#
# Private methods
#   send_request(action,parameters)
#   wait_response(allow_timeout)
#   Logoff()
#   log(message)
#
###################################################################################################

###################################################################################################
# Main code
###################################################################################################
class AGI_AsteriskManager
{
	# Variables
	var $config;
	var $socket = NULL;
	var $server;
	var $port;
	var $event_handlers;
	var $timeout=False;

	# Constructor
	function AGI_AsteriskManager()
	{
		$this->config['username']='aastra-asterisk';
		$this->config['secret']='aastra-xml';

		# Add default values to config for uninitialized values
		if(!isset($this->config['server'])) $this->config['server']='localhost';
		if(!isset($this->config['port'])) $this->config['port']=5038;
	}

	function add_event_handler($event, $callback)
    	{
      		$event = strtolower($event);
      		if(isset($this->event_handlers[$event]))
      			{
        		$this->log("$event handler is already defined, not over-writing.");
        		return false;
      			}
      		$this->event_handlers[$event] = $callback;
      		return true;
    	}

	function process_event($parameters)
    	{
      		$ret = false;
      		$e = strtolower($parameters['Event']);
	      	$handler = '';
      		if(isset($this->event_handlers[$e])) $handler = $this->event_handlers[$e];
      		elseif(isset($this->event_handlers['*'])) $handler = $this->event_handlers['*'];
      		if(is_callable($handler)) $ret = call_user_func($handler, $e, $parameters, $this->server, $this->port);
      		return $ret;
	}

    	function send_request_nowait($action, $parameters=array())
    	{
      		$req="Action: $action\r\n";
	      	foreach($parameters as $var=>$val) $req.="$var: $val\r\n";
	      	$req.="\r\n";
      		fwrite($this->socket, $req);
    	}

	function send_request($action, $parameters=array())
	{
		$this->send_request_nowait($action, $parameters);
      		return $this->wait_response();
	}

	function events($mask='off')
	{
		return $this->send_request('Events', array('EventMask' => $mask));
	}

	function get_socket()
	{
		if($this->socket) return(True);
		else return(False);
	}

	function wait_response($allow_timeout=False)
    	{
     		$timeout=False;
      		do
      			{
        		$type='';
        		$parameters=array();
        		$temp=fgets($this->socket, 4096);
			if($temp===False) 
				{
				$check=stream_get_meta_data($this->socket);
				if($check['timed_out']!='1')
					{
					$this->socket=NULL;
					break;	
					}
				else $buffer='';
				}
			else $buffer=trim($temp);

        		while($buffer != '')
        			{
          			$a = strpos($buffer, ':');
				if($a)
          				{
            				if(!count($parameters)) // first line in a response?
            					{
					$parameters['data'] = '';
              				$type=strtolower(substr($buffer, 0, $a));
              				if(substr($buffer,$a+2)=='Follows')
              					{
                					# A follows response means there is a multiline field that follows.
                					$buff=fgets($this->socket, 4096);
                					while(substr($buff, 0, 6) != '--END ')
                						{
                  						$parameters['data'].=$buff;
                  						$buff=fgets($this->socket,4096);
                						}
              					}
            					}

            				# Store parameter in $parameters
					$key = substr($buffer, 0, $a);
					$value = substr($buffer, $a+2);
					if ($key == 'Output') {
					    $parameters['data'] .= $value."\n";
					}
					$parameters[$key]=$value;
          				}
          			$buffer=trim(fgets($this->socket,4096));
        			}

        		# Process response
        		switch($type)
        			{
          			case '':
            				$timeout=$allow_timeout;
            				break;
          			case 'event':
            				$this->process_event($parameters);
            				break;
          			case 'response':
            				break;
          			default:
					error_log('Unhandled response packet from Manager: '.$type);
            				break;
        			}
      			} while($type!='response' && !$timeout);
      		return $parameters;
    	}

	function wait_event($timeout='60')
    	{
     		$exit=False;
		$time1=time();
      		do
      			{
        		$type='';
        		$parameters=array();
			stream_set_timeout($this->socket, $timeout);
        		$temp=fgets($this->socket, 4096);
			if($temp===False) 
				{
				$check=stream_get_meta_data($this->socket);
				if($check['timed_out']!='1')
					{
					$this->socket=NULL;
					break;	
					}
				else $buffer='';
				}
			else $buffer=trim($temp);
        		while($buffer!='')
        			{
          			$a=strpos($buffer, ':');
          			if($a)
          				{
            				if(!count($parameters)) 
            					{
              				$type=strtolower(substr($buffer,0,$a));
              				if(substr($buffer,$a+2)=='Follows')
              					{
                					# A follows response means there is a multiline field that follows.
                					$parameters['data']='';
                					$buff=fgets($this->socket, 4096);
                					while(substr($buff, 0, 6) != '--END ')
                						{
                  						$parameters['data'].=$buff;
                  						$buff=fgets($this->socket,4096);
                						}
              					}
            					}

            				# Store parameter in $parameters
            				$parameters[substr($buffer,0,$a)]=substr($buffer,$a+2);
          				}
          			$buffer=trim(fgets($this->socket,4096));
        			}

        		# Process response
        		switch($type)
        			{
          			case 'event':
            				$this->process_event($parameters);
					$exit=True;
            				break;
          			default:
            				if($type!='') $this->log('Unhandled response packet from Manager: '.$type);
            				break;
        			}

			# Check timeout
			$time2=time();
			if($time2>($time1+$timeout)) $exit=True;
      			} while(!$exit);
      		return $parameters;
    	}

	function listen($timeout=60)
	{
		$time1=time();
		do {
			$this->wait_event($timeout);
		} while (time() < $time1+$timeout);
	}


    	function connect($server=NULL,$username=NULL,$secret=NULL,$display=True)
    	{
		# OK so far
		$return=True;

      		# Use config if not specified
      		if(!isset($server)) $server = $this->config['server'];
      		if(!isset($username)) $username = $this->config['username'];
      		if(!isset($secret)) $secret = $this->config['secret'];

      		# Get port from server if specified
      		if(strpos($server, ':') !== false)
      			{
        		$c = explode(':', $server);
        		$this->server = $c[0];
        		$this->port = $c[1];
      			}
      		else
      			{
        		$this->server = $server;
        		$this->port = $this->config['port'];
      			}

      		# Connect the socket
      		$errno = $errstr = NULL;
      		$this->socket = @fsockopen($this->server, $this->port, $errno, $errstr);
      		if($this->socket == false)
      			{
        		$this->log("Unable to connect to manager {$this->server}:{$this->port} ($errno): $errstr");
			$return=False;
      			}

      		# Read the header
		if($return)
			{
	      		$str=fgets($this->socket);
     			if($str==false)
     				{
       			# Problem.
	        		$this->log("Asterisk Manager header not received.");
				$return=False;
				}
			}

      		# Login
		if($return)
			{
	      		$res=$this->send_request('login', array('Username'=>$username, 'Secret'=>$secret));
      			if($res['Response'] != 'Success')
      				{
        			$this->log('Failed to login using ['.$username.'] for username and ['.$secret.'] for the password.');
	        		fclose($this->socket);
       	 		$return=False; 
      				}
			}

		# Timeout
		if($return) stream_set_timeout($this->socket,30); 

		# Error message
		if(!$return and $display)
			{
			$output = "<AastraIPPhoneTextScreen>\n";
			$output .= "<Title>Configuration error</Title>\n";
			$output .= "<Text>The application cannot connect to the Asterisk Manager. Please contact your administrator.</Text>\n";
			$output .= "</AastraIPPhoneTextScreen>\n";
			header('Content-Type: text/xml');
			header('Content-Length: '.strlen($output));
			echo $output;
			exit;
			}

		# Return result
      		return($return);
    	}

    	function disconnect()
    		{
      		$this->logoff();
      		fclose($this->socket);
    		}

    	function Command($command, $actionid=NULL)
    	{
      		$parameters = array('Command'=>$command);
      		if($actionid) $parameters['ActionID'] = $actionid;
      		return $this->send_request('Command', $parameters);
    	}

	function CommandArray($command, $actionid=NULL) {
		$ret = $this->Command($command, $actionid);
		$arr = preg_split("\n", $ret['data']);
		# remove the header line
		unset($arr[0]);
		$retval = array();

		for ($i = 0; $i < count($arr); $i++) {
			$retval[$i] = preg_split("/\s+/", $arr[$i+1]);
		}

		return $retval;
	}

	function hangup($channel) {
		$parameters=array('Channel'=>$channel);
		return $this->send_request('Hangup', $parameters);
	}

	function playDTMF($channel, $digit) {
		$parameters=array('Channel'=>$channel,'Digit'=>$digit);
		$this->log_array('PLAY DTMF', $parameters);
		$err = $this->send_request('PlayDTMF', $parameters);
		$this->log_array('PLAY DTMF RETURNS', $err);
		return $err;
	}

	function get_user() {
		$ret = $this->Command('sip show peers');
		$ret = explode("\n", $ret['data']);
		for ($i = 1; $i < count($ret) - 1; $i++) {
			$a = preg_split("/\s+/", $ret[$i]);
			if (strcmp($a[1], $_SERVER['REMOTE_ADDR']) == 0) {
				$n = explode("/", $a[0]);
				return $n[0];
			}
		}
		throw new Exception('Not Authorized');
	}

    	function Logoff()
    	{
      		return $this->send_request('Logoff');
    	}

	function ExtensionState($exten,$context,$actionid=NULL)
    	{
      		$parameters=array('Exten'=>$exten,'Context'=>$context);
      		if($actionid) $parameters['ActionID'] = $actionid;
      		return($this->send_request('ExtensionState', $parameters));
    	}


    	function Originate2($channel,
                       $exten=NULL, $context=NULL, $priority=NULL,
                       $application=NULL, $data=NULL,
                       $timeout=NULL, $callerid=NULL, $variable=NULL, $account=NULL, $async=NULL, $actionid=NULL)
    	{
      		$parameters = array('Channel'=>$channel);
      		if($exten) $parameters['Exten'] = $exten;
      		if($context) $parameters['Context'] = $context;
      		if($priority) $parameters['Priority'] = $priority;
      		if($application) $parameters['Application'] = $application;
      		if($data) $parameters['Data'] = $data;
      		if($timeout) $parameters['Timeout'] = $timeout;
      		if($callerid) $parameters['CallerID'] = $callerid;
      		if($variable) $parameters['Variable'] = $variable;
      		if($account) $parameters['Account'] = $account;
      		if(!is_null($async)) $parameters['Async'] = ($async) ? 'true' : 'false';
      		if($actionid) $parameters['ActionID']=$actionid;
	      	return($this->send_request('Originate',$parameters));
    	}	

	function Originate($channel, $exten, $context, $priority, $timeout, $callerid, $variable, $account, $application, $data)
    	{
      		$parameters = array();
      		if($channel) $parameters['Channel'] = $channel;
      		if($exten) $parameters['Exten'] = $exten;
      		if($context) $parameters['Context'] = $context;
      		if($priority) $parameters['Priority'] = $priority;
      		if($timeout) $parameters['Timeout'] = $timeout;
      		if($callerid) $parameters['CallerID'] = $callerid;
      		if($variable) $parameters['Variable'] = $variable;
      		if($account) $parameters['Account'] = $account;
      		if($application) $parameters['Application'] = $application;
      		if($data) $parameters['Data'] = $data;
      		return($this->send_request('Originate', $parameters));
    	}	


    	function log($message)
    	{
#		Aastra_debug($message);
    	}

	function log_array($msg, $a) {
		 foreach ($a as $k=>$v) {
		 	 $msg.= ' '.$k.'=>'.$v;
		 }
		 error_log($msg);
	}

	function database_show($family='') 
	{
		$r=$this->command('database show '.$family);
		$data=explode("\n",$r['data']);
		$db=array();
		array_shift($data);
		unset($data[count($data)-2]);
		unset($data[count($data)-1]);
		foreach($data as $line) 
			{
			$temp = explode(":",$line);
			if (trim($temp[0]) != '') 
				{
				$temp[1] = isset($temp[1])?$temp[1]:null;
				$db[ trim($temp[0]) ] = trim($temp[1]);
				}
			}
		return $db;
	}
	
	function database_put($family, $key, $value) 
	{
		$r = $this->command("database put ".str_replace(" ","/",$family)." ".str_replace(" ","/",$key)." ".$value);
		return (bool)strstr($r["data"], "success");
	}
	
	function database_get($family,$key) 
	{
		$r=$this->command('database get '.str_replace(' ','/',$family).' '.str_replace(' ','/',$key));
		$data=strpos($r['data'],'Value:');
		if($data!==false) return trim(substr($r['data'],6+$data));
		else return false;
	}
	
	function database_del($family, $key) 
	{
		$r = $this->command("database del ".str_replace(" ","/",$family)." ".str_replace(" ","/",$key));
		return (bool)strstr($r["data"], "removed");
	}

	function QueueAdd($queue, $interface, $penalty=0)
    	{
      		$parameters = array('Queue'=>$queue, 'Interface'=>$interface);
      		if($penalty) $parameters['Penalty'] = $penalty;
      		return $this->send_request('QueueAdd', $parameters);
    	}

    	function QueueRemove($queue, $interface)
    	{
      	return $this->send_request('QueueRemove', array('Queue'=>$queue, 'Interface'=>$interface));
    	}

	function QueuePause($queue, $interface, $pause)
    	{
      	return $this->send_request('QueuePause', array('Queue'=>$queue, 'Interface'=>$interface,'Paused'=>$pause));
    	}

    	function Queues()
    	{
      	return $this->send_request('Queues');
    	}

    	function QueueStatus($actionid=NULL)
    	{
      	if($actionid) return $this->send_request('QueueStatus', array('ActionID'=>$actionid));
      	else return $this->send_request('QueueStatus');
    	}

	function ParkedCalls($actionid=NULL)
    	{
      	if($actionid) return $this->send_request('ParkedCalls', array('ActionID'=>$actionid));
      	else return $this->send_request('ParkedCalls');
    	}

	function Redirect($channel,$extension,$priority,$context)
    	{
      	return $this->send_request('Redirect', array('Channel'=>$channel,'Exten'=>$extension,'Priority'=>$priority,'Context'=>$context));
    	}

	function Reload($module='') 
	{
		$this->command('reload '.$module);
	}

	function UserEvent($event,$data)
	{
	return $this->send_request('UserEvent', array('Privilege'=>'user,all','UserEvent'=>$event,'Data'=>$data));
	}
}
?>
