Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 1386 → Rev 1387

/asterisk-stats/trunk/originate_call.php
0,0 → 1,26
<?php
 
include_once('includes/common.php');
Prolog();
 
include_once('includes/AsteriskManager/AsteriskManager.php');
 
$src = $_POST['src'];
$dst = $_POST['dst'];
 
try {
$ast = new Net_AsteriskManager(array('server' => $mgr_host, 'port' => $mgr_port));
 
$ast->connect();
$ast->login($mgr_user, $mgr_password);
 
$ast->originateCall($dst, "$mgr_channel/$src", $mgr_context, $src);
$g_display->add_text("A call from $src to $dst is originated");
}
catch(PEAR_Exception $e) {
$g_display->add_html_text($e);
}
 
Epilog();
 
?>
/asterisk-stats/trunk/includes/AsteriskManager/AsteriskManagerException.php
0,0 → 1,69
<?php
/**
* This package is capable of interfacing with the open source Asterisk PBX via
* its built in Manager API. This will allow you to execute manager commands
* for administration and maintenance of the server.
*
* Copyright (c) 2008, Doug Bromley <doug.bromley@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the author nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* PHP version 5
*
* @category Net
* @package Net_AsteriskManager
* @author Doug Bromley <doug.bromley@gmail.com>
* @copyright 2008 Doug Bromley
* @license http://www.debian.org/misc/bsd.license New BSD License
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=543
*/
 
/**
* PEAR Exception class is used for exception handling
*/
require_once 'PEAR/Exception.php';
 
/**
* The exception class for the Asterisk Manager library. Extends PEAR exception.
* This class contains static values of error types.
*
* @category Net
* @package Net_AsteriskManager
* @author Doug Bromley <doug.bromley@gmail.com>
* @license http://www.debian.org/misc/bsd.license New BSD License
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=543
*/
class Net_AsteriskManagerException extends PEAR_Exception
{
const NOSOCKET = 'No socket defined';
const AUTHFAIL = 'Authorisation failed';
const CONNECTFAILED = 'Connection failed';
const NOCOMMAND = 'Unknown command specified';
const NOPONG = 'No response to ping';
const NOSERVER = 'No server specified';
const MONITORFAIL = 'Monitoring of channel failed';
const RESPERR = 'Server didn\'t respond as expected';
const CMDSENDERR = 'Sending of command failed';
}
/asterisk-stats/trunk/includes/AsteriskManager/AsteriskManager.php
0,0 → 1,494
<?php
 
/**
* This package is capable of interfacing with the open source Asterisk PBX via
* its built in Manager API. This will allow you to execute manager commands
* for administration and maintenance of the server.
*
* Copyright (c) 2008, Doug Bromley <doug.bromley@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the author nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* PHP version 5
*
* @category Net
* @package Net_AsteriskManager
* @author Doug Bromley <doug.bromley@gmail.com>
* @copyright 2008 Doug Bromley
* @license http://www.debian.org/misc/bsd.license New BSD License
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=543
*/
 
/**
* Including the libraries exception class which extends PEAR_Exception
*/
require 'AsteriskManagerException.php';
 
/**
* Class for accessing the Asterisk Manager interface
* {@link http://www.voip-info.org/wiki/view/Asterisk+manager+API}
*
* @category Net
* @package Net_AsteriskManager
* @author Doug Bromley <doug.bromley@gmail.com>
* @license http://www.debian.org/misc/bsd.license New BSD License
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=543
*/
class Net_AsteriskManager
{
/**
* The Asterisk server which will recieve the manager commands
* @access public
* @var string
*/
public $server;
 
/**
* The port to use when connecting to the Asterisk server
* @access public
* @var integer
*/
public $port = 5038;
 
/**
* The opened socket to the Asterisk server
* @access private
* @var object
*/
private $_socket;
 
/**
* Class constructor
*
* @param array $params Array of the parameters used to connect to the server
* <code>
* array(
* 'server' => '127.0.0.1' // The server to connect to
* 'port' => '5038', // Port of manager API
* 'auto_connect' => true // Autoconnect on construction?
* );
* </code>
*
* @uses AsteriskManager::$server
* @uses AsteriskManager::$port
* @uses AsteriskManager::$_socket
*/
public function __construct($params = array())
{
if (!isset($params['server'])) {
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::NOSERVER
);
}
$this->server = $params['server'];
 
if (isset($params['port'])) {
$this->port = $params['port'];
}
 
if (isset($params['auto_connect'])) {
if ($params['auto_connect']) {
$this->connect();
}
}
}
 
/**
* Private method for checking there is a socket open to the Asterisk
* server.
*
* @return null
*/
private function _checkSocket()
{
if (!$this->_socket) {
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::NOSOCKET
);
}
}
 
/**
* Consolidated method for sending the given command to the server and returning
* its reponse. Any failure in writing or reading will raise an exception.
*
* @param string $command The command to send
*
* @return string
*/
private function _sendCommand($command)
{
if (!fwrite($this->_socket, $command)) {
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::CMDSENDERR
);
}
 
$response = stream_get_contents($this->_socket);
 
if ($response == false) {
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::RESPERR
);
}
 
return $response;
}
 
/**
* If not already connected then connect to the Asterisk server
* otherwise close active connection and reconnect
*
* @return bool
*/
public function connect()
{
if ($this->_socket) {
$this->close();
}
if ($this->_socket = fsockopen($this->server, $this->port)) {
stream_set_timeout($this->_socket, 3);
return true;
}
throw new Net_AsteriskManagerException (
Net_AsteriskManagerException::CONNECTFAILED
);
}
 
/**
* Login into Asterisk Manager interface given the user credentials
*
* @param string $username The username to access the interface
* @param string $password The password defined in manager interface of server
* @param string $authtype Enabling the ability to handle encrypted connections
*
* @return bool
*/
public function login($username, $password, $authtype = null)
{
$this->_checkSocket();
if (strtolower($authtype) == 'md5') {
$response = $this->_sendCommand("Action: Challenge\r\n"
."AuthType: MD5\r\n\r\n");
if (strpos($response, "Response: Success") !== false) {
$challenge = trim(substr($response,
strpos($response, "Challenge: ")));
 
$md5_key = md5($challenge . $password);
$response = $this->_sendCommand("Action: Login\r\nAuthType: MD5\r\n"
."Username: {$username}\r\n"
."Key: {$md5_key}\r\n\r\n");
} else {
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::AUTHFAIL
);
}
} else {
$response = $this->_sendCommand("Action: login\r\n"
."Username: {$username}\r\n"
."Secret: {$password}\r\n\r\n");
}
 
 
if (strpos($response, "Message: Authentication accepted") != false) {
return true;
}
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::AUTHFAIL
);
}
 
/**
* Logout of the current manager session attached to $this::socket
*
* @return bool
*/
public function logout()
{
$this->_checkSocket();
$this->_sendCommand("Action: Logoff\r\n\r\n");
 
return true;
}
 
/**
* Close the connection
*
* @return bool
*/
public function close()
{
$this->_checkSocket();
 
return fclose($this->_socket);
}
 
/**
* Send a command to the Asterisk CLI interface. Acceptable commands
* are dependent on the Asterisk installation.
*
* @param string $command Command to execute on server
*
* @return string|bool
*/
public function command($command)
{
$this->_checkSocket();
$response = $this->_sendCommand("Action: Command\r\n"
."Command: $command\r\n\r\n");
 
if (strpos($response, 'No such command') !== false) {
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::NOCOMMAND
);
}
return $response;
}
 
/**
* A simple 'ping' command which the server responds with 'pong'
*
* @return bool
*/
public function ping()
{
$this->_checkSocket();
 
$response = $this->_sendCommand("Action: Ping\r\n\r\n");
if (strpos($response, "Pong") === false) {
return false;
}
return true;
}
 
/**
* Make a call to an extension with a given channel acting as the originator
*
* @param string $extension The number to dial
* @param string $channel The channel where you wish to originate the call
* @param string $context The context that the call will be dropped into
* @param string $cid The caller ID to use
* @param integer $priority The priority of this command
* @param integer $timeout Timeout in milliseconds before attempt dropped
* @param array $variables An array of variables to pass to Asterisk
* @param string $action_id A unique identifier for this command
*
* @return bool
*/
public function originateCall($extension,
$channel,
$context,
$cid,
$priority = 1,
$timeout = 30000,
$variables = null,
$action_id = null)
{
$this->_checkSocket();
$command = "Action: Originate\r\nChannel: $channel\r\n"
."Context: $context\r\nExten: $extension\r\nPriority: $priority\r\n"
."Callerid: $cid\r\nTimeout: $timeout\r\n";
 
if (count($variables) > 0) {
$chunked_vars = array();
foreach ($variables as $key => $val) {
$chunked_vars[] = "$key=$val";
}
$chunked_vars = implode('|', $chunked_vars);
$command .= "Variable: $variables\r\n";
}
 
if ($action_id) {
$command .= "ActionID: $action_id\r\n";
}
$this->_sendCommand($command."\r\n");
return true;
}
 
/**
* Returns a list of queues and their status
*
* @return string|bool
*/
public function getQueues()
{
$this->_checkSocket();
 
$response = $this->_sendCommand("Action: Queues\r\n\r\n");
return $response;
}
 
/**
* Add a handset to a queue on the server
*
* @param string $queue The name of the queue you wish to add the handset too
* @param string $handset The handset to add, e.g. SIP/234
* @param integer $penalty Penalty
*
* @return bool
*/
public function queueAdd($queue, $handset, $penalty = null)
{
$this->_checkSocket();
$command = "Action: QueueAdd\r\nQueue: $queue\r\n"
."Interface: $handset\r\n";
 
if ($penalty) {
$this->_sendCommand($command."Penalty: $penalty\r\n\r\n");
return true;
}
 
$this->_sendCommand($command."\r\n");
return true;
}
 
/**
* Remove a handset from the given queue
*
* @param string $queue The queue you wish to perform this action on
* @param string $handset The handset you wish to remove (e.g. SIP/200)
*
* @return bool
*/
public function queueRemove($queue, $handset)
{
$this->_checkSocket();
$this->_sendCommand("Action: QueueRemove\r\nQueue: $queue\r\n"
."Interface: $handset\r\n\r\n");
 
return true;
}
 
/**
* Monitor(record) a channel to given file in given format
*
* @param string $channel Channel to monitor (e.g. SIP/234, ZAP/1)
* @param string $filename The filename to save to
* @param string $format The format of the file (e.g. gsm, wav)
* @param integer $mix Boolean 1 or 0 on whether to mix
*
* @return bool
*/
public function startMonitor($channel, $filename, $format, $mix = null)
{
$this->_checkSocket();
$response = $this->_sendCommand("Action: Monitor\r\nChannel: $channel\r\n"
."File: $filename\r\nFormat: $format\r\n"
."Mix: $mix\r\n\r\n");
if (strpos($response, "Success") === false) {
throw new Net_AsteriskManagerException(
Net_AsteriskManagerException::MONITORFAIL
);
} else {
return true;
}
}
 
/**
* Stop monitoring a channel
*
* @param string $channel The channel you wish to stop monitoring
*
* @return bool
*/
public function stopMonitor($channel)
{
$this->_checkSocket();
$this->_sendCommand("Action: StopMonitor\r\n"
."Channel: $channel\r\n\r\n");
return true;
}
 
/**
* Get the status information for a channel
*
* @param string $channel The channel to query
*
* @return string|string
*/
public function getChannelStatus($channel = null)
{
$this->_checkSocket();
$response = $this->_sendCommand("Action: Status\r\nChannel: "
."$channel\r\n\r\n");
return $response;
}
 
/**
* Get a list of SIP peers and their status
*
* @return string|bool
*/
public function getSipPeers()
{
$this->_checkSocket();
 
$response = $this->_sendCommand("Action: Sippeers\r\n\r\n");
return $response;
}
 
/**
* Return a list of IAX peers and their status
*
* @return string|bool
*/
public function getIaxPeers()
{
$this->_checkSocket();
 
$response = $this->_sendCommand("Action: IAXPeers\r\n\r\n");
return $response;
}
 
/**
* Returns a list of all parked calls on the server.
*
* @return string
*/
public function parkedCalls()
{
$this->_checkSocket();
 
$response = $this->_sendCommand("Action: ParkedCalls\r\n"
."Parameters: ActionID\r\n\r\n");
return $response;
}
}
 
?>
/asterisk-stats/trunk/includes/config.php-dist
6,6 → 6,13
$db_password = 'password';
$db_database = 'asterisk';
 
$mgr_host = 'localhost';
$mgr_port = 5038;
$mgr_user = 'originator';
$mgr_password = 'password2';
$mgr_channel = 'SIP';
$mgr_context = 'default';
 
// any local specific query
function BaseQuery()
{
/asterisk-stats/trunk/template/cdr_search.tpl
41,8 → 41,10
<td colspan="4" class="desc">&nbsp;</td>
</tr>
<tr class="buttons">
<td colspan=5><input type=reset name="reset" value="Reset"></td>
<td><input type=submit name=s value="Show CDR"></td>
<td colspan=6>
<input type=reset name="reset" value="Reset">
<input type=submit name=s value="Show CDR">
</td>
</tr>
</table>
</form>
/asterisk-stats/trunk/template/menu.tpl
1,8 → 1,9
<table class="menu">
<tr>
<td><a href=..>Up</a></td>
<td><a href="index.php">Summary</a></td>
<td><a href="cdr_search.php">Search</a></td>
<td><a href="telbook_list.php">Tel. Book</a></td>
</tr>
<tr>
<td><a href=..>Up</a></td>
<td><a href="index.php">Summary</a></td>
<td><a href="cdr_search.php">Search</a></td>
<td><a href="telbook_list.php">Tel. Book</a></td>
<td><a href="originate_form.php">Call</a></td>
</tr>
</table>
/asterisk-stats/trunk/template/originate_form.tpl
0,0 → 1,22
<form method="POST" action="originate_call.php">
<table class="stat cdr search">
<tr>
<th>Source</th>
<td>
<select name=src>${SRC_LIST}
</select>
</td>
</tr>
<tr>
<th>Destination</th>
<td><input type=text name="dst" value="${DST}"></td>
</tr>
<tr class="buttons">
<td colspan=2>
<input type=reset name="reset" value="Reset">
<input type=submit name=s value="Originate">
</td>
</tr>
</table>
</form>
 
/asterisk-stats/trunk/template/telbook_details_begin.tpl
16,3 → 16,5
</select>
</td>
</tr>
<tr>
<td colspan=2>
/asterisk-stats/trunk/template/telbook_details_end.tpl
1,3 → 1,5
</td>
</tr>
<tr class="buttons">
<td colspan=2>
<input type=reset name="reset" value="Reset">
/asterisk-stats/trunk/telbook_list.php
10,7 → 10,7
. " left join telbook_entries e on p.person_id=e.entry_person"
. " order by person_name, entry_title, entry_value");
 
$table = new Table(array('Name', 'Category', 'Type', 'Number', ''));
$table = new Table(array('Name', 'Category', 'Type', 'Number', '', ''));
$table->set_table_class('telbook list');
 
$last_person_id = NULL;
25,8 → 25,10
'comment' => $line['entry_comment']));
$table->addcell(array('text' => $line['entry_value'],
'comment' => $line['entry_comment']));
$table->addcell($same_person ? '' : array('class' => 'link', 'html' =>
display_link('telbook_details.php?id=' . $line['person_id'], 'Edit')));
$table->addcell(array('class' => 'link', 'html' =>
$same_person ? '' : display_link('telbook_details.php?id=' . $line['person_id'], 'Edit')));
$table->addcell(array('class' => 'link', 'html' =>
display_link('originate_form.php?dst=' . $line['entry_value'], 'Call')));
$last_person_id = $line['person_id'];
}
$g_display->add_html_text($table->build());
/asterisk-stats/trunk/style.css
110,10 → 110,15
padding-bottom: 16px;
}
 
table.search tr.buttons td {
table tr.buttons td {
border: none;
text-align: right;
}
 
table tr.buttons:hover td {
background-color: #FFFFFF;
}
 
table.search td.desc {
border: none;
}
122,10 → 127,6
border: none;
}
 
table.search tr.buttons:hover td {
background-color: #FFFFFF;
}
 
table.telbook th {
color: #FFFFFF;
background-color: #6876F8;
141,10 → 142,6
font-size: 8pt;
}
 
table.telbook tr.buttons td {
border: none;
}
 
table td[title] {
background: url("images/red_corner.gif") no-repeat right top;
}
/asterisk-stats/trunk/originate_form.php
0,0 → 1,33
<?php
 
include_once('includes/common.php');
Prolog();
 
$src = $_GET['src'];
$dst = $_GET['dst'];
 
# categories select box
$db->query_params("select entry_title, entry_value, person_name"
. " from telbook_entries join telbook_persons on person_id=entry_person"
. " where entry_title=$1"
. " order by person_name, entry_title, entry_value",
array('I'));
 
$src_list = "";
while($line = $db->fetch_row()) {
$src_list .= "\n\t\t\t\t<option value='"
. htmlspecialchars($line['entry_value']) . "'"
. ($line['entry_value'] == $src ? " selected" : "")
. ">" . htmlspecialchars($line['person_name'] . "/" . $line['entry_title']
. " (" . $line['entry_value'] . ")") . "</option>";
}
$g_display->add_html_variables(array('SRC_LIST' => $src_list));
$g_display->add_variables(array(
'SRC' => $src,
'DST' => $dst));
 
$g_display->add_template('originate_form');
 
Epilog();
 
?>