diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-10 18:12:27 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-10 18:12:27 +0000 |
commit | 9899bafe997a4e020f302c99a6e025b4e8b25191 (patch) | |
tree | 8a108b05d0f319c95ba83f1d5984ae261572bebf /xpp/utils/zconf/Zaptel | |
parent | 1d7d5b07325a186785b22abf09ff531dfc2edd54 (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.pm | 102 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Config/Defaults.pm | 25 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware/PCI.pm | 17 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Span.pm | 17 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Xpp/Line.pm | 59 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Xpp/Xpd.pm | 43 |
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; } |