mirror of https://github.com/sipwise/www_csc.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1096 lines
32 KiB
1096 lines
32 KiB
package csc::Controller::device;
|
|
|
|
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
|
|
|
|
=head2 index
|
|
|
|
=cut
|
|
|
|
sub index : Local
|
|
{
|
|
my ( $self, $c, $preferences) = @_;
|
|
|
|
$c->session->{dev} = undef;
|
|
my $ext = $c->session->{user}{data}{cc} .
|
|
$c->session->{user}{data}{ac} . $c->session->{user}{data}{sn};
|
|
|
|
$c->model('Provisioning')->call_prov($c, 'voip', 'get_autoconf_unit',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
ext => $ext}, \$c->session->{dev}{spa});
|
|
|
|
$c->session->{dev}{spa}{active} = 1;
|
|
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
|
|
#print Dumper $c->session->{dev};
|
|
|
|
$self->spa($c);
|
|
}
|
|
|
|
=head2 spa
|
|
|
|
=cut
|
|
|
|
sub spa : Local
|
|
{
|
|
my ( $self, $c, $preferences) = @_;
|
|
|
|
$c->log->debug('***device::spa called');
|
|
$c->stash->{template} = 'tt/device.tt';
|
|
my %messages = ();
|
|
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
|
|
$c->stash->{subscriber}{active_number} = csc::Utils::get_active_number_string($c);
|
|
if($c->session->{user}{extension}) {
|
|
my $ext = $c->session->{user}{preferences}{extension};
|
|
$c->stash->{subscriber}{active_number} =~ s/$ext$/ - $ext/;
|
|
}
|
|
|
|
# set marker, which phone is going to be configured next (-1 = none)
|
|
$c->session->{dev}{currentphone} = -1;
|
|
|
|
# set stash in case we bail out early
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
|
|
$c->session->{dev}{spa}{mac} =~ s/^(..)(..)(..)(..)(..)(..)$/$1:$2:$3:$4:$5:$6/g
|
|
if(defined $c->session->{dev}{spa}{mac});
|
|
if(defined $c->session->{dev}{spa}{children})
|
|
{
|
|
my $pref = $c->session->{dev}{spa}{children};
|
|
foreach my $p(@$pref)
|
|
{
|
|
$p->{mac} =~ s/^(..)(..)(..)(..)(..)(..)$/$1:$2:$3:$4:$5:$6/g
|
|
if(defined $p->{mac});
|
|
}
|
|
}
|
|
|
|
if(defined $c->stash->{subscriber}{autoconf} &&
|
|
$c->stash->{subscriber}{autoconf}{autoconf} == 1 &&
|
|
$c->stash->{subscriber}{autoconf}{device}{model} eq 'SPA9000')
|
|
{
|
|
my $mac = $c->stash->{subscriber}{autoconf}{unit}{mac};
|
|
$mac =~ s/(\d{2})/$1:/g;
|
|
$mac =~ s/:$//g;
|
|
$c->session->{dev}{spa}{mac} = $mac;
|
|
|
|
$c->session->{dev}{spa}{ip} = $c->stash->{subscriber}{autoconf}{unit}{ip};
|
|
}
|
|
|
|
# fetch ip, mac, groups and extensions
|
|
|
|
elsif($c->request->params->{savespa} ||
|
|
$c->request->params->{addgrp} ||
|
|
$c->request->params->{delgrp} ||
|
|
$c->request->params->{addext} ||
|
|
$c->request->params->{delext})
|
|
{
|
|
return unless($self->_check_mac($c, \%messages));
|
|
$c->session->{dev}{spa}{mac} = $c->request->params->{mac};
|
|
$c->log->debug('***device::spa mac='.$c->session->{dev}{spa}{mac});
|
|
|
|
return unless($self->_check_ip($c, \%messages));
|
|
$c->session->{dev}{spa}{ip} = $c->request->params->{ip};
|
|
$c->log->debug('***device::spa ip='.$c->session->{dev}{spa}{ip});
|
|
|
|
return unless $self->_process_fxs1($c);
|
|
return unless $self->_process_fxs2($c);
|
|
|
|
if($c->request->params->{addgrp})
|
|
{
|
|
my $grp = $c->request->params->{group} || '';
|
|
unless($grp =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid group '.$grp);
|
|
return;
|
|
}
|
|
return unless($self->_check_uniqueness($c, $grp, \%messages));
|
|
|
|
if(defined $c->session->{dev}{spa}{groups})
|
|
{
|
|
my $gref = $c->session->{dev}{spa}{groups};
|
|
push @$gref, { ext => int($grp) };
|
|
$c->session->{dev}{spa}{groups} = $gref;
|
|
}
|
|
else
|
|
{
|
|
my @g = ();
|
|
push @g, { ext => int($grp) };
|
|
$c->session->{dev}{spa}{groups} = \@g;
|
|
}
|
|
}
|
|
elsif($c->request->params->{delgrp})
|
|
{
|
|
my $grp = $c->request->params->{delgrp} || '';
|
|
unless($grp =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid deletion group '.$grp);
|
|
}
|
|
else
|
|
{
|
|
$self->_load_phone_subscribers($c);
|
|
|
|
# first delete phones in this group, then group itself
|
|
|
|
if(defined $c->session->{dev}{spa}{fxs1}{group} &&
|
|
$c->session->{dev}{spa}{fxs1}{group} == int($grp))
|
|
{
|
|
$self->_process_fxs1($c, 1);
|
|
}
|
|
if(defined $c->session->{dev}{spa}{fxs2}{group} &&
|
|
$c->session->{dev}{spa}{fxs2}{group} == int($grp))
|
|
{
|
|
$self->_process_fxs2($c, 1);
|
|
}
|
|
|
|
my @tmp1 = ();
|
|
my @tmp1del = ();
|
|
if(defined $c->session->{dev}{spa}{children})
|
|
{
|
|
my $pref = $c->session->{dev}{spa}{children};
|
|
foreach my $p(@$pref)
|
|
{
|
|
unless($p->{group} == int($grp))
|
|
{
|
|
push @tmp1, $p;
|
|
}
|
|
else
|
|
{
|
|
push @tmp1del, $p;
|
|
}
|
|
}
|
|
foreach my $delphone(@tmp1del)
|
|
{
|
|
if(defined $delphone->{subscriber})
|
|
{
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'terminate_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $delphone->{subscriber}{username},
|
|
domain => $delphone->{subscriber}{domain}},
|
|
undef);
|
|
}
|
|
$c->model('Provisioning')->call_prov($c, 'voip', 'delete_autoconf_unit',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
ext => $delphone->{ext}}, undef);
|
|
|
|
}
|
|
|
|
$c->session->{dev}{spa}{children} = \@tmp1;
|
|
}
|
|
|
|
my @tmp2 = ();
|
|
my $gref = $c->session->{dev}{spa}{groups};
|
|
foreach my $g(@$gref)
|
|
{
|
|
unless($g->{ext} == int($grp))
|
|
{
|
|
push @tmp2, $g
|
|
}
|
|
else
|
|
{
|
|
$c->model('Provisioning')->call_prov($c, 'voip', 'delete_autoconf_group',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
group_id => $g->{id}}, undef);
|
|
}
|
|
}
|
|
$c->session->{dev}{spa}{groups} = \@tmp2;
|
|
}
|
|
}
|
|
if($c->request->params->{addext})
|
|
{
|
|
my $ext = $c->request->params->{ext} || '';
|
|
unless($ext =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid ext '.$ext);
|
|
return;
|
|
}
|
|
return unless($self->_check_uniqueness($c, $ext, \%messages));
|
|
my $grp = $c->request->params->{grp} || '';
|
|
if(length($grp) > 0 && ! $grp =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid ext grp '.$grp);
|
|
return;
|
|
}
|
|
|
|
if(defined $c->session->{dev}{spa}{children})
|
|
{
|
|
my $pref = $c->session->{dev}{spa}{children};
|
|
if(length($grp) > 0)
|
|
{
|
|
push @$pref, { ext => int($ext), group => int($grp) };
|
|
}
|
|
else
|
|
{
|
|
push @$pref, { ext => int($ext) };
|
|
}
|
|
$c->session->{dev}{spa}{children} = $pref;
|
|
}
|
|
else
|
|
{
|
|
my @p = ();
|
|
if(length($grp) > 0)
|
|
{
|
|
push @p, { ext => int($ext), group => int($grp) };
|
|
}
|
|
else
|
|
{
|
|
push @p, { ext => int($ext) };
|
|
}
|
|
$c->session->{dev}{spa}{children} = \@p;
|
|
}
|
|
}
|
|
elsif($c->request->params->{delext})
|
|
{
|
|
my $ext = $c->request->params->{delext} || '';
|
|
unless($ext =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid deletion ext '.$ext);
|
|
}
|
|
else
|
|
{
|
|
my @tmp2 = ();
|
|
$self->_load_phone_subscribers($c);
|
|
my $pref = $c->session->{dev}{spa}{children};
|
|
my $delphone;
|
|
foreach my $p(@$pref)
|
|
{
|
|
unless($p->{ext} eq $ext)
|
|
{
|
|
push @tmp2, $p;
|
|
}
|
|
else
|
|
{
|
|
$delphone = $p;
|
|
}
|
|
}
|
|
$c->session->{dev}{spa}{children} = \@tmp2;
|
|
if(defined $delphone->{subscriber})
|
|
{
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'terminate_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $delphone->{subscriber}{username},
|
|
domain => $delphone->{subscriber}{domain}},
|
|
undef);
|
|
}
|
|
$c->model('Provisioning')->call_prov($c, 'voip', 'delete_autoconf_unit',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
ext => $ext}, undef);
|
|
}
|
|
}
|
|
elsif($c->request->params->{savespa})
|
|
{
|
|
my $model = '';
|
|
|
|
unless(defined $c->session->{dev}{spa}{device_id})
|
|
{
|
|
my $dev;
|
|
$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 => 'SPA9000'},
|
|
\$dev);
|
|
$c->session->{dev}{spa}{device_id} = $dev->{id};
|
|
}
|
|
$c->session->{dev}{spa}{ext} = $c->session->{user}{data}{cc} .
|
|
$c->session->{user}{data}{ac} . $c->session->{user}{data}{sn};
|
|
|
|
$c->model('Provisioning')->call_prov($c, 'voip', 'save_autoconf_unit',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
unit => $c->session->{dev}{spa}},
|
|
\$c->session->{dev}{spa});
|
|
|
|
$c->session->{dev}{spa}{mac} =~ s/^(..)(..)(..)(..)(..)(..)$/$1:$2:$3:$4:$5:$6/g;
|
|
if(defined $c->session->{dev}{spa}{children})
|
|
{
|
|
my $pref = $c->session->{dev}{spa}{children};
|
|
foreach my $p(@$pref)
|
|
{
|
|
$p->{parent_id} = $c->session->{dev}{spa}{id};
|
|
}
|
|
}
|
|
|
|
# show synch link and set config window inactive
|
|
$c->session->{dev}{spa}{sync} = 'http://'.$c->session->{dev}{spa}{ip}.
|
|
'/admin/resync?'.$c->config->{cpe_autoconf_url}.'?mac=$MA';
|
|
$c->session->{dev}{spa}{active} = 0;
|
|
|
|
# now, show config of next phone if available
|
|
$self->_load_phone_subscribers($c);
|
|
|
|
if(defined $c->session->{dev}{spa}{children}[0])
|
|
{
|
|
$c->session->{dev}{currentphone} = 0;
|
|
$c->session->{dev}{spa}{children}[$c->session->{dev}{currentphone}]->{active} = 1;
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
$self->phone($c, 1);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
$c->session->{dev}{currentphone} = -1;
|
|
$messages{topmsg} = 'Server.Voip.SavedSettings';
|
|
$c->session->{messages} = \%messages;
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
elsif($c->request->params->{confspa})
|
|
{
|
|
# just active spa config window
|
|
}
|
|
|
|
|
|
# activate config window for spa and deactivate phone config windows
|
|
|
|
$c->session->{dev}{spa}{active} = 1;
|
|
if($c->session->{dev}{spa}{children})
|
|
{
|
|
foreach my $p($c->session->{dev}{spa}{children})
|
|
{
|
|
foreach my $pp(@$p)
|
|
{
|
|
$pp->{active} = 0;
|
|
}
|
|
}
|
|
}
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
|
|
}
|
|
|
|
=head2 phone
|
|
|
|
=cut
|
|
|
|
sub phone : Local
|
|
{
|
|
my ( $self, $c, $internal) = @_;
|
|
$c->log->debug('***device::index called');
|
|
$c->stash->{template} = 'tt/device.tt';
|
|
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
|
|
$c->stash->{subscriber}{active_number} = csc::Utils::get_active_number_string($c);
|
|
if($c->session->{user}{extension}) {
|
|
my $ext = $c->session->{user}{preferences}{extension};
|
|
$c->stash->{subscriber}{active_number} =~ s/$ext$/ - $ext/;
|
|
}
|
|
my $base_cli = $c->session->{user}{data}{cc}.$c->session->{user}{data}{ac}.$c->session->{user}{data}{sn};
|
|
|
|
my $phone = $c->session->{dev}{spa}{children}[int($c->session->{dev}{currentphone})];
|
|
unless(defined $phone->{subscriber})
|
|
{
|
|
$self->_load_phone_subscribers($c);
|
|
}
|
|
|
|
# just render if we come from spa config
|
|
return if($internal);
|
|
|
|
my %messages = ();
|
|
|
|
|
|
if($c->request->params->{confphone})
|
|
{
|
|
my $ext = int($c->request->params->{confphone});
|
|
|
|
my $found = 0;
|
|
my $lastphone = $c->session->{dev}{currentphone};
|
|
for($c->session->{dev}{currentphone} = 0;
|
|
defined($c->session->{dev}{spa}{children}[$c->session->{dev}{currentphone}]);
|
|
$c->session->{dev}{currentphone}++)
|
|
{
|
|
if($c->session->{dev}{spa}{children}[$c->session->{dev}{currentphone}]->{ext} == $ext)
|
|
{
|
|
$found = 1;
|
|
last;
|
|
}
|
|
}
|
|
unless($found == 1)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::phone has invalid update config ext '.$ext);
|
|
$c->session->{dev}{currentphone} = $lastphone;
|
|
}
|
|
else
|
|
{
|
|
foreach my $p($c->session->{dev}{spa}{children})
|
|
{
|
|
foreach my $pp(@$p)
|
|
{
|
|
$pp->{active} = 0;
|
|
}
|
|
}
|
|
if(defined $c->session->{dev}{spa}{children}[$c->session->{dev}{currentphone}])
|
|
{
|
|
$phone = $c->session->{dev}{spa}{children}[int($c->session->{dev}{currentphone})];
|
|
$phone->{active} = 1;
|
|
}
|
|
}
|
|
}
|
|
elsif($c->request->params->{savephone})
|
|
{
|
|
return unless($self->_check_mac($c, \%messages));
|
|
$phone->{mac} = $c->request->params->{mac};
|
|
$c->log->debug('***device::phone mac='.$phone->{mac});
|
|
|
|
return unless($self->_check_ip($c, \%messages));
|
|
$phone->{ip} = $c->request->params->{ip};
|
|
$c->log->debug('***device::phone ip='.$phone->{ip});
|
|
|
|
my $usr = $c->request->params->{usr} || '';
|
|
unless(length $usr)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::phone has invalid config user '.$usr);
|
|
}
|
|
else
|
|
{
|
|
$phone->{usr} = $usr;
|
|
}
|
|
|
|
my $passwd1 = $c->request->params->{pass1};
|
|
my $passwd2 = $c->request->params->{pass2};
|
|
|
|
if(!defined $passwd1 or length $passwd1 == 0) {
|
|
$messages{msgpasswd} = 'Client.Voip.MissingPass';
|
|
} elsif(length $passwd1 < 6) {
|
|
$messages{msgpasswd} = 'Client.Voip.PassLength';
|
|
} elsif(!defined $passwd2) {
|
|
$messages{msgpasswd} = 'Client.Voip.MissingPass2';
|
|
} elsif($passwd1 ne $passwd2) {
|
|
$messages{msgpasswd} = 'Client.Voip.PassNoMatch';
|
|
}
|
|
if(keys %messages)
|
|
{
|
|
$messages{toperr} = "Client.Voip.InputErrorFound";
|
|
$c->session->{messages} = \%messages;
|
|
return;
|
|
}
|
|
$phone->{passwd} = $passwd1;
|
|
|
|
my $ext = $c->request->params->{savephone} || '';
|
|
unless($ext =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::phone has invalid config ext '.$ext);
|
|
return;
|
|
}
|
|
|
|
|
|
my %settings = ();
|
|
my %create_settings = ();
|
|
|
|
$settings{username} = $create_settings{username} = $c->session->{user}{username} . "-" . $ext;
|
|
$settings{domain} = $create_settings{domain} = $c->session->{user}{domain};
|
|
$settings{password} = $create_settings{password} = $passwd1;
|
|
$settings{webusername} = $create_settings{webusername} = $c->session->{user}{username} . "-" . $ext;
|
|
$settings{webpassword} = $create_settings{webpassword} = $passwd1;
|
|
|
|
if(defined $phone->{subscriber})
|
|
{
|
|
unless($c->model('Provisioning')->call_prov($c, 'voip', 'update_subscriber_password',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
password => $settings{password}},
|
|
undef))
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::phone failed to force-update phone subscriber password for ext '.$ext);
|
|
return;
|
|
}
|
|
unless($c->model('Provisioning')->call_prov($c, 'voip', 'update_webuser_password',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
webusername => $settings{webusername},
|
|
webpassword => $settings{webpassword}},
|
|
undef))
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::phone failed to force-update phone webuser password for ext '.$ext);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($c->model('Provisioning')->call_prov($c, 'billing', 'add_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
subscriber => \%create_settings},
|
|
undef))
|
|
{
|
|
unless($c->model('Provisioning')->call_prov($c, 'voip', 'set_subscriber_preferences',
|
|
{ username => $settings{username},
|
|
domain => $settings{domain},
|
|
preferences => { base_cli => $base_cli, extension => $ext}},
|
|
undef))
|
|
{
|
|
if($c->session->{prov_error} eq 'Client.Voip.ExistingAlias') {
|
|
$messages{msgnumber} = 'Client.Voip.AssignedExtension';
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'delete_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $settings{username},
|
|
domain => $settings{domain}},
|
|
undef);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($c->session->{prov_error} eq 'Client.Voip.ExistingSubscriber') {
|
|
$messages{msgsipuri} = $c->session->{prov_error};
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
} elsif($c->session->{prov_error} eq 'Client.Voip.AssignedNumber') {
|
|
$messages{msgnumber} = $c->session->{prov_error};
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
$phone = $c->session->{dev}{spa}{children}[$c->session->{dev}{currentphone}];
|
|
|
|
unless(defined $phone->{device_id})
|
|
{
|
|
my $dev;
|
|
$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};
|
|
}
|
|
|
|
$c->model('Provisioning')->call_prov($c, 'voip', 'save_autoconf_unit',
|
|
{ username => $c->session->{user}{username},
|
|
domain => $c->session->{user}{domain},
|
|
unit => $phone},
|
|
\$phone);
|
|
|
|
$phone->{mac} =~ s/^(..)(..)(..)(..)(..)(..)$/$1:$2:$3:$4:$5:$6/g;
|
|
|
|
$phone->{configured} = 1;
|
|
$phone->{active} = 0;
|
|
$phone->{sync} = 'http://'.$phone->{ip}.
|
|
'/admin/resync?'.$c->config->{cpe_autoconf_url}.'?mac=$MA';
|
|
|
|
$c->session->{dev}{currentphone}++;
|
|
if(defined $c->session->{dev}{spa}{children}[$c->session->{dev}{currentphone}])
|
|
{
|
|
$c->session->{dev}{spa}{children}[$c->session->{dev}{currentphone}]->{active} = 1;
|
|
}
|
|
else
|
|
{
|
|
# we're done with the phones
|
|
$c->session->{dev}{currentphone} = -1;
|
|
$messages{topmsg} = 'Server.Voip.SavedSettings';
|
|
$c->session->{messages} = \%messages;
|
|
}
|
|
}
|
|
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
|
|
}
|
|
|
|
=head2 end
|
|
|
|
=cut
|
|
|
|
sub end : ActionClass('RenderView') {
|
|
my ( $self, $c ) = @_;
|
|
|
|
if(defined $c->stash->{current_view} and
|
|
($c->stash->{current_view} eq 'Binary' || $c->stash->{current_view} eq 'Plain')) {
|
|
return 1;
|
|
}
|
|
|
|
$c->stash->{current_view} = 'TT';
|
|
unless($c->response->{status} =~ /^3/) { # only if not a redirect
|
|
if(exists $c->session->{prov_error}) {
|
|
$c->session->{messages}{prov_error} = $c->session->{prov_error};
|
|
delete $c->session->{prov_error};
|
|
}
|
|
|
|
if(exists $c->session->{messages}) {
|
|
|
|
$c->stash->{messages} = $c->model('Provisioning')->localize($c, $c->session->{messages});
|
|
delete $c->session->{messages};
|
|
}
|
|
}
|
|
|
|
$c->stash->{subscriber}{username} = $c->session->{user}{username};
|
|
|
|
return 1; # shouldn't matter
|
|
}
|
|
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
sub _check_uniqueness_nofxs : Private
|
|
{
|
|
my ($self, $c, $x, $m) = @_;
|
|
|
|
if($x =~ /^9/)
|
|
{
|
|
$m->{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = $m;
|
|
$c->log->debug('***device::_check_uniqueness detected input starting with 9 - not allowed');
|
|
return;
|
|
}
|
|
|
|
foreach my $g($c->session->{dev}{spa}{groups})
|
|
{
|
|
foreach my $gg(@$g)
|
|
{
|
|
if($x eq $gg->{ext})
|
|
{
|
|
$m->{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = $m;
|
|
$c->log->debug('***device::_check_uniqueness detected group with ext '.$x);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
foreach my $g($c->session->{dev}{spa}{children})
|
|
{
|
|
foreach my $gg(@$g)
|
|
{
|
|
if($x eq $gg->{ext})
|
|
{
|
|
$m->{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = $m;
|
|
$c->log->debug('***device::_check_uniqueness detected phone with ext '.$x);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
sub _check_uniqueness : Private
|
|
{
|
|
my ($self, $c, $x, $m) = @_;
|
|
|
|
if($x =~ /^9/)
|
|
{
|
|
$m->{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = $m;
|
|
$c->log->debug('***device::_check_uniqueness detected input starting with 9 - not allowed');
|
|
return;
|
|
}
|
|
|
|
if(defined $c->session->{dev}{spa}{fxs1} &&
|
|
$x eq $c->session->{dev}{spa}{fxs1}{ext})
|
|
{
|
|
$m->{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = $m;
|
|
$c->log->debug('***device::_check_uniqueness detected fxs1 with ext '.$x);
|
|
return;
|
|
}
|
|
if(defined $c->session->{dev}{spa}{fxs2} &&
|
|
$x eq $c->session->{dev}{spa}{fxs2}{ext})
|
|
{
|
|
$m->{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = $m;
|
|
$c->log->debug('***device::_check_uniqueness detected fxs2 with ext '.$x);
|
|
return;
|
|
}
|
|
|
|
return $self->_check_uniqueness_nofxs($c, $x, $m);
|
|
}
|
|
|
|
sub _load_phone_subscribers {
|
|
my $self = shift;
|
|
my $c = shift;
|
|
|
|
if(defined $c->session->{dev}{spa}{children} ||
|
|
defined $c->session->{dev}{spa}{fxs1} ||
|
|
defined $c->session->{dev}{spa}{fxs2})
|
|
{
|
|
$c->model('Provisioning')->get_voip_account_subscribers($c);
|
|
foreach my $subscriber (@{$c->session->{user}{subscribers}})
|
|
{
|
|
my $pref = $c->session->{dev}{spa}{children};
|
|
foreach my $p(@$pref)
|
|
{
|
|
if($$subscriber{preferences}{base_cli} && $$subscriber{preferences}{extension} eq $p->{ext})
|
|
{
|
|
$p->{subscriber} = $subscriber;
|
|
}
|
|
}
|
|
if(defined $c->session->{dev}{spa}{fxs1} &&
|
|
$$subscriber{preferences}{base_cli} &&
|
|
$$subscriber{preferences}{extension} eq $c->session->{dev}{spa}{fxs1}{ext})
|
|
{
|
|
$c->session->{dev}{spa}{fxs1}{subscriber} = $subscriber;
|
|
}
|
|
if(defined $c->session->{dev}{spa}{fxs2} &&
|
|
$$subscriber{preferences}{base_cli} &&
|
|
$$subscriber{preferences}{extension} eq $c->session->{dev}{spa}{fxs2}{ext})
|
|
{
|
|
$c->session->{dev}{spa}{fxs2}{subscriber} = $subscriber;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sub _process_fxs1 {
|
|
my $self = shift;
|
|
my $c = shift;
|
|
my $delext = shift;
|
|
|
|
my %messages = ();
|
|
|
|
my $fxs1ext_old = $c->session->{dev}{spa}{fxs1}{ext} || '';
|
|
|
|
my $fxs1ext;
|
|
if(defined $delext && $delext == 1)
|
|
{
|
|
$fxs1ext = '';
|
|
}
|
|
else
|
|
{
|
|
$fxs1ext = $c->request->params->{spafxs1};
|
|
}
|
|
|
|
if(length($fxs1ext) > 0 && ! $fxs1ext =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid fxs1 ext '.$fxs1ext);
|
|
return;
|
|
}
|
|
my $fxs1grp = $c->request->params->{fxs1grp} || '';
|
|
if(length($fxs1ext) > 0 && length($fxs1grp) > 0 && ! $fxs1grp =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid fxs1 grp '.$fxs1grp);
|
|
return;
|
|
}
|
|
|
|
if(length($fxs1ext) > 0)
|
|
{
|
|
unless($self->_check_uniqueness_nofxs($c, $fxs1ext, \%messages))
|
|
{
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
return;
|
|
}
|
|
|
|
if($fxs1ext_old ne $fxs1ext && defined $c->session->{dev}{spa}{fxs1}{subscriber})
|
|
{
|
|
$c->log->debug('***device::spa terminating old fxs1 subscriber');
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'terminate_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $c->session->{dev}{spa}{fxs1}{subscriber}{username},
|
|
domain => $c->session->{dev}{spa}{fxs1}{subscriber}{domain}},
|
|
undef);
|
|
}
|
|
|
|
if($fxs1ext_old ne $fxs1ext)
|
|
{
|
|
$c->log->debug('***device::spa fxs1 needs subscriber update');
|
|
my %settings = ();
|
|
my %create_settings = ();
|
|
|
|
$settings{username} = $create_settings{username} = $c->session->{user}{data}{username} . "-" . $fxs1ext;
|
|
$settings{domain} = $create_settings{domain} = $c->session->{user}{data}{domain};
|
|
$settings{password} = $create_settings{password} = $c->session->{user}{data}{password};
|
|
$settings{webusername} = $create_settings{webusername} = $c->session->{user}{data}{username} . "-" . $fxs1ext;
|
|
$settings{webpassword} = $create_settings{webpassword} = $c->session->{user}{data}{password};
|
|
my $base_cli = $c->session->{user}{data}{cc}.$c->session->{user}{data}{ac}.$c->session->{user}{data}{sn};
|
|
|
|
if($c->model('Provisioning')->call_prov($c, 'billing', 'add_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
subscriber => \%create_settings},
|
|
undef))
|
|
{
|
|
unless($c->model('Provisioning')->call_prov($c, 'voip', 'set_subscriber_preferences',
|
|
{ username => $settings{username},
|
|
domain => $settings{domain},
|
|
preferences => { base_cli => $base_cli, extension => $fxs1ext}},
|
|
undef))
|
|
{
|
|
if($c->session->{prov_error} eq 'Client.Voip.ExistingAlias')
|
|
{
|
|
$messages{msgnumber} = 'Client.Voip.AssignedExtension';
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'delete_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $settings{username},
|
|
domain => $settings{domain}},
|
|
undef);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($c->session->{prov_error} eq 'Client.Voip.ExistingSubscriber')
|
|
{
|
|
$messages{msgsipuri} = $c->session->{prov_error};
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
elsif($c->session->{prov_error} eq 'Client.Voip.AssignedNumber')
|
|
{
|
|
$messages{msgnumber} = $c->session->{prov_error};
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(length($fxs1grp) > 0)
|
|
{
|
|
$c->session->{dev}{spa}{fxs1} = { ext => int($fxs1ext), group => int($fxs1grp) };
|
|
}
|
|
else
|
|
{
|
|
$c->session->{dev}{spa}{fxs1} = { ext => int($fxs1ext) };
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($fxs1ext_old ne $fxs1ext && defined $c->session->{dev}{spa}{fxs1}{subscriber})
|
|
{
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'terminate_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $c->session->{dev}{spa}{fxs1}{subscriber}{username},
|
|
domain => $c->session->{dev}{spa}{fxs1}{subscriber}{domain}},
|
|
undef);
|
|
}
|
|
$c->session->{dev}{spa}{fxs1} = undef;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
sub _process_fxs2 {
|
|
my $self = shift;
|
|
my $c = shift;
|
|
my $delext = shift;
|
|
|
|
my %messages = ();
|
|
|
|
my $fxs2ext_old = $c->session->{dev}{spa}{fxs2}{ext} || '';
|
|
|
|
my $fxs2ext;
|
|
if(defined $delext && $delext == 1)
|
|
{
|
|
$fxs2ext = '';
|
|
}
|
|
else
|
|
{
|
|
$fxs2ext = $c->request->params->{spafxs2};
|
|
}
|
|
|
|
if(length($fxs2ext) > 0 && ! $fxs2ext =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid fxs2 ext '.$fxs2ext);
|
|
return;
|
|
}
|
|
my $fxs2grp = $c->request->params->{fxs2grp} || '';
|
|
if(length($fxs2ext) > 0 && length($fxs2grp) > 0 && ! $fxs2grp =~ /^\d+$/)
|
|
{
|
|
$messages{toperr} = 'Client.Voip.InputErrorFound';
|
|
$c->session->{messages} = \%messages;
|
|
$c->log->debug('***device::spa has invalid fxs2 grp '.$fxs2grp);
|
|
return;
|
|
}
|
|
|
|
if(length($fxs2ext) > 0)
|
|
{
|
|
unless($self->_check_uniqueness_nofxs($c, $fxs2ext, \%messages))
|
|
{
|
|
$c->stash->{dev} = $c->session->{dev};
|
|
return;
|
|
}
|
|
|
|
if($fxs2ext_old ne $fxs2ext && defined $c->session->{dev}{spa}{fxs2}{subscriber})
|
|
{
|
|
$c->log->debug('***device::spa terminating old fxs2 subscriber');
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'terminate_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $c->session->{dev}{spa}{fxs2}{subscriber}{username},
|
|
domain => $c->session->{dev}{spa}{fxs2}{subscriber}{domain}},
|
|
undef);
|
|
}
|
|
|
|
if($fxs2ext_old ne $fxs2ext)
|
|
{
|
|
$c->log->debug('***device::spa fxs2 needs subscriber update');
|
|
my %settings = ();
|
|
my %create_settings = ();
|
|
|
|
|
|
$settings{username} = $create_settings{username} = $c->session->{user}{data}{username} . "-" . $fxs2ext;
|
|
$settings{domain} = $create_settings{domain} = $c->session->{user}{data}{domain};
|
|
$settings{password} = $create_settings{password} = $c->session->{user}{data}{password};
|
|
$settings{webusername} = $create_settings{webusername} = $c->session->{user}{data}{username} . "-" . $fxs2ext;
|
|
$settings{webpassword} = $create_settings{webpassword} = $c->session->{user}{data}{password};
|
|
my $base_cli = $c->session->{user}{data}{cc}.$c->session->{user}{data}{ac}.$c->session->{user}{data}{sn};
|
|
|
|
if($c->model('Provisioning')->call_prov($c, 'billing', 'add_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
subscriber => \%create_settings},
|
|
undef))
|
|
{
|
|
unless($c->model('Provisioning')->call_prov($c, 'voip', 'set_subscriber_preferences',
|
|
{ username => $settings{username},
|
|
domain => $settings{domain},
|
|
preferences => { base_cli => $base_cli, extension => $fxs2ext}},
|
|
undef))
|
|
{
|
|
if($c->session->{prov_error} eq 'Client.Voip.ExistingAlias')
|
|
{
|
|
$messages{msgnumber} = 'Client.Voip.AssignedExtension';
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'delete_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $settings{username},
|
|
domain => $settings{domain}},
|
|
undef);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($c->session->{prov_error} eq 'Client.Voip.ExistingSubscriber')
|
|
{
|
|
$messages{msgsipuri} = $c->session->{prov_error};
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
elsif($c->session->{prov_error} eq 'Client.Voip.AssignedNumber')
|
|
{
|
|
$messages{msgnumber} = $c->session->{prov_error};
|
|
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(length($fxs2grp) > 0)
|
|
{
|
|
$c->session->{dev}{spa}{fxs2} = { ext => int($fxs2ext), group => int($fxs2grp) };
|
|
}
|
|
else
|
|
{
|
|
$c->session->{dev}{spa}{fxs2} = { ext => int($fxs2ext) };
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($fxs2ext_old ne $fxs2ext && defined $c->session->{dev}{spa}{fxs2}{subscriber})
|
|
{
|
|
$c->model('Provisioning')->call_prov($c, 'billing', 'terminate_voip_account_subscriber',
|
|
{ id => $c->session->{user}{account_id},
|
|
username => $c->session->{dev}{spa}{fxs2}{subscriber}{username},
|
|
domain => $c->session->{dev}{spa}{fxs2}{subscriber}{domain}},
|
|
undef);
|
|
}
|
|
$c->session->{dev}{spa}{fxs2} = undef;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
=head1 BUGS AND LIMITATIONS
|
|
|
|
=over
|
|
|
|
=item functions should be documented
|
|
|
|
=item device configuration should be separated from CSC
|
|
|
|
=back
|
|
|
|
=head1 SEE ALSO
|
|
|
|
Provisioning model, Catalyst
|
|
|
|
=head1 AUTHORS
|
|
|
|
=over
|
|
|
|
=item Andreas Granig <agranig@sipwise.com>
|
|
|
|
=item Daniel Tiefnig <dtiefnig@sipwise.com>
|
|
|
|
=back
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
The device controller is Copyright (c) 2007-2010 Sipwise GmbH, Austria.
|
|
You should have received a copy of the licences terms together with the
|
|
software.
|
|
|
|
=cut
|
|
|
|
1;
|