diff options
Diffstat (limited to 'kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm')
-rw-r--r-- | kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm b/kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm new file mode 100644 index 0000000..44807bd --- /dev/null +++ b/kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm @@ -0,0 +1,221 @@ +package Zaptel::Xpp::Mpp; +# +# Written by Oron Peled <oron@actcom.co.il> +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +use Getopt::Std; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } + +use Zaptel::Utils; + +=head1 NAME + +Zaptel::Xpp::Mpp - Perl interface to C<astribank_tool(8)> + +=head1 DESCRIPTION + +This package uses C<astribank_tool(8)> to collect information +about Astribanks via MPP (Management Processor Protocol). + +The binary default location is F</usr/sbin/astribank_tool>. It may be +overridden via module parameter C<astribank_tool=> and the +C<ASTRIBANK_TOOL> environment variable (higher priority). + +It may also be set/unset from code via the set_astribank_tool() method. + +=head1 METHODS + +=head2 mpp_addinfo() + +Called with a list of C<Zaptel::Hardware> objects and augment their +data with C<Zaptel::Xpp::Mpp> objects. + +This method is the normal external interface of this class. + +=head2 new() + +Constructor. Receive as parameter an instance of C<Zaptel::Hardware> class +and return a C<Zaptel::Xpp:Mpp> object. + +Normally, used indirectly via the mpp_addinfo() method. + +=head2 set_astribank_tool() + +Override default location of astribank_tool(8). It is legal +to set it to C<undef>. + +=head2 showinfo() + +Dump an C<Zaptel::Xpp::Mpp> object for debugging. + +=cut + +my $astribank_tool = '/usr/sbin/astribank_tool'; + +sub set_astribank_tool($$) { + my $pack = shift || die; + $pack eq 'Zaptel::Xpp::Mpp' or die "$0: Called from wrong package? ($pack)"; + my $arg = shift; + $astribank_tool = $arg; + #print STDERR "Setting astribank_tool='$astribank_tool'\n"; +} + +sub import { + my ($param) = grep(/^astribank_tool=/, @_); + if(defined $param) { + $param =~ s/^astribank_tool=//; + $astribank_tool = $param; + } + if(defined $ENV{ASTRIBANK_TOOL}) { + $astribank_tool = $ENV{ASTRIBANK_TOOL}; + } +} + +sub showinfo($$) { + my $self = shift || die; + my $prefix = shift || die; + + return unless defined $self; + foreach my $k (sort keys %{$self}) { + my $v = $self->{$k}; + if(ref($v) eq 'ARRAY') { + my @a = @{$v}; + my $i; + my $ki; + for($i = 0; $i < @a; $i++) { + $ki = sprintf "%s[%d]", $k, $i; + printf "$prefix%-20s %s\n", $ki, $a[$i]; + } + } else { + if($k eq 'DEV') { + printf "$prefix%-20s -> %s\n", $k, $v->hardware_name; + } else { + printf "$prefix%-20s %s\n", $k, $v; + } + } + } +} + +sub astribank_tool_cmd($) { + my $dev = shift || die; + my $usb_top; + + # Find USB bus toplevel + $usb_top = '/dev/bus/usb'; + $usb_top = '/proc/bus/usb' unless -d $usb_top; + die "No USB toplevel found\n" unless -d $usb_top; + my $name = $dev->priv_device_name(); + die "$0: Unkown private device name" unless defined $name; + my $path = "$usb_top/$name"; + return ($astribank_tool, '-D', "$path"); +} + +sub new($$$) { + my $pack = shift || die; + my $dev = shift || die; + my $product = $dev->product; + + return undef unless $dev->is_astribank; + return undef unless $dev->bus_type eq 'USB'; + return undef unless $product =~ /116./; + my $mppinfo = { + DEV => $dev, + HAS_MPP => 1, + }; + bless $mppinfo, $pack; + #print STDERR "$astribank_tool($path) -- '$product'\n"; + if(! -x $astribank_tool) { + warn "Could not run '$astribank_tool'\n"; + return $mppinfo; + } + return $mppinfo unless $product =~ /116[12]/; + $mppinfo->{'MPP_TALK'} = 1; + my @cmd = astribank_tool_cmd($dev); + my $name = $dev->priv_device_name(); + my $dbg_file = "$name"; + $dbg_file =~ s/\W/_/g; + #$dbg_file = "/tmp/twinstar-debug-$dbg_file"; + $dbg_file = "/dev/null"; + unless(open(F, "@cmd 2> '$dbg_file' |")) { + warn "Failed running '$astribank_tool': $!"; + return undef; + } + local $/ = "\n"; + local $_; + while(<F>) { + chomp; + #printf STDERR "'%s'\n", $_; + if(s/^INFO:\s*//) { + $mppinfo->{'PROTOCOL'} = $1 if /^protocol\s+version:\s*(\d+)/i; + } elsif(s/^EEPROM:\s*//) { + $mppinfo->{'EEPROM_RELEASE'} = $1 if /^release\s*:\s*([\d\.]+)/i; + $mppinfo->{'EEPROM_LABEL'} = $1 if /^label\s*:\s*([\w._'-]+)/i; + } elsif(s/^Extrainfo:\s+:\s*(.+?)$//) { + $mppinfo->{'EEPROM_EXTRAINFO'} = $1; + } elsif(s/^Capabilities:\s*TwinStar\s*:\s*(.+?)$//) { + my $cap = $1; + $mppinfo->{'TWINSTAR_CAPABLE'} = ($cap =~ /yes/i) ? 1 : 0; + } elsif(s/^TwinStar:\s*//) { + $mppinfo->{'TWINSTAR_PORT'} = $1 if /^connected\s+to\s*:\s*usb-(\d+)/i; + if(s/^USB-(\d+)\s*POWER\s*:\s*//) { + my $v = ($_ eq 'ON') ? 1 : 0; + $mppinfo->{'TWINSTAR_POWER'}->[$1] = $v; + } + if(s/^Watchdog[^:]+:\s*//) { + my $v = ($_ eq 'on-guard') ? 1 : 0; + $mppinfo->{'TWINSTAR_WATCHDOG'} = $v; + } + #printf STDERR "\t%s\n", $_; + } else { + #printf STDERR "\t%s\n", $_; + } + } + unless(close F) { + warn "Failed running '$astribank_tool': $!"; + return undef; + } + #$mppinfo->showinfo; + return $mppinfo; +} + +sub mpp_setwatchdog($$) { + my $mppinfo = shift || die; + my $on = shift; + die "$0: Bad value '$on'" unless defined($on) && $on =~ /^[0-1]$/; + my $dev = $mppinfo->dev || die; + return undef unless defined $mppinfo->mpp_talk; + my $old = $mppinfo->tws_watchdog; + my @cmd = astribank_tool_cmd($dev); + print STDERR "DEBUG($on): '@cmd'\n"; + system(@cmd, '-w', $on); + die "Running $astribank_tool failed: $?" if $?; +} + +sub mpp_jump($) { + my $mppinfo = shift || die; + my $dev = $mppinfo->dev || die; + return undef unless defined $mppinfo->mpp_talk; + my $port = $mppinfo->twinstar_port; + $port = ($port == 1) ? 0 : 1; + die "Unknown TwinStar port" unless defined $port; + my @cmd = astribank_tool_cmd($dev); + system(@cmd, '-p', $port); + die "Running $astribank_tool failed: $?" if $?; +} + +sub mpp_addinfo($@) { + my $pack = shift || die; + my @devlist = @_; + + foreach my $dev (@devlist) { + $dev->{MPPINFO} = $pack->new($dev); + } +} + +1; |