// sip out going agi by imran
#!/usr/bin/perl
use Asterisk::AGI;
my $ModuelPath = "/var/www/cgi-bin/modules";
my $ivrPath = "/var/www/html/ivrSounds";
use lib "/var/www/cgi-bin/modules";
use Db;
$AGI = new Asterisk::AGI;
my %input = $AGI->ReadParse();
my $callerid="0";
$callerid= $input{callerid};
$|=1;
$AGI->answer();
($calleridnum, $phoneno, $ZapChannel) = @ARGV;
my $g_OUTPUT;
my $C = $AGI->get_variable(CHANNEL);
my $tempFinalDate;
my $tempCalledNumber;
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
from buddies_relation
where name=\"$phoneno\"
";
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{EVOICE} = $Result[1][14];
my $dial_up_to_seconds=30;
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];
##### call recording feature
my $d_path = "/var/www/html/recordings";
my $gsm_file;
my $wav_file;
my $g_Cents;
my $answeredtime;
my $OrderId;
my $callrate;
#### end
my $recordingSize = readRecordinSize();
if( $g_DATA{CALLRECORDING} eq 'Y' ) {
$AGI->stream_file('preRecorded'); #PreRecorded Msg ...Recording Alert
if( $recordingSize <= 498 ) {
callrecording($phoneno);
}
}
#$dial_up_to_seconds =30;
# - try simple simple sp dialing on extension like SIP/101
$dialstr = "SIP/".$phoneno . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
##$res =$AGI->set_variable('DIALSTATUS', 'RINGING');
#$res = $AGI->exec("DIAL RINGING");
$res =$AGI->set_variable('CHANNEL', 'RINGING');
$AGI->verbose("imran ($res )\n",3);
#$AGI->wait(2);
$res = $AGI->exec("DIAL $dialstr");
# - if ANswer.. exit
my $CALLSTATUS = $AGI->get_variable(DIALSTATUS);
if( $CALLSTATUS eq 'ANSWER' or $CALLSTATUS eq 'ANSWERED' )
{
$answeredtime = $AGI->get_variable(ANSWEREDTIME);
CutBalance($OrderId,$callrate,$answeredtime);
my $priority=4;
$res =$AGI->set_priority($priority);
exit;
}
my $lineno;
my @Result;
my $is_sip =1; # 1 mean SIP call 0 mean ZAP call
# - do accoring to busy , unavail and
if( ( $CALLSTATUS ne 'ANSWER' && $CALLSTATUS ne 'ANSWERED' ) && $g_DATA{CALLFORWARDING} eq 'Y')#Allow Call forwarding
{
# its mean he can now ring on external number and as well extension number.
my @Result=Db->ExecuteQuery("select co_no,outgoing_prefix from codetail");
my %CoPrHash;
my $ZapStr;
# /zap/1&Zap/2&Zap
for($i=1;$i<=$#Result;$i++)
{
$Co =$Result[$i][0];
$prefix =$Result[$i][1];
$CoPrHash{$Co} = $prefix;
$ZapStr .= "Zap/$Co";
if($i != $#Result)
{
$ZapStr .= "&" ;
}
}
$res = $AGI->exec("ChanIsAvail $ZapStr");
my $ChannalName = $AGI->get_variable("AVAILCHAN"); #CHANNEL
$ChannalName =~ /Zap\/(.*?)-/gsi;
$lineno =$1;
my $strSQL = "
select is_ext,info from codetail where co_no='$lineno'";
@Result = Db->ExecuteQuery($strSQL);
if($Result[1][0] ne "")
{
$AGI->stream_file('call-forward');
$is_sip = allowCallForwarding();
}
else
{
# sorry your call couldnt be forward
$AGI->stream_file('call-forwarding');
$AGI->stream_file('number-not-answering');
$AGI->stream_file('sorry-youre-having-problems');
sleep(1);
}
}
# here i am checking for voice mail
if ( $g_DATA{VOICEMAIL} eq 'Y' )
{
#here do delay for specified number of seconds and then open the voice mail
$CALLSTATUS = $AGI->get_variable(DIALSTATUS);
if( ( not( $CALLSTATUS eq 'ANSWER' || $CALLSTATUS eq 'ANSWERED') ) || ($CALLSTATUS eq 'CONGESTION'))
{
#play a stream message for Congession and then activate the voice mail message
$res = $AGI->exec("VoiceMail u$phoneno");
system("chmod +777 /var/spool/asterisk/voicemail/default/$phoneno/ -R");
#my $priority=4;$res =$AGI->set_priority($priority);
}
}
else
{
if (( not( $CALLSTATUS eq 'ANSWER' || $CALLSTATUS eq 'ANSWERED') ) || ($CALLSTATUS eq 'CONGESTION'))
{
$AGI->stream_file('nbdy-avail-to-take-call'); #disconnected
#$AGI->stream_file('agent-loggedoff');
sleep(1);
$AGI->stream_file('call-terminated');
}
}
$CALLSTATUS = $AGI->get_variable(DIALSTATUS);
if ($CALLSTATUS eq 'ANSWER' || $CALLSTATUS eq 'ANSWERED')
{
$answeredtime = $AGI->get_variable(ANSWEREDTIME);
if(!$is_sip )
{
CutBalance($OrderId,$callrate,$answeredtime);
#my $priority=4;$res =$AGI->set_priority($priority);
}
}
my $t = $AGI->exec("StopMonitor $C");
$AGI->hangup();
sleep(3);
system("sox $d_path/$wav_file -r 8000 $d_path/$gsm_file resample -ql");
############# Call Recording Information Goin Into Database #########
$strQry="select max(serialno) from callrecord";
my @ResultSet = Db->ExecuteQuery($strQry);
$serialno = $ResultSet[1][0];
if($serialno eq '') {
$strQry="insert into callrecord(serialno) values(0)";
}
myVerbose("Aarfeen: $CalledNumber");
$serialno = $serialno + 1;
$strQry="insert into callrecord values($serialno, \"$calleridnum\",\"$tempCalledNumber\",\"$tempFinalDate\",\"$d_path/$wav_file\", \"$tempFinalDate\")";
my @ResultSet = Db->ExecuteQuery($strQry);
##################################################################
exit;
sub OUTPUT
{
my ($lable,$value) =@_;
$g_OUTPUT .="($lable=$value)-"
}
# OUTPUT("\$ChannalName",$ChannalName);
# OUTPUT("\$lineno",$lineno);
# $AGI->verbose("$g_OUTPUT\n",3);
sub billing_for_other_calls
{
($OrderId,$callrate) = setup_billing($calleridnum);
if ( $OrderId eq '-1')
{
#No Talk time balance in ur account
$AGI->stream_file('not-enough-credit'); #disconnected
$AGI->hangup();
exit;
}
}
# OUT = 1 for sip and 0 for Zap
sub allowCallForwarding
{
if ( $CALLSTATUS eq 'BUSY' )
{
if ($CALLSTATUS eq 'BUSY' && ( $g_DATA{MINEXT} <= $g_DATA{EXTBUAY} && $g_DATA{MAXEXT} >= $g_DATA{EXTBUAY} ) )
{
#its mean sip dialstr
$dialstr = "SIP/".$g_DATA{EXTBUAY} . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
$res = $AGI->exec("DIAL $dialstr");
return 1;
}
else
{
billing_for_other_calls();
$dialstr = "Zap/" . $lineno . "/" . $Result[1][1] . $g_DATA{EXTBUAY};
$res = $AGI->exec("DIAL $dialstr");
return 0;
}
}
elsif ($CALLSTATUS eq 'NOANSWER' )
{
if ($CALLSTATUS eq 'NOANSWER' && ( $g_DATA{MINEXT} <= $g_DATA{EXTANSWER} && $g_DATA{MAXEXT} >= $g_DATA{EXTANSWER} ) )
{
#its mean sip dialstr
$dialstr = "SIP/".$g_DATA{EXTANSWER} . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
$res = $AGI->exec("DIAL $dialstr");
return 1;
}
else
{
billing_for_other_calls();
$dialstr = "Zap/" . $lineno . "/" . $Result[1][1] . $g_DATA{EXTANSWER};
$res = $AGI->exec("DIAL $dialstr");
return 0;
}
}
elsif ($CALLSTATUS eq 'CHANUNAVAIL')
{
if ($CALLSTATUS eq 'CHANUNAVAIL' && ( $g_DATA{MINEXT} <= $g_DATA{EXTLOG} && $g_DATA{MAXEXT} >= $g_DATA{EXTLOG} ) )
{
#its mean sip dialstr
$dialstr = "SIP/".$g_DATA{EXTLOG} . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
$res = $AGI->exec("DIAL $dialstr");
return 1;
}
else
{
billing_for_other_calls();
$dialstr = "Zap/" . $lineno . "/" . $Result[1][1] . $g_DATA{EXTLOG};
$res = $AGI->exec("DIAL $dialstr");
return 0;
}
}
}
sub myVerbose
{
my ($pStr)=@_;
return 0;
$pStr =~ s/\n/ /ige;
$AGI->verbose("$pStr\n", 3);
}
sub callrecording
{
my ($phoneno) =@_;
my $CalledNumber = $phoneno;
my $CurDate;
$d_path = "/var/www/html/recordings";
$callstart= currentDbDate();
$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);
$tempsql ="select curtime()";
@tempResult = Db->ExecuteQuery($tempsql);
$tempResult[1][0];
$tempFinalDate = "$callstart $tempResult[1][0]";
$tempCalledNumber = $CalledNumber;
$endofLoop=1;
while($endofLoop==1) {
$random = int( rand(60000));
$gsm_file = "GSM$random-FILE.gsm";
$wav_file = "WAV$random-FILE.WAV";
$strQry = "select * from callrecord where filepath=\"$d_path/$wav_file\" ";
my @ResultSet = Db->ExecuteQuery($strQry);
if($Result[1][0] ne '') {
$endofLoop=1;
}
else {
$endofLoop=0;
}
}
$res = $AGI->exec("Monitor WAV|$d_path/WAV$random-FILE|m");
#system("sox $d_path/$wav_file -r 8000 $d_path/$gsm_file resample -ql");
}
sub currentDbDate
{
my $strSQL = "
select curdate()
";
my @Result = Db->ExecuteQuery($strSQL);
return $Result[1][0];
}
sub setup_billing
{
my ( $Exten ) =@_;
my @Result = Db->ExecuteQuery("select id,talktime from buddies_relation where name='$Exten'");
my $Cents = $Result[1][1];
$g_Cents = $Result[1][1];
if($Cents<=0)
{
# sorry u dont have an enough talk time in ur account
$Cents=0;
return ('-1','-1');
}
my $bal=$Cents/100;
my $DollarBal =sprintf("%d",$bal);
my $CentsBal =sprintf("%d",(sprintf("%d",$bal*100)%100));
my $Totalcents =$DollarBal*100 + $CentsBal;
my %Hash;
$Hash{Rates} =0.052;
my $totalCents =$Totalcents ;
my $callrate =sprintf("%d",$Hash{Rates}*100);
my $totalMinutes=sprintf("%d",$totalCents/$callrate);
my $totalSeconds=sprintf("%d",((($totalCents%$callrate)/$callrate)*60));
#$callrate=$callrate/100;
#my $min=sprintf("%d",$answeredtime/60);
#my $Sec=sprintf("%d",$answeredtime%60);
#if($Sec>0)
#{
# $min++;
#}
#
# $Cut= $min*$callrate;
#
# $Cost=$Hash{broadvoice} * $min;
#
# $profit=$Cut-$Cost;
#
# if($dialstatus ne "ANSWER") {$profit=0;}
return ($Result[1][0],$callrate);
}
sub CutBalance
{
my ($id,$Rate,$CallSec) = @_;
my $min=sprintf("%d",$CallSec/60);
my $Sec=sprintf("%d",$CallSec%60);
if($Sec>0)
{
$min++;
}
my $Cut= $min*$Rate;
#$AGI->verbose("$extention = ($id) min($min),sec($Sec),cut($Cut)",3);
my $amount = $g_Cents - $Cut;
my $strSQL = "Update buddies_relation set talktime =\"$amount\" where id=\"$id\" ";
Db->ExecuteQuery($strSQL);
#$AGI->verbose("min($min),sec($Sec),cut($Cut),amount($amount),qury($strSQL)",3);
}
sub readRecordinSize {
my $totalSize;
my $recordingsPath = "/var/www/html/recordings/";
opendir(DIR, $recordingsPath) || die "can't opendir $DOCSPATH: $!";
@dots = readdir(DIR);
foreach $eDIR (@dots)
{
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($recordingsPath.$eDIR);
if($eDIR ne '.' && $eDIR ne '..') {
$totalSize = $totalSize + $size;
}
}
$totalSize = ($totalSize / 1024) / 1024; # Converting Bytes into Megabytes
$fileSize = sprintf("%.2f", $totalSize); #Rounding to 2 Digits after Decimal
return $fileSize;
}