diff options
Diffstat (limited to 'xpp/utils')
-rw-r--r-- | xpp/utils/Makefile | 16 | ||||
-rw-r--r-- | xpp/utils/fpga_load.c | 18 | ||||
-rwxr-xr-x | xpp/utils/genzaptelconf | 152 | ||||
-rwxr-xr-x | xpp/utils/lszaptel | 70 | ||||
-rw-r--r-- | xpp/utils/xpp.rules | 2 | ||||
-rwxr-xr-x | xpp/utils/xpp_blink | 8 | ||||
-rwxr-xr-x | xpp/utils/xpp_sync | 86 | ||||
-rwxr-xr-x | xpp/utils/zapconf | 275 | ||||
-rwxr-xr-x | xpp/utils/zaptel_hardware | 12 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Chans.pm | 15 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Config/Defaults.pm | 29 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware.pm | 8 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware/PCI.pm | 1 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Span.pm | 34 | ||||
-rwxr-xr-x | xpp/utils/zt_registration | 41 |
15 files changed, 552 insertions, 215 deletions
diff --git a/xpp/utils/Makefile b/xpp/utils/Makefile index f9d034a..72ba74d 100644 --- a/xpp/utils/Makefile +++ b/xpp/utils/Makefile @@ -31,6 +31,7 @@ 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 xpp_fxloader +XPD_INIT_PERL = ../init_card_6_26 ../init_card_7_26 # Variables that should be defined above, but need sane defaults: # FIXME: Are those values really sane? @@ -48,7 +49,15 @@ CFLAGS = -g -Wall $(EXTRA_CFLAGS) %.8: % pod2man --section 8 $^ > $@ || $(RM) $@ -PERL_SCRIPTS = zt_registration xpp_sync lszaptel xpp_blink +PERL_SCRIPTS = \ + zt_registration \ + xpp_sync \ + lszaptel \ + xpp_blink \ + zapconf \ + zaptel_hardware \ + # + PERL_MANS = $(PERL_SCRIPTS:%=%.8) TARGETS = init_fxo_modes print_modes @@ -63,7 +72,7 @@ PROG_INSTALL += $(PERL_SCRIPTS) TARGETS += $(PERL_MANS) endif -all: $(TARGETS) +all: perlcheck $(TARGETS) docs: $(PERL_MANS) @@ -120,5 +129,8 @@ wctdm_fxomodes.h: $(WCTDM) init_fxo_modes: print_modes ./$< >$@ +perlcheck: $(PERL_SCRIPTS) $(XPD_INIT_PERL) + for i in $^; do perl -I./zconf -c $$i || exit 1; done + clean: $(RM) *.o $(TARGETS) diff --git a/xpp/utils/fpga_load.c b/xpp/utils/fpga_load.c index 1cbd749..cc9cf81 100644 --- a/xpp/utils/fpga_load.c +++ b/xpp/utils/fpga_load.c @@ -107,6 +107,18 @@ const char *load_status2str(enum fpga_load_status s) } } +/* return 1 if: + * - str has a number + * - It is larger than 0 + * - It equals num + */ +int num_matches(int num, const char* str) { + int str_val = atoi(str); + if (str_val <= 0) + return 0; + return (str_val == num); +} + struct usb_device *dev_of_path(const char *path) { struct usb_bus *bus; @@ -149,10 +161,12 @@ struct usb_device *dev_of_path(const char *path) sprintf(dirname, "%03d", bnum); sprintf(filename, "%03d", dnum); for (bus = usb_busses; bus; bus = bus->next) { - if(strcmp(bus->dirname, dirname) != 0) + if (! num_matches(bnum, bus->dirname)) + //if(strcmp(bus->dirname, dirname) != 0) continue; for (dev = bus->devices; dev; dev = dev->next) { - if(strcmp(dev->filename, filename) == 0) + //if(strcmp(dev->filename, filename) == 0) + if (num_matches(dnum, dev->filename)) return dev; } } diff --git a/xpp/utils/genzaptelconf b/xpp/utils/genzaptelconf index daccee8..cf32fcd 100755 --- a/xpp/utils/genzaptelconf +++ b/xpp/utils/genzaptelconf @@ -516,9 +516,8 @@ unload_module() { set -- $line # $1: the original module, $2: size, $3: refcount, $4: deps list mods=`echo $4 | tr , ' '` - # old versions of xpd_fxs actually depend on xpp, but forget to tell it. - # bug has already been fixed but the code will remain here for a while - # just in case + # xpp_usb keeps the xpds below busy, and hence must be removed + # before them: case "$module" in xpd_*) mods="xpp_usb $mods";; esac for mod in $mods; do # run in a subshell, so it won't step over our vars: @@ -583,7 +582,9 @@ temporary_zapconf() { save) say "Temporarily moving zaptel.conf aside to work around broken modprobe.conf" ZAPCONF_FILE_TMP=`mktemp /tmp/genzaptelconf-zaptel.conf-XXXXXX` || die "Error creating temporary zaptel.conf" - cp -a $ZAPCONF_FILE_SYSTEM $ZAPCONF_FILE_TMP + if [ -f $ZAPCONF_FILE_SYSTEM ]; then + cp -a $ZAPCONF_FILE_SYSTEM $ZAPCONF_FILE_TMP + fi echo -n >$ZAPCONF_FILE_SYSTEM ;; restore) @@ -643,6 +644,8 @@ gen_tmp_conf() { # Extract information from one digital channel (one line in a /proc/zaptel # file). Information is saved to $tmp_dir/span_foo variables. +# FIXME: detection should move to when we know the number of channels +# and hence can tell between an E1 and a T1. detect_digital_channel() { line="$1" chan_num="$2" @@ -653,70 +656,78 @@ detect_digital_channel() { # them by the channel names. This is shorter. # This also allows us to count the channel numbers and check if # we have a E1 span, a T1 span or a BRI span. - if [ "`cat $tmp_dir/span_begin`" = "-1" ] + + # span_lastd is always the one before last + # channel. span_bchan is the last: + echo $chan_num >$tmp_dir/span_end + + if [ "`cat $tmp_dir/span_begin`" != "-1" ] then - echo $chan_num >$tmp_dir/span_begin - echo $span_num >$tmp_dir/span_num - # The Astribank channels provide the information of TE/NT in the channel name. So - # why not use it? - case "$line" in - *XPP_BRI_TE/*) echo 'te' >$tmp_dir/span_termtype;; - *XPP_BRI_NT/*) echo 'nt' >$tmp_dir/span_termtype;; - esac - case "$line" in - *ZTHFC*/*|*ztqoz*/*|*XPP_BRI_*/*) - # BRI channel - echo 'ccs' >$tmp_dir/span_framing - echo 'euroisdn' >$tmp_dir/span_switchtype - if [ "`cat $tmp_dir/span_termtype`" = 'nt' 2>/dev/null ] - then - echo $ZAPBRI_NET >$tmp_dir/span_signalling - else - echo $ZAPBRI_CPE >$tmp_dir/span_signalling - fi + return #we already configured this span. + fi + + # Now we need to give initial configuration to the span + echo $chan_num >$tmp_dir/span_begin + echo $span_num >$tmp_dir/span_num + + case "$line" in + *ZTHFC*/*|*ztqoz*/*|*XPP_BRI_*/*) + # BRI channel + echo 'ccs' >$tmp_dir/span_framing + echo 'euroisdn' >$tmp_dir/span_switchtype + if [ "`cat $tmp_dir/span_termtype`" = 'nt' 2>/dev/null ] + then + echo $ZAPBRI_NET >$tmp_dir/span_signalling + else + echo $ZAPBRI_CPE >$tmp_dir/span_signalling + fi + ;; + *ztgsm*/*) + # Junghanns's GSM cards. + echo 'ccs' >$tmp_dir/span_framing + #Does this mean anything? + echo 'gsm' >$tmp_dir/span_signalling + ;; + *TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*WP[TE]1/*) + # FIXME: handle cwain around here. + # name: *cwain[12]/* . Always E1. + + # PRI span (E1/T1) + echo 'esf' >$tmp_dir/span_framing + echo 'b8zs' >$tmp_dir/span_coding + echo 'national' >$tmp_dir/span_switchtype + if [ "`cat $tmp_dir/span_termtype`" = 'nt' 2>/dev/null ] + then + echo pri_net >$tmp_dir/span_signalling + else + echo pri_cpe >$tmp_dir/span_signalling + fi + # an example of country-specific setup. This is probably not accurate + # Contributions are welcome + case "$lc_country" in + nl) + # (Just an example for per-country info) + echo 'ccs' >$tmp_dir/span_framing + echo 'ami' >$tmp_dir/span_coding + #echo 'crc4' >$tmp_dir/span_yellow + #echo 'euroisdn' >$tmp_dir/span_switchtype + #echo 'pri_cpe' >$tmp_dir/span_signalling ;; - *ztgsm*/*) - # Junghanns's GSM cards. - echo 'ccs' >$tmp_dir/span_framing - #Does this mean anything? - echo 'gsm' >$tmp_dir/span_signalling + il|de|au) + echo 'ccs' >$tmp_dir/span_framing + echo 'hdb3' >$tmp_dir/span_coding + echo 'crc4' >$tmp_dir/span_yellow + echo 'euroisdn' >$tmp_dir/span_switchtype ;; - *TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*WP[TE]1/*) - # PRI span (E1/T1) - echo 'esf' >$tmp_dir/span_framing - echo 'b8zs' >$tmp_dir/span_coding + cl) + echo 'ccs' >$tmp_dir/span_framing + echo 'hdb3' >$tmp_dir/span_coding + #echo 'crc4' >$tmp_dir/span_yellow echo 'national' >$tmp_dir/span_switchtype - echo 'pri_cpe' >$tmp_dir/span_signalling - # an example of country-specific setup. This is probably not accurate - # Contributions are welcome - case "$lc_country" in - nl) - # (Just an example for per-country info) - echo 'ccs' >$tmp_dir/span_framing - echo 'ami' >$tmp_dir/span_coding - #echo 'crc4' >$tmp_dir/span_yellow - #echo 'euroisdn' >$tmp_dir/span_switchtype - #echo 'pri_cpe' >$tmp_dir/span_signalling - ;; - il|de|au) - echo 'ccs' >$tmp_dir/span_framing - echo 'hdb3' >$tmp_dir/span_coding - echo 'crc4' >$tmp_dir/span_yellow - echo 'euroisdn' >$tmp_dir/span_switchtype - ;; - cl) - echo 'ccs' >$tmp_dir/span_framing - echo 'hdb3' >$tmp_dir/span_coding - #echo 'crc4' >$tmp_dir/span_yellow - echo 'national' >$tmp_dir/span_switchtype - ;; - esac - ;; + ;; esac - fi - # span_lastd is always the one before last - # channel. span_bchan is the last: - echo $chan_num >$tmp_dir/span_end + ;; + esac } # read information from the $tmp_dir/span_foo files and generate @@ -744,7 +755,7 @@ write_digital_config() { 31) #E1 dchan="$(($span_begin+15))" bchans="$span_begin-$(($span_begin+14)),$(($span_begin+16))-$span_end" - if [ "$span_switchtype" = 'national' ]; then + if [ "$span_framing" = 'esf' ]; then # don't leave an E1 span with defective defaults: span_framing=ccs span_coding=hdb3 @@ -922,15 +933,14 @@ EOF 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\] )' + if echo $title | egrep -q '((quad|octo)BRI PCI ISDN Card.* \[NT\]\ |octoBRI \[NT\] |HFC-S PCI A ISDN.* \[NT\] |Xorcom .* BRI_NT)' then echo 'nt' >$tmp_dir/span_termtype - else - if echo $title | egrep -q '((quad|octo)BRI PCI ISDN Card.* \[TE\]\ |octoBRI \[TE\] |HFC-S PCI A ISDN.* \[TE\] )' - then - echo 'te' >$tmp_dir/span_termtype - fi + elif echo $title | egrep -q '((quad|octo)BRI PCI ISDN Card.* \[TE\]\ |octoBRI \[TE\] |HFC-S PCI A ISDN.* \[TE\] |Xorcom .* BRI_TE)' + then + echo 'te' >$tmp_dir/span_termtype fi + # The rest of the lines are per-channel lines sed -e 1,2d $procfile | \ while read line @@ -982,7 +992,7 @@ EOF # Astribank FXS span (input port) print_pattern -a input $chan_num fxo $mode ;; - *ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*XPP_BRI_*/*|*WP[TE]1/*) + *ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*XPP_BRI_*/*|*WP[TE]1/*|*XPP_BRI*) detect_digital_channel "$line" "$chan_num" "$span_num" ;; '') ;; # Empty line (after span header) diff --git a/xpp/utils/lszaptel b/xpp/utils/lszaptel index ecb8ced..3126c8a 100755 --- a/xpp/utils/lszaptel +++ b/xpp/utils/lszaptel @@ -8,7 +8,8 @@ # $Id$ # use strict; -BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } use Zaptel; use Zaptel::Span; @@ -20,7 +21,7 @@ foreach my $span (Zaptel::spans()) { OUT => 'Output', IN => 'Input' ); - my ($type) = map { $type_map{$_} or $_ } $chan->type; + my ($type) = map { $type_map{$_} or $_ } $chan->type || ("unknown"); printf "%3d %-10s %-10s %s\n", $chan->num, $type, $chan->signalling, $chan->info; } } @@ -39,18 +40,53 @@ lszaptel Example output: - ### Span 1: XBUS-03/XPD-00 "Xorcom XPD #3/0: FXS" - 1 FXS - 2 FXS - 3 FXS - 4 FXS - 5 FXS - 6 FXS - 7 FXS - 8 FXS - 9 Output - 10 Output - 11 Input - 12 Input - 13 Input - 14 Input + ### Span 1: WCTDM/0 "Wildcard TDM400P REV E/F Board 1" + 1 FXO FXOLS (In use) + 2 FXS FXSKS + 3 FXS FXSKS + 4 FXS FXSKS + ### Span 2: XBUS-00/XPD-00 "Xorcom XPD #00/00: FXO" + 5 FXO FXSKS (In use) + 6 FXO FXSKS (In use) (no pcm) + 7 FXO FXSKS (In use) (no pcm) + 8 FXO FXSKS (In use) (no pcm) + 9 FXO FXSKS (In use) (no pcm) + 10 FXO FXSKS (In use) (no pcm) + 11 FXO FXSKS (In use) (no pcm) + 12 FXO FXSKS (In use) (no pcm) + ### Span 3: XBUS-00/XPD-10 "Xorcom XPD #00/10: FXO" + 13 FXO FXSKS (In use) (no pcm) + 14 FXO FXSKS (In use) (no pcm) + 15 FXO FXSKS (In use) (no pcm) + 16 FXO FXSKS (In use) (no pcm) + 17 FXO FXSKS (In use) (no pcm) + 18 FXO FXSKS (In use) (no pcm) + 19 FXO FXSKS (In use) (no pcm) + 20 FXO FXSKS (In use) (no pcm) + + ... + + ### Span 6: XBUS-01/XPD-00 "Xorcom XPD #01/00: FXS" + 37 FXS FXOLS (In use) + 38 FXS FXOLS (In use) (no pcm) + 39 FXS FXOLS (In use) (no pcm) + 40 FXS FXOLS (In use) (no pcm) + 41 FXS FXOLS (In use) (no pcm) + 42 FXS FXOLS (In use) (no pcm) + 43 FXS FXOLS (In use) (no pcm) + 44 FXS FXOLS (In use) (no pcm) + 45 Output FXOLS (In use) (no pcm) + 46 Output FXOLS (In use) (no pcm) + 47 Input FXOLS (In use) (no pcm) + 48 Input FXOLS (In use) (no pcm) + 49 Input FXOLS (In use) (no pcm) + 50 Input FXOLS (In use) (no pcm) + +The first column is the type of the channel (port, for an analog device) +and the second one is the signalling (if set). + +=head1 FILES + +lszaptel is a somewhat glorified 'cat /proc/zaptel/*' . Unlike that +command, it sorts the spans with the proper order. It also formats the +output slightly differently. diff --git a/xpp/utils/xpp.rules b/xpp/utils/xpp.rules index 10e4c1a..a20acff 100644 --- a/xpp/utils/xpp.rules +++ b/xpp/utils/xpp.rules @@ -1,4 +1,6 @@ BUS!="usb", ACTION!="add", GOTO="xpp_usb_add_end" +KERNEL=="*_ep*", GOTO="xpp_usb_add_end" +KERNEL=="[0-9]*", GOTO="xpp_usb_add_end" # Load firmware into the Xorcom Astribank device: SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[345][01]", \ diff --git a/xpp/utils/xpp_blink b/xpp/utils/xpp_blink index 1993a81..65be247 100755 --- a/xpp/utils/xpp_blink +++ b/xpp/utils/xpp_blink @@ -8,7 +8,8 @@ # $Id$ # use strict; -BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } use Zaptel; use Zaptel::Span; @@ -100,15 +101,18 @@ Blink all the leds of an XPD. =over 16 =item span Select by span number. This only work for XPD registered to zaptel. + will also print the zaptel channels of the span and the + xbus/xpd this span represents. =item xpd Select by xbus + xpd numbers. If only xbus number is given, all the - XPDs of the selected xbus are blinked. + XPDs of the selected xbus (Astribank) are blinked. =back =head1 EXAMPLES $ xpp_blink bzzt span 2 + Using XBUS-04/XPD-10 (connected via usb-0000:00:1d.7-1): channels 15 16 17 18 19 20 21 22 $ xpp_blink xpd 0 1 diff --git a/xpp/utils/xpp_sync b/xpp/utils/xpp_sync index d03c0a4..67825f8 100755 --- a/xpp/utils/xpp_sync +++ b/xpp/utils/xpp_sync @@ -8,7 +8,8 @@ # $Id$ # use strict; -BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } use Zaptel::Xpp; use Zaptel::Xpp::Xbus; @@ -38,10 +39,17 @@ sub get_sorted_xpds() { } } - my @bri_xpds = grep { $_->type =~ /BRI/; } @good_xpds; + my @bri_nt_xpds = grep { $_->type eq 'BRI_NT'; } @good_xpds; + my @bri_te_xpds = grep { $_->type eq 'BRI_TE'; } @good_xpds; my @fxo_xpds = grep { $_->type eq 'FXO'; } @good_xpds; my @fxs_xpds = grep { $_->type eq 'FXS'; } @good_xpds; - return (@bri_xpds, @fxo_xpds, @fxs_xpds); + + # Sync Priority + return + @bri_nt_xpds, + @fxo_xpds, + @bri_te_xpds, + @fxs_xpds; } sub do_select(@) { @@ -88,13 +96,30 @@ sub show_sync() { 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; + my $xpdstr = ''; + my @xpd_types = map { $_->type } sort { $a->num <=> $b->num } @xpds; + my $last_type = ''; + my $mult = 0; + foreach my $curr (@xpd_types) { + if(!$last_type || ($curr eq $last_type)) { + $mult++; + } else { + if($mult == 1) { + $xpdstr .= "$last_type "; + } elsif($mult) { + $xpdstr .= "$last_type*$mult "; + } + $mult = 1; + } + $last_type = $curr; } - print "]"; - my $padding = ' ' x (4 * (8 - @xpds)); - printf "%s (%s)\n", $padding, $xbus->connector; + if($mult == 1) { + $xpdstr .= "$last_type "; + } elsif($mult) { + $xpdstr .= "$last_type*$mult "; + } + my $padding = ' ' x (40 - length $xpdstr); + printf " %1s %s [ %s]%s (%s)\n", $mark, $xbus->name, $xpdstr, $padding, $xbus->connector; } } @@ -135,7 +160,7 @@ __END__ =head1 NAME -xpp_sync - Handle sync selection of Xorcom XPD's. +xpp_sync - Handle sync selection of Xorcom Astribanks. =head1 SYNOPSIS @@ -143,8 +168,15 @@ xpp_sync [auto|host|nn] =head1 DESCRIPTION -Without parameters, the current syncer. Either HOST or the XBUS number. -Then a list of the 3 best XPD's for syncing. +On a normal operation one Astribank device provides timing for all the +other Astribank devices. + +When run without parameters, xpp_sync will display a list of Astribanks +(xbuses) that are connected and registered as Zaptel spans. The current +xpp sync master will be marked (if it is not HOST). + +If you this an Astribank is connected and yet it does not appear on the +output of xpp_sync, it may be unregistered. Try running zt_registration . =head2 Parameters @@ -152,7 +184,7 @@ Then a list of the 3 best XPD's for syncing. =item auto -Automatically selects the best XPD for syncing (with HOST fallback). +Automatically selects the best Astribank for syncing (with HOST fallback). =item host @@ -166,9 +198,27 @@ Set XBUS number nn as sync source. =head2 Example output: - Current sync: 03 + Current sync: 02 Best Available Syncers: - XBUS-00: FXS FXO (USB-0000:00:10.4-4) - + XBUS-03: FXS FXS FXS FXS (USB-0000:00:10.4-1) - XBUS-02: FXS FXS FXS FXS (USB-0000:00:10.4-2) - XBUS-01: FXS FXS FXS FXS (USB-0000:00:10.4-3) + + XBUS-02 [ FXS*3 FXO ] (usb-0000:00:1d.7-3) + XBUS-04 [ FXS*4 ] (usb-0000:00:1d.7-1) + XBUS-03 [ FXS*4 ] (usb-0000:00:1d.7-2) + XBUS-01 [ FXS*4 ] (usb-0000:00:1d.7-4) + XBUS-00 [ FXS*4 ] (usb-0000:00:1d.7-5) + XBUS-05 [ FXS*4 ] (usb-0000:00:1d.7-6) + +In this example we see that the recommended xpp sync master is XBUS-02 - +it is the first on the list. It is also the actual syncer, as we can see +from the '+' beside it. + +=head1 FILES + +=over + +=item /proc/xpp/sync + +xpp_sync is essentially a nicer interface to /proc/xpp/sync . That file +shows the current xpp sync master (and in what format you need to write +to it to set the master). + +=back diff --git a/xpp/utils/zapconf b/xpp/utils/zapconf index 8bcca13..e1a6537 100755 --- a/xpp/utils/zapconf +++ b/xpp/utils/zapconf @@ -5,60 +5,103 @@ # This program is free software; you can redistribute and/or # modify it under the same terms as Perl itself. # -# $Id:$ +# $Id$ # use strict; -BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } use Zaptel; use Zaptel::Xpp; +use Zaptel::Config::Defaults; my %default_context = ( FXO => 'from-pstn', FXS => 'from-internal', IN => 'astbank-input', - OUT => 'astbank-output' + OUT => 'astbank-output', + BRI_TE => 'from-pstn', + BRI_NT => 'from-internal', + PRI_TE => 'from-pstn', + PRI_NT => 'from-internal', ); my %default_group = ( - FXO => '0', - FXS => '5', - IN => '5', - OUT => '5' + FXO => 0, + FXS => 5, + IN => 5, # FIXME: no need for group? + OUT => 5, # FIXME: no need for group? + BRI_TE => 0, + BRI_NT => 5, + PRI_TE => 0, + PRI_NT => 5, ); -my @zaptel_default_vars = qw( - base_exten - lc_country - context_lines - context_phones - context_input - context_output - group_lines - group_phones +my $fxs_default_start = 'ls'; + +my %default_zaptel_signalling = ( + FXO => 'fxsks', + FXS => "fxo$fxs_default_start", + IN => "fxo$fxs_default_start", + OUT => "fxo$fxs_default_start", + ); + +my %default_zapata_signalling = ( + FXO => 'fxs_ks', + FXS => "fxo_$fxs_default_start", + IN => "fxo_$fxs_default_start", + OUT => "fxo_$fxs_default_start", ); +my $base_exten = 4000; my $fxs_immediate = 'no'; -my $fxs_default_start; my $lc_country = 'us'; -my $loadzone; -my $defaultzone; +my $loadzone = $lc_country; +my $defaultzone = $lc_country; +my $bri_sig_style = 'bri_ptmp'; + +my %zaptel_default_vars = ( + base_exten => \$base_exten, + fxs_immediate => \$fxs_immediate, + fxs_default_start => \$fxs_default_start, + lc_country => [ + \$loadzone, + \$defaultzone, + ], + context_lines => \$default_context{FXO}, + context_phones => \$default_context{FXS}, + context_input => \$default_context{IN}, + context_output => \$default_context{OUT}, + group_phones => [ + \$default_group{FXS}, + \$default_group{IN}, + \$default_group{OUT}, + ], + group_lines => \$default_group{FXO}, + ZAPBRI_SIGNALLING => \$bri_sig_style, + ); 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; + foreach my $name (keys %defaults) { + my $val = $defaults{$name}; + my $ref = $zaptel_default_vars{$name}; + my $type = ref $ref; + my @vars = (); + # Some broken shells (msh) export even variables + # That where not defined. Work around that. + next unless defined $val && $val ne ''; + if($type eq 'SCALAR') { + @vars = ($ref); + } elsif($type eq 'ARRAY') { + @vars = @$ref; + } else { + die "$0: Don't know how to map '$name' (type=$type)\n"; + } + foreach my $v (@vars) { + $$v = $val; + } + } } @@ -71,12 +114,25 @@ 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; + my $range_start = $first_num; + my @range; + my $prev = undef; + + die unless $span->is_digital(); + foreach my $c (@{$span->bchan_list()}) { + my $curr = $c + $first_num; + if(!defined($prev)) { + $prev = $curr; + } elsif($curr != $prev + 1) { + push(@range, sprintf("%d-%d", $range_start, $prev)); + $range_start = $curr; + } + $prev = $curr; } - return $range; + if($prev >= $first_num) { + push(@range, sprintf("%d-%d", $range_start, $prev)); + } + return join(',', @range); } sub gen_zaptel_signalling($) { @@ -84,31 +140,26 @@ sub gen_zaptel_signalling($) { 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') { + die "channel $num type $type is not an analog channel\n" if $chan->is_digital(); + if($type eq 'EMPTY') { + printf "# channel %d, %s, no module.\n", $num, $chan->fqn; + return; + } + my $sig = $default_zaptel_signalling{$type} || die "unknown default zaptel signalling for chan $chan type $type"; + if ($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; } + printf "$sig=$num\n"; } my $bri_te_last_timing = 1; sub gen_zaptel_digital($) { my $span = shift || die; - my $num = $span->num(); + my $num = $span->num() || die; + die "Span #$num is analog" unless $span->is_digital(); my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; my $timing; my $lbo = 1; @@ -133,7 +184,7 @@ sub gen_zaptel_digital($) { sub gen_zaptelconf($) { my $file = shift || die; rename "$file", "$file.bak" - or $!{ENOENT} + or $! == 2 # ENOENT (No dependency on Errno.pm) or die "Failed to backup old config: $!\n"; open(F, ">$file") || die "$0: Failed to open $file: $!\n"; my $old = select F; @@ -146,7 +197,7 @@ sub gen_zaptelconf($) { HEAD foreach my $span (@spans) { printf "# Span %d: %s %s\n", $span->num, $span->name, $span->description; - if($span->is_bri()) { + if($span->is_digital()) { gen_zaptel_digital($span); } else { foreach my $chan ($span->chans()) { @@ -172,38 +223,65 @@ TAIL select $old; } +sub gen_zapata_digital($) { + my $span = shift || die; + my $num = $span->num() || die; + die "Span #$num is analog" unless $span->is_digital(); + my $type = $span->type() || die "$0: Span #$num -- unkown type\n"; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $group = $default_group{"$type"}; + my $context = $default_context{"$type"}; + + die "$0: missing default group (termtype=$termtype)\n" unless defined($group); + die "$0: missing default context\n" unless $context; + + my $sig = $span->signalling || die "missing signalling info for span #$num type $type"; + grep($bri_sig_style eq $_, 'bri', 'bri_ptmp', 'pri') or die "unknown signalling style for BRI"; + if($bri_sig_style eq 'bri_ptmp') { + $sig .= '_ptmp'; + } + $group .= "," . (10 + $num); # Invent unique group per span + printf "group=$group\n"; + printf "context=$context\n"; + printf "switchtype = %s\n", $span->switchtype; + printf "signalling = %s\n", $sig; + printf "channel => %s\n", bchan_range($span); + printf "group=\ncontext=default\n"; +} + 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; + die "channel $num type $type is not an analog channel\n" if $chan->is_digital(); + my $exten = $base_exten + $num; + my $sig = $default_zapata_signalling{$type}; my $context = $default_context{$type}; my $group = $default_group{$type}; + my $callerid; + my $immediate; - 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; + return if $type eq 'EMPTY'; + die "missing default_zapata_signalling for chan #$num type $type" unless $sig; + $callerid = ($type eq 'FXO') + ? 'asreceived' + : sprintf "\"Channel %d\" <%04d>", $num, $exten; + if($type eq 'IN') { $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; + # FIXME: $immediage should not be set for 'OUT' channels, but meanwhile + # it's better to be compatible with genzaptelconf + $immediate = 'yes' if $fxs_immediate eq 'yes' and $sig =~ /^fxo_/; + my $signalling = $chan->signalling; + $signalling = " " . $signalling if $signalling; + my $info = $chan->info; + $info = " " . $info if $info; + printf ";;; line=\"%d %s%s%s\"\n", $num, $chan->fqn, $signalling, $info; printf "signalling=$sig\n"; printf "callerid=$callerid\n"; - printf "mailbox=4%03d\n", $num unless $type eq 'FXO'; + printf "mailbox=%04d\n", $exten unless $type eq 'FXO'; if(defined $group) { - printf "group=%d\n", $group; + printf "group=$group\n"; } printf "context=$context\n"; printf "immediate=$immediate\n" if defined $immediate; @@ -222,11 +300,11 @@ sub gen_zapata_channel($) { sub gen_zapataconf($) { my $file = shift || die; rename "$file", "$file.bak" - or $!{ENOENT} + or $! == 2 # ENOENT (No dependency on Errno.pm) 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); + printf "; Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime); print <<"HEAD"; ; Zaptel Channels Configurations (zapata.conf) ; @@ -237,8 +315,12 @@ sub gen_zapataconf($) { 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); + if($span->is_digital()) { + gen_zapata_digital($span); + } else { + foreach my $chan ($span->chans()) { + gen_zapata_channel($chan); + } } print "\n"; } @@ -246,23 +328,6 @@ HEAD 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"; @@ -270,7 +335,9 @@ sub set_defaults { # 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; + %source_defaults = Zaptel::Config::Defaults::do_source( + $defaults, keys(%zaptel_default_vars)) + if -r $defaults; } map_zaptel_defaults(%source_defaults); $zapconf_file = $ENV{ZAPCONF_FILE} || "/etc/zaptel.conf"; @@ -293,3 +360,19 @@ zapconf =head1 DESCRIPTION +This script generate configuration files for Zaptel hardware. +Currently it generate two files: + +=over 4 + +=item /etc/zaptel.conf + +Configuration for ztcfg(1). It's location may be overriden by the +environment variable ZAPCONF_FILE. + +=item /etc/asterisk/zapata-channels.conf + +Configuration for asterisk(1). It should be included in the main /etc/asterisk/zapata.conf. +It's location may be overriden by the environment variable ZAPATA_FILE. + +=back diff --git a/xpp/utils/zaptel_hardware b/xpp/utils/zaptel_hardware index 26aa839..afd3a06 100755 --- a/xpp/utils/zaptel_hardware +++ b/xpp/utils/zaptel_hardware @@ -5,10 +5,11 @@ # This program is free software; you can redistribute and/or # modify it under the same terms as Perl itself. # -# $Id:$ +# $Id$ # use strict; -BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } use Zaptel; use Zaptel::Span; @@ -22,6 +23,8 @@ sub usage { @ARGV == 0 or usage; +Zaptel::Hardware->scan_hardware; + my @hardware = Zaptel::Hardware->devices; my @spans = Zaptel::spans; @@ -89,3 +92,8 @@ zaptel_hardware Show all zaptel hardware devices, both used and unused. +=head1 BUGS + +Assumes a bit too much about the output of lspci and sysfs. Currently +the PCI scanning will not work on e.g. CentOS 4. This should be fixed in +Zaptel::Hardware::PCI.pm diff --git a/xpp/utils/zconf/Zaptel/Chans.pm b/xpp/utils/zconf/Zaptel/Chans.pm index eef922f..f50d212 100644 --- a/xpp/utils/zconf/Zaptel/Chans.pm +++ b/xpp/utils/zconf/Zaptel/Chans.pm @@ -39,6 +39,21 @@ sub new($$$$$$) { my $type; if($fqn =~ m|\bXPP_(\w+)/.*$|) { $type = $1; # One of our AB + } elsif ($fqn =~ m{\b(TE[24]|WCT1|Tor2|TorISA|WP[TE]1|cwain[12])/.*}) { + # TE[24]: Digium wct4xxp + # WCT1: Digium single span card drivers? + # Tor2: Tor PCI cards + # TorISA: ISA ones (still used?) + # WP[TE]1: Sangoma. TODO: this one tells us if it is TE or NT. + # cwain: Junghanns E1 card. + $type = "PRI"; + } elsif ($fqn =~ m{\b(ZTHFC%d*|ztqoz\d*)/.*}) { + # ZTHFC: HFC-s single-port card (zaphfc/vzaphfc) + # ztqoz: qozap (Junghanns) multi-port HFC card + $type = "BRI"; + } elsif ($fqn =~ m{\bztgsm/.*}) { + # Junghanns GSM card + $type = "GSM"; } elsif(defined $signalling) { $type = 'FXS' if $signalling =~ /^FXS/; $type = 'FXO' if $signalling =~ /^FXO/; diff --git a/xpp/utils/zconf/Zaptel/Config/Defaults.pm b/xpp/utils/zconf/Zaptel/Config/Defaults.pm new file mode 100644 index 0000000..90b49ab --- /dev/null +++ b/xpp/utils/zconf/Zaptel/Config/Defaults.pm @@ -0,0 +1,29 @@ +package Zaptel::Config::Defaults; +# +# 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 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 -ec '. $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; +} + +1; diff --git a/xpp/utils/zconf/Zaptel/Hardware.pm b/xpp/utils/zconf/Zaptel/Hardware.pm index 321292a..39305fb 100644 --- a/xpp/utils/zconf/Zaptel/Hardware.pm +++ b/xpp/utils/zconf/Zaptel/Hardware.pm @@ -34,7 +34,11 @@ sub devices($) { return @zaptel_devices; } -Zaptel::Hardware::USB->scan_devices; -Zaptel::Hardware::PCI->scan_devices; +sub scan_hardware($) { + my $pack = shift || die; + + 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 index c6731dc..48fa810 100644 --- a/xpp/utils/zconf/Zaptel/Hardware/PCI.pm +++ b/xpp/utils/zconf/Zaptel/Hardware/PCI.pm @@ -11,6 +11,7 @@ use strict; use Zaptel::Hardware; my @idlist = qw( + 0B0B:0206 1397:16B8 1397:08B4 1057:5608 diff --git a/xpp/utils/zconf/Zaptel/Span.pm b/xpp/utils/zconf/Zaptel/Span.pm index 8496910..47a5a56 100644 --- a/xpp/utils/zconf/Zaptel/Span.pm +++ b/xpp/utils/zconf/Zaptel/Span.pm @@ -46,28 +46,51 @@ my @bri_strings = ( 'HFC-S PCI A ISDN.* \[(NT|TE)\] ' ); +my @pri_strings = ( + 'PRI_(NT|TE)' + ); + our $ZAPBRI_NET = 'bri_net'; our $ZAPBRI_CPE = 'bri_cpe'; +our $ZAPPRI_NET = 'pri_net'; +our $ZAPPRI_CPE = 'pri_cpe'; + sub new($$) { my $pack = shift or die "Wasn't called as a class method\n"; my $num = shift or die "Missing a span number parameter\n"; my $self = { NUM => $num }; bless $self, $pack; + $self->{TYPE} = "UNKNOWN"; open(F, "$proc_base/$num") or die "Failed to open '$proc_base/$num\n"; my $head = <F>; chomp $head; foreach my $cardtype (@bri_strings) { if($head =~ m/$cardtype/) { + $self->{IS_DIGITAL} = 1; $self->{IS_BRI} = 1; $self->{TERMTYPE} = $1; + $self->{TYPE} = "BRI_$1"; $self->{DCHAN_IDX} = 2; $self->{BCHAN_LIST} = [ 0, 1 ]; last; } } + foreach my $cardtype (@pri_strings) { + if($head =~ m/$cardtype/) { + $self->{IS_DIGITAL} = 1; + $self->{IS_PRI} = 1; + $self->{TERMTYPE} = $1; + $self->{TYPE} = "PRI_$1"; + { + $self->{DCHAN_IDX} = 15; # Depends on E1/T1/J1 + $self->{BCHAN_LIST} = [ 0 .. 14, 16 .. 30 ]; + } + last; + } + } die "$0: Unkown TERMTYPE [NT/TE]\n" - if $self->is_bri and !defined $self->{TERMTYPE}; + if $self->is_digital and !defined $self->{TERMTYPE}; ($self->{NAME}, $self->{DESCRIPTION}) = (split(/\s+/, $head, 4))[2, 3]; $self->{IS_ZAPTEL_SYNC_MASTER} = ($self->{DESCRIPTION} =~ /\(MASTER\)/) ? 1 : 0; @@ -99,6 +122,15 @@ sub new($$) { $self->{SIGNALLING} = 'gsm'; } } + if($self->is_pri()) { + $self->{DCHAN} = ($self->chans())[$self->{DCHAN_IDX}]; + $self->{BCHANS} = [ ($self->chans())[@{$self->{BCHAN_LIST}}] ]; + $self->{CODING} = 'hdb3'; + $self->{YELLOW} = undef; + $self->{FRAMING} = 'ccs'; + $self->{SIGNALLING} = ($self->{TERMTYPE} eq 'NT') ? $ZAPPRI_NET : $ZAPPRI_CPE ; + $self->{SWITCHTYPE} = 'euroisdn'; + } return $self; } diff --git a/xpp/utils/zt_registration b/xpp/utils/zt_registration index d6d0278..9a8323f 100755 --- a/xpp/utils/zt_registration +++ b/xpp/utils/zt_registration @@ -8,7 +8,8 @@ # $Id$ # use strict; -BEGIN { my $dir = $0; $dir =~ s:/[^/]+$::; unshift(@INC, "$dir", "$dir/zconf"); } +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } use Zaptel; use Zaptel::Span; @@ -73,7 +74,7 @@ zt_registration [on|off] =head1 DESCRIPTION -Without parameters, show all connected XPD's sorted by physical connector order. +Without parameters, show all connected XPDs sorted by physical connector order. Each one is show to be unregistered (off), or registered to a specific zaptel span (the span number is shown). @@ -84,3 +85,39 @@ All registerations/deregisterations are sorted by physical connector string. off -- deregisters all XPD's from zaptel. on -- registers all XPD's to zaptel. + +=head2 Sample Output + + $ zt_registration + XBUS-02 usb-0000:00:1d.7-3 + XBUS-02/XPD-00: on Span 9 + XBUS-02/XPD-10: on Span 10 + XBUS-02/XPD-20: on Span 11 + XBUS-02/XPD-30: on Span 12 + XBUS-01 usb-0000:00:1d.7-4 + XBUS-01/XPD-00: on Span 13 + XBUS-01/XPD-10: on Span 14 + XBUS-01/XPD-20: on Span 15 + XBUS-01/XPD-30: on Span 16 + XBUS-00 usb-0000:00:1d.7-5 + XBUS-00/XPD-00: on Span 17 + XBUS-00/XPD-10: on Span 18 + XBUS-00/XPD-20: on Span 19 + XBUS-00/XPD-30: on Span 20 + +=head1 FILES + +=over + +=item /proc/xpp/XBUS-nn/XPD-mm/zt_registration + +Reading from this file shows if if the if the specific XPD is +registered. Writing to it 0 or 1 registers / unregisters the device. + +This should allow you to register / unregister a specific XPD rather +than all of them. + +Unregistering an XPD will fail if the span is in use (has some channels +that are in use by e.g. Asterisk). + +=back |