[Astpp-commit] SF.net SVN: astpp:[2245] trunk
Brought to you by:
darrenkw
From: <dar...@us...> - 2009-04-18 17:11:52
|
Revision: 2245 http://astpp.svn.sourceforge.net/astpp/?rev=2245&view=rev Author: darrenkw Date: 2009-04-18 17:11:43 +0000 (Sat, 18 Apr 2009) Log Message: ----------- Callingcards and freeswitch are now working. Modified Paths: -------------- trunk/scripts/astpp-common.pl Added Paths: ----------- trunk/freeswitch/astpp-fs-monitor.pl Added: trunk/freeswitch/astpp-fs-monitor.pl =================================================================== --- trunk/freeswitch/astpp-fs-monitor.pl (rev 0) +++ trunk/freeswitch/astpp-fs-monitor.pl 2009-04-18 17:11:43 UTC (rev 2245) @@ -0,0 +1,277 @@ +#!/usr/bin/perl +# +# ASTPP - Open Source Voip Billing +# +# Copyright (C) 2004, Aleph Communications +# Copyright (C) Freeswitch (Some of this code was borrowed from the freeswitch contrib directory +# The attribution of that needs to be cleaned up.) +# +# Darren Wiebe (da...@al...) +# +# This program is Free Software and is distributed under the +# terms of the GNU General Public License version 2. +############################################################ +use POSIX; +use POSIX qw(strftime); +use POSIX ':signal_h'; # used for alarm to ensure we get heartbeats +use DBI; +use CGI; +use CGI qw/:standard Vars/; +use Getopt::Long; +use Locale::Country; +use Locale::gettext_pp qw(:locale_h); +use Data::Dumper; +use FreeSWITCH::Client; +use strict; +use ASTPP; +use lib './lib', '../lib'; + +require "/usr/local/astpp/astpp-common.pl"; + +$ENV{'LANGUAGE'} = "en"; # de, es, br - whatever +print STDERR "Interface language is set to: $ENV{'LANGUAGE'}\n"; +bindtextdomain( "ASTPP", "/var/locale" ); +textdomain("ASTPP"); +use vars qw($ASTPP $fs $config $astpp_db $osc_db $agile_db $cdr_db $cdr_table + @output @cardlist $config $params $lastheartbeat); +@output = ( "STDOUT", "LOGFILE" ); +my $verbosity = 1; +$ASTPP = ASTPP->new; +$ASTPP->set_verbosity($verbosity) + ; #Tell ASTPP debugging how verbose we want to be. + +sub initialize() { + $config = &load_config(); + $astpp_db = &connect_db( $config, @output ); + $ASTPP->set_astpp_db($astpp_db); + $config = &load_config_db( $astpp_db, $config ) if $astpp_db; + $cdr_db = &cdr_connect_db( $config, @output ); + $fs = &fs_client_connect($config); + open( LOGFILE, ">>$config->{log_file}" ) + || die "Error - could not open $config->{log_file} for writing\n"; + $cdr_table = $config->{freeswitch_cdr_table}; + + # $ASTPP->debug("Rating calls for FreeSwitch", $verbosity); + +} + +sub fs_client_connect() { + my ($config) = @_; + my ($fs); + print STDERR "Connecting to FreeSwitch\n"; + $fs = init FreeSWITCH::Client { + -password => $config->{freeswitch_password}, + -host => $config->{freeswitch_host}, + -port => $config->{ffreeswitch_port} + }; + if ($fs) { + +# channel_create doesnt have the destination number so we wait for the codec event + $fs->sendmsg( + { 'command' => 'event plain heartbeat channel_hangup codec' } ); + $lastheartbeat = time; + return $fs; + } + else { + print STDERR "Unable to connect to FreeSwitch\n"; + } +} + +############################################### +&initialize; +my $timeout = 1; + +sigaction SIGALRM, new POSIX::SigAction sub { + if ( $lastheartbeat < ( time - $config->{freeswitch_timeout} ) ) { + print "Did not receive a heartbeat in the specified timeout\n"; + $fs->disconnect(); + undef $fs; + $fs = &fs_client_connect($config); + } + + # reset the alarm + alarm $timeout; +} or die "Error setting SIGALRM handler: $!\n"; + +alarm $timeout; + +while ( 1 > 0 ) { + my ( $myhash, %uuids ); + if ( defined $fs ) { + my $reply = $fs->readhash(undef); + if ( $reply->{socketerror} ) { + $fs = &fs_client_connect($config); + } + + if ( $reply->{body} ) { + $myhash = $reply->{event}; + + if ( $myhash->{'event-name'} eq "HEARTBEAT" ) + { ## Deal with heartbeats + $lastheartbeat = time; + print "Got a heartbeat\n"; + + } + elsif ( $myhash->{'event-name'} eq "CODEC" ) { ## New call setup + if ( !$uuids{ $myhash->{'unique-id'} } ) { + print $myhash->{'unique-id'} . " has called\n"; + $uuids{ $myhash->{'unique-id'} } = time; + while ( my ( $key, $value ) = each(%$myhash) ) { + print "CODEC: " . $key . ": " . $value . "\n"; + } + } + + } + elsif ( $myhash->{'event-name'} eq "CHANNEL_HANGUP" ) + { ## hangup event + print "\n\n############################\n\n"; + print $myhash->{'unique-id'} . " has hung up\n"; + delete $uuids{ $myhash->{ + 'unique-id'} }; # we get a codec event after hangup + + while ( my ( $key, $value ) = each(%$myhash) ) { + print "HANGUP: " . $key . ": " . $value . "\n"; + } + + # if ( $myhash->{'variable_last_app'} ) { + $myhash->{'variable_last_app'} = "" + if $myhash->{'variable_last_app'} eq ""; + $myhash->{'variable_last_arg'} = "" + if $myhash->{'variable_last_arg'} eq ""; + my $tmp = +"INSERT INTO `fscdr` (`accountcode`, `src`, `dst`, `dcontext`, `clid`," + . "`channel`, `dstchannel`, `lastapp`, `lastdata`, `calldate`, `answerdate`," + . "`enddate`, `duration`, `billsec`, `disposition`, `amaflags`, `uniqueid`," + . "`userfield`, `read_codec`, `write_codec`, `cost`, `vendor`) VALUES (" + . $cdr_db->quote( $myhash->{'variable_accountcode'} ) . "," + . $cdr_db->quote( $myhash->{'caller-caller-id-number'} ) . "," + . $cdr_db->quote( $myhash->{'caller-destination-number'} ) . "," + . $cdr_db->quote( $myhash->{'caller-context'} ) . "," + . $cdr_db->quote( $myhash->{'variable_caller_id'} ) . "," + . $cdr_db->quote( $myhash->{'other-leg-channel-name'} ) . "," + . $cdr_db->quote( $myhash->{'variable_channel_name'} ) . "," + . $cdr_db->quote( $myhash->{'variable_last_app'} ) . "," + . $cdr_db->quote( $myhash->{'variable_last_arg'} ) . "," + . $cdr_db->quote( $myhash->{'variable_start_stamp'} ) . "," + . $cdr_db->quote( $myhash->{'variable_answer_stamp'} ) . "," + . $cdr_db->quote( $myhash->{'variable_end_stamp'} ) . "," + . $cdr_db->quote( $myhash->{'variable_duration'} ) . "," + . $cdr_db->quote( $myhash->{'variable_billsec'} ) . "," + . $cdr_db->quote( $myhash->{'hangup-cause'} ) . ",''," + # . $cdr_db->quote($myhash->{''}) . "," #amaflags + . $cdr_db->quote( $myhash->{'unique-id'} ) . ",''," + # . $cdr_db->quote($myhash->{''}) . "," #userfield + . $cdr_db->quote( $myhash->{'variable_read_codec'} ) . "," + . $cdr_db->quote( $myhash->{'variable_write_codec'} ) + . ",'none','none')"; + print $tmp; + $cdr_db->do($tmp); + my (@chargelist); + push @chargelist, $myhash->{'unique-id'}; + &processlist( $astpp_db, $cdr_db, $cdr_table, $config, + \@chargelist ); + # } + if ( $myhash->{'variable_callingcards'} + && $myhash->{'variable_last_app'} eq "" ) + { + my ( $cardinfo, $brandinfo, $numberinfo, $pricelistinfo,$cc ); + my $cardnumber = substr( $myhash->{'variable_accountcode'}, 3 ); + $cardinfo = &get_callingcard( $astpp_db, $cardnumber, $config ); + if ( !$cardinfo ) { + $cardinfo = &get_account_cc( $astpp_db, $cardnumber ); + $cc = 1 if $cardinfo; + } + +# Getting this far means we have a valid card and pin. +$brandinfo = &get_cc_brand( $astpp_db, $cardinfo->{brand} ) if $cc == 0; +if ($brandinfo->{reseller}) { + $config = &load_config_db_reseller($astpp_db,$config,$brandinfo->{reseller}); +} +$config = &load_config_db_brand($astpp_db,$config,$cardinfo->{brand}); +$pricelistinfo = &get_pricelist( $astpp_db, $brandinfo->{pricelist} ) + if $cc == 0; +$pricelistinfo = &get_pricelist( $astpp_db, $cardinfo->{pricelist} ) + if $cc == 1; + + print STDERR "THIS IS A CALLINGCARD CALL! \n"; + print STDERR "CARD: $cardinfo->{cardnumber} \n"; + print STDERR "CARD: $cardnumber \n"; + $numberinfo = &get_route( + $astpp_db, $config, + $myhash->{'caller-destination-number'}, + $brandinfo->{pricelist}, $cardinfo + ); + if ( $myhash->{'hangup-cause'} =~ /ANSWER/ + || $myhash->{'variable_billsec'} > 0 ) + { + $ASTPP->debug( + debug => "CALL ANSWERED", + verbosity => $verbosity + ); + my $increment; + if ( $numberinfo->{inc} > 0 ) { + $increment = $numberinfo->{inc}; + } + else { + $increment = $pricelistinfo->{inc}; + } + $ASTPP->debug( + debug => +"$numberinfo->{connectcost}, $numberinfo->{cost}, $myhash->{'variable_billsec'}, $increment, $numberinfo->{includedseconds}", + verbosity => $verbosity + ); + my $charge = &calc_call_cost( + $numberinfo->{connectcost}, + $numberinfo->{cost}, + $myhash->{'variable_billsec'}, + $increment, + $numberinfo->{includedseconds} + ); + $ASTPP->debug( + debug => "Cost $charge ", + verbosity => $verbosity + ); + if ( $cardinfo->{minute_fee_pennies} > 0 ) { + $charge = + ( ( $cardinfo->{minute_fee_pennies} * 100 ) + + $charge ) + if $cardinfo->{timeused} + + $myhash->{'variable_billsec'} => + $cardinfo->{minute_fee_minutes}; + } + if ( $cardinfo->{min_length_pennies} > 0 + && ( $cardinfo->{min_length_minutes} * 60 ) > + $myhash->{'variable_billsec'} ) + { + $charge = + ( ( $cardinfo->{min_length_pennies} * 100 ) + + $charge ); + } + + &write_callingcard_cdr( + $astpp_db, + $config, + $cardinfo, + $myhash->{'caller-caller-id-number'}, + $myhash->{'caller-destination-number'}, + $myhash->{'hangup-cause'}, + $myhash->{'variable_start_stamp'}, + $charge, + $myhash->{'variable_billsec'} + ); + &callingcard_set_in_use($astpp_db,$cardinfo,0); + &callingcard_update_balance($astpp_db,$cardinfo,$charge); + } + } + } + else { ## Unknown event + print "EVENT NAME: " . $myhash->{'event-name'} . "\n"; + print Dumper $myhash; + +# print "$reply->{body}\n"; # print out what was sent, myhash is translated by Client.pm + } + + } + } +} + Property changes on: trunk/freeswitch/astpp-fs-monitor.pl ___________________________________________________________________ Added: svn:executable + * Modified: trunk/scripts/astpp-common.pl =================================================================== --- trunk/scripts/astpp-common.pl 2009-03-23 14:18:45 UTC (rev 2244) +++ trunk/scripts/astpp-common.pl 2009-04-18 17:11:43 UTC (rev 2245) @@ -78,6 +78,30 @@ close(CONFIG); } +sub callingcard_update_balance() { #Update the available credit on the calling card. + my ( $astpp_db, $cardinfo, $charge ) = @_; + my $sql = + "UPDATE callingcards SET used = " + . $astpp_db->quote( ($charge) + $cardinfo->{used} ) + . " WHERE cardnumber = " + . $astpp_db->quote( $cardinfo->{cardnumber} ); + $astpp_db->do($sql); +} + + +sub callingcard_set_in_use() { # Set the "inuse" flag on the calling cards. This prevents multiple people from +# using the same card. + my ( $astpp_db, $cardinfo, $status ) = @_; + my $sql; + $sql = + "UPDATE callingcards SET inuse = " + . $astpp_db->quote($status) + . " WHERE cardnumber = " + . $astpp_db->quote( $cardinfo->{cardnumber} ); + $astpp_db->do($sql); +} + + # Add a calling card. sub add_callingcard() { my ( $astpp_db, $config, $branddata, $status, $pennies, @@ -2031,6 +2055,24 @@ } } +sub write_callingcard_cdr() { # Write the callingcardcdr record if this is a calling card. + my ($astpp_db, $config, $cardinfo, $clid, $destination, $status, $callstart, $charge, $answeredtime ) = @_; + my ($sql); + if (!$status) {$status = gettext("N/A"); } + $sql = +"INSERT INTO callingcardcdrs (cardnumber,clid,destination,disposition,callstart,seconds," + . "debit) VALUES (" + . $astpp_db->quote( $cardinfo->{cardnumber} ) . ", " + . $astpp_db->quote($clid) . ", " + . $astpp_db->quote($destination) . ", " + . $astpp_db->quote($status) . ", " + . $astpp_db->quote($callstart) . ", " + . $astpp_db->quote($answeredtime) . ", " + . $astpp_db->quote($charge) . ")"; + $astpp_db->do($sql); + print STDERR $sql . "\n"; +} + # Write cdr to the ASTPP cdr database. This is also used to apply charges and credits to an account. sub write_account_cdr() { my ( $astpp_db, $account, $amount, $description, $timestamp, $answeredtime, $uniqueid, $clid, $pricelist, $pattern ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |