Device-CableModem-Motorola-SB4200
view release on metacpan or search on metacpan
lib/Device/CableModem/Motorola/SB4200.pm view on Meta::CPAN
my $name = shift || croak 'Config name not present';
my $value = shift;
croak 'Config value not present' if not defined $value;
my $raw = $self->_get( $self->{page_conf} );
my $form = HTML::Form->parse( $raw, $self->{page_conf} );
my $input;
foreach my $e ( @{ $form->inputs } ) {
next if $e->type eq 'submit' || $e->name ne $name;
if ( my @possible = $e->possible_values ) {
my %valid = map { ( (defined $_ ? $_ : 0), 1 ) } @possible;
if ( ! $valid{ $value } ) {
croak "The value ($value) for $name is not valid. "
.'You should select one of these: ' . join q{ }, keys %valid;
}
}
$input = $e;
last;
}
croak "$name is not a valid configuration option" if ! $input;
# good to go
$input->value($value);
my $req = $form->click() || croak "Saving $name=$value failed";
$req->uri( $self->{page_conf} );
my $response = $self->_req( $req );
return;
}
sub addresses {
my $self = shift;
my $raw = $self->_get( $self->{page_addr} );
my(%list, @mac);
my $list = sub {
my ( $id, $line, $cols, $udata ) = @_;
(my $name = lc $cols->[0]) =~ tr/ /_/;
$list{ $name } = $cols->[1];
return;
};
my $mac = sub {
my ( $id, $line, $cols, $udata ) = @_;
my($num, $addr, $status) = @{ $cols };
push @mac, { address => $addr, status => $status };
return;
};
HTML::TableParser->new(
[
{ id => 1.4, row => $list },
{ id => 1.5, row => $mac },
],
{ Decode => 1, Trim => 1, Chomp => 1 },
)->parse( $raw );
my $di = $list{dhcp_information};
$list{dhcp_information} = {};
foreach my $info ( split m{ \r?\n }xmsi, $di ) {
my($name, $value) = split m{ : \s+ }xms, $info;
my($num, $type, $other) = split m{ \s+ }xms, $value;
my $has_type = defined $num && defined $type && ! defined $other;
$list{dhcp_information}->{ $name } = $has_type
? { value => $num, type => $type }
: { value => $value }
;
}
my %rv = (
%list,
known_cpe_mac_addresses => [ @mac ],
);
return %rv;
}
sub signal {
my $self = shift;
my $raw = $self->_get( $self->{page_signal} );
# remove junk info, otherwise it will not be parsed correctly
$raw =~ s{
<table \s+ WIDTH="300" .+? >
.+?
\QThe Downstream Power Level reading is\E
.+?
</table>
}{}xmsi;
my(%down, %up);
my $down_row = sub {
my ( $id, $line, $cols, $udata ) = @_;
(my $name = lc $cols->[0]) =~ tr/ /_/;
$down{ $name } = $cols->[1];
return;
};
my $up_row = sub {
my ( $id, $line, $cols, $udata ) = @_;
(my $name = lc $cols->[0]) =~ tr/ /_/;
$up{ $name } = $cols->[1];
return;
};
HTML::TableParser->new(
[
{ id => 1.4, row => $down_row },
{ id => 1.5, row => $up_row },
],
{ Decode => 1, Trim => 1, Chomp => 1 },
)->parse( $raw );
foreach my $v (
\@up{ qw( frequency power_level symbol_rate ) },
\@down{ qw( frequency power_level signal_to_noise_ratio ) },
) {
my($value, $unit, $status) = split m{\s+}xms, ${$v};
${$v} = {
value => $value,
unit => $unit,
};
${$v}->{status} = $status if defined $status;
}
my %rv = (
upstream => { %up },
downstream => { %down },
);
return %rv;
}
sub status {
my $self = shift;
my $raw = $self->_get( $self->{page_status} );
my %rv;
my $cb_row = sub {
my ( $id, $line, $cols, $udata ) = @_;
(my $name = lc $cols->[0]) =~ tr/ /_/;
$rv{ $name } = $cols->[1];
return;
};
HTML::TableParser->new(
[
{ id => 1.4, row => $cb_row },
{ id => 1 , cols => qr/(?:Task|Status)/xmsi },
],
{ Decode => 1, Trim => 1, Chomp => 1 },
)->parse( $raw );
return %rv;
}
sub logs {
my $self = shift;
my $raw = $self->_get( $self->{page_logs} );
my @logs;
my $cb_row = sub {
my ( $id, $line, $cols, $udata ) = @_;
push @logs, {
time => shift @{ $cols },
priority => shift @{ $cols },
code => shift @{ $cols },
message => shift @{ $cols },
};
my $cur = $logs[-1];
my($pn,$ps) = split m/\-/xms, $cur->{priority};
$cur->{priority} = {
code => $pn,
string => $ps,
};
$cur->{time} = undef if $cur->{time} eq '************';
return;
};
HTML::TableParser->new(
[
{ id => 1.4, row => $cb_row },
{ id => 1 , cols => qr/(?:Time|Priority|Code|Message)/xmsi },
],
{ Decode => 1, Trim => 1, Chomp => 1 },
)->parse( $raw );
return @logs;
}
sub versions {
my $self = shift;
my $raw = $self->_get( $self->{page_help} );
my $v;
if ( $raw =~ m{<td.+?>(.+?version.+?)</td>}xmsi ) {
($v = $1) =~ s{<br>}{}xmsig;
}
else {
croak "Can not get version from $self->{page_help} output: $raw"
};
my %rv;
foreach my $vs ( split m/ \r? \n /xms, $self->_trim( $v ) ) {
my($name, $value) = split m/ : \s+ /xms, $vs;
($name, undef) = split m/ \s+ /xms, $name;
$rv{ lc $name } = $value;
}
my @soft = split m/ \- /xms, $rv{software};
$rv{software} = {
model => shift @soft,
version => shift @soft,
string => join( q{-}, @soft ),
};
return %rv;
}
sub _trim {
my $self = shift;
my $s = shift;
$s =~ s{ \A \s+ }{}xmsg;
$s =~ s{ \s+ \z }{}xmsg;
return $s;
}
sub agent {
my $self = shift;
my $ua = LWP::UserAgent->new;
$ua->agent($AGENT);
$ua->timeout( UA_TIMEOUT );
return $ua;
}
sub _get {
my $self = shift;
my $url = shift;
my $r = $self->agent->get($url);
if ( $r->is_success ) {
my $raw = $r->decoded_content;
HTTP::Error::NotFound->throw(
"The address $url is invalid. Server returned a 404 error"
) if $raw =~ RE_404;
return $raw;
}
return HTTP::Error::Connection->throw(
'GET request failed: ' . $r->as_string
);
}
sub _req {
my $self = shift;
my $req = shift;
my $r = $self->agent->request($req);
if ( $r->is_success ) {
my $raw = $r->decoded_content;
HTTP::Error::NotFound->throw(
'The request is invalid. Server returned a 404 error'
) if $raw =~ RE_404;
return $raw;
}
return HTTP::Error::Connection->throw(
'HTTP::Request failed: ' . $r->as_string
);
}
( run in 0.495 second using v1.01-cache-2.11-cpan-71847e10f99 )