Asterisk Monitor 1.10 Released

I released Asterisk Monitor 1.10 on iTunes, starting from this release you should use a php proxy that I developed, to enhance the functionality of  asterisk manager with new functions. I have added more functions in the application such as the reload option for extensions, sip, voicemail, gtalk and queue. I also added the logs watch, and the cdr list. The cdr is only from the CSV file at this point.

In order to use this version and all its features, you should install the php proxy which needs a html server such as apache or lighttpd or any other one, that is able to manage the php files and also the SSL connection. I will not go over these configurations however, if you need some help let me know.  In this version, there is a little bug which is caused by the platform that I used to develop the application. At this point in time, it is not able to use the SSL connection on a different port from the 443.

First of all, edit the manager.conf that is usually under /etc/asterisk
In the general session, put yes on enabled

[general]
enabled = yes
port = 5038
bindaddr = 0.0.0.0

[myusername]
secret = mynewpass
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/0.0.0.0
write = system,call,agent,user,config,command,originate

These are the two files that you must upload on your system and also need to use the rewrite module. On the lighttpd that I used for the tests, I have used the following line in lighttpd.conf to set modrewrite.

url.rewrite = ( "^/asterisk/mxml(.*)$"  => "/mini_cmds.php$1" )

In apache you can do on httpd.conf or .htaccess. Then you need the two php files, the main file where you have the authorization part, the case switch to decide if the actions is original or if it is my function
mini_cmds.php mini_cmds.php

<?
/*
Copyright 2010  Michele Nasoni. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice, this list of
 conditions and the following disclaimer.

 2. 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.

THIS SOFTWARE IS PROVIDED BY MICHELE NASONI (http://www.nasoni.net)  ``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 MICHELE NASONI  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.

The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Michele Nasoni (http://www.nasoni.net).

mini_cmds.php    Version. 1.01    13-dec-2010
*/

session_start();
/*
For the moment only one account
You can transform in an array
*/
$username="YOURUSER";
$password="YOURPASS";
// I am lazy, that I prefer skip an amount of bytes in order to read the end of the file
define("READBYTES",-160*20);
// Sometime you prefer to have multiple installation or to use a different directory for you applications
define('AST_PATH','/opt/asterisk16');
// A Log can help sometime
define("DEBUG",true);
define("DEBUG_PATH",'/tmp/azione.txt');
define('DEBUG_METHOD','w');
/*
If it does not match send a 404 and wait 4 seconds
in a next mod, we can save the IP and block it, probably using fail2ban easy to do
*/

// Put a instead w if you want to append
if( DEBUG )
 $log=fopen(DEBUG_PATH,DEBUG_METHOD);

function debug($what)
{
 // Debug off and the file is open
 if( DEBUG && isset($log) )
 {
 fwrite($log,$what."\n");
 }
}

foreach($_GET as $k=>$v )
 debug("$k => $v");

include("ConnectManager.php");

$cm=new ConnectManager();

if( (!isset($_SESSION['login']) || $_SESSION['login']==0) && ( $username!=$_GET['username'] || $password!=$_GET['secret'] ) )
{
 unset( $_SESSION['login'] );
//    sleep(4);

 $cm->xml(array(array('response'=>'Error','message'=>'Authentication Problem')));
//    header("HTTP/1.0 404 Not Found");
 exit;
}
else if( $_GET['action']=='Login' )
{
 foreach($_SESSION as $k=>$v)
 unset($_SESSION[$k]);
 $_SESSION['login']=1;
}

if( $_SESSION['login']!=1 )
{
 sleep(4);
 header("HTTP/1.0 404 Not Found");
 exit;
}
// Load the Main Class

if( DEBUG )
{
 foreach($_GET as $k=> $v)
 debug("$k => $v");
}

if( !isset($_GET['action']))
{
 return;
}
if( $_GET['action']=='Login')
{
 $cm->xml(array(array('response'=>'Success','message'=>'Authentication accepted')));
 exit;
}

$conn=new ConnectManager();

switch($_GET['action'] )
{
 case 'cdr':
 // For now only the cvs (I should add the module for the DB)
 if( file_exists(AST_PATH.'/var/log/asterisk/cdr-csv/Master.csv'))
 {
 $fpp=fopen(AST_PATH.'/var/log/asterisk/cdr-csv/Master.csv','r');
 if( $fpp )
 {
 // If the APP reload the info start from the previous line read, with the DB I should rework this
 if( isset($_SESSION['cdr_pos'])) {
 debug('Position '.$_SESSION['cdr_pos']);
 fseek($fpp,$_SESSION['cdr_pos'] );
 }
 $rows=array();
 while (($data = fgetcsv($fpp, 1000, ",")) !== FALSE) {
 debug("Reading lines");
 array_push($rows, array( 'clid' =>$data[0], 'src' =>$data[1], 'dst' => $data[2], 'lastdata'=>$data[7], 'answer'=>$data[10], 'end'=>$data[11], 'billsec' => $data[13]) );
 }
 $cm->xml($rows, 1);
 $_SESSION['cdr_pos']=ftell($fpp);
 fclose($fpp);
 }
 }
 break;
 case 'logs':
 if(file_exists(AST_PATH.'/var/log/asterisk/'.strtolower($_GET['command']) ) )
 {
 $fpp=fopen(AST_PATH.'/var/log/asterisk/'.strtolower($_GET['command']),'r');
 if( $fpp )
 {
 $result='';
 $replace=array('"','\'');
 if( isset($_SESSION['log_'.strtolower($_GET['command']).'_pos']))
 {
 fseek($fpp,$_SESSION['log_'.strtolower($_GET['command']).'_pos']);
 }
 else
 {
 fseek($fpp,READBYTES, SEEK_END);
 }
 $res=array();
 while (! feof ($fpp)) {
 $line=fgets($fpp);
 if ( preg_match("/\[(.*)\] ([A-Z]*)\[([0-9]*)\] (.*)/",$line,$match) )
 {
 $res[]=array('date'=>$match[1], 'event' =>$match[2], 'message'=>str_replace($replace,'',$match[4]));
 }
 }
 $cm->xml($res,1);
 $_SESSION['log_'.strtolower($_GET['command']).'_pos']=ftell($fpp);
 fclose($fpp);
 }
 else
 debug('Problem opening the log');
 }
 else
 debug('The log '.AST_PATH.'/var/log/asterisk/'.strtolower($_GET['command']).' does not exist');
 break;
 default:
 // If it is not one of my actions, send it to the manager
 $cm->login();
 $st='';
 foreach($_GET as $k=>$v )
 {
 $st.=ucfirst($k).': '.$v."\r\n";
 }

 $cm->send($st."\r\n\r\n",true);
 $cm->logoff();
 break;
}
if( isset($log) )
 fclose($log);
?>

And the class that manages the connection with the manager and the xml formatting

ConnectManager.php ConnectManager.php

<?
/*
Copyright 2010  Michele Nasoni. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice, this list of
 conditions and the following disclaimer.

 2. 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.

THIS SOFTWARE IS PROVIDED BY MICHELE NASONI (http://www.nasoni.net)  ``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 MICHELE NASONI  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.

The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Michele Nasoni (http://www.nasoni.net).

ConnectManager.php    Version. 1.00    11-dec-2010
*/

class ConnectManager
{
 var $astmanager        ="YOURUSER";        // Asterisk Manager user
 var $astpassword    ="YOURPASS";        // Password
 var $astip        ="127.0.0.1";        // IP
 var $astport        ="5038";        // Port
 var $timeout        ="30";            // Timeout
 var $errno        ="";
 var $errstr        ="";
 var $socket;

 // Open the socket
 function __construct()
 {
 $this->socket=fsockopen($this->astip, $this->astport, $this->errno, $this->errstr, $this->timeout);
 stream_set_timeout($this->socket, $this->timeout);

 if( !$this->socket )
 {
 echo "$errstr ($errno)\n";
 exit(1);
 }
 }

 // Close the socket
 function __destruct()
 {
 fclose($this->socket);
 }

 // The login before sending the actions
 function login()
 {
 $cmd ="Action: Login\r\n";
 $cmd.="UserName: $this->astmanager\r\n";
 $cmd.="Secret: $this->astpassword\r\n";
 $cmd.="Events: off\r\n\r\n";
 $this->send($cmd,false);
 }

 // Logoff
 function logoff()
 {
 $cmd ="Action: Logoff\r\n\r\n";
 $this->send($cmd,false);
 }

 // Send the commands
 function send($cmd, $return )
 {
 fputs($this->socket,$cmd );
 if( $return )
 {
 // If you need the answer
 $this->parseXML();
 }
 else
 $this->listen();
 }

 // Listen for the answer
 private function listen()
 {
 $line='';
 $info='';
 $retInfo='';
 do {
 $line = fgets($this->socket, 4096);
 $retInfo.=$line;
 $info = stream_get_meta_data($this->socket);
 } while ($line != "\r\n" && $info['timed_out'] == false );
 return $retInfo;
 }

 //  Read the
 private function parseXML()
 {
 $res=array();
 $a=0;
 $loop=false;
 do {
 $res[$a]=array();
 $lines=$this->listen($this->socket);
 if( preg_match('/Message: .*( will follow)\r\n/',$lines, $matches) )
 {
 $loop=true;
 }
 if( preg_match('/Event: .*(EntryComplete)\r\n/',$lines, $matches) )
 {
 $loop=false;
 }
 if( preg_match('/EventList: (.*)\r\n/',$lines, $matches) )
 {
 if( $matches[1]=='start') $loop=true;
 if( $matches[1]=='Complete') $loop=false;
 }

 if( preg_match_all('/(\w*): (.*)\r\n/', $lines, $matches) )
 {
 array_shift($matches);
 for($i=0;$i<count($matches[0]);$i++)
 {
 $res[$a][strtolower($matches[0][$i])]=$matches[1][$i];
 }
 }
 $a++;
 }while($loop);
 $this->xml($res);
 }    

 // Format the array in XML
 public function xml( $vals, $force=0)
 {
 $ret='<ajax-response>'."\n";
 if($force ==1)
 {
 $ret.='<response type="object" id="unknown">'."\n";
 $ret.='<generic response="Success" message="list will follow"/>'."\n";
 $ret.='</response>'."\n";
 }
 for($i=0;$i<count($vals);$i++)
 {
 $ret.='<response type="object" id="unknown">'."\n".'<generic';
 foreach($vals[$i] as $k=>$v)
 $ret.=' '.$k.'="'.addslashes(htmlentities($v)).'"';
 $ret.='/>'."\n".'</response>'."\n";
 }
 if( $force==1)
 {
 $ret.='<response type="object" id="unknown">'."\n";
 $ret.='<generic event="EntryComplete"/>'."\n";
 $ret.='</response>'."\n";
 }
 $ret.='</ajax-response>'."\n";
 header ("content-type: text/xml");
 echo $ret;
 }
}
?>

Sorry for the quality of the source code, however, I thaught that it was more important to give you something to start.
I need to hear from you, since I do not know if the application is appreciated and if it is worthed to spend time on it.

If I do not receive feedback this means that there are no interest for it.

19 thoughts on “Asterisk Monitor 1.10 Released”

  1. Hi Michele,

    I have proved this software with the config that you put in the first post “http://www.nasoni.net/2010/11/18/asterisk-monitor/” and it works well the most options, only the CDR and LOG options not work me.

    I have tried to configure it like the last post “http://www.nasoni.net/2010/12/08/asterisk-monitor-1-10-released/#comments” but I can’t to connect the iPhone to the Asterisk Server.

    I have observed that in the last config you have omited the config of file “/etc/asterisk/http.conf” and the “webenabled = yes” option in the file “/etc/asterisk/manager.conf”. Aren’t they necessary or you supposed that they are configured previously?

    I have installed Apache server. Please, can you give me detail that where I need copy the php files and what need modify in the httpd.conf file?

    Is need modify something in the php files?

    Best regards,

    Ramses

  2. Hi Ramses,
    if order to use the CDR and LOGS feature you need to have the proxy. And if you are going to use the proxy you do not need to have the http.conf in asterisk.
    I do not have the configuration for apache, however, I will post it later on, when I will find 2 seconds to test the rewrite and post the right one.
    And, yes you need to configure the mini_cmds.php
    this lines
    $username=”USER”;
    $password=”PASS”;
    with the user and password that you are going to insert on the app and the ConnectManager.php
    var $astmanager =”YOURUSER”; // Asterisk Manager user
    var $astpassword =”YOURPASS”; // Password
    var $astip =”127.0.0.1″; // IP
    var $astport =”5038″; // Port
    var $timeout =”30″; // Timeout
    with the manager.conf

    And it will be appreciated a review on the app store 😀

  3. Hi Michele,

    I tell you:

    – I have copied the file “mini_cmds.php” as “/var/www/html/asterisk/mxml” and “ConnectManager.php” as “/var/www/html/asterisk/ConnectManager.php”.

    – I have changed the following configuration in the Asterisk Server:

    ** manager.conf **
    [general]
    enabled = yes
    port = 5038
    bindaddr = 0.0.0.0

    [AstMonitor]
    secret = password
    deny=0.0.0.0/0.0.0.0
    permit=127.0.0.1/0.0.0.0
    write = system,call,agent,user,config,command,originate

    ** mxml (that is mini_cmds.php)
    $username=”AstMonitor”;
    $password=”password”;

    ** ConnectManager.php **
    var $astmanager =”AstMonitor”; // Asterisk Manager user
    var $astpassword =”password”; // Password

    – In the AstMonitor client I put:

    Host = 192.168.0.250
    Port = 443
    User =AstMonitor
    Pass = password
    Prefix = asterisk
    SSL = ON

    When I try to connect, It tell me “Error connecting the service” in the iPhone.

    In the “ssl_access_log” file appear the next message every time that I try to connect:
    “192.168.0.6 – – [13/Dec/2010:18:18:42 +0100] “GET /asterisk/mxml?action=Login&username=AstMonitor&secret=password HTTP/1.1″ 200 5522”.

    Can you tell me what I am doing wrong?

    Best regards,

    Ramses

  4. to configure apache
    in the ssl.conf (dependently which distribution your are using)

    add this

        <Directory /var/www/html/asterisk/>
            Options Indexes MultiViews FollowSymLinks
            AllowOverride None
            Order deny,allow
            Allow from all
            RewriteEngine on
            RewriteRule ^mxml(.*)$  mini_cmds.php$1
        </Directory>
    
  5. Hi again Michele,

    With the change that you proposed, it works me like it worked me in the first configuration, all except the CDR and LOGs.

    When I try to execute the LOG or the CDR options, appear in the CLI of Asterisk Server the following:

    == Connect attempt from ‘127.0.0.1’ unable to authenticate
    == Connect attempt from ‘127.0.0.1’ unable to authenticate
    == Connect attempt from ‘127.0.0.1’ unable to authenticate

    And not appear nothing in the iPhone.

    When I execute other option, by example, “Vicemail Reload”, in the CLI appear:

    == Connect attempt from ‘127.0.0.1’ unable to authenticate
    == Manager ‘astmonitor’ logged on from 127.0.0.1
    — Reloading module ‘app_voicemail.so’ (Comedian Mail (Voicemail System))
    == Manager ‘astmonitor’ logged off from 127.0.0.1
    == Connect attempt from ‘127.0.0.1’ unable to authenticate

    And in the iPhone appear “Voicemail Reload Success” and OK.

    Best regards,

    Ramses

  6. since the reload is an asterisk commands and it works with the proxy or without, then I cannot understand if you are using the proxy

    to me, it seems that you are not using the apache, but you go directly to asterisk, check the conf and the apache logs

  7. Hi Miguel, 

    I’m sorry if I have not explained well. 

    I think that I’m using the proxy because when I have added the lines that you told me to the ssl.conf file, I can now connect the iPhone to my Asterisk server, isn’t it?. Can you tell me how to test if the proxy is working well or not?

    Sorry if I haven’t a good english…

    Best regards,

    Ramses

    1. Hi
      I found some little mistakes, I am uploading the version 1.01 of mini_cms.php
      to test it do this

      https://YOURIP/asterisk/mxml?action=Login&username=YOURMINICMDSUSER&secret=YOURMINICMDSPASS

      https://YOURIP/asterisk/mxml?action=logs&command=full

  8. I would love to use your program but I am not able to get it to work. I am running apache where would I put the 2 .php files? I can get the first disply page up but nothen past that. Is there some troubleshooting ideas I can use? Thank you for writing this app and thank you for any help.

  9. Do you have personalized the script with the right path?
    Can you take a look on /tmp/azione.txt tif something is logged?

  10. I am sorry I must not have personalized the right script which one needs to be? Am I making asterisk talk to apache or apache talk to asterisk or some other combo?

  11. If you are using apache, it means that you would like to check also the logs.
    Then on the mini_cmds.php

    you need to modify this section

    $username="YOURUSER";
    $password="YOURPASS";
    // I am lazy, that I prefer skip an amount of bytes in order to read the end of the file
    define("READBYTES",-160*20);
    // Sometime you prefer to have multiple installation or to use a different directory for you applications
    define('AST_PATH','/opt/asterisk16');

  12. Yes I personalized that .php, I put my username and password in, I also changed the /opt/asterisk16 to where my asterisk is intalled.

    I am using /var/www/asterisk directory for the 2 .php files. I added the .htaccess file to there also.

    I looked through the log files but have found nothing that talks about this project.

  13. Perfect you skiped this part
    url.rewrite = ( "^/asterisk/mxml(.*)$" => "/mini_cmds.php$1" )
    and probabily the mod_rewrite on apache

Leave a Reply

Your email address will not be published. Required fields are marked *