diff options
Diffstat (limited to 'xpp/perl_modules/Dahdi/Xpp/Xpd.pm')
-rw-r--r-- | xpp/perl_modules/Dahdi/Xpp/Xpd.pm | 177 |
1 files changed, 136 insertions, 41 deletions
diff --git a/xpp/perl_modules/Dahdi/Xpp/Xpd.pm b/xpp/perl_modules/Dahdi/Xpp/Xpd.pm index 591c52f..21ce8b6 100644 --- a/xpp/perl_modules/Dahdi/Xpp/Xpd.pm +++ b/xpp/perl_modules/Dahdi/Xpp/Xpd.pm @@ -12,31 +12,81 @@ use Dahdi::Utils; use Dahdi::Xpp; use Dahdi::Xpp::Line; -sub blink($$) { - my $self = shift; - my $on = shift; - my $result; - my $file = Dahdi::Xpp::xpd_attr_path( +sub xpd_attr_path($@) { + my $self = shift || die; + my ($busnum, $unitnum, $subunitnum, @attr) = ( $self->xbus->num, $self->unit, - $self->subunit, "blink"); - die "$file is missing" unless -f $file; - # First query - open(F, "$file") or die "Failed to open $file for reading: $!"; - $result = <F>; - chomp $result; + $self->subunit, + @_); + foreach my $attr (@attr) { + my $file = sprintf "$Dahdi::Xpp::sysfs_xpds/%02d:%1d:%1d/$attr", + $busnum, $unitnum, $subunitnum; + unless(-f $file) { + my $procfile = sprintf "/proc/xpp/XBUS-%02d/XPD-%1d%1d/$attr", + $busnum, $unitnum, $subunitnum; + warn "$0: OLD DRIVER: missing '$file'. Fall back to /proc\n"; + $file = $procfile; + } + next unless -f $file; + return $file; + } + return undef; +} + +# Backward compat plug for old /proc interface... +sub xpd_old_gettype($) { + my $xpd = shift || die; + my $summary = "/proc/xpp/" . $xpd->fqn . "/summary"; + open(F, $summary) or die "Failed to open '$summary': $!"; + my $head = <F>; close F; - if(defined($on) and $on ne $result) { # Now change - open(F, ">$file") or die "Failed to open $file for writing: $!"; - print F ($on)?"0xFFFF":"0"; - if(!close(F)) { - if($! == 17) { # EEXISTS - # good - } else { - undef $result; - } + chomp $head; + $head =~ s/^XPD-\d+\s+\(//; + $head =~ s/,.*//; + return $head; +} + +sub xpd_getattr($$) { + my $xpd = shift || die; + my $attr = shift || die; + $attr = lc($attr); + my $file = xpd_attr_path($xpd, lc($attr)); + + return xpd_old_gettype($xpd) if $attr eq 'type' and !defined $file; + open(F, $file) || return undef; + my $val = <F>; + close F; + chomp $val; + return $val; +} + +sub xpd_setattr($$$) { + my $xpd = shift || die; + my $attr = shift || die; + my $val = shift; + $attr = lc($attr); + my $file = xpd_attr_path($xpd, $attr); + my $oldval = $xpd->xpd_getattr($attr); + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F "$val"; + if(!close(F)) { + if($! == 17) { # EEXISTS + # good + } else { + return undef; } } + return $oldval; +} + +sub blink($$) { + my $self = shift; + my $on = shift; + my $result = $self->xpd_getattr("blink"); + if(defined($on)) { # Now change + $self->xpd_setattr("blink", ($on)?"0xFFFF":"0"); + } return $result; } @@ -44,10 +94,7 @@ sub dahdi_registration($$) { my $self = shift; my $on = shift; my $result; - my $file = Dahdi::Xpp::xpd_attr_path( - $self->xbus->num, - $self->unit, - $self->subunit, "span", "dahdi_registration"); + my $file = $self->xpd_attr_path("span", "dahdi_registration"); die "$file is missing" unless -f $file; # First query open(F, "$file") or die "Failed to open $file for reading: $!"; @@ -79,14 +126,22 @@ sub xpds_by_spanno() { return @idx; } -sub new($$) { +sub new($$$$$) { my $pack = shift or die "Wasn't called as a class method\n"; my $xbus = shift || die; + my $unit = shift; # May be zero + my $subunit = shift; # May be zero my $procdir = shift || die; - my $self = {}; + my $sysfsdir = shift || die; + my $self = { + XBUS => $xbus, + ID => "$unit$subunit", + UNIT => $unit, + SUBUNIT => $subunit, + DIR => $procdir, + SYSFS_DIR => $sysfsdir, + }; bless $self, $pack; - $self->{XBUS} = $xbus; - $self->{DIR} = $procdir; local $/ = "\n"; open(F, "$procdir/summary") || die "Missing summary file in $procdir"; my $head = <F>; @@ -103,19 +158,10 @@ sub new($$) { } } close F; - $head =~ s/^(XPD-(\d)(\d))\s+// || die; - $self->{ID} = "$2$3"; - $self->{UNIT} = "$2"; - $self->{SUBUNIT} = "$3"; - $self->{FQN} = $xbus->name . "/" . $1; - $head =~ s/^.*\(// || die; - $head =~ s/\) */, / || die; - $head =~ s/\s*,\s*/,/g || die; - my ($type,$present,$span,$rest) = split(/,/, $head); - #warn "Garbage in '$procdir/summary': rest='$rest'\n" if $rest; - if($span =~ s/span\s+(\d+)//) { # since changeset:5119 - $self->{SPANNO} = $1; - } + $self->{FQN} = $xbus->name . "/" . "XPD-$unit$subunit"; + my $type = $self->xpd_getattr('type'); + my $span = $self->xpd_getattr('span'); + $self->{SPANNO} = $span; $self->{TYPE} = $type; $self->{IS_BRI} = ($type =~ /BRI_(NT|TE)/); $self->{IS_PRI} = ($type =~ /[ETJ]1/); @@ -124,4 +170,53 @@ sub new($$) { return $self; } +#------------------------------------ +# static xpd related helper functions +#------------------------------------ + +sub sync_priority_rank($) { + my $xpd = shift || die; + # The @rank array is ordered by priority of sync (good to bad) + my @rank = ( + ($xpd->is_pri and defined($xpd->termtype) and $xpd->termtype eq 'TE'), + ($xpd->is_bri and defined($xpd->termtype) and $xpd->termtype eq 'TE'), + ($xpd->is_pri), + ($xpd->type eq 'FXO'), + ($xpd->is_bri), + ($xpd->type eq 'FXS'), + ); + for(my $i = 0; $i < @rank; $i++) { + return $i if $rank[$i]; + } + return @rank + 1; +} + +# An XPD sync priority comparator for sort() +sub sync_priority_compare() { + my $rank_a = sync_priority_rank($a); + my $rank_b = sync_priority_rank($b); + #print STDERR "DEBUG: $rank_a (", $a->fqn, ") $rank_b (", $b->fqn, ")\n"; + return $a->fqn cmp $b->fqn if $rank_a == $rank_b; + return $rank_a <=> $rank_b; +} + +# For debugging: show a list of XPD's with relevant sync info. +sub show_xpd_rank(@) { + print STDERR "XPD's by rank\n"; + foreach my $xpd (@_) { + my $type = $xpd->type; + my $rank = sync_priority_rank($xpd); + if($xpd->is_digital) { + $type .= " (TERMTYPE " . ($xpd->termtype || "UNKNOWN") . ")"; + } + printf STDERR "%3d %-15s %s\n", $rank, $xpd->fqn, $type; + } +} + +sub xpds_by_rank(@) { + my @xpd_prio = sort sync_priority_compare @_; + #show_xpd_rank(@xpd_prio); + return @xpd_prio; +} + 1; |