summaryrefslogtreecommitdiff
path: root/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zaptel.pm
blob: 892442ff313ef788c96f7f295c07a764d62fe32a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package Zaptel::Config::Gen::Zaptel;
use strict;

use Zaptel::Config::Gen qw(is_true);

sub new($$$) {
	my $pack = shift || die;
	my $gconfig = shift || die;
	my $genopts = shift || die;
	my $file = $ENV{ZAPCONF_FILE} || "/etc/zaptel.conf";
	my $self = {
			FILE	=> $file,
			GCONFIG	=> $gconfig,
			GENOPTS	=> $genopts,
		};
	bless $self, $pack;
	return $self;
}

my $bri_te_last_timing = 1;

sub gen_digital($$) {
	my $gconfig = shift || die;
	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" : '';
	# "MFC/R2 does not normally use CRC4"
	# FIXME: a finer way to override:
	if ($gconfig->{'pri_connection_type'} eq 'R2') { 
		$span_crc4 = '';
		$framing = 'cas';
	}
	$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);
	my $dchan_type;
	if ($span->is_bri()) {
		my $use_bristuff = 0;
		my $cfg_hardhdlc = $gconfig->{'bri_hardhdlc'};
		my $xpd = $span->xpd();
		if(!defined($cfg_hardhdlc) || $cfg_hardhdlc =~ /AUTO/i) {
			# Autodetect
			if(defined($xpd)) {
				# Bristuff?
				if(defined($xpd->dchan_hardhdlc) && !is_true($xpd->dchan_hardhdlc)) {
					$use_bristuff = 1;
				}
			}
		} elsif(!is_true($cfg_hardhdlc)) {
			$use_bristuff = 1;
		}
		if($use_bristuff) {
			$dchan_type = 'dchan';
		} else {
			$dchan_type = 'hardhdlc';
		}
		printf "bchan=%s\n", Zaptel::Config::Gen::bchan_range($span);
		my $dchan = $span->dchan();
		printf "$dchan_type=%d\n", $dchan->num();
	} elsif($span->is_pri()) {
		if ($gconfig->{'pri_connection_type'} eq 'PRI') {
			printf "bchan=%s\n", Zaptel::Config::Gen::bchan_range($span);
			my $dchan = $span->dchan();
			printf "dchan=%d\n", $dchan->num();
		} elsif ($gconfig->{'pri_connection_type'} eq 'R2' ) {
			my $idle_bits = $gconfig->{'r2_idle_bits'};
			printf "cas=%s:$idle_bits\n", Zaptel::Config::Gen::bchan_range($span);
			printf "dchan=%d\n", $span->dchan()->num();
		}
	} else {
		die "Digital span $num is not BRI, nor PRI?";
	}
}

sub gen_signalling($$) {
	my $gconfig = shift || die;
	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 $signalling = $gconfig->{'zaptel_signalling'};
	my $sig = $signalling->{$type} || die "unknown default zaptel signalling for chan $num type $type";
	if ($type eq 'IN') {
		printf "# astbanktype: input\n";
	} elsif ($type eq 'OUT') {
		printf "# astbanktype: output\n";
	}
	printf "$sig=$num\n";
}

sub generate($$$) {
	my $self = shift || die;
	my $file = $self->{FILE};
	my $gconfig = $self->{GCONFIG};
	my $genopts = $self->{GENOPTS};
	my @spans = @_;
	warn "Empty configuration -- no spans\n" unless @spans;
	rename "$file", "$file.bak"
		or $! == 2	# ENOENT (No dependency on Errno.pm)
		or die "Failed to backup old config: $!\n";
	#$gconfig->dump;
	print "Generating $file\n" if $genopts->{verbose};
	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
	my $old = select F;
	printf "# Autogenerated by $0 on %s\n", scalar(localtime);
	print  "# If you edit this file and execute $0 again,\n";
	print  "# your manual changes will be LOST.\n";
	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_digital($gconfig, $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_signalling($gconfig, $chan);
			}
		}
		print "\n";
	}
	print <<"TAIL";
# Global data

loadzone	= $gconfig->{'loadzone'}
defaultzone	= $gconfig->{'defaultzone'}
TAIL
	close F;
	select $old;
}

1;

__END__

=head1 NAME

zaptel - Generate configuration for zaptel drivers.

=head1 SYNOPSIS

 use Zaptel::Config::Gen::Zaptel;

 my $cfg = new Zaptel::Config::Gen::Zaptel(\%global_config, \%genopts);
 $cfg->generate(@span_list);

=head1 DESCRIPTION

Generate the F</etc/zaptel.conf>.
This is the configuration for ztcfg(1).

Its location may be overriden via the environment variable F<ZAPCONF_FILE>.