www_csc/lib/csc/Controller/autodevice.pm

504 lines
16 KiB

package csc::Controller::autodevice;
use strict;
use warnings;
use base 'Catalyst::Controller';
use csc::Utils;
use Data::Dumper;
=head1 NAME
csc::Controller::device - Catalyst Controller
=head1 DESCRIPTION
Catalyst Controller.
=head1 METHODS
=cut
=head2 index
=cut
sub index : Local
{
my ( $self, $c, $pref) = @_;
$c->stash->{active_number} = 0 . $c->session->{user}{data}{ac} . " " . $c->session->{user}{data}{sn};
$c->log->debug('***autodevice::index called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/desktop'));
return;
}
my %messages;
$c->stash->{template} = 'tt/autoconf_device.tt';
$c->session->{autoindex} = 0;
my $ext = $c->session->{user}{data}{cc} .
$c->session->{user}{data}{ac} . $c->session->{user}{data}{sn};
# print Dumper $c->session->{user}{subscribers};
# return;
$c->stash->{subscribers} = $self->_load_subscribers($c, \%messages);
}
sub savespa : Local
{
my ( $self, $c, $pref) = @_;
$c->stash->{active_number} = 0 . $c->session->{user}{data}{ac} . " " . $c->session->{user}{data}{sn};
$c->log->debug('***autodevice::savespa called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/desktop'));
return;
}
$c->stash->{template} = 'tt/autoconf_device.tt';
my %messages;
$c->stash->{subscribers} = $self->_load_subscribers($c, \%messages);
my %spa;
return unless($self->_check_mac($c, \%messages));
$spa{mac} = $c->request->params->{mac};
$c->log->debug('***device::spa mac='.$spa{mac});
return unless($self->_check_ip($c, \%messages));
$spa{ip} = $c->request->params->{ip};
$c->log->debug('***device::spa ip='.$spa{ip});
print($c->request->params->{fieldset} . "\n");
my $num1 = $c->request->params->{fieldset} eq "small" ? $c->request->params->{fxs1} : $c->request->params->{fullnum1};
my $num2 = $c->request->params->{fieldset} eq "small" ? $c->request->params->{fxs2} : $c->request->params->{fullnum2};
$spa{fxs1_subscriber_id} = int($num1) if($num1 && $num1 =~ /^\d+$/);
$spa{fxs2_subscriber_id} = int($num2) if($num2 && $num2 =~ /^\d+$/);
if(defined $spa{fxs1_subscriber_id} && defined $spa{fxs2_subscriber_id} &&
$spa{fxs1_subscriber_id} == $spa{fxs2_subscriber_id})
{
$messages{toperr} = 'Client.Voip.InputErrorFound';
$c->session->{messages} = \%messages;
$c->log->debug('***device::savespa has two identical fxs subscriber ids');
return undef;
}
unless(defined $c->request->params->{fmodel} && length($c->request->params->{fmodel}) > 0)
{
$messages{toperr} = 'Client.Voip.InputErrorFound';
$c->session->{messages} = \%messages;
$c->log->debug('***device::savespa has no model');
return undef;
}
my $model = $c->request->params->{fmodel};
my $dev;
return 1 unless
$c->model('Provisioning')->call_prov($c, 'voip', 'get_autoconf_device_by_vendormodel',
{
username => $c->session->{user}{username},
domain => $c->session->{user}{domain},
vendor => 'Linksys', model => $model
},
\$dev);
$spa{device_id} = $dev->{id};
# print Dumper \%spa;
my $unit;
return 1 unless
$c->model('Provisioning')->call_prov($c, 'voip', 'save_autoconf_unit',
{
username => $c->session->{user}{username},
domain => $c->session->{user}{domain},
unit => \%spa
},
\$unit);
if($model eq 'PAP2T-EU')
{
$messages{topmsg} = 'Server.Voip.SavedSettings';
$c->session->{messages} = \%messages;
$c->response->redirect($c->uri_for('/autodevice'));
return;
}
my $editid = 0;
if(defined $c->request->params->{'editphone.x'})
{
if(defined $c->request->params->{editid} && int($c->request->params->{editid}) > 0)
{
$editid = int($c->request->params->{editid});
}
}
my $i = -1;
foreach my $ext (@{@{$c->stash->{subscribers}[0]}{extensions}})
{
$i++;
if($editid > 0)
{
if($ext->{unit}{id} eq $editid)
{
$c->log->debug('***autodevice::savephone using unit mac '.$ext->{unit}{mac}.' for next phone edit config');
$c->stash->{cphone}{ip} = $ext->{unit}{ip};
$c->stash->{cphone}{mac} = $ext->{unit}{mac};
$c->stash->{cphone}{extid} = $ext->{subscriber_id};
last;
}
else
{
next;
}
}
else
{
# TODO: horrible inefficient, start after last index!
next
if($i < $c->session->{autoindex});
if($ext->{unit} && $ext->{subscriber_id} == $ext->{unit}{subscriber_id}) # might be assigned to FXS as well, where we don't care
{
$c->log->debug('***autodevice::savephone using unit mac '.$ext->{unit}{mac}.' for next phone config');
$c->stash->{cphone}{ip} = $ext->{unit}{ip};
$c->stash->{cphone}{mac} = $ext->{unit}{mac};
$c->stash->{cphone}{extid} = $ext->{subscriber_id};
last;
}
}
}
$c->session->{autoindex} = $i+1;
my $free_ext = 0;
foreach my $ext (@{@{$c->stash->{subscribers}[0]}{extensions}})
{
$free_ext++
unless(defined $ext->{unit});
}
my $all_ext = $#{@{$c->stash->{subscribers}[0]}{extensions}};
if(defined $unit->{fsx1_subscriber_id} && int($unit->{fsx1_subscriber_id} > 0))
{
--$free_ext;
--$all_ext;
}
if(defined $unit->{fsx2_subscriber_id} && int($unit->{fsx2_subscriber_id} > 0))
{
--$free_ext;
--$all_ext;
}
if($all_ext < 1)
{
$messages{topmsg} = 'Server.Voip.SavedSettings';
$c->session->{messages} = \%messages;
$c->response->redirect($c->uri_for('/autodevice'));
return;
}
if($free_ext > 1 || $c->session->{autoindex} <= $#{@{$c->stash->{subscribers}[0]}{extensions}})
{
$c->stash->{morephones} = 1;
}
$messages{topmsg} = 'Server.Voip.SavedSettings';
$c->session->{messages} = \%messages;
$c->stash->{subscribers} = $self->_load_subscribers($c, \%messages);
$c->stash->{template} = 'tt/autoconf_phone.tt';
}
sub savephone: Local
{
my ( $self, $c, $pref) = @_;
$c->stash->{active_number} = 0 . $c->session->{user}{data}{ac} . " " . $c->session->{user}{data}{sn};
$c->log->debug('***autodevice::savephone called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/desktop'));
return;
}
$c->stash->{template} = 'tt/autoconf_phone.tt';
my %messages;
$c->stash->{subscribers} = $self->_load_subscribers($c, \%messages);
my %phone;
return unless($self->_check_mac($c, \%messages));
$phone{mac} = $c->request->params->{mac};
$c->log->debug('***device::savephone mac='.$phone{mac});
return unless($self->_check_ip($c, \%messages));
$phone{ip} = $c->request->params->{ip};
$c->log->debug('***device::savephone ip='.$phone{ip});
unless(defined $c->request->params->{fdw} && length($c->request->params->{fdw}) > 0)
{
$messages{toperr} = 'Client.Voip.InputErrorFound';
$c->session->{messages} = \%messages;
$c->log->debug('***device::savephone has no extension username');
return undef;
}
my $usr = $c->request->params->{fdw};
my $dev;
return 1 unless
$c->model('Provisioning')->call_prov($c, 'voip', 'get_autoconf_device_by_vendormodel',
{
username => $c->session->{user}{username},
domain => $c->session->{user}{domain},
vendor => 'Linksys', model => 'SPA922'
},
\$dev);
$phone{device_id} = $dev->{id};
# print Dumper \%spa;
my $unit;
return 1 unless
$c->model('Provisioning')->call_prov($c, 'voip', 'save_autoconf_unit',
{
username => $usr,
domain => $c->session->{user}{domain},
unit => \%phone
},
\$unit);
# print Dumper $unit;
if(defined $c->request->params->{'fdone.x'})
{
$c->response->redirect($c->uri_for('/autodevice'));
return;
}
my $i = -1;
foreach my $ext (@{@{$c->stash->{subscribers}[0]}{extensions}})
{
$i++;
# TODO: horrible inefficient, start after last index!
next
if($i < $c->session->{autoindex});
if($ext->{unit} && $ext->{subscriber_id} == $ext->{unit}{subscriber_id}) # might be assigned to FXS as well, where we don't care
{
$c->log->debug('***autodevice::savephone using unit id '.$ext->{unit}{id}.' for next phone config');
$c->stash->{cphone}{ip} = $ext->{unit}{ip};
$c->stash->{cphone}{mac} = $ext->{unit}{mac};
$c->stash->{cphone}{extid} = $ext->{subscriber_id};
last;
}
}
$c->session->{autoindex} = $i+1;
my $free_ext = 0;
foreach my $ext (@{@{$c->stash->{subscribers}[0]}{extensions}})
{
$free_ext++
unless(defined $ext->{unit});
}
$free_ext--
if(defined $unit->{new} && $unit->{new} eq '1');
my $lastindex = $#{@{$c->stash->{subscribers}[0]}{extensions}};
$c->log->error('***autodevice::savephone free ext='.$free_ext);
$c->log->error('***autodevice::savephone autoindex='.$c->session->{autoindex});
$c->log->error('***autodevice::savephone lastindex=' . $lastindex);
if($free_ext > 1 || $c->session->{autoindex} < $lastindex)
{
$c->log->error('***autodevice::savephone morephones 1');
$c->stash->{morephones} = 1;
}
elsif($free_ext == 1 && defined $c->stash->{cphone})
{
$c->log->error('***autodevice::savephone morephones 2');
$c->stash->{morephones} = 1;
}
$messages{topmsg} = 'Server.Voip.SavedSettings';
$c->session->{messages} = \%messages;
$c->stash->{subscribers} = $self->_load_subscribers($c, \%messages);
$c->stash->{template} = 'tt/autoconf_phone.tt';
}
sub deldev : Local
{
my ( $self, $c, $pref) = @_;
$c->stash->{active_number} = 0 . $c->session->{user}{data}{ac} . " " . $c->session->{user}{data}{sn};
my %messages;
$c->log->debug('***autodevice::deldev called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/desktop'));
return;
}
unless(defined $c->request->params->{duser} && length($c->request->params->{duser}) > 0)
{
$messages{toperr} = 'Server.Internal';
$c->log->error('***autodevice:deldev: no username given');
}
else
{
$c->log->error('***autodevice:deldev: deleting device for user '.$c->request->params->{duser});
$c->model('Provisioning')->call_prov($c, 'voip', 'delete_autoconf_unit',
{
username => $c->request->params->{duser},
domain => $c->session->{user}{domain},
},
undef);
$messages{topmsg} = 'Server.Voip.SavedSettings';
}
$c->session->{messages} = \%messages;
$c->response->redirect($c->uri_for('/autodevice'));
}
sub _check_mac : Private
{
my ($self, $c, $m) = @_;
my $mac = $c->request->params->{mac};
defined($mac) and $mac = lc($mac);
unless(defined($mac) && $mac =~ /^([0-9a-f]{2}:?){5}[0-9a-f]{2}$/)
{
$m->{toperr} = 'Client.Voip.InputErrorFound';
$c->session->{messages} = $m;
$c->log->debug('***device::_check_mac has invalid mac '.$mac);
return undef;
}
return 1;
}
sub _check_ip : Private
{
my ($self, $c, $m) = @_;
my $ip = $c->request->params->{ip};
unless(defined($ip) && $ip =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/)
{
$m->{toperr} = 'Client.Voip.InputErrorFound';
$c->session->{messages} = $m;
$c->log->debug('***device::_check_ip has invalid ip '.$ip);
return undef;
}
return 1;
}
sub _load_subscribers : Private
{
my ($self, $c, $m) = @_;
my @phones = ();
my %subscribers;
$c->session->{user}{subscribers} = undef;
return undef unless $c->model('Provisioning')->get_voip_account_subscribers($c);
foreach my $subscriber (@{$c->session->{user}{subscribers}}) {
if($$subscriber{preferences}{base_cli}) {
return undef unless $c->model('Provisioning')->call_prov($c, 'voip', 'get_autoconf_unit',
{
username => $subscriber->{username},
domain => $c->session->{user}{domain},
check_fxs => 1
},
\$subscriber->{unit});
if(defined $subscriber->{unit} && $subscriber->{unit}{model} eq "SPA922")
{
$subscriber->{unit}{username} = $subscriber->{username};
push @phones, $subscriber->{unit};
}
push @{$subscribers{$$subscriber{preferences}{base_cli}}{extensions}}, $subscriber;
#TODO: fixme, this is terrible inefficient
@{$subscribers{$$subscriber{preferences}{base_cli}}{extensions}} =
sort {$a->{preferences}{extension} cmp $b->{preferences}{extension}}
@{$subscribers{$$subscriber{preferences}{base_cli}}{extensions}};
} elsif($$subscriber{sn}) {
return undef unless $c->model('Provisioning')->call_prov($c, 'voip', 'get_autoconf_unit',
{
username => $subscriber->{username},
domain => $c->session->{user}{domain},
},
\$c->stash->{unit});
if(defined $c->stash->{unit})
{
$c->stash->{unit}{username} = $subscriber->{username};
}
my $tmp_num = $$subscriber{cc}.$$subscriber{ac}.$$subscriber{sn};
$$subscriber{extensions} = $subscribers{$tmp_num}{extensions}
if exists $subscribers{$tmp_num};
$subscribers{$tmp_num} = $subscriber;
} else {
#TODO: subscribers without number?
$c->log->error('***account::subscriber: subscriber without E.164 number found: '.
$$subscriber{username} .'@'. $$subscriber{domain});
return undef;
}
}
if(defined $c->stash->{unit})
{
my $sid1 = $c->stash->{unit}{fxs1_subscriber_id};
my $sid2 = $c->stash->{unit}{fxs2_subscriber_id};
foreach my $sub (values %subscribers)
{
foreach my $ext (@{$sub->{extensions}})
{
if(defined $sid1 && $ext->{subscriber_id} == $sid1)
{
$c->stash->{unit}{fxs1_subscriber_ext} = $ext->{preferences}{extension};
$c->stash->{unit}{fxs1_subscriber_name} = $ext->{autoconf_displayname};
}
elsif(defined $sid2 && $ext->{subscriber_id} == $sid2)
{
$c->stash->{unit}{fxs2_subscriber_ext} = $ext->{preferences}{extension};
$c->stash->{unit}{fxs2_subscriber_name} = $ext->{autoconf_displayname};
}
}
}
}
if(@phones > 0)
{
$c->stash->{phones} = \@phones;
}
return [sort {$a->{username} cmp $b->{username}} values %subscribers];
}
1;