summaryrefslogtreecommitdiff
path: root/xpp/utils/zconf/Zaptel
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-10 18:12:27 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-10 18:12:27 +0000
commit9899bafe997a4e020f302c99a6e025b4e8b25191 (patch)
tree8a108b05d0f319c95ba83f1d5984ae261572bebf /xpp/utils/zconf/Zaptel
parent1d7d5b07325a186785b22abf09ff531dfc2edd54 (diff)
xpp.r5254:
* Improved polarity reversal hangups in FXO (r5194). Fixed false detection of polarity reversals. * Optimize xframe allocation, by not zeroing the whole memory (in get_xframe()). * Fixed erronous error message that appeared sometimes from fpga_load during USB renumeration. * Zaptel::Chans now provides battery() reporting for some FXO channels (Astribank FXO and wcfxo). git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3643 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/utils/zconf/Zaptel')
-rw-r--r--xpp/utils/zconf/Zaptel/Chans.pm102
-rw-r--r--xpp/utils/zconf/Zaptel/Config/Defaults.pm25
-rw-r--r--xpp/utils/zconf/Zaptel/Hardware/PCI.pm17
-rw-r--r--xpp/utils/zconf/Zaptel/Span.pm17
-rw-r--r--xpp/utils/zconf/Zaptel/Xpp/Line.pm59
-rw-r--r--xpp/utils/zconf/Zaptel/Xpp/Xpd.pm43
6 files changed, 230 insertions, 33 deletions
diff --git a/xpp/utils/zconf/Zaptel/Chans.pm b/xpp/utils/zconf/Zaptel/Chans.pm
index 16ab1d5..b02bf24 100644
--- a/xpp/utils/zconf/Zaptel/Chans.pm
+++ b/xpp/utils/zconf/Zaptel/Chans.pm
@@ -10,31 +10,86 @@ package Zaptel::Chans;
use strict;
use Zaptel::Utils;
+=head1 NAME
+
+Zaptel::Chans - Perl interface to a Zaptel channel information
+
+This package allows access from perl to information about a Zaptel
+channel. It is part of the Zaptel Perl package.
+
+=head1 battery()
+
+Returns 1 if channel reports to have battery (A remote PBX connected to
+an FXO port), 0 if channel reports to not have battery and C<undef>
+otherwise.
+
+Currently only wcfxo and Astribank FXO modules report battery. For the
+rest of the channels
+
+=head1 fqn()
+
+(Fully Qualified Name) Returns the full "name" of the channel.
+
+=head1 index()
+
+Returns the number of this channel (in the span).
+
+=head1 num()
+
+Returns the number of this channel as a Zaptel channel.
+
+=head signalling()
+
+Returns the signalling set for this channel through /etc/zaptel.conf .
+This is always empty before ztcfg was run. And shows the "other" type
+for FXS and for FXO.
+
+=head1 span()
+
+Returns a reference to the span to which this channel belongs.
+
+=head1 type()
+
+Returns the type of the channel: 'FXS', 'FXO', 'EMPTY', etc.
+
+=cut
+
sub new($$$$$$) {
my $pack = shift or die "Wasn't called as a class method\n";
my $span = shift or die "Missing a span parameter\n";
+ my $index = shift;
my $line = shift or die "Missing an input line\n";
+ defined $index or die "Missing an index parameter\n";
+ my $self = {
+ 'SPAN' => $span,
+ 'INDEX' => $index,
+ };
+ bless $self, $pack;
my ($num, $fqn, $rest) = split(/\s+/, $line, 3);
$num or die "Missing a channel number parameter\n";
$fqn or die "Missing a channel fqn parameter\n";
my $signalling = '';
- if(defined $rest && ($rest =~ s/(\w+)//)) {
- $signalling = $1;
- }
my $info = '';
- if(defined $rest && ($rest =~ s/(.*)//)) {
- $info = $1;
+ if(defined $rest) {
+ if($rest =~ s/^\s*(\w+)\s*//) {
+ $signalling = $1;
+ }
+ if($rest =~ s/(.*)//) {
+ $info = $1;
+ }
}
- my $self = {};
- bless $self, $pack;
- $self->{SPAN} = $span;
$self->{NUM} = $num;
$self->{FQN} = $fqn;
$self->{SIGNALLING} = $signalling;
$self->{INFO} = $info;
my $type;
if($fqn =~ m|\bXPP_(\w+)/.*$|) {
- $type = $1; # One of our AB
+ $type = $1; # An Astribank
+ } elsif ($fqn =~ m{\bWCFXO/.*}) {
+ $type = "FXO"; # wcfxo - x100p and relatives.
+ # A single port card. The driver issue RED alarm when
+ # There's no better
+ $self->{BATTERY} = !($span->description =~ /\bRED\b/);
} elsif ($fqn =~ m{\bFXS/.*}) {
$type = "FXS"; # likely Rhino
} elsif ($fqn =~ m{\bFXO/.*}) {
@@ -69,6 +124,18 @@ sub new($$$$$$) {
return $self;
}
+=head1 probe_type()
+
+In the case of some cards, the information in /proc/zaptel is not good
+enough to tell the type of each channel. In this case an extra explicit
+probe is needed.
+
+Currently this is implemented by using some invocations of ztcfg(8).
+
+It may later be replaced by ztscan(8).
+
+=cut
+
my $ztcfg = $ENV{ZTCFG} || '/sbin/ztcfg';
sub probe_type($) {
my $self = shift;
@@ -100,4 +167,21 @@ sub probe_type($) {
return $type;
}
+sub battery($) {
+ my $self = shift or die;
+ my $span = $self->span or die;
+
+ return undef unless $self->type eq 'FXO';
+ return $self->{BATTERY} if defined $self->{BATTERY};
+
+ my $xpd = $span->xpd;
+ my $index = $self->index;
+ return undef if !$xpd;
+
+ # It's an XPD (FXO)
+ my @lines = @{$xpd->lines};
+ my $line = $lines[$index];
+ return $line->battery;
+}
+
1;
diff --git a/xpp/utils/zconf/Zaptel/Config/Defaults.pm b/xpp/utils/zconf/Zaptel/Config/Defaults.pm
index 05f4db3..1d11403 100644
--- a/xpp/utils/zconf/Zaptel/Config/Defaults.pm
+++ b/xpp/utils/zconf/Zaptel/Config/Defaults.pm
@@ -26,4 +26,29 @@ sub do_source($@) {
return %vars;
}
+sub source_vars {
+ my @vars = @_;
+ my $default_file;
+ my %system_files = (
+ "/etc/default/zaptel" => 'Debian and friends',
+ "/etc/sysconfig/zaptel" => 'Red Hat and friends',
+ );
+
+ if(defined $ENV{ZAPTEL_DEFAULTS}) {
+ $default_file = $ENV{ZAPTEL_DEFAULTS};
+ } else {
+ foreach my $f (keys %system_files) {
+ if(-r $f) {
+ if(defined $default_file) {
+ die "An '$f' collides with '$default_file'";
+ }
+ $default_file = $f;
+ }
+ }
+ }
+ die "No default_file" unless $default_file;
+ my %vars = Zaptel::Config::Defaults::do_source($default_file, @vars);
+ return ($default_file, %vars);
+}
+
1;
diff --git a/xpp/utils/zconf/Zaptel/Hardware/PCI.pm b/xpp/utils/zconf/Zaptel/Hardware/PCI.pm
index b1a6b67..45173d4 100644
--- a/xpp/utils/zconf/Zaptel/Hardware/PCI.pm
+++ b/xpp/utils/zconf/Zaptel/Hardware/PCI.pm
@@ -91,7 +91,9 @@ my %pci_ids = (
'1397:08b4/b556' => { DRIVER => 'qozap', DESCRIPTION => 'Junghanns DuoBRI ISDN card' },
'1397:08b4' => { DRIVER => 'qozap', DESCRIPTION => 'Junghanns QuadBRI ISDN card' },
'1397:16b8' => { DRIVER => 'qozap', DESCRIPTION => 'Junghanns OctoBRI ISDN card' },
+ '1397:30b1' => { DRIVER => 'cwain', DESCRIPTION => 'HFC-E1 ISDN E1 card' },
'1397:2bd0' => { DRIVER => 'zaphfc', DESCRIPTION => 'HFC-S ISDN BRI card' },
+ '1397:f001' => { DRIVER => 'ztgsm', DESCRIPTION => 'HFC-GSM Cologne Chips GSM' },
# Rhino cards (based on pci.ids)
'0b0b:0105' => { DRIVER => 'r1t1', DESCRIPTION => 'Rhino R1T1' },
@@ -159,8 +161,19 @@ sub scan_devices($) {
}
while(</sys/bus/pci/drivers/*/[0-9]*>) {
- m,([^/]+)/([^/]+)$,,;
- $pci_devs{$2}{LOADED} = $1;
+ m,^(.*?)/([^/]+)/([^/]+)$,;
+ my $prefix = $1;
+ my $drvname = $2;
+ my $id = $3;
+ my $l = readlink "$prefix/$drvname/module";
+ # Find the real module name (if we can).
+ if(defined $l) {
+ my $moduledir = "$prefix/$drvname/$l";
+ my $modname = $moduledir;
+ $modname =~ s:^.*/::;
+ $drvname = $modname;
+ }
+ $pci_devs{$id}{LOADED} = $drvname;
}
foreach (sort keys %pci_devs) {
my $dev = $pci_devs{$_};
diff --git a/xpp/utils/zconf/Zaptel/Span.pm b/xpp/utils/zconf/Zaptel/Span.pm
index f8e5f01..380dc7f 100644
--- a/xpp/utils/zconf/Zaptel/Span.pm
+++ b/xpp/utils/zconf/Zaptel/Span.pm
@@ -10,6 +10,7 @@ package Zaptel::Span;
use strict;
use Zaptel::Utils;
use Zaptel::Chans;
+use Zaptel::Xpp::Xpd;
my $proc_base = "/proc/zaptel";
@@ -50,6 +51,12 @@ sub new($$) {
my $self = { NUM => $num };
bless $self, $pack;
$self->{TYPE} = "UNKNOWN";
+ my @xpds = Zaptel::Xpp::Xpd::xpds_by_spanno;
+ my $xpd = $xpds[$num];
+ if(defined $xpd) {
+ die "Spanno mismatch: $xpd->spanno, $num" unless $xpd->spanno == $num;
+ $self->{XPD} = $xpd;
+ }
open(F, "$proc_base/$num") or die "Failed to open '$proc_base/$num\n";
my $head = <F>;
chomp $head;
@@ -92,16 +99,20 @@ sub new($$) {
$self->{IS_ZAPTEL_SYNC_MASTER} =
($self->{DESCRIPTION} =~ /\(MASTER\)/) ? 1 : 0;
$self->{CHANS} = [];
+ my @channels;
+ my $index = 0;
while(<F>) {
chomp;
s/^\s*//;
s/\s*$//;
next unless /\S/;
- my $c = Zaptel::Chans->new($self, $_);
- push(@{$self->{CHANS}}, $c);
+ my $c = Zaptel::Chans->new($self, $index, $_);
+ push(@channels, $c);
+ $index++;
}
close F;
-
+ @channels = sort { $a->num <=> $b->num } @channels;
+ $self->{CHANS} = \@channels;
$self->{YELLOW} = undef;
$self->{CRC4} = undef;
if($self->is_bri()) {
diff --git a/xpp/utils/zconf/Zaptel/Xpp/Line.pm b/xpp/utils/zconf/Zaptel/Xpp/Line.pm
new file mode 100644
index 0000000..e3e04f0
--- /dev/null
+++ b/xpp/utils/zconf/Zaptel/Xpp/Line.pm
@@ -0,0 +1,59 @@
+package Zaptel::Xpp::Line;
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2008, Xorcom
+# This program is free software; you can redistribute and/or
+# modify it under the same terms as Perl itself.
+#
+# $Id$
+#
+use strict;
+use Zaptel::Utils;
+
+my $proc_base = "/proc/xpp";
+
+sub new($$$) {
+ my $pack = shift or die "Wasn't called as a class method\n";
+ my $xpd = shift or die;
+ my $index = shift;
+ defined $index or die;
+ my $self = {};
+ bless $self, ref($xpd);
+ $self->{XPD} = $xpd;
+ $self->{INDEX} = $index;
+ return $self;
+}
+
+sub create_all($$) {
+ my $pack = shift or die "Wasn't called as a class method\n";
+ my $xpd = shift || die;
+ my $procdir = shift || die;
+ local $/ = "\n";
+ my @lines;
+ for(my $i = 0; $i < $xpd->{CHANNELS}; $i++) {
+ my $line = Zaptel::Xpp::Line->new($xpd, $i);
+ push(@lines, $line);
+ }
+ $xpd->{LINES} = \@lines;
+ my ($infofile) = glob "$procdir/*_info";
+ die "Failed globbing '$procdir/*_info'" unless defined $infofile;
+ my $type = $xpd->type;
+ open(F, "$infofile") || die "Failed opening '$infofile': $!";
+ while (<F>) {
+ chomp;
+ if($type eq 'FXO') {
+ if(s/^\s*battery\s*:\s*//) {
+ my @batt = split;
+ foreach my $l (@lines) {
+ die unless @batt;
+ $l->{BATTERY} = shift @batt;
+ }
+ die if @batt;
+ }
+ }
+ }
+ close F;
+}
+
+
+1;
diff --git a/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm b/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm
index c05cfdb..326aafd 100644
--- a/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm
+++ b/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm
@@ -9,6 +9,8 @@ package Zaptel::Xpp::Xpd;
#
use strict;
use Zaptel::Utils;
+use Zaptel::Xpp;
+use Zaptel::Xpp::Line;
my $proc_base = "/proc/xpp";
@@ -64,21 +66,15 @@ sub zt_registration($$) {
return $result;
}
-#
-# Backward compatibility for old drivers
-# before changeset:5119
-#
-# Newer drivers should directly have $xpd->spanno
-#
-sub spanno_of_xpd($) {
- my $xpd = shift || die;
-
- warn "Running on old driver. Keep going...\n";
- use Zaptel;
- my @spans = Zaptel::spans;
-
- my ($span) = grep { $_->name eq $xpd->fqn } @spans;
- return ($span) ? $span->num : 0;
+sub xpds_by_spanno() {
+ my @xbuses = Zaptel::Xpp::xbuses("SORT_CONNECTOR");
+ my @xpds = map { $_->xpds } @xbuses;
+ @xpds = grep { $_->spanno } @xpds;
+ @xpds = sort { $a->spanno <=> $b->spanno } @xpds;
+ my @spanno = map { $_->spanno } @xpds;
+ my @idx;
+ @idx[@spanno] = @xpds; # The spanno is the index now
+ return @idx;
}
sub new($$) {
@@ -92,8 +88,18 @@ sub new($$) {
local $/ = "\n";
open(F, "$procdir/summary") || die "Missing summary file in $procdir";
my $head = <F>;
- chomp $head;
- # "XPD-00 (BRI_TE ,card present, span 3)"
+ chomp $head; # "XPD-00 (BRI_TE ,card present, span 3)"
+ # The driver does not export the number of channels...
+ # Let's find it indirectly
+ while(<F>) {
+ chomp;
+ if(s/^\s*offhook\s*:\s*//) {
+ my @offhook = split;
+ @offhook || die "No channels in '$procdir/summary'";
+ $self->{CHANNELS} = @offhook;
+ last;
+ }
+ }
close F;
$head =~ s/^(XPD-(\d\d))\s+// || die;
$self->{ID} = $2;
@@ -105,13 +111,12 @@ sub new($$) {
#warn "Garbage in '$procdir/summary': rest='$rest'\n" if $rest;
if($span =~ s/span\s+(\d+)//) { # since changeset:5119
$self->{SPANNO} = $1;
- } else {
- $self->{SPANNO} = $self->spanno_of_xpd;
}
$self->{TYPE} = $type;
$self->{IS_BRI} = ($type =~ /BRI_(NT|TE)/);
$self->{IS_PRI} = ($type =~ /[ETJ]1_(NT|TE)/);
$self->{IS_DIGITAL} = ( $self->{IS_BRI} || $self->{IS_PRI} );
+ Zaptel::Xpp::Line->create_all($self, $procdir);
return $self;
}