// Version 1 (c) for ZAP incomming call file name zapincomming.agi by imran ( Pakistan )
// features in this agi are handled:
// (1) Call Recording enbabled / disabled database driven controle.
// (2) Call forwarding enbabled / disabled database driven controle.
// (3) Voice Mail enbabled / disabled database driven controle.
// (4) Call Billing Customized CDR database driven controle ( Needs to specify your own call rates )
// (5) Auto IVR response Specify IVR message or specify Extension(s) or Input your Number for direct dial database driven controle.
// (6) IAX/SIP/ZAP dialing You can make SIP/IAX call or local call through zap channel on your PSTN ternmial.
// (7) Call Debuggin you can view call logs via writing filing rather than using verbose expensive function.
// Pending features have to be done( Currently Working on these features ):
// (1) Call Blocking.
// (2) Charge your Card / Account via IVR. ( You can charge your talk time, cardCharging feature)
// (3) Pay your bill through free phone call. ( Through Credit Card charging )
// (4) Sending Simple Messages. (SMS) ( you can send your limited message )
// (5) Sending an image. ( movie ) ( You can send your live movie to the remote side )
// (6) Sending fax copy. ( You can send your document as a fax )
// (7) send email when you are not logon. ( You can send email message to the customer’s device if you are not log on )
#!/usr/bin/perl
use Asterisk::AGI;
my $ModuelPath = "/var/www/cgi-bin/modules";
use lib "/var/www/cgi-bin/modules";
use Db;
$AGI = new Asterisk::AGI;
$AGI->answer();
($calleridnum, $phoneno, $ZapChannel) = @ARGV;
my $dial_up_to_seconds=30;
my $dialstr;
my $DialedNo;
my $d_path = "/var/www/html/recordings";
my $ivrPath = "/var/www/html/ivrSounds";
my $gsm_file;
my $wav_file;
my %g_DATA;
my $ChannalName="";
my $isExt;
my $info;
my $CALLSTATUS;
my $g_OUTPUT ="\n[ START ]\n";
my $DEBUG_OUTPUT_FLAG =1;
$CDR_HASH{CALLERID} ='';
$CDR_HASH{CALLRECORDINGFILE} ='';
$CDR_HASH{CONTEXT} =$AGI->get_variable("CONTEXT");
$CDR_HASH{BILLSEC} =0;
$CDR_HASH{USERFIELD} ='';
$CDR_HASH{CLID} ='';
$CDR_HASH{AMAFLAGS} =3;
$CDR_HASH{APPDATA} ="";
$CDR_HASH{BILLSEC}=0;
if ( $calleridnum eq '' )
{
$calleridnum ='unknown';
$CDR_HASH{CALLERID} =$calleridnum;
}
$CDR_HASH{CALLERID} =$calleridnum;
$ChannalName = $AGI->get_variable("CHANNEL");
#$ChannalName : Zap/1-1
$ChannalName =~ /Zap\/(.*?)-/gsi;
my $lineno =$1;
my $strSQL = "
select is_ext,info from codetail where co_no='$lineno'";
my @Result = Db->ExecuteQuery($strSQL);
if($Result[1][0] eq "")
{
$AGI->stream_file("$ivrPath/welcomt2ippx","0123456789");
sleep(3);
exit;
}
$isExt =$Result[1][0];
$info =$Result[1][1];
#when Extension are defined
if($isExt)
{
# in $info= "100023-100024" out $info= "100023&SIP/100024&SIP/"
my @DATA = split (/-/,$info);
for ( my $nIndex=0; $nIndex <$#DATA; $nIndex++ )
{
if ( $DATA[$nIndex] ne '' )
{
$DialedNo = $DATA[$nIndex];
last;
}
}
if ( $DialedNo eq '' )
{
# extension is not defined
sleep(3);
exit;
}
%g_DATA=getAccessOfCalledExten($DialedNo);
$info =~ s/\-/&SIP\//g;
$dialstr = "SIP/$info|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
else
{
my $strSQL = "
select 0map,1map ,2map ,3map ,path from ivr where id='$info'";
my @Result = Db->ExecuteQuery($strSQL);
if($Result[1][4] eq "")
{
$AGI->stream_file("$ivrPath/welcomt2ippx","0123456789");
sleep(3);
exit;
}
$n0map =$Result[1][0];
$n1map =$Result[1][1];
$n2map =$Result[1][2];
$n3map =$Result[1][3];
$path =$Result[1][4];
# in = $path ="woman.gsm" out = $path = "woman";
$path =~ s/\..*$//g;
for($i=0;$i<3;$i++)
{
$DialedNo="";
$DialedNo= $AGI->get_data("$ivrPath/$path", 5000, 3);
if($DialedNo eq "")
{
if($i == 2){$DialedNo=$n0map;}
else {next;}
}
elsif( $DialedNo ==0 )
{
$DialedNo=$n0map;
}
elsif($DialedNo ==1)
{
$DialedNo=$n1map;
}
elsif($DialedNo ==2)
{
$DialedNo=$n2map;
}
elsif($DialedNo ==3)
{
$DialedNo=$n3map;
}
else
{
if(!(length($DialedNo)==3))
{
next;
}
}
%g_DATA=getAccessOfCalledExten($DialedNo);
$dialstr = "SIP/".$DialedNo . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
last;
}
}
if( $g_DATA{MINEXT} <= $DialedNo && $g_DATA{MAXEXT} >= $DialedNo )
{
#valid Extension
$AGI->stream_file("pls-wait-connect-call");
}
else
{
#Sorry Invalid Extension
$AGI->stream_file('you-dialed-wrong-number');
$AGI->hangup();
exit;
}
if ( $g_DATA{CALLRECORDING} eq 'Y' )
{
callrecording($DialedNo);
}
$res = $AGI->exec("DIAL $dialstr");
$CALLSTATUS = $AGI->get_variable(DIALSTATUS);
$CDR_HASH{CHANNEL} =$AGI->get_variable("CHANNEL");
$CDR_HASH{CALLEDID} =$DialedNo;
$CDR_HASH{DIALSTATUS}=$CALLSTATUS;
$CDR_HASH{ANSWERTIME}=$answeredtime;
$CDR_HASH{APPDATA} =$dialstr;
if ( $CALLSTATUS ne 'ANSWER' && $CALLSTATUS ne 'ANSWERED')
{
if ( $g_DATA{CALLFORWARDING} eq 'Y' )
{
$dialstr = &callforwording();
if( $dialstr eq '' )
{
goto LABLE2;
}
$res = $AGI->exec("DIAL $dialstr");
$CALLSTATUS = $AGI->get_variable(DIALSTATUS);
$CDR_HASH{CHANNEL} =$AGI->get_variable("CHANNEL");
$CDR_HASH{CALLEDID} =$DialedNo;
$CDR_HASH{DIALSTATUS}=$CALLSTATUS;
$CDR_HASH{ANSWERTIME}=$answeredtime;
$CDR_HASH{APPDATA} =$dialstr;
if ( $CALLSTATUS eq 'ANSWER' or $CALLSTATUS eq 'ANSWERED')
{
goto LABLE;
}
}
LABLE2:
if ( $g_DATA{VOICEMAIL} eq 'Y' )
{
$res = $AGI->exec("VoiceMail u$DialedNo");
sleep(2);
system("chmod +777 /var/spool/asterisk/voicemail/default/$phoneno/ -R");
}
else
{
$AGI->stream_file('nbdy-avail-to-take-call'); #disconnected #$AGI->stream_file('agent-loggedoff');
sleep(1);
$AGI->stream_file('call-terminated');
sleep(1);
$AGI->stream_file('thanks-for-using');
}
}
LABLE:
if ( $CALLSTATUS eq 'ANSWER' or $CALLSTATUS eq 'ANSWERED')
{
$CDR_HASH{BILLSEC} =$CDR_HASH{ANSWERTIME} - 3;
}
if ( $g_DATA{CALLRECORDING} eq 'Y' )
{
my $C = $AGI->get_variable(CHANNEL);
my $t = $AGI->exec("StopMonitor $C");
$AGI->hangup();
sleep(3);
system("sox $d_path/$wav_file -r 8000 $d_path/$gsm_file resample -ql");
}
else
{
$AGI->hangup();
}
&saveCdrData(%CDR_HASH);
exit;
sub myVerbose
{
my ($pStr)=@_;
return;
$pStr =~ s/\n/ /ige;
$AGI->verbose("$pStr\n", 3);
return;
}
sub callrecording
{
my ($phoneno) =@_;
my $CalledNumber = $phoneno;
my $CurDate;
$CurDate = $AGI->get_variable("DATETIME");
$CurDate =~ s/://gsi;
$CurDate=substr($CurDate,4,4) . substr($CurDate,2,2) .substr($CurDate,0,2) .substr($CurDate,8,7);
$gsm_file = "Callfrom-$calleridnum-CallTo-$CalledNumber-at-$CurDate.gsm";
$wav_file = "Callfrom-$calleridnum-CallTo-$CalledNumber-at-$CurDate.WAV";
$res = $AGI->exec("Monitor WAV|$d_path/Callfrom-$calleridnum-CallTo-$CalledNumber-at-$CurDate|m");
$CDR_HASH{CALLRECORDINGFILE} = $gsm_file;
}
sub getAccessOfCalledExten
{
my ( $ext )=@_;
my %g_DATA;
my $strSQL = "
select
call_recording,
local_calling,
international_calling,
international_calling_ww35,
international_calling_all,
call_forwarding,
extension_busy,
extension_answered,
extension_logged,
caller_id,
summary_call,
call_waiting,
voice_mail,
seconds,
evoice,
calltype
from buddies_relation
where name=\"$ext\"
";
my @Result = Db->ExecuteQuery($strSQL);
$g_DATA{CALLRECORDING} = $Result[ 1][ 0];
$g_DATA{LOCALCALLING} = $Result[ 1][ 1];
$g_DATA{INTCALL} = $Result[ 1][ 2];
$g_DATA{INTCALLWW35} = $Result[ 1][ 3];
$g_DATA{INTCALLALL} = $Result[ 1][ 4];
$g_DATA{CALLFORWARDING}= $Result[ 1][ 5];
$g_DATA{EXTBUAY} = $Result[ 1][ 6];
$g_DATA{EXTANSWER} = $Result[ 1][ 7];
$g_DATA{EXTLOG} = $Result[ 1][ 8];
$g_DATA{CALLERID} = $Result[ 1][ 9];
$g_DATA{SUMMARYCALL} = $Result[ 1][ 10];
$g_DATA{CALLWAITING} = $Result[ 1][ 11];
$g_DATA{VOICEMAIL} = $Result[ 1][ 12];
$g_DATA{SECONDS} = $Result[ 1][ 13];
$g_DATA{CALLTYPE} = $Result[ 1][ 14];
if ( $g_DATA{SECONDS} ne '' && $g_DATA{VOICEMAIL} eq 'Y')
{
$dial_up_to_seconds =$g_DATA{SECONDS};
}
my @r = Db->ExecuteQuery("select min(name), max(name) from sip_buddies");
$g_DATA{MINEXT} = $r[ 1][ 0];
$g_DATA{MAXEXT} = $r[ 1][ 1];
return %g_DATA;
}
// NOTE: this function needs your customiezed call forwading functionality depends on call status BUSY, NOANSWER, NOAVAILABLE etc
sub callforwording
{
my $dial="";
if ( $CALLSTATUS eq 'BUSY' )
{
if ( $g_DATA{MINEXT} <= $g_DATA{EXTBUAY} && $g_DATA{MAXEXT} >= $g_DATA{EXTBUAY} )
{
# make here SIP/IAX/ZAP dailstring according to the dype of $g_DATA{EXTBUAY} number
if( $g_DATA{CALLTYPE} eq '1' )
{
$dial = = "SIP/" . $g_DATA{EXTBUAY} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
else if( $g_DATA{CALLTYPE} eq '2' )
{
$dial = = "IAX2/admin:admin123\@carrier/".$g_DATA{EXTBUAY} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
else if( $g_DATA{CALLTYPE} eq '3' )
{
$dial = = "ZAP/g1/" . $g_DATA{EXTBUAY} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
$DialedNo =$g_DATA{EXTBUAY};
return $dial;
}
return $dial;
}
if ( $CALLSTATUS eq 'NO ANSWER' )
{
if ( $g_DATA{MINEXT} <= $g_DATA{EXTANSWER} && $g_DATA{MAXEXT} >= $g_DATA{EXTANSWER} )
{
# make here SIP/IAX/ZAP dailstring according to the dype of $g_DATA{EXTANSWER} number
if( $g_DATA{CALLTYPE} eq '1' )
{
$dial = = "SIP/" . $g_DATA{EXTANSWER} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
else if( $g_DATA{CALLTYPE} eq '2' )
{
$dial = = "IAX2/admin:admin123\@carrier/" . $g_DATA{EXTANSWER} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
else if( $g_DATA{CALLTYPE} eq '3' )
{
$dial = = "ZAP/g1/" . $g_DATA{EXTANSWER} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
$DialedNo =$g_DATA{EXTANSWER};
return $dial;
}
return $dial;
}
if ( $CALLSTATUS eq 'NOAVAILABLE' )
{
if ( $g_DATA{MINEXT} <= $g_DATA{EXTLOG} && $g_DATA{MAXEXT} >= $g_DATA{EXTLOG} )
{
# make here SIP/IAX/ZAP dailstring according to the dype of $g_DATA{EXTLOG} number
if( $g_DATA{CALLTYPE} eq '1' )
{
$dial = = "SIP/" . $g_DATA{EXTLOG} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
else if( $g_DATA{CALLTYPE} eq '2' )
{
$dial = = "IAX2/admin:admin123\@carrier/" . $g_DATA{EXTLOG} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
else if( $g_DATA{CALLTYPE} eq '3' )
{
$dial = = "ZAP/g1/" . $g_DATA{EXTLOG} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
}
$DialedNo =$g_DATA{EXTLOG};
return $dial;
}
return $dial;
}
return $dial;
}
sub savelog
{
open(FILE, ">>/var/lib/asterisk/agi-bin/dialoutlog.txt") or die("Couldn't open dialoutlog.txt\n");
print FILE "(". localtime() .")".$g_OUTPUT;
close(FILE);
}
# table mycdr by imran
# IN Hash
# OUT nothing
sub saveCdrData
{
my (%HASH)=@_;
Db->ExecuteQuery("insert into mycdr(clid,src,dst,dcontext,channel,duration,billsec,disposition,calldate,recordedfile,amaflags,userfield,lastdata)
values('$HASH{CLID}','$HASH{CALLERID}','$HASH{CALLEDID}','$HASH{CONTEXT}','$HASH{CHANNEL}','$HASH{ANSWERTIME}','$HASH{BILLSEC}','$HASH{DIALSTATUS}',sysdate(),'$HASH{CALLRECORDINGFILE}','$HASH{AMAFLAGS}','$HASH{USERFIELD}','$HASH{APPDATA}')");
if($DEBUG_OUTPUT_FLAG)
{
$g_OUTPUT .="[ END ]\n\n";
#$AGI->verbose("$g_OUTPUT", 3) ;
&savelog();
}
}