Projekat

Općenito

Profil

Prijedlozi #14772 » asterisk.pl

Ernad Husremović, 05.07.2008 23:48

 
# Category=Phone

#@ Interface to the Asterisk PBX for CallerID and Voicemail
#

=begin comment

Use this code to provide an interface between Misterhouse and the Asterisk
PBX using the Asterisk AGI and Asterisk Manager interfaces. T

This module provides the following features:
o Obtains CallerID information directory from Asterisk AGI
o Logs DTMF Dialing from Asterisk AGI
o Polls Asterisk for any new VoiceMail using Asterisk Manager
o Polls Asterisk for Unregistered IAX2 connections (phone system down) using Asterisk Manager

You must have the Asterisk PERL libraries installed.
You can download them from here: http://asterisk.gnuinter.net/

Add these to you mh.ini for AGI to Misterhouse security. These values must
match the corresponding values in /var/lib/asterisk/agi-bin/Misterh=House.agi
server_asterisk_port = 8090
asterisk_server_username = yourusername
asterisk_server_password = yourpassword

Add these to your mh.ini for Misterhouse to Asterisk Manager security
These settings must match the corresponding fields in /etc/asterisk/manager.conf
asterisk_manager_host = <name or IP address of asterisk server>
asterisk_manager_port = <manager port>
asterisk_manager_username = <manager username>
asterisk_manager_password = <manager password>

You manager.conf file needs to have "read classes" disabled to prevent asynchronous
events from being sent to the code module.

Define these parameters to check voice mail
asterisk_voicemail_period = <minutes between voicemail checks>
asterisk_voicemail_box = <mailbox id to check for voicemail>

=cut

use Asterisk::Manager;
use CID_Lookup;
use CID_Log;
use CID_Announce;
use Telephony_Item;
use PocketSphinx;

my ($auth, $username, $password, $callername, $callernumber, $line);

$ast_callerid = new Telephony_Item();
$cid_lookup = new CID_Lookup($ast_callerid);
$cid_log = new CID_Log($cid_lookup);
$cid_announce = new CID_Announce($cid_lookup, 'Call from $format1');

# Create the asterisk server on MisterHouse to accept incoming connections from Asterisk AGI
$asterisk_server = new Socket_Item(undef, undef, 'server_asterisk');

# Create the asterisk manager interface to poll Asterisk
$astman = new Asterisk::Manager;

$asterisk_listener = new PocketSphinx_Listener ("sphinx_microphone", 16000, 0, 1);

# Here we find data sent from Asterisk and parse it out and do what needs to be done with it.
# I am not good with MisterHouse as of yet to know the best way to handle certain things but this
# works for me and may need to be changed around to work for you. One of the things I changed is
# CallerID stuff so that I can keep better track of the line that the call came in on. I just copied
# some of the code from other files in MisterHouse to do what I needed done but there is definetly
# better ways to do this and I am hoping that someone will help guide me in the right direction
# or take it upon themselves to fix it and redistribute it back out for all to use.
if (my $data = said $asterisk_server) {
print_log("asterisk DATA: $data") if $Debug{asterisk};
# First check for the login and password before letting them do anything.
if (!$auth){
if ($data =~ /Login: (.*)/){
$username = $1;
} elsif ($username && $data =~ /Secret: (.*)/){
$password = $1;
if ($config_parms{asterisk_server_username} eq $username &&
$config_parms{asterisk_server_password} eq $password) {
$auth = 1;
} else {
set $asterisk_server "Incorrect login information\n\n";
$username = '';
$password = '';
}
}
} else {
if ($data =~ /CallerID:/){
$callername = "Unknown";
$callernumber = "Unknown";
$line = "1";
if ($data =~ /CallerID: .* \<+(.*)\> Line: (.*)/) {
$callername = "Unknown";
$callernumber = $1;
$callernumber =~ s/\"//g;
$callernumber =~ s/\+//g;
$line = $2;
}
elsif ($data =~ /CallerID: (.*) \<(.*)\> Line: (.*)/) {
$callername = $1;
$callernumber = $2;
$callernumber =~ s/\"//g;
$callernumber =~ s/\+//g;
$line = $3;
}
elsif ($data =~ /CallerID: (.*) Line: (.*)/) {
$callername = "Unknown";
$callernumber = $1;
$callernumber =~ s/\"//g;
$callernumber =~ s/\+//g;
$line = $2;
}
$ast_callerid->cid_name($callername);
$ast_callerid->cid_number($callernumber);
$ast_callerid->address($line);
$ast_callerid->cid_type("N");
$cid_lookup->set ("CID", $ast_callerid);
$callername = $cid_lookup->name( );
&audrey_callerid ($callername, $callernumber);
} elsif ($data =~ /DTMF:/){
$data =~ /DTMF: (.*) CallFrom: (.*)/;
$ast_callerid->cid_name("");
$ast_callerid->cid_number($1);
$ast_callerid->address($2);
$ast_callerid->cid_type("N");
my $dtmf = $1;
my $callfrom = $2;
$cid_lookup->set ("DIALED", $ast_callerid);
} elsif ($data =~ /Command:/){
$data =~ /Command:(.*) Response=(.*)/;
my $cmd = $1;
my $response = lc($2);
my $respond = "asterisk" if $response =~ /^y/;
print_log("Asterisk Command: $cmd with response code: $response") if $Debug{asterisk};
&process_external_command($cmd, 0, 'asterisk', $respond);
} elsif ($data =~ /Sphinx/){
$data =~ /(.*): extension: (.*)/;
my $command = $1;
my $extension = $2;
print_log("Asterisk Sphinx: command: $command extension: $extension") if $Debug{asterisk};
if ($command =~ /Sphinx Connect/) {
$asterisk_listener->start_listener( );
}
if ($command =~ /Sphinx Disconnect/) {
$asterisk_listener->stop_listener( );
}
}
$auth = '';
}
}

sub hangup_callback {
print_log "asterisk: hangup callback\n";
}

sub default_callback {
my (%data) = @_;
foreach (keys %data) {
print_log ("asterisk callback: $_: ". $data{$_}) if $Debug{asterisk};
}
}

# Inform the humans that the phone system is down
sub asterisk_down {
return if (state $mode_occupied eq 'vacation');
print_log ("asterisk: asterisk_down");
$Save{voiceMail} = 0;
speak (rooms=> "all", text=> "Danger will robinson ... the telephone system appears broken");
}

# Connect to the Asterisk Manager interface
sub asterisk_connect {
print_log "asterisk_connect::" if $Debug{asterisk};
my $connect = $astman->connected;
return if ($astman->connected);
$astman->host($config_parms{asterisk_manager_host});
$astman->user($config_parms{asterisk_manager_username});
$astman->port($config_parms{asterisk_manager_port});
$astman->secret($config_parms{asterisk_manager_password});
&asterisk_down if (!$astman->connect);
$astman->setcallback('Hangup', \&hangup_callback);
$astman->setcallback('DEFAULT', \&default_callback);
}

sub asterisk_disconnect {
$astman->disconnect;
print_log "asterisk_disconnect::" if $Debug{asterisk};
}

# Query Asterisk for Unregistered IAX2 connections
sub check_iax2 {
my $teliax_active = 0;
&asterisk_connect;
my (@data) = $astman->sendcommand( 'Action' => 'Command', 'Command' => "iax2 show registry", 2, 2);
foreach (@data) {
$_ =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/;
my $host = $1;
my $dnsmgr = $2;
my $username = $3;
my $client = $4;
my $refresh = $5;
my $state = $6;
if (($username eq 'jduda') && ($state eq 'Registered')) {
$teliax_active = 1;
}
print_log "asterisk iax2: $host $dnsmgr $username $client $refresh $state" if $Debug{asterisk};
}
&asterisk_down if (!$teliax_active);
&asterisk_disconnect;
}

# Query Asterisk for Unregistered IAX2 connections
sub check_sip {
my $teliax_active = 0;
&asterisk_connect;
my (@data) = $astman->sendcommand( 'Action' => 'Command', 'Command' => "sip show registry", 2, 2);
foreach (@data) {
$_ =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/;
my $host = $1;
my $username = $2;
my $refresh = $3;
my $state = $4;
if (($username eq 'jduda') && ($state eq 'Registered')) {
$teliax_active = 1;
}
print_log "asterisk sip: $host $username $refresh $state" if $Debug{asterisk};
}
&asterisk_down if (!$teliax_active);
&asterisk_disconnect;
}

# Query Asterisk for New Voice Mail Messages
sub check_voice_mail {
&asterisk_connect;
my (%data) = $astman->sendcommand('Action' => "MailboxCount", 'Mailbox' => $config_parms{asterisk_voicemail_box});
foreach (keys %data) {
print_log "asterisk vm: $_: ". $data{$_} if $Debug{asterisk};
if ($_ =~ /NewMessages/) {
$Save{voiceMail} = $data{$_};
}
}
&asterisk_disconnect;
}

# Check for New VoiceMail using a Voice Command
$v_voice_mail = new Voice_Cmd("any voice mail");
if (my $state = said $v_voice_mail) {
&check_voice_mail;
if ($Save{voiceMail}) {
my $message = "messages";
if ($Save{voiceMail} == 1) {
$message = "message";
}
speak (rooms=> "all", text=> "You have $Save{voiceMail} voice mail $message waiting");
} else {
speak (rooms=> "all", text=> "no voice mail messages");
}
}

# Periodically check for New VoiceMail and IAX2 connections
if ($New_Minute) {
if ($config_parms{asterisk_voicemail_period} && !($Minute % $config_parms{asterisk_voicemail_period})) {
&check_voice_mail;
if ($Save{voiceMail} && (state $mode_occupied ne 'vacation')) {
run_voice_cmd "any voice mail";
}
}
# &check_iax2 if ( !($Minute % 5) );
&check_sip if ( !($Minute % 5) );
}


$v_call_phone = new Voice_Cmd("call [shelia,shelia cell,meghan cell,meghan]");
if (my $state = said $v_call_phone) {
&asterisk_connect;
my $number = "";
if ($state eq 'shelia') {
$number = "7818850102";
} elsif ($state eq 'shelia cell') {
$number = "7147851962";
} elsif ($state eq 'meghan cell') {
$number = "8438227696";
} elsif ($state eq 'meghan') {
$number = "7013642900";
}
my (%data) = $astman->sendcommand( Action => "Originate",
Channel => "SIP/101",
Context => "internal",
Exten => $number,
Priority => "1",
Timeout => "30000"
);
foreach (keys %data) {
print_log "asterisk vm: $_: ". $data{$_} if $Debug{asterisk};
}
&asterisk_disconnect;
}

#Action: Originate
#Channel: SIP/101
#Context: home
#Exten: 5406050674
#Priority: 1
#Callerid: 7817361994
#Timeout: 30000
#Variable: var1=23|var2=24|var3=25
#ActionID: ABC45678901234567890

sub audrey_callerid {
my ($name, $number) = @_;
print_log "audrey_callerid: $name $number";
my $file = "$Pgm_Root/web/misc/callerid.shtml";
open (DATA, ">$file") || print_log "Couldn't open file $file, $!";
print DATA "<html><head><title>CALLERID</title>";
print DATA "<h1>CALLERID</h1><br />";
print DATA "<h2>$name</h2><br />";
print DATA "<h2>$number</h2><br />";
print DATA "</html>";
close DATA;
run_voice_cmd "Set all Audrey screen on";
run_voice_cmd "Set all Audrey to callerid screen";
set $t_audrey_callerid 60 * 3;
}

$t_audrey_callerid = new Timer;
if (expired $t_audrey_callerid) {
run_voice_cmd "Set all Audrey to main screen";
run_after_delay 5, sub {
run_voice_cmd "Set all Audrey screen off";
}
}


    (1-1/1)