summaryrefslogtreecommitdiff
path: root/xpp/perl_modules/Dahdi/Xpp/Xpd.pm
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/perl_modules/Dahdi/Xpp/Xpd.pm')
-rw-r--r--xpp/perl_modules/Dahdi/Xpp/Xpd.pm177
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;