Kamran Ahmad
2005-Jul-18 05:20 UTC
[Asterisk-Users] why $cdr{'CALLERID'} and $cdr{'DNID'} are empty in perl agi connected with asterisk manager
hello perl experts i am working with "ast-rad-acc.pl" from http://www.voip-info.org/tiki-index.php?page=PortaOne+Radius+auth i dont know why $cdr{'DNID'} and $cdr{'CALLERID'} under 'sub send_acc {' are empty. i m successfully connected with asterisk manager and when call i hangup my perl application is getting that all other thing are ok but i dont know why only these two variables are not working. other variables like CALLID, ACCOUNTCODE, etc are ok but these two DNID and CALLERID are empty here is the code i am using with asterisk-CVS #!/usr/bin/perl # # Based on http://mail.newmmc.com/~wsmith/astcdr author is unknown, # found here http://www.voip-info.org/wiki-Asterisk+AGI # # RADIUS Accounting By # (c)2004 Porta Software Ltd. www.portaone.com # Oleksandr Kapitanenko <kapitan@portaone.com> # use strict; use Asterisk::Manager; use Sys::Syslog; use POSIX; use Config::IniFiles; use Authen::Radius; Authen::Radius->load_dictionary; # Lock file # my $lock_file = '/var/run/ast-rad-acc.pid'; # Config vars # my $runas_user = 'nobody'; my $ast_hostname = 'localhost'; my $ast_username = 'test'; my $ast_password = 'test'; my $monitor_dir = '/var/spool/asterisk/monitor'; # Read global RADIUS configuratuin from extensions.conf # # I havte doing that but Asterisk manager interface can not read global variables # my $config_dir = '/usr/local/etc/asterisk'; # Globals # my %channels; my ($rad_serv, $rad_sec, $nas_ip); # Check if already running # if( -e $lock_file ) { open(PID,$lock_file); my $pid=<PID>; close PID; chomp $pid; if( !-e "/proc/$pid" ) { print STDERR "Lock file present, but no process with pid=$pid.\n"; die "Can't delete lock file $lock_file\n" if !unlink $lock_file; print STDERR "Lock file has been removed.\n"; } else { die "Lockfile present, another copy is punning pid=$pid\n"; } } load_config(); my ($name, $passwd, $uid, $gid) getpwnam($runas_user) or die "$runas_user not in passwd file";; # Become daemon # my $pid; if( !defined($pid = fork()) ) { die "cannot fork: $!"; } elsif ($pid) { # Create lockfile, and finish parent process # open(PID, "> $lock_file") || die "ast-rad-acc.pl: Unable to create lockfile $lock_file\n"; print PID "$pid"; close PID; chown $uid, $gid, $lock_file; exit; } else { # daemon setpgrp(); select(STDERR); $| = 1; select(STDOUT); $| = 1; openlog('ast-rad-acc', 'cons,pid', 'daemon'); syslog('notice', "RADIUS accounting for Asterisk started"); } # Install signall handler # $SIG{INT} = \&safe_exit; $SIG{QUIT} = \&safe_exit; $SIG{TERM} = \&safe_exit; $SIG{HUP} = \&load_config; # Drop privileges # setuid($uid); $< = $uid; $> = $uid; my $astman = new Asterisk::Manager; $astman->user($ast_username); $astman->secret($ast_password); $astman->host($ast_hostname); my $ast_connected = 1; while( 1 ) { if( $astman->connect ) { $ast_connected = 1; syslog('info', 'Connected to Asterisk!'); $astman->setcallback('DEFAULT', \&status_callback); eval { $astman->eventloop; }; } else { syslog('err', 'Could not connect to Asterisk!') if $ast_connected; $ast_connected = 0; } sleep 1; } sub status_callback { my (%event) = @_; return unless defined(%event); foreach (keys %event) { syslog('debug', "$_: ". $event{$_} . "\n" ); } syslog('debug', "\n"); for ($event{'Event'}) { # Variable read example # print STDERR $astman->sendcommand( Action => 'Getvar', Channel => $event{'Channel'}, Variable => 'DNID' ); $event{'Callerid'} = $1 if defined $event{'Callerid'} && $event{'Callerid'} =~ /<(\d*)>/; /newchannel/i && do { my $call_origin = "originate"; $call_origin = "answer" if $event{'State'} =~ /^Ring$/i; my $call_type = "VoIP"; $call_type = "Telephony" if $event{'Channel'} =~ /^(Zap)|(VPB)|(phone)|(Modem)|(CAPI)|(mISDN)|(Console)/; # session-protocol # other, cisco, h323, multicast, sipv2, sdp, frf11-trunk, cisco-switched, MarsAnalog, C1000Isdn, aal2-trunk my $protocol = 'other'; $protocol = 'sipv2' if $event{'Channel'} =~ /^SIP/i; $protocol = 'h323' if $event{'Channel'} =~ /^h323/i; $channels{$event{'Channel'}} = { 'CHANNEL' => $event{'Channel'}, 'CALLERID' => $event{'Callerid'}, 'DNID' => $event{'DNID'}, 'UNIQUEID' => $event{'Uniqueid'}, 'CALL_START' => time(), 'LINK_START' => time(), 'LINK_END' => time(), 'CALL_ORIGIN' => $call_origin, 'CALL_TYPE' => $call_type, 'CALL_PROTOCOL' => $protocol, 'CALL_ID' => $event{'Uniqueid'}, 'RADIUS_Server' => $rad_serv, 'RADIUS_Secret' => $rad_sec, 'NAS_IP_Address' => $nas_ip }; $channels{$event{'Channel'}}{'Remoteip'} $event{'Remoteip'} if defined $event{'Remoteip'}; }; /newexten/i && do { $channels{$event{'Channel'}}{'DNID'} $event{'DNID'} if defined $event{'DNID'}; $channels{$event{'Channel'}}{'ACCOUNTCODE'} $event{'AppData'} if defined $event{'Application'} && $event{'Application'} eq 'SetAccount'; if( defined $event{'Application'} && $event{'Application'} eq 'SetVar') { my ( $_var, $_val ) = split(/=/, $event{'AppData'}); $channels{$event{'Channel'}}{$_var} = $_val; } }; /Newcallerid/i && do { $channels{$event{'Channel'}}{'CALLERID'} $event{'Callerid'} if defined $event{'Callerid'}; }; /newstate/i && do { $channels{$event{'Channel'}}{'CALLERID'} $event{'Callerid'} if defined $event{'Callerid'}; $channels{$event{'Channel'}}{'DNID'} $event{'DNID'} if defined $event{'DNID'}; }; /^link$/i && do { my $channel = $event{'Channel1'}; return unless $channels{$channel}; $channels{$channel}{'DSTCHANNEL'} $event{'Channel2'}; $channels{$channel}{'LINK_START'} = time(); $channels{$event{'Channel2'}}{'LINK_START'} time(); $channels{$event{'Channel1'}}{'CALL_ID'} $event{'Uniqueid1'}; $channels{$event{'Channel2'}}{'CALL_ID'} $event{'Uniqueid1'}; $channels{$event{'Channel1'}}{'ACCOUNTCODE'} $channels{$event{'Channel1'}}{'CALLERID'} if !defined $channels{$event{'Channel1'}}{'ACCOUNTCODE'}; $channels{$event{'Channel2'}}{'ACCOUNTCODE'} $channels{$event{'Channel1'}}{'ACCOUNTCODE'}; syslog('info', 'Link without uniqueid') unless $channels{$channel}{'UNIQUE'}; syslog('info', 'Link without channeld') unless $channel; syslog('info', 'Link on undefined channel') unless $channels{$channel}; return unless($channel && $channels{$channel} && $channels{$channel}{'UNIQUEID'}); }; /^unlink$/i && do { my $channel = $event{'Channel1'}; return unless $channels{$channel}; $channels{$event{'Channel1'}}{'LINK_END'} = time(); $channels{$event{'Channel2'}}{'LINK_END'} = time(); syslog('info', 'UnLink without uniqueid') unless $channels{$channel}{'UNIQUE'}; syslog('info', 'UnLink without channeld') unless $channel; syslog('info', 'UnLink on undefined channel') unless $channels{$channel}; return unless($channel && $channels{$channel} && $channels{$channel}{'UNIQUEID'}); }; /hangup/i && do { my $channel = $event{'Channel'}; return unless $channels{$channel}; $channels{$event{'Channel'}}{'CALL_END'} = time(); $channels{$event{'Channel'}}{'CAUSE'} = 16; $channels{$event{'Channel'}}{'CAUSE'} $event{'Cause'} if defined $event{'Cause'}; send_acc(%{$channels{$event{'Channel'}}}); delete $channels{$event{'Channel'}}; }; /shutdown/i && do { die 'ast-rad-acc: Asterisk disconnect'; }; /Reload/i && do { load_config(); }; } } sub send_acc { my (%cdr) = @_; my $r = new Authen::Radius(Host => $cdr{'RADIUS_Server'}, Secret => $cdr{'RADIUS_Secret'}); if( !defined $r ) { syslog('crit', "RADIUS host '$cdr{'RADIUS_Server'}' ERROR"); return; } $r->clear_attributes(); $r->add_attributes ( { Name => 'NAS-IP-Address', Value => $cdr{'NAS_IP_Address'} }, { Name => 'NAS-Port-Name', Value => $cdr{'CHANNEL'} }, { Name => 'User-Name', Value => $cdr{'ACCOUNTCODE'} }, { Name => 'Calling-Station-Id', Value => $cdr{'CALLERID'} }, { Name => 'Called-Station-Id', Value => $cdr{'DNID'} }, { Name => 'Acct-Status-Type', Value => 'Stop' }, { Name => 'h323-call-type', Value => $cdr{'CALL_TYPE'} }, { Name => 'h323-call-origin', Value => $cdr{'CALL_ORIGIN'} }, { Name => 'h323-setup-time', Value => format_date($cdr{'CALL_START'}) }, { Name => 'h323-connect-time', Value => format_date($cdr{'LINK_START'}) }, { Name => 'h323-disconnect-time', Value => format_date($cdr{'LINK_END'}) }, { Name => 'h323-disconnect-cause', Value => $cdr{'CAUSE'} }, { Name => 'h323-voice-quality', Value => '0' }, { Name => 'Cisco-AVPair', Value => "session-protocol=$cdr{'CALL_PROTOCOL'}" }, { Name => 'Cisco-AVPair', Value => "call-id=$cdr{'CALL_ID'}" }, { Name => 'Acct-Session-Time', Value => $cdr{'LINK_END'} - $cdr{'LINK_START'} }, ); $r->add_attributes ( { Name => 'h323-remote-address', Value => $cdr{'Remoteip'} } ) if defined $cdr{'Remoteip'}; $r->send_packet (ACCOUNTING_REQUEST) and my $type $r->recv_packet; syslog('crit', "No responce from RADIUS server") if !defined $type; } # # sample '09:16:05 GMT Sat Dec 11 2004' # sub format_date { my ($date) = @_; return strftime "%H:%M:%S GMT %a %b %e %Y", gmtime($date); } # Signal Handlers # sub safe_exit { my($sig) = @_; syslog('crit', "Caught a SIG$sig - shutting down"); $astman->disconnect if $ast_connected; unlink $lock_file or syslog('crit', "Unable to create lockfile $lock_file\n"); closelog(); exit; } sub load_config { my $conf=Config::IniFiles->new(-file => "$config_dir/extensions.conf"); syslog('crit', "Config file error!") if !defined $conf; $rad_serv = $conf->val('globals','RADIUS_Server'); $rad_sec = $conf->val('globals','RADIUS_Secret'); $nas_ip = $conf->val('globals','NAS_IP_Address'); syslog('notice', "extensions.conf loaded"); } __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Possibly Parallel Threads
- Asterisk with PortaOne Radius client- problem in accounting script with OH323
- how to connect to asterisk via perl agi
- Multiple inserts on a through association.
- Guest startup process blocks if a hook's child process is still running (i.e : after forking)
- CTDB_Recovery_Lock