lib/Asterisk/Conf/Zapata.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 21 | 175 | 12.0 |
branch | 0 | 80 | 0.0 |
condition | 1 | 27 | 3.7 |
subroutine | 4 | 13 | 30.7 |
pod | 0 | 8 | 0.0 |
total | 26 | 303 | 8.5 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Asterisk::Conf::Zapata; | ||||||
2 | |||||||
3 | require 5.004; | ||||||
4 | |||||||
5 | =head1 NAME | ||||||
6 | |||||||
7 | Asterisk::Config::Zapata - Zapata configuration stuff | ||||||
8 | |||||||
9 | =head1 SYNOPSIS | ||||||
10 | |||||||
11 | stuff goes here | ||||||
12 | |||||||
13 | =head1 DESCRIPTION | ||||||
14 | |||||||
15 | description | ||||||
16 | |||||||
17 | =over 4 | ||||||
18 | |||||||
19 | =cut | ||||||
20 | |||||||
21 | 1 | 1 | 604 | use Asterisk; | |||
1 | 2 | ||||||
1 | 21 | ||||||
22 | 1 | 1 | 236 | use Asterisk::Conf; | |||
1 | 2 | ||||||
1 | 1733 | ||||||
23 | @ISA = ('Asterisk::Conf'); | ||||||
24 | |||||||
25 | $VERSION = '0.01'; | ||||||
26 | |||||||
27 | $DEBUG = 5; | ||||||
28 | |||||||
29 | sub new { | ||||||
30 | 1 | 1 | 0 | 289 | my ($class, %args) = @_; | ||
31 | 1 | 2 | my $self = {}; | ||||
32 | 1 | 2 | $self->{'name'} = 'Zapata'; | ||||
33 | 1 | 1 | $self->{'description'} = 'Zaptel Channel Driver Configuration'; | ||||
34 | 1 | 1 | $self->{'configfile'} = '/etc/asterisk/zapata.conf'; | ||||
35 | 1 | 1 | $self->{'config'} = {}; | ||||
36 | 1 | 1 | $self->{'configtemp'} = {}; | ||||
37 | 1 | 2 | $self->{'contextorder'} = ( 'channels' ); | ||||
38 | 1 | 1 | $self->{'channelgroup'} = {}; | ||||
39 | |||||||
40 | 1 | 45 | $self->{'variables'} = { | ||||
41 | 'language' => { 'default' => 'en', 'type' => 'text', 'regex' => '^\w\w$' }, | ||||||
42 | 'context' => { 'default' => 'default', 'type' => 'text', 'regex' => '^\w*$' }, | ||||||
43 | 'switchtype' => { 'default' => 'national', 'type' => 'one', 'values' => [ 'national', 'dms100', '4ess', '5ess', 'euroisdn'] }, | ||||||
44 | 'signalling' => { 'default' => 'fxo_ls', 'type' => 'one', 'values' => ['em', 'em_w', 'featd', 'featdmf', 'featb', 'fxs_ls', 'fxs_gs', 'fxs_ks', 'fxo_ls', 'fxo_gs', 'gxo', 'ks', 'pri_cpe', 'pri_net'] }, | ||||||
45 | 'prewink' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
46 | 'preflash' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
47 | 'wink' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
48 | 'flash' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
49 | 'start' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
50 | 'rxwink' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
51 | 'rxflash' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
52 | 'debounce' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
53 | 'rxwink' => { 'default' => '300', 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
54 | 'usecallerid' => { 'default' => 'yes', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
55 | 'hidecallerid' => { 'default' => 'no', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
56 | 'callwaiting' => { 'default' => 'yes', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
57 | 'callwaitingcallerid' => { 'default' => 'yes', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
58 | 'threewaycalling' => { 'default' => 'yes', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
59 | 'transfer' => { 'default' => 'yes', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
60 | 'cancallforward' => { 'default' => 'yes', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
61 | 'mailbox' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
62 | 'echocancel' => { 'default' => 'yes', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
63 | 'echocancelwhenbridged' => { 'default' => 'no', 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
64 | 'rxgain' => { 'default' => '0.0', 'type' => 'text', 'regex' => '^[\d\.]*$' }, | ||||||
65 | 'txgain' => { 'default' => '0.0', 'type' => 'text', 'regex' => '^[\d\.]*$' }, | ||||||
66 | 'group' => { 'default' => '1', 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
67 | 'immediate' => { 'default' => undef, 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
68 | 'callerid' => { 'default' => undef, 'type' => 'text', 'regex' => '^.*$' }, | ||||||
69 | 'amaflags' => { 'default' => undef, 'type' => 'one', 'values' => ['default', 'omit', 'billing', 'documentation'] }, | ||||||
70 | 'accountcode' => { 'default' => undef, 'type' => 'text', 'regex' => '^\w*$' }, | ||||||
71 | 'adsi' => { 'default' => undef, 'type' => 'one', 'values' => ['yes', 'no'] }, | ||||||
72 | 'musiconhold' => { 'default' => undef, 'type' => 'text', '^\w*$' }, | ||||||
73 | |||||||
74 | 'idledial' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
75 | 'idleext' => { 'default' => undef, 'type' => 'text', 'regex' => '^\w*$' }, | ||||||
76 | 'minunused' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
77 | 'minidle' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' }, | ||||||
78 | |||||||
79 | 'channel' => { 'default' => undef, 'type' => 'text', 'regex' => '^[\d\,\-]*$' }, | ||||||
80 | 'stripmsd' => { 'default' => undef, 'type' => 'text', 'regex' => '^\d*$' } | ||||||
81 | }; | ||||||
82 | |||||||
83 | |||||||
84 | 1 | 33 | 7 | bless $self, ref $class || $class; | |||
85 | # while (my ($key,$value) = each %args) { $self->set($key,$value); } | ||||||
86 | 1 | 2 | return $self; | ||||
87 | } | ||||||
88 | |||||||
89 | 0 | sub DESTROY { } | |||||
90 | |||||||
91 | sub _setvar { | ||||||
92 | 0 | 0 | 0 | my ($self, $context, $var, $val, $order, $precomment, $postcomment) = @_; | |||
93 | |||||||
94 | 0 | 0 | $self->{'configtemp'}{$context}{$var}{val} = $val; | ||||
95 | 0 | 0 | $self->{'configtemp'}{$context}{$var}{precomment} = $precomment; | ||||
96 | 0 | 0 | $self->{'configtemp'}{$context}{$var}{postcomment} = $postcomment; | ||||
97 | 0 | 0 | $self->{'configtemp'}{$context}{$var}{order} = $order; | ||||
98 | |||||||
99 | } | ||||||
100 | |||||||
101 | sub _group { | ||||||
102 | 0 | 0 | 0 | my ($self, $context, $channels) = @_; | |||
103 | |||||||
104 | 0 | 0 | 0 | if ($channels) { | |||
105 | 0 | 0 | push(@{$self->{channelgroup}{$context}}, $channels); | ||||
0 | 0 | ||||||
106 | } else { | ||||||
107 | 0 | 0 | return @{$self->{channelgroup}{$context}}; | ||||
0 | 0 | ||||||
108 | } | ||||||
109 | } | ||||||
110 | |||||||
111 | sub channels { | ||||||
112 | 0 | 0 | 0 | 0 | my ($self, $context, $channels, $order, $precomment, $postcomment) = @_; | ||
113 | |||||||
114 | 0 | 0 | my @chans = (); | ||||
115 | 0 | 0 | my $channel = ''; | ||||
116 | 0 | 0 | my $x; | ||||
117 | |||||||
118 | 0 | 0 | $self->_group($context, $channels); | ||||
119 | 0 | 0 | 0 | if ($channels =~ /(\d+)\-(\d+)/) { | |||
0 | |||||||
0 | |||||||
120 | 0 | 0 | my $beg = $1; my $end = $2; | ||||
0 | 0 | ||||||
121 | 0 | 0 | 0 | if ($end > $beg) { | |||
122 | 0 | 0 | for ($x = $beg; $x <= $end; $x++) { | ||||
123 | 0 | 0 | push(@chans, $x); | ||||
124 | } | ||||||
125 | } | ||||||
126 | } elsif ($channels =~ /^(\d*)$/) { | ||||||
127 | 0 | 0 | push(@chans, $channels); | ||||
128 | } elsif ($channels =~ /^\d*,/) { | ||||||
129 | 0 | 0 | push(@chans, split(/,/, $channels)); | ||||
130 | } else { | ||||||
131 | 0 | 0 | 0 | print STDERR "channels got here: $channels\n" if ($DEBUG); | |||
132 | } | ||||||
133 | 0 | 0 | @chans = ( $channels ); | ||||
134 | 0 | 0 | foreach $channel (@chans) { | ||||
135 | |||||||
136 | # $self->{'config'}{$context}{$channel}{'channel'} = $channel; | ||||||
137 | 0 | 0 | foreach $var (keys %{$self->{'configtemp'}{$context}}) { | ||||
0 | 0 | ||||||
138 | 0 | 0 | $self->{'config'}{$context}{$channel}{$var}{precomment} = $self->{'configtemp'}{$context}{$var}{precomment}; | ||||
139 | 0 | 0 | $self->{'config'}{$context}{$channel}{$var}{postcomment} = $self->{'configtemp'}{$context}{$var}{postcomment}; | ||||
140 | 0 | 0 | $self->{'config'}{$context}{$channel}{$var}{val} = $self->{'configtemp'}{$context}{$var}{val}; | ||||
141 | 0 | 0 | $self->{'config'}{$context}{$channel}{$var}{order} = $self->{'configtemp'}{$context}{$var}{order}; | ||||
142 | } | ||||||
143 | } | ||||||
144 | |||||||
145 | } | ||||||
146 | |||||||
147 | sub readconfig { | ||||||
148 | 0 | 0 | 0 | 0 | my ($self) = @_; | ||
149 | |||||||
150 | 0 | 0 | my $context = ''; | ||||
151 | 0 | 0 | my $line = ''; | ||||
152 | 0 | 0 | my $precomment = ''; | ||||
153 | 0 | 0 | my $postcomment = ''; | ||||
154 | |||||||
155 | 0 | 0 | my $configfile = $self->configfile(); | ||||
156 | 0 | 0 | my $contextorder = 0; | ||||
157 | 0 | 0 | my $order = 0; | ||||
158 | |||||||
159 | 0 | 0 | 0 | open(CF, "<$configfile") || die "Error loading $configfile: $!\n"; | |||
160 | 0 | 0 | while ($line = |
||||
161 | # chop($line); | ||||||
162 | |||||||
163 | |||||||
164 | #deal with comments | ||||||
165 | 0 | 0 | 0 | if ($line =~ /^;/) { | |||
0 | |||||||
0 | |||||||
0 | |||||||
166 | 0 | 0 | $precomment .= $line; | ||||
167 | 0 | 0 | next; | ||||
168 | } elsif ($line =~ /^;ACZ(\w*):\s*(.*)/) { | ||||||
169 | 0 | 0 | print STDERR "ACZ Variable $1 = $2\n"; | ||||
170 | 0 | 0 | next; | ||||
171 | } elsif ($line =~ /(;.*)$/) { | ||||||
172 | 0 | 0 | $postcomment .= $1; | ||||
173 | 0 | 0 | $line =~ s/;.*$//; | ||||
174 | } elsif ($line =~ /^\s*$/) { | ||||||
175 | 0 | 0 | $precomment = ''; | ||||
176 | 0 | 0 | $postcomment = ''; | ||||
177 | 0 | 0 | next; | ||||
178 | } | ||||||
179 | |||||||
180 | 0 | 0 | chop($line); | ||||
181 | #strip off whitespace at the end of the line | ||||||
182 | 0 | 0 | $line =~ s/\s*$//; | ||||
183 | |||||||
184 | |||||||
185 | 0 | 0 | 0 | if ($line =~ /^\[(\w+)\]$/) { | |||
0 | |||||||
0 | |||||||
186 | 0 | 0 | $context = $1; | ||||
187 | 0 | 0 | $self->_addcontext($context, $contextorder); | ||||
188 | 0 | 0 | $contextorder++; | ||||
189 | } elsif ($line =~ /^channel\s*[=>]+\s*(.*)$/) { | ||||||
190 | 0 | 0 | $channel = $1; | ||||
191 | 0 | 0 | $self->channels($context, $1, $order, $precomment, $postcomment); | ||||
192 | 0 | 0 | $precomment = ''; | ||||
193 | 0 | 0 | $postcomment = ''; | ||||
194 | 0 | 0 | $order++; | ||||
195 | } elsif ($line =~ /^(\w+)\s*[=>]+\s*(.*)/) { | ||||||
196 | 0 | 0 | $self->_setvar($context, $1, $2, $order, $precomment, $postcomment); | ||||
197 | 0 | 0 | $precomment = ''; | ||||
198 | 0 | 0 | $postcomment = ''; | ||||
199 | 0 | 0 | $order++; | ||||
200 | } else { | ||||||
201 | 0 | 0 | 0 | print STDERR "Unknown line: $line\n" if ($DEBUG); | |||
202 | } | ||||||
203 | |||||||
204 | } | ||||||
205 | 0 | 0 | close(CF); | ||||
206 | |||||||
207 | 0 | 0 | return 1; | ||||
208 | } | ||||||
209 | |||||||
210 | sub writeconfig { | ||||||
211 | 0 | 0 | 0 | 0 | my ($self, $fh) = @_; | ||
212 | |||||||
213 | 0 | 0 | 0 | if (!$fh) { | |||
214 | 0 | 0 | $fh = \*STDERR; | ||||
215 | } | ||||||
216 | |||||||
217 | 0 | 0 | foreach $context ($self->_contextorder()) { | ||||
218 | 0 | 0 | print $fh "[$context]\n"; | ||||
219 | |||||||
220 | 0 | 0 | foreach $channelgroup ($self->_group($context)) { | ||||
221 | 0 | 0 | print $fh ";ACZGroup: $channelgroup\n"; | ||||
222 | } | ||||||
223 | |||||||
224 | 0 | 0 | foreach $channel (sort {$a <=> $b} keys %{$self->{config}{$context}}) { | ||||
0 | 0 | ||||||
0 | 0 | ||||||
225 | 0 | 0 | foreach $key (keys %{$self->{config}{$context}{$channel}}) { | ||||
0 | 0 | ||||||
226 | 0 | 0 | 0 | next if ($key eq 'channel'); | |||
227 | 0 | 0 | 0 | if ($self->{config}{$context}{$channel}{$key}{val}) { | |||
228 | 0 | 0 | print $fh $self->{config}{$context}{$channel}{$key}{'precomment'}; | ||||
229 | 0 | 0 | print $fh "$key => " . $self->{config}{$context}{$channel}{$key}{val}; | ||||
230 | 0 | 0 | 0 | if ($self->{config}{$context}{$channel}{$key}{postcomment}) { | |||
231 | 0 | 0 | print $fh ' ' . $self->{config}{$context}{$channel}{$key}{postcomment}; | ||||
232 | } else { | ||||||
233 | 0 | 0 | print $fh "\n"; | ||||
234 | } | ||||||
235 | } | ||||||
236 | } | ||||||
237 | 0 | 0 | print $fh "channel => $channel\n"; | ||||
238 | 0 | 0 | print $fh "\n"; | ||||
239 | } | ||||||
240 | } | ||||||
241 | } | ||||||
242 | |||||||
243 | sub deletechannel { | ||||||
244 | 0 | 0 | 0 | 0 | my ($self, $context, $channel) = @_; | ||
245 | |||||||
246 | # if (defined($self->{config}{$context}{$channel})) { | ||||||
247 | # $self->{config}{$context}{$channel} = {}; | ||||||
248 | # } | ||||||
249 | |||||||
250 | 0 | 0 | delete($self->{config}{$context}{$channel}); | ||||
251 | 0 | 0 | return 1; | ||||
252 | } | ||||||
253 | |||||||
254 | sub setvariable { | ||||||
255 | 1 | 1 | 0 | 549 | my ($self, $context, $channel, $var, $val) = @_; | ||
256 | |||||||
257 | 1 | 6 | $self->{config}{$context}{$channel}{$var}{val} = $val; | ||||
258 | 1 | 2 | $self->{config}{$context}{$channel}{$var}{precomment} = ";Modified by Asterisk::Config::Zapata\n"; | ||||
259 | |||||||
260 | } | ||||||
261 | |||||||
262 | sub helptext { | ||||||
263 | 0 | 0 | 0 | my ($self, $helpname) = @_; | |||
264 | |||||||
265 | |||||||
266 | } | ||||||
267 | |||||||
268 | sub cgiform { | ||||||
269 | 0 | 0 | 0 | my ($self, $action, $context, %vars) = @_; | |||
270 | |||||||
271 | #actions can be show, list, add, addform, modify, modifyform, delete, deleteform | ||||||
272 | |||||||
273 | 0 | my $html = ''; | |||||
274 | |||||||
275 | 0 | my $channel = $vars{'channel'}; | |||||
276 | |||||||
277 | 0 | my $module = $self->{'name'}; | |||||
278 | 0 | my $URL = $ENV{'REQUEST_URI'}; | |||||
279 | 0 | 0 | if (!$context) { | ||||
280 | 0 | $html .= " Context must be specified\n"; |
|||||
281 | 0 | return $html; | |||||
282 | } | ||||||
283 | |||||||
284 | #if no action specified then default to list | ||||||
285 | 0 | 0 | if (!$action) { | ||||
286 | 0 | $action = 'list'; | |||||
287 | } | ||||||
288 | |||||||
289 | 0 | 0 | if ($action =~ /(.*)form$/) { | ||||
290 | 0 | $html .= " | |||||
291 | 0 | $html .= " | |||||
292 | 0 | $html .= "\n"; | |||||
293 | 0 | $html .= "\n"; | |||||
294 | 0 | $html .= "\n"; | |||||
295 | } | ||||||
296 | |||||||
297 | |||||||
298 | |||||||
299 | 0 | 0 | if ($action eq 'list') { | ||||
300 | 0 | foreach $channel ( sort keys %{$self->{config}{$context}} ) { | |||||
0 | |||||||
301 | 0 | $html .= "Channel $channel\n"; | |||||
302 | } | ||||||
303 | } | ||||||
304 | |||||||
305 | 0 | 0 | 0 | if ($action eq 'show' || $action =~ /^modify/ || $action =~ /^delete/ ) { | |||
0 | |||||||
306 | 0 | 0 | 0 | if (!$channel || !$self->{'config'}{$context}{$channel}) { | |||
307 | 0 | $html .= " Channel not specified, or channel does not exist\n"; |
|||||
308 | 0 | return $html; | |||||
309 | } | ||||||
310 | } | ||||||
311 | |||||||
312 | 0 | 0 | 0 | if ($action eq 'deleteform') { | |||
0 | 0 | ||||||
0 | |||||||
313 | 0 | $html .= " Are you sure you want to delete channel $channel?\n"; |
|||||
314 | 0 | $html .= " Confirm\n"; |
|||||
315 | |||||||
316 | } elsif ($action eq 'delete') { | ||||||
317 | 0 | 0 | 0 | if ($vars{'doit'} == 1 && $self->deletechannel($context, $channel)) { | |||
318 | 0 | $html .= " Channel $channel has been deleted\n"; |
|||||
319 | } else { | ||||||
320 | 0 | $html .= " Unable to delete channel $channel\n"; |
|||||
321 | |||||||
322 | } | ||||||
323 | } elsif ( $action eq 'show' || $action =~ /^modify/ || $action =~ /^add/ ) { | ||||||
324 | |||||||
325 | |||||||
326 | 0 | 0 | if ($action eq 'show') { | ||||
327 | 0 | $html .= "Modify\n"; | |||||
328 | 0 | $html .= "Delete\n"; | |||||
329 | } | ||||||
330 | |||||||
331 | #loop through allowed variables | ||||||
332 | 0 | foreach $var ( sort keys %{$self->{'variables'}} ) { | |||||
0 | |||||||
333 | |||||||
334 | 0 | my $value = ''; | |||||
335 | 0 | 0 | if ($self->{'config'}{$context}{$channel}{$var}{'val'}) { | ||||
336 | 0 | $value = $self->{'config'}{$context}{$channel}{$var}{'val'}; | |||||
337 | } else { | ||||||
338 | 0 | $value = $self->{'variables'}{$var}{'default'}; | |||||
339 | } | ||||||
340 | |||||||
341 | 0 | 0 | 0 | if ($action eq 'show') { | |||
0 | |||||||
0 | |||||||
342 | 0 | $html .= " $var: $value\n"; |
|||||
343 | } elsif ($action =~ /(.*)form$/) { | ||||||
344 | 0 | my $subaction = $1; | |||||
345 | 0 | my $fieldtype = $self->{'variables'}{$var}{'type'}; | |||||
346 | 0 | $html .= "\n"; | |||||
347 | 0 | 0 | if ($fieldtype eq 'text') { | ||||
0 | |||||||
348 | 0 | $html .= " $var: \n"; |
|||||
349 | } elsif ($fieldtype eq 'one') { | ||||||
350 | 0 | $html .= " $var: \n"; |
|||||
351 | 0 | foreach $item (@{$self->{'variables'}{$var}{'values'}}) { | |||||
0 | |||||||
352 | 0 | 0 | my $checked = 'checked' if ($item eq $value); | ||||
353 | 0 | $html .= " $item\n"; | |||||
354 | } | ||||||
355 | } | ||||||
356 | |||||||
357 | } elsif ($action eq 'modify' || $action eq 'add') { | ||||||
358 | 0 | 0 | 0 | if ($action eq 'add' || ($vars{$var} ne $vars{"OLD$var"})) { | |||
359 | 0 | my $newval = $vars{$var}; | |||||
360 | #need to check for valid value here | ||||||
361 | 0 | 0 | if ($self->variablecheck($context, $var, $newval)) { | ||||
362 | 0 | $self->setvariable($context, $channel, $var, $newval); | |||||
363 | } | ||||||
364 | } | ||||||
365 | |||||||
366 | } | ||||||
367 | |||||||
368 | } | ||||||
369 | |||||||
370 | } | ||||||
371 | |||||||
372 | 0 | 0 | if ($action =~ /form$/) { | ||||
373 | 0 | $html .= "\n"; | |||||
374 | } | ||||||
375 | |||||||
376 | 0 | return $html; | |||||
377 | } | ||||||
378 | |||||||
379 | |||||||
380 | 1; |