summaryrefslogtreecommitdiff
path: root/xpp/utils/zapconf
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/utils/zapconf')
-rwxr-xr-xxpp/utils/zapconf275
1 files changed, 179 insertions, 96 deletions
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