diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-05-17 19:34:32 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-05-17 19:34:32 +0000 |
commit | 5b68efc40a339a8ae3d9d137c7b9af809c3f5519 (patch) | |
tree | 365f4c82a3123daebaf9a8d41817916c1dd74bf4 /xpp/utils | |
parent | 5174fc292d1a6184271a39aea2826b57f177454e (diff) |
* Tested with zaptel-1.2.17.1
* Add D-Channel TX, RX and BAD frames count in /proc/xpp/XBUS-*/XPD-*/bri_info
* Adjust output of xpp_sync script. Pad for 8 port BRI.
* Added a debugging module parport_debug (not compiled by default).
* Added an optional patch to zaptel:
- compiles only if ZAPTEL_SYNC_TICK is defined
- Allow interested driver to register for "sync" notification.
- Does not affect drivers that do not use this feature.
* Added external synchronization feature:
- Only if ZAPTEL_SYNC_TICK feature is compiled in
- Than XPP may be synchronized by another card (e.g: an Astribank
with FXS can be synchronized by a Digium PRI card).
- May be enabled/disabled in runtime via the 'sync_tick_active' module
parameter to the xpp.ko module.
* Fixed a potential bug in D-Channel hexdump printing.
* New visual indications in BRI leds:
- Constant ON RED/GREEN: Shows the port type -- NT/TE.
- Very fast "double blink": Layer1 work, no D-Channel yet.
- Steady blinking (1/2 sec): D-Channel trafic detected.
* xpp_fxloader moved to /usr/share/zaptel .
* adj_clock removed: never really used.
* Debugfs code now disabled by default.
* Now we have Zaptel::Hardware and a sample zaptel_hardware script (not
(installed by default).
* We also have a sample perl zapconf (not installed by default) which
aims at replacing genzaptelconf (sans the modules detection).
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@2529 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/utils')
-rw-r--r-- | xpp/utils/Makefile | 18 | ||||
-rwxr-xr-x | xpp/utils/genzaptelconf | 17 | ||||
-rwxr-xr-x | xpp/utils/lszaptel | 2 | ||||
-rw-r--r-- | xpp/utils/xpp.rules | 2 | ||||
-rwxr-xr-x | xpp/utils/xpp_sync | 40 | ||||
-rwxr-xr-x | xpp/utils/zapconf | 295 | ||||
-rwxr-xr-x | xpp/utils/zaptel_hardware | 91 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel.pm | 2 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Chans.pm | 13 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware.pm | 40 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware/PCI.pm | 105 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware/USB.pm | 108 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Span.pm | 6 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Xpp.pm | 3 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Xpp/Xbus.pm | 13 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Xpp/Xpd.pm | 16 | ||||
-rwxr-xr-x | xpp/utils/zt_registration | 4 |
17 files changed, 724 insertions, 51 deletions
diff --git a/xpp/utils/Makefile b/xpp/utils/Makefile index 96b37db..6bf190a 100644 --- a/xpp/utils/Makefile +++ b/xpp/utils/Makefile @@ -25,10 +25,13 @@ HOTPLUG_USB_DIR = /etc/hotplug/usb UDEV_RULES_DIR = /etc/udev/rules.d # Perl disabled by default, until we see it is safe: #PERLLIBDIR = $(shell eval `perl -V:sitelib`; echo "$$sitelib") +PERL_DIRS := Zaptel Zaptel/Hardware Zaptel/Xpp +PERL_MODS_PAT := *.pm $(PERL_DIRS:%=%/*.pm) +PERL_MODS := $(shell cd zconf; echo $(PERL_MODS_PAT)) XPD_FIRMWARE = $(wildcard ../firmwares/*.hex) XPD_INIT_DATA = $(XPD_FIRMWARE) init_fxo_modes -XPD_INIT = $(wildcard ../init_card_?_*) ../calibrate_slics +XPD_INIT = $(wildcard ../init_card_?_*) ../calibrate_slics xpp_fxloader # Variables that should be defined above, but need sane defaults: # FIXME: Are those values really sane? @@ -50,16 +53,14 @@ PERL_SCRIPTS = zt_registration xpp_sync lszaptel xpp_blink PERL_MANS = $(PERL_SCRIPTS:%=%.8) TARGETS = init_fxo_modes print_modes -PROG_INSTALL = genzaptelconf -MAN_INSTALL = genzaptelconf.8 +PROG_INSTALL = genzaptelconf +MAN_INSTALL = $(PROG_INSTALL:%=%.8) ifeq (1,$(PBX_LIBUSB)) TARGETS += libhexfile.a fpga_load test_parse PROG_INSTALL += fpga_load -MAN_INSTALL += fpga_load.8 endif ifneq (,$(PERLLIBDIR)) PROG_INSTALL += $(PERL_SCRIPTS) -MAN_INSTALL += $(PERL_MANS) TARGETS += $(PERL_MANS) endif @@ -77,16 +78,17 @@ install: all $(INSTALL_DATA) $(MAN_INSTALL) $(DESTDIR)$(MANDIR)/ $(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR) $(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/ - $(INSTALL) xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/ + # for backward compatibility and for hotplug users: + ln -sf $(DATADIR)/xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/ $(INSTALL) -d $(DESTDIR)$(UDEV_RULES_DIR) $(INSTALL_DATA) xpp.rules $(DESTDIR)$(UDEV_RULES_DIR)/ ifneq (,$(PERLLIBDIR)) $(INSTALL) -d $(DESTDIR)$(PERLLIBDIR) - for i in Zaptel Zaptel/Xpp; \ + for i in $(PERL_DIRS); \ do \ $(INSTALL) -d "$(DESTDIR)$(PERLLIBDIR)/$$i"; \ done - for i in Zaptel.pm Zaptel/Xpp/Xbus.pm Zaptel/Xpp/Xpd.pm Zaptel/Xpp.pm Zaptel/Span.pm Zaptel/Chans.pm; \ + for i in $(PERL_MODS); \ do \ $(INSTALL_DATA) "zconf/$$i" "$(DESTDIR)$(PERLLIBDIR)/$$i"; \ done diff --git a/xpp/utils/genzaptelconf b/xpp/utils/genzaptelconf index 4bf8a38..daccee8 100755 --- a/xpp/utils/genzaptelconf +++ b/xpp/utils/genzaptelconf @@ -87,7 +87,7 @@ tmp_dir= # A list of all modules: # - the list of modules which will be probed (in this order) if -d is used # - The module that will be deleted from /etc/modules , if -d -M is used -ALL_MODULES="vzaphfc zaphfc qozap ztgsm wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wcte12xp wct1xxp wct4xxp wcte11xp wanpipe wcusb xpp_usb" +ALL_MODULES="wct4xxp wcte12xp wcte11xp wct1xxp wanpipe tor2 torisa qozap vzaphfc zaphfc ztgsm wctdm24xxp wctdm opvxa1200 wcfxo pciradio wcusb xpp_usb" # The name of the variable in /etc/sysconfig/zaptel into which to set # the list of detected modules. @@ -102,6 +102,7 @@ modules_var=MODULES #ZAPBRI_SIGNALLING=bri ZAPBRI_SIGNALLING=bri_ptmp #ZAPBRI_SIGNALLING=pri +zapconf_def_termtype=te # read default configuration from /etc/default/zaptel if [ -r $ZAPTEL_BOOT_DEBIAN ]; then . $ZAPTEL_BOOT_DEBIAN; fi @@ -915,6 +916,10 @@ EOF echo 'ami' >$tmp_dir/span_coding echo '' >$tmp_dir/span_switchtype echo '' >$tmp_dir/span_signalling + if [ "$zapconf_def_termtype" != '' ] + then + echo "$zapconf_def_termtype" >$tmp_dir/span_termtype + fi # Check if ZapBRI cards are in TE or NT mode if echo $title | egrep -q '((quad|octo)BRI PCI ISDN Card.* \[NT\]\ |octoBRI \[NT\] |HFC-S PCI A ISDN.* \[NT\] )' @@ -1101,6 +1106,16 @@ then detect fi +if [ "$zapconf_use_perl" = yes ]; then + #redefine genconf to use perl utilities: + genconf() { + case "$1" in + list) zaptel_hardware ;; + files) zapconf ;; + esac + } +fi + if [ "$mode" = list ]; then genconf list else diff --git a/xpp/utils/lszaptel b/xpp/utils/lszaptel index 4a6f8b9..ecb8ced 100755 --- a/xpp/utils/lszaptel +++ b/xpp/utils/lszaptel @@ -21,7 +21,7 @@ foreach my $span (Zaptel::spans()) { IN => 'Input' ); my ($type) = map { $type_map{$_} or $_ } $chan->type; - printf "%3d %s\n", $chan->num, $type; + printf "%3d %-10s %-10s %s\n", $chan->num, $type, $chan->signalling, $chan->info; } } diff --git a/xpp/utils/xpp.rules b/xpp/utils/xpp.rules index 8a669b1..10e4c1a 100644 --- a/xpp/utils/xpp.rules +++ b/xpp/utils/xpp.rules @@ -2,7 +2,7 @@ BUS!="usb", ACTION!="add", GOTO="xpp_usb_add_end" # Load firmware into the Xorcom Astribank device: SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[345][01]", \ - RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/$sysfs{bcdDevice}" + RUN+="/usr/share/zaptel/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/$sysfs{bcdDevice}" LABEL="xpp_usb_add_end" diff --git a/xpp/utils/xpp_sync b/xpp/utils/xpp_sync index e1258d9..d03c0a4 100755 --- a/xpp/utils/xpp_sync +++ b/xpp/utils/xpp_sync @@ -82,6 +82,22 @@ sub unique_xbus(@) { my $curr_sync = Zaptel::Xpp::sync; my @sync_xpds = unique_xbus(get_sorted_xpds()); +sub show_sync() { + foreach my $xpd (@sync_xpds) { + my $xbus = $xpd->xbus; + my @xpds = $xbus->xpds; + my @types = map { $_->type } @xpds; + my $mark = ($curr_sync =~ /\d+/ and $xbus->num == $curr_sync)?"+":""; + printf "\t%1s %s [ ", $mark, $xbus->name; + foreach my $x (sort { $a->num <=> $b->num } @xpds) { + printf "%-3s ", $x->type; + } + print "]"; + my $padding = ' ' x (4 * (8 - @xpds)); + printf "%s (%s)\n", $padding, $xbus->connector; + } +} + sub check_fxo_host_sync() { my @host_synced_xpds = grep { $_->xbus->num() ne $curr_sync } @sync_xpds; my @host_synced_fxos = grep($_->type eq 'FXO', @host_synced_xpds); @@ -111,29 +127,7 @@ if($sync) { } else { print "Current sync: ", $curr_sync, "\n"; print "Best Available Syncers:\n"; - foreach my $xpd (@sync_xpds) { - my $xbus = $xpd->xbus; - my @xpds = $xbus->xpds; - my @types = map { $_->type } @xpds; - my $mark = ($curr_sync =~ /\d+/ and $xbus->num == $curr_sync)?"+":""; - printf "\t%1s %s [ ", $mark, $xbus->name; - my $next = 0; - foreach my $x (sort { $a->num <=> $b->num } @xpds) { - my $n = $x->num; - # Fill spaces - for(my $i = $next; $i < $n; $i++) { - printf "%-3s ", ""; - } - printf "%-3s ", $x->type; - $next = $n + 1; - } - # Fill spaces to end - my $n = 4; - for(my $i = $next; $i < $n; $i++) { - printf "%-3s ", ""; - } - printf "] (%s)\n", $xbus->connector; - } + show_sync; check_fxo_host_sync; } diff --git a/xpp/utils/zapconf b/xpp/utils/zapconf new file mode 100755 index 0000000..8bcca13 --- /dev/null +++ b/xpp/utils/zapconf @@ -0,0 +1,295 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled <oron@actcom.co.il> +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id:$ +# +use strict; +BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } + +use Zaptel; +use Zaptel::Xpp; + +my %default_context = ( + FXO => 'from-pstn', + FXS => 'from-internal', + IN => 'astbank-input', + OUT => 'astbank-output' + ); + +my %default_group = ( + FXO => '0', + FXS => '5', + IN => '5', + OUT => '5' + ); + +my @zaptel_default_vars = qw( + base_exten + lc_country + context_lines + context_phones + context_input + context_output + group_lines + group_phones + ); + +my $fxs_immediate = 'no'; +my $fxs_default_start; +my $lc_country = 'us'; +my $loadzone; +my $defaultzone; + +sub map_zaptel_defaults { + my %defaults = @_; + + $default_group{FXO} = $defaults{group_lines} + if defined $defaults{group_lines}; + $default_group{FXS} = $default_group{IN} = $default_group{OUT} = $defaults{group_phones} + if defined $defaults{group_phones}; + $default_context{FXO} ||= $defaults{context_lines}; + $default_context{FXS} ||= $defaults{context_phones}; + $default_context{IN} ||= $defaults{context_input}; + $default_context{OUT} ||= $defaults{context_output}; + $fxs_immediate ||= $defaults{fxs_immediate}; + $fxs_default_start ||= $defaults{fxs_default_start} || 'ls'; + $lc_country ||= $defaults{lc_country}; + $loadzone = $defaultzone = $lc_country; +} + + +my $zapconf_file; +my $zapata_file; + +my @spans = Zaptel::spans(); + +sub bchan_range($) { + my $span = shift || die; + my $first_chan = ($span->chans())[0]; + my $first_num = $first_chan->num(); + my $range; + + if($span->is_bri()) { + $range = sprintf "%d-%d", $first_num, $first_num + 1; + } + return $range; +} + +sub gen_zaptel_signalling($) { + my $chan = shift || die; + my $type = $chan->type; + my $num = $chan->num; + + if($type eq 'FXO') { + printf "fxsks=%d\n", $num; + } elsif($type eq 'FXS') { + printf "fxo%s=%d\n", $fxs_default_start, $num; + } elsif ($type eq 'IN') { + printf "# astbanktype: input\n"; + printf "fxo%s=%d\n", $fxs_default_start, $num; + } elsif ($type eq 'OUT') { + printf "# astbanktype: output\n"; + printf "fxo%s=%d\n", $fxs_default_start, $num; + } elsif ($type eq 'BRI_TE') { + printf "# termtype: te\n"; + } elsif ($type eq 'BRI_NT') { + printf "# termtype: nt\n"; + } elsif($type eq 'EMPTY') { + printf "# channel %d, %s, no module.\n", $num, $chan->fqn; + return; + } +} + +my $bri_te_last_timing = 1; + +sub gen_zaptel_digital($) { + my $span = shift || die; + my $num = $span->num(); + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $timing; + my $lbo = 1; + my $framing = $span->framing() || die "$0: No framing information for span #$num\n"; + my $coding = $span->coding() || die "$0: No coding information for span #$num\n"; + my $span_yellow = $span->yellow(); + $span_yellow = (defined $span_yellow) ? ",$span_yellow" : ''; + + $timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++; + printf "span=%d,%d,%d,%s,%s\n", + $num, + $timing, + $lbo, + $framing, + "$coding$span_yellow"; + printf "# termtype: %s\n", lc($termtype); + printf "bchan=%s\n", bchan_range($span); + my $dchan = $span->dchan(); + printf "dchan=%d\n", $dchan->num(); +} + +sub gen_zaptelconf($) { + my $file = shift || die; + rename "$file", "$file.bak" + or $!{ENOENT} + or die "Failed to backup old config: $!\n"; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime); + print <<"HEAD"; +# Zaptel Configuration File +# +# This file is parsed by the Zaptel Configurator, ztcfg +# +HEAD + foreach my $span (@spans) { + printf "# Span %d: %s %s\n", $span->num, $span->name, $span->description; + if($span->is_bri()) { + gen_zaptel_digital($span); + } else { + foreach my $chan ($span->chans()) { + if(1 || !defined $chan->type) { + my $type = $chan->probe_type; + my $num = $chan->num; + die "Failed probing type for channel $num" + unless defined $type; + $chan->type($type); + } + gen_zaptel_signalling($chan); + } + } + print "\n"; + } + print <<"TAIL"; +# Global data + +loadzone = $loadzone +defaultzone = $defaultzone +TAIL + close F; + select $old; +} + +sub gen_zapata_channel($) { + my $chan = shift || die; + my $type = $chan->type; + my $num = $chan->num; + my $sig; + my $immediate; + my $callerid = sprintf "\"Channel %d\" <4%03d>", $num, $num; + my $context = $default_context{$type}; + my $group = $default_group{$type}; + + if ($type eq 'FXO') { + $sig = "fxs_ks"; + $callerid = 'asreceived'; + } elsif($type eq 'FXS') { + $sig = "fxo_" . $fxs_default_start; + $immediate = 'yes' if $fxs_immediate eq 'yes'; + } elsif($type eq 'IN') { + $sig = "fxo_" . $fxs_default_start; + $immediate = 'yes'; + } elsif($type eq 'OUT') { + $sig = "fxo_" . $fxs_default_start; + } elsif($type eq 'EMPTY') { + return; + } + die "Unknown signalling for channel $num type $type\n" + unless defined $sig; + printf ";;; line=\"%d %s\"\n", $num, $chan->fqn; + printf "signalling=$sig\n"; + printf "callerid=$callerid\n"; + printf "mailbox=4%03d\n", $num unless $type eq 'FXO'; + if(defined $group) { + printf "group=%d\n", $group; + } + printf "context=$context\n"; + printf "immediate=$immediate\n" if defined $immediate; + printf "channel => %d\n", $num; + # Reset following values to default + printf "callerid=\n"; + printf "mailbox=\n" unless $type eq 'FXO'; + if(defined $group) { + printf "group=\n"; + } + printf "context=default\n"; + printf "immediate=no\n" if defined $immediate; + print "\n"; +} + +sub gen_zapataconf($) { + my $file = shift || die; + rename "$file", "$file.bak" + or $!{ENOENT} + or die "Failed to backup old config: $!\n"; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime); + print <<"HEAD"; +; Zaptel Channels Configurations (zapata.conf) +; +; This is not intended to be a complete zapata.conf. Rather, it is intended +; to be #include-d by /etc/zapata.conf that will include the global settings +; + +HEAD + foreach my $span (@spans) { + printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description; + foreach my $chan ($span->chans()) { + gen_zapata_channel($chan); + } + print "\n"; + } + close F; + select $old; +} + +# Use the shell to source a file and expand a given list +# of variables. +sub do_source($@) { + my $file = shift; + my @vars = @_; + my @output = `env -i sh -e -c '. $file; export @vars; env'`; + die "$0: Sourcing '$file' exited with $?" if $?; + my %vars; + + foreach my $line (@output) { + chomp $line; + my ($k, $v) = split(/=/, $line, 2); + $vars{$k} = $v if grep /^$k$/, @vars; + } + return %vars; +} + +sub set_defaults { + my $zaptel_boot_debian = $ENV{ZAPTEL_BOOT_DEBIAN} || "/etc/default/zaptel"; + my $zaptel_boot_fedora = $ENV{ZAPTEL_BOOT_FEDORA} || "/etc/sysconfig/zaptel"; + + # Source default files + my %source_defaults; + foreach my $defaults ($zaptel_boot_debian, $zaptel_boot_fedora) { + %source_defaults = do_source($defaults, @zaptel_default_vars) if -r $defaults; + } + map_zaptel_defaults(%source_defaults); + $zapconf_file = $ENV{ZAPCONF_FILE} || "/etc/zaptel.conf"; + $zapata_file = $ENV{ZAPATA_FILE} || "/etc/asterisk/zapata-channels.conf"; +} + +set_defaults; +gen_zaptelconf $zapconf_file; +gen_zapataconf $zapata_file; + +__END__ + +=head1 NAME + +zapconf - Generate configuration for zaptel channels. + +=head1 SYNOPSIS + +zapconf + +=head1 DESCRIPTION + diff --git a/xpp/utils/zaptel_hardware b/xpp/utils/zaptel_hardware new file mode 100755 index 0000000..26aa839 --- /dev/null +++ b/xpp/utils/zaptel_hardware @@ -0,0 +1,91 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled <oron@actcom.co.il> +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id:$ +# +use strict; +BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } + +use Zaptel; +use Zaptel::Span; +use Zaptel::Xpp; +use Zaptel::Xpp::Xbus; +use Zaptel::Hardware; + +sub usage { + die "Usage: $0\n"; +} + +@ARGV == 0 or usage; + +my @hardware = Zaptel::Hardware->devices; +my @spans = Zaptel::spans; + +sub show_xbus($) { + my $xbus = shift or die; + my @xpds = $xbus->xpds; + my $connector = ($xbus->status eq 'CONNECTED') ? $xbus->connector : "MISSING"; + $connector = "(" . $connector . ")"; + printf "%-20s\n", $connector; + foreach my $xpd (sort { $a->num <=> $b->num } @xpds) { + my $reg = $xpd->zt_registration; + my $span; + my $spanstr; + if($reg && @spans) { + ($span) = grep { $_->name eq $xpd->fqn } @spans; + $spanstr = ($span) ? ("Span " . $span->num) : ""; + } else { + $spanstr = "Unregistered"; + } + my $master = ''; + $master = "XPP-SYNC" if $xpd->is_sync_master; + $master .= " ZAPTEL-SYNC" if defined($span) && $span->is_zaptel_sync_master; + printf "\t%-10s: %-8s %s %s\n", $xpd->fqn, $xpd->type, $spanstr, $master; + } +} + +my %seen; +my $format = "%-20s\t%4s:%4s %-12s "; + +foreach my $dev (@hardware) { + my $xbus = $dev->xbus; + my $driver = $dev->driver || ""; + $driver = "[$driver]"; + printf $format, $dev->hardware_name, $dev->vendor, $dev->product, $driver; + if(!$xbus) { + printf "\n"; + next; + } + $seen{$xbus->name} = 1; + show_xbus($xbus); +} + +my $notified_lost = 0; +foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) { + if(!$seen{$xbus->name}) { + print "----------- XPP Spans with disconnected hardware -----------\n" + unless $notified_lost++; + printf $format, $xbus->name, '', '', "NO HARDWARE"; + show_xbus($xbus); + } +} + + +__END__ + +=head1 NAME + +zaptel_hardware - Shows Zaptel hardware devices. + +=head1 SYNOPSIS + +zaptel_hardware + +=head1 DESCRIPTION + +Show all zaptel hardware devices, both used and unused. + diff --git a/xpp/utils/zconf/Zaptel.pm b/xpp/utils/zconf/Zaptel.pm index 7642b0e..3717e72 100644 --- a/xpp/utils/zconf/Zaptel.pm +++ b/xpp/utils/zconf/Zaptel.pm @@ -15,7 +15,7 @@ my $proc_base = "/proc/zaptel"; sub spans() { my @spans; - -d $proc_base or die "Missing '$proc_base'. Perhaps zaptel module isn't loaded?\n"; + -d $proc_base or return (); foreach my $zfile (glob "$proc_base/*") { $zfile =~ s:$proc_base/::; my $span = Zaptel::Span->new($zfile); diff --git a/xpp/utils/zconf/Zaptel/Chans.pm b/xpp/utils/zconf/Zaptel/Chans.pm index 3364060..eef922f 100644 --- a/xpp/utils/zconf/Zaptel/Chans.pm +++ b/xpp/utils/zconf/Zaptel/Chans.pm @@ -22,25 +22,26 @@ sub AUTOLOAD { } } -sub new($$$$$) { +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 $num = shift or die "Missing a channel number parameter\n"; my $fqn = shift or die "Missing a channel fqn parameter\n"; - my $info = shift; + my $signalling = shift || ''; + my $info = shift || ''; 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 - } elsif(defined $info) { - $type = (split(/\s+/, $info))[0]; - $type = 'FXS' if $type =~ /^FXS/; - $type = 'FXO' if $type =~ /^FXO/; + } elsif(defined $signalling) { + $type = 'FXS' if $signalling =~ /^FXS/; + $type = 'FXO' if $signalling =~ /^FXO/; } else { $type = undef; } diff --git a/xpp/utils/zconf/Zaptel/Hardware.pm b/xpp/utils/zconf/Zaptel/Hardware.pm new file mode 100644 index 0000000..321292a --- /dev/null +++ b/xpp/utils/zconf/Zaptel/Hardware.pm @@ -0,0 +1,40 @@ +package Zaptel::Hardware; +# +# Written by Oron Peled <oron@actcom.co.il> +# Copyright (C) 2007, 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::Hardware::USB; +use Zaptel::Hardware::PCI; + +my @zaptel_devices; + +sub device_detected($$) { + my $dev = shift || die; + my $name = shift || die; + warn "Device '$name' already known\n" + if grep { $_->hardware_name eq $name } @zaptel_devices; + push(@zaptel_devices, $dev); +} + +sub device_removed($) { + my $dev = shift || die; + my $name = $dev->hardware_name; + die "Missing zaptel device hardware name" unless $name; + @zaptel_devices = grep { $_->hardware_name ne $name } @zaptel_devices; +} + +sub devices($) { + my $pack = shift || die; + + return @zaptel_devices; +} + +Zaptel::Hardware::USB->scan_devices; +Zaptel::Hardware::PCI->scan_devices; + +1; diff --git a/xpp/utils/zconf/Zaptel/Hardware/PCI.pm b/xpp/utils/zconf/Zaptel/Hardware/PCI.pm new file mode 100644 index 0000000..c6731dc --- /dev/null +++ b/xpp/utils/zconf/Zaptel/Hardware/PCI.pm @@ -0,0 +1,105 @@ +package Zaptel::Hardware::PCI; +# +# Written by Oron Peled <oron@actcom.co.il> +# Copyright (C) 2007, 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::Hardware; + +my @idlist = qw( + 1397:16B8 + 1397:08B4 + 1057:5608 + 10B5:3001 + 10B5:4000 + 10B5:9030 + 10B5:D00D + D161:0800 + D161:2400 + E159:0001 + ); + +$ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; +my $prog = 'lspci'; + +# Accessors (miniperl does not have Class:Accessor) +our $AUTOLOAD; +sub AUTOLOAD { + my $self = shift; + my $name = uc($AUTOLOAD); + $name =~ s/.*://; # strip fully-qualified portion + if (@_) { + return $self->{$name} = shift; + } else { + return $self->{$name}; + } +} + +my @devices; + +sub pci_sorter() { + return + sprintf("%03d/%03d", $a->bus, $a->dev) cmp + sprintf("%03d/%03d", $b->bus, $b->dev); +} + +sub new($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $self = { @_ }; + bless $self, $pack; + my $hardware_name = sprintf("pci:%s:%s:%s", $self->{DOMAIN}, $self->{BUS}, $self->{DEV}); + $self->{HARDWARE_NAME} = $hardware_name; + Zaptel::Hardware::device_detected($self, $hardware_name); + my $sysfile = sprintf "/sys/bus/pci/devices/%s:%s:%s/driver/module", $self->{DOMAIN}, $self->{BUS}, $self->{DEV}; + my $module = readlink($sysfile); + if(defined $module) { + $module =~ s:^.*/::; + $self->{DRIVER} = $module; + } + return $self; +} + +sub devices($) { + my $pack = shift or die "Wasn't called as a class method\n"; + return sort pci_sorter @devices; +} + +my $domain_support = 1; # Optimistic... + +sub scan_devices($) { + my $pack = shift || die; + if(!open(F, "$prog -Dn 2> /dev/null |")) { + $domain_support = 0; + open(F, "$prog -n|") || die "$0: Failed running $prog: $!"; + } + while(<F>) { + chomp; + my ($phys,$id) = (split(/\s+/))[0,2]; + my $domain; + my $bus; + my $dev; + if($domain_support) { + ($domain,$bus,$dev) = split(/:/, $phys); + } else { + ($bus,$dev) = split(/:/, $phys); + $domain = '0000'; + } + next unless grep { uc($id) eq $_ } @idlist; + my($vendor,$product) = split(/:/, $id); + my $d = Zaptel::Hardware::PCI->new( + DOMAIN => $domain, + BUS => $bus, + DEV => $dev, + VENDOR => $vendor, + PRODUCT => $product, + ); + push(@devices, $d); + } + close F; +} + +1; diff --git a/xpp/utils/zconf/Zaptel/Hardware/USB.pm b/xpp/utils/zconf/Zaptel/Hardware/USB.pm new file mode 100644 index 0000000..bbf00fe --- /dev/null +++ b/xpp/utils/zconf/Zaptel/Hardware/USB.pm @@ -0,0 +1,108 @@ +package Zaptel::Hardware::USB; +# +# Written by Oron Peled <oron@actcom.co.il> +# Copyright (C) 2007, 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::Hardware; +use Zaptel::Xpp; +use Zaptel::Xpp::Xbus; + +my @idlist = qw( + e4e4:1130 + e4e4:1131 + e4e4:1132 + e4e4:1140 + e4e4:1141 + e4e4:1142 + e4e4:1150 + e4e4:1151 + e4e4:1152 + ); + + +$ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; +my $prog = 'lsusb'; + +# Accessors (miniperl does not have Class:Accessor) +our $AUTOLOAD; +sub AUTOLOAD { + my $self = shift; + my $name = uc($AUTOLOAD); + $name =~ s/.*://; # strip fully-qualified portion + if (@_) { + return $self->{$name} = shift; + } else { + return $self->{$name}; + } +} + +my @devices; +my @xbuses = Zaptel::Xpp::xbuses('SORT_CONNECTOR'); + +sub usb_sorter() { + return + sprintf("%03d/%03d", $a->bus, $a->dev) cmp + sprintf("%03d/%03d", $b->bus, $b->dev); +} + +sub xbus_of_usb($$) { + my $bus = shift; + my $dev = shift; + + my ($wanted) = grep { + my $b = $_->usb_bus; + my $d = $_->usb_dev; + defined($b) && $b == $bus && + defined($d) && $d == $dev + } @xbuses; + return $wanted; +} + +sub new($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $self = { @_ }; + bless $self, $pack; + my $xbus = xbus_of_usb($self->bus, $self->dev); + if(defined $xbus) { + $self->{XBUS} = $xbus; + $self->{DRIVER} = 'xpp_usb'; + } + my $hardware_name = sprintf("usb:%03d/%03d", $self->{BUS}, $self->{DEV}); + $self->{HARDWARE_NAME} = $hardware_name; + Zaptel::Hardware::device_detected($self, $hardware_name); + return $self; +} + +sub devices($) { + my $pack = shift or die "Wasn't called as a class method\n"; + return sort usb_sorter @devices; +} + +sub scan_devices($) { + my $pack = shift || die; + open(F, "$prog|") || die "$0: Failed running $prog: $!"; + while(<F>) { + chomp; + my ($bus,$dev,$id) = (split(/\s+/))[1,3,5]; + $dev =~ s/://; + $bus =~ s/^0*//; + $dev =~ s/^0*//; + next unless grep { lc($id) eq $_ } @idlist; + my($vendor,$product) = split(/:/, $id); + my $d = Zaptel::Hardware::USB->new( + BUS => $bus, + DEV => $dev, + VENDOR => $vendor, + PRODUCT => $product, + ); + push(@devices, $d); + } + close F; +} + +1; diff --git a/xpp/utils/zconf/Zaptel/Span.pm b/xpp/utils/zconf/Zaptel/Span.pm index c020d2f..8496910 100644 --- a/xpp/utils/zconf/Zaptel/Span.pm +++ b/xpp/utils/zconf/Zaptel/Span.pm @@ -69,14 +69,16 @@ sub new($$) { die "$0: Unkown TERMTYPE [NT/TE]\n" if $self->is_bri and !defined $self->{TERMTYPE}; ($self->{NAME}, $self->{DESCRIPTION}) = (split(/\s+/, $head, 4))[2, 3]; + $self->{IS_ZAPTEL_SYNC_MASTER} = + ($self->{DESCRIPTION} =~ /\(MASTER\)/) ? 1 : 0; $self->{CHANS} = []; while(<F>) { chomp; s/^\s*//; s/\s*$//; next unless /\S/; - my ($chan, $name, $info) = split(/\s+/, $_, 3); - my $c = Zaptel::Chans->new($self, $chan, $name, $info); + my ($chan, $name, $signalling, $info) = split(/\s+/, $_, 4); + my $c = Zaptel::Chans->new($self, $chan, $name, $signalling, $info); push(@{$self->{CHANS}}, $c); } close F; diff --git a/xpp/utils/zconf/Zaptel/Xpp.pm b/xpp/utils/zconf/Zaptel/Xpp.pm index dd1f34c..28de49d 100644 --- a/xpp/utils/zconf/Zaptel/Xpp.pm +++ b/xpp/utils/zconf/Zaptel/Xpp.pm @@ -27,8 +27,9 @@ sub xbuses { my $optsort = shift || 'SORT_NAME'; my @xbuses; + -d "/proc/xpp" or return (); open(F, "$proc_base/xbuses") || - die "$0: Failed to open $proc_base/xbuses. xpp module is loaded?\n"; + die "$0: Failed to open $proc_base/xbuses: $!\n"; while(<F>) { chomp; my ($name, @attr) = split; diff --git a/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm b/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm index 772e050..0dd6d84 100644 --- a/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm +++ b/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm @@ -64,6 +64,19 @@ sub new($$) { bless $self, $pack; $self->{NAME} or die "Missing xbus name"; my $prefix = "$proc_base/" . $self->{NAME}; + my $usbfile = "$prefix/xpp_usb"; + if(open(F, "$usbfile")) { + my $head = <F>; + chomp $head; + close F; + $head =~ s/^device: +([^, ]+)/$1/i or die; + my ($usb_bus, $usb_dev) = split('/', $head); + die unless defined($usb_bus) && defined($usb_dev); + $usb_bus =~ s/^0*//; + $usb_dev =~ s/^0*//; + $self->{USB_BUS} = $usb_bus; + $self->{USB_DEV} = $usb_dev; + } @{$self->{XPDS}} = (); foreach my $fqn (glob "$prefix/XPD-??") { $fqn =~ s:$proc_base/::; diff --git a/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm b/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm index 94176b8..852aaea 100644 --- a/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm +++ b/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm @@ -82,11 +82,17 @@ sub new($$) { bless $self, $pack; my $dir = "$proc_base/" . $self->fqn; $self->{DIR} = $dir; - my ($name) = glob "$dir/*_info"; - die "Missing info file in $dir" unless $name; - $name =~ s|^.*/||; # basename - die "Bad info file name ($name) in $dir" if $name !~ /(\w+)_info/; - $self->{TYPE} = uc($1); + open(F, "$dir/summary") || die "Missing summary file in $dir"; + my $head = <F>; + chomp $head; + # "XPD-00 (BRI_TE ,card present, span registered) SYNC MASTER" + close F; + $head =~ s/^.*\(//; + $head =~ s/\) */, /; + $head =~ s/\s*,\s*/,/g; + my ($type,$present,$registered,$sync) = split(/,/, $head); + $self->{TYPE} = uc($type); + $self->{IS_SYNC_MASTER} = ($sync =~ /MASTER/); return $self; } diff --git a/xpp/utils/zt_registration b/xpp/utils/zt_registration index a1cb8ee..d6d0278 100755 --- a/xpp/utils/zt_registration +++ b/xpp/utils/zt_registration @@ -50,14 +50,14 @@ foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) { if(!defined($on)) { # Query only my ($span) = grep { $_->name eq $xpd->fqn } @spans; my $spanstr = ($span) ? ("Span " . $span->num) : ""; - myprintf "2 %s %s\n", state2str($prev), $spanstr ; + myprintf "%s %s\n", state2str($prev), $spanstr ; next; } if(!defined($prev)) { # Failure printf "Failed %s\n", $!; next; } - myprintf "3 %3s ==> %3s\n", state2str($prev), state2str($on); + myprintf "%3s ==> %3s\n", state2str($prev), state2str($on); } } |