unlink$/i && do {
return unless $channels{$event{'Channel1'}};
return unless $channels{$event{'Channel2'}};
if(ref($channels{$event{'Channel1'}}) =~ /HASH.*/){
$channels{$event{'Channel1'}}{'LINK_END'} = time();
} else {
syslog('debug',"Unlink: no hash entry for $event{'Channel1'}");
}
if(ref($channels{$event{'Channel2'}}) =~ /HASH.*/){
$channels{$event{'Channel2'}}{'LINK_END'} = time();
} else {
syslog('debug',"Unlink: no hash entry for $event{'Channel2'}");
}
};
/userevent/i && $event{'UserEvent'} =~ /_sip_auth/i && do {
$channels{$event{'Channel'}}{'User-Name'} = $event{'User-Name'} if defined $event{'User-Name'};
$channels{$event{'Channel'}}{'DNID'} = $event{'DNID'} if defined $event{'DNID'};
$channels{$event{'Channel'}}{'Last_Update'} = time();
send_acc('Start', %{$channels{$event{'Channel'}}}) if defined $channels{$event{'Channel'}}{'DNID'};
};
/hangup/i && do {
if (defined $channels{$event{'Channel'}}{'DSTCHANNEL'} &&
defined $channels{$event{'Channel'}}{'Last_Update'} &&
(ref($channels{$channels{$event{'Channel'}}{'DSTCHANNEL'}}) =~ /HASH.*/)){
if($channels{$event{'Channel'}}{'DSTCHANNEL'} ne $event{'Channel'}){
my $chname = $channels{$event{'Channel'}}{'DSTCHANNEL'};
my %tmpchan = %{$channels{$chname}};
delete $channels{$chname};
$channels{$event{'Channel'}}{'DSTCHANNEL'} = $channels{$chname}{'DSTCHANNEL'} if defined $channels{$chname}{'DSTCHANNEL'};
NaV{$channels{$event{'Channel'}}};
delete $channels{$event{'Channel'}};
NaVtmpchan;
undef %tmpchan;
undef $chname;
}
}
my $channel = $event{'Channel'};
return unless $channels{$channel};
return unless $channels{$channel}{'RADIUS_Server'};
$channels{$channel}{'CALL_END'} = time();
if (defined $channels{$channel}{'LINK_START'}){
$channels{$channel}{'LINK_END'} = time() unless defined $channels{$channel}{'LINK_END'};
}else{
$channels{$channel}{'LINK_START'} = 0;
$channels{$channel}{'LINK_END'} = 0;
}
$channels{$channel}{'CAUSE'} = 16;
$channels{$channel}{'CAUSE'} = $event{'Cause'} if defined $event{'Cause'};
send_acc('Stop', %{$channels{$channel}}) if defined $channels{$channel}{'Last_Update'};
delete $channels{$channel};
};
/rename/i && do {
if(defined $event{'Newname'} && defined $event{'Oldname'})
{
delete $channels{$event{'Newname'}} if defined $channels{$event{'Newname'}};
if (defined $channels{$event{'Oldname'}}){
%{$channels{$event{'Newname'}}} = %{$channels{$event{'Oldname'}}} if ref($channels{$event{'Oldname'}}) =~ /HASH.*/;
delete $channels{$event{'Oldname'}};
}
}
};
/shutdown/i && do {
die 'ast-rad-acc: Asterisk disconnect';
};
/Reload/i && do {
load_config();
};
}
}
sub send_update {
my $curtime = time();
foreach (keys %channels) {
next unless (ref($channels{$_}) =~ /HASH.*/)&&(defined $channels{$_}{'Last_Update'});
if (($curtime-$channels{$_}{'Last_Update'})>=$update_timeout)
{
$channels{$_}{'Last_Update'} = $curtime;
send_acc('Update',%{$channels{$_}});
}
}
alarm 5;
}
sub send_acc {
my ($acc_type,%cdr) = @_;
my $r = new Authen::Radius(Host => $cdr{'RADIUS_Server'}."\:".$cdr{'RADIUS_Acct_Port'}, Secret => $cdr{'RADIUS_Secret'});
- syslog('notice', $cdr{'RADIUS_Server'}."\:".$cdr{'RADIUS_Acct_Port'}." ".$cdr{'RADIUS_Secret'});
if( !defined $r ) {
syslog('crit', "RADIUS host '$cdr{'RADIUS_Server'}' ERROR");
return;
}
$r->clear_attributes();
my $confid = uc(md5_hex($cdr{'CHANNEL'}));
$confid =~ s/(\w{8})(\w{8})(\w{8})(\w{8})/$1 $2 $3 $4/;
if ($acc_type eq 'Start')
{
$r->add_attributes ({ Name => 'Acct-Status-Type', Value => 'Start' },
{ Name => 'h323-setup-time', Value => format_date($cdr{'CALL_START'}) },
{ Name => 'h323-call-type', Value => $cdr{'CALL_TYPE'} },
{ Name => 'h323-call-origin', Value => $cdr{'CALL_ORIGIN'} },
{ 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-Id', Value => $cdr{'CHANNEL'} }
);
$r->add_attributes ( { Name => 'h323-remote-address', Value => $cdr{'Remoteip'} } ) if defined $cdr{'Remoteip'};
$r->add_attributes ( { Name => 'h323-gw-id', Value => $cdr{'DSTCHANNEL'} } ) if defined $cdr{'DSTCHANNEL'};
syslog('err', "Start sent for $cdr{'CHANNEL'}.");
} else {
if ($acc_type eq 'Stop')
{
$r->add_attributes (
{ Name => 'Acct-Status-Type', Value => 'Stop' },
{ 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 => 'Acct-Session-Time', Value => $cdr{'LINK_END'} - $cdr{'LINK_START'} },
{ Name => 'Cisco-AVPair', Value => "session-protocol=$cdr{'CALL_PROTOCOL'}" },
{ Name => 'Cisco-AVPair', Value => "call-id=$cdr{'CALL_ID'}" },
{ Name => 'Acct-Session-Id', Value => $cdr{'CHANNEL'} }
);
$r->add_attributes ( { Name => 'h323-remote-address', Value => $cdr{'Remoteip'} } ) if defined $cdr{'Remoteip'};
$r->add_attributes ( { Name => 'h323-gw-id', Value => $cdr{'DSTCHANNEL'} } ) if defined $cdr{'DSTCHANNEL'};
syslog('err', "Stop sent for $cdr{'CHANNEL'}.");
} else {
if ($acc_type eq 'Update')
{
$r->add_attributes ({ Name => 'Acct-Status-Type', Value => 'Alive' });
$r->add_attributes ({ Name => 'Acct-Session-Id', Value => $cdr{'CHANNEL'} });
syslog('err', "Update sent for $cdr{'CHANNEL'}.");
} else {
syslog('err', "Bad ACC_STATUS_TYPE specified");
return;
}}}
$r->add_attributes (
{ Name => 'NAS-IP-Address', Value => $cdr{'NAS_IP_Address'} },
{ Name => 'NAS-Port-Name', Value => $cdr{'CHANNEL'} },
{ Name => 'User-Name', Value => $cdr{'User-Name'} },
{ Name => 'Calling-Station-Id', Value => $cdr{'CALLERID'} },
{ Name => 'Called-Station-Id', Value => $cdr{'DNID'} },
{ Name => 'h323-conf-id', Value => $confid }
);
$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) = @_;
my $old_locale = setlocale(LC_TIME);
setlocale(LC_TIME, 'POSIX');
my $str_date = strftime "%H:%M:%S.000 UTC %a %b %e %Y", gmtime($date);
setlocale(LC_TIME, $old_locale);
return $str_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 $glob = 0;
my $conf;
open($conf, "<$config_dir/extensions.conf") || die "Can't open config file: $!\n";
while (<$conf>)
{
next if ($_ =~ /
\s*;.*/);