summaryrefslogtreecommitdiff
path: root/xpp/dahdi_genconf
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2008-06-19 17:23:15 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2008-06-19 17:23:15 +0000
commitc1ae88873823bdc2d884f72cc2b06eab017b97b1 (patch)
tree07db658e30eb6837646bb5ced9d82e9372b5bd11 /xpp/dahdi_genconf
parente78c863ec69587ffb55e44abc0641f5c392a08f3 (diff)
XPP utilities rename: first moves.
git-svn-id: http://svn.asterisk.org/svn/dahdi/tools/trunk@4415 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'xpp/dahdi_genconf')
-rwxr-xr-xxpp/dahdi_genconf603
1 files changed, 603 insertions, 0 deletions
diff --git a/xpp/dahdi_genconf b/xpp/dahdi_genconf
new file mode 100755
index 0000000..7f94f6b
--- /dev/null
+++ b/xpp/dahdi_genconf
@@ -0,0 +1,603 @@
+#! /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;
+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',
+ BRI_TE => 'from-pstn',
+ BRI_NT => 'from-internal',
+ E1_TE => 'from-pstn',
+ T1_TE => 'from-pstn',
+ J1_TE => 'from-pstn',
+ E1_NT => 'from-internal',
+ T1_NT => 'from-internal',
+ J1_NT => 'from-internal',
+ );
+
+my %default_group = (
+ FXO => 0,
+ FXS => "5",
+ IN => '',
+ OUT => '',
+ BRI_TE => 0,
+ BRI_NT => 6,
+ E1_TE => 0,
+ T1_TE => 0,
+ J1_TE => 0,
+ E1_NT => 6,
+ T1_NT => 6,
+ J1_NT => 6,
+ );
+
+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 $lc_country = 'us';
+my $loadzone = $lc_country;
+my $defaultzone = $lc_country;
+my $bri_sig_style = 'bri_ptmp';
+my $brint_overlap = 'no';
+
+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,
+ brint_overlap => \$brint_overlap,
+ );
+
+sub map_zaptel_defaults {
+ my %defaults = @_;
+ 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;
+ }
+ }
+}
+
+
+my $zapconf_file;
+my $zapatachannels_file;
+my $users_file;
+my $zapataconf_file;
+
+my %files = (
+ zaptel => { file => \$zapconf_file, func => \&gen_zaptelconf },
+ zapata => { file => \$zapatachannels_file, func => \&gen_zapatachannelsconf },
+ users => { file => \$users_file, func => \&gen_usersconf },
+ zapataconf => { file => \$zapataconf_file, func => \&gen_zapataconf },
+);
+
+my @default_files = ("zaptel", "zapata");
+
+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_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;
+ }
+ if($prev >= $first_num) {
+ push(@range, sprintf("%d-%d", $range_start, $prev));
+ }
+ return join(',', @range);
+}
+
+sub gen_zaptel_signalling($) {
+ my $chan = shift || die;
+ my $type = $chan->type;
+ my $num = $chan->num;
+
+ die "channel $num type $type is not an analog channel\n" if $chan->span->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";
+ } elsif ($type eq 'OUT') {
+ printf "# astbanktype: output\n";
+ }
+ printf "$sig=$num\n";
+}
+
+my $bri_te_last_timing = 1;
+
+sub gen_zaptel_digital($) {
+ my $span = shift || die;
+ 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 = 0;
+ 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_crc4 = $span->crc4();
+ $span_crc4 = (defined $span_crc4) ? ",$span_crc4" : '';
+ 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%s%s\n",
+ $num,
+ $timing,
+ $lbo,
+ $framing,
+ $coding,
+ $span_crc4,
+ $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 $! == 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);
+ 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_digital()) {
+ 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;
+}
+
+my %DefaultConfigs = (
+ context => 'default',
+ group => '63', # FIXME: should not be needed.
+ overlapdial => 'no',
+ busydetect => 'no',
+ rxgain => 0,
+ txgain => 0,
+);
+
+sub reset_zapata_values {
+ foreach my $arg (@_) {
+ if (exists $DefaultConfigs{$arg}) {
+ print "$arg = $DefaultConfigs{$arg}\n";
+ } else {
+ print "$arg =\n";
+ }
+ }
+}
+
+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"};
+ my @to_reset = qw/context group/;
+
+ 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($span->is_bri() and $bri_sig_style eq 'bri_ptmp') {
+ $sig .= '_ptmp';
+ }
+ if ($span->is_bri() && $termtype eq 'NT' && $brint_overlap eq 'yes') {
+ print "overlapdial = yes\n";
+ push(@to_reset, qw/overlapdial/);
+ }
+
+ $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);
+ reset_zapata_values(@to_reset);
+}
+
+sub gen_zapata_channel($) {
+ my $chan = shift || die;
+ my $type = $chan->type;
+ my $num = $chan->num;
+ die "channel $num type $type is not an analog channel\n" if $chan->span->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;
+
+ 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';
+ }
+ # 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=%04d\n", $exten unless $type eq 'FXO';
+ if(defined $group) {
+ printf "group=$group\n";
+ }
+ 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_zapatachannelsconf($) {
+ my $file = shift || die;
+ rename "$file", "$file.bak"
+ 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);
+ 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;
+ if($span->is_digital()) {
+ gen_zapata_digital($span);
+ } else {
+ foreach my $chan ($span->chans()) {
+ gen_zapata_channel($chan);
+ }
+ }
+ print "\n";
+ }
+ close F;
+ select $old;
+}
+
+sub gen_users_channel($) {
+ my $chan = shift || die;
+ my $type = $chan->type;
+ my $num = $chan->num;
+ die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
+ my $exten = $base_exten + $num;
+ my $sig = $default_zapata_signalling{$type};
+ my $full_name = "$type $num";
+
+ die "missing default_zapata_signalling for chan #$num type $type" unless $sig;
+ print << "EOF";
+[$exten]
+callwaiting = yes
+context = numberplan-custom-1
+fullname = $full_name
+cid_number = $exten
+hasagent = no
+hasdirectory = no
+hasiax = no
+hasmanager = no
+hassip = no
+hasvoicemail = yes
+host = dynamic
+mailbox = $exten
+threewaycalling = yes
+vmsecret = 1234
+secret = 1234
+signalling = $sig
+zapchan = $num
+registeriax = no
+registersip = no
+canreinvite = no
+nat = no
+dtmfmode = rfc2833
+disallow = all
+allow = all
+
+EOF
+}
+
+# generate users.conf . The specific users.conf is strictly oriented
+# towards using with the asterisk-gui .
+#
+# This code could have generated a much simpler and smaller
+# configuration file, had there been minimal level of support for
+# configuration templates in the asterisk configuration rewriting. Right
+# now Asterisk's configuration rewriting simply freaks out in the face
+# of templates: http://bugs.digium.com/11442 .
+sub gen_usersconf($) {
+ my $file = shift || die;
+ rename "$file", "$file.bak"
+ 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;
+ print <<"HEAD";
+;!
+;! Automatically generated configuration file
+;! Filename: @{[basename($file)]} ($file)
+;! Generator: $0
+;! Creation Date: @{[scalar(localtime)]}
+;!
+[general]
+;
+; Full name of a user
+;
+fullname = New User
+;
+; Starting point of allocation of extensions
+;
+userbase = @{[$base_exten+1]}
+;
+; Create voicemail mailbox and use use macro-stdexten
+;
+hasvoicemail = yes
+;
+; Set voicemail mailbox @{[$base_exten+1]} password to 1234
+;
+vmsecret = 1234
+;
+; Create SIP Peer
+;
+hassip = no
+;
+; Create IAX friend
+;
+hasiax = no
+;
+; Create Agent friend
+;
+hasagent = no
+;
+; Create H.323 friend
+;
+;hash323 = yes
+;
+; Create manager entry
+;
+hasmanager = no
+;
+; Remaining options are not specific to users.conf entries but are general.
+;
+callwaiting = yes
+threewaycalling = yes
+callwaitingcallerid = yes
+transfer = yes
+canpark = yes
+cancallforward = yes
+callreturn = yes
+callgroup = 1
+pickupgroup = 1
+localextenlength = @{[length($base_exten)]}
+
+
+HEAD
+ foreach my $span (@spans) {
+ next unless grep { $_ eq $span->type} ( 'FXS', 'IN', 'OUT' );
+ printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
+ foreach my $chan ($span->chans()) {
+ gen_users_channel($chan);
+ }
+ print "\n";
+ }
+ close F;
+ select $old;
+}
+
+sub gen_zapataconf($) {
+ my $file = shift || die;
+ open(F, ">>$file") || die "$0: Failed to open $file: $!\n";
+ my $old = select F;
+ foreach my $span (@spans) {
+ next unless $span->type eq 'FXO';
+ my $current_sig = "";
+ for my $chan ($span->chans()) {
+ my $chan_num = $chan->num;
+ if ($default_zapata_signalling{$chan->type} ne $current_sig) {
+ $current_sig = $default_zapata_signalling{$chan->type};
+ print "\nsignalling = $current_sig";
+ print "\nchannel => $chan_num";
+ } else {
+ print ",$chan_num";
+ }
+ }
+ print "\n";
+ }
+ close F;
+ select $old;
+}
+
+sub set_defaults {
+ # Source default files
+ my ($default_file, %source_defaults) =
+ Zaptel::Config::Defaults::source_vars(keys(%zaptel_default_vars));
+ map_zaptel_defaults(%source_defaults);
+ # Fixups
+ foreach my $val (values %default_zaptel_signalling, values %default_zapata_signalling) {
+ $val =~ s/{fxs_default_start}/$fxs_default_start/g;
+ }
+ $zapconf_file = $ENV{ZAPCONF_FILE} || "/etc/zaptel.conf";
+ $zapatachannels_file = $ENV{ZAPATA_FILE} || "/etc/asterisk/zapata-channels.conf";
+ $users_file = $ENV{USERS_FILE} || "/etc/asterisk/users.conf";
+ $zapataconf_file = $ENV{ZAPATACONF_FILE} || "/etc/asterisk/zapata.conf";
+}
+
+sub parse_args {
+ return if @ARGV == 0;
+ @default_files = ();
+ for my $file (@ARGV) {
+ die "$0: Unknown file '$file'" unless defined $files{$file};
+ push @default_files, $file;
+ }
+}
+
+sub generate_files {
+ for my $file (@default_files) {
+ &{$files{$file}->{func}}(${$files{$file}->{file}});
+ }
+}
+set_defaults;
+parse_args;
+generate_files;
+
+__END__
+
+=head1 NAME
+
+zapconf - Generate configuration for zaptel channels.
+
+=head1 SYNOPSIS
+
+zapconf [FILES...]
+
+=head1 DESCRIPTION
+
+This script generate configuration files for Zaptel hardware.
+Currently it can generate three files: zaptel, zapata, users and zapataconf (see below).
+Without arguments, it generates only zaptel and zapata.
+
+=over 4
+
+=item zaptel - /etc/zaptel.conf
+
+Configuration for ztcfg(1). It's location may be overriden by the
+environment variable ZAPCONF_FILE.
+
+=item zapata - /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.
+
+=item users - /etc/asterisk/users.conf
+
+Configuration for asterisk(1) and AsteriskGUI.
+It's location may be overriden by the environment variable USERS_FILE.
+
+=item zapataconf - /etc/asterisk/zapata.conf
+
+Configuration for asterisk(1) and AsteriskGUI.
+It's location may be overriden by the environment variable ZAPATACONF_FILE.
+
+
+=back