From c88eaa22e13bd4c092b367a28e57064659660466 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Thu, 2 Aug 2007 12:21:11 +0000 Subject: Merge xpp r4372: * Update to zaptel-1.2.18 and zaptel-1.4.3 (r4308 onward) * Fix a critical race with zaptel synchronization (r4362) * Added a /proc/xpp/cmds for statistics about command timing (r4360) * Fix a digit mapping bug with hardware dtmf detection (r4357) * In xpp/utils/Makefile add perl syntax checks to our scripts (r4337) * Better USB data error checking (r4336) * udev rules (xpp.rules) avoid false calls from wrong nodes (r4331) * Improve hardware detection and reporting in lszaptel, zaptel_hardware. zapconf is basically functional. * Leds are blinked synchronously on all Astribanks now (r4262) * Fix a BRI bug if OPTIMIZE_CHANMUTE was compiled into zaptel (r4258) (This feature was not yet accepted into official zaptel) * Removed compile warning about HZ != 1000 (r4218) * Firmware updates. * fpga_load now supports USB pathes without zeros (r4211) * XPD numbers have changed to '' (r4196) * Proper support for ZT_VMWI ioctl, if used in zaptel (r4092) * Fix FXO power denial detection (r4054) * FXO could accidentally go off-hook with some compilers (r4048) (From branches/1.2 r2732, r2735 - branches/1.4 2736) git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2813 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/utils/zapconf | 275 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 179 insertions(+), 96 deletions(-) (limited to 'xpp/utils/zapconf') 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 -- cgit v1.2.3