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